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

📄 snmp_core.c

📁 -
💻 C
📖 第 1 页 / 共 3 页
字号:
	leave_suid();	if (theInSnmpConnection < 0)	    fatal("Cannot open snmp Port");	commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);	debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n",	    (int) port, theInSnmpConnection);	if (Config.Addrs.snmp_outgoing.s_addr != no_addr.s_addr) {	    enter_suid();	    theOutSnmpConnection = comm_open(SOCK_DGRAM,		0,		Config.Addrs.snmp_outgoing,		port,		COMM_NONBLOCKING,		"SNMP Port");	    leave_suid();	    if (theOutSnmpConnection < 0)		fatal("Cannot open Outgoing SNMP Port");	    commSetSelect(theOutSnmpConnection,		COMM_SELECT_READ,		snmpHandleUdp,		NULL, 0);	    debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n",		(int) port, theOutSnmpConnection);	    fd_note(theOutSnmpConnection, "Outgoing SNMP socket");	    fd_note(theInSnmpConnection, "Incoming SNMP socket");	} else {	    theOutSnmpConnection = theInSnmpConnection;	}	memset(&theOutSNMPAddr, '\0', sizeof(struct in_addr));	len = sizeof(struct sockaddr_in);	memset(&xaddr, '\0', len);	x = getsockname(theOutSnmpConnection,	    (struct sockaddr *) &xaddr, &len);	if (x < 0)	    debug(51, 1) ("theOutSnmpConnection FD %d: getsockname: %s\n",		theOutSnmpConnection, xstrerror());	else	    theOutSNMPAddr = xaddr.sin_addr;    }}voidsnmpConnectionShutdown(void){    if (theInSnmpConnection < 0)	return;    if (theInSnmpConnection != theOutSnmpConnection) {	debug(49, 1) ("FD %d Closing SNMP socket\n", theInSnmpConnection);	comm_close(theInSnmpConnection);    }    /*     * Here we set 'theInSnmpConnection' to -1 even though the SNMP 'in'     * and 'out' sockets might be just one FD.  This prevents this     * function from executing repeatedly.  When we are really ready to     * exit or restart, main will comm_close the 'out' descriptor.     */ theInSnmpConnection = -1;    /*     * Normally we only write to the outgoing SNMP socket, but we     * also have a read handler there to catch messages sent to that     * specific interface.  During shutdown, we must disable reading     * on the outgoing socket.     */    assert(theOutSnmpConnection > -1);    commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);}voidsnmpConnectionClose(void){    snmpConnectionShutdown();    if (theOutSnmpConnection > -1) {	debug(49, 1) ("FD %d Closing SNMP socket\n", theOutSnmpConnection);	comm_close(theOutSnmpConnection);    }}/* * Functions for handling the requests. *//* * Accept the UDP packet */voidsnmpHandleUdp(int sock, void *not_used){    LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);    struct sockaddr_in from;    socklen_t from_len;    snmp_request_t *snmp_rq;    int len;    debug(49, 5) ("snmpHandleUdp: Called.\n");    commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);    from_len = sizeof(struct sockaddr_in);    memset(&from, '\0', from_len);    memset(buf, '\0', SNMP_REQUEST_SIZE);    Counter.syscalls.sock.recvfroms++;    len = recvfrom(sock,	buf,	SNMP_REQUEST_SIZE,	0,	(struct sockaddr *) &from,	&from_len);    if (len > 0) {	buf[len] = '\0';	debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",	    sock,	    len,	    inet_ntoa(from.sin_addr));	snmp_rq = xcalloc(1, sizeof(snmp_request_t));	snmp_rq->buf = (u_char *) buf;	snmp_rq->len = len;	snmp_rq->sock = sock;	snmp_rq->outbuf = xmalloc(snmp_rq->outlen = SNMP_REQUEST_SIZE);	xmemcpy(&snmp_rq->from, &from, sizeof(struct sockaddr_in));	snmpDecodePacket(snmp_rq);	xfree(snmp_rq);    } else {	debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", sock, xstrerror());    }}/* * Turn SNMP packet into a PDU, check available ACL's */voidsnmpDecodePacket(snmp_request_t * rq){    struct snmp_pdu *PDU;    struct snmp_session Session;    aclCheck_t checklist;    u_char *Community;    u_char *buf = rq->buf;    int len = rq->len;    int allow = 0;    debug(49, 5) ("snmpDecodePacket: Called.\n");    /* Now that we have the data, turn it into a PDU */    PDU = snmp_pdu_create(0);    Session.Version = SNMP_VERSION_1;    Community = snmp_parse(&Session, PDU, buf, len);    checklist.src_addr = rq->from.sin_addr;    checklist.snmp_community = (char *) Community;    allow = aclCheckFast(Config.accessList.snmp, &checklist);    if ((snmp_coexist_V2toV1(PDU)) && (Community) && (allow)) {	rq->community = Community;	rq->PDU = PDU;	debug(49, 5) ("snmpAgentParse: reqid=[%d]\n", PDU->reqid);	snmpConstructReponse(rq);    } else {	debug(49, 1) ("Failed SNMP agent query from : %s.\n",	    inet_ntoa(rq->from.sin_addr));	snmp_free_pdu(PDU);    }}/* * Packet OK, ACL Check OK, Create reponse. */voidsnmpConstructReponse(snmp_request_t * rq){    struct snmp_session Session;    struct snmp_pdu *RespPDU;    int ret;    debug(49, 5) ("snmpConstructReponse: Called.\n");    RespPDU = snmpAgentResponse(rq->PDU);    snmp_free_pdu(rq->PDU);    if (RespPDU != NULL) {	Session.Version = SNMP_VERSION_1;	Session.community = rq->community;	Session.community_len = strlen((char *) rq->community);	ret = snmp_build(&Session, RespPDU, rq->outbuf, &rq->outlen);	sendto(rq->sock, rq->outbuf, rq->outlen, 0, (struct sockaddr *) &rq->from, sizeof(rq->from));	snmp_free_pdu(RespPDU);	xfree(rq->outbuf);    }}/* * Decide how to respond to the request, construct a response and * return the response to the requester. *  * If configured forward any reponses which are not for this agent. */struct snmp_pdu *snmpAgentResponse(struct snmp_pdu *PDU){    struct snmp_pdu *Answer = NULL;    oid_ParseFn *ParseFn = NULL;    variable_list *VarPtr, *VarNew = NULL, **VarPtrP;    int index = 0;    debug(49, 5) ("snmpAgentResponse: Called.\n");    if ((Answer = snmp_pdu_create(SNMP_PDU_RESPONSE))) {	Answer->reqid = PDU->reqid;	Answer->errindex = 0;	if (PDU->command == SNMP_PDU_GET) {	    variable_list **RespVars;	    RespVars = &(Answer->variables);	    /* Loop through all variables */	    for (VarPtrP = &(PDU->variables);		*VarPtrP;		VarPtrP = &((*VarPtrP)->next_variable)) {		VarPtr = *VarPtrP;		index++;		/* Find the parsing function for this variable */		ParseFn = snmpTreeGet(VarPtr->name, VarPtr->name_length);		if (ParseFn == NULL) {		    Answer->errstat = SNMP_ERR_NOSUCHNAME;		    debug(49, 5) ("snmpAgentResponse: No such oid. ");		} else		    VarNew = (*ParseFn) (VarPtr, (snint *) & (Answer->errstat));		/* Was there an error? */		if ((Answer->errstat != SNMP_ERR_NOERROR) ||		    (VarNew == NULL)) {		    Answer->errindex = index;		    debug(49, 5) ("snmpAgentParse: successful.\n");		    /* Just copy the rest of the variables.  Quickly. */		    *RespVars = VarPtr;		    *VarPtrP = NULL;		    return (Answer);		}		/* No error.  Insert this var at the end, and move on to the next.		 */		*RespVars = VarNew;		RespVars = &(VarNew->next_variable);	    }	    return (Answer);	} else if (PDU->command == SNMP_PDU_GETNEXT) {	    oid *NextOidName = NULL;	    int NextOidNameLen = 0;	    ParseFn = snmpTreeNext(PDU->variables->name, PDU->variables->name_length,		&(NextOidName), (snint *) & NextOidNameLen);	    if (ParseFn == NULL) {		Answer->errstat = SNMP_ERR_NOSUCHNAME;		debug(49, 5) ("snmpAgentResponse: No such oid: ");		snmpDebugOid(5, PDU->variables->name, PDU->variables->name_length);	    } else {		xfree(PDU->variables->name);		PDU->variables->name = NextOidName;		PDU->variables->name_length = NextOidNameLen;		VarNew = (*ParseFn) (PDU->variables, (snint *) & Answer->errstat);	    }	    /* Was there an error? */	    if (Answer->errstat != SNMP_ERR_NOERROR) {		Answer->errindex = 1;		Answer->variables = PDU->variables;		PDU->variables = NULL;	    } else {		Answer->variables = VarNew;	    }	} else {	    snmp_free_pdu(Answer);	    Answer = NULL;	}    }    return (Answer);}oid_ParseFn *snmpTreeGet(oid * Current, snint CurrentLen){    oid_ParseFn *Fn = NULL;    mib_tree_entry *mibTreeEntry = NULL, *lastEntry = NULL;    int count = 0;    debug(49, 5) ("snmpTreeGet: Called\n");    debug(49, 6) ("snmpTreeGet: Current : \n");    snmpDebugOid(6, Current, CurrentLen);    mibTreeEntry = mib_tree_head;    if (Current[count] == mibTreeEntry->name[count]) {	count++;	while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {	    lastEntry = mibTreeEntry;	    mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);	    count++;	}    }    if (mibTreeEntry && mibTreeEntry->parsefunction)	Fn = mibTreeEntry->parsefunction;    debug(49, 5) ("snmpTreeGet: return\n");    return (Fn);}oid_ParseFn *snmpTreeNext(oid * Current, snint CurrentLen, oid ** Next, snint * NextLen){    oid_ParseFn *Fn = NULL;    mib_tree_entry *mibTreeEntry = NULL, *nextoid = NULL;    int count = 0;    debug(49, 5) ("snmpTreeNext: Called\n");    debug(49, 6) ("snmpTreeNext: Current : \n");    snmpDebugOid(6, Current, CurrentLen);    mibTreeEntry = mib_tree_head;    if (Current[count] == mibTreeEntry->name[count]) {	count++;	while ((mibTreeEntry) && (count < CurrentLen) && (!mibTreeEntry->parsefunction)) {	    mibTreeEntry = snmpTreeEntry(Current[count], count, mibTreeEntry);	    count++;	}	debug(49, 5) ("snmpTreeNext: Recursed down to requested object\n");    } else {	return NULL;    }    if (mibTreeEntry == mib_tree_last)	return (Fn);    if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {	*NextLen = CurrentLen;	*Next = (*mibTreeEntry->instancefunction) (Current, NextLen, mibTreeEntry, &Fn);	if (*Next)	    return (Fn);    }    if ((mibTreeEntry) && (mibTreeEntry->parsefunction)) {	count--;	nextoid = snmpTreeSiblingEntry(Current[count], count, mibTreeEntry->parent);	if (nextoid) {	    debug(49, 5) ("snmpTreeNext: Next OID found for sibling\n");	    mibTreeEntry = nextoid;	    count++;	} else {	    debug(49, 5) ("snmpTreeNext: Attempting to recurse up for next object\n");	    while (!nextoid) {		count--;		if (mibTreeEntry->parent->parent) {		    nextoid = mibTreeEntry->parent;		    mibTreeEntry = snmpTreeEntry(Current[count] + 1, count, nextoid->parent);		    if (!mibTreeEntry) {			mibTreeEntry = nextoid;

⌨️ 快捷键说明

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