Minor textual updates/corrections
[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.11 1999/04/18 20:28:42 philip 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 = 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 extern struct aftype rose_aftype;
99
100 static short sVafinit = 0;
101
102 struct aftype *aftypes[] =
103 {
104 #if HAVE_AFUNIX
105     &unix_aftype,
106 #endif
107 #if HAVE_AFINET
108     &inet_aftype,
109 #endif
110 #if HAVE_AFINET6
111     &inet6_aftype,
112 #endif
113 #if HAVE_AFAX25
114     &ax25_aftype,
115 #endif
116 #if HAVE_AFNETROM
117     &netrom_aftype,
118 #endif
119 #if HAVE_AFROSE
120     &rose_aftype,
121 #endif
122 #if HAVE_AFIPX
123     &ipx_aftype,
124 #endif
125 #if HAVE_AFATALK
126     &ddp_aftype,
127 #endif
128 #if HAVE_AFECONET
129     &ec_aftype,
130 #endif
131     &unspec_aftype,
132     NULL
133 };
134
135 void afinit()
136 {
137     unspec_aftype.title = _("UNSPEC");
138 #if HAVE_AFUNIX
139     unix_aftype.title = _("UNIX Domain");
140 #endif
141 #if HAVE_AFINET
142     inet_aftype.title = _("DARPA Internet");
143 #endif
144 #if HAVE_AFINET6
145     inet6_aftype.title = _("IPv6");
146 #endif
147 #if HAVE_AFAX25
148     ax25_aftype.title = _("AMPR AX.25");
149 #endif
150 #if HAVE_AFNETROM
151     netrom_aftype.title = _("AMPR NET/ROM");
152 #endif
153 #if HAVE_AFIPX
154     ipx_aftype.title = _("Novell IPX");
155 #endif
156 #if HAVE_AFATALK
157     ddp_aftype.title = _("Appletalk DDP");
158 #endif
159 #if HAVE_AFECONET
160     ec_aftype.title = _("Econet");
161 #endif
162 #if HAVE_AFROSE
163     rose_aftype.title = _("AMPR ROSE");
164 #endif
165     sVafinit = 1;
166 }
167
168 /* set the default AF list from the program name or a constant value    */
169 void aftrans_def(char *tool, char *argv0, char *dflt)
170 {
171     char *tmp;
172     char *buf;
173
174     strcpy(afname, dflt);
175
176     if (!(tmp = strrchr(argv0, '/')))
177         tmp = argv0;            /* no slash?! */
178     else
179         tmp++;
180
181     if (!(buf = strdup(tmp)))
182         return;
183
184     if (strlen(tool) >= strlen(tmp)) {
185         free(buf);
186         return;
187     }
188     tmp = buf + (strlen(tmp) - strlen(tool));
189
190     if (strcmp(tmp, tool) != 0) {
191         free(buf);
192         return;
193     }
194     *tmp = '\0';
195     if ((tmp = strchr(buf, '_')))
196         *tmp = '\0';
197
198     afname[0] = '\0';
199     if (aftrans_opt(buf))
200         strcpy(afname, buf);
201
202     free(buf);
203 }
204
205
206 /* Check our protocol family table for this family. */
207 struct aftype *get_aftype(const char *name)
208 {
209     struct aftype **afp;
210
211     if (!sVafinit)
212         afinit();
213
214     afp = aftypes;
215     while (*afp != NULL) {
216         if (!strcmp((*afp)->name, name))
217             return (*afp);
218         afp++;
219     }
220     if (index(name, ','))
221         fprintf(stderr, _("Please don't supply more than one address family.\n"));
222     return (NULL);
223 }
224
225
226 /* Check our protocol family table for this family. */
227 struct aftype *get_afntype(int af)
228 {
229     struct aftype **afp;
230
231     if (!sVafinit)
232         afinit();
233
234     afp = aftypes;
235     while (*afp != NULL) {
236         if ((*afp)->af == af)
237             return (*afp);
238         afp++;
239     }
240     return (NULL);
241 }
242
243 /* Check our protocol family table for this family and return its socket */
244 int get_socket_for_af(int af)
245 {
246     struct aftype **afp;
247
248     if (!sVafinit)
249         afinit();
250
251     afp = aftypes;
252     while (*afp != NULL) {
253         if ((*afp)->af == af)
254             return (*afp)->fd;
255         afp++;
256     }
257     return -1;
258 }
259
260 int aftrans_opt(const char *arg)
261 {
262     struct aftrans_t *paft;
263     char *tmp1, *tmp2;
264     char buf[256];
265
266     safe_strncpy(buf, arg, sizeof(buf));
267
268     tmp1 = buf;
269
270     while (tmp1) {
271
272         tmp2 = index(tmp1, ',');
273
274         if (tmp2)
275             *(tmp2++) = '\0';
276
277         paft = aftrans;
278         for (paft = aftrans; paft->alias; paft++) {
279             if (strcmp(tmp1, paft->alias))
280                 continue;
281             if (strlen(paft->name) + strlen(afname) + 1 >= sizeof(afname)) {
282                 fprintf(stderr, _("Too much address family arguments.\n"));
283                 return (0);
284             }
285             if (paft->flag)
286                 (*paft->flag)++;
287             if (afname[0])
288                 strcat(afname, ",");
289             strcat(afname, paft->name);
290             break;
291         }
292         if (!paft->alias) {
293             fprintf(stderr, _("Unknown address family `%s'.\n"), tmp1);
294             return (1);
295         }
296         tmp1 = tmp2;
297     }
298
299     return (0);
300 }
301
302 /* type: 0=all, 1=getroute */
303 void print_aflist(int type) {
304     int count = 0;
305     char * txt;
306     struct aftype **afp;
307
308     if (!sVafinit)
309         afinit();
310
311     afp = aftypes;
312     while (*afp != NULL) {
313         if ((type == 1 && ((*afp)->rprint == NULL)) || ((*afp)->af == 0)) {
314                 afp++; continue;
315         }
316         if ((count % 3) == 0) fprintf(stderr,count?"\n    ":"    "); 
317         txt = (*afp)->name; if (!txt) txt = "..";
318         fprintf(stderr,"%s (%s) ",txt,(*afp)->title);
319         count++;
320         afp++;
321     }
322     fprintf(stderr,"\n");
323 }