net-tools/net-tools-1.60-cont-buff.patch

299 lines
8.1 KiB
Diff

# net-tools-1.60-cont-buff.patch
# This Patch fixes the -ic option from netstat
# without destroying the proc_read buffer function
# if any questions occur contact my at fdg@suse.de
Index: net-tools-1.60/ifconfig.c
===================================================================
--- net-tools-1.60.orig/ifconfig.c
+++ net-tools-1.60/ifconfig.c
@@ -108,7 +108,7 @@ static int if_print(char *ifname)
printf(_("Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg\n"));
if (!ifname) {
- res = for_all_interfaces(do_if_print, &opt_a);
+ res = for_all_interfaces(do_if_print, &opt_a, 0);
} else {
struct interface *ife;
@@ -1081,7 +1081,7 @@ static int set_ifstate(char *parent, uns
pt.flag = flag;
memset(searcher, 0, sizeof(searcher));
i = for_all_interfaces((int (*)(struct interface *,void *))do_ifcmd,
- &pt);
+ &pt, 0);
if (i == -1)
return -1;
if (i == 1)
Index: net-tools-1.60/include/interface.h
===================================================================
--- net-tools-1.60.orig/include/interface.h
+++ net-tools-1.60/include/interface.h
@@ -63,10 +63,10 @@ struct interface {
extern int if_fetch(struct interface *ife);
-extern int for_all_interfaces(int (*)(struct interface *, void *), void *);
+extern int for_all_interfaces(int (*)(struct interface *, void *), void *, int);
extern int free_interface_list(void);
extern struct interface *lookup_interface(char *name);
-extern int if_readlist(void);
+extern int if_readlist(int);
extern int do_if_fetch(struct interface *ife);
extern int do_if_print(struct interface *ife, void *cookie);
@@ -76,6 +76,8 @@ extern void ife_print(struct interface *
extern int ife_short;
extern const char *if_port_text[][4];
+extern int get_iface_count(void);
+char *get_iface_name(int index);
/* Defines for poor glibc2.0 users, the feature check is done at runtime */
#if !defined(SIOCSIFTXQLEN)
Index: net-tools-1.60/lib/interface.c
===================================================================
--- net-tools-1.60.orig/lib/interface.c
+++ net-tools-1.60/lib/interface.c
@@ -90,7 +90,7 @@ int ife_field = 5;
static struct interface *int_list, *int_last;
-static int if_readlist_proc(char *);
+static int if_readlist_proc(char *, int);
static struct interface *add_interface(char *name)
{
@@ -120,17 +120,17 @@ struct interface *lookup_interface(char
{
struct interface *ife = NULL;
- if (if_readlist_proc(name) < 0)
+ if (if_readlist_proc(name, 0) < 0)
return NULL;
ife = add_interface(name);
return ife;
}
-int for_all_interfaces(int (*doit) (struct interface *, void *), void *cookie)
+int for_all_interfaces(int (*doit) (struct interface *, void *), void *cookie, int flag_cacheof)
{
struct interface *ife;
- if (!int_list && (if_readlist() < 0))
+ if (!int_list && (if_readlist(flag_cacheof) < 0))
return -1;
for (ife = int_list; ife; ife = ife->next) {
int err = doit(ife, cookie);
@@ -162,6 +162,7 @@ int free_interface_list(void)
while ((ife = int_list) != NULL) {
int_list = ife->next;
free(ife);
+ int_last = NULL;
}
return 0;
}
@@ -315,7 +316,7 @@ static int get_dev_fields(char *bp, stru
return 0;
}
-static int if_readlist_proc(char *target)
+static int if_readlist_proc(char *target, int flag_cacheof)
{
static int proc_read;
FILE *fh;
@@ -323,10 +324,12 @@ static int if_readlist_proc(char *target
struct interface *ife;
int err;
- if (proc_read)
- return 0;
- if (!target)
- proc_read = 1;
+ if (proc_read) {
+ return 0;
+ }
+ if ((!target) && (flag_cacheof == 0)) {
+ proc_read = 1;
+ }
fh = fopen(_PATH_PROCNET_DEV, "r");
if (!fh) {
@@ -386,9 +389,9 @@ static int if_readlist_proc(char *target
return err;
}
-int if_readlist(void)
+int if_readlist(int flag_cacheof)
{
- int err = if_readlist_proc(NULL);
+ int err = if_readlist_proc(NULL, flag_cacheof);
if (!err)
err = if_readconf();
return err;
@@ -910,3 +913,26 @@ void ife_print(struct interface *i)
else
ife_print_long(i);
}
+
+int get_iface_count(void)
+{
+ int num_iface = 0;
+ struct interface* ife = int_list;
+
+ for (; ife != NULL; ife=ife->next) {
+ num_iface++;
+ }
+
+ return num_iface;
+}
+
+char* get_iface_name(int index) {
+ struct interface* ife = int_list;
+
+ while ((index-- > 0) && (ife->next != NULL)) {
+ ife = ife->next;
+ }
+
+ return ife->name;
+}
+
Index: net-tools-1.60/netstat.c
===================================================================
--- net-tools-1.60.orig/netstat.c
+++ net-tools-1.60/netstat.c
@@ -153,9 +153,24 @@ int flag_exp = 1;
int flag_prg = 0;
int flag_arg = 0;
int flag_ver = 0;
+int flag_cacheof = 0;
FILE *procinfo;
+struct iface_cache {
+ char iface_name[16+1];
+ int rxok;
+ int rxerr;
+ int rxdrp;
+ int rxovr;
+ int txok;
+ int txerr;
+ int txdrp;
+ int txovr;
+};
+
+static struct iface_cache* mycache;
+
#define INFO_GUTS1(file,name,proc) \
procinfo = fopen((file), "r"); \
if (procinfo == NULL) { \
@@ -253,6 +268,77 @@ static char prg_cache_loaded = 0;
/* NOT working as of glibc-2.0.7: */
#undef DIRENT_HAVE_D_TYPE_WORKS
+int do_if_cache_print(struct interface *ife, void *cookie)
+{
+ int *opt_a = (int *) cookie;
+ int res;
+ int num_iface = get_iface_count();
+ int i;
+
+ struct iface_cache* cur_iface_cache = NULL;
+
+ res = do_if_fetch(ife);
+
+ if (mycache == NULL) {
+ mycache = malloc(num_iface * sizeof(struct iface_cache));
+ if (mycache == NULL) { exit(-1); }
+ memset(mycache, '\0', num_iface * sizeof(struct iface_cache));
+ for (i=0; i < num_iface; i++) {
+ strncpy(mycache[i].iface_name, get_iface_name(i), 16);
+ }
+ }
+
+ for (i=0; i < num_iface; i++) {
+ if (strcmp(ife->name, mycache[i].iface_name) == 0) {
+ cur_iface_cache = &mycache[i];
+ break;
+ }
+ }
+
+ if (cur_iface_cache != NULL) {
+ int swap;
+
+ swap = ife->stats.rx_packets;
+ ife->stats.rx_packets -= cur_iface_cache->rxok;
+ cur_iface_cache->rxok = swap;
+
+ swap = ife->stats.rx_errors;
+ ife->stats.rx_errors -= cur_iface_cache->rxerr;
+ cur_iface_cache->rxerr = swap;
+
+ swap = ife->stats.rx_dropped;
+ ife->stats.rx_dropped -= cur_iface_cache->rxdrp;
+ cur_iface_cache->rxdrp = swap;
+
+ swap = ife->stats.rx_fifo_errors;
+ ife->stats.rx_fifo_errors -= cur_iface_cache->rxovr;
+ cur_iface_cache->rxovr = swap;
+
+ swap = ife->stats.tx_packets;
+ ife->stats.tx_packets -= cur_iface_cache->txok;
+ cur_iface_cache->txok = swap;
+
+ swap = ife->stats.tx_errors;
+ ife->stats.tx_errors -= cur_iface_cache->txerr;
+ cur_iface_cache->txerr = swap;
+
+ swap = ife->stats.tx_dropped;
+ ife->stats.tx_dropped -= cur_iface_cache->txdrp;
+ cur_iface_cache->txdrp = swap;
+
+ swap = ife->stats.tx_fifo_errors;
+ ife->stats.tx_fifo_errors -= cur_iface_cache->txovr;
+ cur_iface_cache->txovr = swap;
+ }
+
+ if (res >= 0) {
+ if ((ife->flags & IFF_UP) || *opt_a) {
+ ife_print(ife);
+ }
+ }
+ return res;
+}
+
static void prg_cache_add(int inode, char *name)
{
unsigned hi = PRG_HASHIT(inode);
@@ -1458,10 +1544,20 @@ static int iface_info(void)
get_max_ifacename();
- if (for_all_interfaces(do_if_print, &flag_all) < 0) {
- perror(_("missing interface information"));
- exit(1);
+ if (flag_cacheof == 1) {
+ if (for_all_interfaces(do_if_cache_print, &flag_all, flag_cacheof) < 0) {
+ perror(_("missing interface information"));
+ exit(1);
+ }
+ }
+ else {
+ if (for_all_interfaces(do_if_print, &flag_all, flag_cacheof) < 0) {
+ perror(_("missing interface information"));
+ exit(1);
+ }
}
+
+
if (flag_cnt)
free_interface_list();
else {
@@ -1588,6 +1684,7 @@ int main
flag_lst++;
break;
case 'c':
+ flag_cacheof = 1;
flag_cnt++;
break;