Revision: 14863
Author:   adrian.chadd
Date:     Fri Jul  8 22:32:28 2011
Log:      Enable IPv6 support for the SNMP agent.


http://code.google.com/p/lusca-cache/source/detail?r=14863

Modified:
 /playpen/LUSCA_HEAD_ipv6/src/cf.data.pre
 /playpen/LUSCA_HEAD_ipv6/src/globals.h
 /playpen/LUSCA_HEAD_ipv6/src/snmp_core.c
 /playpen/LUSCA_HEAD_ipv6/src/structs.h

=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/cf.data.pre    Fri Jul  1 07:59:54 2011
+++ /playpen/LUSCA_HEAD_ipv6/src/cf.data.pre    Fri Jul  8 22:32:28 2011
@@ -4789,6 +4789,18 @@
        the same value since they both use port 3401.
 DOC_END

+NAME: snmp_outgoing_address6
+TYPE: address6
+LOC: Config.Addrs.snmp_outgoing6
+DEFAULT: ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+DOC_NONE
+
+NAME: snmp_incoming_address6
+TYPE: address6
+LOC: Config.Addrs.snmp_incoming6
+DEFAULT: ::0
+DOC_NONE
+
 COMMENT_START
  ICP OPTIONS
-----------------------------------------------------------------------------
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/globals.h      Sun Jul  4 06:56:53 2010
+++ /playpen/LUSCA_HEAD_ipv6/src/globals.h      Fri Jul  8 22:32:28 2011
@@ -80,13 +80,17 @@
 #ifdef SQUID_SNMP
 extern int theInSnmpConnection;        /* -1 */
 extern int theOutSnmpConnection;       /* -1 */
+extern int theInSnmpConnection6;       /* -1 */
+extern int theOutSnmpConnection6;      /* -1 */
 extern char *snmp_agentinfo;
 #endif
 extern int n_disk_objects;     /* 0 */
 extern iostats IOStats;
 extern struct _acl_deny_info_list *DenyInfoList;       /* NULL */
 extern struct in_addr theOutICPAddr;
+#if 0
 extern struct in_addr theOutSNMPAddr;
+#endif
 extern struct timeval squid_start;
 extern int store_dirs_rebuilding;      /* 1 */
 extern int store_swap_size;    /* 0 */
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/snmp_core.c    Mon Sep  6 21:39:50 2010
+++ /playpen/LUSCA_HEAD_ipv6/src/snmp_core.c    Fri Jul  8 22:32:28 2011
@@ -289,13 +289,16 @@
 snmpConnectionOpen(void)
 {
     u_short port;
+#if 0
     struct sockaddr_in xaddr;
     socklen_t len;
     int x;
+#endif

     debug(49, 5) ("snmpConnectionOpen: Called\n");
     if ((port = Config.Port.snmp) > (u_short) 0) {
        enter_suid();
+
        theInSnmpConnection = comm_open(SOCK_DGRAM,
            IPPROTO_UDP,
            Config.Addrs.snmp_incoming,
@@ -303,12 +306,25 @@
            COMM_NONBLOCKING,
            COMM_TOS_DEFAULT,
            "SNMP Port");
+
+       sqinet_set_port(&Config.Addrs.snmp_incoming6, port, SQADDR_NONE);
+       theInSnmpConnection6 = comm_open6(SOCK_DGRAM,
+           IPPROTO_UDP,
+           &Config.Addrs.snmp_incoming6,
+           COMM_NONBLOCKING,
+           COMM_TOS_DEFAULT,
+           "SNMP Port");
+
        leave_suid();
-       if (theInSnmpConnection < 0)
+       if (theInSnmpConnection < 0 || theInSnmpConnection6 < 0)
            fatal("Cannot open snmp Port");
- commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
+       commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp,
+         NULL, 0);
+       commSetSelect(theInSnmpConnection6, COMM_SELECT_READ, snmpHandleUdp,
+         NULL, 0);
        debug(1, 1) ("Accepting SNMP messages on port %d, FD %d.\n",
            (int) port, theInSnmpConnection);
+
        if (! IsNoAddr(&Config.Addrs.snmp_outgoing)) {
            enter_suid();
            theOutSnmpConnection = comm_open(SOCK_DGRAM,
@@ -332,6 +348,32 @@
        } else {
            theOutSnmpConnection = theInSnmpConnection;
        }
+
+       if (! sqinet_is_noaddr(&Config.Addrs.snmp_outgoing6)) {
+           enter_suid();
+           sqinet_set_port(&Config.Addrs.snmp_outgoing6, port, SQADDR_NONE);
+           theOutSnmpConnection = comm_open6(SOCK_DGRAM,
+               IPPROTO_UDP,
+               &Config.Addrs.snmp_outgoing6,
+               COMM_NONBLOCKING,
+               COMM_TOS_DEFAULT,
+               "SNMP Port");
+           leave_suid();
+           if (theOutSnmpConnection6 < 0)
+               fatal("Cannot open Outgoing SNMP Port");
+           commSetSelect(theOutSnmpConnection6,
+               COMM_SELECT_READ,
+               snmpHandleUdp,
+               NULL, 0);
+           debug(1, 1) ("Outgoing SNMP messages on port %d, FD %d.\n",
+               (int) port, theOutSnmpConnection);
+           fd_note(theOutSnmpConnection6, "Outgoing SNMP socket");
+           fd_note(theInSnmpConnection6, "Incoming SNMP socket");
+       } else {
+           theOutSnmpConnection6 = theInSnmpConnection6;
+       }
+
+#if 0
        memset(&theOutSNMPAddr, '\0', sizeof(struct in_addr));
        len = sizeof(struct sockaddr_in);
        memset(&xaddr, '\0', len);
@@ -342,32 +384,51 @@
                theOutSnmpConnection, xstrerror());
        else
            theOutSNMPAddr = xaddr.sin_addr;
+#endif
     }
 }

 void
 snmpConnectionShutdown(void)
 {
-    if (theInSnmpConnection < 0)
+    if (theInSnmpConnection < 0 && theInSnmpConnection6 < 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;
+     */
+
+    if (theInSnmpConnection != -1) {
+        if (theInSnmpConnection != theOutSnmpConnection) {
+            debug(49, 1) ("FD %d Closing IPv4 SNMP socket\n",
+              theInSnmpConnection);
+            comm_close(theInSnmpConnection);
+            theInSnmpConnection6 = -1;
+        }
+    }
+
+    if (theInSnmpConnection6 != -1) {
+        if (theInSnmpConnection6 != theOutSnmpConnection6) {
+            debug(49, 1) ("FD %d Closing IPv6 SNMP socket\n",
+              theInSnmpConnection6);
+            comm_close(theInSnmpConnection6);
+            theInSnmpConnection6 = -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);
+    if (theOutSnmpConnection != -1)
+ commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, NULL, NULL, 0);
+    if (theOutSnmpConnection6 != -1)
+ commSetSelect(theOutSnmpConnection6, COMM_SELECT_READ, NULL, NULL, 0);
 }

 void
@@ -391,15 +452,15 @@
 snmpHandleUdp(int sock, void *not_used)
 {
     LOCAL_ARRAY(char, buf, SNMP_REQUEST_SIZE);
-    struct sockaddr_in from;
+    struct sockaddr_storage from;
     socklen_t from_len;
     snmp_request_t *snmp_rq;
     int len;

-    debug(49, 5) ("snmpHandleUdp: Called.\n");
+    debug(49, 5) ("snmpHandleUdp: Called: FD %d\n", sock);

     commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
-    from_len = sizeof(struct sockaddr_in);
+    from_len = sizeof(from);
     memset(&from, '\0', from_len);
     memset(buf, '\0', SNMP_REQUEST_SIZE);

@@ -413,21 +474,29 @@
        &from_len);

     if (len > 0) {
+       char sbuf[MAX_IPSTRLEN];
        buf[len] = '\0';
-       debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",
-           sock,
-           len,
-           inet_ntoa(from.sin_addr));
+       sqaddr_t f;
+       sqinet_init(&f);
+       sqinet_set_sockaddr(&f, &from);
+       if (do_debug(49, 3)) {
+           (void) sqinet_ntoa(&f, sbuf, MAX_IPSTRLEN, SQADDR_NONE);
+           debug(49, 3) ("snmpHandleUdp: FD %d: received %d bytes from %s.\n",
+             sock, len, sbuf);
+       }

        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));
+       sqinet_init(&snmp_rq->from);
+       sqinet_copy(&snmp_rq->from, &f);
        snmpDecodePacket(snmp_rq);
+       sqinet_done(&snmp_rq->from);
        xfree(snmp_rq->outbuf);
        xfree(snmp_rq);
+       sqinet_done(&f);
     } else {
        debug(49, 1) ("snmpHandleUdp: FD %d recvfrom: %s\n", sock, xstrerror());
     }
@@ -453,7 +522,7 @@
     Community = snmp_parse(&rq->session, PDU, buf, len);
     memset(&checklist, '\0', sizeof(checklist));
     aclCheckSetup(&checklist);
-    sqinet_set_v4_inaddr(&checklist.src_address, &rq->from.sin_addr);
+    sqinet_copy(&checklist.src_address, &rq->from);
     checklist.snmp_community = (char *) Community;

     if (Community)
@@ -464,8 +533,9 @@
        debug(49, 5) ("snmpDecodePacket: reqid=[%d]\n", PDU->reqid);
        snmpConstructReponse(rq);
     } else {
-       debug(49, 1) ("Failed SNMP agent query from : %s.\n",
-           inet_ntoa(rq->from.sin_addr));
+       char sbuf[MAX_IPSTRLEN];
+       (void) sqinet_ntoa(&rq->from, sbuf, MAX_IPSTRLEN, SQADDR_NONE);
+       debug(49, 1) ("Failed SNMP agent query from : %s.\n", sbuf);
        snmp_free_pdu(PDU);
     }
     if (Community)
@@ -485,8 +555,18 @@
     RespPDU = snmpAgentResponse(rq->PDU);
     snmp_free_pdu(rq->PDU);
     if (RespPDU != NULL) {
+       int family;
        snmp_build(&rq->session, RespPDU, rq->outbuf, &rq->outlen);
- comm_udp_sendto(rq->sock, &rq->from, sizeof(rq->from), rq->outbuf, rq->outlen);
+       /* check address family */
+       /* XXX is this needed? How's rq->sock figured out? */
+       family = sqinet_get_family(&rq->from);
+       if (family == AF_INET)
+               assert(rq->sock == theOutSnmpConnection);
+       else if (family == AF_INET6)
+               assert(rq->sock == theOutSnmpConnection6);
+       else
+               debug(49, 0) ("%s: address family=%d ?!\n", __func__, family);
+       comm_udp_sendto6(rq->sock, &rq->from, rq->outbuf, rq->outlen);
        snmp_free_pdu(RespPDU);
     }
 }
=======================================
--- /playpen/LUSCA_HEAD_ipv6/src/structs.h      Fri Jul  8 21:30:40 2011
+++ /playpen/LUSCA_HEAD_ipv6/src/structs.h      Fri Jul  8 22:32:28 2011
@@ -242,7 +242,7 @@
     int sock;
     long reqid;
     int outlen;
-    struct sockaddr_in from;
+    sqaddr_t from;
     struct snmp_pdu *PDU;
     aclCheck_t *acl_checklist;
     u_char *community;
@@ -577,6 +577,8 @@
 #if SQUID_SNMP
        struct in_addr snmp_incoming;
        struct in_addr snmp_outgoing;
+       sqaddr_t snmp_incoming6;
+       sqaddr_t snmp_outgoing6;
 #endif
        struct in_addr client_netmask_v4;
        sqaddr_t client_netmask_v6;

--
You received this message because you are subscribed to the Google Groups 
"lusca-commit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/lusca-commit?hl=en.

Reply via email to