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

📄 drivers.c

📁 ifstat源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static int route_map_stats(char *name, struct if_msghdr *ifmsg, void *data) {  struct ifstat_data *cur;    if ((cur = ifstat_get_interface((struct ifstat_list *) data, name)) == NULL)    return 1;  ifstat_set_interface_stats(cur, ifmsg->ifm_data.ifi_ibytes,			     ifmsg->ifm_data.ifi_obytes);  return 1;}static int route_get_stats(struct ifstat_driver *driver,			   struct ifstat_list *ifs) {  return route_map_ifs(driver, &route_map_stats, ifs);}static int route_map_scan(char *name, struct if_msghdr *ifmsg, void *data) {  examine_interface((struct ifstat_list *) data, name,		    ifmsg->ifm_flags, ifmsg->ifm_data.ifi_type);  return 1;}static int route_scan_interfaces(struct ifstat_driver *driver,				 struct ifstat_list *ifs) {  return route_map_ifs(driver, &route_map_scan, (void *) ifs);} static void route_close_driver(struct ifstat_driver *driver) {  struct route_driver_data *data = driver->data;  if (data->buf != NULL)    free(data->buf);  free(data);}#endif#ifdef USE_DLPI#define DLPI_DEFBUF_LEN 1024#define DLPI_NO_PPA -1#define DLPI_DEVICE "/dev/dlpi"struct dlpi_driver_data {  int fd;  unsigned int *buf;  int maxlen;  int ppa;};static int dlpi_open_driver(struct ifstat_driver *driver, char *options) {  struct dlpi_driver_data *dlpi;  if ((dlpi = malloc(sizeof(struct dlpi_driver_data))) == NULL) {    ifstat_perror("malloc");    return 0;  }  if ((dlpi->fd = open(options != NULL ? options : DLPI_DEVICE, O_RDWR)) < 0) {    ifstat_perror("open");    free(dlpi);    return 0;  }  dlpi->maxlen = DLPI_DEFBUF_LEN;  if ((dlpi->buf = malloc(dlpi->maxlen)) == NULL) {    ifstat_perror("malloc");    free(dlpi);    return 0;  }  dlpi->ppa = DLPI_NO_PPA;  driver->data = (void *) dlpi;  return 1;}static int dlpi_req (struct dlpi_driver_data *dlpi, void *req, int reqlen,		     int ackprim, void **ack, int *acklen) {  struct strbuf ctlptr;  int len, ret, flags;  dl_error_ack_t *err_ack;    ctlptr.maxlen = 0;  ctlptr.len = reqlen;  ctlptr.buf = req;    if (putmsg(dlpi->fd, &ctlptr, NULL, 0) < 0) {    ifstat_perror("putmsg");    return 0;  }    ctlptr.maxlen = dlpi->maxlen;  ctlptr.buf = (char *) dlpi->buf;  ctlptr.len = 0;    len = 0;  flags = 0;  while ((ret = getmsg(dlpi->fd, &ctlptr, NULL, &flags)) == MORECTL) {    /* duplicate size of buf */    dlpi->maxlen *= 2;    if ((dlpi->buf = realloc(dlpi->buf, dlpi->maxlen)) == NULL) {      ifstat_perror("malloc");      return 0;    }    len += ctlptr.len;    ctlptr.buf = (char *) dlpi->buf + len;    ctlptr.maxlen = dlpi->maxlen - len;    ctlptr.len = 0;  }  if (ret < 0) {    ifstat_perror("getmsg");    return 0;  }  len += ctlptr.len;    err_ack = (dl_error_ack_t *) dlpi->buf;  if (err_ack->dl_primitive != ackprim) {    if (err_ack->dl_primitive == DL_ERROR_ACK) {      errno = err_ack->dl_errno;      ifstat_perror("dlpi");    } else {      ifstat_error("dlpi: unexpected ack type returned");    }    return 0;  }  if (ack != NULL)    *ack = dlpi->buf;  if (acklen != NULL)    *acklen = len;	  return 1;}static int dlpi_attach(struct dlpi_driver_data *dlpi, int ppa) {  dl_attach_req_t attach_req;  dl_detach_req_t dettach_req;    /* check if already attached */  if (dlpi->ppa == ppa)    return 1;    /* else detach */  if (dlpi->ppa != DLPI_NO_PPA) {    dettach_req.dl_primitive = DL_DETACH_REQ;    if (!dlpi_req(dlpi, &dettach_req, sizeof(dl_detach_req_t),		  DL_OK_ACK, NULL, NULL))      return 0;    dlpi->ppa = DLPI_NO_PPA;    if (ppa == DLPI_NO_PPA)      return 1; /* we're done */  }  /* attach */  attach_req.dl_primitive = DL_ATTACH_REQ;  attach_req.dl_ppa = ppa;  if (!dlpi_req(dlpi, &attach_req, sizeof(dl_attach_req_t),		DL_OK_ACK, NULL, NULL))    return 0;  dlpi->ppa = ppa;    return 1;}static int dlpi_get_ifmib(struct dlpi_driver_data *dlpi, int ppa, mib_ifEntry *mib) {  dl_get_statistics_req_t stats_req;  dl_get_statistics_ack_t *stats_ack;  int len;  /* first attach to PPA */  if (!dlpi_attach(dlpi, ppa))    return 0;  /* grab stats */  stats_req.dl_primitive = DL_GET_STATISTICS_REQ;  if (!dlpi_req(dlpi, &stats_req, sizeof(dl_get_statistics_req_t), 		DL_GET_STATISTICS_ACK, (void **) &stats_ack, &len))    return 0;  if (len < sizeof(dl_get_statistics_ack_t) ||      stats_ack->dl_stat_offset < 0 ||       stats_ack->dl_stat_offset + sizeof(mib_ifEntry) > len) {    ifstat_error("dlpi: invalid data returned by stats ack");  }  memcpy(mib, (char *) stats_ack + stats_ack->dl_stat_offset,	 sizeof(mib_ifEntry));  return 1;}static int dlpi_map_ifs(struct dlpi_driver_data *dlpi,			int (*mapf)(mib_ifEntry *mib, int ppa, char *name,				    void *mdata),			void *mdata) {  dl_hp_ppa_req_t ppa_req;  dl_hp_ppa_ack_t *ppa_ack;  dl_hp_ppa_info_t *ppa_info;  mib_ifEntry mib;  void *buf;  int len, i, ofs;  char ifname[sizeof(ppa_info->dl_module_id_1) + 12];  if (!dlpi_attach(dlpi, DLPI_NO_PPA))    return 0;  ppa_req.dl_primitive = DL_HP_PPA_REQ;  if (!dlpi_req(dlpi, &ppa_req, sizeof(ppa_req),		DL_HP_PPA_ACK, (void **) &ppa_ack, &len))    return 0;  if (len < sizeof(dl_hp_ppa_ack_t)) {    ifstat_error("dlpi: short read for ppa ack");    return 0;  }  /* copy buffer since used by later calls */  if ((buf = malloc(len)) == NULL) {    perror("malloc");    return 0;  }  memcpy(buf, (void *) ppa_ack, len);  ppa_ack = buf;    /* browse interface list */  ofs = ppa_ack->dl_offset;  for(i = 0; i < ppa_ack->dl_count; i++) {    if (ofs < 0 || ofs + sizeof(dl_hp_ppa_info_t) > len) {      ifstat_error("dlpi: data returned by ppa ack exceeds data buffer");      free(buf);      return 0;    }    ppa_info = (dl_hp_ppa_info_t *) ((char *) ppa_ack + ofs);    if (dlpi_get_ifmib(dlpi, ppa_info->dl_ppa, &mib)) {      sprintf(ifname, "%s%d", ppa_info->dl_module_id_1, ppa_info->dl_instance_num);      if (!mapf(&mib, ppa_info->dl_ppa, ifname, mdata)) {	free(buf);	return 0;      }    }        ofs = ppa_ack->dl_offset + ppa_info->dl_next_offset;  }  free(buf);  return 1;}static int dlpi_map_scan(mib_ifEntry *mib, int ppa, char *name,			void *mdata) {  examine_interface((struct ifstat_list *) mdata, name,		    (mib->ifOper == 1 ? IFF_UP : 0) |		    (mib->ifType == 24 ? IFF_LOOPBACK : 0), 0);  return 1;    }static int dlpi_scan_interfaces(struct ifstat_driver *driver,				struct ifstat_list *ifs) {  return dlpi_map_ifs(driver->data, &dlpi_map_scan, (void *) ifs);}static int dlpi_map_stats(mib_ifEntry *mib, int ppa, char *name,			  void *mdata) {  struct ifstat_data *cur;  if ((cur = ifstat_get_interface((struct ifstat_list *) mdata, name)) == NULL)    return 1;  ifstat_set_interface_stats(cur, mib->ifInOctets, mib->ifOutOctets);  ifstat_set_interface_index(cur, ppa);  return 1;}static int dlpi_get_stats(struct ifstat_driver *driver,			  struct ifstat_list *ifs) {  int i;  struct ifstat_data *cur;  mib_ifEntry mib;  if (ifs->flags & IFSTAT_HASINDEX) { /* poll by index (ppa) */    for (cur = ifs->first; cur != NULL; cur = cur->next) {      i = ifstat_get_interface_index(cur);      if (!dlpi_get_ifmib(driver->data, i, &mib))	continue;      ifstat_set_interface_stats(cur, mib.ifInOctets, mib.ifOutOctets);      ifstat_set_interface_index(cur, i);    }    return 1;  }  return dlpi_map_ifs(driver->data, &dlpi_map_stats, (void *) ifs);}    void dlpi_close_driver(struct ifstat_driver *driver) {  struct dlpi_driver_data *dlpi = driver->data;  free(dlpi->buf);  close(dlpi->fd);  free(dlpi);}#endif#ifdef USE_WIN32struct win32_driver_data {  void *buf;  int len;};static int win32_open_driver(struct ifstat_driver *driver, char *options) {  struct win32_driver_data *data;  if ((data = malloc(sizeof(struct win32_driver_data))) == NULL) {    ifstat_perror("malloc");    return 0;  }  data->buf = NULL;  data->len = 0;  driver->data = (void *) data;  return 1;}static int win32_getiftable(struct ifstat_driver *driver,			    PMIB_IFTABLE *iftable) {  struct win32_driver_data *data = driver->data;  ULONG size;  DWORD ret;  size = data->len;  while ((ret = GetIfTable((PMIB_IFTABLE) data->buf,			   &size, 1)) == ERROR_INSUFFICIENT_BUFFER) {    data->len = size * 2;    if ((data->buf = realloc(data->buf, data->len)) == NULL) {      perror("realloc");      return 0;    }  }    if (ret == NO_ERROR) {    *iftable = (PMIB_IFTABLE) data->buf;    return 1;  }    perror("GetIfTable");  return 0;}static int win32_scan_interfaces(struct ifstat_driver *driver,				 struct ifstat_list *ifs) {  PMIB_IFTABLE iftable;  DWORD i;    if (!win32_getiftable(driver, &iftable))    return 0;  for (i = 0; i < iftable->dwNumEntries; i++)     examine_interface(ifs,		      iftable->table[i].bDescr,		      ((iftable->table[i].dwOperStatus ==		       MIB_IF_OPER_STATUS_OPERATIONAL) ? IFF_UP : 0) |		      ((iftable->table[i].dwType ==		       MIB_IF_TYPE_LOOPBACK) ? IFF_LOOPBACK : 0), 0);  return 1;}static int win32_get_stats(struct ifstat_driver *driver,			   struct ifstat_list *ifs) {  PMIB_IFTABLE iftable;  DWORD i;  struct ifstat_data *cur;  if (!win32_getiftable(driver, &iftable))    return 0;  for (i = 0; i < iftable->dwNumEntries; i++) {    if ((cur = ifstat_get_interface(ifs, iftable->table[i].bDescr)) != NULL)      ifstat_set_interface_stats(cur,				 (unsigned long)				 iftable->table[i].dwInOctets,				 (unsigned long)				 iftable->table[i].dwOutOctets);  }  return 1;}void win32_close_driver(struct ifstat_driver *driver) {  struct win32_driver_data *data = driver->data;    if (data->buf != NULL)    free(data->buf);  free(data);}#endif static struct ifstat_driver drivers[] = {#ifdef USE_KSTAT    { "kstat", &kstat_open_driver, &ioctl_scan_interfaces, &kstat_get_stats,    &kstat_close_driver },#endif#ifdef USE_IFMIB    { "ifmib", NULL, &ifmib_scan_interfaces, &ifmib_get_stats, NULL },#endif#ifdef USE_IFDATA  { "ifdata", &ifdata_open_driver, &ifdata_scan_interfaces,    &ifdata_get_stats, &ifdata_close_driver },#endif#ifdef USE_ROUTE  { "route", &route_open_driver, &route_scan_interfaces,    &route_get_stats, &route_close_driver },#endif  #ifdef USE_KVM    { "kvm",  &kvm_open_driver, &kvm_scan_interfaces, &kvm_get_stats,    &kvm_close_driver },#endif#ifdef USE_PROC    { "proc", &proc_open_driver, &ioctl_scan_interfaces, &proc_get_stats,    &proc_close_driver },#endif#ifdef USE_DLPI  { "dlpi", &dlpi_open_driver, &dlpi_scan_interfaces, &dlpi_get_stats,    &dlpi_close_driver },#endif#ifdef USE_WIN32  { "win32", &win32_open_driver, &win32_scan_interfaces,    &win32_get_stats, &win32_close_driver },#endif  #ifdef USE_SNMP    { "snmp", &snmp_open_driver, &snmp_scan_interfaces, &snmp_get_stats,    &snmp_close_driver },#endif    { NULL } };  int ifstat_get_driver(char *name, struct ifstat_driver *driver) {  int num = 0;    if (name != NULL)     for (num = 0; drivers[num].name != NULL; num++)      if (!strcasecmp(drivers[num].name, name))	break;  if (drivers[num].name == NULL)    return 0;  memcpy(driver, &(drivers[num]), sizeof(struct ifstat_driver));  driver->data = NULL;  return 1;}char* ifstat_list_drivers() {  int num;  int len = 0, pos = 0;  char *res;    for(num = 0; drivers[num].name != NULL; num++)    len += strlen(drivers[num].name) + 2;  if ((res = malloc(len + 1)) == NULL) {    ifstat_perror("malloc");    return NULL;  }  for(num = 0; drivers[num].name != NULL; num++) {    if (num != 0) {      memcpy(res + pos, ", ", 2);      pos += 2;    }    len = strlen(drivers[num].name);    memcpy(res + pos, drivers[num].name, len);    pos += len;  }  res[pos] = '\0';  return res;}

⌨️ 快捷键说明

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