📄 interface.c
字号:
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 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 get_dev_fields(char *bp, struct interface *ife){ switch (procnetdev_vsn) { case 3: sscanf(bp, "%Lu %Lu %lu %lu %lu %lu %lu %lu %Lu %Lu %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, "%Lu %Lu %lu %lu %lu %lu %Lu %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.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, "%Lu %lu %lu %lu %lu %Lu %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 inline int procnetdev_version(char *buf){ if (strstr(buf, "compressed")) return 3; if (strstr(buf, "bytes")) return 2; return 1;}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) { fprintf(stderr, _("Warning: cannot open %s (%s). Limited output.\n"), _PATH_PROCNET_DEV, strerror(errno)); return if_readconf(); } fgets(buf, sizeof buf, fh); /* eat line */ 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)) { perror(_PATH_PROCNET_DEV); err = -1; proc_read = 0; } fclose(fh); return err;}static int if_readlist(void) { int err = if_readlist_proc(NULL); if (!err) err = if_readconf(); return err;} static 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;}/* Support for fetching an IPX address */#if HAVE_AFIPXstatic 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(struct interface *ife){ struct ifreq ifr; int fd; char *ifname = ife->name; 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;#ifdef HAVE_HWSLIP if (ife->type == ARPHRD_SLIP || ife->type == ARPHRD_CSLIP || ife->type == ARPHRD_SLIP6 || ife->type == ARPHRD_CSLIP6 || ife->type == ARPHRD_ADAPT) {#ifdef SIOCGOUTFILL strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGOUTFILL, &ifr) < 0) ife->outfill = 0; else ife->outfill = (unsigned int) ifr.ifr_data;#endif#ifdef SIOCGKEEPALIVE strcpy(ifr.ifr_name, ifname); if (ioctl(skfd, SIOCGKEEPALIVE, &ifr) < 0) ife->keepalive = 0; else ife->keepalive = (unsigned int) ifr.ifr_data;#endif }#endif 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 /* IPv4 address? */ fd = get_socket_for_af(AF_INET); if (fd >= 0) { strcpy(ifr.ifr_name, ifname); ifr.ifr_addr.sa_family = 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) memset(&ife->dstaddr, 0, sizeof(struct sockaddr)); else ife->dstaddr = ifr.ifr_dstaddr; strcpy(ifr.ifr_name, ifname); if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0) memset(&ife->broadaddr, 0, sizeof(struct sockaddr)); else ife->broadaddr = ifr.ifr_broadaddr; strcpy(ifr.ifr_name, ifname); if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0) memset(&ife->netmask, 0, sizeof(struct sockaddr)); else ife->netmask = ifr.ifr_netmask; } else memset(&ife->addr, 0, sizeof(struct sockaddr)); }#endif#if HAVE_AFATALK /* DDP address maybe ? */ fd = get_socket_for_af(AF_APPLETALK); if (fd >= 0) { strcpy(ifr.ifr_name, ifname); if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) { ife->ddpaddr = ifr.ifr_addr; ife->has_ddp = 1; } }#endif#if HAVE_AFIPX /* Look for IPX addresses with all framing types */ fd = get_socket_for_af(AF_IPX); if (fd >= 0) { strcpy(ifr.ifr_name, ifname); if (!ipx_getaddr(fd, IPX_FRAME_ETHERII, &ifr)) { ife->has_ipx_bb = 1; ife->ipxaddr_bb = ifr.ifr_addr; } strcpy(ifr.ifr_name, ifname); if (!ipx_getaddr(fd, IPX_FRAME_SNAP, &ifr)) { ife->has_ipx_sn = 1; ife->ipxaddr_sn = ifr.ifr_addr; } strcpy(ifr.ifr_name, ifname); if (!ipx_getaddr(fd, IPX_FRAME_8023, &ifr)) { ife->has_ipx_e3 = 1; ife->ipxaddr_e3 = ifr.ifr_addr; } strcpy(ifr.ifr_name, ifname); if (!ipx_getaddr(fd, IPX_FRAME_8022, &ifr)) { ife->has_ipx_e2 = 1; ife->ipxaddr_e2 = ifr.ifr_addr; } }#endif#if HAVE_AFECONET /* Econet address maybe? */ fd = get_socket_for_af(AF_ECONET); if (fd >= 0) { strcpy(ifr.ifr_name, ifname); if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) { ife->ecaddr = ifr.ifr_addr; ife->has_econet = 1; } }#endif return 0;}static int do_if_fetch(struct interface *ife){ if (if_fetch(ife) < 0) { char *errmsg; if (errno == ENODEV) { /* Give better error message for this case. */ errmsg = _("Device not found"); } else { errmsg = strerror(errno); } fprintf(stderr, _("%s: error fetching interface information: %s\n"), ife->name, errmsg); return -1; } return 0; }/* This structure defines hardware protocols and their handlers. */struct hwtype { const char *name; const char *title; int type; int alen; char *(*print) (unsigned char *); int (*input) (char *, struct sockaddr *); int (*activate) (int fd); int suppress_null_addr;};/* Display an UNSPEC address. */static char *pr_unspec(unsigned char *ptr){ static char buff[64]; char *pos; unsigned int i; pos = buff; for (i = 0; i < sizeof(struct sockaddr); i++) { pos += sprintf(pos, "%02X-", (*ptr++ & 0377)); } buff[strlen(buff) - 1] = '\0'; return (buff);}static struct hwtype unspec_hwtype ={ "unspec", "UNSPEC", -1, 0, pr_unspec, NULL, NULL};static struct hwtype loop_hwtype ={ "loop", "Local Loopback", ARPHRD_LOOPBACK, 0, NULL, NULL, NULL};#if HAVE_HWETHER#include <net/if_arp.h>#include <linux/if_ether.h>static struct hwtype ether_hwtype;/* Display an Ethernet address in readable format. */static char *pr_ether(unsigned char *ptr){ static char buff[64]; snprintf(buff, sizeof(buff), "%02X:%02X:%02X:%02X:%02X:%02X", (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377), (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377) ); return (buff);}#ifdef KEEP_UNUSED/* Input an Ethernet address and convert to binary. */static int in_ether(char *bufp, struct sockaddr *sap){ unsigned char *ptr; char c, *orig; int i; unsigned val; sap->sa_family = ether_hwtype.type; ptr = sap->sa_data; i = 0; orig = bufp; while ((*bufp != '\0') && (i < ETH_ALEN)) { val = 0; c = *bufp++; if (isdigit(c)) val = c - '0'; else if (c >= 'a' && c <= 'f') val = c - 'a' + 10; else if (c >= 'A' && c <= 'F') val = c - 'A' + 10; else {#ifdef DEBUG fprintf(stderr, _("in_ether(%s): invalid ether address!\n"), orig);#endif errno = EINVAL; return (-1); } val <<= 4; c = *bufp; if (isdigit(c)) val |= c - '0'; else if (c >= 'a' && c <= 'f') val |= c - 'a' + 10; else if (c >= 'A' && c <= 'F') val |= c - 'A' + 10; else if (c == ':' || c == 0) val >>= 4; else {#ifdef DEBUG fprintf(stderr, _("in_ether(%s): invalid ether address!\n"), orig);#endif errno = EINVAL; return (-1); } if (c != 0) bufp++; *ptr++ = (unsigned char) (val & 0377); i++; /* We might get a semicolon here - not required. */ if (*bufp == ':') { if (i == ETH_ALEN) {#ifdef DEBUG fprintf(stderr, _("in_ether(%s): trailing : ignored!\n"), orig)#endif ; /* nothing */ } bufp++; } } /* That's it. Any trailing junk? */ if ((i == ETH_ALEN) && (*bufp != '\0')) {#ifdef DEBUG fprintf(stderr, _("in_ether(%s): trailing junk!\n"), orig); errno = EINVAL; return (-1);#endif }#ifdef DEBUG fprintf(stderr, "in_ether(%s): %s\n", orig, pr_ether(sap->sa_data));#endif return (0);}#endif /* KEEP_UNUSED */static struct hwtype ether_hwtype ={ "ether", "Ethernet", ARPHRD_ETHER, ETH_ALEN, pr_ether, NULL /* UNUSED in_ether */, NULL};#endif /* HAVE_HWETHER */#if HAVE_HWPPP#include <net/if_arp.h>#ifdef KEEP_UNUSED/* Start the PPP encapsulation on the file descriptor. */static int do_ppp(int fd){ fprintf(stderr, _("You cannot start PPP with this program.\n"));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -