u_char * cmu_snmp_parse(netsnmp_session * session, netsnmp_pdu *pdu, u_char * data, size_t length) { u_char *bufp = NULL; snmp_sess_init(session); /* gimme a break! */ switch (pdu->version) { case SNMP_VERSION_1: case SNMP_VERSION_2c: case SNMP_DEFAULT_VERSION: break; default: return NULL; } #ifndef NO_INTERNAL_VARLIST if (snmp_parse(0, session, pdu, data, length) != SNMP_ERR_NOERROR) { return NULL; } #else /* * while there are two versions of variable_list: * use an internal variable list for snmp_parse; * clone the result. */ if (1) { netsnmp_pdu *snmp_clone_pdu(netsnmp_pdu *); netsnmp_pdu *snmp_2clone_pdu(netsnmp_pdu *from_pdu, netsnmp_pdu *to_pdu); netsnmp_pdu *ipdu; ipdu = snmp_clone_pdu(pdu); if (snmp_parse(0, session, ipdu, data, length) != SNMP_ERR_NOERROR) { snmp_free_internal_pdu(ipdu); return NULL; } pdu = snmp_2clone_pdu(ipdu, pdu); snmp_free_internal_pdu(ipdu); } #endif /* NO_INTERNAL_VAR_LIST */ /* * Add a null to meet the caller's expectations. */ bufp = (u_char *) malloc(1 + pdu->community_len); if (bufp && pdu->community_len) { memcpy(bufp, pdu->community, pdu->community_len); bufp[pdu->community_len] = '\0'; } return (bufp); }
THREAD(udpTrapReceiveThread, arg) { //NutThreadSetPriority(32); NH * nh = (NH*)arg; uint8_t data[256]; uint32_t addr; uint16_t port; int i; for(;;) { i = NutUdpReceiveFrom(nh->udpTrapSock, &addr, &port, data, 256, 0); //printf("Some trap traffic...\n"); data[i] = '\0'; if (i > 0) { //printf("a trap received...\n"); if(nh->opponent == addr) { snmpPacket* packetIn = snmp_packetalloc(); //input snmp_parse(packetIn, data, i); uint8_t* ptr = (uint8_t*)packetIn->value; strcpy(nh->trapMessage, ptr); // printf("Viesti: \"%s\"\n", ptr); nh->opponent = 0; snmp_free(packetIn); } }else if( i== 0) printf("trap thread running\n"); else printf("trap thread running\n"); } }
int main(void) { netsnmp_session session; netsnmp_pdu *pdu; netsnmp_variable_list *vars; int status=45,ctr; pdu = (netsnmp_pdu *) calloc(1, sizeof(netsnmp_pdu)); if (pdu) { pdu->version = SNMP_VERSION_1; pdu->command = SNMP_MSG_RESPONSE; pdu->errstat = SNMP_DEFAULT_ERRSTAT; pdu->errindex = SNMP_DEFAULT_ERRINDEX; pdu->securityModel = SNMP_DEFAULT_SECMODEL; pdu->transport_data = NULL; pdu->transport_data_length = 0; pdu->securityNameLen = 0; pdu->contextNameLen = 0; pdu->time = 0; pdu->reqid = snmp_get_next_reqid(); pdu->msgid = snmp_get_next_msgid(); } printf("Message before parsing"); for(ctr=0;ctr<pktlen;ctr++) printf("%x",pkt[ctr]); printf("\n\n"); status=snmp_parse(&session,pdu,pkt,pktlen); printf("Status %d",status); for(vars = pdu->variables; vars; vars = vars->next_variable) { print_variable(vars->name, vars->name_length, vars); printf("printing.."); } return (0); }
THREAD(udpReceiveThread, arg) { NH * nh = (NH*)arg; uint8_t data[256]; uint32_t addr; uint16_t port; int i; for(;;) { i = NutUdpReceiveFrom(nh->udpSock, &addr, &port, data, 256, 0); data[i] = '\0'; if (i > 0) { //printf("Udp connection\n"); //printf("%s:%d \n", inet_ntoa(addr), port); //fflush(stdout); //bool doCleanPacketIn = true; snmpPacket* packetIn = snmp_packetalloc(); snmpPacket* packetOut = snmp_packetalloc(); snmp_parse(packetIn, data, i); packetOut->command = SNMP_GET_RESP; packetOut->requestID = packetIn->requestID; packetOut->objectID = packetIn->objectID; long value; // --- vastataan ready to play -viestiin if(packetIn->objectID == 1 && packetIn->command == SNMP_GET_REQ) //READY-TO-PLAY -message { if(nh->readyToPlay == true) value = 1; else value = 0; packetOut->valueType = SNMP_INT; packetOut->valueLength = 1; packetOut->value = &value; packetOut->error = 0x00; snmp_construct(packetOut); NutUdpSendTo(nh->udpSock, addr, port, packetOut->packet, packetOut->length); } // --- odotetaan vastausta ready to play viestiin else if(nh->getOpponentList && packetIn->objectID == 1 && packetIn->command == SNMP_GET_RESP) { uint8_t tmp; tmp = *((uint8_t*)(packetIn->value)); if(tmp == 1) //fill the opponent list, if broadcast is sent { nh->opponentList[nh->numOpponents] = addr; nh->numOpponents++; } } // --- haaste vastaanotettu else if (nh->opponent == 0 && packetIn->objectID == 2 && packetIn->command == SNMP_SET_REQ) { nh->openRequest = true; nh->opponent = addr; nh->requestID = packetIn->requestID; } //haaste vastaanotettu, mutta meillä oli jo haaste päällä else if ( (nh->openRequest || addr != nh->opponent) && packetIn->objectID == 2 && packetIn->command == SNMP_SET_REQ) NH_sendSnmpError(nh, addr, SNMP_PORT, SNMP_GET_RESP, 2, packetOut->requestID); // --- odotetaan vastausta haasteeseen else if( packetIn->objectID == 2 && nh->challengeSend == true && nh->opponent == addr && packetIn->command == SNMP_GET_RESP ) { nh->challengeSend = false; if( packetIn->error != 0x00) nh->opponent = false; else nh->challengeAccepted = true; } // --- odotetaan vastustajan START-TURN else if(packetIn->objectID == 2 && nh->opponent == addr && packetIn->command == SNMP_SET_REQ ) { nh->enemyStartedTurn = true; //printf("NW: enemy started turn\n"); } // --- odotetaan vastustajalta OK-viestiä else if(nh->opponent == addr && packetIn->command == SNMP_GET_RESP && packetIn->objectID == nh->currentOID && packetIn->valueType == SNMP_INT) { if(packetIn->error == 0x00) { nh->enemyOK = true; //printf("NW: Received enemyOK!\n"); } } // --- odotetaan salvoja else if( packetIn->objectID == 3 && nh->opponent == addr && packetIn->command == SNMP_SET_REQ ) { nh->enemySalvoReceived = true; //printf("NW: SALVO received (%d):\n", nh->enemySalvoReceived); // debug uint8_t* ptr = (uint8_t*)packetIn->value; for(i = 0; i < 5; i++) { nh->lastEnemySalvo[i].x = ptr[i*2]; nh->lastEnemySalvo[i].y = ptr[i*2+1]; //printf("%d - %d\n", nh->lastEnemySalvo[i].x, nh->lastEnemySalvo[i].y); } // OK vastaus NH_sendBooleanResponse(nh, 3, true); } // --- Odotetaan salvon tuloksia else if( packetIn->objectID == 4 && nh->opponent == addr && packetIn->command == SNMP_GET_RESP) { //printf("NW: SALVO results received: \n"); // debug uint8_t* ptr = (uint8_t*)packetIn->value; for (i = 0; i < 5; i++) nh->salvoResults[i] = ptr[i]; //debug //for (i = 0; i < 5; i++) //printf("%d: %d\n", i, nh->salvoResults[i]); nh->salvoResultsReceived = true; } // --- odotetaan salvon tuloksien pyyntöä else if(packetIn->objectID == 4 && packetIn->command == SNMP_GET_REQ && nh->opponent == addr) { nh->resultsQueryReceived = true; //printf("NW: enemy asked for salvo results: %d\n", nh->resultsQueryReceived); } // --- chattiviesti: else if(packetIn->objectID == 5 && packetIn->command == SNMP_SET_REQ && packetIn->valueType == SNMP_OCT) { /* uint8_t* ptr = (uint8_t*)packetIn->value; //lisätään viestin alkuun lähettähän ip sprintf(nh->chatMsgs[nh->emptyMsg], inet_ntoa(addr)); strcat(nh->chatMsgs[nh->emptyMsg], ":\n"); strncat(nh->chatMsgs[nh->emptyMsg], message, MAX_MSG_LENGTH - 16); //lisätään viesti listaan sprintf(chatMsgs[nh->emptyMsg], ptr); nh->manageMessages(); */ } else if(packetIn->command == SNMP_GET_REQ) //debug { printf("NW: weird SNMP_GET_REQ received, OID: %d, opponent: %s", packetIn->objectID, inet_ntoa(nh->opponent)); } snmp_free(packetIn); snmp_free(packetOut); } else if (i == 0) { printf ("Udp timeout\n"); } else { printf ("Udp error\n"); } } }
// unload the data into SNMP++ objects int SnmpMessage::unload(Pdu &pdu, // Pdu object OctetStr &community, // community object snmp_version &version, // SNMP version # OctetStr *engine_id, // optional v3 OctetStr *security_name, // optional v3 long int *security_model, UdpAddress *from_addr, Snmp *snmp_session) { pdu.clear(); if (!valid_flag) return SNMP_CLASS_INVALID; snmp_pdu *raw_pdu; raw_pdu = snmp_pdu_create(0); // do a "snmp_free_pdu( raw_pdu)" before return int status; #ifdef _SNMPv3 OctetStr context_engine_id; OctetStr context_name; long int security_level = SNMP_SECURITY_LEVEL_NOAUTH_NOPRIV; if ((security_model) && (security_name) && (engine_id) && (snmp_session)) { status = v3MP::I->snmp_parse(snmp_session, raw_pdu, databuff, (int)bufflen, *engine_id, *security_name, context_engine_id, context_name, security_level, *security_model, version, *from_addr); if (status != SNMPv3_MP_OK) { pdu.set_request_id( raw_pdu->reqid); pdu.set_type( raw_pdu->command); snmp_free_pdu( raw_pdu); return status; } pdu.set_context_engine_id(context_engine_id); pdu.set_context_name(context_name); pdu.set_security_level(security_level); pdu.set_message_id(raw_pdu->msgid); pdu.set_maxsize_scopedpdu(raw_pdu->maxsize_scopedpdu); } else { #endif unsigned char community_name[MAX_LEN_COMMUNITY + 1]; int community_len = MAX_LEN_COMMUNITY + 1; status = snmp_parse(raw_pdu, databuff, (int) bufflen, community_name, community_len, version); if (status != SNMP_CLASS_SUCCESS) { snmp_free_pdu(raw_pdu); return status; } community.set_data( community_name, community_len); #ifdef _SNMPv3 } #endif // load up the SNMP++ variables pdu.set_request_id(raw_pdu->reqid); pdu.set_error_status((int) raw_pdu->errstat); pdu.set_error_index((int) raw_pdu->errindex); pdu.set_type( raw_pdu->command); // deal with traps a little different if ( raw_pdu->command == sNMP_PDU_V1TRAP) { // timestamp TimeTicks timestamp; timestamp = raw_pdu->time; pdu.set_notify_timestamp( timestamp); // set the agent address IpAddress agent_addr(inet_ntoa(raw_pdu->agent_addr.sin_addr)); if (agent_addr != "0.0.0.0") { pdu.set_v1_trap_address(agent_addr); LOG_BEGIN(DEBUG_LOG | 4); LOG("SNMPMessage: Trap address of received v1 trap"); LOG(agent_addr.get_printable()); LOG_END; } // set enterprise, notifyid Oid enterprise; if (raw_pdu->enterprise_length >0) { for (int i=0; i< raw_pdu->enterprise_length; i++) { enterprise += (int) (raw_pdu->enterprise[i]); } pdu.set_notify_enterprise(enterprise); } switch (raw_pdu->trap_type) { case 0: pdu.set_notify_id(coldStart); break; case 1: pdu.set_notify_id(warmStart); break; case 2: pdu.set_notify_id(linkDown); break; case 3: pdu.set_notify_id(linkUp); break; case 4: pdu.set_notify_id(authenticationFailure); break; case 5: pdu.set_notify_id(egpNeighborLoss); break; case 6: { // enterprise specific // base id + specific # Oid eOid = enterprise; eOid += 0ul; eOid += raw_pdu->specific_type; pdu.set_notify_id( eOid); break; } default: { LOG_BEGIN(WARNING_LOG | 3); LOG("SNMPMessage: Received trap with illegal trap type"); LOG(raw_pdu->trap_type); LOG_END; } } } // vbs Vb tempvb; Oid tempoid; struct variable_list *vp; int vb_nr = 1; for(vp = raw_pdu->variables; vp; vp = vp->next_variable, vb_nr++) { // extract the oid portion tempoid.set_data( (unsigned long *)vp->name, ( unsigned int) vp->name_length); tempvb.set_oid( tempoid); // extract the value portion switch(vp->type){ // octet string case sNMP_SYNTAX_OCTETS: { OctetStr octets( (unsigned char *) vp->val.string, (unsigned long) vp->val_len); tempvb.set_value( octets); } break; case sNMP_SYNTAX_OPAQUE: { OpaqueStr octets( (unsigned char *) vp->val.string, (unsigned long) vp->val_len); tempvb.set_value( octets); } break; // object id case sNMP_SYNTAX_OID: { Oid oid( (unsigned long*) vp->val.objid, (int) vp->val_len); tempvb.set_value( oid); if ((vb_nr == 2) && ((raw_pdu->command == sNMP_PDU_TRAP) || (raw_pdu->command == sNMP_PDU_INFORM)) && (tempoid == SNMP_MSG_OID_TRAPID)) { // set notify_id pdu.set_notify_id(oid); continue; // don't add vb to pdu } } break; // timeticks case sNMP_SYNTAX_TIMETICKS: { TimeTicks timeticks( (unsigned long) *(vp->val.integer)); tempvb.set_value( timeticks); if ((vb_nr == 1) && ((raw_pdu->command == sNMP_PDU_TRAP) || (raw_pdu->command == sNMP_PDU_INFORM)) && (tempoid == SNMP_MSG_OID_SYSUPTIME)) { // set notify_timestamp pdu.set_notify_timestamp( timeticks); continue; // don't add vb to pdu } } break; // 32 bit counter case sNMP_SYNTAX_CNTR32: { Counter32 counter32( (unsigned long) *(vp->val.integer)); tempvb.set_value( counter32); } break; // 32 bit gauge case sNMP_SYNTAX_GAUGE32: { Gauge32 gauge32( (unsigned long) *(vp->val.integer)); tempvb.set_value( gauge32); } break; // ip address case sNMP_SYNTAX_IPADDR: { char buffer[42]; if (vp->val_len == 16) sprintf( buffer, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:" "%02x%02x:%02x%02x:%02x%02x:%02x%02x", vp->val.string[ 0], vp->val.string[ 1], vp->val.string[ 2], vp->val.string[ 3], vp->val.string[ 4], vp->val.string[ 5], vp->val.string[ 6], vp->val.string[ 7], vp->val.string[ 8], vp->val.string[ 9], vp->val.string[10], vp->val.string[11], vp->val.string[12], vp->val.string[13], vp->val.string[14], vp->val.string[15]); else sprintf( buffer,"%d.%d.%d.%d", vp->val.string[0], vp->val.string[1], vp->val.string[2], vp->val.string[3]); IpAddress ipaddress( buffer); tempvb.set_value( ipaddress); } break; // 32 bit integer case sNMP_SYNTAX_INT: { SnmpInt32 int32( (long) *(vp->val.integer)); tempvb.set_value( int32); } break; // 32 bit unsigned integer /* Not distinguishable from Gauge32 case sNMP_SYNTAX_UINT32: { SnmpUInt32 uint32( (unsigned long) *(vp->val.integer)); tempvb.set_value( uint32); } break; */ // v2 counter 64's case sNMP_SYNTAX_CNTR64: { // Frank Fock (was empty before) Counter64 c64(((counter64*)vp->val.counter64)->high, ((counter64*)vp->val.counter64)->low); tempvb.set_value( c64); break; } case sNMP_SYNTAX_NULL: tempvb.set_null(); break; // v2 vb exceptions case sNMP_SYNTAX_NOSUCHOBJECT: case sNMP_SYNTAX_NOSUCHINSTANCE: case sNMP_SYNTAX_ENDOFMIBVIEW: tempvb.set_exception_status(vp->type); break; default: tempvb.set_null(); } // end switch // append the vb to the pdu pdu += tempvb; } snmp_free_pdu( raw_pdu); return SNMP_CLASS_SUCCESS; }
int main(void) { netsnmp_session session; netsnmp_pdu *pdu; netsnmp_variable_list *vars; int status=45,ctr,i; pdu = (netsnmp_pdu *) calloc(1, sizeof(netsnmp_pdu)); if (pdu) { //pdu->version = SNMP_VERSION_1; //pdu->command = SNMP_MSG_RESPONSE; //pdu->errstat = SNMP_DEFAULT_ERRSTAT; //pdu->errindex = SNMP_DEFAULT_ERRINDEX; pdu->securityModel = SNMP_DEFAULT_SECMODEL; pdu->transport_data = NULL; pdu->transport_data_length = 0; pdu->securityNameLen = 0; pdu->contextNameLen = 0; pdu->time = 0; pdu->reqid = snmp_get_next_reqid(); pdu->msgid = snmp_get_next_msgid(); } printf("Message before parsing\n"); for(ctr=0;ctr<pktlen;ctr++) printf("%x",pkt[ctr]); printf("\n\n"); status=snmp_parse(&session,pdu,pkt,pktlen); printf("Status %d",status); for(vars = pdu->variables; vars; vars = vars->next_variable) { print_variable(vars->name, vars->name_length, vars); } printf("pdu:\nversion:%ld\ncommand:%d\n",pdu->version,pdu->command); printf("Decoding done. \n Now encoding..."); status=snmp_build(&newpkt,&newpktlen,&offset,&session,pdu); printf("\nstatus = %d\n",status); printf("\nnewpktlen = %d\n",newpktlen); printf("\noffset = %d\n",offset); if(status==0 || status==-20) { //newpktlen=sizeof(newpkt); //printf("seems successful\n Here's the new packet:\npktlen :%d\n",newpktlen); printf("Packet dump : \n"); for(ctr=newpktlen-offset;ctr<newpktlen;ctr++) { printf("%X",newpkt[ctr]); } printf("\nPacket dump - END \n"); for(ctr=newpktlen-offset,i=0;i<pktlen && ctr<newpktlen;i++,ctr++) { if(newpkt[ctr]!=pkt[i]) { printf("\nMISMATCH"); exit(1); } } printf("\nMATCH!!!!\n Parse successful\n"); } return (0); }