[通信技术资料] SNMP:简单网络管理协议编程实现

[复制链接]
5030|1
 楼主| abner_ma 发表于 2023-1-31 16:38 | 显示全部楼层 |阅读模式
   SNMP简单网络管理协议(Simple Network Management Protocol),是由互联网工程任务组定义的一套网络管理协议。SNMP可以使网络管理员通过一台工作站完成对计算机、路由器和其他网络设备的远程管理和监视。利用SNMP协议可以更好地管理和监控网络。管理工作站可以远程管理所有支持该协议的网络设备,如监视网络状态、修改网络设备配置、接收网络事件警告等。SNMP作为TCP/IP协议的一部分,其消息是被封装到UDP协议中进行传输的。SNMP协议主要由两大部分组成:网络管理站(也叫管理进程)和被管的网络单元(也叫被管设备),被管设备种类众多,比如:路由器、终端服务器、打印机等。在本文档中,国民技术的N32G457QEL_EVB V1.1全功能开发板就充当被管理设备。被管设备端和管理相关的软件叫代理程序(SNMP agent)或者代理进程,它是运行于设备上的代码或程序。管理进程和代理进程之间的通信可以有两种方式:一种是管理进程向代理进程发起的,询问其具体参数值(get操作)或者为其设置某个参数值(set操作);另一种是代理进程主动向管理进程发起的,向其报告自身的某些重要事件的发生(trap操作)。
   到目前为止,SNMP共有三个版本:v1,v2和v3。V1和v2有很多共同的特征,v3在前面版本的基础上增强了安全性方面的功能。其各自的消息格式、操作命令等。
NMP系统基本组件
  SNMP系统基本组件包括网络管理系统NMS(Network Management System)、代理进程(Agent)、被管对象(Managed Object)和管理信息库MIB(Management Information Base)。如图所示他们共同构成SNMP的管理模型,在SNMP的体系结构中都起着至关重要的作用。
NMSNMS是网络中扮演管理者,是一个采用SNMP协议对网络设备进行管理/监视的系统,运行在NMS服务器上。
  • NMS可以向设备上的Agent发出请求,查询或修改一个或多个具体的参数值。
  • NMS可以接收设备上的Agent主动发送的Trap信息,以获知被管理设备当前的状态。


AgentAgent是被管理设备中的一个代理进程,用于维护被管理设备的信息数据并响应来自NMS的请求,把管理数据汇报给发送请求的NMS。
  • Agent接收到NMS的请求信息后,通过MIB表完成相应指令后,并把操作结果响应给NMS。
  • 当设备发生故障或者其它事件时,设备会通过Agent主动发送信息给NMS,向NMS报告设备当前的状态变化。


Managed Object
Managed Object指被管理对象。每一个设备可能包含多个被管理对象,被管理对象可以是设备中的某个硬件,也可以是在硬件、软件(如路由选择协议)上配置的参数集合。

MIBMIB是一个数据库,指明了被管理设备所维护的变量,是能够被Agent查询和设置的信息。MIB在数据库中定义了被管理设备的一系列属性:对象的名称、对象的状态、对象的访问权限和对象的数据类型等。通过MIB,可以完成以下功能:
  • Agent通过查询MIB,可以获知设备当前的状态信息。
  • Agent通过修改MIB,可以设置设备的状态参数。




SNMP嵌入式系统实现方法:
MCU选用Cotex M3系列STM32F103芯片,以太网控制芯片选用WIZnet的W5500。

主要代码:(附件为整个代码)
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <stdarg.h>

  5. #include "ctype.h"
  6. #include "w5500.h"
  7. #include "socket.h"
  8. #include "config.h"
  9. #include "mcu_int.h"
  10. #include "snmpLib.h"
  11. #include "snmpDemo.h"

  12. struct messageStruct request_msg;
  13. struct messageStruct response_msg;

  14. uint8 errorStatus, errorIndex;

  15. #define COPY_SEGMENT_TEMP20110929(x) \
  16. { \
  17.         request_msg.index += seglen; \
  18.         memcpy(&response_msg.buffer[response_msg.index], &request_msg.buffer[x.start], seglen ); \
  19.         response_msg.index += seglen; \
  20. }

  21. void WDEBUG(char *fmt, ...)
  22. {
  23.         char zlog_string[100];
  24.         va_list ap;       

  25.         va_start(ap, fmt);
  26.         vsprintf(zlog_string, fmt, ap);
  27.         strcat(zlog_string, "\r\n");
  28.         printf(zlog_string);       
  29.         va_end(ap);       
  30. }

  31. int32 findEntry(uint8 *oid, int32 len)
  32. {
  33.         int32 i;

  34.         for (i = 0 ; i < maxData ; i++)
  35.         {
  36.                 if (len == snmpData[i].oidlen)
  37.                 {
  38.                         if (!memcmp(snmpData[i].oid, oid, len)) return(i);
  39.                 }
  40.         }

  41.         return OID_NOT_FOUND;
  42. }


  43. int32 getOID(int32 id, uint8 *oid, uint8 *len)
  44. {
  45.         int32 j;

  46.         if (!((id >= 0) && (id < maxData))) return INVALID_ENTRY_ID;

  47.         *len = snmpData[id].oidlen;

  48.         for (j = 0 ; j < *len ; j++)
  49.         {
  50.                 oid[j] = snmpData[id].oid[j];
  51.         }

  52.         return SUCCESS;
  53. }


  54. int32 getValue( uint8 *vptr, int32 vlen)
  55. {
  56.         int32 index = 0;
  57.         int32 value = 0;

  58.         while (index < vlen)
  59.         {
  60.                 if (index != 0) value <<= 8;
  61.                 value |= vptr[index++];
  62.         }

  63.         return value;
  64. }


  65. int32 getEntry(int32 id, uint8 *dataType, void *ptr, int32 *len)
  66. {
  67.         if (!((id >= 0) && (id < maxData))) return INVALID_ENTRY_ID;

  68.         *dataType = snmpData[id].dataType;

  69.         switch(*dataType)
  70.         {
  71.         case SNMPDTYPE_OCTET_STRING :
  72.         case SNMPDTYPE_OBJ_ID :
  73.                 {
  74.                         uint8 *string = ptr;
  75.                         int32 j;

  76.                         if (snmpData[id].getfunction != NULL)
  77.                         {
  78.                                 snmpData[id].getfunction( (void *)&snmpData[id].u.octetstring, &snmpData[id].dataLen );
  79.                         }

  80.                         if ( (*dataType)==SNMPDTYPE_OCTET_STRING )
  81.                         {
  82.                                 snmpData[id].dataLen = (uint8)strlen((int8*)&snmpData[id].u.octetstring);
  83.                         }


  84.                         *len = snmpData[id].dataLen;
  85.                         for (j = 0 ; j < *len ; j++)
  86.                         {
  87.                                 string[j] = snmpData[id].u.octetstring[j];
  88.                         }
  89.                 }
  90.                 break;

  91.         case SNMPDTYPE_INTEGER :
  92.         case SNMPDTYPE_TIME_TICKS :
  93.         case SNMPDTYPE_COUNTER :
  94.         case SNMPDTYPE_GAUGE :
  95.                 {
  96.                         int32 *value = ( int32 * )ptr;

  97.                         if (snmpData[id].getfunction != NULL)
  98.                         {
  99.                                 snmpData[id].getfunction( (void *)&snmpData[id].u.intval, &snmpData[id].dataLen );
  100.                         }

  101.                         *len = sizeof(uint32);
  102.                         *value = HTONL(snmpData[id].u.intval);
  103.                 }
  104.                 break;

  105.         default :
  106.                 return INVALID_DATA_TYPE;
  107.         }

  108.         return SUCCESS;
  109. }


  110. int32 setEntry(int32 id, void *val, int32 vlen, uint8 dataType, int32 index)
  111. {

  112.         int32 retStatus=OID_NOT_FOUND;
  113.         int32 j;

  114.         if (snmpData[id].dataType != dataType)
  115.         {
  116.                 errorStatus = BAD_VALUE;
  117.                 errorIndex = index;
  118.                 return INVALID_DATA_TYPE;
  119.         }

  120.         switch(snmpData[id].dataType)
  121.         {
  122.         case SNMPDTYPE_OCTET_STRING :
  123.         case SNMPDTYPE_OBJ_ID :
  124.                 {
  125.                         uint8 *string = val;
  126.                         for (j = 0 ; j < vlen ; j++)
  127.                         {
  128.                                 snmpData[id].u.octetstring[j] = string[j];
  129.                         }
  130.                         snmpData[id].dataLen = vlen;
  131.                 }
  132.                 retStatus = SUCCESS;
  133.                 break;

  134.         case SNMPDTYPE_INTEGER :
  135.         case SNMPDTYPE_TIME_TICKS :
  136.         case SNMPDTYPE_COUNTER :
  137.         case SNMPDTYPE_GAUGE :
  138.                 {
  139.                         snmpData[id].u.intval = getValue( (uint8 *)val, vlen);
  140.                         snmpData[id].dataLen = vlen;

  141.                         if (snmpData[id].setfunction != NULL)
  142.                         {
  143.                                 snmpData[id].setfunction(snmpData[id].u.intval);
  144.                         }

  145.                 }
  146.                 retStatus = SUCCESS;
  147.                 break;

  148.         default :
  149.                 retStatus = INVALID_DATA_TYPE;
  150.                 break;

  151.         }

  152.         return retStatus;
  153. }


  154. int32 parseLength(const uint8 *msg, int32 *len)
  155. {
  156.         int32 i=1;

  157.         if (msg[0] & 0x80)
  158.         {
  159.                 int32 tlen = (msg[0] & 0x7f) - 1;
  160.                 *len = msg[i++];

  161.                 while (tlen--)
  162.                 {
  163.                         *len <<= 8;
  164.                         *len |= msg[i++];
  165.                 }
  166.         }
  167.         else
  168.         {
  169.                 *len = msg[0];
  170.         }

  171.         return i;
  172. }


  173. int32 parseTLV(const uint8 *msg, int32 index, tlvStructType *tlv)
  174. {
  175.         int32 Llen = 0;

  176.         tlv->start = index;

  177.         Llen = parseLength((const uint8 *)&msg[index+1], &tlv->len );

  178.         tlv->vstart = index + Llen + 1;

  179.         switch (msg[index])
  180.         {
  181.         case SNMPDTYPE_SEQUENCE:
  182.         case GET_REQUEST:
  183.         case GET_NEXT_REQUEST:
  184.         case SET_REQUEST:
  185.                 tlv->nstart = tlv->vstart;
  186.                 break;
  187.         default:
  188.                 tlv->nstart = tlv->vstart + tlv->len;
  189.                 break;
  190.         }

  191.         return 0;
  192. }


  193. void insertRespLen(int32 reqStart, int32 respStart, int32 size)
  194. {
  195.         int32 indexStart, lenLength;
  196.         uint32 mask = 0xff;
  197.         int32 shift = 0;

  198.         if (request_msg.buffer[reqStart+1] & 0x80)
  199.         {
  200.                 lenLength = request_msg.buffer[reqStart+1] & 0x7f;
  201.                 indexStart = respStart+2;

  202.                 while (lenLength--)
  203.                 {
  204.                         response_msg.buffer[indexStart+lenLength] =
  205.                                 (uint8)((size & mask) >> shift);
  206.                         shift+=8;
  207.                         mask <<= shift;
  208.                 }
  209.         }
  210.         else
  211.         {
  212.                 response_msg.buffer[respStart+1] = (uint8)(size & 0xff);
  213.         }
  214. }


  215. int32 parseVarBind(int32 reqType, int32 index)
  216. {
  217.         int32 seglen = 0, id;
  218.         tlvStructType name, value;
  219.         int32 size = 0;
  220.        
  221.         extern const int32 maxData;

  222.         parseTLV(request_msg.buffer, request_msg.index, &name);

  223.         if ( request_msg.buffer[name.start] != SNMPDTYPE_OBJ_ID ) return -1;

  224.         id = findEntry(&request_msg.buffer[name.vstart], name.len);

  225.         if ((reqType == GET_REQUEST) || (reqType == SET_REQUEST))
  226.         {
  227.                 seglen = name.nstart - name.start;
  228.                 COPY_SEGMENT_TEMP20110929(name);
  229.                 size = seglen;
  230.         }
  231.         else if (reqType == GET_NEXT_REQUEST)
  232.         {
  233.                 response_msg.buffer[response_msg.index] = request_msg.buffer[name.start];

  234.                 if (++id >= maxData)
  235.                 {
  236.                         id = OID_NOT_FOUND;
  237.                         seglen = name.nstart - name.start;
  238.                         COPY_SEGMENT_TEMP20110929(name);
  239.                         size = seglen;
  240.                 }
  241.                 else
  242.                 {
  243.                         request_msg.index += name.nstart - name.start;

  244.                         getOID(id, &response_msg.buffer[response_msg.index+2], &response_msg.buffer[response_msg.index+1]);

  245.                         seglen = response_msg.buffer[response_msg.index+1]+2;
  246.                         response_msg.index += seglen ;
  247.                         size = seglen;
  248.                 }
  249.         }

  250.         parseTLV(request_msg.buffer, request_msg.index, &value);

  251.         if (id != OID_NOT_FOUND)
  252.         {
  253.                 uint8 dataType;
  254.                 int32 len;

  255.                 if ((reqType == GET_REQUEST) || (reqType == GET_NEXT_REQUEST))
  256.                 {
  257.                         getEntry(id, &dataType, &response_msg.buffer[response_msg.index+2], &len);

  258.                         response_msg.buffer[response_msg.index] = dataType;
  259.                         response_msg.buffer[response_msg.index+1] = len;
  260.                         seglen = (2 + len);
  261.                         response_msg.index += seglen;

  262.                         request_msg.index += (value.nstart - value.start);

  263.                 }
  264.                 else if (reqType == SET_REQUEST)
  265.                 {
  266.                         setEntry(id, &request_msg.buffer[value.vstart], value.len, request_msg.buffer[value.start], index);
  267.                         seglen = value.nstart - value.start;
  268.                         COPY_SEGMENT_TEMP20110929(value);
  269.                 }
  270.         }
  271.         else
  272.         {
  273.                 seglen = value.nstart - value.start;
  274.                 COPY_SEGMENT_TEMP20110929(value);

  275.                 errorIndex = index;
  276.                 errorStatus = NO_SUCH_NAME;
  277.         }

  278.         size += seglen;

  279.         return size;
  280. }


  281. int32 parseSequence(int32 reqType, int32 index)
  282. {
  283.         int32 seglen;
  284.         tlvStructType seq;
  285.         int32 size = 0, respLoc;

  286.         parseTLV(request_msg.buffer, request_msg.index, &seq);

  287.         if ( request_msg.buffer[seq.start] != SNMPDTYPE_SEQUENCE ) return -1;

  288.         seglen = seq.vstart - seq.start;
  289.         respLoc = response_msg.index;
  290.         COPY_SEGMENT_TEMP20110929(seq);

  291.         size = parseVarBind( reqType, index );
  292.         insertRespLen(seq.start, respLoc, size);
  293.         size += seglen;

  294.         return size;
  295. }


  296. int32 parseSequenceOf(int32 reqType)
  297. {
  298.         int32 seglen;
  299.         tlvStructType seqof;
  300.         int32 size = 0, respLoc;
  301.         int32 index = 0;

  302.         parseTLV(request_msg.buffer, request_msg.index, &seqof);

  303.         if ( request_msg.buffer[seqof.start] != SNMPDTYPE_SEQUENCE_OF ) return -1;

  304.         seglen = seqof.vstart - seqof.start;
  305.         respLoc = response_msg.index;
  306.         COPY_SEGMENT_TEMP20110929(seqof);

  307.         while (request_msg.index < request_msg.len)
  308.         {
  309.                 size += parseSequence( reqType, index++ );
  310.         }

  311.         insertRespLen(seqof.start, respLoc, size);

  312.         return size;
  313. }


  314. int32 parseRequest()
  315. {
  316.         int32 ret, seglen;
  317.         tlvStructType snmpreq, requestid, errStatus, errIndex;
  318.         int32 size = 0, respLoc, reqType;

  319.         parseTLV(request_msg.buffer, request_msg.index, &snmpreq);

  320.         reqType = request_msg.buffer[snmpreq.start];

  321.         if ( !VALID_REQUEST(reqType) ) return -1;

  322.         seglen = snmpreq.vstart - snmpreq.start;
  323.         respLoc = snmpreq.start;
  324.         size += seglen;
  325.         COPY_SEGMENT_TEMP20110929(snmpreq);

  326.         response_msg.buffer[snmpreq.start] = GET_RESPONSE;

  327.         parseTLV(request_msg.buffer, request_msg.index, &requestid);
  328.         seglen = requestid.nstart - requestid.start;
  329.         size += seglen;
  330.         COPY_SEGMENT_TEMP20110929(requestid);

  331.         parseTLV(request_msg.buffer, request_msg.index, &errStatus);
  332.         seglen = errStatus.nstart - errStatus.start;
  333.         size += seglen;
  334.         COPY_SEGMENT_TEMP20110929(errStatus);

  335.         parseTLV(request_msg.buffer, request_msg.index, &errIndex);
  336.         seglen = errIndex.nstart - errIndex.start;
  337.         size += seglen;
  338.         COPY_SEGMENT_TEMP20110929(errIndex);

  339.         ret = parseSequenceOf(reqType);
  340.         if (ret == -1) return -1;
  341.         else size += ret;

  342.         insertRespLen(snmpreq.start, respLoc, size);

  343.         if (errorStatus)
  344.         {
  345.                 response_msg.buffer[errStatus.vstart] = errorStatus;
  346.                 response_msg.buffer[errIndex.vstart] = errorIndex + 1;
  347.         }

  348.         return size;
  349. }


  350. int32 parseCommunity()
  351. {
  352.         int32 seglen;
  353.         tlvStructType community;
  354.         int32 size=0;

  355.         parseTLV(request_msg.buffer, request_msg.index, &community);

  356.         if (!((request_msg.buffer[community.start] == SNMPDTYPE_OCTET_STRING) && (community.len == COMMUNITY_SIZE)))
  357.         {
  358.                 return -1;
  359.         }

  360.         if (!memcmp(&request_msg.buffer[community.vstart], (int8 *)COMMUNITY, COMMUNITY_SIZE))
  361.         {
  362.                 seglen = community.nstart - community.start;
  363.                 size += seglen;
  364.                 COPY_SEGMENT_TEMP20110929(community);

  365.                 size += parseRequest();
  366.         }
  367.         else
  368.         {
  369.                 return -1;
  370.         }

  371.         return size;
  372. }


  373. int32 parseVersion()
  374. {
  375.         int32 size = 0, seglen;
  376.         tlvStructType tlv;

  377.         size = parseTLV(request_msg.buffer, request_msg.index, &tlv);

  378.         if (!((request_msg.buffer[tlv.start] == SNMPDTYPE_INTEGER) && (request_msg.buffer[tlv.vstart] == SNMP_V1)))
  379.                 return -1;

  380.         seglen = tlv.nstart - tlv.start;
  381.         size += seglen;
  382.         COPY_SEGMENT_TEMP20110929(tlv);
  383.         size = parseCommunity();

  384.         if (size == -1) return size;
  385.         else return (size + seglen);
  386. }


  387. int32 parseSNMPMessage()
  388. {
  389.         int32 size = 0, seglen, respLoc;
  390.         tlvStructType tlv;

  391.         parseTLV(request_msg.buffer, request_msg.index, &tlv);

  392.         if (request_msg.buffer[tlv.start] != SNMPDTYPE_SEQUENCE_OF) return -1;

  393.         seglen = tlv.vstart - tlv.start;
  394.         respLoc = tlv.start;
  395.         COPY_SEGMENT_TEMP20110929(tlv);

  396.         size = parseVersion();

  397.         if (size == -1) return -1;
  398.         else size += seglen;

  399.         insertRespLen(tlv.start, respLoc, size);

  400.         return 0;
  401. }


  402. void dumpCode(int8* header, int8* tail, unsigned char *buff, int len)
  403. {
  404.         int i;

  405.         printf(header);

  406.         for (i=0; i<len; i++)
  407.         {
  408.                 if ( i%16==0 )        printf("0x%04x : ", i);
  409.                 printf("%02x ",buff[i]);

  410.                 if ( i%16-15==0 )
  411.                 {
  412.                         int j;
  413.                         printf("  ");
  414.                         for (j=i-15; j<=i; j++)
  415.                         {
  416.                                 if ( isprint(buff[j]) )        printf("%c", buff[j]);
  417.                                 else                                        printf(".");
  418.                         }
  419.                         printf("\r\n");
  420.                 }
  421.         }

  422.         if ( i%16!=0 )
  423.         {
  424.                 int j;
  425.                 int spaces=(len-i+16-i%16)*3+2;
  426.                 for (j=0; j<spaces; j++)         printf(" ");
  427.                 for (j=i-i%16; j<len; j++)
  428.                 {
  429.                         if ( isprint(buff[j]) )        printf("%c", buff[j]);
  430.                         else                                        printf(".");
  431.                 }
  432.         }
  433.         printf(tail);
  434. }

  435. void ipToByteArray(int8 *ip, uint8 *pDes)
  436. {
  437.         uint32 i, ip1=0, ip2=0, ip3=0, ip4=0;
  438.         int8 buff[32];
  439.         uint32 len = (uint32)strlen(ip);
  440.         strcpy(buff, ip);

  441.         for (i=0; i<len; i++)
  442.         {
  443.                 if ( buff[i]=='.' )                buff[i] = ' ';
  444.         }

  445.         sscanf(buff, "%u %u %u %u", &ip1, &ip2, &ip3, &ip4);
  446.         pDes[0] = ip1; pDes[1] = ip2; pDes[2] = ip3; pDes[3] = ip4;
  447. }


  448. int32 makeTrapVariableBindings(dataEntryType *oid_data, void *ptr, uint32 *len)
  449. {
  450.         uint32 j;

  451.         ((uint8*)ptr)[0] = 0x30;
  452.         ((uint8*)ptr)[1] = 0xff;
  453.         ((uint8*)ptr)[2] = 0x06;
  454.         ((uint8*)ptr)[3] = oid_data->oidlen;

  455.         for (j = 0 ; j < oid_data->oidlen ; j++)
  456.         {
  457.                 ((uint8*)ptr)[j+4] = oid_data->oid[j];
  458.         }

  459.         switch(oid_data->dataType)
  460.         {
  461.         case SNMPDTYPE_OCTET_STRING :
  462.         case SNMPDTYPE_OBJ_ID :
  463.                 {
  464.                         uint8 *string = &((uint8*)ptr)[4+oid_data->oidlen+2];

  465.                         if ( oid_data->dataType==SNMPDTYPE_OCTET_STRING )
  466.                         {
  467.                                 oid_data->dataLen = (uint8)strlen((int8*)&oid_data->u.octetstring);
  468.                         }
  469.                         for (j = 0 ; j < oid_data->dataLen ; j++)
  470.                         {
  471.                                 string[j] = oid_data->u.octetstring[j];
  472.                         }

  473.                         ((uint8*)ptr)[4+oid_data->oidlen] = oid_data->dataType;
  474.                         ((uint8*)ptr)[4+oid_data->oidlen+1] = oid_data->dataLen;
  475.                         ((uint8*)ptr)[1] = 2 + oid_data->oidlen + 2 + oid_data->dataLen;
  476.                         *len = 4 + oid_data->oidlen + 2 + oid_data->dataLen;
  477.                 }
  478.                 break;

  479.         case SNMPDTYPE_INTEGER :
  480.         case SNMPDTYPE_TIME_TICKS :
  481.         case SNMPDTYPE_COUNTER :
  482.         case SNMPDTYPE_GAUGE :
  483.                 {
  484.                         oid_data->dataLen = 4;

  485.                         *(int32*)(&((uint8*)ptr)[4+oid_data->oidlen+2]) = HTONL(oid_data->u.intval);

  486.                         ((uint8*)ptr)[4+oid_data->oidlen] = oid_data->dataType;
  487.                         ((uint8*)ptr)[4+oid_data->oidlen+1] = oid_data->dataLen;
  488.                         ((uint8*)ptr)[1] = 2 + oid_data->oidlen + 2 + oid_data->dataLen;
  489.                         *len = 4 + oid_data->oidlen + 2 + oid_data->dataLen;
  490.                 }
  491.                 break;

  492.         default :
  493.                 return INVALID_DATA_TYPE;
  494.         }

  495.         return SUCCESS;
  496. }

  497. int32 SnmpXInit()
  498. {
  499.        
  500. //        initTable();
  501. //        LED3=0;
  502.         return 0;
  503. }

  504. uint8 packet_trap[1024] = {0,};
  505. int32 SnmpXTrapSend(int8* managerIP, int8* agentIP, int8* community, dataEntryType enterprise_oid, uint32 genericTrap, uint32 specificTrap, uint32 va_count, ...)
  506. {
  507.         uint32 i;
  508.         int32 packet_index = 0;
  509.         int32 packet_buff1 = 0;
  510.         int32 packet_buff2 = 0;
  511.         int32 packet_buff3 = 0;
  512.         uint8 trap_agentip[4] = {0,};
  513.        
  514.         ipToByteArray(agentIP, trap_agentip);

  515.         packet_trap[packet_index++] = 0x30; // ASN.1 Header

  516.         packet_trap[packet_index] = 0xff; // pdu_length, temp
  517.         packet_buff1 = packet_index++;

  518.         packet_trap[packet_index++] = 0x02; // Version
  519.         packet_trap[packet_index++] = 0x01;
  520.         packet_trap[packet_index++] = 0x00;
  521.        
  522.         packet_trap[packet_index++] = 0x04; // Community
  523.         packet_trap[packet_index++] = (uint8)strlen(community);
  524.         memcpy(&(packet_trap[packet_index]), community, strlen(community));

  525.         packet_index = packet_index + (uint8)strlen(community);

  526.         packet_trap[packet_index++] = 0xa4; // trap
  527.         packet_trap[packet_index] = 0xff; // length, temp
  528.         packet_buff2 = packet_index++;

  529.         packet_trap[packet_index++] = 0x06; // enterprise_oid
  530.         packet_trap[packet_index++] = enterprise_oid.oidlen;
  531.         for (i=0; i<enterprise_oid.oidlen; i++)
  532.         {
  533.                 packet_trap[packet_index++] = enterprise_oid.oid[i];
  534.         }
  535.        
  536.         packet_trap[packet_index++] = 0x40; // agent ip
  537.         packet_trap[packet_index++] = 0x04;
  538.         packet_trap[packet_index++] = trap_agentip[0];
  539.         packet_trap[packet_index++] = trap_agentip[1];
  540.         packet_trap[packet_index++] = trap_agentip[2];
  541.         packet_trap[packet_index++] = trap_agentip[3];

  542.         packet_trap[packet_index++] = 0x02; // Generic Trap
  543.         packet_trap[packet_index++] = 0x01;
  544.         packet_trap[packet_index++] = (uint8)genericTrap;

  545.         packet_trap[packet_index++] = 0x02; // Specific Trap
  546.         packet_trap[packet_index++] = 0x01;
  547.         packet_trap[packet_index++] = (uint8)specificTrap;

  548.         packet_trap[packet_index++] = 0x43; // Timestamp
  549.         packet_trap[packet_index++] = 0x01;
  550.         packet_trap[packet_index++] = 0x00;

  551.         packet_trap[packet_index++] = 0x30; // Sequence of variable-bindings
  552.         packet_trap[packet_index] = 0xff;
  553.         packet_buff3 = packet_index++;
  554.        
  555.         // variable-bindings
  556.         {
  557.                 va_list ap;
  558.                 uint32 length_var_bindings = 0;
  559.                 uint32 length_buff = 0;

  560.                 va_start (ap, va_count);

  561.                 for (i=0; i<va_count; i++)
  562.                 {
  563.                         dataEntryType* fff = va_arg(ap, dataEntryType*);
  564.                         makeTrapVariableBindings(fff, &(packet_trap[packet_index]), &length_buff);
  565.                         packet_index = packet_index + length_buff;
  566.                         length_var_bindings = length_var_bindings + length_buff;
  567.                 }

  568.                 packet_trap[packet_buff3] = length_var_bindings;

  569.                 va_end (ap);
  570.         }
  571.         packet_trap[packet_buff1] = packet_index - 2;
  572.         packet_trap[packet_buff2] = packet_index - (9 + (uint8)strlen(community));

  573.         // Send Packet
  574.         {
  575.                 uint8 svr_addr[6];

  576.                 //UDPOpen(SOCK_SNMP, 162);
  577.         socket(SOCK_SNMP,Sn_MR_UDP,162,0);
  578.                 ipToByteArray(managerIP, svr_addr);
  579.                 sendto(SOCK_SNMP, packet_trap, packet_index, svr_addr, 162);
  580.                
  581.                 close(SOCK_SNMP);               
  582.                 return 0;
  583.         }
  584. }


  585. int32 SnmpXDaemon()
  586. {
  587.         int32 snmpfd = 0;
  588.         int32 fromlen = 0;
  589.         int32 retStatus = 0;
  590.         int32 len = 0;
  591.         uint8 loopsnmpd = 1;
  592.     uint8 svr_addr[6];
  593.         uint16  svr_port;
  594.         UNUSED(snmpfd);
  595.         UNUSED(fromlen);
  596.         UNUSED(retStatus);
  597. //        UDPOpen(SOCK_SNMP, 161);
  598.     socket(SOCK_SNMP,Sn_MR_UDP,161,0);
  599.         WDEBUG("Start SNMP Daemon(Agent) ");

  600.         while(loopsnmpd)
  601.         {

  602.                 if ( (len = getSn_RX_RSR(SOCK_SNMP))>0 )
  603.                 {
  604.                 request_msg.len= recvfrom(SOCK_SNMP, (uint8 *)&request_msg.buffer[0], len, svr_addr, &svr_port);
  605.                 }
  606.                 else
  607.                 {
  608.                 request_msg.len = 0;
  609.                 continue;
  610.                 }
  611.                 if (request_msg.len > 0)
  612.                 {
  613.                             dumpCode("\r\n[Request]\r\n", "\r\n", request_msg.buffer, request_msg.len);
  614.    
  615.                             request_msg.index = 0;
  616.                             response_msg.index = 0;
  617.                             errorStatus = errorIndex = 0;
  618.    
  619.                             if (parseSNMPMessage() != -1)
  620.                             {
  621.                             sendto(SOCK_SNMP, response_msg.buffer, response_msg.index, svr_addr, svr_port);
  622.                             }
  623.    
  624.                             dumpCode("\r\n[Response]\r\n", "\r\n", response_msg.buffer, response_msg.index);
  625.                          }
  626.             }           
  627.            close(SOCK_SNMP);
  628.          return(0);
  629. }







本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
lightour7788 发表于 2025-3-28 10:00 | 显示全部楼层
谢楼主,正在做snmp,参考一下
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:项目经理
简介:资深嵌入式开发工程师

104

主题

191

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部