Files
w5500-eth/Internet/SNMP/snmp.c
2025-12-10 17:55:05 +03:00

918 lines
25 KiB
C

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <time.h>
#include "socket.h"
#include "snmp.h"
#include "snmp_custom.h"
/********************************************************************************************/
/* SNMP : Functions declaration */
/********************************************************************************************/
// SNMP Parsing functions
int32_t findEntry(uint8_t *oid, int32_t len);
int32_t getOID(int32_t id, uint8_t *oid, uint8_t *len);
int32_t getValue(uint8_t *vptr, int32_t vlen);
int32_t getEntry(int32_t id, uint8_t *dataType, void *ptr, int32_t *len);
int32_t setEntry(int32_t id, void *val, int32_t vlen, uint8_t dataType, int32_t index);
int32_t makeTrapVariableBindings(dataEntryType *oid_data, void *ptr, uint32_t *len);
int32_t parseLength(const uint8_t *msg, int32_t *len);
int32_t parseTLV(const uint8_t *msg, int32_t index, tlvStructType *tlv);
void insertRespLen(int32_t reqStart, int32_t respStart, int32_t size);
int32_t parseVarBind(int32_t reqType, int32_t index);
int32_t parseSequence(int32_t reqType, int32_t index);
int32_t parseSequenceOf(int32_t reqType);
int32_t parseRequest();
int32_t parseCommunity();
int32_t parseVersion();
int32_t parseSNMPMessage();
// Debugging function
#ifdef _SNMP_DEBUG_
void dumpCode(uint8_t* header, uint8_t* tail, uint8_t *buff, int32_t len);
#endif
// Utils
void ipToByteArray(int8_t *ip, uint8_t *pDes);
/********************************************************************************************/
/* SNMP : Variable declaration */
/********************************************************************************************/
// SNMP message structures
struct messageStruct request_msg;
struct messageStruct response_msg;
// SNMP Time counter
static time_t startTime = 0;
volatile uint32_t snmp_tick_10ms = 0; //volatile uint32_t snmp_tick_1ms = 0;
// SNMP Sockets
static uint8_t SOCK_SNMP_AGENT;
static uint8_t SOCK_SNMP_TRAP;
uint8_t packet_trap[MAX_TRAPMSG_LEN] = {0,};
uint8_t errorStatus, errorIndex;
/********************************************************************************************/
/* SNMP : Time handler */
/********************************************************************************************/
void currentUptime(void *ptr, uint8_t *len) {
time_t curTime = getSNMPTimeTick();
//*(uint32_t *)ptr = (uint32_t)(curTime - startTime) / 10; // calculation for 1ms tick
*(uint32_t *)ptr = (uint32_t)(curTime - startTime); // calculation for 10ms tick
*len = 4;
}
void SNMP_time_handler(void) {
//snmp_tick_1ms++;
snmp_tick_10ms++;
}
uint32_t getSNMPTimeTick(void) {
//return snmp_tick_1ms;
return snmp_tick_10ms;
}
/********************************************************************************************/
/* SNMP : Library Part */
/********************************************************************************************/
/**
@addtogroup snmp_module
@{
*/
/**
Initialize SNMP Daemon.
This should be called just one time at first time
@param none
@return none
*/
void snmpd_init(uint8_t * managerIP, uint8_t * agentIP, uint8_t sn_agent, uint8_t sn_trap) {
#ifdef _SNMP_DEBUG_
printf("\r\n - SNMP : Start SNMP Agent Daemon\r\n");
#endif
SOCK_SNMP_AGENT = sn_agent;
SOCK_SNMP_TRAP = sn_trap;
if ((SOCK_SNMP_AGENT > _WIZCHIP_SOCK_NUM_) || (SOCK_SNMP_TRAP > _WIZCHIP_SOCK_NUM_)) {
return;
}
startTime = getSNMPTimeTick(); // Start time (unit: 10ms)
initTable(); // Settings for OID entry values
initial_Trap(managerIP, agentIP);
/*
// Example Codes for SNMP Trap
{
dataEntryType enterprise_oid = {0x0a, {0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x9b, 0x19, 0x01, 0x00},
SNMPDTYPE_OBJ_ID, 0x0a, {"\x2b\x06\x01\x04\x01\x81\x9b\x19\x10\x00"}, NULL, NULL};
dataEntryType trap_oid1 = {8, {0x2b, 6, 1, 4, 1, 0, 11, 0}, SNMPDTYPE_OCTET_STRING, 30, {""}, NULL, NULL};
dataEntryType trap_oid2 = {8, {0x2b, 6, 1, 4, 1, 0, 12, 0}, SNMPDTYPE_INTEGER, 4, {""}, NULL, NULL};
strcpy((char *)trap_oid1.u.octetstring, "Alert!!!"); // String added
trap_oid2.u.intval = 123456; // Integer value added
// Generic Trap: warmStart
snmp_sendTrap((void *)"192.168.0.214", (void *)"192.168.0.112", (void *)"public", enterprise_oid, SNMPTRAP_WARMSTART, 0, 0);
// Enterprise-Specific Trap
snmp_sendTrap((void *)"192.168.0.214", (void *)"192.168.0.112", (void *)"public", enterprise_oid, 6, 0, 2, &trap_oid1, &trap_oid2);
}
*/
}
/**
SNMP Process Handler.
UDP Socket and SNMP Agent transaction handling.
@param none
@return none
*/
int32_t snmpd_run(void) {
int32_t ret;
int32_t len = 0;
uint8_t svr_addr[6];
uint16_t svr_port;
#if 1
// 20231019 taylor
uint8_t addr_len;
#endif
if (SOCK_SNMP_AGENT > _WIZCHIP_SOCK_NUM_) {
return -99;
}
switch (getSn_SR(SOCK_SNMP_AGENT)) {
case SOCK_UDP :
if ((len = getSn_RX_RSR(SOCK_SNMP_AGENT)) > 0) {
#if 1
// 20231019 taylor//teddy 240122
#if ((_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300))
request_msg.len = recvfrom(SOCK_SNMP_AGENT, request_msg.buffer, len, svr_addr, &svr_port, &addr_len);
#else
request_msg.len = recvfrom(SOCK_SNMP_AGENT, request_msg.buffer, len, svr_addr, &svr_port);
#endif
#else
request_msg.len = recvfrom(SOCK_SNMP_AGENT, request_msg.buffer, len, svr_addr, &svr_port);
#endif
} else {
request_msg.len = 0;
}
if (request_msg.len > 0) {
#ifdef _SNMP_DEBUG_
dumpCode((void *)"\r\n[Request]\r\n", (void *)"\r\n", request_msg.buffer, request_msg.len);
#endif
// Initialize
request_msg.index = 0;
response_msg.index = 0;
errorStatus = errorIndex = 0;
memset(response_msg.buffer, 0x00, MAX_SNMPMSG_LEN);
// Received message parsing and send response process
if (parseSNMPMessage() != -1) {
#if 1
// 20231016 taylor//teddy 240122
#if ((_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300))
sendto(SOCK_SNMP_AGENT, response_msg.buffer, response_msg.index, svr_addr, svr_port, 4);
#else
sendto(SOCK_SNMP_AGENT, response_msg.buffer, response_msg.index, svr_addr, svr_port);
#endif
#else
sendto(SOCK_SNMP_AGENT, response_msg.buffer, response_msg.index, svr_addr, svr_port);
#endif
}
#ifdef _SNMP_DEBUG_
dumpCode((void *)"\r\n[Response]\r\n", (void *)"\r\n", response_msg.buffer, response_msg.index);
#endif
}
break;
case SOCK_CLOSED :
if ((ret = socket(SOCK_SNMP_AGENT, Sn_MR_UDP, PORT_SNMP_AGENT, 0x00)) != SOCK_SNMP_AGENT) {
return ret;
}
#ifdef _SNMP_DEBUG_
printf(" - [%d] UDP Socket for SNMP Agent, port [%d]\r\n", SOCK_SNMP_AGENT, PORT_SNMP_AGENT);
#endif
break;
default :
break;
}
return 1;
}
int32_t findEntry(uint8_t *oid, int32_t len) {
int32_t i;
for (i = 0 ; i < maxData ; i++) {
if (len == snmpData[i].oidlen) {
if (!memcmp(snmpData[i].oid, oid, len)) {
return (i);
}
}
}
return OID_NOT_FOUND;
}
int32_t getOID(int32_t id, uint8_t *oid, uint8_t *len) {
int32_t j;
if (!((id >= 0) && (id < maxData))) {
return INVALID_ENTRY_ID;
}
*len = snmpData[id].oidlen;
for (j = 0 ; j < *len ; j++) {
oid[j] = snmpData[id].oid[j];
}
return SNMP_SUCCESS;
}
int32_t getValue(uint8_t *vptr, int32_t vlen) {
int32_t index = 0;
int32_t value = 0;
while (index < vlen) {
if (index != 0) {
value <<= 8;
}
value |= vptr[index++];
}
return value;
}
int32_t getEntry(int32_t id, uint8_t *dataType, void *ptr, int32_t *len) {
uint8_t * ptr_8;
int32_t value;
uint8_t * string;
int32_t j;
if (!((id >= 0) && (id < maxData))) {
return INVALID_ENTRY_ID;
}
*dataType = snmpData[id].dataType;
switch (*dataType) {
case SNMPDTYPE_OCTET_STRING :
case SNMPDTYPE_OBJ_ID : {
string = ptr;
if (snmpData[id].getfunction != NULL) {
snmpData[id].getfunction((void *)&snmpData[id].u.octetstring, &snmpData[id].dataLen);
}
if ((*dataType) == SNMPDTYPE_OCTET_STRING) {
snmpData[id].dataLen = (uint8_t)strlen((char const*)&snmpData[id].u.octetstring);
}
*len = snmpData[id].dataLen;
for (j = 0 ; j < *len ; j++) {
string[j] = snmpData[id].u.octetstring[j];
}
}
break;
case SNMPDTYPE_INTEGER :
case SNMPDTYPE_TIME_TICKS :
case SNMPDTYPE_COUNTER :
case SNMPDTYPE_GAUGE : {
if (snmpData[id].getfunction != NULL) {
snmpData[id].getfunction((void *)&snmpData[id].u.intval, &snmpData[id].dataLen);
}
if (snmpData[id].dataLen) {
*len = snmpData[id].dataLen;
} else {
*len = sizeof(uint32_t);
}
/*
// Original code (IAR, STM32)
// This code is not working in NXP+LPCXpresso (32-bit pointer operation error)
value = (int32_t *)ptr;
value = HTONL(snmpData[id].u.intval);
*/
ptr_8 = ptr;
//value = HTONL(snmpData[id].u.intval); // Endian convert when processing 32bit pointer operation
value = snmpData[id].u.intval;
for (j = 0 ; j < *len ; j++) {
ptr_8[j] = (uint8_t)((value >> ((*len - j - 1) * 8)));
}
}
break;
default :
return INVALID_DATA_TYPE;
}
return SNMP_SUCCESS;
}
int32_t setEntry(int32_t id, void *val, int32_t vlen, uint8_t dataType, int32_t index) {
int32_t retStatus = OID_NOT_FOUND;
int32_t j;
if (snmpData[id].dataType != dataType) {
errorStatus = BAD_VALUE;
errorIndex = index;
return INVALID_DATA_TYPE;
}
switch (snmpData[id].dataType) {
case SNMPDTYPE_OCTET_STRING :
case SNMPDTYPE_OBJ_ID : {
uint8_t *string = val;
for (j = 0 ; j < vlen ; j++) {
snmpData[id].u.octetstring[j] = string[j];
}
snmpData[id].dataLen = vlen;
}
retStatus = SNMP_SUCCESS;
break;
case SNMPDTYPE_INTEGER :
case SNMPDTYPE_TIME_TICKS :
case SNMPDTYPE_COUNTER :
case SNMPDTYPE_GAUGE : {
snmpData[id].u.intval = getValue((uint8_t *)val, vlen);
snmpData[id].dataLen = vlen;
if (snmpData[id].setfunction != NULL) {
snmpData[id].setfunction(snmpData[id].u.intval);
}
}
retStatus = SNMP_SUCCESS;
break;
default :
retStatus = INVALID_DATA_TYPE;
break;
}
return retStatus;
}
int32_t parseLength(const uint8_t *msg, int32_t *len) {
int32_t i = 1;
if (msg[0] & 0x80) {
int32_t tlen = (msg[0] & 0x7f) - 1;
*len = msg[i++];
while (tlen--) {
*len <<= 8;
*len |= msg[i++];
}
} else {
*len = msg[0];
}
return i;
}
int32_t parseTLV(const uint8_t *msg, int32_t index, tlvStructType *tlv) {
int32_t Llen = 0;
tlv->start = index;
Llen = parseLength((const uint8_t *)&msg[index + 1], &tlv->len);
tlv->vstart = index + Llen + 1;
switch (msg[index]) {
case SNMPDTYPE_SEQUENCE:
case GET_REQUEST:
case GET_NEXT_REQUEST:
case SET_REQUEST:
tlv->nstart = tlv->vstart;
break;
default:
tlv->nstart = tlv->vstart + tlv->len;
break;
}
return 0;
}
void insertRespLen(int32_t reqStart, int32_t respStart, int32_t size) {
int32_t indexStart, lenLength;
uint32_t mask = 0xff;
int32_t shift = 0;
if (request_msg.buffer[reqStart + 1] & 0x80) {
lenLength = request_msg.buffer[reqStart + 1] & 0x7f;
indexStart = respStart + 2;
while (lenLength--) {
response_msg.buffer[indexStart + lenLength] =
(uint8_t)((size & mask) >> shift);
shift += 8;
mask <<= shift;
}
} else {
response_msg.buffer[respStart + 1] = (uint8_t)(size & 0xff);
}
}
int32_t parseVarBind(int32_t reqType, int32_t index) {
int32_t seglen = 0, id;
tlvStructType name, value;
int32_t size = 0;
//extern const int32_t maxData;
parseTLV(request_msg.buffer, request_msg.index, &name);
if (request_msg.buffer[name.start] != SNMPDTYPE_OBJ_ID) {
return -1;
}
id = findEntry(&request_msg.buffer[name.vstart], name.len);
if ((reqType == GET_REQUEST) || (reqType == SET_REQUEST)) {
seglen = name.nstart - name.start;
COPY_SEGMENT(name);
size = seglen;
} else if (reqType == GET_NEXT_REQUEST) {
response_msg.buffer[response_msg.index] = request_msg.buffer[name.start];
if (++id >= maxData) {
id = OID_NOT_FOUND;
seglen = name.nstart - name.start;
COPY_SEGMENT(name);
size = seglen;
} else {
request_msg.index += name.nstart - name.start;
getOID(id, &response_msg.buffer[response_msg.index + 2], &response_msg.buffer[response_msg.index + 1]);
seglen = response_msg.buffer[response_msg.index + 1] + 2;
response_msg.index += seglen ;
size = seglen;
}
}
parseTLV(request_msg.buffer, request_msg.index, &value);
if (id != OID_NOT_FOUND) {
uint8_t dataType;
int32_t len;
if ((reqType == GET_REQUEST) || (reqType == GET_NEXT_REQUEST)) {
getEntry(id, &dataType, &response_msg.buffer[response_msg.index + 2], &len);
response_msg.buffer[response_msg.index] = dataType;
response_msg.buffer[response_msg.index + 1] = len;
seglen = (2 + len);
response_msg.index += seglen;
request_msg.index += (value.nstart - value.start);
} else if (reqType == SET_REQUEST) {
setEntry(id, &request_msg.buffer[value.vstart], value.len, request_msg.buffer[value.start], index);
seglen = value.nstart - value.start;
COPY_SEGMENT(value);
}
} else {
seglen = value.nstart - value.start;
COPY_SEGMENT(value);
errorIndex = index;
errorStatus = NO_SUCH_NAME;
}
size += seglen;
return size;
}
int32_t parseSequence(int32_t reqType, int32_t index) {
int32_t seglen;
tlvStructType seq;
int32_t size = 0, respLoc;
parseTLV(request_msg.buffer, request_msg.index, &seq);
if (request_msg.buffer[seq.start] != SNMPDTYPE_SEQUENCE) {
return -1;
}
seglen = seq.vstart - seq.start;
respLoc = response_msg.index;
COPY_SEGMENT(seq);
size = parseVarBind(reqType, index);
insertRespLen(seq.start, respLoc, size);
size += seglen;
return size;
}
int32_t parseSequenceOf(int32_t reqType) {
int32_t seglen;
tlvStructType seqof;
int32_t size = 0, respLoc;
int32_t index = 0;
parseTLV(request_msg.buffer, request_msg.index, &seqof);
if (request_msg.buffer[seqof.start] != SNMPDTYPE_SEQUENCE_OF) {
return -1;
}
seglen = seqof.vstart - seqof.start;
respLoc = response_msg.index;
COPY_SEGMENT(seqof);
while (request_msg.index < request_msg.len) {
size += parseSequence(reqType, index++);
}
insertRespLen(seqof.start, respLoc, size);
return size;
}
int32_t parseRequest() {
int32_t ret, seglen;
tlvStructType snmpreq, requestid, errStatus, errIndex;
int32_t size = 0, respLoc, reqType;
parseTLV(request_msg.buffer, request_msg.index, &snmpreq);
reqType = request_msg.buffer[snmpreq.start];
if (!VALID_REQUEST(reqType)) {
return -1;
}
seglen = snmpreq.vstart - snmpreq.start;
respLoc = snmpreq.start;
size += seglen;
COPY_SEGMENT(snmpreq);
response_msg.buffer[snmpreq.start] = GET_RESPONSE;
parseTLV(request_msg.buffer, request_msg.index, &requestid);
seglen = requestid.nstart - requestid.start;
size += seglen;
COPY_SEGMENT(requestid);
parseTLV(request_msg.buffer, request_msg.index, &errStatus);
seglen = errStatus.nstart - errStatus.start;
size += seglen;
COPY_SEGMENT(errStatus);
parseTLV(request_msg.buffer, request_msg.index, &errIndex);
seglen = errIndex.nstart - errIndex.start;
size += seglen;
COPY_SEGMENT(errIndex);
ret = parseSequenceOf(reqType);
if (ret == -1) {
return -1;
} else {
size += ret;
}
insertRespLen(snmpreq.start, respLoc, size);
if (errorStatus) {
response_msg.buffer[errStatus.vstart] = errorStatus;
response_msg.buffer[errIndex.vstart] = errorIndex + 1;
}
return size;
}
int32_t parseCommunity() {
int32_t seglen;
tlvStructType community;
int32_t size = 0;
parseTLV(request_msg.buffer, request_msg.index, &community);
if (!((request_msg.buffer[community.start] == SNMPDTYPE_OCTET_STRING) && (community.len == COMMUNITY_SIZE))) {
return -1;
}
if (!memcmp(&request_msg.buffer[community.vstart], (int8_t *)COMMUNITY, COMMUNITY_SIZE)) {
seglen = community.nstart - community.start;
size += seglen;
COPY_SEGMENT(community);
size += parseRequest();
} else {
return -1;
}
return size;
}
int32_t parseVersion() {
int32_t size = 0, seglen;
tlvStructType tlv;
size = parseTLV(request_msg.buffer, request_msg.index, &tlv);
if (!((request_msg.buffer[tlv.start] == SNMPDTYPE_INTEGER) && (request_msg.buffer[tlv.vstart] == SNMP_V1))) {
return -1;
}
seglen = tlv.nstart - tlv.start;
size += seglen;
COPY_SEGMENT(tlv);
size = parseCommunity();
if (size == -1) {
return size;
} else {
return (size + seglen);
}
}
int32_t parseSNMPMessage() {
int32_t size = 0, seglen, respLoc;
tlvStructType tlv;
parseTLV(request_msg.buffer, request_msg.index, &tlv);
if (request_msg.buffer[tlv.start] != SNMPDTYPE_SEQUENCE_OF) {
return -1;
}
seglen = tlv.vstart - tlv.start;
respLoc = tlv.start;
COPY_SEGMENT(tlv);
size = parseVersion();
if (size == -1) {
return -1;
} else {
size += seglen;
}
insertRespLen(tlv.start, respLoc, size);
return 0;
}
void ipToByteArray(int8_t *ip, uint8_t *pDes) {
uint32_t i, ip1 = 0, ip2 = 0, ip3 = 0, ip4 = 0;
int8_t buff[32];
uint32_t len = (uint32_t)strlen((char const*)ip);
strcpy((char *)buff, (char const*)ip);
for (i = 0; i < len; i++) {
if (buff[i] == '.') {
buff[i] = ' ';
}
}
sscanf((char const*)buff, "%u %u %u %u", &ip1, &ip2, &ip3, &ip4);
pDes[0] = ip1; pDes[1] = ip2; pDes[2] = ip3; pDes[3] = ip4;
}
int32_t makeTrapVariableBindings(dataEntryType *oid_data, void *ptr, uint32_t *len) {
uint32_t j;
((uint8_t*)ptr)[0] = 0x30;
((uint8_t*)ptr)[1] = 0xff;
((uint8_t*)ptr)[2] = 0x06;
((uint8_t*)ptr)[3] = oid_data->oidlen;
for (j = 0 ; j < oid_data->oidlen ; j++) {
((uint8_t*)ptr)[j + 4] = oid_data->oid[j];
}
switch (oid_data->dataType) {
case SNMPDTYPE_OCTET_STRING :
case SNMPDTYPE_OBJ_ID : {
uint8_t *string = &((uint8_t*)ptr)[4 + oid_data->oidlen + 2];
if (oid_data->dataType == SNMPDTYPE_OCTET_STRING) {
oid_data->dataLen = (uint8_t)strlen((char const*)&oid_data->u.octetstring);
}
for (j = 0 ; j < oid_data->dataLen ; j++) {
string[j] = oid_data->u.octetstring[j];
}
((uint8_t*)ptr)[4 + oid_data->oidlen] = oid_data->dataType;
((uint8_t*)ptr)[4 + oid_data->oidlen + 1] = oid_data->dataLen;
((uint8_t*)ptr)[1] = 2 + oid_data->oidlen + 2 + oid_data->dataLen;
*len = 4 + oid_data->oidlen + 2 + oid_data->dataLen;
}
break;
case SNMPDTYPE_INTEGER :
case SNMPDTYPE_TIME_TICKS :
case SNMPDTYPE_COUNTER :
case SNMPDTYPE_GAUGE : {
oid_data->dataLen = 4;
*(int32_t*)(&((uint8_t*)ptr)[4 + oid_data->oidlen + 2]) = HTONL(oid_data->u.intval);
((uint8_t*)ptr)[4 + oid_data->oidlen] = oid_data->dataType;
((uint8_t*)ptr)[4 + oid_data->oidlen + 1] = oid_data->dataLen;
((uint8_t*)ptr)[1] = 2 + oid_data->oidlen + 2 + oid_data->dataLen;
*len = 4 + oid_data->oidlen + 2 + oid_data->dataLen;
}
break;
default :
return INVALID_DATA_TYPE;
}
return SNMP_SUCCESS;
}
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, ...) {
uint32_t i;
int32_t packet_index = 0;
int32_t packet_buff1 = 0;
int32_t packet_buff2 = 0;
int32_t packet_buff3 = 0;
va_list ap;
uint32_t length_var_bindings = 0;
uint32_t length_buff = 0;
//SNMP Trap packet generation
packet_trap[packet_index++] = 0x30; // ASN.1 Header
packet_trap[packet_index] = 0xff; // pdu_length, temp
packet_buff1 = packet_index++;
packet_trap[packet_index++] = 0x02; // Version
packet_trap[packet_index++] = 0x01;
packet_trap[packet_index++] = 0x00;
packet_trap[packet_index++] = 0x04; // Community
packet_trap[packet_index++] = (uint8_t)strlen((char const*)community);
memcpy(&(packet_trap[packet_index]), community, strlen((char const*)community));
packet_index = packet_index + (uint8_t)strlen((char const*)community);
packet_trap[packet_index++] = 0xa4; // trap
packet_trap[packet_index] = 0xff; // length, temp
packet_buff2 = packet_index++;
packet_trap[packet_index++] = 0x06; // enterprise_oid
packet_trap[packet_index++] = enterprise_oid.oidlen;
for (i = 0; i < enterprise_oid.oidlen; i++) {
packet_trap[packet_index++] = enterprise_oid.oid[i];
}
packet_trap[packet_index++] = 0x40; // agent ip
packet_trap[packet_index++] = 0x04;
packet_trap[packet_index++] = agentIP[0];
packet_trap[packet_index++] = agentIP[1];
packet_trap[packet_index++] = agentIP[2];
packet_trap[packet_index++] = agentIP[3];
packet_trap[packet_index++] = 0x02; // Generic Trap
packet_trap[packet_index++] = 0x01;
packet_trap[packet_index++] = (uint8_t)genericTrap;
packet_trap[packet_index++] = 0x02; // Specific Trap
packet_trap[packet_index++] = 0x01;
packet_trap[packet_index++] = (uint8_t)specificTrap;
packet_trap[packet_index++] = 0x43; // Timestamp
packet_trap[packet_index++] = 0x01;
packet_trap[packet_index++] = 0x00;
packet_trap[packet_index++] = 0x30; // Sequence of variable-bindings
packet_trap[packet_index] = 0xff;
packet_buff3 = packet_index++;
// variable-bindings
{
va_start(ap, va_count);
for (i = 0; i < va_count; i++) {
dataEntryType* fff = va_arg(ap, dataEntryType*);
makeTrapVariableBindings(fff, &(packet_trap[packet_index]), &length_buff);
packet_index = packet_index + length_buff;
length_var_bindings = length_var_bindings + length_buff;
}
packet_trap[packet_buff3] = length_var_bindings;
va_end(ap);
}
packet_trap[packet_buff1] = packet_index - 2;
packet_trap[packet_buff2] = packet_index - (9 + (uint8_t)strlen((char const*)community));
// Send SNMP Trap Packet to NMS
{
socket(SOCK_SNMP_TRAP, Sn_MR_UDP, PORT_SNMP_TRAP, 0);
#if 1
// 20231016 taylor//teddy 240122
#if ((_WIZCHIP_ == 6100) || (_WIZCHIP_ == 6300))
sendto(SOCK_SNMP_TRAP, packet_trap, packet_index, managerIP, PORT_SNMP_TRAP, 4);
#else
sendto(SOCK_SNMP_TRAP, packet_trap, packet_index, managerIP, PORT_SNMP_TRAP);
#endif
#else
sendto(SOCK_SNMP_TRAP, packet_trap, packet_index, managerIP, PORT_SNMP_TRAP);
#endif
close(SOCK_SNMP_TRAP);
return 0;
}
}
#ifdef _SNMP_DEBUG_
void dumpCode(uint8_t* header, uint8_t* tail, uint8_t *buff, int32_t len) {
int i;
printf((char const*)header);
for (i = 0; i < len; i++) {
if (i % 16 == 0) {
printf("0x%04x : ", i);
}
printf("%02x ", buff[i]);
if (i % 16 - 15 == 0) {
int j;
printf(" ");
for (j = i - 15; j <= i; j++) {
if (isprint(buff[j])) {
printf("%c", buff[j]);
} else {
printf(".");
}
}
printf("\r\n");
}
}
if (i % 16 != 0) {
int j;
int spaces = (len - i + 16 - i % 16) * 3 + 2;
for (j = 0; j < spaces; j++) {
printf(" ");
}
for (j = i - i % 16; j < len; j++) {
if (isprint(buff[j])) {
printf("%c", buff[j]);
} else {
printf(".");
}
}
}
printf((char const*)tail);
}
#endif