0
0
mirror of https://github.com/ecki/net-tools.git synced 2025-04-12 03:53:03 +00:00
Files
Mike Frysinger ebb9d9e151 inet_gr: tweak formatting to avoid confusing the compiler
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.
2021-01-04 00:37:37 -05:00

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 */