]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Bug 1298: Multiple OIDs in SNMP GETNEXT not processed
authorserassio <>
Thu, 5 May 2005 21:44:44 +0000 (21:44 +0000)
committerserassio <>
Thu, 5 May 2005 21:44:44 +0000 (21:44 +0000)
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

snmplib/snmp_api.c
src/snmp_core.cc
src/structs.h

index 345b53095df95d41c5cb469342f2e8016b358d06..430f4622b8eab5355fc311e7027afb5ab3d8d883 100644 (file)
@@ -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);
 }
index 7944c9f6c018dd850c8f17984e5f9e5c6dc40b51..feabc58cec97b534b715496e49fbd86177bd3e19 100644 (file)
@@ -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;
         }
     }
 
index 6fa91ef537479d73ac7fab2fa84f29e7e380849d..c392d3a86dbe4ccf677c12b8c73604fdf3700324 100644 (file)
@@ -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