diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 5768979f21e..3b8931a9026 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1262,6 +1262,8 @@ in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr *laddr, } done: + if (error == 0 && laddr->s_addr == INADDR_ANY) + return (EHOSTUNREACH); return (error); } diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index b8fb3861c5b..5de09a32a2f 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -519,6 +519,11 @@ ip_input(struct mbuf *m) goto bad; } } + /* The unspecified address can appear only as a src address - RFC1122 */ + if (__predict_false(ntohl(ip->ip_dst.s_addr) == INADDR_ANY)) { + IPSTAT_INC(ips_badaddr); + goto bad; + } if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) { sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 72faf53299e..7b9c5668e88 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -672,6 +672,8 @@ tcp_input_with_port(struct mbuf **mp, int *offp, int proto, uint16_t port) * Note that packets with unspecified IPv6 destination is * already dropped in ip6_input. */ + KASSERT(!IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst), + ("%s: unspecified destination v6 address", __func__)); if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { /* XXX stat */ goto drop; @@ -740,6 +742,12 @@ tcp_input_with_port(struct mbuf **mp, int *offp, int proto, uint16_t port) TCPSTAT_INC(tcps_rcvbadsum); goto drop; } + KASSERT(ip->ip_dst.s_addr != INADDR_ANY, + ("%s: unspecified destination v4 address", __func__)); + if (__predict_false(ip->ip_src.s_addr == INADDR_ANY)) { + /* XXX stat */ + goto drop; + } } #endif /* INET */ diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 8b1f97f322e..81a3fd49a93 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -368,6 +368,8 @@ in6_pcbladdr(struct inpcb *inp, struct sockaddr_in6 *sin6, inp, inp->inp_cred, scope_ambiguous, &in6a, NULL); if (error) return (error); + if (IN6_IS_ADDR_UNSPECIFIED(&in6a)) + return (EHOSTUNREACH); /* * Do not update this earlier, in case we return with an error.