summaryrefslogtreecommitdiff
blob: e80922144be60b299c9652e9f0e2816269561d21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
Fix clientaddr functionality. Includes further memory leak and newline fixes.

Previously, the clientaddr option in snmp.conf was parsed, but the actual
clientaddr was used to bind(), yet sendmsg() was still called with 0.0.0.0.

This patch alters:
- netsnmp_udp_fmtaddr: include both sides of addr_pair for debugging.
- netsnmp_udp_transport: Set addr_pair->local_addr in the remote && client_socket path.
- netsnmp_udp_transport: Print a debugging error on failure to bind()
- netsnmp_udp_transport: Print out the full client open addr_pair data.

Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
Status: Merged in upstream r16654
Tracking-URL: https://sourceforge.net/tracker/?func=detail&atid=312694&aid=1775124&group_id=12694

Further fixes:
Revision 16681
    add missing newline in debug msg
Revision 16704
    CHANGES: snmplib: BUG: Coverity #183: fix memory leak if IP_PKTINFO fails
Revision 16716
    CHANGES: snmplib: Do not leak memory whenever an udp address is formatted.

Fixes bug: bugs.gentoo.org/180266

diff -Naur net-snmp-5.4.1.orig/snmplib/snmpUDPDomain.c net-snmp-5.4.1/snmplib/snmpUDPDomain.c
--- net-snmp-5.4.1.orig/snmplib/snmpUDPDomain.c	2007-06-11 02:15:24.000000000 +0400
+++ net-snmp-5.4.1/snmplib/snmpUDPDomain.c	2007-12-27 18:15:56.000000000 +0300
@@ -104,11 +104,13 @@
 	char tmp[64];
         to = (struct sockaddr_in *) &(addr_pair->remote_addr);
         if (to == NULL) {
-            return strdup("UDP: unknown");
+            sprintf(tmp, "UDP: [%s]->unknown",
+                    inet_ntoa(addr_pair->local_addr));
+        } else {
+            sprintf(tmp, "UDP: [%s]->", inet_ntoa(addr_pair->local_addr));
+            sprintf(tmp + strlen(tmp), "[%s]:%hd",
+                    inet_ntoa(to->sin_addr), ntohs(to->sin_port));
         }
-
-        sprintf(tmp, "UDP: [%s]:%hu",
-                inet_ntoa(to->sin_addr), ntohs(to->sin_port));
         return strdup(tmp);
     }
 }
@@ -642,6 +644,7 @@
             if (setsockopt(t->sock, SOL_IP, IP_PKTINFO, &sockopt, sizeof sockopt) == -1) {
                 DEBUGMSGTL(("netsnmp_udp", "couldn't set IP_PKTINFO: %s\n",
                     strerror(errno)));
+                netsnmp_transport_free(t);
                 return NULL;
             }
             DEBUGMSGTL(("netsnmp_udp", "set IP_PKTINFO\n"));
@@ -667,10 +670,24 @@
         if (client_socket) {
             struct sockaddr_in client_addr;
             netsnmp_sockaddr_in2(&client_addr, client_socket, NULL);
+            addr_pair.local_addr = client_addr.sin_addr;
             client_addr.sin_port = 0;
-            bind(t->sock, (struct sockaddr *)&client_addr,
+            rc = bind(t->sock, (struct sockaddr *)&client_addr,
                   sizeof(struct sockaddr));
+            if ( rc != 0 ) {
+                DEBUGMSGTL(("netsnmp_udp", "failed to bind for clientaddr: %d %s\n",
+                            errno, strerror(errno)));
+                netsnmp_udp_close(t);
+                netsnmp_transport_free(t);
+                return NULL;
+            }
         }
+
+        str = netsnmp_udp_fmtaddr(NULL, (void *)&addr_pair,
+                 sizeof(netsnmp_udp_addr_pair));
+        DEBUGMSGTL(("netsnmp_udp", "client open %s\n", str));
+        free(str);
+
         /*
          * Save the (remote) address in the
          * transport-specific data pointer for later use by netsnmp_udp_send.
@@ -839,12 +856,12 @@
                 if (host == NULL) {
                     DEBUGMSGTL(("netsnmp_sockaddr_in",
                                 "servname not numeric, "
-				"check if it really is a destination)"));
+				"check if it really is a destination)\n"));
                     host = port;
                     port = NULL;
                 } else {
                     DEBUGMSGTL(("netsnmp_sockaddr_in",
-                                "servname not numeric"));
+                                "servname not numeric\n"));
                     free(peername);
                     return 0;
                 }