Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.80 retrieving revision 1.82.2.6 diff -u -p -r1.80 -r1.82.2.6 --- src/sys/netinet/ip_input.c 1999/01/19 23:39:57 1.80 +++ src/sys/netinet/ip_input.c 2000/05/06 16:43:25 1.82.2.6 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.80 1999/01/19 23:39:57 mycroft Exp $ */ +/* $NetBSD: ip_input.c,v 1.82.2.6 2000/05/06 16:43:25 he Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -340,6 +340,16 @@ next: } ip = mtod(m, struct ip *); } + + /* + * RFC1122: packets with a multicast source address are + * not allowed. + */ + if (IN_MULTICAST(ip->ip_src.s_addr)) { + /* XXX stat */ + goto bad; + } + if (in_cksum(m, hlen) != 0) { ipstat.ips_badsum++; goto bad; @@ -353,6 +363,15 @@ next: len = ip->ip_len; /* + * Check for additional length bogosity + */ + if (len < hlen) + { + ipstat.ips_badlen++; + goto bad; + } + + /* * Check that the amount of data in the buffers * is as at least much as the IP header would have us expect. * Trim mbufs if longer than we expect. @@ -411,7 +430,8 @@ next: * Check our list of addresses, to see if the packet is for us. */ INADDR_TO_IA(ip->ip_dst, ia); - if (ia != NULL) goto ours; + if (ia != NULL) + goto ours; if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) { for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first; ifa != NULL; ifa = ifa->ifa_list.tqe_next) { @@ -579,6 +599,9 @@ found: /* * Switch out to protocol's input routine. */ +#if IFA_STATS + ia->ia_ifa.ifa_data.ifad_inbytes += ip->ip_len; +#endif ipstat.ips_delivered++; (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen); goto next; @@ -833,11 +856,11 @@ ip_dooptions(m) struct mbuf *m; { register struct ip *ip = mtod(m, struct ip *); - register u_char *cp; + register u_char *cp, *cp0; register struct ip_timestamp *ipt; register struct in_ifaddr *ia; int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB, forward = 0; - struct in_addr *sin, dst; + struct in_addr dst; n_time ntime; dst = ip->ip_dst; @@ -896,7 +919,7 @@ ip_dooptions(m) break; } off--; /* 0 origin */ - if (off > optlen - sizeof(struct in_addr)) { + if ((off + sizeof(struct in_addr)) > optlen) { /* * End of source route. Should be for us. */ @@ -938,7 +961,7 @@ ip_dooptions(m) * If no space remains, ignore. */ off--; /* 0 origin */ - if (off > optlen - sizeof(struct in_addr)) + if ((off + sizeof(struct in_addr)) > optlen) break; bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr, sizeof(ipaddr.sin_addr)); @@ -967,7 +990,7 @@ ip_dooptions(m) goto bad; break; } - sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1); + cp0 = (cp + ipt->ipt_ptr - 1); switch (ipt->ipt_flg) { case IPOPT_TS_TSONLY: @@ -982,8 +1005,8 @@ ip_dooptions(m) m->m_pkthdr.rcvif); if (ia == 0) continue; - bcopy((caddr_t)&ia->ia_addr.sin_addr, - (caddr_t)sin, sizeof(struct in_addr)); + bcopy(&ia->ia_addr.sin_addr, + cp0, sizeof(struct in_addr)); ipt->ipt_ptr += sizeof(struct in_addr); break; @@ -991,7 +1014,7 @@ ip_dooptions(m) if (ipt->ipt_ptr - 1 + sizeof(n_time) + sizeof(struct in_addr) > ipt->ipt_len) goto bad; - bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr, + bcopy(cp0, &ipaddr.sin_addr, sizeof(struct in_addr)); if (ifa_ifwithaddr((SA)&ipaddr) == 0) continue; @@ -1002,7 +1025,8 @@ ip_dooptions(m) goto bad; } ntime = iptime(); - bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1, + cp0 = (u_char *) &ntime; /* XXX GCC BUG */ + bcopy(cp0, (caddr_t)cp + ipt->ipt_ptr - 1, sizeof(n_time)); ipt->ipt_ptr += sizeof(n_time); } @@ -1214,7 +1238,7 @@ ip_forward(m, srcrt) ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), ip->ip_ttl); #endif - if (m->m_flags & M_BCAST || in_canforward(ip->ip_dst) == 0) { + if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) { ipstat.ips_cantforward++; m_freem(m); return;