fix ip packet forwarding to not stomp on headers when fragmented;
authorSam Leffler <sam@ucbvax.Berkeley.EDU>
Fri, 13 May 1983 06:04:55 +0000 (22:04 -0800)
committerSam Leffler <sam@ucbvax.Berkeley.EDU>
Fri, 13 May 1983 06:04:55 +0000 (22:04 -0800)
SCCS-vsn: sys/netinet/ip_input.c 1.67
SCCS-vsn: sys/netinet/ip_output.c 1.47
SCCS-vsn: sys/netinet/ip_var.h 4.10
SCCS-vsn: sys/netinet/raw_ip.c 4.18
SCCS-vsn: sys/netinet/tcp_output.c 4.53
SCCS-vsn: sys/netinet/udp_usrreq.c 4.47

usr/src/sys/netinet/ip_input.c
usr/src/sys/netinet/ip_output.c
usr/src/sys/netinet/ip_var.h
usr/src/sys/netinet/raw_ip.c
usr/src/sys/netinet/tcp_output.c
usr/src/sys/netinet/udp_usrreq.c

index f3dcbec..5499ddc 100644 (file)
@@ -1,4 +1,4 @@
-/*     ip_input.c      1.66    83/03/12        */
+/*     ip_input.c      1.67    83/05/12        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -646,8 +646,7 @@ ip_forward(ip)
        mcopy = m_copy(dtom(ip), 0, imin(ip->ip_len, 64));
        ip_stripoptions(ip, mopt);
 
        mcopy = m_copy(dtom(ip), 0, imin(ip->ip_len, 64));
        ip_stripoptions(ip, mopt);
 
-       /* last 0 here means no directed broadcast */
-       error = ip_output(dtom(ip), mopt, (struct route *)0, 0);
+       error = ip_output(dtom(ip), mopt, (struct route *)0, IP_FORWARDING);
        if (error == 0) {
                if (mcopy)
                        m_freem(mcopy);
        if (error == 0) {
                if (mcopy)
                        m_freem(mcopy);
index 034d856..10453c9 100644 (file)
@@ -1,4 +1,4 @@
-/*     ip_output.c     1.46    83/02/10        */
+/*     ip_output.c     1.47    83/05/12        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 
 int    ipnorouteprint = 0;
 
 
 int    ipnorouteprint = 0;
 
-ip_output(m, opt, ro, allowbroadcast)
+ip_output(m, opt, ro, flags)
        struct mbuf *m;
        struct mbuf *opt;
        struct route *ro;
        struct mbuf *m;
        struct mbuf *opt;
        struct route *ro;
-       int allowbroadcast;
+       int flags;
 {
        register struct ip *ip = mtod(m, struct ip *);
        register struct ifnet *ifp;
 {
        register struct ip *ip = mtod(m, struct ip *);
        register struct ifnet *ifp;
@@ -35,10 +35,12 @@ ip_output(m, opt, ro, allowbroadcast)
        /*
         * Fill in IP header.
         */
        /*
         * Fill in IP header.
         */
-       ip->ip_v = IPVERSION;
        ip->ip_hl = hlen >> 2;
        ip->ip_hl = hlen >> 2;
-       ip->ip_off &= IP_DF;
-       ip->ip_id = htons(ip_id++);
+       if ((flags & IP_FORWARDING) == 0) {
+               ip->ip_v = IPVERSION;
+               ip->ip_off &= IP_DF;
+               ip->ip_id = htons(ip_id++);
+       }
 
        /*
         * Route packet.
 
        /*
         * Route packet.
@@ -52,19 +54,23 @@ ip_output(m, opt, ro, allowbroadcast)
                ro->ro_dst.sa_family = AF_INET;
                ((struct sockaddr_in *)&ro->ro_dst)->sin_addr = ip->ip_dst;
                /*
                ro->ro_dst.sa_family = AF_INET;
                ((struct sockaddr_in *)&ro->ro_dst)->sin_addr = ip->ip_dst;
                /*
-                * If routing to interface only, short circuit routing lookup.
+                * If routing to interface only,
+                * short circuit routing lookup.
                 */
                 */
-               if (ro == &routetoif) {
-                       /* check ifp is AF_INET??? */
+               if (flags & IP_ROUTETOIF) {
                        ifp = if_ifonnetof(in_netof(ip->ip_dst));
                        ifp = if_ifonnetof(in_netof(ip->ip_dst));
-                       if (ifp == 0)
-                               goto unreachable;
+                       if (ifp == 0) {
+                               error = ENETUNREACH;
+                               goto bad;
+                       }
                        goto gotif;
                }
                rtalloc(ro);
        }
                        goto gotif;
                }
                rtalloc(ro);
        }
-       if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0)
-               goto unreachable;
+       if (ro->ro_rt == 0 || (ifp = ro->ro_rt->rt_ifp) == 0) {
+               error = ENETUNREACH;
+               goto bad;
+       }
        ro->ro_rt->rt_use++;
        if (ro->ro_rt->rt_flags & RTF_GATEWAY)
                dst = &ro->ro_rt->rt_gateway;
        ro->ro_rt->rt_use++;
        if (ro->ro_rt->rt_flags & RTF_GATEWAY)
                dst = &ro->ro_rt->rt_gateway;
@@ -89,7 +95,7 @@ gotif:
                        error = EADDRNOTAVAIL;
                        goto bad;
                }
                        error = EADDRNOTAVAIL;
                        goto bad;
                }
-               if (!allowbroadcast) {
+               if ((flags & IP_ALLOWBROADCAST) == 0) {
                        error = EACCES;
                        goto bad;
                }
                        error = EACCES;
                        goto bad;
                }
@@ -173,15 +179,10 @@ gotif:
        m_freem(m);
        goto done;
 
        m_freem(m);
        goto done;
 
-unreachable:
-       if (ipnorouteprint)
-               printf("no route to %x (from %x, len %d)\n",
-                   ip->ip_dst.s_addr, ip->ip_src.s_addr, ip->ip_len);
-       error = ENETUNREACH;
 bad:
        m_freem(m);
 done:
 bad:
        m_freem(m);
 done:
-       if (ro == &iproute && ro->ro_rt)
+       if (ro == &iproute && (flags & IP_ROUTETOIF) == 0 && ro->ro_rt)
                RTFREE(ro->ro_rt);
        return (error);
 }
                RTFREE(ro->ro_rt);
        return (error);
 }
index 390b1fa..370acef 100644 (file)
@@ -1,4 +1,4 @@
-/*     ip_var.h        4.9     83/02/23        */
+/*     ip_var.h        4.10    83/05/12        */
 
 /*
  * Overlay for ip header used by other protocols (tcp, udp).
 
 /*
  * Overlay for ip header used by other protocols (tcp, udp).
@@ -62,6 +62,11 @@ struct       ipstat {
 };
 
 #ifdef KERNEL
 };
 
 #ifdef KERNEL
+/* flags passed to ip_output as last parameter */
+#define        IP_FORWARDING           0x1     /* most of ip header exists */
+#define        IP_ROUTETOIF            0x10    /* same as SO_DONTROUTE */
+#define        IP_ALLOWBROADCAST       SS_PRIV /* can send broadcast packets */
+
 struct ipstat  ipstat;
 struct ipq     ipq;                    /* ip reass. queue */
 u_short        ip_id;                          /* ip packet ctr, for ids */
 struct ipstat  ipstat;
 struct ipq     ipq;                    /* ip reass. queue */
 u_short        ip_id;                          /* ip packet ctr, for ids */
index 24ed7a4..37bada5 100644 (file)
@@ -1,4 +1,4 @@
-/*     raw_ip.c        4.17    83/02/10        */
+/*     raw_ip.c        4.18    83/05/12        */
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
 
 #include "../h/param.h"
 #include "../h/mbuf.h"
@@ -86,7 +86,8 @@ rip_output(m0, so)
                ip->ip_src.s_addr = 0;
        ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
        ip->ip_ttl = MAXTTL;
                ip->ip_src.s_addr = 0;
        ip->ip_dst = ((struct sockaddr_in *)&rp->rcb_faddr)->sin_addr;
        ip->ip_ttl = MAXTTL;
-       return (ip_output(m, (struct mbuf *)0, &routetoif, 1));
+       return (ip_output(m, (struct mbuf *)0, (struct route *)0, 
+          IP_ROUTETOIF|IP_ALLOWBROADCAST));
 bad:
        m_freem(m);
        return (error);
 bad:
        m_freem(m);
        return (error);
index 1343117..96184d2 100644 (file)
@@ -1,4 +1,4 @@
-/*     tcp_output.c    4.52    83/03/25        */
+/*     tcp_output.c    4.53    83/05/12        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -46,6 +46,8 @@ tcp_output(tp)
        int sendalot;
 
 
        int sendalot;
 
 
+       if (tp->t_state == TCPS_CLOSED)
+               return (EINVAL);
        /*
         * Determine length of data that should be transmitted,
         * and flags that will be used.
        /*
         * Determine length of data that should be transmitted,
         * and flags that will be used.
@@ -293,8 +295,11 @@ noopt:
         */
        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + optlen + len;
        ((struct ip *)ti)->ip_ttl = TCP_TTL;
         */
        ((struct ip *)ti)->ip_len = sizeof (struct tcpiphdr) + optlen + len;
        ((struct ip *)ti)->ip_ttl = TCP_TTL;
-       if (error = ip_output(m, tp->t_ipopt, (so->so_options & SO_DONTROUTE) ?
-           &routetoif : &tp->t_inpcb->inp_route, 0))
+       if (so->so_options & SO_DONTROUTE)
+               error = ip_output(m, tp->t_ipopt, 0, IP_ROUTETOIF);
+       else
+               error = ip_output(m, tp->t_ipopt, &tp->t_inpcb->inp_route, 0);
+       if (error)
                return (error);
 
        /*
                return (error);
 
        /*
index d96d268..4e96d39 100644 (file)
@@ -1,4 +1,4 @@
-/*     udp_usrreq.c    4.46    83/05/03        */
+/*     udp_usrreq.c    4.47    83/05/12        */
 
 #include "../h/param.h"
 #include "../h/dir.h"
 
 #include "../h/param.h"
 #include "../h/dir.h"
@@ -159,6 +159,7 @@ udp_output(inp, m0)
        register struct udpiphdr *ui;
        register struct socket *so;
        register int len = 0;
        register struct udpiphdr *ui;
        register struct socket *so;
        register int len = 0;
+       int flags;
 
        /*
         * Calculate data length and get a mbuf
 
        /*
         * Calculate data length and get a mbuf
@@ -198,9 +199,8 @@ udp_output(inp, m0)
        ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
        ((struct ip *)ui)->ip_ttl = MAXTTL;
        so = inp->inp_socket;
        ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
        ((struct ip *)ui)->ip_ttl = MAXTTL;
        so = inp->inp_socket;
-       return (ip_output(m, (struct mbuf *)0,
-           (so->so_options & SO_DONTROUTE) ? &routetoif : (struct route *)0,
-           so->so_state & SS_PRIV));
+       flags = (so->so_options & SO_DONTROUTE) | (so->so_state & SS_PRIV);
+       return (ip_output(m, (struct mbuf *)0, (struct route *)0, flags));
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/