📄 interface.c
字号:
/* interface.c * linqianghe@163.com * 2006-10-19 */#include "interface.h"#include "pathnames.h"#include "util.h"#include "sockets.h"#include "net-support.h"#include "af_inet.h"#include "log.h"#include <stdio.h>#include <string.h>#include <errno.h>#include <ctype.h>#include <linux/sockios.h>#include <sys/ioctl.h>#include <stdlib.h>int ife_short; int procnetdev_vsn = 1;static struct interface *int_list, *int_last;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 procnetdev_version(char *buf){ if( strstr(buf, "compressed") ) return 3; if( strstr(buf, "bytes") ) return 2; return 1;}static char *get_name(char *name, char *p){ while( isspace(*p) ) p++; while( *p ){ if( isspace(*p) ) break; if( *p == ':' ){ char *dot = p, *dotname = name; *name++ = *p++; while( isdigit(*p) ) *name++ = *p++; if( *p != ':' ){ p = dot; name = dotname; } if( *p == '\0' ) return NULL; p++; break; } *name++ = *p++; } *name++ = '\0'; return p;}static struct interface *add_interface(char *name){ struct interface *ife, **nextp, *new; for( ife = int_last; ife; ife = ife->prev ){ int n = nstrcmp(ife->name, name); if( n == 0 ) return ife; if( n < 0 ) break; } new(new); safe_strncpy(new->name, name, IFNAMSIZ); nextp = ife ? &ife->next : &int_list; new->prev = ife; new->next = *nextp; if (new->next) new->next->prev = new; else int_last = new; *nextp = new; return new;}static int get_dev_fields(char *bp, struct interface *ife){ switch (procnetdev_vsn) { case 3: sscanf(bp, "%llu %llu %lu %lu %lu %lu %lu %lu %llu %llu %lu %lu %lu %lu %lu %lu", &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, "%llu %llu %lu %lu %lu %lu %llu %llu %lu %lu %lu %lu %lu", &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, "%llu %lu %lu %lu %lu %llu %lu %lu %lu %lu %lu", &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;}static int if_readconf(void){ int numreqs = 30; struct ifconf ifc; struct ifreq *ifr; int n, err = -1; int skfd; skfd = get_socket_for_af( MY_AF_INET ); if( skfd < 0 ){ PR_DEBUG( "warning: no inet socket available: %s\n", strerror(errno) ); skfd = sockets_open(0); if( skfd < 0 ) 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(skfd, SIOCGIFCONF, &ifc) < 0) { PR_ERR( "SIOCGIFCONF: %s", strerror(errno) ); goto out; } if( ifc.ifc_len == sizeof(struct ifreq) * numreqs ){ numreqs += 10; continue; } break; } ifr = ifc.ifc_req; for( n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq) ){ add_interface(ifr->ifr_name); ifr++; } err = 0;out: free(ifc.ifc_buf); return err;}static int if_readlist_proc(char *target){ static int proc_read; FILE *fh; char buf[512]; struct interface *ife; int err; if( proc_read ) return 0; if( !target ) proc_read = 1; fh = fopen( _PATH_PROCNET_DEV, "r" ); if( !fh ){ PR_ERR( "Warning: cannot open %s (%s). Limited output.\n", _PATH_PROCNET_DEV, strerror(errno) ); return if_readconf(); } fgets(buf, sizeof buf, fh); fgets(buf, sizeof buf, fh); procnetdev_vsn = procnetdev_version(buf); err = 0; while( fgets(buf, sizeof buf, fh) ){ char *s, name[IFNAMSIZ]; s = get_name( name, buf ); ife = add_interface( name ); get_dev_fields(s, ife); ife->statistics_valid = 1; if( target && !strcmp(target,name) ) break; } if( ferror(fh) ){ PR_DEBUG( _PATH_PROCNET_DEV ": %s", strerror(errno) ); err = -1; proc_read = 0; } fclose(fh); return err;}int if_readlist(void){ int err = if_readlist_proc(NULL); if( err < 0 ) err = if_readconf(); return err;}int if_fetch(struct interface *ife){ struct ifreq ifr; int fd; char *ifname = ife->name; strcpy(ifr.ifr_name, ifname); if( ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0 ){ PR_DEBUG("SIOCGIFFLAGS error!\n"); return (-1); } ife->flags = ifr.ifr_flags; strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0){ PR_DEBUG("SIOCGIFHWADDR error!\n"); 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 ){ PR_DEBUG("SIOCGIFMETRIC error!\n"); ife->metric = 0; }else{ ife->metric = ifr.ifr_metric; } strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0){ PR_DEBUG("SIOCGIFMTU error!\n"); ife->mtu = 0; }else ife->mtu = ifr.ifr_mtu; strcpy(ifr.ifr_name, ifname); if( ioctl(skfd, SIOCGIFMAP, &ifr) < 0 ){ PR_DEBUG("SIOCGIFMAP error!\n"); 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){ PR_DEBUG("SIOCGIFMAP2 error!\n"); memset(&ife->map, 0, sizeof(struct ifmap)); }else{ ife->map = ifr.ifr_map; } strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) < 0){ PR_DEBUG("SIOCGIFTXQLEN error!\n"); ife->tx_queue_len = -1; /* unknown value */ }else ife->tx_queue_len = ifr.ifr_qlen; fd = get_socket_for_af( MY_AF_INET ); if (fd >= 0) { strcpy(ifr.ifr_name, ifname); ifr.ifr_addr.sa_family = MY_AF_INET; if( ioctl(fd, SIOCGIFADDR, &ifr) == 0 ){ ife->has_ip = 1; ife->addr = ifr.ifr_addr; strcpy(ifr.ifr_name, ifname); if (ioctl(fd, SIOCGIFDSTADDR, &ifr) < 0){ PR_DEBUG("SIOCGIFDSTADDR error!\n"); memset(&ife->dstaddr, 0, sizeof(struct sockaddr)); }else{ ife->dstaddr = ifr.ifr_dstaddr; } strcpy(ifr.ifr_name, ifname); if( ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0 ){ PR_DEBUG("SIOCGIFBRDADDR error!\n"); memset(&ife->broadaddr, 0, sizeof(struct sockaddr)); }else ife->broadaddr = ifr.ifr_broadaddr; strcpy(ifr.ifr_name, ifname); if( ioctl(fd, SIOCGIFNETMASK, &ifr) < 0 ){ PR_DEBUG("SIOCGIFNETMASK error!\n"); memset(&ife->netmask, 0, sizeof(struct sockaddr)); }else ife->netmask = ifr.ifr_netmask; }else{ PR_DEBUG("SIOCGIFADDR error!\n"); memset(&ife->addr, 0, sizeof(struct sockaddr)); } } return 0;}int do_if_fetch(struct interface *ife){ if( if_fetch(ife) < 0 ){ char *errmsg; if( errno == ENODEV ){ errmsg = "Device not found"; }else{ errmsg = strerror(errno); } fprintf(stderr, "%s: error fetching interface information: %s\n", ife->name, errmsg ); return -1; } return 0;}void ife_print_short(struct interface *ptr){ printf("%-5.5s ", ptr->name); printf("%5d %3d", ptr->mtu, ptr->metric); /* If needed, display the interface statistics. */ if (ptr->statistics_valid) { printf("%8llu %6lu %6lu %6lu", ptr->stats.rx_packets, ptr->stats.rx_errors, ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors); printf("%8llu %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"); if (ptr->flags & IFF_DEBUG) printf("D"); if (ptr->flags & IFF_LOOPBACK) printf("L"); if (ptr->flags & IFF_MULTICAST) printf("M");#ifdef HAVE_DYNAMIC if (ptr->flags & IFF_DYNAMIC) printf("d");#endif if (ptr->flags & IFF_PROMISC) printf("P"); if (ptr->flags & IFF_NOTRAILERS) printf("N"); if (ptr->flags & IFF_NOARP) printf("O"); if (ptr->flags & IFF_POINTOPOINT) printf("P"); if (ptr->flags & IFF_SLAVE) printf("s"); if (ptr->flags & IFF_MASTER) printf("m"); if (ptr->flags & IFF_RUNNING) printf("R"); if (ptr->flags & IFF_UP) printf("U"); printf("\n");}void ife_print_long(struct interface *ptr){ struct aftype *ap; struct hwtype *hw; int hf; int can_compress = 0; unsigned long long rx, tx, short_rx, short_tx; char Rext[5]="b"; char Text[5]="b"; ap = get_afntype(ptr->addr.sa_family); if (ap == NULL) ap = get_afntype(0); hf = ptr->type; if (hf == ARPHRD_CSLIP || hf == ARPHRD_CSLIP6) can_compress = 1; hw = get_hwntype(hf); if( hw == NULL ) hw = get_hwntype(-1); printf( "%-9.9s Link encap:%s ", ptr->name, hw->title ); if( hw->print != NULL && ( !(hw_null_address(hw, ptr->hwaddr) && hw->suppress_null_addr))) printf("HWaddr %s ", hw->print((unsigned char *)ptr->hwaddr)); printf("\n"); if( ptr->has_ip ){ printf( " %s addr:%s ", ap->name, ap->sprint(&ptr->addr, 1) ); if( ptr->flags & IFF_POINTOPOINT ){ printf(" P-t-P:%s ", ap->sprint(&ptr->dstaddr, 1)); } if( ptr->flags & IFF_BROADCAST ){ printf(" Bcast:%s ", ap->sprint(&ptr->broadaddr, 1)); } printf(" Mask:%s\n", ap->sprint(&ptr->netmask, 1)); } printf(" "); /* DONT FORGET TO ADD THE FLAGS IN ife_print_short, too */ if( ptr->flags == 0 ) printf("[NO FLAGS] "); if( ptr->flags & IFF_UP ) printf("UP "); if( ptr->flags & IFF_BROADCAST ) printf("BROADCAST "); if( ptr->flags & IFF_DEBUG ) printf("DEBUG "); if( ptr->flags & IFF_LOOPBACK ) printf("LOOPBACK "); if( ptr->flags & IFF_POINTOPOINT ) printf("POINTOPOINT "); if( ptr->flags & IFF_NOTRAILERS ) printf("NOTRAILERS "); if( ptr->flags & IFF_RUNNING ) printf("RUNNING "); if( ptr->flags & IFF_NOARP ) printf("NOARP "); if( ptr->flags & IFF_PROMISC ) printf("PROMISC "); if( ptr->flags & IFF_ALLMULTI ) printf("ALLMULTI "); if( ptr->flags & IFF_SLAVE ) printf("SLAVE "); if( ptr->flags & IFF_MASTER ) printf("MASTER "); if( ptr->flags & IFF_MULTICAST ) printf("MULTICAST "); printf(" MTU:%d Metric:%d", ptr->mtu, ptr->metric ? ptr->metric : 1); printf("\n"); if( ptr->statistics_valid ){ printf(" "); printf("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n", ptr->stats.rx_packets, ptr->stats.rx_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); rx = ptr->stats.rx_bytes; tx = ptr->stats.tx_bytes; short_rx = rx * 10; short_tx = tx * 10; if( rx > 1048576 ) { short_rx /= 1048576; strcpy(Rext, "Mb"); } else if( rx > 1024 ) { short_rx /= 1024; strcpy(Rext, "Kb"); } if( tx > 1048576 ) { short_tx /= 1048576; strcpy(Text, "Mb"); } else if( tx > 1024 ) { short_tx /= 1024; strcpy(Text, "Kb"); } printf(" "); printf("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n", ptr->stats.tx_packets, ptr->stats.tx_errors, ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors, ptr->stats.tx_carrier_errors); printf(" collisions:%lu ", ptr->stats.collisions); if( can_compress ) printf("compressed:%lu ", ptr->stats.tx_compressed); if( ptr->tx_queue_len != -1 ) printf("txqueuelen:%d ", ptr->tx_queue_len); printf("\n "); printf("RX bytes:%llu (%lu.%lu %s) TX bytes:%llu (%lu.%lu %s)\n", rx, (unsigned long)(short_rx / 10), (unsigned long)(short_rx % 10), Rext, tx, (unsigned long)(short_tx / 10), (unsigned long)(short_tx % 10), Text); } if( (ptr->map.irq || ptr->map.mem_start || ptr->map.dma || ptr->map.base_addr) ){ printf(" "); if( ptr->map.irq ) printf("Interrupt:%d ", ptr->map.irq); if( ptr->map.base_addr >= 0x100 ) printf("Base address:0x%x ", ptr->map.base_addr); if( ptr->map.mem_start ){ printf("Memory:%lx-%lx ", ptr->map.mem_start, ptr->map.mem_end); } if (ptr->map.dma) printf("DMA chan:%x ", ptr->map.dma); printf("\n"); } printf("\n");}void ife_print(struct interface *i){ if( ife_short ) ife_print_short( i ); else ife_print_long( i );}int do_if_print(struct interface *ife, void *cookie){ int *opt_a = (int *) cookie; int res; res = do_if_fetch( ife ); if( res >= 0 ){ if( (ife->flags & IFF_UP) || *opt_a ) ife_print(ife); } return res;}struct interface *lookup_interface(char *name){ struct interface *ife = NULL; if( if_readlist_proc(name) < 0 ){ PR_DEBUG( "can't fine the dev: %s\n", name ); return NULL; } ife = add_interface(name); return ife;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -