Commit ab1a31ff authored by Klaas Freitag's avatar Klaas Freitag

Print 2.1 interface aliases in netstat and ifconfig.

parent d2d7772b
......@@ -21,7 +21,10 @@
# 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
......
......@@ -15,6 +15,7 @@
* 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"
......@@ -179,6 +180,8 @@ ife_print(struct interface *ptr)
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],
......@@ -264,6 +267,12 @@ ife_print(struct interface *ptr)
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"),
......@@ -284,7 +293,8 @@ ife_print(struct interface *ptr)
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)) {
......@@ -305,40 +315,37 @@ ife_print(struct interface *ptr)
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"
......@@ -30,106 +34,276 @@
#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
......@@ -146,9 +320,6 @@ 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;
......@@ -265,6 +436,5 @@ if_fetch(char *ifname, struct interface *ife)
}
#endif
if_getstats(ifname, ife);
return 0;
}
......@@ -29,6 +29,8 @@ struct user_net_device_stats
};
struct interface {
struct interface *next;
char name[IFNAMSIZ]; /* interface name */
short type; /* if type */
short flags; /* various flags */
......@@ -55,15 +57,24 @@ struct interface {
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
......@@ -21,7 +21,7 @@ AFOBJS = unix.o inet.o inet6.o ax25.o ipx.o ddp.o ipx.o netrom.o af.o rose.o ec
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) \
......
......@@ -62,7 +62,7 @@ int rprint_fib(int ext, int numeric)
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",
......@@ -181,7 +181,7 @@ int rprint_cache(int ext, int numeric)
"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",
......
......@@ -3,34 +3,41 @@
#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, ...);
#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;
}
#include <stddef.h>
void *xmalloc(size_t sz);
void *xrealloc(void *p, size_t sz);
#define new(p) ((p) = xmalloc(sizeof(*(p))))
......@@ -167,22 +167,31 @@ Set the length of the transmit queue of the device. It is useful to set this
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>
......@@ -4,6 +4,7 @@
.\" 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"
......@@ -212,7 +213,7 @@ The socket is actively attempting to establish a connection.
.TP
.I
SYN_RECV
The connection is being initialized.
A connection request has been received from the network.
.TP
.I
FIN_WAIT1
......@@ -225,7 +226,7 @@ remote end.
.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
......@@ -371,6 +372,13 @@ to the socket.
(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
......@@ -431,6 +439,7 @@ to the socket.
.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.
......@@ -44,6 +45,7 @@
* 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
......@@ -1066,15 +1068,19 @@ static int ipx_info(void)
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");
......@@ -1089,47 +1095,38 @@ ife_print(struct interface *ptr)
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;
}
......
......@@ -25,6 +25,7 @@ struct entry {
char *title;
char *out;
enum State type;
unsigned long val;
};
static enum State state;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment