diff options
author | glebius <glebius@FreeBSD.org> | 2012-09-20 05:41:20 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2012-09-20 05:41:20 +0000 |
commit | 31abec7892fc7f7b272cf84350d175065a76bc86 (patch) | |
tree | 6bb8a726b57686058e68e3eb61325a42868ea127 /contrib/bsnmp/snmpd | |
parent | 32d0efe39300667d09edc9a16cefedeb9128035d (diff) | |
download | FreeBSD-src-31abec7892fc7f7b272cf84350d175065a76bc86.zip FreeBSD-src-31abec7892fc7f7b272cf84350d175065a76bc86.tar.gz |
Re-do r240271:
- Set IP_RECVDSTADDR sockopt on the socket only in case if
it is INADDR_ANY bound.
- Supply IP_SENDSRCADDR control message only if we did receive
IP_RECVDSTADDR control message.
This fixes operation of snmpd bound to a specific local IP address.
PR: bin/171279
Diffstat (limited to 'contrib/bsnmp/snmpd')
-rw-r--r-- | contrib/bsnmp/snmpd/main.c | 10 | ||||
-rw-r--r-- | contrib/bsnmp/snmpd/trans_udp.c | 15 |
2 files changed, 17 insertions, 8 deletions
diff --git a/contrib/bsnmp/snmpd/main.c b/contrib/bsnmp/snmpd/main.c index 6fdc6d3..e7257b5 100644 --- a/contrib/bsnmp/snmpd/main.c +++ b/contrib/bsnmp/snmpd/main.c @@ -1203,6 +1203,8 @@ snmpd_input(struct port_input *pi, struct tport *tport) ret = recv_stream(pi); } else { + struct in_addr *laddr; + memset(cbuf, 0, CMSG_SPACE(sizeof(struct in_addr))); msg.msg_control = cbuf; msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr)); @@ -1210,8 +1212,14 @@ snmpd_input(struct port_input *pi, struct tport *tport) cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); cmsgp->cmsg_level = IPPROTO_IP; cmsgp->cmsg_type = IP_SENDSRCADDR; + laddr = (struct in_addr *)CMSG_DATA(cmsgp); - ret = recv_dgram(pi, (struct in_addr *)CMSG_DATA(cmsgp)); + ret = recv_dgram(pi, laddr); + + if (laddr->s_addr == 0) { + msg.msg_control = NULL; + msg.msg_controllen = 0; + } } if (ret == -1) diff --git a/contrib/bsnmp/snmpd/trans_udp.c b/contrib/bsnmp/snmpd/trans_udp.c index 0a119d2..3faef41 100644 --- a/contrib/bsnmp/snmpd/trans_udp.c +++ b/contrib/bsnmp/snmpd/trans_udp.c @@ -109,13 +109,6 @@ udp_init_port(struct tport *tp) syslog(LOG_ERR, "creating UDP socket: %m"); return (SNMP_ERR_RES_UNAVAIL); } - if (setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on, - sizeof(on)) == -1) { - syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m"); - close(p->input.fd); - p->input.fd = -1; - return (SNMP_ERR_GENERR); - } ip = (p->addr[0] << 24) | (p->addr[1] << 16) | (p->addr[2] << 8) | p->addr[3]; memset(&addr, 0, sizeof(addr)); @@ -123,6 +116,14 @@ udp_init_port(struct tport *tp) addr.sin_port = htons(p->port); addr.sin_family = AF_INET; addr.sin_len = sizeof(addr); + if (addr.sin_addr.s_addr == INADDR_ANY && + setsockopt(p->input.fd, IPPROTO_IP, IP_RECVDSTADDR, &on, + sizeof(on)) == -1) { + syslog(LOG_ERR, "setsockopt(IP_RECVDSTADDR): %m"); + close(p->input.fd); + p->input.fd = -1; + return (SNMP_ERR_GENERR); + } if (bind(p->input.fd, (struct sockaddr *)&addr, sizeof(addr))) { if (errno == EADDRNOTAVAIL) { close(p->input.fd); |