Net-snmp总结(六)-net-snmp源码分析

时间:2022-06-02 07:12:27

一、net-snmp源码分析

Net-snmp代码的核心,就是初始化函数时,向代理(snmpd)注册了回调处理函数,当(snmpd)接收到一个snmp请求包时,它会先对包进行校验,如果校验不通过,会返回相应的错误。如果通过后,它会解析请求包,并把请求包的内容转换成请求结构(netsnmp_agent_request_info【包含请求包的pdu信息】,netsnmp_request_info【包含请求包的vb信息】)。匹配到相关的oid时,就调用相应的注册处理函数并传入请求结构给处理函数,处理函数只需要根据结构中的内容进行相应的业务处理就可以了。

下面用之前添加的testGet代码来做简要说明。

/** Initializes the testGet module */
void
init_testGet(void)
{
const oid GetTime_oid[] = { 1, 3, 6, 1, 4, 1, 77695, 1 };

DEBUGMSGTL(("testGet", "Initializing\n"));

netsnmp_register_scalar(netsnmp_create_handler_registration
("GetTime", handle_GetTime, GetTime_oid,
OID_LENGTH(GetTime_oid), HANDLER_CAN_RONLY));
}

int
handle_GetTime(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
time_t t;
switch (reqinfo->mode) {

case MODE_GET:
time(&t);
char szTime[100];
snprintf(szTime,100,"%s",ctime(&t));
snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR,
/*
* XXX: a pointer to the scalar's data
*/ szTime,
/*
* XXX: the length of the data in bytes
*/ strlen(szTime));

break;


default:
/*
* we should never get here, so this is a really bad error
*/
snmp_log(LOG_ERR, "unknown mode (%d) in handle_GetTime\n",
reqinfo->mode);
return SNMP_ERR_GENERR;
}

return SNMP_ERR_NOERROR;
}

初始函数调用netsnmp_create_handler_registration向snmpd注册GetTime_oid的处理函数为handle_GetTime,当snmpd调用handle_GetTime时,便会把相应的snmp包的信息从这几个参数中传进来。其中reqinfo 就是snmp请求包被snmpd解析后得到的结构,包含了请求包的会话和pdu信息;requests主要包含了 VB 信息。每次处理一个SNMP请求,就调用一次注册函数。

 

主要的几个结构体如下

netsnmp_agent_request_info

/** @struct netsnmp_agent_request_info_s  
* The agent transaction request structure
*/
typedef struct netsnmp_agent_request_info_s {
int mode;
/** pdu contains authinfo, eg */
/* netsnmp_pdu *pdu; */
struct netsnmp_agent_session_s *asp; /* may not be needed */
/*
* can be used to pass information on a per-pdu basis from a
* helper to the later handlers
*/
netsnmp_data_list *agent_data;
} netsnmp_agent_request_info;

netsnmp_request_info

/** @typedef struct netsnmp_request_info_s netsnmp_request_info  
* Typedefs the netsnmp_request_info_s struct into
* netsnmp_request_info*/

/** @struct netsnmp_request_info_s
* The netsnmp request info structure.
*/

typedef struct netsnmp_request_info_s {
/**
* variable bindings
*/
netsnmp_variable_list *requestvb;

/**
* can be used to pass information on a per-request basis from a
* helper to the later handlers
*/
netsnmp_data_list *parent_data;

/*
* pointer to the agent_request_info for this request
*/
struct netsnmp_agent_request_info_s *agent_req_info;

/** don't free, reference to (struct tree)->end */
oid *range_end;
size_t range_end_len;

/*
* flags
*/
int delegated;
int processed;
int inclusive;

int status;
/** index in original pdu */
int index;

/** get-bulk */
int repeat;
int orig_repeat;
netsnmp_variable_list *requestvb_start;

/* internal use */
struct netsnmp_request_info_s *next;
struct netsnmp_request_info_s *prev;
struct netsnmp_subtree_s *subtree;
} netsnmp_request_info;

二、net-snmp程序逻辑

snmpd代理完成两个功能:

1、接收网管发过来的snmp包,并对接收到的snmp包进行解析,校验后,找到并调用相应的处理函数进行处理。

2、调用注册了的告警函数,向网管发送告警信息。


Net-snmp代码流程图如下图所示




Net-snmp总结(六)-net-snmp源码分析