summaryrefslogtreecommitdiffstats
path: root/sys/netinet/udp_usrreq.c
diff options
context:
space:
mode:
authorbms <bms@FreeBSD.org>2007-03-08 15:26:54 +0000
committerbms <bms@FreeBSD.org>2007-03-08 15:26:54 +0000
commit428a375b20f0af97722089874e08b6e7ef2142f8 (patch)
tree08e778f16008a77f0b796a0639cc7d0ee603fd3c /sys/netinet/udp_usrreq.c
parent0d80e5c2726cfb0eeb56d19ab729583febe6d46f (diff)
downloadFreeBSD-src-428a375b20f0af97722089874e08b6e7ef2142f8.zip
FreeBSD-src-428a375b20f0af97722089874e08b6e7ef2142f8.tar.gz
Fix IP_SENDSRCADDR semantics.
* To use this option with a UDP socket, it must be bound to a local port, and INADDR_ANY, to disallow possible collisions with existing udp inpcbs bound to the same port on other interfaces at send time. * If the socket is bound to INADDR_ANY, specifying IP_SENDSRCADDR with INADDR_ANY will be rejected as it is ambiguous. * If the socket is bound to an address other than INADDR_ANY, specifying IP_SENDSRCADDR with INADDR_ANY will be disallowed by in_pcbbind_setup(). Reviewed by: silence on -net Tested with: src/tools/regression/netinet/ipbroadcast MFC after: 4 days
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r--sys/netinet/udp_usrreq.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 2743cf7..0966f2e 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -747,7 +747,7 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
return (EMSGSIZE);
}
- src.sin_addr.s_addr = INADDR_ANY;
+ src.sin_family = 0;
if (control != NULL) {
/*
* XXX: Currently, we assume all the optional information is
@@ -797,7 +797,7 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
return (error);
}
- if (src.sin_addr.s_addr != INADDR_ANY || addr != NULL) {
+ if (src.sin_family == AF_INET || addr != NULL) {
INP_INFO_WLOCK(&udbinfo);
unlock_udbinfo = 1;
} else
@@ -808,10 +808,17 @@ udp_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr,
mac_create_mbuf_from_inpcb(inp, m);
#endif
+ /*
+ * If the IP_SENDSRCADDR control message was specified, override the
+ * source address for this datagram. Its use is invalidated if the
+ * address thus specified is incomplete or clobbers other inpcbs.
+ */
laddr = inp->inp_laddr;
lport = inp->inp_lport;
- if (src.sin_addr.s_addr != INADDR_ANY) {
- if (lport == 0) {
+ if (src.sin_family == AF_INET) {
+ if ((lport == 0) ||
+ (laddr.s_addr == INADDR_ANY &&
+ src.sin_addr.s_addr == INADDR_ANY)) {
error = EINVAL;
goto release;
}
OpenPOWER on IntegriCloud