# Extensively modified from 01/21/94 onwards by
# Alan Cox <A.Cox@swansea.ac.uk>
# Copyright 1993-1994 Swansea University Computer Society
-#
+#
+# Be careful!
+# This Makefile doesn't describe complete dependencies for all include files.
+# If you change include files you might need to do make clean.
#
# {1.20} Bernd Eckenfels: Even more modifications for the new
# package layout
* your option) any later version.
* {1.34} - 19980630 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* - gettext instead of catgets for i18n
+ * 10/1998 - Andi Kleen. Use interface list primitives.
*/
#include "config.h"
printf(_(" Mask:%s\n"), ap->sprint(&ptr->netmask, 1));
#if HAVE_AFINET6
}
+ /* FIXME: should be integrated into interface.c. */
+
if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
while(fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
ptr->mtu, ptr->metric?ptr->metric:1);
/* If needed, display the interface statistics. */
+
+ if (ptr->statistics_valid) {
+ /* XXX: statistics are currently only printed for the original address,
+ * not for the aliases, although strictly speaking they're shared
+ * by all addresses.
+ */
printf(" ");
printf(_("RX packets:%lu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"),
printf(_("compressed:%lu "), ptr->stats.tx_compressed);
if (ptr->tx_queue_len != -1)
printf(_("txqueuelen:%d "), ptr->tx_queue_len);
- printf("\n");
+ printf("\n");
+ }
if ((ptr->map.irq || ptr->map.mem_start || ptr->map.dma ||
ptr->map.base_addr)) {
printf("\n");
}
-static void
-if_print(char *ifname)
+static int do_if_print(struct interface *ife, void *cookie)
{
- struct interface ife;
-
- if (ifname == (char *)NULL) {
- 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;
- char *sep;
- if (fgets(buffer, 256, fd) == NULL)
- break;
- sep = strrchr(buffer, ':');
- if (sep)
- *sep = 0;
- while (*name == ' ') name++;
- if (if_fetch(name, &ife) < 0) {
- fprintf (stderr, _("%s: unknown interface.\n"), name);
- continue;
- }
-
- if (((ife.flags & IFF_UP) == 0) && !opt_a) continue;
- ife_print(&ife);
- }
- fclose(fd);
- } else {
- if (if_fetch(ifname, &ife) < 0)
- fprintf(stderr, _("%s: unknown interface.\n"), ifname);
- else
- ife_print(&ife);
- }
+ int *opt_a = (int *)cookie;
+
+ if (if_fetch(ife->name, ife) < 0) {
+ fprintf (stderr, _("%s: error fetching interface information: %s\n\n"),
+ ife->name, strerror(errno));
+ return -1;
+ }
+ if (!(ife->flags & IFF_UP) && !(*opt_a))
+ return 0;
+ ife_print(ife);
+ return 0;
+}
+
+static void if_print(char *ifname)
+{
+ struct interface *ife;
+
+ if (!ifname) {
+ for_all_interfaces(do_if_print, &opt_a);
+ } else {
+ ife = lookup_interface(ifname);
+ if (!ife)
+ fprintf(stderr, _("%s: interface not found.\n"), ifname);
+ else if (if_fetch(ifname, ife) < 0)
+ fprintf(stderr, _("%s: error fetching interface information: %s"),
+ ifname, strerror(errno));
+ else
+ ife_print(ife);
+ }
}
/* Code to manipulate interface information, shared between ifconfig and
- netstat. */
+ netstat.
+
+ 10/1998 partly rewriten by Andi Kleen to support interface list.
+ I don't claim that the list operations are efficient @).
+*/
#include "config.h"
#include "net-support.h"
#include "pathnames.h"
#include "version.h"
+#include "proc.h"
#include "interface.h"
#include "sockets.h"
+#include "util.h"
+#include "intl.h"
+
+int procnetdev_vsn = 1;
-int procnetdev_vsn = 1;
+static struct interface *int_list;
-static void
-if_getstats(char *ifname, struct interface *ife)
+void add_interface(struct interface *n)
{
- FILE *f = fopen(_PATH_PROCNET_DEV, "r");
- char buf[256];
- char *bp;
+ struct interface *ife, **pp;
- if (f == NULL)
- return;
+ pp = &int_list;
+ for (ife = int_list; ife; pp = &ife->next, ife = ife->next) {
+ /* XXX: should use numerical sort */
+ if (strcmp(ife->name, n->name) > 0)
+ break;
+ }
+ n->next = (*pp);
+ (*pp) = n;
+}
- fgets(buf, 255, f); /* throw away first line of header */
- fgets(buf, 255, f);
+struct interface *lookup_interface(char *name)
+{
+ struct interface *ife;
+ if (!int_list && (if_readlist()) < 0)
+ return NULL;
+ for (ife = int_list; ife; ife = ife->next) {
+ if (!strcmp(ife->name,name))
+ break;
+ }
+ return ife;
+}
- 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);
+int
+for_all_interfaces(int (*doit)(struct interface *, void *), void *cookie)
+{
+ struct interface *ife;
+
+ if (!int_list && (if_readlist() < 0))
+ return -1;
+ for (ife = int_list; ife; ife = ife->next) {
+ int err = doit(ife, cookie);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int if_readconf(void)
+{
+ int numreqs = 30;
+ struct ifconf ifc;
+ struct ifreq *ifr;
+ int n, err = -1;
+
+ int sk;
+ sk = socket(PF_INET, SOCK_DGRAM, 0);
+ if (sk < 0) {
+ perror(_("error opening inet socket"));
+ return -1;
+ }
+
+ ifc.ifc_buf = NULL;
+ for (;;) {
+ ifc.ifc_len = sizeof(struct ifreq) * numreqs;
+ ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len);
+
+ if (ioctl(sk, SIOCGIFCONF, &ifc) < 0) {
+ perror("SIOCGIFCONF");
+ goto out;
+ }
+
+ if (ifc.ifc_len == sizeof(struct ifreq)*numreqs) {
+ /* assume it overflowed and try again */
+ numreqs += 10;
+ continue;
+ }
+ break;
+ }
+
+ for (ifr = ifc.ifc_req,n = 0; n < ifc.ifc_len;
+ n += sizeof(struct ifreq), ifr++) {
+ struct interface *ife;
+
+ ife = lookup_interface(ifr->ifr_name);
+ if (ife)
+ continue;
+
+ new(ife);
+ strcpy(ife->name, ifr->ifr_name);
+ add_interface(ife);
+ }
+ err = 0;
+
+out:
+ free(ifc.ifc_buf);
+ close(sk);
+ return err;
+}
+
+static char *get_name(char *name, char *p)
+{
+ while (isspace(*p)) p++;
+ while (*p) {
+ if (isspace(*p))
+ break;
+ if (*p == ':') { /* could be an alias */
+ char *dot = p, *dotname = name;
+ *name++ = *p++;
+ while (isdigit(*p))
+ *name++ = *p++;
+ if (*p != ':') { /* it wasn't, backup */
+ p = dot;
+ name = dotname;
+ }
+ if (*p == '\0') return NULL;
+ p++;
+ break;
+ }
+ *name++ = *p++;
+ }
+ *name++ = '\0';
+ return p;
+}
+
+static int procnetdev_version(char *buf)
+{
+ if (strstr(buf,"compressed"))
+ return 3;
+ if (strstr(buf,"bytes"))
+ return 2;
+ return 1;
+}
+
+static int get_dev_fields(char *bp, struct interface *ife)
+ {
+ 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;
+ }
+ return 0;
}
+int if_readlist(void)
+{
+ FILE *fh;
+ char buf[512];
+ struct interface *ife;
+ int err;
+
+ fh = fopen(_PATH_PROCNET_DEV,"r");
+ if (!fh) {
+ perror(_PATH_PROCNET_DEV);
+ return -1;
+ }
+
+ fgets(buf,sizeof buf,fh); /* eat line */
+ fgets(buf,sizeof buf,fh);
+
+#if 0 /* pretty, but can't cope with missing fields */
+ fmt = proc_gen_fmt(_PATH_PROCNET_DEV, 1, fh,
+ "face", "", /* parsed separately */
+ "bytes", "%lu",
+ "packets", "%lu",
+ "errs", "%lu",
+ "drop", "%lu",
+ "fifo", "%lu",
+ "frame", "%lu",
+ "compressed", "%lu",
+ "multicast", "%lu",
+ "bytes", "%lu",
+ "packets", "%lu",
+ "errs", "%lu",
+ "drop", "%lu",
+ "fifo", "%lu",
+ "colls", "%lu",
+ "carrier", "%lu",
+ "compressed", "%lu",
+ NULL);
+ if (!fmt)
+ return -1;
+#else
+ procnetdev_vsn = procnetdev_version(buf);
+#endif
+
+ err = 0;
+ while (fgets(buf,sizeof buf,fh)) {
+ char *s;
+
+ new(ife);
+
+ s = get_name(ife->name, buf);
+ get_dev_fields(s, ife);
+ ife->statistics_valid = 1;
+
+ add_interface(ife);
+ }
+ if (ferror(fh)) {
+ perror(_PATH_PROCNET_DEV);
+ err = -1;
+ }
+
+ if (!err)
+ err = if_readconf();
+
+#if 0
+ free(fmt);
+#endif
+ return err;
+}
+
/* Support for fetching an IPX address */
#if HAVE_AFIPX
{
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;
}
#endif
- if_getstats(ifname, ife);
return 0;
}
};
struct interface {
+ struct interface *next;
+
char name[IFNAMSIZ]; /* interface name */
short type; /* if type */
short flags; /* various flags */
int has_ddp;
int has_econet;
char hwaddr[32]; /* HW address */
+ int statistics_valid;
struct user_net_device_stats stats; /* statistics */
};
-extern int procnetdev_vsn;
-
extern int if_fetch(char *ifname, struct interface *ife);
-/* Check for supported features */
+extern int for_all_interfaces(int (*)(struct interface *, void *), void *);
+extern struct interface *lookup_interface(char *name);
+extern int if_readlist(void);
-#if defined(SIOCSIFTXQLEN) && defined(ifr_qlen)
-#define HAVE_TXQUEUELEN
+/* Define for poor glibc2.0 users, the feature check is done at runtime */
+#if !defined(SIOCSIFTXQLEN)
+#define SIOCSIFTXQLEN 0x8943
+#define SIOCGIFTXQLEN 0x8942
#endif
+
+#if !defined(ifr_qlen)
+#define ifr_qlen ifr_ifru.ifru_ivalue
+#endif
+
+#define HAVE_TXQUEUELEN
AFGROBJS = inet_gr.o inet6_gr.o ipx_gr.o ddp_gr.o netrom_gr.o ax25_gr.o rose_gr.o getroute.o
AFSROBJS = inet_sr.o inet6_sr.o netrom_sr.o ipx_sr.o setroute.o
ACTOBJS = slip_ac.o ppp_ac.o activate.o
-VARIA = getargs.o masq_info.o proc.o
+VARIA = getargs.o masq_info.o proc.o util.o
NLSMISC = net-string.o
OBJS = $(NLSMISC) $(VARIA) $(AFOBJS) $(HWOBJS) \
window=0;
mss=0;
- fmt = proc_gen_fmt(_PATH_PROCNET_ROUTE, fp,
+ fmt = proc_gen_fmt(_PATH_PROCNET_ROUTE, 0, fp,
"Iface", "%16s",
"Destination", "%128s",
"Gateway", "%128s",
"Flags Metric Ref Use Iface "
"MSS Window irtt HH Arp\n"));
- fmt = proc_gen_fmt(_PATH_PROCNET_ROUTE, fp,
+ fmt = proc_gen_fmt(_PATH_PROCNET_ROUTE, 0, fp,
"Iface", "%16s",
"Destination", "%128s",
"Gateway", "%128s",
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
+#include <ctype.h>
/* Caller must free return string. */
+
char *
-proc_gen_fmt(char *name, FILE *fh, ...)
+proc_gen_fmt(char *name, int more, FILE *fh, ...)
{
char buf[512], format[512] = "";
- char *title, *head;
+ char *title, *head, *hdr;
va_list ap;
- if (!fgets(buf, sizeof buf, fh))
+ if (!fgets(buf, (sizeof buf)-1, fh))
return NULL;
+ strcat(buf," ");
va_start(ap,fh);
- head = strtok(buf, " \t");
title = va_arg(ap, char *);
- while (title && head) {
+ for (hdr = buf; hdr; ) {
+ while (isspace(*hdr) || *hdr == '|') hdr++;
+ head = hdr;
+ hdr = strpbrk(hdr,"| \t\n");
+ if (hdr) *hdr++ = 0;
+
if (!strcmp(title, head)) {
strcat(format, va_arg(ap, char *));
title = va_arg(ap, char *);
+ if (!title || !head) break;
} else {
- strcat(format, "%*[^ \t]");
+ strcat(format, "%*s"); /* XXX */
}
strcat(format, " ");
- head = strtok(NULL, " \t");
}
va_end(ap);
- if (title) {
+ if (!more && title) {
fprintf(stderr, "warning: %s does not contain required field %s\n",
name, title);
return NULL;
/* Generate a suitable scanf format for a column title line */
-char *proc_gen_fmt(char *name, FILE *fh, ...);
+char *proc_gen_fmt(char *name, int more, FILE *fh, ...);
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include "util.h"
+
+static void oom(void)
+{
+ fprintf(stderr, "out of virtual memory\n");
+ exit(2);
+}
+
+void *xmalloc(size_t sz)
+{
+ void *p = calloc(sz,1);
+ if (!p)
+ oom();
+ return p;
+}
+
+void *xrealloc(void *oldp, size_t sz)
+{
+ void *p = realloc(oldp,sz);
+ if (!p)
+ oom();
+ return p;
+}
--- /dev/null
+#include <stddef.h>
+
+void *xmalloc(size_t sz);
+void *xrealloc(void *p, size_t sz);
+
+#define new(p) ((p) = xmalloc(sizeof(*(p))))
+
to small values for slower devices with a high latency (modem links, ISDN)
to prevent fast bulk transfers from disturbing interactive traffic like
telnet too much.
+.SH NOTES
+Since kernel release 2.2 there are no explicit interface statistics for
+alias interfaces anymore. The statistics printed for the original address
+are shared with all alias addresses on the same device. If you want per-address
+statistics you should add explicit accounting
+rules for the address using the
+.BR ipchains(8)
+command.
+
.SH FILES
.I /proc/net/socket
.br
.I /proc/net/dev
.br
.I /proc/net/if_inet6
-.br
-.I /etc/init.d/network
.SH BUGS
While appletalk DDP and IPX addresses will be displayed they cannot be
altered by this command.
.SH SEE ALSO
-route(8), netstat(8), arp(8), rarp(8)
+route(8), netstat(8), arp(8), rarp(8), ipchains(8)
.SH AUTHORS
Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
.br
Alan Cox, <Alan.Cox@linux.org>
.br
Phil Blundell, <Philip.Blundell@pobox.com>
+.br
+Andi Kleen, <ak@muc.de>
.\" Original: (mdw@tc.cornell.edu & dc6iq@insu1.etec.uni-karlsruhe.de)
.\"
.\" Modified: Bernd.Eckenfels@inka.de
+.\" Modified: Andi Kleen ak@muc.de
.\"
.\"
.TH NETSTAT 8 "20 Feb 1999" "net-tools" "Linux Programmer's Manual"
.TP
.I
SYN_RECV
-The connection is being initialized.
+A connection request has been received from the network.
.TP
.I
FIN_WAIT1
.TP
.I
TIME_WAIT
-The socket is waiting after close for remote shutdown retransmission.
+The socket is waiting after close to handle packets still in the network.
.TP
.I
CLOSED
(this needs to be done by somebody who knows it)
.PP
+.SH NOTES
+Since kernel release 2.2 netstat -i does not display interface statistics for
+alias interfaces anymore. To get per alias interface counters you need to
+setup explicit rules using the
+.BR ipchains(8)
+command.
+
.SH FILES
.ta
.I /etc/services
.BR ipfw (4),
.BR ipfw (8),
.BR ipfwadm (8)
+.BR ipchains (8)
.PP
.SH BUGS
+
/*
* netstat This file contains an implementation of the command
* that helps in debugging the networking modules.
* minor header file misplacement tidy up.
*980411 {1.34} Arnaldo Carvalho i18n: catgets -> gnu gettext, substitution
* of sprintf for snprintf
+ *10/1998 Andi Kleen Use new interface primitives.
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
static void
ife_print(struct interface *ptr)
{
- printf("%-5.5s ", ptr->name);
+ printf("%-7.7s ", ptr->name);
printf("%5d %3d ", ptr->mtu, ptr->metric);
/* If needed, display the interface statistics. */
- printf("%6lu %6lu %6lu %6lu ",
- ptr->stats.rx_packets, ptr->stats.rx_errors,
- ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors);
- printf("%6lu %6lu %6lu %6lu ",
- ptr->stats.tx_packets, ptr->stats.tx_errors,
- ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors);
+ if (ptr->statistics_valid) {
+ printf("%6lu %6lu %6lu %6lu ",
+ ptr->stats.rx_packets, ptr->stats.rx_errors,
+ ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors);
+ printf("%6lu %6lu %6lu %6lu ",
+ ptr->stats.tx_packets, ptr->stats.tx_errors,
+ ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors);
+ } else {
+ printf("%-56s", " - no statistics available -");
+ }
if (ptr->flags == 0) printf(_("[NO FLAGS]"));
if (ptr->flags & IFF_ALLMULTI) printf("A");
if (ptr->flags & IFF_BROADCAST) printf("B");
printf("\n");
}
+static int do_if_print(struct interface *ife, void *cookie)
+{
+ int *opt_a = (int *)cookie;
+ if (if_fetch(ife->name, ife) < 0) {
+ fprintf (stderr, _("%s: unknown interface.\n"), ife->name);
+ return -1;
+ }
+ if (!(ife->flags & IFF_UP) && !(*opt_a))
+ return 0;
+ ife_print(ife);
+ return 0;
+}
+
static int
iface_info(void)
{
- struct interface ife;
- char buffer[256];
- FILE *fd;
-
- printf(_("Kernel Interface table\n"));
- printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flags\n"));
-
- /* Create a channel to the NET kernel. */
if ((skfd = sockets_open()) < 0) {
perror("socket");
exit(1);
}
- fd = fopen(_PATH_PROCNET_DEV, "r");
- fgets(buffer, 256, fd); /* chuck first two lines */
- fgets(buffer, 256, fd);
- while (!feof(fd)) {
- char *name = buffer;
- char *sep;
- if (fgets(buffer, 256, fd) == NULL)
- break;
- sep = strrchr(buffer, ':');
- if (sep)
- *sep = 0;
- while (*name == ' ') name++;
- if (if_fetch(name, &ife) < 0) {
- fprintf(stderr, _("%s: unknown interface.\n"),
- name);
- continue;
- }
-
- if (((ife.flags & IFF_UP) == 0) && !flag_all) continue;
- ife_print(&ife);
+ printf(_("Kernel Interface table\n"));
+ printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flags\n"));
+
+ if (for_all_interfaces(do_if_print, &flag_all) < 0) {
+ perror(_("missing interface information"));
+ exit(1);
}
- fclose(fd);
close(skfd);
-
+ skfd = -1;
+
return 0;
}
char *title;
char *out;
enum State type;
+ unsigned long val;
};
static enum State state;