⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 protocol.c

📁 Snmp(简单网管协议)软件包。
💻 C
📖 第 1 页 / 共 3 页
字号:
 * |                       h.sessionID                             | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |                     h.transactionID                           | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |                       h.packetID                              | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |                     h.payload_length                          | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * *    Total length = 20 bytes * *  If we don't seem to have the full packet, return NULL *    and let the driving code go back for the rest. *  Don't report this as an error, as it's quite "normal" *    with a connection-oriented service. * *  Note that once the header has been successfully processed *    (and hence we should have the full packet), any subsequent *    "running out of room" is indeed an error. */u_char *agentx_parse_header(struct snmp_pdu *pdu, u_char *data, size_t *length){     register u_char *bufp = data;     size_t payload;     if ( *length < 20 ) {	/* Incomplete header */	return NULL;     }     DEBUGDUMPHEADER("recv", "AgentX Header");     DEBUGDUMPHEADER("recv", "Version");     DEBUGDUMPSETUP("recv", bufp, 1);     pdu->version = AGENTX_VERSION_BASE | *bufp;     DEBUGMSG(("dumpv_recv", "  Version:\t%d\n", *bufp));     DEBUGINDENTLESS();     bufp++;     DEBUGDUMPHEADER("recv", "Command");     DEBUGDUMPSETUP("recv", bufp, 1);     pdu->command = *bufp;     DEBUGMSG(("dumpv_recv", "  Command:\t%d (%s)\n", *bufp, agentx_cmd(*bufp)));     DEBUGINDENTLESS();     bufp++;     DEBUGDUMPHEADER("recv", "Flags");     DEBUGDUMPSETUP("recv", bufp, 1);     pdu->flags |= *bufp;     DEBUGMSG(("dumpv_recv", "  Flags:\t0x%x\n", *bufp));     DEBUGINDENTLESS();     bufp++;     DEBUGDUMPHEADER("recv", "Reserved Byte");     DEBUGDUMPSETUP("recv", bufp, 1);     DEBUGMSG(("dumpv_recv", "  Reserved:\t0x%x\n", *bufp));     DEBUGINDENTLESS();     bufp++;     DEBUGDUMPHEADER("recv", "Session ID");     pdu->sessid = agentx_parse_int( bufp,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );     DEBUGINDENTLESS();     bufp += 4;     DEBUGDUMPHEADER("recv", "Transaction ID");     pdu->transid = agentx_parse_int( bufp,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );     DEBUGINDENTLESS();     bufp += 4;     DEBUGDUMPHEADER("recv", "Packet ID");     pdu->reqid = agentx_parse_int( bufp,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );     DEBUGINDENTLESS();     bufp += 4;     DEBUGDUMPHEADER("recv", "Payload Length");     payload = agentx_parse_int( bufp,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );     DEBUGINDENTLESS();     bufp += 4;     *length -= 20;     if ( *length != payload ) {	/* Short payload */	return NULL;     }     return bufp;}intagentx_parse(struct snmp_session *session, struct snmp_pdu *pdu, u_char *data, size_t len){     register u_char *bufp = data;     u_char buffer[BUFSIZ];     u_char *prefix_ptr;     oid    oid_buffer[MAX_OID_LEN], end_oid_buf[MAX_OID_LEN];     size_t buf_len         = BUFSIZ;     size_t oid_buf_len     = MAX_OID_LEN;     size_t end_oid_buf_len = MAX_OID_LEN;     int    range_bound;/* OID-range upper bound */     int    inc;	/* Inclusive SearchRange flag */     int    type;	/* VarBind data type */     size_t *length = &len;     if ( pdu == NULL ) {		/* Dump the packet in a formatted style */	pdu = (struct snmp_pdu *)malloc( sizeof( struct snmp_pdu ));	free( pdu );	return(0);     }     if (!IS_AGENTX_VERSION( session->version ))	return SNMPERR_BAD_VERSION;#ifndef SNMPERR_INCOMPLETE_PACKET	/*	 *  Ideally, "short" packets on stream connections should	 *    be handled specially, and the driving code set up to	 *    keep reading until the full packet is received.	 *	 *  For now, lets assume that all packets are read in one go.	 *    I've probably inflicted enough damage on the UCD library	 *    for one week!	 *	 *  I'll come back to this once Wes is speaking to me again.	 */#define SNMPERR_INCOMPLETE_PACKET SNMPERR_ASN_PARSE_ERR#endif		/*		 *  Handle (common) header ....		 */     bufp = agentx_parse_header( pdu, bufp, length );     if ( bufp == NULL )	return SNMPERR_INCOMPLETE_PACKET;	/* i.e. wait for the rest */				/* Control PDU handling */     pdu->flags |= UCD_MSG_FLAG_ALWAYS_IN_VIEW;     pdu->flags |= UCD_MSG_FLAG_FORCE_PDU_COPY;     pdu->flags &= (~UCD_MSG_FLAG_RESPONSE_PDU);		/*		 *  ... and (not-un-common) context		 */     if ( pdu->flags & 	AGENTX_MSG_FLAG_NON_DEFAULT_CONTEXT ) {        DEBUGDUMPHEADER("recv", "Context");	bufp = agentx_parse_string( bufp, length, buffer, &buf_len,				pdu->flags &  AGENTX_FLAGS_NETWORK_BYTE_ORDER );        DEBUGINDENTLESS();        if ( bufp == NULL )	    return SNMPERR_ASN_PARSE_ERR;	pdu->community_len = buf_len;	snmp_clone_mem((void **)&pdu->community, 				(void *)buffer, (unsigned) buf_len);	buf_len = BUFSIZ;     }     DEBUGDUMPHEADER("recv", "PDU");     DEBUGINDENTMORE();     switch ( pdu->command ) {	case AGENTX_MSG_OPEN:		pdu->time = *bufp;	/* Timeout */		bufp     += 4;		*length  -= 4;			/* Store subagent OID & description in a VarBind */                DEBUGDUMPHEADER("recv", "Subagent OID");		bufp = agentx_parse_oid( bufp, length, NULL,				oid_buffer, &oid_buf_len,				pdu->flags &  AGENTX_FLAGS_NETWORK_BYTE_ORDER );                DEBUGINDENTLESS();		if ( bufp == NULL ) {                    DEBUGINDENTLESS();		    return SNMPERR_ASN_PARSE_ERR;                }                DEBUGDUMPHEADER("recv", "Subagent Description");		bufp = agentx_parse_string( bufp, length, buffer, &buf_len,				pdu->flags &  AGENTX_FLAGS_NETWORK_BYTE_ORDER );                DEBUGINDENTLESS();		if ( bufp == NULL ) {                    DEBUGINDENTLESS();		    return SNMPERR_ASN_PARSE_ERR;                }		snmp_pdu_add_variable( pdu, oid_buffer, oid_buf_len,				ASN_OCTET_STR, buffer, buf_len);		oid_buf_len = MAX_OID_LEN;		buf_len     = BUFSIZ;		break;	case AGENTX_MSG_CLOSE:		pdu->errstat = *bufp;	/* Reason */		bufp     += 4;		*length  -= 4;		break;	case AGENTX_MSG_UNREGISTER:	case AGENTX_MSG_REGISTER:		pdu->time = *bufp;	/* Timeout (Register only) */		bufp++;		pdu->priority = *bufp;		bufp++;		pdu->range_subid = *bufp;		bufp++;		bufp++;		*length -= 4;		prefix_ptr = bufp+1;                DEBUGDUMPHEADER("recv", "Registration OID");		bufp = agentx_parse_oid( bufp, length, NULL,				oid_buffer, &oid_buf_len,				pdu->flags &  AGENTX_FLAGS_NETWORK_BYTE_ORDER );                DEBUGINDENTLESS();		if ( bufp == NULL ) {                    DEBUGINDENTLESS();		    return SNMPERR_ASN_PARSE_ERR;                }		if ( pdu->range_subid ) {					if ( *prefix_ptr ) {			    pdu->range_subid += 5;			}    			range_bound = agentx_parse_int( bufp,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );			bufp    += 4;			*length -= 4;				/* Construct the end-OID */			end_oid_buf_len = oid_buf_len*sizeof(oid);			memmove( &end_oid_buf, oid_buffer, end_oid_buf_len );			end_oid_buf[ pdu->range_subid-1 ] = range_bound;						snmp_pdu_add_variable( pdu, oid_buffer, oid_buf_len,				ASN_PRIV_INCL_RANGE, (u_char *)end_oid_buf, end_oid_buf_len);		}		else {			snmp_add_null_var( pdu, oid_buffer, oid_buf_len );		}		oid_buf_len = MAX_OID_LEN;		break;	case AGENTX_MSG_GETBULK:                DEBUGDUMPHEADER("recv", "Non-repeaters");		pdu->non_repeaters = agentx_parse_short( bufp,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );                DEBUGINDENTLESS();                DEBUGDUMPHEADER("recv", "Max-repeaters");		pdu->max_repetitions = agentx_parse_short( bufp+2,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );                DEBUGINDENTLESS();		bufp    += 4;		*length -= 4;		/*  Fallthrough - SearchRange handling is the same */			case AGENTX_MSG_GETNEXT:	case AGENTX_MSG_GET:			/*			*  SearchRange List			*  Keep going while we have data left			*/                DEBUGDUMPHEADER("recv", "Search Range");		while ( *length > 0 ) {		    bufp = agentx_parse_oid( bufp, length, &inc,				oid_buffer, &oid_buf_len,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );		    if ( bufp == NULL ) {                            DEBUGINDENTLESS();                            DEBUGINDENTLESS();			    return SNMPERR_ASN_PARSE_ERR;                    }		    bufp = agentx_parse_oid( bufp, length, NULL,				end_oid_buf, &end_oid_buf_len,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );		    if ( bufp == NULL ) {                            DEBUGINDENTLESS();                            DEBUGINDENTLESS();			    return SNMPERR_ASN_PARSE_ERR;                    }		    end_oid_buf_len *= sizeof(oid);			/* 'agentx_parse_oid()' returns the number of sub_ids */		    if ( inc )			snmp_pdu_add_variable( pdu, oid_buffer, oid_buf_len,				ASN_PRIV_INCL_RANGE, (u_char *)end_oid_buf, end_oid_buf_len);		    else			snmp_pdu_add_variable( pdu, oid_buffer, oid_buf_len,				ASN_PRIV_EXCL_RANGE, (u_char *)end_oid_buf, end_oid_buf_len);		}                DEBUGINDENTLESS();                oid_buf_len     = MAX_OID_LEN;		end_oid_buf_len = MAX_OID_LEN;		break;	case AGENTX_MSG_RESPONSE:     		pdu->flags |= UCD_MSG_FLAG_RESPONSE_PDU;					/* sysUpTime */		pdu->time = agentx_parse_int( bufp,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );		bufp    += 4;		*length -= 4;				pdu->errstat   = agentx_parse_short( bufp,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );		pdu->errindex  = agentx_parse_short( bufp+2,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );		bufp    += 4;		*length -= 4;		/*  Fallthrough - VarBind handling is the same */			case AGENTX_MSG_INDEX_ALLOCATE:	case AGENTX_MSG_INDEX_DEALLOCATE:	case AGENTX_MSG_NOTIFY:	case AGENTX_MSG_TESTSET:				/*			*  VarBind List			*  Keep going while we have data left			*/                DEBUGDUMPHEADER("recv", "VarBindList");		while ( *length > 0 ) {		    bufp = agentx_parse_varbind( bufp, length, &type,				oid_buffer, &oid_buf_len,				buffer, &buf_len,				pdu->flags & AGENTX_FLAGS_NETWORK_BYTE_ORDER );		    if ( bufp == NULL ) {                            DEBUGINDENTLESS();                            DEBUGINDENTLESS();			    return SNMPERR_ASN_PARSE_ERR;                    }		    snmp_pdu_add_variable( pdu, oid_buffer, oid_buf_len,				(u_char)type, buffer, buf_len);		    oid_buf_len = MAX_OID_LEN;		    buf_len     = BUFSIZ;		}                DEBUGINDENTLESS();                break;	case AGENTX_MSG_COMMITSET:	case AGENTX_MSG_UNDOSET:	case AGENTX_MSG_CLEANUPSET:	case AGENTX_MSG_PING:		/* "Empty" packet */		break;	case AGENTX_MSG_ADD_AGENT_CAPS:			/* Store AgentCap OID & description in a VarBind */		bufp = agentx_parse_oid( bufp, length, NULL,				oid_buffer, &oid_buf_len,				pdu->flags &  AGENTX_FLAGS_NETWORK_BYTE_ORDER );		if ( bufp == NULL )		    return SNMPERR_ASN_PARSE_ERR;		bufp = agentx_parse_string( bufp, length, buffer, &buf_len,				pdu->flags &  AGENTX_FLAGS_NETWORK_BYTE_ORDER );		if ( bufp == NULL )		    return SNMPERR_ASN_PARSE_ERR;		snmp_pdu_add_variable( pdu, oid_buffer, oid_buf_len,				ASN_OCTET_STR, buffer, buf_len);		oid_buf_len = MAX_OID_LEN;		buf_len     = BUFSIZ;		break;	case AGENTX_MSG_REMOVE_AGENT_CAPS:			/* Store AgentCap OID & description in a VarBind */		bufp = agentx_parse_oid( bufp, length, NULL,				oid_buffer, &oid_buf_len,				pdu->flags &  AGENTX_FLAGS_NETWORK_BYTE_ORDER );		if ( bufp == NULL )		    return SNMPERR_ASN_PARSE_ERR;		snmp_add_null_var( pdu, oid_buffer, oid_buf_len );		oid_buf_len = MAX_OID_LEN;		break;	default:                DEBUGINDENTLESS();                DEBUGINDENTLESS();		DEBUGMSGTL(("agentx","Unrecognised PDU type"));		return SNMPERR_UNKNOWN_PDU;     }     DEBUGINDENTLESS();     DEBUGINDENTLESS();     DEBUGINDENTLESS();     return SNMP_ERR_NOERROR;}#ifdef TESTINGtestit( struct snmp_pdu *pdu1){     char packet1[BUFSIZ];     char packet2[BUFSIZ];     int len1, len2;     struct snmp_pdu pdu2;     struct snmp_session sess;     memset( &pdu2, 0, sizeof(struct snmp_pdu));     memset( packet1, 0, BUFSIZ );     memset( packet2, 0, BUFSIZ );          	/* Encode this into a "packet" */     len1 = BUFSIZ;     if ( agentx_build( &sess, pdu1, packet1, &len1 ) < 0 ) {         DEBUGMSGTL(("agentx","First build failed"));	 exit(1);     }     DEBUGMSGTL(("agentx","First build succeeded:\n"));     xdump( packet1, len1, "Ax1> ");          	/* Unpack this into a PDU */     len2 = len1;     if ( agentx_parse( &pdu2, packet1, &len2, (u_char **)NULL ) < 0 ) {         DEBUGMSGTL(("agentx","First parse failed\n"));	 exit(1);     }     DEBUGMSGTL(("agentx","First parse succeeded:\n"));     if ( len2 != 0 )          DEBUGMSGTL(("agentx","Warning - parsed packet has %d bytes left\n", len2));     	/* Encode this into another "packet" */     len2 = BUFSIZ;     if ( agentx_build( &sess, &pdu2, packet2, &len2 ) < 0 ) {         DEBUGMSGTL(("agentx","Second build failed\n"));	 exit(1);     }     DEBUGMSGTL(("agentx","Second build succeeded:\n"));     xdump( packet2, len2, "Ax2> ");	/* Compare the results */     if ( len1 != len2 ) {     	DEBUGMSGTL(("agentx","Error: first build (%d) is different to second (%d)\n",			len1, len2));	exit(1);     }     if (memcmp( packet1, packet2, len1 ) != 0 ) {     	DEBUGMSGTL(("agentx","Error: first build data is different to second\n"));	exit(1);     }     DEBUGMSGTL(("agentx","OK\n"));}main (){     struct snmp_pdu pdu1;     oid oid_buf[] = { 1, 3, 6, 1, 2, 1, 10 };     oid oid_buf2[] = { 1, 3, 6, 1, 2, 1, 20 };     oid null_oid[] = { 0, 0 };     char *string = "Example string";          char *context = "LUCS";          	/* Create an example AgentX pdu structure */     memset( &pdu1, 0, sizeof(struct snmp_pdu));     pdu1.command = AGENTX_MSG_TESTSET;     pdu1.flags  =  0;     pdu1.sessid = 16;     pdu1.transid  = 24;     pdu1.reqid  = 132;          pdu1.time   = 10;     pdu1.non_repeaters   = 3;     pdu1.max_repetitions   = 32;     pdu1.priority = 5;     pdu1.range_subid = 0;     snmp_pdu_add_variable( &pdu1, oid_buf, sizeof(oid_buf)/sizeof(oid),				ASN_OBJECT_ID, (char *)oid_buf2, sizeof(oid_buf2));     snmp_pdu_add_variable( &pdu1, oid_buf, sizeof(oid_buf)/sizeof(oid),				ASN_INTEGER, (char *)&pdu1.reqid, sizeof(pdu1.reqid));     snmp_pdu_add_variable( &pdu1, oid_buf, sizeof(oid_buf)/sizeof(oid),				ASN_OCTET_STR, (char *)string, strlen(string));     printf("Test with non-network order.....\n");     testit( &pdu1 );     printf("\nTest with network order.....\n");     pdu1.flags |= AGENTX_FLAGS_NETWORK_BYTE_ORDER;     testit( &pdu1 );     pdu1.community = context;     pdu1.community_len = strlen(context);     pdu1.flags |= AGENTX_FLAGS_NON_DEFAULT_CONTEXT;     printf("Test with non-default context.....\n");     testit( &pdu1 ); }#endif/* returns the proper length of an incoming agentx packet. *//* *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ *    |   h.version   |    h.type     |    h.flags    |  <reserved>   | *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ *    |                          h.sessionID                          | *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ *    |                        h.transactionID                        | *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ *    |                          h.packetID                           | *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ *    |                        h.payload_length                       | *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ *    20 bytes in header */intagentx_check_packet(u_char *packet, size_t packet_len) {  if (packet_len < 20)    return 0; /* minimum header length == 20 */  return agentx_parse_int(packet+16,                          *(packet+2) & AGENTX_FLAGS_NETWORK_BYTE_ORDER) + 20;}  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -