diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1262,6 +1262,8 @@ } 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 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -519,6 +519,11 @@ 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 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -672,6 +672,8 @@ * 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 @@ 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 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -368,6 +368,8 @@ 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.