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/raw_ip.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/raw_ip.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.31 retrieving revision 1.38 diff -u -p -r1.31 -r1.38 --- src/sys/netinet/raw_ip.c 1996/06/23 12:12:49 1.31 +++ src/sys/netinet/raw_ip.c 1997/11/16 20:58:18 1.38 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_ip.c,v 1.31 1996/06/23 12:12:49 mycroft Exp $ */ +/* $NetBSD: raw_ip.c,v 1.38 1997/11/16 20:58:18 mycroft Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1993 @@ -81,10 +81,9 @@ void rip_init() { - in_pcbinit(&rawcbtable, 1); + in_pcbinit(&rawcbtable, 1, 1); } -struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET }; /* * Setup generic address and protocol structures * for raw_input routine, then pass them along with @@ -101,40 +100,56 @@ rip_input(m, va_alist) { register struct ip *ip = mtod(m, struct ip *); register struct inpcb *inp; - struct socket *last = 0; + struct inpcb *last = 0; + struct mbuf *opts = 0; + struct sockaddr_in ripsrc; + ripsrc.sin_family = AF_INET; + ripsrc.sin_len = sizeof(struct sockaddr_in); ripsrc.sin_addr = ip->ip_src; + ripsrc.sin_port = 0; + bzero((caddr_t)ripsrc.sin_zero, sizeof(ripsrc.sin_zero)); + for (inp = rawcbtable.inpt_queue.cqh_first; inp != (struct inpcb *)&rawcbtable.inpt_queue; inp = inp->inp_queue.cqe_next) { if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p) continue; - if (inp->inp_laddr.s_addr != INADDR_ANY && - inp->inp_laddr.s_addr != ip->ip_dst.s_addr) + if (!in_nullhost(inp->inp_laddr) && + !in_hosteq(inp->inp_laddr, ip->ip_dst)) continue; - if (inp->inp_faddr.s_addr != INADDR_ANY && - inp->inp_faddr.s_addr != ip->ip_src.s_addr) + if (!in_nullhost(inp->inp_faddr) && + !in_hosteq(inp->inp_faddr, ip->ip_src)) continue; if (last) { struct mbuf *n; if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) { - if (sbappendaddr(&last->so_rcv, - sintosa(&ripsrc), n, - (struct mbuf *)0) == 0) + if (last->inp_flags & INP_CONTROLOPTS || + last->inp_socket->so_options & SO_TIMESTAMP) + ip_savecontrol(last, &opts, ip, n); + if (sbappendaddr(&last->inp_socket->so_rcv, + sintosa(&ripsrc), n, opts) == 0) { /* should notify about lost packet */ m_freem(n); - else - sorwakeup(last); + if (opts) + m_freem(opts); + } else + sorwakeup(last->inp_socket); } } - last = inp->inp_socket; + last = inp; } if (last) { - if (sbappendaddr(&last->so_rcv, sintosa(&ripsrc), m, - (struct mbuf *)0) == 0) + if (last->inp_flags & INP_CONTROLOPTS || + last->inp_socket->so_options & SO_TIMESTAMP) + ip_savecontrol(last, &opts, ip, m); + if (sbappendaddr(&last->inp_socket->so_rcv, + sintosa(&ripsrc), m, opts) == 0) { m_freem(m); - else - sorwakeup(last); + if (opts) + m_freem(opts); + } else + sorwakeup(last->inp_socket); } else { m_freem(m); ipstat.ips_noproto++; @@ -166,13 +181,18 @@ rip_output(m, va_alist) va_end(ap); flags = - (inp->inp_socket->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST; + (inp->inp_socket->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST + | IP_RETURNMTU; /* * If the user handed us a complete IP packet, use it. * Otherwise, allocate an mbuf for a header and fill it in. */ if ((inp->inp_flags & INP_HDRINCL) == 0) { + if ((m->m_pkthdr.len + sizeof(struct ip)) > IP_MAXPACKET) { + m_freem(m); + return (EMSGSIZE); + } M_PREPEND(m, sizeof(struct ip), M_WAIT); ip = mtod(m, struct ip *); ip->ip_tos = 0; @@ -184,7 +204,15 @@ rip_output(m, va_alist) ip->ip_ttl = MAXTTL; opts = inp->inp_options; } else { + if (m->m_pkthdr.len > IP_MAXPACKET) { + m_freem(m); + return (EMSGSIZE); + } ip = mtod(m, struct ip *); + if (m->m_pkthdr.len != ip->ip_len) { + m_freem(m); + return (EINVAL); + } if (ip->ip_id == 0) ip->ip_id = htons(ip_id++); opts = NULL; @@ -192,7 +220,7 @@ rip_output(m, va_alist) flags |= IP_RAWOUTPUT; ipstat.ips_rawout++; } - return (ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions)); + return (ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions, &inp->inp_errormtu)); } /* @@ -285,7 +313,7 @@ rip_bind(inp, nam) if (addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK) return (EAFNOSUPPORT); - if (addr->sin_addr.s_addr != INADDR_ANY && + if (!in_nullhost(addr->sin_addr) && ifa_ifwithaddr(sintosa(addr)) == 0) return (EADDRNOTAVAIL); inp->inp_laddr = addr->sin_addr; @@ -315,7 +343,7 @@ rip_disconnect(inp) struct inpcb *inp; { - inp->inp_faddr.s_addr = INADDR_ANY; + inp->inp_faddr = zeroin_addr; } u_long rip_sendspace = RIPSNDQ;