diff options
author | Phil Blundell <philb@gnu.org> | 1998-03-02 22:02:22 +0000 |
---|---|---|
committer | Phil Blundell <philb@gnu.org> | 1998-03-02 22:02:22 +0000 |
commit | b612eddf20531cb51380746df765055b89092f38 (patch) | |
tree | e4ff00c4f0cc6b74b48a817dde782e03726cfdc2 | |
parent | Merge more changes from my private tree, mostly ifconfig tidyups. (diff) | |
download | net-tools-b612eddf20531cb51380746df765055b89092f38.tar.gz net-tools-b612eddf20531cb51380746df765055b89092f38.tar.bz2 net-tools-b612eddf20531cb51380746df765055b89092f38.zip |
Update for new kernel, plus more changes.
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | ifconfig.c | 421 | ||||
-rw-r--r-- | interface.c | 253 | ||||
-rw-r--r-- | interface.h | 62 | ||||
-rw-r--r-- | lib/ash.c | 58 | ||||
-rw-r--r-- | lib/inet6_gr.c | 1 | ||||
-rw-r--r-- | netstat.c | 132 | ||||
-rw-r--r-- | sockets.c | 86 | ||||
-rw-r--r-- | sockets.h | 3 |
10 files changed, 491 insertions, 556 deletions
@@ -1,3 +1,26 @@ +Mon Mar 2 20:45:29 1998 Philip Blundell <Philip.Blundell@pobox.com> + + * interface.c: New file, contains code shared between ifconfig and + netstat. + * sockets.c: Likewise. + + * ifconfig.c (ife_print): Add support for latest /proc/net/dev + format. + + * ifconfig.c (ipx_getaddr): Reformat. + + * lib/inet6_gr.c: Don't #include <netinet/ip6.h> + +Fri Feb 27 20:43:34 1998 Philip Blundell <philb@gnu.org> + + * ifconfig.c (if_print): When displaying all interfaces, get list + from /proc/net/dev rather than using obsolete SIOCGIFCONF. + (main): Protect portsel code with #ifdef. + + * lib/ash.c: Tidy up. + (pr_ash): Print the address in canonical Ash notation, and accept + FF termination. + Fri Feb 13 18:47:09 1998 Philip Blundell <philb@gnu.org> * ifconfig.c (ife_print): Only print the broadcast addreess if the @@ -172,8 +172,8 @@ nlsdir: subdirs: @for i in $(SUBDIRS); do $(MAKE) -C $$i $(MDEFINES) ; done -ifconfig: $(NET-LIB) ifconfig.o - $(CC) $(LDFLAGS) -o ifconfig ifconfig.o $(NLIB) $(RESLIB) +ifconfig: $(NET-LIB) ifconfig.o interface.o sockets.o + $(CC) $(LDFLAGS) -o ifconfig ifconfig.o interface.o sockets.o $(NLIB) $(RESLIB) hostname: hostname.o $(CC) $(LDFLAGS) -o hostname hostname.o @@ -187,8 +187,8 @@ arp: $(NET-LIB) arp.o rarp: $(NET-LIB) rarp.o $(CC) $(LDFLAGS) -o rarp rarp.o $(NLIB) -netstat: $(NET-LIB) netstat.o statistics.o - $(CC) $(LDFLAGS) -o netstat netstat.o statistics.o $(NLIB) $(RESLIB) +netstat: $(NET-LIB) netstat.o statistics.o interface.o sockets.o + $(CC) $(LDFLAGS) -o netstat netstat.o statistics.o interface.o sockets.o $(NLIB) $(RESLIB) installbin: install -o root -g root -m 0755 arp ${BASEDIR}/sbin @@ -3,7 +3,7 @@ * that either displays or sets the characteristics of * one or more of the system's networking interfaces. * - * Version: ifconfig 1.32 (1998-02-09) + * Version: ifconfig 1.33 (1998-03-02) * * Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> * and others. Copyright 1993 MicroWalt Corporation @@ -76,64 +76,6 @@ struct in6_ifreq { #define HAVE_TXQUEUELEN #endif -/* This is from <linux/netdevice.h>. */ - -struct user_net_device_stats -{ - unsigned long rx_packets; /* total packets received */ - unsigned long tx_packets; /* total packets transmitted */ - unsigned long rx_bytes; /* total bytes received */ - unsigned long tx_bytes; /* total bytes transmitted */ - unsigned long rx_errors; /* bad packets received */ - unsigned long tx_errors; /* packet transmit problems */ - unsigned long rx_dropped; /* no space in linux buffers */ - unsigned long tx_dropped; /* no space available in linux */ - unsigned long multicast; /* multicast packets received */ - unsigned long collisions; - - /* detailed rx_errors: */ - unsigned long rx_length_errors; - unsigned long rx_over_errors; /* receiver ring buff overflow */ - unsigned long rx_crc_errors; /* recved pkt with crc error */ - unsigned long rx_frame_errors; /* recv'd frame alignment error */ - unsigned long rx_fifo_errors; /* recv'r fifo overrun */ - unsigned long rx_missed_errors; /* receiver missed packet */ - /* detailed tx_errors */ - unsigned long tx_aborted_errors; - unsigned long tx_carrier_errors; - unsigned long tx_fifo_errors; - unsigned long tx_heartbeat_errors; - unsigned long tx_window_errors; -}; - -struct interface { - char name[IFNAMSIZ]; /* interface name */ - short type; /* if type */ - short flags; /* various flags */ - int metric; /* routing metric */ - int mtu; /* MTU value */ - int tx_queue_len; /* transmit queue length */ - struct ifmap map; /* hardware setup */ - struct sockaddr addr; /* IP address */ - struct sockaddr dstaddr; /* P-P IP address */ - struct sockaddr broadaddr; /* IP broadcast address */ - struct sockaddr netmask; /* IP network mask */ - struct sockaddr ipxaddr_bb; /* IPX network address */ - struct sockaddr ipxaddr_sn; /* IPX network address */ - struct sockaddr ipxaddr_e3; /* IPX network address */ - struct sockaddr ipxaddr_e2; /* IPX network address */ - struct sockaddr ddpaddr; /* Appletalk DDP address */ - int has_ip; - int has_ipx_bb; - int has_ipx_sn; - int has_ipx_e3; - int has_ipx_e2; - int has_ax25; - int has_ddp; - char hwaddr[32]; /* HW address */ - struct user_net_device_stats stats; /* statistics */ -}; - static const char *if_port_text[][4] = { /* Keep in step with <linux/netdevice.h> */ { "unknown", NULL , NULL, NULL }, @@ -153,33 +95,16 @@ static const char *if_port_text[][4] = { #include "pathnames.h" #include "version.h" #include "net-locale.h" +#include "interface.h" +#include "sockets.h" char *Release = RELEASE, - *Version = "ifconfig 1.32 (1998-02-09)"; + *Version = "ifconfig 1.33 (1998-03-02)"; int opt_a = 0; /* show all interfaces */ int opt_i = 0; /* show the statistics */ int opt_v = 0; /* debugging output flag */ -int skfd = -1; /* generic raw socket desc. */ -#if HAVE_AFIPX -int ipx_sock = -1; /* IPX socket */ -#endif -#if HAVE_AFAX25 -int ax25_sock = -1; /* AX.25 socket */ -#endif -#if HAVE_AFROSE -int rose_sock = -1; /* Rose socket */ -#endif -#if HAVE_AFINET -int inet_sock = -1; /* INET socket */ -#endif -#if HAVE_AFINET6 -int inet6_sock = -1; /* INET6 socket */ -#endif -#if HAVE_AFATALK -int ddp_sock = -1; /* Appletalk DDP socket */ -#endif int addr_family = 0; /* currently selected AF */ @@ -189,7 +114,7 @@ ife_print(struct interface *ptr) struct aftype *ap; struct hwtype *hw; int hf; - char *dispname=NLS_CATSAVE (catfd, ifconfigSet, ifconfig_over, "overruns"); + int can_compress = 0; static struct aftype *ipxtype=NULL, *ddptype=NULL; #if HAVE_AFINET6 FILE *f; @@ -208,18 +133,11 @@ ife_print(struct interface *ptr) hf=ptr->type; - if(strncmp(ptr->name,"lo",2)==0) + if (strncmp(ptr->name, "lo", 2) == 0) hf=255; - if(hf==ARPHRD_CSLIP || hf==ARPHRD_CSLIP6) - { -#if NLS - /* NLS must free dispname */ - free (dispname); -#endif - /* Overrun got reused: BAD - fix later */ - dispname=NLS_CATSAVE (catfd, ifconfigSet, ifconfig_compress, "compressed"); - } + if (hf==ARPHRD_CSLIP || hf==ARPHRD_CSLIP6) + can_compress = 1; hw = get_hwntype(hf); if (hw == NULL) hw = get_hwntype(-1); @@ -341,19 +259,24 @@ ife_print(struct interface *ptr) printf(" "); printf(NLS_CATGETS(catfd, ifconfigSet, ifconfig_rx, - "RX packets:%lu errors:%lu dropped:%lu %s:%lu frame:%lu\n"), + "RX packets:%lu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"), ptr->stats.rx_packets, ptr->stats.rx_errors, - ptr->stats.rx_dropped, dispname, ptr->stats.rx_fifo_errors, + ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors, ptr->stats.rx_frame_errors); + if (can_compress) + printf(" compressed:%lu\n", ptr->stats.rx_compressed); printf(" "); printf(NLS_CATGETS(catfd, ifconfigSet, ifconfig_tx, - "TX packets:%lu errors:%lu dropped:%lu %s:%lu carrier:%lu\n"), + "TX packets:%lu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"), ptr->stats.tx_packets, ptr->stats.tx_errors, - ptr->stats.tx_dropped, dispname, ptr->stats.tx_fifo_errors, + ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors, ptr->stats.tx_carrier_errors); - printf(" collisions:%lu\n", ptr->stats.collisions); + printf(" collisions:%lu ", ptr->stats.collisions); + if (can_compress) + printf("compressed:%lu ", ptr->stats.tx_compressed); + printf("\n"); if ((ptr->map.irq || ptr->map.mem_start || ptr->map.dma || ptr->map.base_addr)) { @@ -376,258 +299,35 @@ ife_print(struct interface *ptr) } printf("\n"); - -#if NLS - /* NLS must free dispname */ - free (dispname); -#endif -} - - -static void if_getstats(char *ifname, struct interface *ife) -{ - FILE *f = fopen(_PATH_PROCNET_DEV, "r"); - char buf[256]; - int have_byte_counters = 0; - char *bp; - if (f==NULL) - return; - fgets(buf, 255, f); /* throw away first line of header */ - fgets(buf, 255, f); - if (strstr(buf, "bytes")) have_byte_counters=1; - while(fgets(buf,255,f)) { - bp=buf; - while(*bp&&isspace(*bp)) - bp++; - if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':') { - bp=strchr(bp,':'); - bp++; - if (have_byte_counters) { - sscanf(bp,"%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", - &ife->stats.rx_bytes, - &ife->stats.rx_packets, - &ife->stats.rx_errors, - &ife->stats.rx_dropped, - &ife->stats.rx_fifo_errors, - &ife->stats.rx_frame_errors, - - &ife->stats.tx_bytes, - &ife->stats.tx_packets, - &ife->stats.tx_errors, - &ife->stats.tx_dropped, - &ife->stats.tx_fifo_errors, - &ife->stats.collisions, - - &ife->stats.tx_carrier_errors - ); - } else { - sscanf(bp,"%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", - &ife->stats.rx_packets, - &ife->stats.rx_errors, - &ife->stats.rx_dropped, - &ife->stats.rx_fifo_errors, - &ife->stats.rx_frame_errors, - - &ife->stats.tx_packets, - &ife->stats.tx_errors, - &ife->stats.tx_dropped, - &ife->stats.tx_fifo_errors, - &ife->stats.collisions, - - &ife->stats.tx_carrier_errors - ); - ife->stats.rx_bytes = 0; - ife->stats.tx_bytes = 0; - } - break; - } - } - fclose(f); -} - -/* Support for fetching an IPX address */ - -#if HAVE_AFIPX -static int ipx_getaddr(int sock, int ft, struct ifreq *ifr) -{ - ((struct sockaddr_ipx *)&ifr->ifr_addr)->sipx_type=ft; - return ioctl(sock, SIOCGIFADDR, ifr); -} -#endif - -/* Fetch the interface configuration from the kernel. */ -static int -if_fetch(char *ifname, struct interface *ife) -{ - struct ifreq ifr; - - memset((char *) ife, 0, sizeof(struct interface)); - strcpy(ife->name, ifname); - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1); - ife->flags = ifr.ifr_flags; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) - memset(ife->hwaddr, 0, 32); - else - memcpy(ife->hwaddr,ifr.ifr_hwaddr.sa_data,8); - - ife->type=ifr.ifr_hwaddr.sa_family; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) - ife->metric = 0; - else - ife->metric = ifr.ifr_metric; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) - ife->mtu = 0; - else - ife->mtu = ifr.ifr_mtu; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) - memset(&ife->map, 0, sizeof(struct ifmap)); - else - memcpy(&ife->map,&ifr.ifr_map,sizeof(struct ifmap)); - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) - memset(&ife->map, 0, sizeof(struct ifmap)); - else - ife->map = ifr.ifr_map; - -#ifdef HAVE_TXQUEUELEN - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) < 0) - ife->tx_queue_len = -1; /* unknown value */ - else - ife->tx_queue_len = ifr.ifr_qlen; -#else - ife->tx_queue_len = -1; /* unknown value */ -#endif - -#if HAVE_AFINET - strcpy(ifr.ifr_name, ifname); - if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFDSTADDR, &ifr) < 0) - memset(&ife->dstaddr, 0, sizeof(struct sockaddr)); - else - ife->dstaddr = ifr.ifr_dstaddr; - - strcpy(ifr.ifr_name, ifname); - if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFBRDADDR, &ifr) < 0) - memset(&ife->broadaddr, 0, sizeof(struct sockaddr)); - else - ife->broadaddr = ifr.ifr_broadaddr; - - strcpy(ifr.ifr_name, ifname); - if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFNETMASK, &ifr) < 0) - memset(&ife->netmask, 0, sizeof(struct sockaddr)); - else - ife->netmask = ifr.ifr_netmask; - - strcpy(ifr.ifr_name, ifname); - if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0) - memset(&ife->addr, 0, sizeof(struct sockaddr)); - else - ife->addr = ifr.ifr_addr; -#endif - -#if HAVE_AFATALK - /* DDP address maybe ? */ - strcpy(ifr.ifr_name, ifname); - if (ddp_sock >= 0 && ioctl(ddp_sock, SIOCGIFADDR, &ifr) == 0) { - ife->ddpaddr=ifr.ifr_addr; - ife->has_ddp=1; - } -#endif - -#if HAVE_AFIPX - /* Look for IPX addresses with all framing types */ - strcpy(ifr.ifr_name, ifname); - if (ipx_sock >= 0) { - if (!ipx_getaddr(ipx_sock, IPX_FRAME_ETHERII, &ifr)) { - ife->has_ipx_bb=1; - ife->ipxaddr_bb=ifr.ifr_addr; - } - strcpy(ifr.ifr_name, ifname); - if (!ipx_getaddr(ipx_sock, IPX_FRAME_SNAP, &ifr)) { - ife->has_ipx_sn=1; - ife->ipxaddr_sn=ifr.ifr_addr; - } - strcpy(ifr.ifr_name, ifname); - if(!ipx_getaddr(ipx_sock, IPX_FRAME_8023, &ifr)) { - ife->has_ipx_e3=1; - ife->ipxaddr_e3=ifr.ifr_addr; - } - strcpy(ifr.ifr_name, ifname); - if(!ipx_getaddr(ipx_sock, IPX_FRAME_8022, &ifr)) { - ife->has_ipx_e2=1; - ife->ipxaddr_e2=ifr.ifr_addr; - } - } -#endif - - if_getstats(ifname,ife); - return(0); } - static void if_print(char *ifname) { struct interface ife; if (ifname == (char *)NULL) { - int i; - struct ifconf ifc; - struct ifreq *ifr; - ifc.ifc_buf = NULL; - ifc.ifc_len = 0; - if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0 || ifc.ifc_len == 0) { - int n = 2, s; - ifc.ifc_buf = NULL; - do { - n *= 2; - ifc.ifc_buf = realloc(ifc.ifc_buf, (ifc.ifc_len = s = - n*sizeof(struct ifreq))); - if (ifc.ifc_buf == NULL) { - fprintf(stderr, "Out of memory\n"); - exit(1); - } - - if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) { - perror("SIOCGIFCONF"); - return; - } - } while (ifc.ifc_len == s); - } else { - ifc.ifc_buf = malloc(ifc.ifc_len); - if (ifc.ifc_buf == NULL) { - fprintf(stderr, "Out of memory.\n"); - exit(1); - } - if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) { - perror("SIOCGIFCONF"); - return; - } - } - ifr = ifc.ifc_req; - for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) { - if (if_fetch(ifr->ifr_name, &ife) < 0) { + FILE *fd = fopen(_PATH_PROCNET_DEV, "r"); + char buffer[256]; + fgets(buffer, 256, fd); /* chuck first two lines */ + fgets(buffer, 256, fd); + while (!feof(fd)) { + char *name = buffer; + if (fgets(buffer, 256, fd) == NULL) + break; + buffer[6] = 0; + while (*name == ' ') name++; + if (if_fetch(name, &ife) < 0) { fprintf(stderr, NLS_CATGETS(catfd, ifconfigSet, ifconfig_unkn, "%s: unknown interface.\n"), - ifr->ifr_name); + name); continue; } if (((ife.flags & IFF_UP) == 0) && !opt_a) continue; ife_print(&ife); } - free(ifc.ifc_buf); + fclose(fd); } else { if (if_fetch(ifname, &ife) < 0) fprintf(stderr, NLS_CATGETS(catfd, ifconfigSet, @@ -722,65 +422,6 @@ version(void) exit(1); } -static int sockets_open() -{ -#if HAVE_AFINET - inet_sock = socket(AF_INET, SOCK_DGRAM, 0); -#endif - -#if HAVE_AFINET6 - inet6_sock = socket(AF_INET6, SOCK_DGRAM, 0); -#endif - -#if HAVE_AFIPX - ipx_sock = socket(AF_IPX, SOCK_DGRAM, 0); -#endif - -#if HAVE_AFAX25 - ax25_sock = socket(AF_AX25, SOCK_DGRAM, 0); -#endif - -#if HAVE_ROSE - rose_sock = socket(AF_ROSE, SOCK_DGRAM, 0); -#endif - -#if HAVE_AFATALK - ddp_sock = socket(AF_APPLETALK, SOCK_DGRAM, 0); -#endif - - /* - * Now pick any (existing) useful socket family for generic queries - */ - -#if HAVE_AFINET - if (inet_sock != -1) return inet_sock; -#endif - -#if HAVE_AFINET6 - if (inet6_sock != -1) return inet6_sock; -#endif - -#if HAVE_AFIPX - if (ipx_sock != -1) return ipx_sock; -#endif - -#if HAVE_AFAX25 - if (ax25_sock != -1) return ax25_sock; -#endif - -#if HAVE_AFROSE - if (rose_sock != -1) return rose_sock; -#endif - -#if HAVE_AFATALK - if (ddp_sock != -1) return ddp_sock; -#endif - - /* We have no address families. */ - fprintf(stderr, "No usable address families found.\n"); - return -1; -} - int main(int argc, char **argv) { diff --git a/interface.c b/interface.c new file mode 100644 index 0000000..a36f73a --- /dev/null +++ b/interface.c @@ -0,0 +1,253 @@ +/* Code to manipulate interface information, shared between ifconfig and + netstat. */ + +#include "config.h" + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netinet/in.h> +#include <net/if.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <ctype.h> + +#if HAVE_AFIPX +#include "ipx.h" +#endif +#include "net-support.h" +#include "pathnames.h" +#include "version.h" +#include "net-locale.h" + +#include "interface.h" +#include "sockets.h" + +int procnetdev_vsn = 1; + +static void +if_getstats(char *ifname, struct interface *ife) +{ + FILE *f = fopen(_PATH_PROCNET_DEV, "r"); + char buf[256]; + char *bp; + + if (f == NULL) + return; + + fgets(buf, 255, f); /* throw away first line of header */ + fgets(buf, 255, f); + + if (strstr(buf, "compressed")) + procnetdev_vsn = 3; + else + if (strstr(buf, "bytes")) + procnetdev_vsn = 2; + + while (fgets(buf, 255, f)) { + bp=buf; + while(*bp && isspace(*bp)) + bp++; + if (strncmp(bp, ifname, strlen(ifname)) == 0 && + bp[strlen(ifname)] == ':') { + bp = strchr(bp, ':'); + bp++; + switch (procnetdev_vsn) { + case 3: + sscanf(bp, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", + &ife->stats.rx_bytes, + &ife->stats.rx_packets, + &ife->stats.rx_errors, + &ife->stats.rx_dropped, + &ife->stats.rx_fifo_errors, + &ife->stats.rx_frame_errors, + &ife->stats.rx_compressed, + &ife->stats.rx_multicast, + + &ife->stats.tx_bytes, + &ife->stats.tx_packets, + &ife->stats.tx_errors, + &ife->stats.tx_dropped, + &ife->stats.tx_fifo_errors, + &ife->stats.collisions, + &ife->stats.tx_carrier_errors, + &ife->stats.tx_compressed + ); + break; + case 2: + sscanf(bp, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", + &ife->stats.rx_bytes, + &ife->stats.rx_packets, + &ife->stats.rx_errors, + &ife->stats.rx_dropped, + &ife->stats.rx_fifo_errors, + &ife->stats.rx_frame_errors, + + &ife->stats.tx_bytes, + &ife->stats.tx_packets, + &ife->stats.tx_errors, + &ife->stats.tx_dropped, + &ife->stats.tx_fifo_errors, + &ife->stats.collisions, + &ife->stats.tx_carrier_errors + ); + ife->stats.rx_multicast = 0; + break; + case 1: + sscanf(bp, "%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", + &ife->stats.rx_packets, + &ife->stats.rx_errors, + &ife->stats.rx_dropped, + &ife->stats.rx_fifo_errors, + &ife->stats.rx_frame_errors, + + &ife->stats.tx_packets, + &ife->stats.tx_errors, + &ife->stats.tx_dropped, + &ife->stats.tx_fifo_errors, + &ife->stats.collisions, + &ife->stats.tx_carrier_errors + ); + ife->stats.rx_bytes = 0; + ife->stats.tx_bytes = 0; + ife->stats.rx_multicast = 0; + break; + } + break; + } + } + fclose(f); +} + +/* Support for fetching an IPX address */ + +#if HAVE_AFIPX +static int ipx_getaddr(int sock, int ft, struct ifreq *ifr) +{ + ((struct sockaddr_ipx *)&ifr->ifr_addr)->sipx_type=ft; + return ioctl(sock, SIOCGIFADDR, ifr); +} +#endif + +/* Fetch the interface configuration from the kernel. */ +int +if_fetch(char *ifname, struct interface *ife) +{ + struct ifreq ifr; + + memset((char *) ife, 0, sizeof(struct interface)); + strcpy(ife->name, ifname); + + strcpy(ifr.ifr_name, ifname); + if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) return(-1); + ife->flags = ifr.ifr_flags; + + strcpy(ifr.ifr_name, ifname); + if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) + memset(ife->hwaddr, 0, 32); + else + memcpy(ife->hwaddr,ifr.ifr_hwaddr.sa_data,8); + + ife->type=ifr.ifr_hwaddr.sa_family; + + strcpy(ifr.ifr_name, ifname); + if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) + ife->metric = 0; + else + ife->metric = ifr.ifr_metric; + + strcpy(ifr.ifr_name, ifname); + if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) + ife->mtu = 0; + else + ife->mtu = ifr.ifr_mtu; + + strcpy(ifr.ifr_name, ifname); + if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) + memset(&ife->map, 0, sizeof(struct ifmap)); + else + memcpy(&ife->map,&ifr.ifr_map,sizeof(struct ifmap)); + + strcpy(ifr.ifr_name, ifname); + if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0) + memset(&ife->map, 0, sizeof(struct ifmap)); + else + ife->map = ifr.ifr_map; + +#ifdef HAVE_TXQUEUELEN + strcpy(ifr.ifr_name, ifname); + if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) < 0) + ife->tx_queue_len = -1; /* unknown value */ + else + ife->tx_queue_len = ifr.ifr_qlen; +#else + ife->tx_queue_len = -1; /* unknown value */ +#endif + +#if HAVE_AFINET + strcpy(ifr.ifr_name, ifname); + if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFDSTADDR, &ifr) < 0) + memset(&ife->dstaddr, 0, sizeof(struct sockaddr)); + else + ife->dstaddr = ifr.ifr_dstaddr; + + strcpy(ifr.ifr_name, ifname); + if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFBRDADDR, &ifr) < 0) + memset(&ife->broadaddr, 0, sizeof(struct sockaddr)); + else + ife->broadaddr = ifr.ifr_broadaddr; + + strcpy(ifr.ifr_name, ifname); + if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFNETMASK, &ifr) < 0) + memset(&ife->netmask, 0, sizeof(struct sockaddr)); + else + ife->netmask = ifr.ifr_netmask; + + strcpy(ifr.ifr_name, ifname); + if (inet_sock < 0 || ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0) + memset(&ife->addr, 0, sizeof(struct sockaddr)); + else + ife->addr = ifr.ifr_addr; +#endif + +#if HAVE_AFATALK + /* DDP address maybe ? */ + strcpy(ifr.ifr_name, ifname); + if (ddp_sock >= 0 && ioctl(ddp_sock, SIOCGIFADDR, &ifr) == 0) { + ife->ddpaddr=ifr.ifr_addr; + ife->has_ddp=1; + } +#endif + +#if HAVE_AFIPX + /* Look for IPX addresses with all framing types */ + strcpy(ifr.ifr_name, ifname); + if (ipx_sock >= 0) { + if (!ipx_getaddr(ipx_sock, IPX_FRAME_ETHERII, &ifr)) { + ife->has_ipx_bb=1; + ife->ipxaddr_bb=ifr.ifr_addr; + } + strcpy(ifr.ifr_name, ifname); + if (!ipx_getaddr(ipx_sock, IPX_FRAME_SNAP, &ifr)) { + ife->has_ipx_sn=1; + ife->ipxaddr_sn=ifr.ifr_addr; + } + strcpy(ifr.ifr_name, ifname); + if(!ipx_getaddr(ipx_sock, IPX_FRAME_8023, &ifr)) { + ife->has_ipx_e3=1; + ife->ipxaddr_e3=ifr.ifr_addr; + } + strcpy(ifr.ifr_name, ifname); + if(!ipx_getaddr(ipx_sock, IPX_FRAME_8022, &ifr)) { + ife->has_ipx_e2=1; + ife->ipxaddr_e2=ifr.ifr_addr; + } + } +#endif + + if_getstats(ifname, ife); + return 0; +} diff --git a/interface.h b/interface.h new file mode 100644 index 0000000..9f31076 --- /dev/null +++ b/interface.h @@ -0,0 +1,62 @@ +struct user_net_device_stats +{ + unsigned long rx_packets; /* total packets received */ + unsigned long tx_packets; /* total packets transmitted */ + unsigned long rx_bytes; /* total bytes received */ + unsigned long tx_bytes; /* total bytes transmitted */ + unsigned long rx_errors; /* bad packets received */ + unsigned long tx_errors; /* packet transmit problems */ + unsigned long rx_dropped; /* no space in linux buffers */ + unsigned long tx_dropped; /* no space available in linux */ + unsigned long rx_multicast; /* multicast packets received */ + unsigned long rx_compressed; + unsigned long tx_compressed; + unsigned long collisions; + + /* detailed rx_errors: */ + unsigned long rx_length_errors; + unsigned long rx_over_errors; /* receiver ring buff overflow */ + unsigned long rx_crc_errors; /* recved pkt with crc error */ + unsigned long rx_frame_errors; /* recv'd frame alignment error */ + unsigned long rx_fifo_errors; /* recv'r fifo overrun */ + unsigned long rx_missed_errors; /* receiver missed packet */ + /* detailed tx_errors */ + unsigned long tx_aborted_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; + unsigned long tx_heartbeat_errors; + unsigned long tx_window_errors; +}; + +struct interface { + char name[IFNAMSIZ]; /* interface name */ + short type; /* if type */ + short flags; /* various flags */ + int metric; /* routing metric */ + int mtu; /* MTU value */ + int tx_queue_len; /* transmit queue length */ + struct ifmap map; /* hardware setup */ + struct sockaddr addr; /* IP address */ + struct sockaddr dstaddr; /* P-P IP address */ + struct sockaddr broadaddr; /* IP broadcast address */ + struct sockaddr netmask; /* IP network mask */ + struct sockaddr ipxaddr_bb; /* IPX network address */ + struct sockaddr ipxaddr_sn; /* IPX network address */ + struct sockaddr ipxaddr_e3; /* IPX network address */ + struct sockaddr ipxaddr_e2; /* IPX network address */ + struct sockaddr ddpaddr; /* Appletalk DDP address */ + int has_ip; + int has_ipx_bb; + int has_ipx_sn; + int has_ipx_e3; + int has_ipx_e2; + int has_ax25; + int has_ddp; + char hwaddr[32]; /* HW address */ + struct user_net_device_stats stats; /* statistics */ +}; + +extern int procnetdev_vsn; + +extern int if_fetch(char *ifname, struct interface *ife); + @@ -22,10 +22,10 @@ #include "net-locale.h" #ifndef ARPHRD_ASH -#error Your C library does not support Ash +#error No support for Ash on this system #endif -#define ASH_ALEN 32 +#define ASH_ALEN 64 extern struct hwtype ash_hwtype; @@ -37,16 +37,12 @@ pr_ash(unsigned char *ptr) char *p = buff; unsigned int i = 0; - while (ptr[i] != 0xc9 && (i < ASH_ALEN)) { - sprintf(p, "%x:", ptr[i]); - i++; - p += 2; - } - - if (p != buff) - p[-1] = 0; - else - p[0] = 0; + p[0] = '['; p++; + while (ptr[i] != 0xc9 && ptr[i] != 0xff && (i < ASH_ALEN)) + sprintf (p++, "%01", ptr[i++]); + *(p++) = ']'; + *p = 0; + return buff; } @@ -57,8 +53,8 @@ pr_sash(struct sockaddr *sap) static char buf[64]; if (sap->sa_family == 0xFFFF || sap->sa_family == 0) - return strncpy(buf, "[NONE SET]", 64); - return(pr_ash(sap->sa_data)); + return strncpy (buf, "[NONE SET]", 64); + return pr_ash (sap->sa_data); } @@ -71,25 +67,25 @@ in_ash(char *bufp, struct sockaddr *sap) sap->sa_family = ash_hwtype.type; ptr = sap->sa_data; - while (bufp && i < 32) { - char *next; - int hop = strtol(bufp, &next, 16); - ptr[i++] = hop; - switch (*next) { - case ':': - bufp = next + 1; - break; - case 0: - bufp = NULL; - break; - default: - fprintf(stderr, "Malformed Ash address"); - memset(ptr, 0xc9, 32); - return -1; - } + while (bufp && i < ASH_ALEN) { + char *next; + int hop = strtol (bufp, &next, 16); + ptr[i++] = hop; + switch (*next) { + case ':': + bufp = next + 1; + break; + case 0: + bufp = NULL; + break; + default: + fprintf (stderr, "Malformed Ash address"); + memset (ptr, 0xc9, ASH_ALEN); + return -1; + } } - while (i < 32) + while (i < ASH_ALEN) ptr[i++] = 0xc9; return 0; diff --git a/lib/inet6_gr.c b/lib/inet6_gr.c index 385d6c6..aea63fa 100644 --- a/lib/inet6_gr.c +++ b/lib/inet6_gr.c @@ -17,7 +17,6 @@ #include <string.h> #include <stdio.h> #include <unistd.h> -#include <netinet/ip6.h> #ifndef __GLIBC__ #include <netinet6/ipv6_route.h> /* glibc doesn't have this */ #endif @@ -6,7 +6,7 @@ * NET-3 Networking Distribution for the LINUX operating * system. * - * Version: netstat 1.25 (1998-02-09) + * Version: netstat 1.26 (1998-03-02) * * Authors: Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de> * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org> @@ -97,7 +97,7 @@ typedef enum { #include "lib/net-features.h" char *Release = RELEASE, - *Version = "netstat 1.25 (1998-02-13)", + *Version = "netstat 1.26 (1998-03-02)", *Signature = "Fred Baumgarten <dc6iq@insu1.etec.uni-karlsruhe.de> and Alan Cox."; @@ -1156,134 +1156,6 @@ ife_print(struct interface *ptr) printf("\n"); } -static void if_getstats(char *ifname, struct interface *ife) -{ - FILE *f=fopen("/proc/net/dev","r"); - int have_byte_counters=0; - char buf[256]; - char *bp; - if(f==NULL) - return; - fgets(buf, 255, f); /* throw away first line of header */ - fgets(buf, 255, f); - if (strstr(buf, "bytes")) have_byte_counters=1; - while(fgets(buf,255,f)) - { - bp=buf; - while(*bp&&isspace(*bp)) - bp++; - if(strncmp(bp,ifname,strlen(ifname))==0 && bp[strlen(ifname)]==':') - { - bp=strchr(bp,':'); - bp++; - if (have_byte_counters) { - sscanf(bp,"%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", - &ife->stats.rx_bytes, - &ife->stats.rx_packets, - &ife->stats.rx_errors, - &ife->stats.rx_dropped, - &ife->stats.rx_fifo_errors, - &ife->stats.rx_frame_errors, - - &ife->stats.tx_bytes, - &ife->stats.tx_packets, - &ife->stats.tx_errors, - &ife->stats.tx_dropped, - &ife->stats.tx_fifo_errors, - &ife->stats.collisions, - - &ife->stats.tx_carrier_errors - ); - } else { - sscanf(bp,"%ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", - &ife->stats.rx_packets, - &ife->stats.rx_errors, - &ife->stats.rx_dropped, - &ife->stats.rx_fifo_errors, - &ife->stats.rx_frame_errors, - - &ife->stats.tx_packets, - &ife->stats.tx_errors, - &ife->stats.tx_dropped, - &ife->stats.tx_fifo_errors, - &ife->stats.collisions, - - &ife->stats.tx_carrier_errors - ); - ife->stats.rx_bytes = 0; - ife->stats.tx_bytes = 0; - } - fclose(f); - return; - } - } - fclose(f); -} - -/* Fetch the inteface configuration from the kernel. */ -static int -if_fetch(char *ifname, struct interface *ife) -{ - struct ifreq ifr; - - memset((char *) ife, 0, sizeof(struct interface)); - strcpy(ife->name, ifname); - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0) { - fprintf(stderr, "SIOCGIFFLAGS: %s\n", strerror(errno)); - return(-1); - } - ife->flags = ifr.ifr_flags; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFADDR, &ifr) < 0) { - memset(&ife->addr, 0, sizeof(struct sockaddr)); - } else ife->addr = ifr.ifr_addr; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) { - memset(&ife->hwaddr, 0, sizeof(struct sockaddr)); - } else ife->hwaddr = ifr.ifr_addr; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0) { - ife->metric = 0; - } else ife->metric = ifr.ifr_metric; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0) { - ife->mtu = 0; - } else ife->mtu = ifr.ifr_mtu; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFDSTADDR, &ifr) < 0) { - memset(&ife->dstaddr, 0, sizeof(struct sockaddr)); - } else ife->dstaddr = ifr.ifr_dstaddr; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) < 0) { - memset(&ife->broadaddr, 0, sizeof(struct sockaddr)); - } else ife->broadaddr = ifr.ifr_broadaddr; - - strcpy(ifr.ifr_name, ifname); - if (ioctl(skfd, SIOCGIFNETMASK, &ifr) < 0) { - memset(&ife->netmask, 0, sizeof(struct sockaddr)); - } else { - memcpy(ife->netmask.sa_data, &ifr.ifr_data, sizeof(struct sockaddr)); - } - - if_getstats(ifname,ife); -/* strcpy(ifr.ifr_name, ifname); - ifr.ifr_data = (caddr_t) &ife->stats; - if (ioctl(skfd, SIOCGIFSTATS, &ifr) < 0) { - memset(&ife->stats, 0, sizeof(struct dev_stats)); - } - */ - return(0); -} - - static int iface_info(void) { diff --git a/sockets.c b/sockets.c new file mode 100644 index 0000000..f7f501b --- /dev/null +++ b/sockets.c @@ -0,0 +1,86 @@ +/* sockets.c */ + +#include <sys/socket.h> +#include <stdio.h> + +#include "config.h" +#include "sockets.h" + +int skfd = -1; /* generic raw socket desc. */ +#if HAVE_AFIPX +int ipx_sock = -1; /* IPX socket */ +#endif +#if HAVE_AFAX25 +int ax25_sock = -1; /* AX.25 socket */ +#endif +#if HAVE_AFROSE +int rose_sock = -1; /* Rose socket */ +#endif +#if HAVE_AFINET +int inet_sock = -1; /* INET socket */ +#endif +#if HAVE_AFINET6 +int inet6_sock = -1; /* INET6 socket */ +#endif +#if HAVE_AFATALK +int ddp_sock = -1; /* Appletalk DDP socket */ +#endif + +int sockets_open(void) +{ +#if HAVE_AFINET + inet_sock = socket(AF_INET, SOCK_DGRAM, 0); +#endif + +#if HAVE_AFINET6 + inet6_sock = socket(AF_INET6, SOCK_DGRAM, 0); +#endif + +#if HAVE_AFIPX + ipx_sock = socket(AF_IPX, SOCK_DGRAM, 0); +#endif + +#if HAVE_AFAX25 + ax25_sock = socket(AF_AX25, SOCK_DGRAM, 0); +#endif + +#if HAVE_ROSE + rose_sock = socket(AF_ROSE, SOCK_DGRAM, 0); +#endif + +#if HAVE_AFATALK + ddp_sock = socket(AF_APPLETALK, SOCK_DGRAM, 0); +#endif + + /* + * Now pick any (existing) useful socket family for generic queries + */ + +#if HAVE_AFINET + if (inet_sock != -1) return inet_sock; +#endif + +#if HAVE_AFINET6 + if (inet6_sock != -1) return inet6_sock; +#endif + +#if HAVE_AFIPX + if (ipx_sock != -1) return ipx_sock; +#endif + +#if HAVE_AFAX25 + if (ax25_sock != -1) return ax25_sock; +#endif + +#if HAVE_AFROSE + if (rose_sock != -1) return rose_sock; +#endif + +#if HAVE_AFATALK + if (ddp_sock != -1) return ddp_sock; +#endif + + /* We have no address families. */ + fprintf(stderr, "No usable address families found.\n"); + return -1; +} diff --git a/sockets.h b/sockets.h new file mode 100644 index 0000000..864f4ce --- /dev/null +++ b/sockets.h @@ -0,0 +1,3 @@ +extern int skfd, ipx_sock, ax25_sock, rose_sock, inet_sock, inet6_sock, ddp_sock; + +extern int sockets_open(void); |