man/pt_BR/ifconfig.8: remove untranslated paragraph
[platform/upstream/net-tools.git] / lib / inet_gr.c
1 /*
2    $Id: inet_gr.c,v 1.14 2009/07/08 00:24:03 ecki Exp $
3
4    Modifications:
5    1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
6    1999-01-01 - Bernd Eckenfels          - fixed the routing cache printouts
7    1999-10-07 - Kurt Garloff <garloff@suse.de> - do host (instead of network) name
8                                                 lookup for gws and hosts
9  */
10
11 #include "config.h"
12
13 #if HAVE_AFINET
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <netinet/in.h>
17 #include <arpa/inet.h>
18 #include <arpa/nameser.h>
19 /* #include <net/route.h> realy broken */
20 #include <ctype.h>
21 #include <errno.h>
22 #include <netdb.h>
23 #include <resolv.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <stdio.h>
27 #include <unistd.h>
28 #include "version.h"
29 #include "net-support.h"
30 #include "pathnames.h"
31 #include "intl.h"
32 #include "net-features.h"
33 #include "proc.h"
34 extern struct aftype inet_aftype;
35
36 extern char *INET_sprintmask(struct sockaddr *sap, int numeric, 
37                              unsigned int netmask);
38
39 int rprint_fib(int ext, int numeric)
40 {
41     char buff[1024], iface[17], flags[64];
42     char gate_addr[128], net_addr[128];
43     char mask_addr[128];
44     int num, iflags, metric, refcnt, use, mss, window, irtt;
45     FILE *fp = fopen(_PATH_PROCNET_ROUTE, "r");
46     char *fmt;
47
48     if (!fp) {
49         perror(_PATH_PROCNET_ROUTE);
50         printf(_("INET (IPv4) not configured in this system.\n"));
51         return 1;
52     }
53     printf(_("Kernel IP routing table\n"));
54
55     if (ext == 1)
56         printf(_("Destination     Gateway         Genmask         "
57                  "Flags Metric Ref    Use Iface\n"));
58     if (ext == 2)
59         printf(_("Destination     Gateway         Genmask         "
60                  "Flags   MSS Window  irtt Iface\n"));
61     if (ext >= 3)
62         printf(_("Destination     Gateway         Genmask         "
63                  "Flags Metric Ref    Use Iface    "
64                  "MSS   Window irtt\n"));
65
66     irtt = 0;
67     window = 0;
68     mss = 0;
69
70     fmt = proc_gen_fmt(_PATH_PROCNET_ROUTE, 0, fp,
71                        "Iface", "%15s",
72                        "Destination", "%127s",
73                        "Gateway", "%127s",
74                        "Flags", "%X",
75                        "RefCnt", "%d",
76                        "Use", "%d",
77                        "Metric", "%d",
78                        "Mask", "%127s",
79                        "MTU", "%d",
80                        "Window", "%d",
81                        "IRTT", "%d",
82                        NULL);
83     /* "%15s %127s %127s %X %d %d %d %127s %d %d %d\n" */
84
85     if (!fmt)
86         return 1;
87
88     while (fgets(buff, 1023, fp)) {
89         struct sockaddr snet_target, snet_gateway, snet_mask;
90         struct sockaddr_in *sin_netmask;
91
92         num = sscanf(buff, fmt,
93                      iface, net_addr, gate_addr,
94                      &iflags, &refcnt, &use, &metric, mask_addr,
95                      &mss, &window, &irtt);
96         if (num < 10 || !(iflags & RTF_UP))
97             continue;
98
99         /* Fetch and resolve the target address. */
100         (void) inet_aftype.input(1, net_addr, &snet_target);
101
102         /* Fetch and resolve the gateway address. */
103         (void) inet_aftype.input(1, gate_addr, &snet_gateway);
104
105         /* Fetch and resolve the genmask. */
106         (void) inet_aftype.input(1, mask_addr, &snet_mask);
107         
108         sin_netmask = (struct sockaddr_in *)&snet_mask;
109         strcpy(net_addr, INET_sprintmask(&snet_target, 
110                                          (numeric | 0x8000 | (iflags & RTF_HOST? 0x4000: 0)),
111                                          sin_netmask->sin_addr.s_addr));
112         net_addr[15] = '\0';
113
114         strcpy(gate_addr, inet_aftype.sprint(&snet_gateway, numeric | 0x4000));
115         gate_addr[15] = '\0';
116
117         strcpy(mask_addr, inet_aftype.sprint(&snet_mask, 1));
118         mask_addr[15] = '\0';
119
120         /* Decode the flags. */
121         flags[0] = '\0';
122         if (iflags & RTF_UP)
123             strcat(flags, "U");
124         if (iflags & RTF_GATEWAY)
125             strcat(flags, "G");
126 #if HAVE_RTF_REJECT
127         if (iflags & RTF_REJECT)
128             strcpy(flags, "!");
129 #endif
130         if (iflags & RTF_HOST)
131             strcat(flags, "H");
132         if (iflags & RTF_REINSTATE)
133             strcat(flags, "R");
134         if (iflags & RTF_DYNAMIC)
135             strcat(flags, "D");
136         if (iflags & RTF_MODIFIED)
137             strcat(flags, "M");
138         if (iflags & RTF_DEFAULT)
139             strcat(flags, "d");
140         if (iflags & RTF_ALLONLINK)
141             strcat(flags, "a");
142         if (iflags & RTF_ADDRCONF)
143             strcat(flags, "c");
144         if (iflags & RTF_NONEXTHOP)
145             strcat(flags, "o");
146         if (iflags & RTF_EXPIRES)
147             strcat(flags, "e");
148         if (iflags & RTF_CACHE)
149             strcat(flags, "c");
150         if (iflags & RTF_FLOW)
151             strcat(flags, "f");
152         if (iflags & RTF_POLICY)
153             strcat(flags, "p");
154         if (iflags & RTF_LOCAL)
155             strcat(flags, "l");
156         if (iflags & RTF_MTU)
157             strcat(flags, "u");
158         if (iflags & RTF_WINDOW)
159             strcat(flags, "w");
160         if (iflags & RTF_IRTT)
161             strcat(flags, "i");
162         if (iflags & RTF_NOTCACHED) /* 2.0.36 */
163             strcat(flags, "n");
164
165         /* Print the info. */
166         if (ext == 1) {
167 #if HAVE_RTF_REJECT
168             if (iflags & RTF_REJECT)
169                 printf("%-15s -               %-15s %-5s %-6d -  %7d -\n",
170                        net_addr, mask_addr, flags, metric, use);
171             else
172 #endif
173                 printf("%-15s %-15s %-15s %-5s %-6d %-2d %7d %s\n",
174                        net_addr, gate_addr, mask_addr, flags,
175                        metric, refcnt, use, iface);
176         }
177         if (ext == 2) {
178 #if HAVE_RTF_REJECT
179             if (iflags & RTF_REJECT)
180                 printf("%-15s -               %-15s %-5s     - -          - -\n",
181                        net_addr, mask_addr, flags);
182             else
183 #endif
184                 printf("%-15s %-15s %-15s %-5s %5d %-5d %6d %s\n",
185                        net_addr, gate_addr, mask_addr, flags,
186                        mss, window, irtt, iface);
187         }
188         if (ext >= 3) {
189 #if HAVE_RTF_REJECT
190             if (iflags & RTF_REJECT)
191                 printf("%-15s -               %-15s %-5s %-6d -  %7d -        -     -      -\n",
192                        net_addr, mask_addr, flags, metric, use);
193             else
194 #endif
195                 printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6.6s   %-5d %-6d %d\n",
196                        net_addr, gate_addr, mask_addr, flags,
197                        metric, refcnt, use, iface, mss, window, irtt);
198         }
199     }
200
201     free(fmt);
202     (void) fclose(fp);
203     return (0);
204 }
205
206 int rprint_cache(int ext, int numeric)
207 {
208     char buff[1024], iface[17], flags[64];
209     char gate_addr[128], dest_addr[128], specdst[128];
210     char src_addr[128];
211     struct sockaddr snet;
212     unsigned int iflags;
213     int num, format, metric, refcnt, use, mss, window, irtt, hh, hhref, hhuptod, arp, tos;
214     char *fmt = NULL;
215
216     FILE *fp = fopen(_PATH_PROCNET_RTCACHE, "r");
217
218     if (!fp) {
219         perror(_PATH_PROCNET_RTCACHE);
220         printf(_("INET (IPv4) not configured in this system.\n"));
221         return 1;
222     }
223
224    /* Okay, first thing we need to know is the format of the rt_cache. 
225     * I am aware of two possible layouts:
226     * 2.2.0
227     * "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\tHHUptod\tSpecDst"
228     * "%s\t%08lX\t%08lX\t%8X\t%d\t%u\t%d\t%08lX\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X" 
229     *
230     * 2.0.36
231     * "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tHH\tARP"
232     * "%s\t%08lX\t%08lX\t%02X\t%d\t%u\t%d\t%08lX\t%d\t%lu\t%u\t%d\t%1d"
233     */
234     
235     format = proc_guess_fmt(_PATH_PROCNET_RTCACHE, fp, "IRTT",1,"TOS",2,"HHRef",4,"HHUptod",8,"SpecDst",16,"HH",32,"ARP",64,NULL);
236
237     printf(_("Kernel IP routing cache\n"));
238
239     switch(format) {
240         case -1: /* I/O Error */
241           perror(_PATH_PROCNET_RTCACHE);
242           exit(-1);
243           break;
244         case 63: /* 2.2.0 Format */
245           format = 2;
246           break;
247         case 97: /* 2.0.36 Format */
248           format = 1;
249           break;
250         default:
251           printf("ERROR: proc_guess_fmt(%s,... returned: %d\n",_PATH_PROCNET_RTCACHE, format);
252           break;
253     }
254     
255     rewind(fp);
256
257     if (ext == 1)
258       printf(_("Source          Destination     Gateway         "
259                "Flags Metric Ref    Use Iface\n"));
260     if (ext == 2)
261       printf(_("Source          Destination     Gateway         "
262                "Flags   MSS Window  irtt Iface\n"));
263
264     if (format == 1) {
265       if (ext >= 3)
266         printf(_("Source          Destination     Gateway         "
267                  "Flags Metric Ref    Use Iface    "
268                  "MSS   Window irtt  HH  Arp\n"));
269
270       fmt = proc_gen_fmt(_PATH_PROCNET_RTCACHE, 0, fp,
271                        "Iface", "%15s",
272                        "Destination", "%127s",
273                        "Gateway", "%127s",
274                        "Flags", "%X",
275                        "RefCnt", "%d",
276                        "Use", "%d",
277                        "Metric", "%d",
278                        "Source", "%127s",
279                        "MTU", "%d",
280                        "Window", "%d",
281                        "IRTT", "%d",
282                        "HH", "%d",
283                        "ARP", "%d",
284                        NULL);
285       /* "%15s %127s %127s %X %d %d %d %127s %d %d %d %d %d\n" */
286     }
287
288     if (format == 2) {
289       if (ext >= 3)
290         printf(_("Source          Destination     Gateway         "
291                  "Flags Metric Ref    Use Iface    "
292                  "MSS   Window irtt  TOS HHRef HHUptod     SpecDst\n"));
293         fmt = proc_gen_fmt(_PATH_PROCNET_RTCACHE, 0, fp,
294                        "Iface", "%15s",
295                        "Destination", "%127s",
296                        "Gateway", "%127s",
297                        "Flags", "%X",
298                        "RefCnt", "%d",
299                        "Use", "%d",
300                        "Metric", "%d",
301                        "Source", "%127s",
302                        "MTU", "%d",
303                        "Window", "%d",
304                        "IRTT", "%d",
305                        "TOS", "%d",
306                        "HHRef", "%d",
307                        "HHUptod", "%d",
308                        "SpecDst", "%127s",
309                        NULL);
310       /* "%15s %127s %127s %X %d %d %d %127s %d %d %d %d %d %127s\n" */
311     }
312
313
314     irtt = 0;
315     window = 0;
316     mss = 0;
317     hh = 0; hhref = 0; hhuptod = 0;
318     arp = 0; tos = 0;
319     while (fgets(buff, 1023, fp)) {
320         if (format == 1) {
321           num = sscanf(buff, fmt,
322                      iface, dest_addr, gate_addr,
323                      &iflags, &refcnt, &use, &metric, src_addr,
324                      &mss, &window, &irtt, &hh, &arp);
325           if (num < 12)
326             continue;
327         }
328         if (format == 2) {
329           num = sscanf(buff, fmt,
330                      iface, dest_addr, gate_addr,
331                      &iflags, &refcnt, &use, &metric, src_addr,
332                      &mss, &window, &irtt, &tos, &hhref, &hhuptod, &specdst);
333           if (num < 12)
334             continue;
335         }
336         
337
338         /* Fetch and resolve the target address. */
339         (void) inet_aftype.input(1, dest_addr, &snet);
340         strcpy(dest_addr, inet_aftype.sprint(&snet, numeric));
341         dest_addr[15] = '\0';
342
343         /* Fetch and resolve the gateway address. */
344         (void) inet_aftype.input(1, gate_addr, &snet);
345         strcpy(gate_addr, inet_aftype.sprint(&snet, numeric));
346         gate_addr[15] = '\0';
347
348         /* Fetch and resolve the source. */
349         (void) inet_aftype.input(1, src_addr, &snet);
350         strcpy(src_addr, inet_aftype.sprint(&snet, numeric));
351         src_addr[15] = '\0';
352
353         /* Fetch and resolve the SpecDst addrerss. */
354         (void) inet_aftype.input(1, specdst, &snet);
355         strcpy(specdst, inet_aftype.sprint(&snet, numeric));
356         specdst[15] = '\0';
357
358         /* Decode the flags. */
359         flags[0] = '\0';
360 if (format == 1) {
361         if (iflags & RTF_UP)
362             strcat(flags, "U");
363         if (iflags & RTF_HOST)
364             strcat(flags, "H");
365 }
366         if (iflags & RTF_GATEWAY)
367             strcat(flags, "G");
368 #if HAVE_RTF_REJECT
369         if (iflags & RTF_REJECT)
370             strcpy(flags, "!");
371 #endif
372         if (iflags & RTF_REINSTATE)
373             strcat(flags, "R");
374         if (iflags & RTF_DYNAMIC)
375             strcat(flags, "D");
376         if (iflags & RTF_MODIFIED)
377             strcat(flags, "M");
378
379 /* possible collision with 2.0 flags U and H */
380 if (format == 2) {
381         if (iflags & RTCF_DEAD)
382             strcat(flags, "-");
383         if (iflags & RTCF_ONLINK)
384             strcat(flags, "o");
385 }
386         if (iflags & RTCF_NOTIFY)
387             strcat(flags, "n");
388         if (iflags & RTCF_DIRECTDST)
389             strcat(flags, "d");
390         if (iflags & RTCF_TPROXY)
391             strcat(flags, "t");
392         if (iflags & RTCF_FAST)
393             strcat(flags, "f");
394         if (iflags & RTCF_MASQ)
395             strcat(flags, "q");
396         if (iflags & RTCF_SNAT)
397             strcat(flags, "Ns");
398         if (iflags & RTCF_DOREDIRECT)
399             strcat(flags, "r");
400         if (iflags & RTCF_DIRECTSRC)
401             strcat(flags, "i");
402         if (iflags & RTCF_DNAT)
403             strcat(flags, "Nd");
404         if (iflags & RTCF_BROADCAST)
405             strcat(flags, "b");
406         if (iflags & RTCF_MULTICAST)
407             strcat(flags, "m");
408         if (iflags & RTCF_REJECT)
409             strcat(flags, "#");
410         if (iflags & RTCF_LOCAL)
411             strcat(flags, "l");
412         /* Print the info. */
413         if (ext == 1) {
414                 printf("%-15s %-15s %-15s %-5s %-6d %-2d %7d %s\n",
415                        src_addr, dest_addr, gate_addr, flags,
416                        metric, refcnt, use, iface);
417         }
418         if (ext == 2) {
419                 printf("%-15s %-15s %-15s %-5s %5d %-5d %6d %s\n",
420                        src_addr, dest_addr, gate_addr, flags,
421                        mss, window, irtt, iface);
422         }
423         if (format == 1) {
424           if (ext >= 3) {
425                 printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6.6s   %-5d %-6d %-5d %-3d %d\n",
426                        src_addr, dest_addr, gate_addr, flags,
427                  metric, refcnt, use, iface, mss, window, irtt, hh, arp);
428           }
429         }
430         if (format == 2) {
431           if (ext >= 3) {
432                 printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6.6s   %-5d %-6d %-5d %-3d %-3d   %-3d %15s\n",
433                        src_addr, dest_addr, gate_addr, flags,
434                  metric, refcnt, use, iface, mss, window, irtt, tos, hhref, hhuptod, specdst);
435           }
436         }
437     }
438
439     free(fmt);
440     (void) fclose(fp);
441     return (0);
442 }
443
444 int INET_rprint(int options)
445 {
446     int ext = options & FLAG_EXT;
447     int numeric = options & (FLAG_NUM_HOST | FLAG_SYM);
448     int rc = E_INTERN;
449
450     if (options & FLAG_FIB)
451         if ((rc = rprint_fib(ext, numeric)))
452             return (rc);
453     if (options & FLAG_CACHE)
454         rc = rprint_cache(ext, numeric);
455
456     return (rc);
457 }
458
459 #endif                          /* HAVE_AFINET */