Add Bluetooth socket support
[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.14 2007/12/01 17:49:35 ecki 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 #include "util.h"
29
30 int flag_unx;
31 int flag_ipx;
32 int flag_ax25;
33 int flag_ddp;
34 int flag_netrom;
35 int flag_inet;
36 int flag_inet6;
37 int flag_econet;
38 int flag_rose;
39 int flag_x25 = 0;
40 int flag_ash;
41 int flag_bluetooth;
42
43
44 struct aftrans_t {
45     char *alias;
46     char *name;
47     int *flag;
48 } aftrans[] = {
49
50     {
51         "ax25", "ax25", &flag_ax25
52     },
53     {
54         "ip", "inet", &flag_inet
55     },
56     {
57         "ip6", "inet6", &flag_inet6
58     },
59     {
60         "ipx", "ipx", &flag_ipx
61     },
62     {
63         "rose", "rose", &flag_rose
64     },
65     {
66         "appletalk", "ddp", &flag_ddp
67     },
68     {
69         "netrom", "netrom", &flag_netrom
70     },
71     {
72         "inet", "inet", &flag_inet
73     },
74     {
75         "inet6", "inet6", &flag_inet6
76     },
77     {
78         "ddp", "ddp", &flag_ddp
79     },
80     {
81         "unix", "unix", &flag_unx
82     },
83     {
84         "tcpip", "inet", &flag_inet
85     },
86     {
87         "econet", "ec", &flag_econet
88     },
89     {
90         "x25", "x25", &flag_x25
91     },
92     {
93         "ash", "ash", &flag_ash
94     },
95     {
96         "bluetooth", "bluetooth", &flag_bluetooth
97     },
98     {
99         0, 0, 0
100     }
101 };
102
103 char afname[256] = "";
104
105 extern struct aftype unspec_aftype;
106 extern struct aftype unix_aftype;
107 extern struct aftype inet_aftype;
108 extern struct aftype inet6_aftype;
109 extern struct aftype ax25_aftype;
110 extern struct aftype netrom_aftype;
111 extern struct aftype ipx_aftype;
112 extern struct aftype ddp_aftype;
113 extern struct aftype ec_aftype;
114 extern struct aftype x25_aftype;
115 extern struct aftype rose_aftype;
116 extern struct aftype ash_aftype;
117
118 static short sVafinit = 0;
119
120 struct aftype *aftypes[] =
121 {
122 #if HAVE_AFUNIX
123     &unix_aftype,
124 #endif
125 #if HAVE_AFINET
126     &inet_aftype,
127 #endif
128 #if HAVE_AFINET6
129     &inet6_aftype,
130 #endif
131 #if HAVE_AFAX25
132     &ax25_aftype,
133 #endif
134 #if HAVE_AFNETROM
135     &netrom_aftype,
136 #endif
137 #if HAVE_AFROSE
138     &rose_aftype,
139 #endif
140 #if HAVE_AFIPX
141     &ipx_aftype,
142 #endif
143 #if HAVE_AFATALK
144     &ddp_aftype,
145 #endif
146 #if HAVE_AFECONET
147     &ec_aftype,
148 #endif
149 #if HAVE_AFASH
150     &ash_aftype,
151 #endif
152 #if HAVE_AFX25
153     &x25_aftype,
154 #endif
155     &unspec_aftype,
156     NULL
157 };
158
159 void afinit()
160 {
161     unspec_aftype.title = _("UNSPEC");
162 #if HAVE_AFUNIX
163     unix_aftype.title = _("UNIX Domain");
164 #endif
165 #if HAVE_AFINET
166     inet_aftype.title = _("DARPA Internet");
167 #endif
168 #if HAVE_AFINET6
169     inet6_aftype.title = _("IPv6");
170 #endif
171 #if HAVE_AFAX25
172     ax25_aftype.title = _("AMPR AX.25");
173 #endif
174 #if HAVE_AFNETROM
175     netrom_aftype.title = _("AMPR NET/ROM");
176 #endif
177 #if HAVE_AFIPX
178     ipx_aftype.title = _("Novell IPX");
179 #endif
180 #if HAVE_AFATALK
181     ddp_aftype.title = _("Appletalk DDP");
182 #endif
183 #if HAVE_AFECONET
184     ec_aftype.title = _("Econet");
185 #endif
186 #if HAVE_AFX25
187     x25_aftype.title = _("CCITT X.25");
188 #endif
189 #if HAVE_AFROSE
190     rose_aftype.title = _("AMPR ROSE");
191 #endif
192 #if HAVE_AFASH
193     ash_aftype.title = _("Ash");
194 #endif
195     sVafinit = 1;
196 }
197
198 /* set the default AF list from the program name or a constant value    */
199 void aftrans_def(char *tool, char *argv0, char *dflt)
200 {
201     char *tmp;
202     char *buf;
203
204     strcpy(afname, dflt);
205
206     if (!(tmp = strrchr(argv0, '/')))
207         tmp = argv0;            /* no slash?! */
208     else
209         tmp++;
210
211     if (!(buf = strdup(tmp)))
212         return;
213
214     if (strlen(tool) >= strlen(tmp)) {
215         free(buf);
216         return;
217     }
218     tmp = buf + (strlen(tmp) - strlen(tool));
219
220     if (strcmp(tmp, tool) != 0) {
221         free(buf);
222         return;
223     }
224     *tmp = '\0';
225     if ((tmp = strchr(buf, '_')))
226         *tmp = '\0';
227
228     afname[0] = '\0';
229     if (aftrans_opt(buf))
230         strcpy(afname, buf);
231
232     free(buf);
233 }
234
235
236 /* Check our protocol family table for this family. */
237 struct aftype *get_aftype(const char *name)
238 {
239     struct aftype **afp;
240
241     if (!sVafinit)
242         afinit();
243
244     afp = aftypes;
245     while (*afp != NULL) {
246         if (!strcmp((*afp)->name, name))
247             return (*afp);
248         afp++;
249     }
250     if (index(name, ','))
251         fprintf(stderr, _("Please don't supply more than one address family.\n"));
252     return (NULL);
253 }
254
255
256 /* Check our protocol family table for this family. */
257 struct aftype *get_afntype(int af)
258 {
259     struct aftype **afp;
260
261     if (!sVafinit)
262         afinit();
263
264     afp = aftypes;
265     while (*afp != NULL) {
266         if ((*afp)->af == af)
267             return (*afp);
268         afp++;
269     }
270     return (NULL);
271 }
272
273 /* Check our protocol family table for this family and return its socket */
274 int get_socket_for_af(int af)
275 {
276     struct aftype **afp;
277
278     if (!sVafinit)
279         afinit();
280
281     afp = aftypes;
282     while (*afp != NULL) {
283         if ((*afp)->af == af)
284             return (*afp)->fd;
285         afp++;
286     }
287     return -1;
288 }
289
290 int aftrans_opt(const char *arg)
291 {
292     struct aftrans_t *paft;
293     char *tmp1, *tmp2;
294     char buf[256];
295
296     safe_strncpy(buf, arg, sizeof(buf));
297
298     tmp1 = buf;
299
300     while (tmp1) {
301
302         tmp2 = index(tmp1, ',');
303
304         if (tmp2)
305             *(tmp2++) = '\0';
306
307         paft = aftrans;
308         for (paft = aftrans; paft->alias; paft++) {
309             if (strcmp(tmp1, paft->alias))
310                 continue;
311             if (strlen(paft->name) + strlen(afname) + 1 >= sizeof(afname)) {
312                 fprintf(stderr, _("Too much address family arguments.\n"));
313                 return (0);
314             }
315             if (paft->flag)
316                 (*paft->flag)++;
317             if (afname[0])
318                 strcat(afname, ",");
319             strcat(afname, paft->name);
320             break;
321         }
322         if (!paft->alias) {
323             fprintf(stderr, _("Unknown address family `%s'.\n"), tmp1);
324             return (1);
325         }
326         tmp1 = tmp2;
327     }
328
329     return (0);
330 }
331
332 /* type: 0=all, 1=getroute */
333 void print_aflist(int type) {
334     int count = 0;
335     char * txt;
336     struct aftype **afp;
337
338     if (!sVafinit)
339         afinit();
340
341     afp = aftypes;
342     while (*afp != NULL) {
343         if ((type == 1 && ((*afp)->rprint == NULL)) || ((*afp)->af == 0)) {
344                 afp++; continue;
345         }
346         if ((count % 3) == 0) fprintf(stderr,count?"\n    ":"    "); 
347         txt = (*afp)->name; if (!txt) txt = "..";
348         fprintf(stderr,"%s (%s) ",txt,(*afp)->title);
349         count++;
350         afp++;
351     }
352     fprintf(stderr,"\n");
353 }