diff options
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r-- | sys/netinet/ip_input.c | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 7cd856889801..3cf13cf0e6e9 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -350,6 +350,16 @@ ip_input(struct mbuf *m) } ip = mtod(m, struct ip *); } + + /* 127/8 must not appear on wire - RFC1122 */ + if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || + (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) { + if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) { + ipstat.ips_badaddr++; + goto bad; + } + } + if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) { sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); } else { @@ -393,15 +403,10 @@ tooshort: m_adj(m, ip->ip_len - m->m_pkthdr.len); } - /* - * Don't accept packets with a loopback destination address - * unless they arrived via the loopback interface. - */ - if ((ntohl(ip->ip_dst.s_addr) & IN_CLASSA_NET) == - (IN_LOOPBACKNET << IN_CLASSA_NSHIFT) && - (m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) { - goto bad; - } +#ifdef IPSEC + if (ipsec_gethist(m, NULL)) + goto pass; +#endif /* * IpHack's section. @@ -796,6 +801,19 @@ found: } #endif +#ifdef IPSEC + /* + * enforce IPsec policy checking if we are seeing last header. + * note that we do not visit this with protocols with pcb layer + * code - like udp/tcp/raw ip. + */ + if ((inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0 && + ipsec4_in_reject(m, NULL)) { + ipsecstat.in_polvio++; + goto bad; + } +#endif + /* * Switch out to protocol's input routine. */ @@ -1189,6 +1207,10 @@ ip_dooptions(m) */ case IPOPT_LSRR: case IPOPT_SSRR: + if (optlen < IPOPT_OFFSET + sizeof(*cp)) { + code = &cp[IPOPT_OLEN] - (u_char *)ip; + goto bad; + } if ((off = cp[IPOPT_OFFSET]) < IPOPT_MINOFF) { code = &cp[IPOPT_OFFSET] - (u_char *)ip; goto bad; @@ -1308,12 +1330,21 @@ nosourcerouting: case IPOPT_TS: code = cp - (u_char *)ip; ipt = (struct ip_timestamp *)cp; - if (ipt->ipt_len < 5) + if (ipt->ipt_len < 4 || ipt->ipt_len > 40) { + code = (u_char *)&ipt->ipt_len - (u_char *)ip; goto bad; + } + if (ipt->ipt_ptr < 5) { + code = (u_char *)&ipt->ipt_ptr - (u_char *)ip; + goto bad; + } if (ipt->ipt_ptr > ipt->ipt_len - (int)sizeof(int32_t)) { - if (++ipt->ipt_oflw == 0) + if (++ipt->ipt_oflw == 0) { + code = (u_char *)&ipt->ipt_ptr - + (u_char *)ip; goto bad; + } break; } sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1); @@ -1324,8 +1355,11 @@ nosourcerouting: case IPOPT_TS_TSANDADDR: if (ipt->ipt_ptr - 1 + sizeof(n_time) + - sizeof(struct in_addr) > ipt->ipt_len) + sizeof(struct in_addr) > ipt->ipt_len) { + code = (u_char *)&ipt->ipt_ptr - + (u_char *)ip; goto bad; + } ipaddr.sin_addr = dst; ia = (INA)ifaof_ifpforaddr((SA)&ipaddr, m->m_pkthdr.rcvif); @@ -1338,8 +1372,11 @@ nosourcerouting: case IPOPT_TS_PRESPEC: if (ipt->ipt_ptr - 1 + sizeof(n_time) + - sizeof(struct in_addr) > ipt->ipt_len) + sizeof(struct in_addr) > ipt->ipt_len) { + code = (u_char *)&ipt->ipt_ptr - + (u_char *)ip; goto bad; + } (void)memcpy(&ipaddr.sin_addr, sin, sizeof(struct in_addr)); if (ifa_ifwithaddr((SA)&ipaddr) == 0) @@ -1348,6 +1385,9 @@ nosourcerouting: break; default: + /* XXX can't take &ipt->ipt_flg */ + code = (u_char *)&ipt->ipt_ptr - + (u_char *)ip + 1; goto bad; } ntime = iptime(); |