⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drivers.c

📁 ifstat源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				   O_RDONLY, data->errbuf)) == NULL) {    ifstat_error("kvm_openfiles: %s", data->errbuf);    return 0;  }  memset(&kvm_syms, 0, sizeof(kvm_syms));  kvm_syms[0].n_name = "_ifnet";  if (kvm_nlist(data->kvmfd, kvm_syms) < 0 ||      kvm_syms[0].n_value == 0) {    kvm_syms[0].n_name = "ifnet";    if (kvm_nlist(data->kvmfd, kvm_syms) < 0) {      ifstat_error("kvm_nlist: %s", data->errbuf);      return 0;    }  }    if (kvm_syms[0].n_value == 0) {    ifstat_error("kvm: no _ifnet or ifnet symbol found");    return 0;  }    if (kvm_read(data->kvmfd, (unsigned long) kvm_syms[0].n_value,	       &ifnetaddr, sizeof(ifnetaddr)) < 0) {    ifstat_error("kvm_read(ifnetaddr): %s", data->errbuf);    return 0;  }    if (ifnetaddr == 0) {    ifstat_error("kvm: ifnetaddr has null address.");    return 0;  }    data->ifnetaddr = ifnetaddr;  driver->data = (void *) data;  return 1;}#ifdef HAVE_IFNET_IF_NEXT#define IFNET_NEXT(ifnet) (ifnet).if_next#else#ifdef HAVE_IFNET_IF_LINK#define if_list if_link#endif#ifndef TAILQ_NEXT#define TAILQ_NEXT(elm, field)    ((elm)->field.tqe_next)#endif#define IFNET_NEXT(ifnet) TAILQ_NEXT((&ifnet), if_list)#endifstatic int kvm_map_ifs(struct ifstat_driver *driver,		       int (*mapf)(char *name, struct ifnet *ifnet, void *data),		       void *mdata) {  struct kvm_driver_data *data = driver->data;  unsigned long ifaddr;  struct ifnet ifnet;#ifndef HAVE_IFNET_IF_XNAME  char ifname[IFNAMSIZ + 1];#endif  char interface[IFNAMSIZ + 10];  for (ifaddr = data->ifnetaddr; ifaddr != 0;       ifaddr = (unsigned long) IFNET_NEXT(ifnet)) {    if (kvm_read(data->kvmfd, ifaddr, &ifnet, sizeof(ifnet)) < 0) {      ifstat_error("kvm_read: %s", data->errbuf);      return 0;    }#ifdef HAVE_IFNET_IF_XNAME    memcpy(interface, ifnet.if_xname, sizeof(interface));    interface[sizeof(interface) - 1] = '\0';#else       if (kvm_read(data->kvmfd, (unsigned long) ifnet.if_name, &ifname, sizeof(ifname)) < 0) {      ifstat_error("kvm_read: %s", data->errbuf);      return 0;    }    ifname[sizeof(ifname) - 1] = '\0';    sprintf(interface, "%s%d", ifname, ifnet.if_unit);#endif    if (!mapf(interface, &ifnet, mdata))      return 0;  }  return 1;}static int kvm_map_stats(char *name, struct ifnet *ifnet, void *data) {  struct ifstat_data *cur;      if ((cur = ifstat_get_interface((struct ifstat_list *) data, name)) == NULL)    return 1;  ifstat_set_interface_stats(cur, ifnet->if_ibytes, ifnet->if_obytes);  return 1;}static int kvm_get_stats(struct ifstat_driver *driver,			 struct ifstat_list *ifs) {  return kvm_map_ifs(driver, &kvm_map_stats, (void *) ifs);}static int kvm_map_scan(char *name, struct ifnet *ifnet, void *data) {  examine_interface((struct ifstat_list *) data, name,		    ifnet->if_flags, ifnet->if_type);  return 1;}static int kvm_scan_interfaces(struct ifstat_driver *driver,			       struct ifstat_list *ifs) {  return kvm_map_ifs(driver, &kvm_map_scan, (void *) ifs);} static void kvm_close_driver(struct ifstat_driver *driver) {  kvm_close(((struct kvm_driver_data *) driver->data)->kvmfd);}#endif#ifdef USE_IFMIBstatic int get_ifcount() {  int ifcount[] = {    CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT  };  int count, size;    size = sizeof(count);  if (sysctl(ifcount, sizeof(ifcount) / sizeof(int), &count, &size, NULL, 0) < 0) {    ifstat_perror("sysctl(net.link.generic.ifmib.ifcount)");    return -1;  }  return count;}static int get_ifdata(int index, struct ifmibdata * ifmd) {  int ifinfo[] = {    CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, index, IFDATA_GENERAL  };  int size = sizeof(*ifmd);  if (sysctl(ifinfo, sizeof(ifinfo) / sizeof(int), ifmd, &size, NULL, 0) < 0)    return 0;  return 1;}static int ifmib_scan_interfaces(struct ifstat_driver *driver,				 struct ifstat_list *ifs) {  int count, i;  struct ifmibdata ifmd;    if ((count = get_ifcount()) <= 0)    return 0;  for (i = 1; i <= count; i++) {    if (!get_ifdata(i, &ifmd))      continue;    examine_interface(ifs, ifmd.ifmd_name, ifmd.ifmd_flags,		      ifmd.ifmd_data.ifi_type);  }  return 1;}static int ifmib_get_stats(struct ifstat_driver *driver,			   struct ifstat_list *ifs) {  int count, i;  struct ifmibdata ifmd;  struct ifstat_data *cur;  if (ifs->flags & IFSTAT_HASINDEX) { /* poll by index */    for (cur = ifs->first; cur != NULL; cur = cur->next) {      i = ifstat_get_interface_index(cur);      if (i < 0 || !get_ifdata(i, &ifmd))	continue;      if (strcmp(ifstat_get_interface_name(cur), ifmd.ifmd_name))	continue;      ifstat_set_interface_stats(cur,				 ifmd.ifmd_data.ifi_ibytes,				 ifmd.ifmd_data.ifi_obytes);      ifstat_set_interface_index(cur, i);    }    return 1;  }   if ((count = get_ifcount()) <= 0)    return 0;    for (i = 1; i <= count; i++) {    if (!get_ifdata(i, &ifmd))      continue;    if ((cur = ifstat_get_interface(ifs, ifmd.ifmd_name)) == NULL)      continue;    ifstat_set_interface_stats(cur,			       ifmd.ifmd_data.ifi_ibytes,			       ifmd.ifmd_data.ifi_obytes);    ifstat_set_interface_index(cur, i);  }  return 1;}#endif#ifdef USE_IFDATAstruct ifdata_driver_data {  int sd;#ifdef HAVE_IFREQ_IFR_DATA  struct if_data ifd;#else  struct ifdatareq ifd;#endif  };static int ifdata_open_driver(struct ifstat_driver *driver,			      char *options) {  struct ifdata_driver_data *data;  if ((data = malloc(sizeof(struct ifdata_driver_data))) == NULL) {    ifstat_perror("malloc");    return 0;  }  if ((data->sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {    ifstat_perror("socket");    free(data);    return 0;  }    driver->data = (void *) data;  return 1;}static struct if_data *ifdata_get_data(struct ifdata_driver_data *data,				       char *name) {#ifdef HAVE_IFREQ_IFR_DATA    struct ifreq ifr;    strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));  ifr.ifr_data = (caddr_t) &(data->ifd);  if (ioctl(data->sd, SIOCGIFDATA, (char *) &ifr) < 0)    return NULL;  return &(data->ifd);#else  strncpy(data->ifd.ifd_name, name, sizeof(data->ifd.ifd_name));  if (ioctl(data->sd, SIOCGIFDATA, (char *) &(data->ifd)) < 0)    return NULL;  return &(data->ifd.ifd_ifd);#endif}struct ifdata_scan_data {  struct ifstat_list *ifs;  struct ifdata_driver_data *data;};static int ifdata_map_scan(int sd, struct ifreq *ifr, void *pdata) {  struct ifdata_scan_data *sdata = pdata;  struct if_data *ifd;    if (ioctl(sd, SIOCGIFFLAGS, (char *)ifr) != 0)    return 1;  if ((ifd = ifdata_get_data(sdata->data, ifr->ifr_name)) == NULL)    return 1;  examine_interface(sdata->ifs, ifr->ifr_name,		    ifr->ifr_flags, ifd->ifi_type);  return 1;}static int ifdata_scan_interfaces(struct ifstat_driver *driver,				  struct ifstat_list *ifs) {  struct ifdata_driver_data *data = driver->data;  struct ifdata_scan_data sdata = { ifs, data };  return ioctl_map_ifs(data->sd, &ifdata_map_scan, &sdata);} static int ifdata_get_stats(struct ifstat_driver *driver,			    struct ifstat_list *ifs) {  struct ifdata_driver_data *data = driver->data;  struct if_data *ifd;  struct ifstat_data *cur;    for (cur = ifs->first; cur != NULL; cur = cur->next) {    if (cur->flags & IFSTAT_TOTAL)      continue;    if ((ifd = ifdata_get_data(data, cur->name)) != NULL)      ifstat_set_interface_stats(cur, ifd->ifi_ibytes, ifd->ifi_obytes);  }  return 1;}static void ifdata_close_driver(struct ifstat_driver *driver) {  struct ifdata_driver_data *data = driver->data;  if (data->sd >= 0)    close(data->sd);  free(data);}#endif#ifdef USE_PROCstruct proc_driver_data {  char *file;  int checked;};static int proc_open_driver(struct ifstat_driver *driver,			    char *options) {  struct proc_driver_data *data;  if ((data = malloc(sizeof(struct proc_driver_data))) == NULL) {    ifstat_perror("malloc");    return 0;  }  data->file = (options != NULL) ? strdup(options) : NULL;  data->checked = 0;  driver->data = (void *) data;  return 1;}static void proc_close_driver(struct ifstat_driver *driver) {  struct proc_driver_data *data = driver->data;  if (data->file != NULL)    free(data->file);  free(data);}static int proc_get_stats(struct ifstat_driver *driver,			  struct ifstat_list *ifs) {  char buf[1024];  FILE *f;  char *iface, *stats;  unsigned long bytesin, bytesout;  struct ifstat_data *cur;  struct proc_driver_data *data = driver->data;  char *file;  if (data->file != NULL)    file = data->file;  else    file = PROC_FILE;  if ((f = fopen(file, "r")) == NULL) {    ifstat_error("can't open %s: %s", file, strerror(errno));    return 0;  }    /* check first lines */  if (fgets(buf, sizeof(buf), f) == NULL)    goto badproc;  if (!data->checked && strncmp(buf, "Inter-|", 7))    goto badproc;  if (fgets(buf, sizeof(buf), f) == NULL)    goto badproc;  if (!data->checked) {    if (strncmp(buf, " face |by", 9))      goto badproc;    data->checked = 1;  }  while (fgets(buf, sizeof(buf), f) != NULL) {    if ((stats = strchr(buf, ':')) == NULL)      continue;    *stats++ = '\0';    iface = buf;    while (*iface == ' ')      iface++;    if (*iface == '\0')      continue;    if (sscanf(stats, "%lu %*u %*u %*u %*u %*u %*u %*u %lu %*u", &bytesin, &bytesout) != 2)      continue;        if ((cur = ifstat_get_interface(ifs, iface)) != NULL)      ifstat_set_interface_stats(cur, bytesin, bytesout);  }  fclose(f);  return 1; badproc:  fclose(f);  ifstat_error("%s: unsupported format.", file);  return 0;}#endif#ifdef USE_ROUTEstruct route_driver_data {  char *buf;  size_t size;};#define DEFAULT_SIZE 16384static int route_open_driver(struct ifstat_driver *driver,			      char *options) {  struct route_driver_data *data;  if ((data = malloc(sizeof(struct route_driver_data))) == NULL) {    ifstat_perror("malloc");    return 0;  }  if ((data->buf = malloc(DEFAULT_SIZE)) < 0) {    ifstat_perror("malloc");    free(data);    return 0;  }  data->size = DEFAULT_SIZE;  driver->data = (void *) data;  return 1;}static int route_map_ifs(struct ifstat_driver *driver,		       int (*mapf)(char *name, struct if_msghdr *ifmsg, void *data),		       void *mdata) {  struct route_driver_data *data = driver->data;  int iflist[] = {    CTL_NET, PF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0   };  struct if_msghdr *ifm;  struct sockaddr_dl *dl;  char *ptr;  char ifname[IFNAMSIZ + 1];  size_t len;  if (data->size != 0) { /* try with current buf size */    len = data->size;    if (sysctl(iflist, sizeof(iflist) / sizeof(int),	       data->buf, &len, NULL, 0) < 0) {      if (errno != ENOMEM) {	ifstat_perror("sysctl");	return 0;      }      /* buffer too small */      free (data->buf);      data->size = 0;    }  }   if (data->size == 0) {    /* ask for size */    if (sysctl(iflist, sizeof(iflist) / sizeof(int),	       NULL, &len, NULL, 0) < 0) {      ifstat_perror("sysctl");      return 0;    }    if ((data->buf = malloc(len)) < 0) {      ifstat_perror("malloc");      return 0;    }    if (sysctl(iflist, sizeof(iflist) / sizeof(int),	       data->buf, &len, NULL, 0) < 0) {      ifstat_perror("sysctl");      return 0;    }  }  /* browse interfaes */  for (ptr = data->buf; ptr < data->buf + len; ptr += ifm->ifm_msglen) {    ifm = (struct if_msghdr *) ptr;    if (ifm->ifm_type != RTM_IFINFO)      continue;    if (ifm->ifm_msglen <= sizeof(struct if_msghdr)) /* no address */      continue;    dl = (struct sockaddr_dl *) (ptr + sizeof(struct if_msghdr));    if (dl->sdl_family != AF_LINK)      continue;    if (dl->sdl_nlen > (sizeof(ifname) - 1))      dl->sdl_nlen = sizeof(ifname) - 1;    memcpy(ifname, dl->sdl_data, dl->sdl_nlen);    ifname[dl->sdl_nlen] = '\0';    if (!mapf(ifname, ifm, mdata))      return 0;  }  return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -