rpms/net-snmp/devel net-snmp-5.3.1-local-addr.patch, NONE, 1.1 net-snmp.spec, 1.87, 1.88

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Wed Sep 13 08:16:45 UTC 2006


Author: rvokal

Update of /cvs/dist/rpms/net-snmp/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv19650

Modified Files:
	net-snmp.spec 
Added Files:
	net-snmp-5.3.1-local-addr.patch 
Log Message:

enable smux only on loopback address by default, use correct answer address

net-snmp-5.3.1-local-addr.patch:
 README                  |    1 
 snmplib/snmpUDPDomain.c |  168 ++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 143 insertions(+), 26 deletions(-)

--- NEW FILE net-snmp-5.3.1-local-addr.patch ---
diff -urNp net-snmp-5.3.1.orig/README net-snmp-5.3.1/README
--- net-snmp-5.3.1.orig/README	2006-07-14 00:55:27.000000000 +0300
+++ net-snmp-5.3.1/README	2006-09-06 00:17:16.000000000 +0300
@@ -343,6 +343,7 @@ THANKS
     Andrew Rucker Jones <arjones at users.sourceforge.net>
     Dai.H. <dg-f at users.sourceforge.net>
     Thomas Anders <tanders at users.sourceforge.net>
+    Vladislav Bogdanov <slava_reg at nsys.by>
 
   We've probably forgotten people on this list.  Let us know if you've
   contributed code and we've left you out.
diff -urNp net-snmp-5.3.1.orig/snmplib/snmpUDPDomain.c net-snmp-5.3.1/snmplib/snmpUDPDomain.c
--- net-snmp-5.3.1.orig/snmplib/snmpUDPDomain.c	2005-11-06 00:01:42.000000000 +0200
+++ net-snmp-5.3.1/snmplib/snmpUDPDomain.c	2006-09-06 00:13:59.000000000 +0300
@@ -64,6 +64,11 @@
 
 static netsnmp_tdomain udpDomain;
 
+typedef struct netsnmp_udp_addr_pair_s {
+    struct sockaddr_in remote_addr;
+    struct in_addr local_addr;
+} netsnmp_udp_addr_pair;
+
 /*
  * not static, since snmpUDPIPv6Domain needs it, but not public, either.
  * (ie don't put it in a public header.)
@@ -78,17 +83,23 @@ void _netsnmp_udp_sockopt_set(int fd, in
 static char *
 netsnmp_udp_fmtaddr(netsnmp_transport *t, void *data, int len)
 {
-    struct sockaddr_in *to = NULL;
+    netsnmp_udp_addr_pair *addr_pair = NULL;
 
-    if (data != NULL && len == sizeof(struct sockaddr_in)) {
-        to = (struct sockaddr_in *) data;
+    if (data != NULL && len == sizeof(netsnmp_udp_addr_pair)) {
+	addr_pair = (netsnmp_udp_addr_pair *) data;
     } else if (t != NULL && t->data != NULL) {
-        to = (struct sockaddr_in *) t->data;
+	addr_pair = (netsnmp_udp_addr_pair *) t->data;
     }
-    if (to == NULL) {
+
+    if (addr_pair == NULL) {
         return strdup("UDP: unknown");
     } else {
+        struct sockaddr_in *to = NULL;
 	char tmp[64];
+        to = (struct sockaddr_in *) &(addr_pair->remote_addr);
+        if (to == NULL) {
+            return strdup("UDP: unknown");
+        }
 
         sprintf(tmp, "UDP: [%s]:%hu",
                 inet_ntoa(to->sin_addr), ntohs(to->sin_port));
@@ -98,6 +109,77 @@ netsnmp_udp_fmtaddr(netsnmp_transport *t
 
 
 
+#if defined IP_PKTINFO
+
+# define dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr))
+
+static int netsnmp_udp_recvfrom(int s, char *buf, int len, struct sockaddr *from, int *fromlen, struct in_addr *dstip)
+{
+    int r;
+    struct iovec iov[1];
+    char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
+    struct cmsghdr *cmsgptr;
+    struct msghdr msg;
+
+    iov[0].iov_base = buf;
+    iov[0].iov_len = len;
+
+    memset(&msg, 0, sizeof msg);
+    msg.msg_name = from;
+    msg.msg_namelen = *fromlen;
+    msg.msg_iov = iov;
+    msg.msg_iovlen = 1;
+    msg.msg_control = &cmsg;
+    msg.msg_controllen = sizeof(cmsg);
+
+    r = recvmsg(s, &msg, 0);
+
+    if (r == -1) {
+        return -1;
+    }
+    
+    DEBUGMSGTL(("netsnmp_udp", "got source addr: %s\n", inet_ntoa(((struct sockaddr_in *)from)->sin_addr)));
+    for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
+        if (cmsgptr->cmsg_level == SOL_IP && cmsgptr->cmsg_type == IP_PKTINFO) {
+            memcpy((void *) dstip, dstaddr(cmsgptr), sizeof(struct in_addr));
+            DEBUGMSGTL(("netsnmp_udp", "got destination (local) addr %s\n",
+                    inet_ntoa(*dstip)));
+        }
+    }
+    return r;
+}
+
+static int netsnmp_udp_sendto(int fd, struct in_addr *srcip, struct sockaddr *remote,
+			char *data, int len)
+{
+    struct iovec iov = { data, len };
+    struct {
+        struct cmsghdr cm;
+        struct in_pktinfo ipi;
+    } cmsg = {
+        .cm = {
+            .cmsg_len	= sizeof(struct cmsghdr) + sizeof(struct in_pktinfo),
+            .cmsg_level	= SOL_IP,
+            .cmsg_type	= IP_PKTINFO,
+        },
+        .ipi = {
+            .ipi_ifindex	= 0,
+            .ipi_spec_dst	= srcip ? srcip->s_addr : 0,
+        },
+    };
+    struct msghdr m = {
+        .msg_name	= remote,
+        .msg_namelen	= sizeof(struct sockaddr_in),
+        .msg_iov	= &iov,
+        .msg_iovlen	= 1,
+        .msg_control	= &cmsg,
+        .msg_controllen	= sizeof(cmsg),
+        .msg_flags	= 0,
+    };
+    return sendmsg(fd, &m, MSG_NOSIGNAL|MSG_DONTWAIT);
+}
+#endif /* IP_PKTINFO */
+
 /*
  * You can write something into opaque that will subsequently get passed back 
  * to your send function if you like.  For instance, you might want to
@@ -110,27 +192,33 @@ netsnmp_udp_recv(netsnmp_transport *t, v
 {
     int             rc = -1;
     socklen_t       fromlen = sizeof(struct sockaddr);
+    netsnmp_udp_addr_pair *addr_pair = NULL;
     struct sockaddr *from;
 
     if (t != NULL && t->sock >= 0) {
-        from = (struct sockaddr *) malloc(sizeof(struct sockaddr_in));
-        if (from == NULL) {
+        addr_pair = (netsnmp_udp_addr_pair *) malloc(sizeof(netsnmp_udp_addr_pair));
+        if (addr_pair == NULL) {
             *opaque = NULL;
             *olength = 0;
             return -1;
         } else {
-            memset(from, 0, fromlen);
+            memset(addr_pair, 0, sizeof(netsnmp_udp_addr_pair));
+            from = (struct sockaddr *) &(addr_pair->remote_addr);
         }
 
 	while (rc < 0) {
-	    rc = recvfrom(t->sock, buf, size, 0, from, &fromlen);
+#if defined IP_PKTINFO
+            rc = netsnmp_udp_recvfrom(t->sock, buf, size, from, &fromlen, &(addr_pair->local_addr));
+#else
+            rc = recvfrom(t->sock, buf, size, 0, from, &fromlen);
+#endif /* IP_PKTINFO */
 	    if (rc < 0 && errno != EINTR) {
 		break;
 	    }
 	}
 
         if (rc >= 0) {
-            char *str = netsnmp_udp_fmtaddr(NULL, from, fromlen);
+            char *str = netsnmp_udp_fmtaddr(NULL, addr_pair, sizeof(netsnmp_udp_addr_pair));
             DEBUGMSGTL(("netsnmp_udp",
 			"recvfrom fd %d got %d bytes (from %s)\n",
 			t->sock, rc, str));
@@ -139,8 +227,8 @@ netsnmp_udp_recv(netsnmp_transport *t, v
             DEBUGMSGTL(("netsnmp_udp", "recvfrom fd %d err %d (\"%s\")\n",
                         t->sock, errno, strerror(errno)));
         }
-        *opaque = (void *)from;
-        *olength = sizeof(struct sockaddr_in);
+        *opaque = (void *)addr_pair;
+        *olength = sizeof(netsnmp_udp_addr_pair);
     }
     return rc;
 }
@@ -152,24 +240,31 @@ netsnmp_udp_send(netsnmp_transport *t, v
 		 void **opaque, int *olength)
 {
     int rc = -1;
+    netsnmp_udp_addr_pair *addr_pair = NULL;
     struct sockaddr *to = NULL;
 
     if (opaque != NULL && *opaque != NULL &&
-        *olength == sizeof(struct sockaddr_in)) {
-        to = (struct sockaddr *) (*opaque);
+        *olength == sizeof(netsnmp_udp_addr_pair)) {
+        addr_pair = (netsnmp_udp_addr_pair *) (*opaque);
     } else if (t != NULL && t->data != NULL &&
-               t->data_length == sizeof(struct sockaddr_in)) {
-        to = (struct sockaddr *) (t->data);
+                t->data_length == sizeof(netsnmp_udp_addr_pair)) {
+        addr_pair = (netsnmp_udp_addr_pair *) (t->data);
     }
 
+    to = (struct sockaddr *) &(addr_pair->remote_addr);
+
     if (to != NULL && t != NULL && t->sock >= 0) {
-        char *str = netsnmp_udp_fmtaddr(NULL, (void *) to,
-					sizeof(struct sockaddr_in));
+        char *str = netsnmp_udp_fmtaddr(NULL, (void *) addr_pair,
+                                        sizeof(netsnmp_udp_addr_pair));
         DEBUGMSGTL(("netsnmp_udp", "send %d bytes from %p to %s on fd %d\n",
                     size, buf, str, t->sock));
         free(str);
 	while (rc < 0) {
-	    rc = sendto(t->sock, buf, size, 0, to, sizeof(struct sockaddr));
+#if defined IP_PKTINFO
+            rc = netsnmp_udp_sendto(t->sock, addr_pair ? &(addr_pair->local_addr) : NULL, to, buf, size);
+#else
+            rc = sendto(t->sock, buf, size, 0, to, sizeof(struct sockaddr));
+#endif /* IP_PKTINFO */
 	    if (rc < 0 && errno != EINTR) {
                 DEBUGMSGTL(("netsnmp_udp", "sendto error, rc %d (errno %d)\n",
                             rc, errno));
@@ -486,18 +581,26 @@ netsnmp_udp_transport(struct sockaddr_in
     int             rc = 0;
     char           *str = NULL;
     char           *client_socket = NULL;
+    netsnmp_udp_addr_pair *addr_pair = NULL;
 
     if (addr == NULL || addr->sin_family != AF_INET) {
         return NULL;
     }
 
+    addr_pair = (struct	udp_addr_pair *) malloc(sizeof(netsnmp_udp_addr_pair));
+    if (addr_pair == NULL) {
+        return NULL;
+    }
+    memset(addr_pair, 0, sizeof(netsnmp_udp_addr_pair));
+    memcpy(&(addr_pair->remote_addr), addr, sizeof(struct sockaddr_in));
+
     t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
     if (t == NULL) {
         return NULL;
     }
 
-    str = netsnmp_udp_fmtaddr(NULL, (void *)addr, 
-				 sizeof(struct sockaddr_in));
+    str = netsnmp_udp_fmtaddr(NULL, (void *)addr_pair, 
+                                 sizeof(netsnmp_udp_addr_pair));
     DEBUGMSGTL(("netsnmp_udp", "open %s %s:%d\n", local ? "local" : "remote",
                 str,addr->sin_port));
     free(str);
@@ -532,6 +635,18 @@ netsnmp_udp_transport(struct sockaddr_in
         t->local[5] = (htons(addr->sin_port) & 0x00ff) >> 0;
         t->local_length = 6;
 
+#ifdef  IP_PKTINFO
+        { 
+            int sockopt = 1;
+            int sockoptlen = sizeof(int);
+            if (setsockopt(t->sock, SOL_IP, IP_PKTINFO, &sockopt, sizeof sockopt) == -1) {
+                DEBUGMSGTL(("netsnmp_udp", "couldn't set IP_PKTINFO: %s\n",
+                    strerror(errno)));
+                return NULL;
+            }
+            DEBUGMSGTL(("netsnmp_udp", "set IP_PKTINFO\n"));
+        }
+#endif
         rc = bind(t->sock, (struct sockaddr *) addr,
                   sizeof(struct sockaddr));
         if (rc != 0) {
@@ -561,7 +679,7 @@ netsnmp_udp_transport(struct sockaddr_in
          * transport-specific data pointer for later use by netsnmp_udp_send.
          */
 
-        t->data = malloc(sizeof(struct sockaddr_in));
+        t->data = malloc(sizeof(netsnmp_udp_addr_pair));
         t->remote = malloc(6);
         if (t->data == NULL || t->remote == NULL) {
             netsnmp_transport_free(t);
@@ -571,8 +689,8 @@ netsnmp_udp_transport(struct sockaddr_in
         t->remote[4] = (htons(addr->sin_port) & 0xff00) >> 8;
         t->remote[5] = (htons(addr->sin_port) & 0x00ff) >> 0;
         t->remote_length = 6;
-        memcpy(t->data, addr, sizeof(struct sockaddr_in));
-        t->data_length = sizeof(struct sockaddr_in);
+        memcpy(t->data, addr_pair, sizeof(netsnmp_udp_addr_pair));
+        t->data_length = sizeof(netsnmp_udp_addr_pair);
     }
 
     /*
@@ -993,7 +1111,8 @@ netsnmp_udp_getSecName(void *opaque, int
                        char **contextName)
 {
     com2SecEntry   *c;
-    struct sockaddr_in *from = (struct sockaddr_in *) opaque;
+    netsnmp_udp_addr_pair *addr_pair = (netsnmp_udp_addr_pair *) opaque;
+    struct sockaddr_in *from = (struct sockaddr_in *) &(addr_pair->remote_addr);
     char           *ztcommunity = NULL;
 
     if (secName != NULL) {
@@ -1015,7 +1134,7 @@ netsnmp_udp_getSecName(void *opaque, int
      * name.  
      */
 
-    if (opaque == NULL || olength != sizeof(struct sockaddr_in) ||
+    if (opaque == NULL || olength != sizeof(netsnmp_udp_addr_pair) ||
         from->sin_family != AF_INET) {
         DEBUGMSGTL(("netsnmp_udp_getSecName",
 		    "no IPv4 source address in PDU?\n"));


Index: net-snmp.spec
===================================================================
RCS file: /cvs/dist/rpms/net-snmp/devel/net-snmp.spec,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -r1.87 -r1.88
--- net-snmp.spec	6 Sep 2006 07:46:15 -0000	1.87
+++ net-snmp.spec	13 Sep 2006 08:16:43 -0000	1.88
@@ -7,7 +7,7 @@
 Summary: A collection of SNMP protocol tools and libraries.
 Name: net-snmp
 Version: %{major_ver}
-Release: 7%{?dist}
+Release: 8%{?dist}
 Epoch: 1
 
 License: BSDish
@@ -42,6 +42,7 @@
 Patch29: net-snmp-5.3.1-config_libdir.patch
 Patch30: net-snmp-5.3.1-lm_sensors.patch
 Patch31: net-snmp-5.3.1-tcp-udp-mib-byteorder.patch
+Patch32: net-snmp-5.3.1-local-addr.patch
 
 Prereq: /sbin/chkconfig
 Obsoletes: ucd-snmp
@@ -149,6 +150,7 @@
 %patch29 -p1 -b .libdir
 %patch30 -p1 -b .lm_sensors
 %patch31 -p0 -b .byteorder
+%patch32 -p1 -b .local-addr
 
 # Do this patch with a perl hack...
 perl -pi -e "s|'\\\$install_libdir'|'%{_libdir}'|" ltmain.sh
@@ -180,6 +182,7 @@
 	--with-pic					\
 	--enable-embedded-perl				\
 	--enable-mfd-rewrites				\
+	--enable-local-smux				\
 	--with-sys-contact="root at localhost" <<EOF
 
 EOF
@@ -351,6 +354,10 @@
 %{_libdir}/lib*.so.*
 
 %changelog
+* Wed Sep 13 2006 Radek Vokal <rvokal at redhat.com> 5.3.1-8
+- enable smux to listen only on LOCAL by default (#181667)
+- use correct answer adrress 
+
 * Tue Sep  5 2006 Radek Vokal <rvokal at redhat.com> 5.3.1-7
 - better upstream patch for byteorder
 - add epoch to corespond with upstream versioning 




More information about the fedora-cvs-commits mailing list