- Allow device probing again (this should fix the problem Arnaldo de Melo
[platform/upstream/net-tools.git] / lib / af.c
1 /*
2  * lib/af.c   This file contains the top-level part of the protocol
3  *              support functions module for the NET-2 base distribution.
4  *
5  * Version:     $Id: af.c,v 1.7 1998/11/17 15:16:26 freitag Exp $
6  *
7  * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
8  *              Copyright 1993 MicroWalt Corporation
9  *
10  *              This program is free software; you can redistribute it
11  *              and/or  modify it under  the terms of  the GNU General
12  *              Public  License as  published  by  the  Free  Software
13  *              Foundation;  either  version 2 of the License, or  (at
14  *              your option) any later version.
15  */
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <errno.h>
21 #include <ctype.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include "config.h"
25 #include "net-support.h"
26 #include "pathnames.h"
27 #include "intl.h"
28
29
30 int flag_unx = 0;
31 int flag_ipx = 0;
32 int flag_ax25 = 0;
33 int flag_ddp = 0;
34 int flag_netrom = 0;
35 int flag_inet = 0;
36 int flag_inet6 = 0;
37 int flag_econet = 0;
38
39
40 struct aftrans_t {
41     char *alias;
42     char *name;
43     int *flag;
44 } aftrans[] = {
45
46     {
47         "ax25", "ax25", &flag_ax25
48     },
49     {
50         "ip", "inet", &flag_inet
51     },
52     {
53         "ip6", "inet6", &flag_inet6
54     },
55     {
56         "ipx", "ipx", &flag_ipx
57     },
58     {
59         "appletalk", "ddp", &flag_ddp
60     },
61     {
62         "netrom", "netrom", &flag_netrom
63     },
64     {
65         "inet", "inet", &flag_inet
66     },
67     {
68         "inet6", "inet6", &flag_inet6
69     },
70     {
71         "ddp", "ddp", &flag_ddp
72     },
73     {
74         "unix", "unix", &flag_unx
75     },
76     {
77         "tcpip", "inet", &flag_inet
78     },
79     {
80         "econet", "ec", &flag_econet
81     },
82     {
83         0, 0, 0
84     }
85 };
86
87 char afname[256] = "";
88
89 extern struct aftype unspec_aftype;
90 extern struct aftype unix_aftype;
91 extern struct aftype inet_aftype;
92 extern struct aftype inet6_aftype;
93 extern struct aftype ax25_aftype;
94 extern struct aftype netrom_aftype;
95 extern struct aftype ipx_aftype;
96 extern struct aftype ddp_aftype;
97 extern struct aftype ec_aftype;
98
99 static short sVafinit = 0;
100
101 struct aftype *aftypes[] =
102 {
103 #if HAVE_AFUNIX
104     &unix_aftype,
105 #endif
106 #if HAVE_AFINET
107     &inet_aftype,
108 #endif
109 #if HAVE_AFINET6
110     &inet6_aftype,
111 #endif
112 #if HAVE_AFAX25
113     &ax25_aftype,
114 #endif
115 #if HAVE_AFNETROM
116     &netrom_aftype,
117 #endif
118 #if HAVE_AFIPX
119     &ipx_aftype,
120 #endif
121 #if HAVE_AFATALK
122     &ddp_aftype,
123 #endif
124 #if HAVE_AFECONET
125     &ec_aftype,
126 #endif
127     &unspec_aftype,
128     NULL
129 };
130
131 void afinit()
132 {
133     unspec_aftype.title = _("UNSPEC");
134 #if HAVE_AFINET
135     unix_aftype.title = _("UNIX Domain");
136 #endif
137 #if HAVE_AFINET
138     inet_aftype.title = _("DARPA Internet");
139 #endif
140 #if HAVE_AFINET6
141     inet6_aftype.title = _("IPv6");
142 #endif
143 #if HAVE_AFAX25
144     ax25_aftype.title = _("AMPR AX.25");
145 #endif
146 #if HAVE_AFNETROM
147     netrom_aftype.title = _("AMPR NET/ROM");
148 #endif
149 #if HAVE_AFIPX
150     ipx_aftype.title = _("IPX");
151 #endif
152 #if HAVE_AFATALK
153     ddp_aftype.title = _("Appletalk DDP");
154 #endif
155 #if HAVE_AFECONET
156     ec_aftype.title = _("Econet");
157 #endif
158     sVafinit = 1;
159 }
160
161 /* set the default AF list from the program name or a constant value    */
162 void aftrans_def(char *tool, char *argv0, char *dflt)
163 {
164     char *tmp;
165     char *buf;
166
167     strcpy(afname, dflt);
168
169     if (!(tmp = strrchr(argv0, '/')))
170         tmp = argv0;            /* no slash?! */
171     else
172         tmp++;
173
174     if (!(buf = strdup(tmp)))
175         return;
176
177     if (strlen(tool) >= strlen(tmp)) {
178         free(buf);
179         return;
180     }
181     tmp = buf + (strlen(tmp) - strlen(tool));
182
183     if (strcmp(tmp, tool) != 0) {
184         free(buf);
185         return;
186     }
187     *tmp = '\0';
188     if ((tmp = strchr(buf, '_')))
189         *tmp = '\0';
190
191     afname[0] = '\0';
192     if (aftrans_opt(buf))
193         strcpy(afname, buf);
194
195     free(buf);
196 }
197
198
199 /* Check our protocol family table for this family. */
200 struct aftype *get_aftype(const char *name)
201 {
202     struct aftype **afp;
203
204     if (!sVafinit)
205         afinit();
206
207     afp = aftypes;
208     while (*afp != NULL) {
209         if (!strcmp((*afp)->name, name))
210             return (*afp);
211         afp++;
212     }
213     if (index(name, ','))
214         fprintf(stderr, _("Please don't supply more than one address family.\n"));
215     return (NULL);
216 }
217
218
219 /* Check our protocol family table for this family. */
220 struct aftype *get_afntype(int af)
221 {
222     struct aftype **afp;
223
224     if (!sVafinit)
225         afinit();
226
227     afp = aftypes;
228     while (*afp != NULL) {
229         if ((*afp)->af == af)
230             return (*afp);
231         afp++;
232     }
233     return (NULL);
234 }
235
236 /* Check our protocol family table for this family and return its socket */
237 int get_socket_for_af(int af)
238 {
239     struct aftype **afp;
240
241     if (!sVafinit)
242         afinit();
243
244     afp = aftypes;
245     while (*afp != NULL) {
246         if ((*afp)->af == af)
247             return (*afp)->fd;
248         afp++;
249     }
250     return -1;
251 }
252
253 int aftrans_opt(const char *arg)
254 {
255     struct aftrans_t *paft;
256     char *tmp1, *tmp2;
257     char buf[256];
258
259     safe_strncpy(buf, arg, sizeof(buf));
260
261     tmp1 = buf;
262
263     while (tmp1) {
264
265         tmp2 = index(tmp1, ',');
266
267         if (tmp2)
268             *(tmp2++) = '\0';
269
270         paft = aftrans;
271         for (paft = aftrans; paft->alias; paft++) {
272             if (strcmp(tmp1, paft->alias))
273                 continue;
274             if (strlen(paft->name) + strlen(afname) + 1 >= sizeof(afname)) {
275                 fprintf(stderr, _("Too much address family arguments.\n"));
276                 return (0);
277             }
278             if (paft->flag)
279                 (*paft->flag)++;
280             if (afname[0])
281                 strcat(afname, ",");
282             strcat(afname, paft->name);
283             break;
284         }
285         if (!paft->alias) {
286             fprintf(stderr, _("Unknown address family `%s'.\n"), tmp1);
287             return (1);
288         }
289         tmp1 = tmp2;
290     }
291
292     return (0);
293 }