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

📄 snmp.c

📁 ifstat源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ifstat - InterFace STATistics * Copyright (c) 2001, Ga雔 Roualland <gael.roualland@dial.oleane.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: snmp.c,v 1.26 2003/05/06 23:30:02 gael Exp $ */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdlib.h>#include <stdio.h>#include "ifstat.h"#ifdef USE_SNMP#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <string.h>#ifdef HAVE_NET_SNMP#include <net-snmp/net-snmp-config.h>#include <net-snmp/net-snmp-includes.h>#else#include <ucd-snmp/ucd-snmp-config.h>#include <ucd-snmp/ucd-snmp-includes.h>#endif#include "snmp.h"/* define this to use ifcount as a hint to discover interfaces   does not work well with routers that do not number interfaces sequentially,   but is faster that the ifIndex walk used otherwise */#undef USE_SNMP_IFCOUNTstatic char *snmp_sess_errstring(struct snmp_session *ss) {  char *res;  snmp_error(ss, NULL, NULL, &res);  return res;}#ifdef USE_SNMP_IFCOUNT/* report the value interfaces.ifNumber.0, actually the number of interfaces */static int snmp_get_ifcount(struct snmp_session *ss) {  int nifaces = -1;  oid ifcount[] = { 1, 3, 6, 1, 2, 1, 2, 1, 0 };  struct snmp_pdu *pdu;  struct snmp_pdu *response = NULL;  int status;  if ((pdu = snmp_pdu_create(SNMP_MSG_GET)) == NULL) {    ifstat_error("snmp_pdu_create: %s", snmp_api_errstring(snmp_errno));    return -1;  }  snmp_add_null_var(pdu, ifcount, sizeof(ifcount) / sizeof(oid));  if ((status = snmp_synch_response(ss, pdu, &response)) != STAT_SUCCESS ||      response->errstat != SNMP_ERR_NOERROR ||      response->variables == NULL ||      response->variables->type != ASN_INTEGER) {    if (status == STAT_SUCCESS)      ifstat_error("snmp: Error: %s", snmp_errstring(response->errstat));    else      ifstat_error("snmpget(interfaces.ifNumber.0): %s", snmp_sess_errstring(ss));    if (response)      snmp_free_pdu(response);    return -1;  }  nifaces = *(response->variables->val.integer);  snmp_free_pdu(response);      if (nifaces < 0)    return -1;  return nifaces;}#endifstatic int snmp_get_nextif(struct snmp_session *ss, int index) {  oid ifindex[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 1, 0 };  int len = sizeof(ifindex) / sizeof(oid);  struct snmp_pdu *pdu;  struct snmp_pdu *response = NULL;  struct variable_list *vars;  int status;  if (index >= 0)    ifindex[len - 1] = index;  if ((pdu = snmp_pdu_create(SNMP_MSG_GETNEXT)) == NULL) {    ifstat_error("snmp_pdu_create: %s", snmp_api_errstring(snmp_errno));    return -1;  }  snmp_add_null_var(pdu, ifindex, (index < 0) ? len - 1 : len);  if ((status = snmp_synch_response(ss, pdu, &response)) != STAT_SUCCESS ||      response->errstat != SNMP_ERR_NOERROR ||      response->variables == NULL) {    if (status == STAT_SUCCESS)       ifstat_error("snmp: Error: %s", snmp_errstring(response->errstat));    else      ifstat_error("snmpgetnext(interfaces.ifTable.ifEntry.ifIndex...): %s",		   snmp_sess_errstring(ss));    if (response != NULL)      snmp_free_pdu(response);    return -1;  }  for(vars = response->variables; vars; vars = vars->next_variable) {    /* check that the variable is under the base oid */    if (vars->name_length != len)      continue;    if (memcmp(ifindex, vars->name, sizeof(ifindex) - sizeof(oid)) != 0)      continue;    index = vars->name[vars->name_length - 1];    snmp_free_pdu(response);    return index;  }  snmp_free_pdu(response);  return -1;}#define S_IFNAMEMAX 64struct ifsnmp {  char name[S_IFNAMEMAX];  unsigned long bout, bin;  int flags, index;};#define S_UP         1#define S_BIN        2#define S_BOUT       4#define S_LOOP       8#define S_INVALID   16#define S_NUMNAME   32#define S_IFNAME    64  /* fill a struct ifsnmp buffer of selected information (flags) for   interface index to (index + nifaces - 1). ifsnmp must be large   enough, and nifaces shouldb'nt too large since some devices have   limited capability for large responses...   In case we get a unknown name answer and we're   polling several interfaces at once, interfaces will be polled   again individually to try to solve the problem.*/static int snmp_get_ifinfos(struct snmp_session *ss, int nifaces,			    int flags, struct ifsnmp * ifsnmp, int *toobig) {  struct snmp_pdu *pdu, *response = NULL;  oid ifinfo[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 0, 0 }; /* interfaces.ifTable.ifEntry.x.n */#define ifDescr 2#define ifType 3  #define ifOperStatus 8  #define ifInOctets 10#define ifOutOctets 16  struct variable_list *vars;  int i, status;   if (nifaces <= 0)    return 0;    if ((pdu = snmp_pdu_create(SNMP_MSG_GET)) == NULL) {    ifstat_error("snmp_pdu_create: %s", snmp_api_errstring(snmp_errno));    return 0;  }  for (i = 0; i < nifaces; i++) {    ifsnmp[i].flags = 0;    ifsnmp[i].name[0] = 0;    /* set interface index */    ifinfo[10] = ifsnmp[i].index;    if (flags & S_NUMNAME) {      sprintf(ifsnmp[i].name, "if%d", ifsnmp[i].index);    } else if (flags & S_IFNAME) {      /* require descr */      ifinfo[9] = ifDescr;      snmp_add_null_var(pdu, ifinfo, sizeof(ifinfo) / sizeof(oid));    }        /* then optional data */    if (flags & S_UP) {      ifinfo[9] = ifOperStatus;      snmp_add_null_var(pdu, ifinfo, sizeof(ifinfo) / sizeof(oid));    }    if (flags & S_BOUT) {      ifinfo[9] = ifOutOctets;      snmp_add_null_var(pdu, ifinfo, sizeof(ifinfo) / sizeof(oid));    }    if (flags & S_BIN) {      ifinfo[9] = ifInOctets;      snmp_add_null_var(pdu, ifinfo, sizeof(ifinfo) / sizeof(oid));    }    if (flags & S_LOOP) {      ifinfo[9] = ifType;      snmp_add_null_var(pdu, ifinfo, sizeof(ifinfo) / sizeof(oid));    }  }      if ((status = snmp_synch_response(ss, pdu, &response)) != STAT_SUCCESS ||      response->errstat != SNMP_ERR_NOERROR ||      response->variables == NULL) {    if (status == STAT_SUCCESS) {      if (response->errstat != SNMP_ERR_NOSUCHNAME &&	  response->errstat != SNMP_ERR_TOOBIG)	ifstat_error("snmp: Error: %s", snmp_errstring(response->errstat));      else if (nifaces > 1) {	/* maybe only one of the interface is broken or too many interfaces polled at once	   -- repoll inetrface per interface */	if (response->errstat == SNMP_ERR_TOOBIG && toobig != NULL)	  (*toobig)++;	if (response != NULL)	  snmp_free_pdu(response);	status = 0;	for (i = 0; i < nifaces; i++) {	  if (!snmp_get_ifinfos(ss, 1, flags, ifsnmp + i, NULL))	    ifsnmp[i].flags |= S_INVALID;	  else	    status = 1;	}	return status;      }    } else      ifstat_error("snmpget(interfaces.ifTable.ifEntry...): %s", snmp_sess_errstring(ss));    if (response != NULL)      snmp_free_pdu(response);    return 0;  }  for(vars = response->variables; vars; vars = vars->next_variable) {    /* check that the variable is under the base oid */    if (memcmp(ifinfo, vars->name, sizeof(ifinfo) - 2 * sizeof(oid)) != 0)      continue;    for(i = 0; i < nifaces; i++) {      if (ifsnmp[i].index == vars->name[10])	break;    }    if (i == nifaces) /* not found */      continue;    switch (vars->name[9]) {    case ifDescr:      if (vars->type == ASN_OCTET_STR) {        int count = vars->val_len;        if (count >= sizeof(ifsnmp[i].name))          count = sizeof(ifsnmp[i].name) - 1;	strncpy(ifsnmp[i].name, vars->val.string, count);        ifsnmp[i].name[count] = '\0';      }      break;    case ifOperStatus:      if (vars->type == ASN_INTEGER) {	if (*(vars->val.integer) == 1) /* up */	  ifsnmp[i].flags |= S_UP;      }      break;    case ifType:      if (vars->type == ASN_INTEGER) {	if (*(vars->val.integer) == 24) /* softwareLoopback */	  ifsnmp[i].flags |= S_LOOP;      }      break;    case ifInOctets:

⌨️ 快捷键说明

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