aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog23
-rw-r--r--Makefile8
-rw-r--r--ifconfig.c421
-rw-r--r--interface.c253
-rw-r--r--interface.h62
-rw-r--r--lib/ash.c58
-rw-r--r--lib/inet6_gr.c1
-rw-r--r--netstat.c132
-rw-r--r--sockets.c86
-rw-r--r--sockets.h3
10 files changed, 491 insertions, 556 deletions
diff --git a/ChangeLog b/ChangeLog
index fa3687e..d4746da 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/Makefile b/Makefile
index 14911af..13ab7c7 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/ifconfig.c b/ifconfig.c
index 547a11c..80e728f 100644
--- a/ifconfig.c
+++ b/ifconfig.c
@@ -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);
+
diff --git a/lib/ash.c b/lib/ash.c
index ff531b8..54ecdf9 100644
--- a/lib/ash.c
+++ b/lib/ash.c
@@ -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
diff --git a/netstat.c b/netstat.c
index 305a63a..ad16516 100644
--- a/netstat.c
+++ b/netstat.c
@@ -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);