📄 snmp.c
字号:
if (vars->type == ASN_INTEGER || vars->type == ASN_COUNTER) { ifsnmp[i].flags |= S_BIN; ifsnmp[i].bin = *(vars->val.integer); } break; case ifOutOctets: if (vars->type == ASN_INTEGER || vars->type == ASN_COUNTER) { ifsnmp[i].flags |= S_BOUT; ifsnmp[i].bout = *(vars->val.integer); } break; } } snmp_free_pdu(response); return 1;}/* driver API */struct snmp_driver_data { struct snmp_session *session; int num_ifnames, num_ifsreqs; struct ifsnmp *ifsnmp;};/* maximum number of interfaces to poll at once, min 1 */#define MAXIFSREQS 64#define DEFIFSREQS 8/* initiailise the snmp driver, strings syntax is [comm@][#]host*/int snmp_open_driver(struct ifstat_driver *driver, char *options) { char *host; char *community; struct snmp_session session; struct snmp_driver_data *data; if ((data = malloc(sizeof(struct snmp_driver_data))) == NULL) { ifstat_perror("malloc"); return 0; } if (options == NULL) options = "localhost"; if ((host = strchr(options, '@')) != NULL) { *host++ = '\0'; community = options; } else { host = options; community = "public"; } if (*host == '#') { host++; data->num_ifnames = 1; /* numeric interface names */ } else data->num_ifnames = 0; if ((options = strchr(host, '/')) != NULL) { *options++ = '\0'; data->num_ifsreqs = atoi(options); if (data->num_ifsreqs < 1) { ifstat_error("snmp: bad number of interface requests: %s; ignored.", options); data->num_ifsreqs = DEFIFSREQS; } else if (data->num_ifsreqs > MAXIFSREQS) { ifstat_error("snmp: number of interface requests too large: %d; using %d instead.", data->num_ifsreqs, MAXIFSREQS); data->num_ifsreqs = MAXIFSREQS; } } else data->num_ifsreqs = DEFIFSREQS; if ((data->ifsnmp = calloc(sizeof(struct ifsnmp), data->num_ifsreqs)) == NULL) { ifstat_perror("malloc"); free(data); return 0; } init_snmp(ifstat_progname); snmp_sess_init(&session); session.peername = host; session.version = SNMP_VERSION_1; session.community = community; session.community_len = strlen(community); if ((data->session = snmp_open(&session)) == NULL) { ifstat_error("snmp_open: %s", snmp_api_errstring(snmp_errno)); free(data->ifsnmp); free(data); return 0; } driver->data = (void *) data; return 1;}/* cleanups session */void snmp_close_driver(struct ifstat_driver *driver) { struct snmp_driver_data *data = driver->data; snmp_close(data->session); free(data->ifsnmp); free(data);}#ifdef USE_SNMP_IFCOUNTstatic int snmp_map_ifs(struct ifstat_driver *driver, int (*mapf)(struct ifstat_driver *driver, int nifaces, void *pdata), void *pdata) { struct snmp_driver_data *data = driver->data; struct ifsnmp *ifsnmp = data->ifsnmp; int ifaces, nifaces, index, i; if ((ifaces = snmp_get_ifcount(data->session)) <= 0) { ifstat_error("snmp: no interfaces returned."); return 0; } for(index = 0; index <= (ifaces /data->num_ifsreqs); index++) { nifaces = ifaces - index * data->num_ifsreqs; if (nifaces > data->num_ifsreqs) nifaces = data->num_ifsreqs; for (i = 0; i < nifaces; i++) ifsnmp[i].index = index * data->num_ifsreqs + i + 1; if(!mapf(driver, nifaces, pdata)) return 0; } return 1;}#elsestatic int snmp_map_ifs(struct ifstat_driver *driver, int (*mapf)(struct ifstat_driver *driver, int nifaces, void *pdata), void *pdata) { struct snmp_driver_data *data = driver->data; struct ifsnmp *ifsnmp = data->ifsnmp; int ifaces, nifaces, index; index = -1; nifaces = ifaces = 0; while((index = snmp_get_nextif(data->session, index)) >= 0) { ifaces++; ifsnmp[nifaces++].index = index; if (nifaces >= data->num_ifsreqs) { if(!mapf(driver, nifaces, pdata)) return 0; nifaces = 0; } } if (nifaces > 0) return mapf(driver, nifaces, pdata); return (ifaces != 0);}#endifstatic int snmp_map_scan(struct ifstat_driver *driver, int nifaces, void *pdata) { struct snmp_driver_data *data = driver->data; struct ifsnmp *ifsnmp = data->ifsnmp; struct ifstat_list *ifs = pdata; struct ifstat_data *iface; int i; if (!snmp_get_ifinfos(data->session, nifaces, S_UP | S_LOOP | (data->num_ifnames ? S_NUMNAME : S_IFNAME), ifsnmp, NULL)) return 1; for (i=0; i < nifaces; i++) { if (ifsnmp[i].flags & S_INVALID) continue; if ((ifsnmp[i].flags & S_LOOP) && !(ifs->flags & IFSTAT_LOOPBACK)) continue; if ((ifsnmp[i].flags & S_UP) || (ifs->flags & IFSTAT_DOWN)) { if ((iface = ifstat_get_interface(ifs, ifsnmp[i].name)) != NULL) { if (!ifstat_quiet && !(iface->flags & IFSTAT_HASSTATS)) { ifstat_error("warning: multiple interfaces detected with same name (%s); " "you should enable numeric mode by prepending # to the hostname.", ifsnmp[i].name); iface->flags |= IFSTAT_HASSTATS; } } else ifstat_add_interface(ifs, ifsnmp[i].name, 0); } } return 1;}int snmp_scan_interfaces(struct ifstat_driver *driver, struct ifstat_list *ifs) { return snmp_map_ifs(driver, &snmp_map_scan, (void *) ifs);}static void snmp_toobig(struct ifstat_driver *driver) { struct snmp_driver_data *data = driver->data; if (data->num_ifsreqs > 1) { data->num_ifsreqs >>= 1; if (!ifstat_quiet) ifstat_error("warning: changing poll grouping to %d to avoid \"too big\" errors", data->num_ifsreqs); }}static int snmp_map_stats(struct ifstat_driver *driver, int nifaces, void *pdata) { struct snmp_driver_data *data = driver->data; struct ifsnmp *ifsnmp = data->ifsnmp; struct ifstat_list *ifs = pdata; struct ifstat_data *cur; int i, toobig = 0; if (!snmp_get_ifinfos(data->session, nifaces, S_BIN | S_BOUT | (data->num_ifnames ? S_NUMNAME : S_IFNAME), ifsnmp, &toobig)) return 1; if (toobig) snmp_toobig(driver); for (i=0; i < nifaces; i++) { if (ifsnmp[i].flags & S_INVALID) continue; if (!(ifsnmp[i].flags & S_BIN && ifsnmp[i].flags & S_BOUT)) continue; /* overwrite if name if needed */ if ((cur = ifstat_get_interface(ifs, ifsnmp[i].name)) != NULL) { ifstat_set_interface_stats(cur, ifsnmp[i].bin, ifsnmp[i].bout); ifstat_set_interface_index(cur, ifsnmp[i].index); } } return 1;}int snmp_get_stats(struct ifstat_driver *driver, struct ifstat_list *ifs) { struct snmp_driver_data *data = driver->data; int ifaces, i, toobig = 0; struct ifstat_data *cur, *block; struct ifsnmp *ifsnmp = data->ifsnmp; if (ifs->flags & IFSTAT_HASINDEX) { /* poll by index */ cur = ifs->first; while (cur != NULL) { /* init as many interface as possible */ block = cur; ifaces = 0; while (ifaces < data->num_ifsreqs && cur != NULL) { ifsnmp[ifaces++].index = cur->index; cur = cur->next; } /* poll them */ if (!snmp_get_ifinfos(data->session, ifaces, S_BIN | S_BOUT | (data->num_ifnames ? 0 : S_IFNAME), ifsnmp, &toobig)) continue; if (toobig) snmp_toobig(driver); for (i = 0; i < ifaces; i++) { if (ifsnmp[i].flags & S_INVALID) continue; if (!(ifsnmp[i].flags & S_BIN && ifsnmp[i].flags & S_BOUT)) continue; if (!data->num_ifnames && strcmp(ifsnmp[i].name, block->name)) continue; /* interface changed of index... */ ifstat_set_interface_stats(block, ifsnmp[i].bin, ifsnmp[i].bout); ifstat_set_interface_index(block, ifsnmp[i].index); block = block->next; } } return 1; } return snmp_map_ifs(driver, &snmp_map_stats, (void *) ifs);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -