snmp.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include <stdarg.h>
  5. #include <time.h>
  6. #include "socket.h"
  7. #include "snmp.h"
  8. #include "snmp_custom.h"
  9. /********************************************************************************************/
  10. /* SNMP : Functions declaration */
  11. /********************************************************************************************/
  12. // SNMP Parsing functions
  13. int32_t findEntry(uint8_t *oid, int32_t len);
  14. int32_t getOID(int32_t id, uint8_t *oid, uint8_t *len);
  15. int32_t getValue( uint8_t *vptr, int32_t vlen);
  16. int32_t getEntry(int32_t id, uint8_t *dataType, void *ptr, int32_t *len);
  17. int32_t setEntry(int32_t id, void *val, int32_t vlen, uint8_t dataType, int32_t index);
  18. int32_t makeTrapVariableBindings(dataEntryType *oid_data, void *ptr, uint32_t *len);
  19. int32_t parseLength(const uint8_t *msg, int32_t *len);
  20. int32_t parseTLV(const uint8_t *msg, int32_t index, tlvStructType *tlv);
  21. void insertRespLen(int32_t reqStart, int32_t respStart, int32_t size);
  22. int32_t parseVarBind(int32_t reqType, int32_t index);
  23. int32_t parseSequence(int32_t reqType, int32_t index);
  24. int32_t parseSequenceOf(int32_t reqType);
  25. int32_t parseRequest();
  26. int32_t parseCommunity();
  27. int32_t parseVersion();
  28. int32_t parseSNMPMessage();
  29. // Debugging function
  30. #ifdef _SNMP_DEBUG_
  31. void dumpCode(uint8_t* header, uint8_t* tail, uint8_t *buff, int32_t len);
  32. #endif
  33. // Utils
  34. void ipToByteArray(int8_t *ip, uint8_t *pDes);
  35. /********************************************************************************************/
  36. /* SNMP : Variable declaration */
  37. /********************************************************************************************/
  38. // SNMP message structures
  39. struct messageStruct request_msg;
  40. struct messageStruct response_msg;
  41. // SNMP Time counter
  42. static time_t startTime = 0;
  43. volatile uint32_t snmp_tick_10ms = 0; //volatile uint32_t snmp_tick_1ms = 0;
  44. // SNMP Sockets
  45. static uint8_t SOCK_SNMP_AGENT;
  46. static uint8_t SOCK_SNMP_TRAP;
  47. uint8_t packet_trap[MAX_TRAPMSG_LEN] = {0,};
  48. uint8_t errorStatus, errorIndex;
  49. /********************************************************************************************/
  50. /* SNMP : Time handler */
  51. /********************************************************************************************/
  52. void currentUptime(void *ptr, uint8_t *len)
  53. {
  54. time_t curTime = getSNMPTimeTick();
  55. //*(uint32_t *)ptr = (uint32_t)(curTime - startTime) / 10; // calculation for 1ms tick
  56. *(uint32_t *)ptr = (uint32_t)(curTime - startTime); // calculation for 10ms tick
  57. *len = 4;
  58. }
  59. void SNMP_time_handler(void)
  60. {
  61. //snmp_tick_1ms++;
  62. snmp_tick_10ms++;
  63. }
  64. uint32_t getSNMPTimeTick(void)
  65. {
  66. //return snmp_tick_1ms;
  67. return snmp_tick_10ms;
  68. }
  69. /********************************************************************************************/
  70. /* SNMP : Library Part */
  71. /********************************************************************************************/
  72. /**
  73. * @addtogroup snmp_module
  74. * @{
  75. */
  76. /**
  77. * Initialize SNMP Daemon.
  78. * This should be called just one time at first time
  79. *
  80. * @param none
  81. * @return none
  82. */
  83. void snmpd_init(uint8_t * managerIP, uint8_t * agentIP, uint8_t sn_agent, uint8_t sn_trap)
  84. {
  85. #ifdef _SNMP_DEBUG_
  86. printf("\r\n - SNMP : Start SNMP Agent Daemon\r\n");
  87. #endif
  88. SOCK_SNMP_AGENT = sn_agent;
  89. SOCK_SNMP_TRAP = sn_trap;
  90. if((SOCK_SNMP_AGENT > _WIZCHIP_SOCK_NUM_) || (SOCK_SNMP_TRAP > _WIZCHIP_SOCK_NUM_)) return;
  91. startTime = getSNMPTimeTick(); // Start time (unit: 10ms)
  92. initTable(); // Settings for OID entry values
  93. initial_Trap(managerIP, agentIP);
  94. /*
  95. // Example Codes for SNMP Trap
  96. {
  97. dataEntryType enterprise_oid = {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x9b, 0x19, 0x01, 0x00},
  98. SNMPDTYPE_OBJ_ID, 0x0a, {"\x2b\x06\x01\x04\x01\x81\x9b\x19\x10\x00"}, NULL, NULL};
  99. dataEntryType trap_oid1 = {8, {0x2b, 6, 1, 4, 1, 0, 11, 0}, SNMPDTYPE_OCTET_STRING, 30, {""}, NULL, NULL};
  100. dataEntryType trap_oid2 = {8, {0x2b, 6, 1, 4, 1, 0, 12, 0}, SNMPDTYPE_INTEGER, 4, {""}, NULL, NULL};
  101. strcpy((char *)trap_oid1.u.octetstring, "Alert!!!"); // String added
  102. trap_oid2.u.intval = 123456; // Integer value added
  103. // Generic Trap: warmStart
  104. snmp_sendTrap((void *)"192.168.0.214", (void *)"192.168.0.112", (void *)"public", enterprise_oid, SNMPTRAP_WARMSTART, 0, 0);
  105. // Enterprise-Specific Trap
  106. snmp_sendTrap((void *)"192.168.0.214", (void *)"192.168.0.112", (void *)"public", enterprise_oid, 6, 0, 2, &trap_oid1, &trap_oid2);
  107. }
  108. */
  109. }
  110. /**
  111. * SNMP Process Handler.
  112. * UDP Socket and SNMP Agent transaction handling.
  113. *
  114. * @param none
  115. * @return none
  116. */
  117. int32_t snmpd_run(void)
  118. {
  119. int32_t ret;
  120. int32_t len = 0;
  121. uint8_t svr_addr[6];
  122. uint16_t svr_port;
  123. if(SOCK_SNMP_AGENT > _WIZCHIP_SOCK_NUM_) return -99;
  124. switch(getSn_SR(SOCK_SNMP_AGENT))
  125. {
  126. case SOCK_UDP :
  127. if ( (len = getSn_RX_RSR(SOCK_SNMP_AGENT)) > 0)
  128. {
  129. request_msg.len= recvfrom(SOCK_SNMP_AGENT, request_msg.buffer, len, svr_addr, &svr_port);
  130. }
  131. else
  132. {
  133. request_msg.len = 0;
  134. }
  135. if (request_msg.len > 0)
  136. {
  137. #ifdef _SNMP_DEBUG_
  138. dumpCode((void *)"\r\n[Request]\r\n", (void *)"\r\n", request_msg.buffer, request_msg.len);
  139. #endif
  140. // Initialize
  141. request_msg.index = 0;
  142. response_msg.index = 0;
  143. errorStatus = errorIndex = 0;
  144. memset(response_msg.buffer, 0x00, MAX_SNMPMSG_LEN);
  145. // Received message parsing and send response process
  146. if (parseSNMPMessage() != -1)
  147. {
  148. sendto(SOCK_SNMP_AGENT, response_msg.buffer, response_msg.index, svr_addr, svr_port);
  149. }
  150. #ifdef _SNMP_DEBUG_
  151. dumpCode((void *)"\r\n[Response]\r\n", (void *)"\r\n", response_msg.buffer, response_msg.index);
  152. #endif
  153. }
  154. break;
  155. case SOCK_CLOSED :
  156. if((ret = socket(SOCK_SNMP_AGENT, Sn_MR_UDP, PORT_SNMP_AGENT, 0x00)) != SOCK_SNMP_AGENT)
  157. return ret;
  158. #ifdef _SNMP_DEBUG_
  159. printf(" - [%d] UDP Socket for SNMP Agent, port [%d]\r\n", SOCK_SNMP_AGENT, PORT_SNMP_AGENT);
  160. #endif
  161. break;
  162. default :
  163. break;
  164. }
  165. return 1;
  166. }
  167. int32_t findEntry(uint8_t *oid, int32_t len)
  168. {
  169. int32_t i;
  170. for (i = 0 ; i < maxData ; i++)
  171. {
  172. if (len == snmpData[i].oidlen)
  173. {
  174. if (!memcmp(snmpData[i].oid, oid, len)) return(i);
  175. }
  176. }
  177. return OID_NOT_FOUND;
  178. }
  179. int32_t getOID(int32_t id, uint8_t *oid, uint8_t *len)
  180. {
  181. int32_t j;
  182. if (!((id >= 0) && (id < maxData))) return INVALID_ENTRY_ID;
  183. *len = snmpData[id].oidlen;
  184. for (j = 0 ; j < *len ; j++)
  185. {
  186. oid[j] = snmpData[id].oid[j];
  187. }
  188. return SNMP_SUCCESS;
  189. }
  190. int32_t getValue( uint8_t *vptr, int32_t vlen)
  191. {
  192. int32_t index = 0;
  193. int32_t value = 0;
  194. while (index < vlen)
  195. {
  196. if (index != 0) value <<= 8;
  197. value |= vptr[index++];
  198. }
  199. return value;
  200. }
  201. int32_t getEntry(int32_t id, uint8_t *dataType, void *ptr, int32_t *len)
  202. {
  203. uint8_t * ptr_8;
  204. int32_t value;
  205. uint8_t * string;
  206. int32_t j;
  207. if (!((id >= 0) && (id < maxData))) return INVALID_ENTRY_ID;
  208. *dataType = snmpData[id].dataType;
  209. switch(*dataType)
  210. {
  211. case SNMPDTYPE_OCTET_STRING :
  212. case SNMPDTYPE_OBJ_ID :
  213. {
  214. string = ptr;
  215. if (snmpData[id].getfunction != NULL)
  216. {
  217. snmpData[id].getfunction( (void *)&snmpData[id].u.octetstring, &snmpData[id].dataLen );
  218. }
  219. if ( (*dataType)==SNMPDTYPE_OCTET_STRING )
  220. {
  221. snmpData[id].dataLen = (uint8_t)strlen((char const*)&snmpData[id].u.octetstring);
  222. }
  223. *len = snmpData[id].dataLen;
  224. for (j = 0 ; j < *len ; j++)
  225. {
  226. string[j] = snmpData[id].u.octetstring[j];
  227. }
  228. }
  229. break;
  230. case SNMPDTYPE_INTEGER :
  231. case SNMPDTYPE_TIME_TICKS :
  232. case SNMPDTYPE_COUNTER :
  233. case SNMPDTYPE_GAUGE :
  234. {
  235. if (snmpData[id].getfunction != NULL)
  236. {
  237. snmpData[id].getfunction( (void *)&snmpData[id].u.intval, &snmpData[id].dataLen );
  238. }
  239. if(snmpData[id].dataLen) *len = snmpData[id].dataLen;
  240. else *len = sizeof(uint32_t);
  241. /*
  242. // Original code (IAR, STM32)
  243. // This code is not working in NXP+LPCXpresso (32-bit pointer operation error)
  244. value = (int32_t *)ptr;
  245. *value = HTONL(snmpData[id].u.intval);
  246. */
  247. ptr_8 = ptr;
  248. //value = HTONL(snmpData[id].u.intval); // Endian convert when processing 32bit pointer operation
  249. value = snmpData[id].u.intval;
  250. for (j = 0 ; j < *len ; j++)
  251. {
  252. ptr_8[j] = (uint8_t)((value >> ((*len-j-1)*8)));
  253. }
  254. }
  255. break;
  256. default :
  257. return INVALID_DATA_TYPE;
  258. }
  259. return SNMP_SUCCESS;
  260. }
  261. int32_t setEntry(int32_t id, void *val, int32_t vlen, uint8_t dataType, int32_t index)
  262. {
  263. int32_t retStatus=OID_NOT_FOUND;
  264. int32_t j;
  265. if (snmpData[id].dataType != dataType)
  266. {
  267. errorStatus = BAD_VALUE;
  268. errorIndex = index;
  269. return INVALID_DATA_TYPE;
  270. }
  271. switch(snmpData[id].dataType)
  272. {
  273. case SNMPDTYPE_OCTET_STRING :
  274. case SNMPDTYPE_OBJ_ID :
  275. {
  276. uint8_t *string = val;
  277. for (j = 0 ; j < vlen ; j++)
  278. {
  279. snmpData[id].u.octetstring[j] = string[j];
  280. }
  281. snmpData[id].dataLen = vlen;
  282. }
  283. retStatus = SNMP_SUCCESS;
  284. break;
  285. case SNMPDTYPE_INTEGER :
  286. case SNMPDTYPE_TIME_TICKS :
  287. case SNMPDTYPE_COUNTER :
  288. case SNMPDTYPE_GAUGE :
  289. {
  290. snmpData[id].u.intval = getValue( (uint8_t *)val, vlen);
  291. snmpData[id].dataLen = vlen;
  292. if (snmpData[id].setfunction != NULL)
  293. {
  294. snmpData[id].setfunction(snmpData[id].u.intval);
  295. }
  296. }
  297. retStatus = SNMP_SUCCESS;
  298. break;
  299. default :
  300. retStatus = INVALID_DATA_TYPE;
  301. break;
  302. }
  303. return retStatus;
  304. }
  305. int32_t parseLength(const uint8_t *msg, int32_t *len)
  306. {
  307. int32_t i=1;
  308. if (msg[0] & 0x80)
  309. {
  310. int32_t tlen = (msg[0] & 0x7f) - 1;
  311. *len = msg[i++];
  312. while (tlen--)
  313. {
  314. *len <<= 8;
  315. *len |= msg[i++];
  316. }
  317. }
  318. else
  319. {
  320. *len = msg[0];
  321. }
  322. return i;
  323. }
  324. int32_t parseTLV(const uint8_t *msg, int32_t index, tlvStructType *tlv)
  325. {
  326. int32_t Llen = 0;
  327. tlv->start = index;
  328. Llen = parseLength((const uint8_t *)&msg[index+1], &tlv->len );
  329. tlv->vstart = index + Llen + 1;
  330. switch (msg[index])
  331. {
  332. case SNMPDTYPE_SEQUENCE:
  333. case GET_REQUEST:
  334. case GET_NEXT_REQUEST:
  335. case SET_REQUEST:
  336. tlv->nstart = tlv->vstart;
  337. break;
  338. default:
  339. tlv->nstart = tlv->vstart + tlv->len;
  340. break;
  341. }
  342. return 0;
  343. }
  344. void insertRespLen(int32_t reqStart, int32_t respStart, int32_t size)
  345. {
  346. int32_t indexStart, lenLength;
  347. uint32_t mask = 0xff;
  348. int32_t shift = 0;
  349. if (request_msg.buffer[reqStart+1] & 0x80)
  350. {
  351. lenLength = request_msg.buffer[reqStart+1] & 0x7f;
  352. indexStart = respStart+2;
  353. while (lenLength--)
  354. {
  355. response_msg.buffer[indexStart+lenLength] =
  356. (uint8_t)((size & mask) >> shift);
  357. shift+=8;
  358. mask <<= shift;
  359. }
  360. }
  361. else
  362. {
  363. response_msg.buffer[respStart+1] = (uint8_t)(size & 0xff);
  364. }
  365. }
  366. int32_t parseVarBind(int32_t reqType, int32_t index)
  367. {
  368. int32_t seglen = 0, id;
  369. tlvStructType name, value;
  370. int32_t size = 0;
  371. //extern const int32_t maxData;
  372. parseTLV(request_msg.buffer, request_msg.index, &name);
  373. if ( request_msg.buffer[name.start] != SNMPDTYPE_OBJ_ID ) return -1;
  374. id = findEntry(&request_msg.buffer[name.vstart], name.len);
  375. if ((reqType == GET_REQUEST) || (reqType == SET_REQUEST))
  376. {
  377. seglen = name.nstart - name.start;
  378. COPY_SEGMENT(name);
  379. size = seglen;
  380. }
  381. else if (reqType == GET_NEXT_REQUEST)
  382. {
  383. response_msg.buffer[response_msg.index] = request_msg.buffer[name.start];
  384. if (++id >= maxData)
  385. {
  386. id = OID_NOT_FOUND;
  387. seglen = name.nstart - name.start;
  388. COPY_SEGMENT(name);
  389. size = seglen;
  390. }
  391. else
  392. {
  393. request_msg.index += name.nstart - name.start;
  394. getOID(id, &response_msg.buffer[response_msg.index+2], &response_msg.buffer[response_msg.index+1]);
  395. seglen = response_msg.buffer[response_msg.index+1]+2;
  396. response_msg.index += seglen ;
  397. size = seglen;
  398. }
  399. }
  400. parseTLV(request_msg.buffer, request_msg.index, &value);
  401. if (id != OID_NOT_FOUND)
  402. {
  403. uint8_t dataType;
  404. int32_t len;
  405. if ((reqType == GET_REQUEST) || (reqType == GET_NEXT_REQUEST))
  406. {
  407. getEntry(id, &dataType, &response_msg.buffer[response_msg.index+2], &len);
  408. response_msg.buffer[response_msg.index] = dataType;
  409. response_msg.buffer[response_msg.index+1] = len;
  410. seglen = (2 + len);
  411. response_msg.index += seglen;
  412. request_msg.index += (value.nstart - value.start);
  413. }
  414. else if (reqType == SET_REQUEST)
  415. {
  416. setEntry(id, &request_msg.buffer[value.vstart], value.len, request_msg.buffer[value.start], index);
  417. seglen = value.nstart - value.start;
  418. COPY_SEGMENT(value);
  419. }
  420. }
  421. else
  422. {
  423. seglen = value.nstart - value.start;
  424. COPY_SEGMENT(value);
  425. errorIndex = index;
  426. errorStatus = NO_SUCH_NAME;
  427. }
  428. size += seglen;
  429. return size;
  430. }
  431. int32_t parseSequence(int32_t reqType, int32_t index)
  432. {
  433. int32_t seglen;
  434. tlvStructType seq;
  435. int32_t size = 0, respLoc;
  436. parseTLV(request_msg.buffer, request_msg.index, &seq);
  437. if ( request_msg.buffer[seq.start] != SNMPDTYPE_SEQUENCE ) return -1;
  438. seglen = seq.vstart - seq.start;
  439. respLoc = response_msg.index;
  440. COPY_SEGMENT(seq);
  441. size = parseVarBind( reqType, index );
  442. insertRespLen(seq.start, respLoc, size);
  443. size += seglen;
  444. return size;
  445. }
  446. int32_t parseSequenceOf(int32_t reqType)
  447. {
  448. int32_t seglen;
  449. tlvStructType seqof;
  450. int32_t size = 0, respLoc;
  451. int32_t index = 0;
  452. parseTLV(request_msg.buffer, request_msg.index, &seqof);
  453. if ( request_msg.buffer[seqof.start] != SNMPDTYPE_SEQUENCE_OF ) return -1;
  454. seglen = seqof.vstart - seqof.start;
  455. respLoc = response_msg.index;
  456. COPY_SEGMENT(seqof);
  457. while (request_msg.index < request_msg.len)
  458. {
  459. size += parseSequence( reqType, index++ );
  460. }
  461. insertRespLen(seqof.start, respLoc, size);
  462. return size;
  463. }
  464. int32_t parseRequest()
  465. {
  466. int32_t ret, seglen;
  467. tlvStructType snmpreq, requestid, errStatus, errIndex;
  468. int32_t size = 0, respLoc, reqType;
  469. parseTLV(request_msg.buffer, request_msg.index, &snmpreq);
  470. reqType = request_msg.buffer[snmpreq.start];
  471. if ( !VALID_REQUEST(reqType) ) return -1;
  472. seglen = snmpreq.vstart - snmpreq.start;
  473. respLoc = snmpreq.start;
  474. size += seglen;
  475. COPY_SEGMENT(snmpreq);
  476. response_msg.buffer[snmpreq.start] = GET_RESPONSE;
  477. parseTLV(request_msg.buffer, request_msg.index, &requestid);
  478. seglen = requestid.nstart - requestid.start;
  479. size += seglen;
  480. COPY_SEGMENT(requestid);
  481. parseTLV(request_msg.buffer, request_msg.index, &errStatus);
  482. seglen = errStatus.nstart - errStatus.start;
  483. size += seglen;
  484. COPY_SEGMENT(errStatus);
  485. parseTLV(request_msg.buffer, request_msg.index, &errIndex);
  486. seglen = errIndex.nstart - errIndex.start;
  487. size += seglen;
  488. COPY_SEGMENT(errIndex);
  489. ret = parseSequenceOf(reqType);
  490. if (ret == -1) return -1;
  491. else size += ret;
  492. insertRespLen(snmpreq.start, respLoc, size);
  493. if (errorStatus)
  494. {
  495. response_msg.buffer[errStatus.vstart] = errorStatus;
  496. response_msg.buffer[errIndex.vstart] = errorIndex + 1;
  497. }
  498. return size;
  499. }
  500. int32_t parseCommunity()
  501. {
  502. int32_t seglen;
  503. tlvStructType community;
  504. int32_t size=0;
  505. parseTLV(request_msg.buffer, request_msg.index, &community);
  506. if (!((request_msg.buffer[community.start] == SNMPDTYPE_OCTET_STRING) && (community.len == COMMUNITY_SIZE)))
  507. {
  508. return -1;
  509. }
  510. if (!memcmp(&request_msg.buffer[community.vstart], (int8_t *)COMMUNITY, COMMUNITY_SIZE))
  511. {
  512. seglen = community.nstart - community.start;
  513. size += seglen;
  514. COPY_SEGMENT(community);
  515. size += parseRequest();
  516. }
  517. else
  518. {
  519. return -1;
  520. }
  521. return size;
  522. }
  523. int32_t parseVersion()
  524. {
  525. int32_t size = 0, seglen;
  526. tlvStructType tlv;
  527. size = parseTLV(request_msg.buffer, request_msg.index, &tlv);
  528. if (!((request_msg.buffer[tlv.start] == SNMPDTYPE_INTEGER) && (request_msg.buffer[tlv.vstart] == SNMP_V1)))
  529. return -1;
  530. seglen = tlv.nstart - tlv.start;
  531. size += seglen;
  532. COPY_SEGMENT(tlv);
  533. size = parseCommunity();
  534. if (size == -1) return size;
  535. else return (size + seglen);
  536. }
  537. int32_t parseSNMPMessage()
  538. {
  539. int32_t size = 0, seglen, respLoc;
  540. tlvStructType tlv;
  541. parseTLV(request_msg.buffer, request_msg.index, &tlv);
  542. if (request_msg.buffer[tlv.start] != SNMPDTYPE_SEQUENCE_OF) return -1;
  543. seglen = tlv.vstart - tlv.start;
  544. respLoc = tlv.start;
  545. COPY_SEGMENT(tlv);
  546. size = parseVersion();
  547. if (size == -1) return -1;
  548. else size += seglen;
  549. insertRespLen(tlv.start, respLoc, size);
  550. return 0;
  551. }
  552. void ipToByteArray(int8_t *ip, uint8_t *pDes)
  553. {
  554. uint32_t i, ip1=0, ip2=0, ip3=0, ip4=0;
  555. int8_t buff[32];
  556. uint32_t len = (uint32_t)strlen((char const*)ip);
  557. strcpy((char *)buff, (char const*)ip);
  558. for (i=0; i<len; i++)
  559. {
  560. if ( buff[i]=='.' ) buff[i] = ' ';
  561. }
  562. sscanf((char const*)buff, "%u %u %u %u", &ip1, &ip2, &ip3, &ip4);
  563. pDes[0] = ip1; pDes[1] = ip2; pDes[2] = ip3; pDes[3] = ip4;
  564. }
  565. int32_t makeTrapVariableBindings(dataEntryType *oid_data, void *ptr, uint32_t *len)
  566. {
  567. uint32_t j;
  568. ((uint8_t*)ptr)[0] = 0x30;
  569. ((uint8_t*)ptr)[1] = 0xff;
  570. ((uint8_t*)ptr)[2] = 0x06;
  571. ((uint8_t*)ptr)[3] = oid_data->oidlen;
  572. for (j = 0 ; j < oid_data->oidlen ; j++)
  573. {
  574. ((uint8_t*)ptr)[j+4] = oid_data->oid[j];
  575. }
  576. switch(oid_data->dataType)
  577. {
  578. case SNMPDTYPE_OCTET_STRING :
  579. case SNMPDTYPE_OBJ_ID :
  580. {
  581. uint8_t *string = &((uint8_t*)ptr)[4+oid_data->oidlen+2];
  582. if ( oid_data->dataType==SNMPDTYPE_OCTET_STRING )
  583. {
  584. oid_data->dataLen = (uint8_t)strlen((char const*)&oid_data->u.octetstring);
  585. }
  586. for (j = 0 ; j < oid_data->dataLen ; j++)
  587. {
  588. string[j] = oid_data->u.octetstring[j];
  589. }
  590. ((uint8_t*)ptr)[4+oid_data->oidlen] = oid_data->dataType;
  591. ((uint8_t*)ptr)[4+oid_data->oidlen+1] = oid_data->dataLen;
  592. ((uint8_t*)ptr)[1] = 2 + oid_data->oidlen + 2 + oid_data->dataLen;
  593. *len = 4 + oid_data->oidlen + 2 + oid_data->dataLen;
  594. }
  595. break;
  596. case SNMPDTYPE_INTEGER :
  597. case SNMPDTYPE_TIME_TICKS :
  598. case SNMPDTYPE_COUNTER :
  599. case SNMPDTYPE_GAUGE :
  600. {
  601. oid_data->dataLen = 4;
  602. *(int32_t*)(&((uint8_t*)ptr)[4+oid_data->oidlen+2]) = HTONL(oid_data->u.intval);
  603. ((uint8_t*)ptr)[4+oid_data->oidlen] = oid_data->dataType;
  604. ((uint8_t*)ptr)[4+oid_data->oidlen+1] = oid_data->dataLen;
  605. ((uint8_t*)ptr)[1] = 2 + oid_data->oidlen + 2 + oid_data->dataLen;
  606. *len = 4 + oid_data->oidlen + 2 + oid_data->dataLen;
  607. }
  608. break;
  609. default :
  610. return INVALID_DATA_TYPE;
  611. }
  612. return SNMP_SUCCESS;
  613. }
  614. int32_t snmp_sendTrap(uint8_t * managerIP, uint8_t * agentIP, int8_t* community, dataEntryType enterprise_oid, uint32_t genericTrap, uint32_t specificTrap, uint32_t va_count, ...)
  615. {
  616. uint32_t i;
  617. int32_t packet_index = 0;
  618. int32_t packet_buff1 = 0;
  619. int32_t packet_buff2 = 0;
  620. int32_t packet_buff3 = 0;
  621. va_list ap;
  622. uint32_t length_var_bindings = 0;
  623. uint32_t length_buff = 0;
  624. //SNMP Trap packet generation
  625. packet_trap[packet_index++] = 0x30; // ASN.1 Header
  626. packet_trap[packet_index] = 0xff; // pdu_length, temp
  627. packet_buff1 = packet_index++;
  628. packet_trap[packet_index++] = 0x02; // Version
  629. packet_trap[packet_index++] = 0x01;
  630. packet_trap[packet_index++] = 0x00;
  631. packet_trap[packet_index++] = 0x04; // Community
  632. packet_trap[packet_index++] = (uint8_t)strlen((char const*)community);
  633. memcpy(&(packet_trap[packet_index]), community, strlen((char const*)community));
  634. packet_index = packet_index + (uint8_t)strlen((char const*)community);
  635. packet_trap[packet_index++] = 0xa4; // trap
  636. packet_trap[packet_index] = 0xff; // length, temp
  637. packet_buff2 = packet_index++;
  638. packet_trap[packet_index++] = 0x06; // enterprise_oid
  639. packet_trap[packet_index++] = enterprise_oid.oidlen;
  640. for (i=0; i<enterprise_oid.oidlen; i++)
  641. {
  642. packet_trap[packet_index++] = enterprise_oid.oid[i];
  643. }
  644. packet_trap[packet_index++] = 0x40; // agent ip
  645. packet_trap[packet_index++] = 0x04;
  646. packet_trap[packet_index++] = agentIP[0];
  647. packet_trap[packet_index++] = agentIP[1];
  648. packet_trap[packet_index++] = agentIP[2];
  649. packet_trap[packet_index++] = agentIP[3];
  650. packet_trap[packet_index++] = 0x02; // Generic Trap
  651. packet_trap[packet_index++] = 0x01;
  652. packet_trap[packet_index++] = (uint8_t)genericTrap;
  653. packet_trap[packet_index++] = 0x02; // Specific Trap
  654. packet_trap[packet_index++] = 0x01;
  655. packet_trap[packet_index++] = (uint8_t)specificTrap;
  656. packet_trap[packet_index++] = 0x43; // Timestamp
  657. packet_trap[packet_index++] = 0x01;
  658. packet_trap[packet_index++] = 0x00;
  659. packet_trap[packet_index++] = 0x30; // Sequence of variable-bindings
  660. packet_trap[packet_index] = 0xff;
  661. packet_buff3 = packet_index++;
  662. // variable-bindings
  663. {
  664. va_start (ap, va_count);
  665. for (i=0; i<va_count; i++)
  666. {
  667. dataEntryType* fff = va_arg(ap, dataEntryType*);
  668. makeTrapVariableBindings(fff, &(packet_trap[packet_index]), &length_buff);
  669. packet_index = packet_index + length_buff;
  670. length_var_bindings = length_var_bindings + length_buff;
  671. }
  672. packet_trap[packet_buff3] = length_var_bindings;
  673. va_end (ap);
  674. }
  675. packet_trap[packet_buff1] = packet_index - 2;
  676. packet_trap[packet_buff2] = packet_index - (9 + (uint8_t)strlen((char const*)community));
  677. // Send SNMP Trap Packet to NMS
  678. {
  679. socket(SOCK_SNMP_TRAP, Sn_MR_UDP, PORT_SNMP_TRAP, 0);
  680. sendto(SOCK_SNMP_TRAP, packet_trap, packet_index, managerIP, PORT_SNMP_TRAP);
  681. close(SOCK_SNMP_TRAP);
  682. return 0;
  683. }
  684. }
  685. #ifdef _SNMP_DEBUG_
  686. void dumpCode(uint8_t* header, uint8_t* tail, uint8_t *buff, int32_t len)
  687. {
  688. int i;
  689. printf((char const*)header);
  690. for (i=0; i<len; i++)
  691. {
  692. if ( i%16==0 ) printf("0x%04x : ", i);
  693. printf("%02x ",buff[i]);
  694. if ( i%16-15==0 )
  695. {
  696. int j;
  697. printf(" ");
  698. for (j=i-15; j<=i; j++)
  699. {
  700. if ( isprint(buff[j]) ) printf("%c", buff[j]);
  701. else printf(".");
  702. }
  703. printf("\r\n");
  704. }
  705. }
  706. if ( i%16!=0 )
  707. {
  708. int j;
  709. int spaces=(len-i+16-i%16)*3+2;
  710. for (j=0; j<spaces; j++) printf(" ");
  711. for (j=i-i%16; j<len; j++)
  712. {
  713. if ( isprint(buff[j]) ) printf("%c", buff[j]);
  714. else printf(".");
  715. }
  716. }
  717. printf((char const*)tail);
  718. }
  719. #endif