mirror of
https://github.com/ecki/net-tools.git
synced 2025-04-12 03:53:03 +00:00
The slight indentation here makes the compiler (and maybe readers) think the fmt was intended to be in the "else" body. Tweak it so it's clear to everyone that this is what we want.
459 lines
13 KiB
C
459 lines
13 KiB
C
/*
|
|
$Id: inet_gr.c,v 1.14 2009/07/08 00:24:03 ecki Exp $
|
|
|
|
Modifications:
|
|
1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
|
|
1999-01-01 - Bernd Eckenfels - fixed the routing cache printouts
|
|
1999-10-07 - Kurt Garloff <garloff@suse.de> - do host (instead of network) name
|
|
lookup for gws and hosts
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#if HAVE_AFINET
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <arpa/nameser.h>
|
|
/* #include <net/route.h> realy broken */
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <netdb.h>
|
|
#include <resolv.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include "version.h"
|
|
#include "net-support.h"
|
|
#include "pathnames.h"
|
|
#include "intl.h"
|
|
#include "net-features.h"
|
|
#include "proc.h"
|
|
#include "util.h"
|
|
extern struct aftype inet_aftype;
|
|
|
|
extern char *INET_sprintmask(const struct sockaddr_storage *sap, int numeric,
|
|
unsigned int netmask);
|
|
|
|
int rprint_fib(int ext, int numeric)
|
|
{
|
|
char buff[1024], iface[17], flags[64];
|
|
char gate_addr[128], net_addr[128];
|
|
char mask_addr[128];
|
|
int num, iflags, metric, refcnt, use, mss, window, irtt;
|
|
FILE *fp = fopen(_PATH_PROCNET_ROUTE, "r");
|
|
char *fmt;
|
|
|
|
if (!fp) {
|
|
perror(_PATH_PROCNET_ROUTE);
|
|
printf(_("INET (IPv4) not configured in this system.\n"));
|
|
return 1;
|
|
}
|
|
printf(_("Kernel IP routing table\n"));
|
|
|
|
if (ext == 1)
|
|
printf(_("Destination Gateway Genmask "
|
|
"Flags Metric Ref Use Iface\n"));
|
|
if (ext == 2)
|
|
printf(_("Destination Gateway Genmask "
|
|
"Flags MSS Window irtt Iface\n"));
|
|
if (ext >= 3)
|
|
printf(_("Destination Gateway Genmask "
|
|
"Flags Metric Ref Use Iface "
|
|
"MSS Window irtt\n"));
|
|
|
|
irtt = 0;
|
|
window = 0;
|
|
mss = 0;
|
|
|
|
fmt = proc_gen_fmt(_PATH_PROCNET_ROUTE, 0, fp,
|
|
"Iface", "%15s",
|
|
"Destination", "%127s",
|
|
"Gateway", "%127s",
|
|
"Flags", "%X",
|
|
"RefCnt", "%d",
|
|
"Use", "%d",
|
|
"Metric", "%d",
|
|
"Mask", "%127s",
|
|
"MTU", "%d",
|
|
"Window", "%d",
|
|
"IRTT", "%d",
|
|
NULL);
|
|
/* "%15s %127s %127s %X %d %d %d %127s %d %d %d\n" */
|
|
|
|
if (!fmt)
|
|
return 1;
|
|
|
|
while (fgets(buff, 1023, fp)) {
|
|
struct sockaddr_storage snet_target, snet_gateway, snet_mask;
|
|
struct sockaddr_in *sin_netmask;
|
|
|
|
num = sscanf(buff, fmt,
|
|
iface, net_addr, gate_addr,
|
|
&iflags, &refcnt, &use, &metric, mask_addr,
|
|
&mss, &window, &irtt);
|
|
if (num < 10 || !(iflags & RTF_UP))
|
|
continue;
|
|
|
|
/* Fetch and resolve the target address. */
|
|
(void) inet_aftype.input(1, net_addr, &snet_target);
|
|
|
|
/* Fetch and resolve the gateway address. */
|
|
(void) inet_aftype.input(1, gate_addr, &snet_gateway);
|
|
|
|
/* Fetch and resolve the genmask. */
|
|
(void) inet_aftype.input(1, mask_addr, &snet_mask);
|
|
|
|
sin_netmask = (struct sockaddr_in *)&snet_mask;
|
|
safe_strncpy(net_addr, INET_sprintmask(&snet_target,
|
|
(numeric | 0x8000 | (iflags & RTF_HOST? 0x4000: 0)),
|
|
sin_netmask->sin_addr.s_addr), sizeof(net_addr));
|
|
net_addr[15] = '\0';
|
|
|
|
safe_strncpy(gate_addr, inet_aftype.sprint(&snet_gateway, numeric | 0x4000),
|
|
sizeof(gate_addr));
|
|
gate_addr[15] = '\0';
|
|
|
|
safe_strncpy(mask_addr, inet_aftype.sprint(&snet_mask, 1), sizeof(mask_addr));
|
|
mask_addr[15] = '\0';
|
|
|
|
/* Decode the flags. */
|
|
flags[0] = '\0';
|
|
if (iflags & RTF_UP)
|
|
strcat(flags, "U");
|
|
if (iflags & RTF_GATEWAY)
|
|
strcat(flags, "G");
|
|
#if HAVE_RTF_REJECT
|
|
if (iflags & RTF_REJECT)
|
|
safe_strncpy(flags, "!", sizeof(flags));
|
|
#endif
|
|
if (iflags & RTF_HOST)
|
|
strcat(flags, "H");
|
|
if (iflags & RTF_REINSTATE)
|
|
strcat(flags, "R");
|
|
if (iflags & RTF_DYNAMIC)
|
|
strcat(flags, "D");
|
|
if (iflags & RTF_MODIFIED)
|
|
strcat(flags, "M");
|
|
if (iflags & RTF_DEFAULT)
|
|
strcat(flags, "d");
|
|
if (iflags & RTF_ALLONLINK)
|
|
strcat(flags, "a");
|
|
if (iflags & RTF_ADDRCONF)
|
|
strcat(flags, "c");
|
|
if (iflags & RTF_NONEXTHOP)
|
|
strcat(flags, "o");
|
|
if (iflags & RTF_EXPIRES)
|
|
strcat(flags, "e");
|
|
if (iflags & RTF_CACHE)
|
|
strcat(flags, "c");
|
|
if (iflags & RTF_FLOW)
|
|
strcat(flags, "f");
|
|
if (iflags & RTF_POLICY)
|
|
strcat(flags, "p");
|
|
if (iflags & RTF_LOCAL)
|
|
strcat(flags, "l");
|
|
if (iflags & RTF_MTU)
|
|
strcat(flags, "u");
|
|
if (iflags & RTF_WINDOW)
|
|
strcat(flags, "w");
|
|
if (iflags & RTF_IRTT)
|
|
strcat(flags, "i");
|
|
if (iflags & RTF_NOTCACHED) /* 2.0.36 */
|
|
strcat(flags, "n");
|
|
|
|
/* Print the info. */
|
|
if (ext == 1) {
|
|
#if HAVE_RTF_REJECT
|
|
if (iflags & RTF_REJECT)
|
|
printf("%-15s - %-15s %-5s %-6d - %7d -\n",
|
|
net_addr, mask_addr, flags, metric, use);
|
|
else
|
|
#endif
|
|
printf("%-15s %-15s %-15s %-5s %-6d %-2d %7d %s\n",
|
|
net_addr, gate_addr, mask_addr, flags,
|
|
metric, refcnt, use, iface);
|
|
}
|
|
if (ext == 2) {
|
|
#if HAVE_RTF_REJECT
|
|
if (iflags & RTF_REJECT)
|
|
printf("%-15s - %-15s %-5s - - - -\n",
|
|
net_addr, mask_addr, flags);
|
|
else
|
|
#endif
|
|
printf("%-15s %-15s %-15s %-5s %5d %-5d %6d %s\n",
|
|
net_addr, gate_addr, mask_addr, flags,
|
|
mss, window, irtt, iface);
|
|
}
|
|
if (ext >= 3) {
|
|
#if HAVE_RTF_REJECT
|
|
if (iflags & RTF_REJECT)
|
|
printf("%-15s - %-15s %-5s %-6d - %7d - - - -\n",
|
|
net_addr, mask_addr, flags, metric, use);
|
|
else
|
|
#endif
|
|
printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6.6s %-5d %-6d %d\n",
|
|
net_addr, gate_addr, mask_addr, flags,
|
|
metric, refcnt, use, iface, mss, window, irtt);
|
|
}
|
|
}
|
|
|
|
free(fmt);
|
|
(void) fclose(fp);
|
|
return (0);
|
|
}
|
|
|
|
int rprint_cache(int ext, int numeric)
|
|
{
|
|
char buff[1024], iface[17], flags[64];
|
|
char gate_addr[128], dest_addr[128], specdst[128];
|
|
char src_addr[128];
|
|
struct sockaddr_storage snet;
|
|
unsigned int iflags;
|
|
int num, format, metric, refcnt, use, mss, window, irtt, hh, hhref, hhuptod, arp, tos;
|
|
char *fmt = NULL;
|
|
|
|
FILE *fp = fopen(_PATH_PROCNET_RTCACHE, "r");
|
|
|
|
if (!fp) {
|
|
perror(_PATH_PROCNET_RTCACHE);
|
|
printf(_("INET (IPv4) not configured in this system.\n"));
|
|
return 1;
|
|
}
|
|
|
|
/* Okay, first thing we need to know is the format of the rt_cache.
|
|
* I am aware of two possible layouts:
|
|
* 2.2.0
|
|
* "Iface\tDestination\tGateway \tFlags\t\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tTOS\tHHRef\tHHUptod\tSpecDst"
|
|
* "%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"
|
|
*
|
|
* 2.0.36
|
|
* "Iface\tDestination\tGateway \tFlags\tRefCnt\tUse\tMetric\tSource\t\tMTU\tWindow\tIRTT\tHH\tARP"
|
|
* "%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"
|
|
*/
|
|
|
|
format = proc_guess_fmt(_PATH_PROCNET_RTCACHE, fp, "IRTT",1,"TOS",2,"HHRef",4,"HHUptod",8,"SpecDst",16,"HH",32,"ARP",64,NULL);
|
|
|
|
printf(_("Kernel IP routing cache\n"));
|
|
|
|
switch(format) {
|
|
case -1: /* I/O Error */
|
|
perror(_PATH_PROCNET_RTCACHE);
|
|
exit(-1);
|
|
break;
|
|
case 63: /* 2.2.0 Format */
|
|
format = 2;
|
|
break;
|
|
case 97: /* 2.0.36 Format */
|
|
format = 1;
|
|
break;
|
|
default:
|
|
printf("ERROR: proc_guess_fmt(%s,... returned: %d\n",_PATH_PROCNET_RTCACHE, format);
|
|
break;
|
|
}
|
|
|
|
rewind(fp);
|
|
|
|
if (ext == 1)
|
|
printf(_("Source Destination Gateway "
|
|
"Flags Metric Ref Use Iface\n"));
|
|
if (ext == 2)
|
|
printf(_("Source Destination Gateway "
|
|
"Flags MSS Window irtt Iface\n"));
|
|
|
|
if (format == 1) {
|
|
if (ext >= 3)
|
|
printf(_("Source Destination Gateway "
|
|
"Flags Metric Ref Use Iface "
|
|
"MSS Window irtt HH Arp\n"));
|
|
|
|
fmt = proc_gen_fmt(_PATH_PROCNET_RTCACHE, 0, fp,
|
|
"Iface", "%15s",
|
|
"Destination", "%127s",
|
|
"Gateway", "%127s",
|
|
"Flags", "%X",
|
|
"RefCnt", "%d",
|
|
"Use", "%d",
|
|
"Metric", "%d",
|
|
"Source", "%127s",
|
|
"MTU", "%d",
|
|
"Window", "%d",
|
|
"IRTT", "%d",
|
|
"HH", "%d",
|
|
"ARP", "%d",
|
|
NULL);
|
|
/* "%15s %127s %127s %X %d %d %d %127s %d %d %d %d %d\n" */
|
|
}
|
|
|
|
if (format == 2) {
|
|
if (ext >= 3)
|
|
printf(_("Source Destination Gateway "
|
|
"Flags Metric Ref Use Iface "
|
|
"MSS Window irtt TOS HHRef HHUptod SpecDst\n"));
|
|
|
|
fmt = proc_gen_fmt(_PATH_PROCNET_RTCACHE, 0, fp,
|
|
"Iface", "%15s",
|
|
"Destination", "%127s",
|
|
"Gateway", "%127s",
|
|
"Flags", "%X",
|
|
"RefCnt", "%d",
|
|
"Use", "%d",
|
|
"Metric", "%d",
|
|
"Source", "%127s",
|
|
"MTU", "%d",
|
|
"Window", "%d",
|
|
"IRTT", "%d",
|
|
"TOS", "%d",
|
|
"HHRef", "%d",
|
|
"HHUptod", "%d",
|
|
"SpecDst", "%127s",
|
|
NULL);
|
|
/* "%15s %127s %127s %X %d %d %d %127s %d %d %d %d %d %127s\n" */
|
|
}
|
|
|
|
|
|
irtt = 0;
|
|
window = 0;
|
|
mss = 0;
|
|
hh = 0; hhref = 0; hhuptod = 0;
|
|
arp = 0; tos = 0;
|
|
while (fgets(buff, 1023, fp)) {
|
|
if (format == 1) {
|
|
num = sscanf(buff, fmt,
|
|
iface, dest_addr, gate_addr,
|
|
&iflags, &refcnt, &use, &metric, src_addr,
|
|
&mss, &window, &irtt, &hh, &arp);
|
|
if (num < 12)
|
|
continue;
|
|
}
|
|
if (format == 2) {
|
|
num = sscanf(buff, fmt,
|
|
iface, dest_addr, gate_addr,
|
|
&iflags, &refcnt, &use, &metric, src_addr,
|
|
&mss, &window, &irtt, &tos, &hhref, &hhuptod, &specdst);
|
|
if (num < 12)
|
|
continue;
|
|
}
|
|
|
|
|
|
/* Fetch and resolve the target address. */
|
|
(void) inet_aftype.input(1, dest_addr, &snet);
|
|
safe_strncpy(dest_addr, inet_aftype.sprint(&snet, numeric), sizeof(dest_addr));
|
|
|
|
/* Fetch and resolve the gateway address. */
|
|
(void) inet_aftype.input(1, gate_addr, &snet);
|
|
safe_strncpy(gate_addr, inet_aftype.sprint(&snet, numeric), sizeof(gate_addr));
|
|
|
|
/* Fetch and resolve the source. */
|
|
(void) inet_aftype.input(1, src_addr, &snet);
|
|
safe_strncpy(src_addr, inet_aftype.sprint(&snet, numeric), sizeof(src_addr));
|
|
|
|
/* Fetch and resolve the SpecDst addrerss. */
|
|
(void) inet_aftype.input(1, specdst, &snet);
|
|
safe_strncpy(specdst, inet_aftype.sprint(&snet, numeric), sizeof(specdst));
|
|
|
|
/* Decode the flags. */
|
|
flags[0] = '\0';
|
|
if (format == 1) {
|
|
if (iflags & RTF_UP)
|
|
strcat(flags, "U");
|
|
if (iflags & RTF_HOST)
|
|
strcat(flags, "H");
|
|
}
|
|
if (iflags & RTF_GATEWAY)
|
|
strcat(flags, "G");
|
|
#if HAVE_RTF_REJECT
|
|
if (iflags & RTF_REJECT)
|
|
safe_strncpy(flags, "!", sizeof(flags));
|
|
#endif
|
|
if (iflags & RTF_REINSTATE)
|
|
strcat(flags, "R");
|
|
if (iflags & RTF_DYNAMIC)
|
|
strcat(flags, "D");
|
|
if (iflags & RTF_MODIFIED)
|
|
strcat(flags, "M");
|
|
|
|
/* possible collision with 2.0 flags U and H */
|
|
if (format == 2) {
|
|
if (iflags & RTCF_DEAD)
|
|
strcat(flags, "-");
|
|
if (iflags & RTCF_ONLINK)
|
|
strcat(flags, "o");
|
|
}
|
|
if (iflags & RTCF_NOTIFY)
|
|
strcat(flags, "n");
|
|
if (iflags & RTCF_DIRECTDST)
|
|
strcat(flags, "d");
|
|
if (iflags & RTCF_TPROXY)
|
|
strcat(flags, "t");
|
|
if (iflags & RTCF_FAST)
|
|
strcat(flags, "f");
|
|
if (iflags & RTCF_MASQ)
|
|
strcat(flags, "q");
|
|
if (iflags & RTCF_SNAT)
|
|
strcat(flags, "Ns");
|
|
if (iflags & RTCF_DOREDIRECT)
|
|
strcat(flags, "r");
|
|
if (iflags & RTCF_DIRECTSRC)
|
|
strcat(flags, "i");
|
|
if (iflags & RTCF_DNAT)
|
|
strcat(flags, "Nd");
|
|
if (iflags & RTCF_BROADCAST)
|
|
strcat(flags, "b");
|
|
if (iflags & RTCF_MULTICAST)
|
|
strcat(flags, "m");
|
|
if (iflags & RTCF_REJECT)
|
|
strcat(flags, "#");
|
|
if (iflags & RTCF_LOCAL)
|
|
strcat(flags, "l");
|
|
/* Print the info. */
|
|
if (ext == 1) {
|
|
printf("%-15s %-15s %-15s %-5s %-6d %-2d %7d %s\n",
|
|
src_addr, dest_addr, gate_addr, flags,
|
|
metric, refcnt, use, iface);
|
|
}
|
|
if (ext == 2) {
|
|
printf("%-15s %-15s %-15s %-5s %5d %-5d %6d %s\n",
|
|
src_addr, dest_addr, gate_addr, flags,
|
|
mss, window, irtt, iface);
|
|
}
|
|
if (format == 1) {
|
|
if (ext >= 3) {
|
|
printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6.6s %-5d %-6d %-5d %-3d %d\n",
|
|
src_addr, dest_addr, gate_addr, flags,
|
|
metric, refcnt, use, iface, mss, window, irtt, hh, arp);
|
|
}
|
|
}
|
|
if (format == 2) {
|
|
if (ext >= 3) {
|
|
printf("%-15s %-15s %-15s %-5s %-6d %-3d %6d %-6.6s %-5d %-6d %-5d %-3d %-3d %-3d %15s\n",
|
|
src_addr, dest_addr, gate_addr, flags,
|
|
metric, refcnt, use, iface, mss, window, irtt, tos, hhref, hhuptod, specdst);
|
|
}
|
|
}
|
|
}
|
|
|
|
free(fmt);
|
|
(void) fclose(fp);
|
|
return (0);
|
|
}
|
|
|
|
int INET_rprint(int options)
|
|
{
|
|
int ext = options & FLAG_EXT;
|
|
int numeric = options & (FLAG_NUM_HOST | FLAG_SYM);
|
|
int rc = E_INTERN;
|
|
|
|
if (options & FLAG_FIB)
|
|
if ((rc = rprint_fib(ext, numeric)))
|
|
return (rc);
|
|
if (options & FLAG_CACHE)
|
|
rc = rprint_cache(ext, numeric);
|
|
|
|
return (rc);
|
|
}
|
|
|
|
#endif /* HAVE_AFINET */
|