From: serassio <> Date: Thu, 5 May 2005 21:44:44 +0000 (+0000) Subject: Bug 1298: Multiple OIDs in SNMP GETNEXT not processed X-Git-Tag: SQUID_3_0_PRE4~784 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0536fdfc5da5dca0f2baaa4ae9f084bbd7e62b6f;p=thirdparty%2Fsquid.git Bug 1298: Multiple OIDs in SNMP GETNEXT not processed Bug 1299: SNMPv2 requests should result in SNMPv2 responses This patch fixes some minor issues in the SNMP Agent. The GETNEXT/BULK requests both may contain more than one OID just like normal GET, but Squid ignored all but the first. Also the response version was always SNMP Version 1, even if the request was a SNMP Version 2(c) request. Forward port of 2.5 patch --- diff --git a/snmplib/snmp_api.c b/snmplib/snmp_api.c index 345b53095d..430f4622b8 100644 --- a/snmplib/snmp_api.c +++ b/snmplib/snmp_api.c @@ -149,5 +149,8 @@ snmp_parse(struct snmp_session * session, strncpy((char *) bufp, (char *) Community, CommunityLen); bufp[CommunityLen] = '\0'; + session->community = bufp; + session->community_len = CommunityLen; + return (bufp); } diff --git a/src/snmp_core.cc b/src/snmp_core.cc index 7944c9f6c0..feabc58cec 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -1,6 +1,6 @@ /* - * $Id: snmp_core.cc,v 1.66 2005/04/18 21:52:43 hno Exp $ + * $Id: snmp_core.cc,v 1.67 2005/05/05 15:44:45 serassio Exp $ * * DEBUG: section 49 SNMP support * AUTHOR: Glenn Chisholm @@ -526,7 +526,6 @@ snmpDecodePacket(snmp_request_t * rq) struct snmp_pdu *PDU; - struct snmp_session Session; u_char *Community; u_char *buf = rq->buf; int len = rq->len; @@ -535,8 +534,8 @@ snmpDecodePacket(snmp_request_t * rq) 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); + rq->session.Version = SNMP_VERSION_1; + Community = snmp_parse(&rq->session, PDU, buf, len); ACLChecklist checklist; checklist.src_addr = rq->from.sin_addr; checklist.snmp_community = (char *) Community; @@ -569,8 +568,6 @@ static void snmpConstructReponse(snmp_request_t * rq) { - struct snmp_session Session; - struct snmp_pdu *RespPDU; debug(49, 5) ("snmpConstructReponse: Called.\n"); @@ -578,10 +575,7 @@ snmpConstructReponse(snmp_request_t * rq) snmp_free_pdu(rq->PDU); if (RespPDU != NULL) { - Session.Version = SNMP_VERSION_1; - Session.community = rq->community; - Session.community_len = strlen((char *) rq->community); - snmp_build(&Session, RespPDU, rq->outbuf, &rq->outlen); + snmp_build(&rq->session, RespPDU, rq->outbuf, &rq->outlen); comm_udp_sendto(rq->sock, &rq->from, sizeof(rq->from), rq->outbuf, rq->outlen); snmp_free_pdu(RespPDU); } @@ -598,10 +592,6 @@ static struct snmp_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"); @@ -610,36 +600,63 @@ static struct snmp_pdu * Answer->reqid = PDU->reqid; Answer->errindex = 0; - if (PDU->command == SNMP_PDU_GET) { - variable_list **RespVars; - - RespVars = &(Answer->variables); + if (PDU->command == SNMP_PDU_GET || PDU->command == SNMP_PDU_GETNEXT) { + int get_next = (PDU->command == SNMP_PDU_GETNEXT); + variable_list *VarPtr_; + variable_list **RespVars = &(Answer->variables); + oid_ParseFn *ParseFn; + int index = 0; /* Loop through all variables */ - for (VarPtrP = &(PDU->variables); - *VarPtrP; - VarPtrP = &((*VarPtrP)->next_variable)) { - VarPtr = *VarPtrP; + for (VarPtr_ = PDU->variables; VarPtr_; VarPtr_ = VarPtr_->next_variable) { + variable_list *VarPtr = VarPtr_; + variable_list *VarNew = NULL; + oid *NextOidName = NULL; + snint NextOidNameLen = 0; index++; /* Find the parsing function for this variable */ - ParseFn = snmpTreeGet(VarPtr->name, VarPtr->name_length); + + if (get_next) + ParseFn = snmpTreeNext(VarPtr->name, VarPtr->name_length, &NextOidName, &NextOidNameLen); + else + ParseFn = snmpTreeGet(VarPtr->name, VarPtr->name_length); if (ParseFn == NULL) { Answer->errstat = SNMP_ERR_NOSUCHNAME; debug(49, 5) ("snmpAgentResponse: No such oid. "); - } else + } else { + if (get_next) { + VarPtr = snmp_var_new(NextOidName, NextOidNameLen); + xfree(NextOidName); + } + VarNew = (*ParseFn) (VarPtr, (snint *) & (Answer->errstat)); + if (get_next) + snmp_var_free(VarPtr); + } + /* Was there an error? */ - if ((Answer->errstat != SNMP_ERR_NOERROR) || - (VarNew == NULL)) { + 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; + debug(49, 5) ("snmpAgentResponse: error.\n"); + + if (VarNew) + snmp_var_free(VarNew); + + /* Free the already processed results, if any */ + while ((VarPtr = Answer->variables) != NULL) { + Answer->variables = VarPtr->next_variable; + snmp_var_free(VarPtr); + } + + /* Steal the original PDU list of variables for the error response */ + Answer->variables = PDU->variables; + + PDU->variables = NULL; + return (Answer); } @@ -649,38 +666,6 @@ static struct snmp_pdu * 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; } } diff --git a/src/structs.h b/src/structs.h index 6fa91ef537..c392d3a86d 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1,6 +1,6 @@ /* - * $Id: structs.h,v 1.518 2005/05/01 08:11:48 serassio Exp $ + * $Id: structs.h,v 1.519 2005/05/05 15:44:45 serassio Exp $ * * * SQUID Web Proxy Cache http://www.squid-cache.org/ @@ -108,6 +108,8 @@ struct _snmp_request_t struct snmp_pdu *PDU; ACLChecklist *acl_checklist; u_char *community; + + struct snmp_session session; }; #endif