summaryrefslogtreecommitdiffstats
path: root/sys/netinet/udp_usrreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r--sys/netinet/udp_usrreq.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 6bfe5238e4b..4a90f786784 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.180 2014/04/14 09:06:42 mpi Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.181 2014/04/16 13:04:38 mpi Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -972,7 +972,7 @@ udp_output(struct mbuf *m, ...)
struct udpiphdr *ui;
u_int32_t ipsecflowinfo = 0;
int len = m->m_pkthdr.len;
- struct in_addr laddr = { INADDR_ANY };
+ struct in_addr *laddr;
int error = 0;
va_list ap;
@@ -998,30 +998,46 @@ udp_output(struct mbuf *m, ...)
if (addr) {
sin = mtod(addr, struct sockaddr_in *);
+
if (addr->m_len != sizeof(*sin)) {
error = EINVAL;
goto release;
}
+ if (sin->sin_family != AF_INET) {
+ error = EAFNOSUPPORT;
+ goto release;
+ }
+ if (sin->sin_port == 0) {
+ error = EADDRNOTAVAIL;
+ goto release;
+ }
+
if (inp->inp_faddr.s_addr != INADDR_ANY) {
error = EISCONN;
goto release;
}
- if ((error = in_fixaddr(inp, sin, &laddr)))
+
+ laddr = in_selectsrc(sin, inp->inp_moptions, &inp->inp_route,
+ &inp->inp_laddr, &error, inp->inp_rtableid);
+ if (laddr == NULL) {
+ if (error == 0)
+ error = EADDRNOTAVAIL;
goto release;
+ }
if (inp->inp_lport == 0) {
int s = splsoftnet();
error = in_pcbbind(inp, NULL, curproc);
splx(s);
- if (error) goto release;
+ if (error)
+ goto release;
}
} else {
if (inp->inp_faddr.s_addr == INADDR_ANY) {
error = ENOTCONN;
goto release;
}
- if (laddr.s_addr == INADDR_ANY)
- laddr = inp->inp_laddr;
+ laddr = &inp->inp_laddr;
}
#ifdef IPSEC
@@ -1081,7 +1097,7 @@ udp_output(struct mbuf *m, ...)
bzero(ui->ui_x1, sizeof ui->ui_x1);
ui->ui_pr = IPPROTO_UDP;
ui->ui_len = htons((u_int16_t)len + sizeof (struct udphdr));
- ui->ui_src = laddr;
+ ui->ui_src = *laddr;
ui->ui_dst = sin ? sin->sin_addr : inp->inp_faddr;
ui->ui_sport = inp->inp_lport;
ui->ui_dport = sin ? sin->sin_port : inp->inp_fport;