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.101 retrieving revision 1.116 diff -u -p -r1.101 -r1.116 --- src/sys/netinet/ip_input.c 2000/02/17 10:59:35 1.101 +++ src/sys/netinet/ip_input.c 2000/07/06 12:51:40 1.116 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.101 2000/02/17 10:59:35 darrenr Exp $ */ +/* $NetBSD: ip_input.c,v 1.116 2000/07/06 12:51:40 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -120,7 +120,8 @@ #include #include -#include +#include + #include #include @@ -139,10 +140,13 @@ #include #include "gif.h" +#ifdef MROUTING +#include +#endif + #ifdef IPSEC #include #include -#include #endif #ifndef IPFORWARDING @@ -200,7 +204,6 @@ struct in_ifaddrhashhead *in_ifaddrhasht struct ifqueue ipintrq; struct ipstat ipstat; u_int16_t ip_id; -int ip_defttl; struct ipqhead ipq; int ipq_locked; @@ -281,8 +284,8 @@ static void save_rte __P((u_char *, stru void ip_init() { - register struct protosw *pr; - register int i; + struct protosw *pr; + int i; pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl", 0, NULL, NULL, M_IPQ); @@ -340,10 +343,10 @@ ipintr() void ip_input(struct mbuf *m) { - register struct ip *ip = NULL; - register struct ipq *fp; - register struct in_ifaddr *ia; - register struct ifaddr *ifa; + struct ip *ip = NULL; + struct ipq *fp; + struct in_ifaddr *ia; + struct ifaddr *ifa; struct ipqent *ipqe; int hlen = 0, mff, len; int downmatch; @@ -464,7 +467,7 @@ ip_input(struct mbuf *m) * in the list may have previously cleared it. */ m0 = m; - pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IP]]); + pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh); for (; pfh; pfh = pfh->pfil_link.tqe_next) if (pfh->pfil_func) { rv = pfh->pfil_func(ip, hlen, @@ -709,11 +712,11 @@ bad: */ struct mbuf * ip_reass(ipqe, fp) - register struct ipqent *ipqe; - register struct ipq *fp; + struct ipqent *ipqe; + struct ipq *fp; { - register struct mbuf *m = ipqe->ipqe_m; - register struct ipqent *nq, *p, *q; + struct mbuf *m = ipqe->ipqe_m; + struct ipqent *nq, *p, *q; struct ip *ip; struct mbuf *t; int hlen = ipqe->ipqe_ip->ip_hl << 2; @@ -843,8 +846,6 @@ insert: * Make header visible. */ ip->ip_len = next; - ip->ip_ttl = 0; /* xxx */ - ip->ip_sum = 0; ip->ip_src = fp->ipq_src; ip->ip_dst = fp->ipq_dst; LIST_REMOVE(fp, ipq_q); @@ -853,7 +854,7 @@ insert: m->m_data -= (ip->ip_hl << 2); /* some debugging cruft by sklower, below, will go away soon */ if (m->m_flags & M_PKTHDR) { /* XXX this should be done elsewhere */ - register int plen = 0; + int plen = 0; for (t = m; t; t = t->m_next) plen += t->m_len; m->m_pkthdr.len = plen; @@ -875,7 +876,7 @@ void ip_freef(fp) struct ipq *fp; { - register struct ipqent *q, *p; + struct ipqent *q, *p; IPQ_LOCK_CHECK(); @@ -897,7 +898,7 @@ ip_freef(fp) void ip_slowtimo() { - register struct ipq *fp, *nfp; + struct ipq *fp, *nfp; int s = splsoftnet(); IPQ_LOCK(); @@ -948,12 +949,12 @@ int ip_dooptions(m) struct mbuf *m; { - register struct ip *ip = mtod(m, struct ip *); - register u_char *cp; - register struct ip_timestamp *ipt; - register struct in_ifaddr *ia; + struct ip *ip = mtod(m, struct ip *); + u_char *cp, *cp0; + struct ip_timestamp *ipt; + 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; @@ -966,8 +967,12 @@ ip_dooptions(m) if (opt == IPOPT_NOP) optlen = 1; else { + if (cnt < IPOPT_OLEN + sizeof(*cp)) { + code = &cp[IPOPT_OLEN] - (u_char *)ip; + goto bad; + } optlen = cp[IPOPT_OLEN]; - if (optlen <= 0 || optlen > cnt) { + if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt) { code = &cp[IPOPT_OLEN] - (u_char *)ip; goto bad; } @@ -993,6 +998,10 @@ ip_dooptions(m) code = ICMP_UNREACH_NET_PROHIB; goto bad; } + 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; @@ -1012,7 +1021,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. */ @@ -1044,6 +1053,10 @@ ip_dooptions(m) break; case IPOPT_RR: + 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; @@ -1052,7 +1065,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)); @@ -1075,14 +1088,23 @@ ip_dooptions(m) 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 - 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); + cp0 = (cp + ipt->ipt_ptr - 1); switch (ipt->ipt_flg) { case IPOPT_TS_TSONLY: @@ -1090,23 +1112,29 @@ ip_dooptions(m) 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 = ifatoia(ifaof_ifpforaddr(sintosa(&ipaddr), 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; 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; - bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr, + } + bcopy(cp0, &ipaddr.sin_addr, sizeof(struct in_addr)); if (ifatoia(ifa_ifwithaddr(sintosa(&ipaddr))) == NULL) @@ -1115,10 +1143,14 @@ ip_dooptions(m) break; default: + /* XXX can't take &ipt->ipt_flg */ + code = (u_char *)&ipt->ipt_ptr - + (u_char *)ip + 1; goto bad; } ntime = iptime(); - bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1, + cp0 = (u_char *) &ntime; /* XXX grumble, GCC... */ + bcopy(cp0, (caddr_t)cp + ipt->ipt_ptr - 1, sizeof(n_time)); ipt->ipt_ptr += sizeof(n_time); } @@ -1147,7 +1179,7 @@ struct in_ifaddr * ip_rtaddr(dst) struct in_addr dst; { - register struct sockaddr_in *sin; + struct sockaddr_in *sin; sin = satosin(&ipforward_rt.ro_dst); @@ -1198,8 +1230,8 @@ save_rte(option, dst) struct mbuf * ip_srcroute() { - register struct in_addr *p, *q; - register struct mbuf *m; + struct in_addr *p, *q; + struct mbuf *m; if (ip_nhops == 0) return ((struct mbuf *)0); @@ -1268,12 +1300,12 @@ ip_srcroute() */ void ip_stripoptions(m, mopt) - register struct mbuf *m; + struct mbuf *m; struct mbuf *mopt; { - register int i; + int i; struct ip *ip = mtod(m, struct ip *); - register caddr_t opts; + caddr_t opts; int olen; olen = (ip->ip_hl << 2) - sizeof (struct ip); @@ -1315,9 +1347,9 @@ ip_forward(m, srcrt) struct mbuf *m; int srcrt; { - register struct ip *ip = mtod(m, struct ip *); - register struct sockaddr_in *sin; - register struct rtentry *rt; + struct ip *ip = mtod(m, struct ip *); + struct sockaddr_in *sin; + struct rtentry *rt; int error, type = 0, code = 0; struct mbuf *mcopy; n_long dest; @@ -1403,8 +1435,9 @@ ip_forward(m, srcrt) } #ifdef IPSEC - m->m_pkthdr.rcvif = NULL; -#endif /*IPSEC*/ + /* Don't lookup socket in forwading case */ + ipsec_setsocket(m, NULL); +#endif error = ip_output(m, (struct mbuf *)0, &ipforward_rt, (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), 0); if (error) @@ -1514,10 +1547,10 @@ ip_forward(m, srcrt) void ip_savecontrol(inp, mp, ip, m) - register struct inpcb *inp; - register struct mbuf **mp; - register struct ip *ip; - register struct mbuf *m; + struct inpcb *inp; + struct mbuf **mp; + struct ip *ip; + struct mbuf *m; { if (inp->inp_socket->so_options & SO_TIMESTAMP) {