keep USETRAILERS from SIOCSARP
[unix-history] / usr / src / sys / netinet / ip_input.c
index 63674e9..5983463 100644 (file)
@@ -3,7 +3,7 @@
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
  * All rights reserved.  The Berkeley software License Agreement
  * specifies the terms and conditions for redistribution.
  *
- *     @(#)ip_input.c  7.1 (Berkeley) %G%
+ *     @(#)ip_input.c  7.6.1.2 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -300,7 +300,7 @@ ip_reass(ip, fp)
         * If first fragment to arrive, create a reassembly queue.
         */
        if (fp == 0) {
         * If first fragment to arrive, create a reassembly queue.
         */
        if (fp == 0) {
-               if ((t = m_get(M_WAIT, MT_FTABLE)) == NULL)
+               if ((t = m_get(M_DONTWAIT, MT_FTABLE)) == NULL)
                        goto dropfrag;
                fp = mtod(t, struct ipq *);
                insque(fp, &ipq);
                        goto dropfrag;
                fp = mtod(t, struct ipq *);
                insque(fp, &ipq);
@@ -488,6 +488,7 @@ ip_drain()
        }
 }
 
        }
 }
 
+extern struct in_ifaddr *ifptoia();
 struct in_ifaddr *ip_rtaddr();
 
 /*
 struct in_ifaddr *ip_rtaddr();
 
 /*
@@ -593,14 +594,14 @@ ip_dooptions(ip, ifp)
                        off--;                  /* 0 origin */
                        if (off > optlen - sizeof(struct in_addr))
                                break;
                        off--;                  /* 0 origin */
                        if (off > optlen - sizeof(struct in_addr))
                                break;
-                       bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
+                       bcopy((caddr_t)(&ip->ip_dst), (caddr_t)&ipaddr.sin_addr,
                            sizeof(ipaddr.sin_addr));
                        /*
                         * locate outgoing interface
                         */
                        if ((ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
                                type = ICMP_UNREACH;
                            sizeof(ipaddr.sin_addr));
                        /*
                         * locate outgoing interface
                         */
                        if ((ia = ip_rtaddr(ipaddr.sin_addr)) == 0) {
                                type = ICMP_UNREACH;
-                               code = ICMP_UNREACH_SRCFAIL;
+                               code = ICMP_UNREACH_HOST;
                                goto bad;
                        }
                        bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
                                goto bad;
                        }
                        bcopy((caddr_t)&(IA_SIN(ia)->sin_addr),
@@ -618,7 +619,7 @@ ip_dooptions(ip, ifp)
                                        goto bad;
                                break;
                        }
                                        goto bad;
                                break;
                        }
-                       sin = (struct in_addr *)(cp+cp[IPOPT_OFFSET]-1);
+                       sin = (struct in_addr *)(cp + ipt->ipt_ptr - 1);
                        switch (ipt->ipt_flg) {
 
                        case IPOPT_TS_TSONLY:
                        switch (ipt->ipt_flg) {
 
                        case IPOPT_TS_TSONLY:
@@ -628,21 +629,20 @@ ip_dooptions(ip, ifp)
                                if (ipt->ipt_ptr + sizeof(n_time) +
                                    sizeof(struct in_addr) > ipt->ipt_len)
                                        goto bad;
                                if (ipt->ipt_ptr + sizeof(n_time) +
                                    sizeof(struct in_addr) > ipt->ipt_len)
                                        goto bad;
-                               if (in_ifaddr == 0)
-                                       goto bad;       /* ??? */
-                               bcopy((caddr_t)&IA_SIN(in_ifaddr)->sin_addr,
+                               ia = ifptoia(ifp);
+                               bcopy((caddr_t)&IA_SIN(ia)->sin_addr,
                                    (caddr_t)sin, sizeof(struct in_addr));
                                    (caddr_t)sin, sizeof(struct in_addr));
-                               sin++;
+                               ipt->ipt_ptr += sizeof(struct in_addr);
                                break;
 
                        case IPOPT_TS_PRESPEC:
                                break;
 
                        case IPOPT_TS_PRESPEC:
+                               if (ipt->ipt_ptr + sizeof(n_time) +
+                                   sizeof(struct in_addr) > ipt->ipt_len)
+                                       goto bad;
                                bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
                                    sizeof(struct in_addr));
                                if (ifa_ifwithaddr((struct sockaddr *)&ipaddr) == 0)
                                        continue;
                                bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
                                    sizeof(struct in_addr));
                                if (ifa_ifwithaddr((struct sockaddr *)&ipaddr) == 0)
                                        continue;
-                               if (ipt->ipt_ptr + sizeof(n_time) +
-                                   sizeof(struct in_addr) > ipt->ipt_len)
-                                       goto bad;
                                ipt->ipt_ptr += sizeof(struct in_addr);
                                break;
 
                                ipt->ipt_ptr += sizeof(struct in_addr);
                                break;
 
@@ -650,7 +650,8 @@ ip_dooptions(ip, ifp)
                                goto bad;
                        }
                        ntime = iptime();
                                goto bad;
                        }
                        ntime = iptime();
-                       bcopy((caddr_t)&ntime, (caddr_t)sin, sizeof(n_time));
+                       bcopy((caddr_t)&ntime, (caddr_t)cp + ipt->ipt_ptr - 1,
+                           sizeof(n_time));
                        ipt->ipt_ptr += sizeof(n_time);
                }
        }
                        ipt->ipt_ptr += sizeof(n_time);
                }
        }
@@ -729,7 +730,9 @@ ip_srcroute()
 
        if (ip_nhops == 0)
                return ((struct mbuf *)0);
 
        if (ip_nhops == 0)
                return ((struct mbuf *)0);
-       m = m_get(M_WAIT, MT_SOOPTS);
+       m = m_get(M_DONTWAIT, MT_SOOPTS);
+       if (m == 0)
+               return ((struct mbuf *)0);
        m->m_len = ip_nhops * sizeof(struct in_addr) + IPOPT_OFFSET + 1 + 1;
 
        /*
        m->m_len = ip_nhops * sizeof(struct in_addr) + IPOPT_OFFSET + 1 + 1;
 
        /*
@@ -839,7 +842,7 @@ ip_forward(ip, ifp)
                return;
 #endif
        }
                return;
 #endif
        }
-       if (ip->ip_ttl < IPTTLDEC) {
+       if (ip->ip_ttl <= IPTTLDEC) {
                type = ICMP_TIMXCEED, code = ICMP_TIMXCEED_INTRANS;
                goto sendicmp;
        }
                type = ICMP_TIMXCEED, code = ICMP_TIMXCEED_INTRANS;
                goto sendicmp;
        }
@@ -868,11 +871,15 @@ ip_forward(ip, ifp)
         * perhaps should send a redirect to sender to shortcut a hop.
         * Only send redirect if source is sending directly to us,
         * and if packet was not source routed (or has any options).
         * perhaps should send a redirect to sender to shortcut a hop.
         * Only send redirect if source is sending directly to us,
         * and if packet was not source routed (or has any options).
+        * Also, don't send redirect if forwarding using a default route
+        * or a route modfied by a redirect.
         */
         */
+#define        satosin(sa)     ((struct sockaddr_in *)(sa))
        if (ipforward_rt.ro_rt && ipforward_rt.ro_rt->rt_ifp == ifp &&
        if (ipforward_rt.ro_rt && ipforward_rt.ro_rt->rt_ifp == ifp &&
+           (ipforward_rt.ro_rt->rt_flags & RTF_DYNAMIC) == 0 &&
+           satosin(&ipforward_rt.ro_rt->rt_dst)->sin_addr.s_addr != 0 &&
            ipsendredirects && ip->ip_hl == (sizeof(struct ip) >> 2)) {
                struct in_ifaddr *ia;
            ipsendredirects && ip->ip_hl == (sizeof(struct ip) >> 2)) {
                struct in_ifaddr *ia;
-               extern struct in_ifaddr *ifptoia();
                u_long src = ntohl(ip->ip_src.s_addr);
                u_long dst = ntohl(ip->ip_dst.s_addr);
 
                u_long src = ntohl(ip->ip_src.s_addr);
                u_long dst = ntohl(ip->ip_dst.s_addr);