more lint
[unix-history] / usr / src / sys / netinet / ip_input.c
index 445b075..8f10e58 100644 (file)
@@ -1,19 +1,44 @@
-/* ip_input.c 1.10 81/10/31 */
+/* ip_input.c 1.14 81/11/16 */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/clock.h"
 #include "../h/mbuf.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../h/clock.h"
 #include "../h/mbuf.h"
-#include "../inet/cksum.h"
-#include "../inet/inet.h"
-#include "../inet/inet_systm.h"
-#include "../inet/imp.h"
-#include "../inet/ip.h"                        /* belongs before inet.h */
-#include "../inet/ip_icmp.h"
-#include "../inet/tcp.h"
+#include "../h/protocol.h"
+#include "../h/protosw.h"
+#include "../net/inet_cksum.h"
+#include "../net/inet.h"
+#include "../net/inet_systm.h"
+#include "../net/imp.h"
+#include "../net/ip.h"                 /* belongs before inet.h */
+#include "../net/ip_var.h"
+#include "../net/ip_icmp.h"
+#include "../net/tcp.h"
+
+u_char ip_protox[IPPROTO_MAX];
 
 
-int    nosum = 0;
+/*
+ * Ip initialization.
+ */
+ip_init()
+{
+       register struct protosw *pr;
+       register int i;
 
 
+       pr = pffindproto(PF_INET, IPPROTO_RAW);
+       if (pr == 0)
+               panic("ip_init");
+       for (i = 0; i < IPPROTO_MAX; i++)
+               ip_protox[i] = pr - protosw;
+       for (pr = protosw; pr <= protoswLAST; pr++)
+               if (pr->pr_family == PF_INET &&
+                   pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
+                       ip_protox[pr->pr_protocol] = pr - protosw;
+       ipq.next = ipq.prev = &ipq;
+       ip_id = time & 0xffff;
+}
+
+u_char ipcksum = 1;
 struct ip *ip_reass();
 
 /*
 struct ip *ip_reass();
 
 /*
@@ -31,7 +56,6 @@ ip_input(m0)
        register struct ip *ip;         /* known to be r11 in CKSUM below */
        register struct mbuf *m = m0;
        register int i;
        register struct ip *ip;         /* known to be r11 in CKSUM below */
        register struct mbuf *m = m0;
        register int i;
-       register struct ipq *q;
        register struct ipq *fp;
        int hlen;
 
        register struct ipq *fp;
        int hlen;
 
@@ -49,12 +73,12 @@ COUNT(IP_INPUT);
        if (ip->ip_sum) {
                printf("ip_sum %x\n", ip->ip_sum);
                netstat.ip_badsum++;
        if (ip->ip_sum) {
                printf("ip_sum %x\n", ip->ip_sum);
                netstat.ip_badsum++;
-               if (!nosum) {
+               if (ipcksum) {
                        m_freem(m);
                        return;
                }
        }
                        m_freem(m);
                        return;
                }
        }
-       ip->ip_len = ntohs(ip->ip_len);
+       ip->ip_len = ntohs((u_short)ip->ip_len);
        ip->ip_id = ntohs(ip->ip_id);
        ip->ip_off = ntohs(ip->ip_off);
 
        ip->ip_id = ntohs(ip->ip_id);
        ip->ip_off = ntohs(ip->ip_off);
 
@@ -82,10 +106,10 @@ COUNT(IP_INPUT);
         * ship it on.
         */
        if (hlen > sizeof (struct ip))
         * ship it on.
         */
        if (hlen > sizeof (struct ip))
-               ip_dooptions(ip, hlen);
+               ip_dooptions(ip);
        if (ip->ip_dst.s_addr != n_lhost.s_addr) {
                if (--ip->ip_ttl == 0) {
        if (ip->ip_dst.s_addr != n_lhost.s_addr) {
                if (--ip->ip_ttl == 0) {
-                       icmp_error(ip, ICMP_TIMXCEED);
+                       icmp_error(ip, ICMP_TIMXCEED, 0);
                        return;
                }
                ip_output(dtom(ip));
                        return;
                }
                ip_output(dtom(ip));
@@ -111,9 +135,9 @@ found:
         * convert offset of this to bytes.
         */
        ip->ip_len -= hlen;
         * convert offset of this to bytes.
         */
        ip->ip_len -= hlen;
-       ip->ip_mff = 0;
+       ((struct ipasfrag *)ip)->ipf_mff = 0;
        if (ip->ip_off & IP_MF)
        if (ip->ip_off & IP_MF)
-               ip->ip_mff = 1;
+               ((struct ipasfrag *)ip)->ipf_mff = 1;
        ip->ip_off <<= 3;
 
        /*
        ip->ip_off <<= 3;
 
        /*
@@ -121,8 +145,8 @@ found:
         * or if this is not the first fragment,
         * attempt reassembly; if it succeeds, proceed.
         */
         * or if this is not the first fragment,
         * attempt reassembly; if it succeeds, proceed.
         */
-       if (ip->ip_mff || ip->ip_off) {
-               ip = ip_reass(ip, fp);
+       if (((struct ipasfrag *)ip)->ipf_mff || ip->ip_off) {
+               ip = ip_reass((struct ipasfrag *)ip, fp);
                if (ip == 0)
                        return;
                hlen = ip->ip_hl << 2;
                if (ip == 0)
                        return;
                hlen = ip->ip_hl << 2;
@@ -130,33 +154,7 @@ found:
        } else
                if (fp)
                        (void) ip_freef(fp);
        } else
                if (fp)
                        (void) ip_freef(fp);
-
-       /*
-        * Switch out to protocol specific routine.
-        * SHOULD GO THROUGH PROTOCOL SWITCH TABLE
-        */
-       switch (ip->ip_p) {
-
-       case IPPROTO_ICMP:
-               icmp_input(m);
-               break;
-
-       case IPPROTO_TCP:
-               if (hlen > sizeof (struct ip))
-                       ip_stripoptions(ip, hlen);
-               tcp_input(m);
-               break;
-
-       case IPPROTO_UDP:
-               if (hlen > sizeof (struct ip))
-                       ip_stripoptions(ip, hlen);
-               udp_input(m);
-               break;
-
-       default:
-               raw_input(m);
-               break;
-       }
+       (*protosw[ip_protox[ip->ip_p]].pr_input)(m);
 }
 
 /*
 }
 
 /*
@@ -167,11 +165,11 @@ found:
  */
 struct ip *
 ip_reass(ip, fp)
  */
 struct ip *
 ip_reass(ip, fp)
-       register struct ip *ip;
+       register struct ipasfrag *ip;
        register struct ipq *fp;
 {
        register struct mbuf *m = dtom(ip);
        register struct ipq *fp;
 {
        register struct mbuf *m = dtom(ip);
-       register struct ip *q;
+       register struct ipasfrag *q;
        struct mbuf *t;
        int hlen = ip->ip_hl << 2;
        int i, next;
        struct mbuf *t;
        int hlen = ip->ip_hl << 2;
        int i, next;
@@ -195,15 +193,15 @@ ip_reass(ip, fp)
                fp->ipq_ttl = IPFRAGTTL;
                fp->ipq_p = ip->ip_p;
                fp->ipq_id = ip->ip_id;
                fp->ipq_ttl = IPFRAGTTL;
                fp->ipq_p = ip->ip_p;
                fp->ipq_id = ip->ip_id;
-               fp->ipq_next = fp->ipq_prev = (struct ip *)fp;
-               fp->ipq_src = ip->ip_src;
-               fp->ipq_dst = ip->ip_dst;
+               fp->ipq_next = fp->ipq_prev = (struct ipasfrag *)fp;
+               fp->ipq_src = ((struct ip *)ip)->ip_src;
+               fp->ipq_dst = ((struct ip *)ip)->ip_dst;
        }
 
        /*
         * Find a segment which begins after this one does.
         */
        }
 
        /*
         * Find a segment which begins after this one does.
         */
-       for (q = fp->ipq_next; q != (struct ip *)fp; q = q->ip_next)
+       for (q = fp->ipq_next; q != (struct ipasfrag *)fp; q = q->ipf_next)
                if (q->ip_off > ip->ip_off)
                        break;
 
                if (q->ip_off > ip->ip_off)
                        break;
 
@@ -212,8 +210,8 @@ ip_reass(ip, fp)
         * our data already.  If so, drop the data from the incoming
         * segment.  If it provides all of our data, drop us.
         */
         * our data already.  If so, drop the data from the incoming
         * segment.  If it provides all of our data, drop us.
         */
-       if (q->ip_prev != (struct ip *)fp) {
-               i = q->ip_prev->ip_off + q->ip_prev->ip_len - ip->ip_off;
+       if (q->ipf_prev != (struct ipasfrag *)fp) {
+               i = q->ipf_prev->ip_off + q->ipf_prev->ip_len - ip->ip_off;
                if (i > 0) {
                        if (i >= ip->ip_len)
                                goto dropfrag;
                if (i > 0) {
                        if (i >= ip->ip_len)
                                goto dropfrag;
@@ -227,30 +225,30 @@ ip_reass(ip, fp)
         * While we overlap succeeding segments trim them or,
         * if they are completely covered, dequeue them.
         */
         * While we overlap succeeding segments trim them or,
         * if they are completely covered, dequeue them.
         */
-       while (q != (struct ip *)fp && ip->ip_off + ip->ip_len > q->ip_off) {
+       while (q != (struct ipasfrag *)fp && ip->ip_off + ip->ip_len > q->ip_off) {
                i = (ip->ip_off + ip->ip_len) - q->ip_off;
                if (i < q->ip_len) {
                        q->ip_len -= i;
                        m_adj(dtom(q), i);
                        break;
                }
                i = (ip->ip_off + ip->ip_len) - q->ip_off;
                if (i < q->ip_len) {
                        q->ip_len -= i;
                        m_adj(dtom(q), i);
                        break;
                }
-               q = q->ip_next;
-               m_freem(dtom(q->ip_prev));
-               ip_deq(q->ip_prev);
+               q = q->ipf_next;
+               m_freem(dtom(q->ipf_prev));
+               ip_deq(q->ipf_prev);
        }
 
        /*
         * Stick new segment in its place;
         * check for complete reassembly.
         */
        }
 
        /*
         * Stick new segment in its place;
         * check for complete reassembly.
         */
-       ip_enq(ip, q->ip_prev);
+       ip_enq(ip, q->ipf_prev);
        next = 0;
        next = 0;
-       for (q = fp->ipq_next; q != (struct ip *)fp; q = q->ip_next) {
+       for (q = fp->ipq_next; q != (struct ipasfrag *)fp; q = q->ipf_next) {
                if (q->ip_off != next)
                        return (0);
                next += q->ip_len;
        }
                if (q->ip_off != next)
                        return (0);
                next += q->ip_len;
        }
-       if (q->ip_prev->ip_mff)
+       if (q->ipf_prev->ipf_mff)
                return (0);
 
        /*
                return (0);
 
        /*
@@ -261,7 +259,7 @@ ip_reass(ip, fp)
        t = m->m_next;
        m->m_next = 0;
        m_cat(m, t);
        t = m->m_next;
        m->m_next = 0;
        m_cat(m, t);
-       while ((q = q->ip_next) != (struct ip *)fp)
+       while ((q = q->ipf_next) != (struct ipasfrag *)fp)
                m_cat(m, dtom(q));
 
        /*
                m_cat(m, dtom(q));
 
        /*
@@ -272,14 +270,14 @@ ip_reass(ip, fp)
         */
        ip = fp->ipq_next;
        ip->ip_len = next;
         */
        ip = fp->ipq_next;
        ip->ip_len = next;
-       ip->ip_src = fp->ipq_src;
-       ip->ip_dst = fp->ipq_dst;
+       ((struct ip *)ip)->ip_src = fp->ipq_src;
+       ((struct ip *)ip)->ip_dst = fp->ipq_dst;
        remque(fp);
        remque(fp);
-       m_free(dtom(fp));
+       (void) m_free(dtom(fp));
        m = dtom(ip);
        m = dtom(ip);
-       m->m_len += sizeof (struct ip);
-       m->m_off -= sizeof (struct ip);
-       return (ip);
+       m->m_len += sizeof (struct ipasfrag);
+       m->m_off -= sizeof (struct ipasfrag);
+       return ((struct ip *)ip);
 
 dropfrag:
        m_freem(m);
 
 dropfrag:
        m_freem(m);
@@ -294,15 +292,15 @@ struct ipq *
 ip_freef(fp)
        struct ipq *fp;
 {
 ip_freef(fp)
        struct ipq *fp;
 {
-       register struct ip *q;
+       register struct ipasfrag *q;
        struct mbuf *m;
 
        struct mbuf *m;
 
-       for (q = fp->ipq_next; q != (struct ip *)fp; q = q->ip_next)
+       for (q = fp->ipq_next; q != (struct ipasfrag *)fp; q = q->ipf_next)
                m_freem(dtom(q));
        m = dtom(fp);
        fp = fp->next;
        remque(fp->prev);
                m_freem(dtom(q));
        m = dtom(fp);
        fp = fp->next;
        remque(fp->prev);
-       m_free(m);
+       (void) m_free(m);
        return (fp);
 }
 
        return (fp);
 }
 
@@ -311,27 +309,26 @@ ip_freef(fp)
  * Like insque, but pointers in middle of structure.
  */
 ip_enq(p, prev)
  * Like insque, but pointers in middle of structure.
  */
 ip_enq(p, prev)
-       register struct ip *p;
-       register struct ip *prev;
+       register struct ipasfrag *p, *prev;
 {
 COUNT(IP_ENQ);
 
 {
 COUNT(IP_ENQ);
 
-       p->ip_prev = prev;
-       p->ip_next = prev->ip_next;
-       prev->ip_next->ip_prev = p;
-       prev->ip_next = p;
+       p->ipf_prev = prev;
+       p->ipf_next = prev->ipf_next;
+       prev->ipf_next->ipf_prev = p;
+       prev->ipf_next = p;
 }
 
 /*
  * To ip_enq as remque is to insque.
  */
 ip_deq(p)
 }
 
 /*
  * To ip_enq as remque is to insque.
  */
 ip_deq(p)
-       register struct ip *p;
+       register struct ipasfrag *p;
 {
 COUNT(IP_DEQ);
 
 {
 COUNT(IP_DEQ);
 
-       p->ip_prev->ip_next = p->ip_next;
-       p->ip_next->ip_prev = p->ip_prev;
+       p->ipf_prev->ipf_next = p->ipf_next;
+       p->ipf_next->ipf_prev = p->ipf_prev;
 }
 
 /*
 }
 
 /*
@@ -339,22 +336,24 @@ COUNT(IP_DEQ);
  * if a timer expires on a reassembly
  * queue, discard it.
  */
  * if a timer expires on a reassembly
  * queue, discard it.
  */
-ip_timeo()
+ip_slowtimo()
 {
 {
-       register struct ip *q;
        register struct ipq *fp;
        int s = splnet();
        register struct ipq *fp;
        int s = splnet();
-COUNT(IP_TIMEO);
+COUNT(IP_SLOWTIMO);
 
        for (fp = ipq.next; fp != &ipq; )
                if (--fp->ipq_ttl == 0)
                        fp = ip_freef(fp);
                else
                        fp = fp->next;
 
        for (fp = ipq.next; fp != &ipq; )
                if (--fp->ipq_ttl == 0)
                        fp = ip_freef(fp);
                else
                        fp = fp->next;
-       timeout(ip_timeo, 0, hz);
        splx(s);
 }
 
        splx(s);
 }
 
+ip_drain()
+{
+
+}
 /*
  * Do option processing on a datagram,
  * possibly discarding it if bad options
 /*
  * Do option processing on a datagram,
  * possibly discarding it if bad options
@@ -364,8 +363,9 @@ ip_dooptions(ip)
        struct ip *ip;
 {
        register u_char *cp;
        struct ip *ip;
 {
        register u_char *cp;
-       int opt, optlen, cnt, s;
-       struct socket *sp;
+       int opt, optlen, cnt;
+       struct ip_addr *sp;
+       register struct ip_timestamp *ipt;
 
        cp = (u_char *)(ip + 1);
        cnt = (ip->ip_hl << 2) - sizeof (struct ip);
 
        cp = (u_char *)(ip + 1);
        cnt = (ip->ip_hl << 2) - sizeof (struct ip);
@@ -384,12 +384,12 @@ ip_dooptions(ip)
 
                case IPOPT_LSRR:
                case IPOPT_SSRR:
 
                case IPOPT_LSRR:
                case IPOPT_SSRR:
-                       if (cp[2] < 4 || cp[2] > optlen - 3)
+                       if (cp[2] < 4 || cp[2] > optlen - (sizeof (long) - 1))
                                break;
                                break;
-                       sp = (struct socket *)(cp+cp[2]);
+                       sp = (struct ip_addr *)(cp + cp[2]);
                        if (n_lhost.s_addr == *(u_long *)sp) {
                                if (opt == IPOPT_SSRR) {
                        if (n_lhost.s_addr == *(u_long *)sp) {
                                if (opt == IPOPT_SSRR) {
-                                       /* make sure *sp directly accessible*/
+                                       /* MAKE SURE *SP DIRECTLY ACCESSIBLE */
                                }
                                ip->ip_dst = *sp;
                                *sp = n_lhost;
                                }
                                ip->ip_dst = *sp;
                                *sp = n_lhost;
@@ -398,46 +398,45 @@ ip_dooptions(ip)
                        break;
 
                case IPOPT_TS:
                        break;
 
                case IPOPT_TS:
-                       if (cp[2] < 5)
+                       ipt = (struct ip_timestamp *)cp;
+                       if (ipt->ipt_len < 5)
                                goto bad;
                                goto bad;
-                       if (cp[2] > cp[1] - 3) {
-                               if ((cp[3] & 0xf0) == 0xf0)
+                       if (ipt->ipt_ptr > ipt->ipt_len - sizeof (long)) {
+                               if (++ipt->ipt_oflw == 0)
                                        goto bad;
                                        goto bad;
-                               cp[3] += 0x10;
                                break;
                        }
                                break;
                        }
-                       sp = (struct socket *)(cp+cp[2]);
-                       switch (cp[3] & 0xf) {
+                       sp = (struct ip_addr *)(cp+cp[2]);
+                       switch (ipt->ipt_flg) {
 
                        case IPOPT_TS_TSONLY:
                                break;
 
                        case IPOPT_TS_TSANDADDR:
 
                        case IPOPT_TS_TSONLY:
                                break;
 
                        case IPOPT_TS_TSANDADDR:
-                               if (cp[2] > cp[1] - 7)
+                               if (ipt->ipt_ptr + 8 > ipt->ipt_len)
                                        goto bad;
                                        goto bad;
+                               *(struct ip_addr *)sp++ = n_lhost;
                                break;
 
                        case IPOPT_TS_PRESPEC:
                                if (*(u_long *)sp != n_lhost.s_addr)
                                        break;
                                break;
 
                        case IPOPT_TS_PRESPEC:
                                if (*(u_long *)sp != n_lhost.s_addr)
                                        break;
-                               if (cp[2] > cp[1] - 7)
+                               if (ipt->ipt_ptr + 8 > ipt->ipt_len)
                                        goto bad;
                                        goto bad;
-                               cp[1] += 4;
+                               ipt->ipt_ptr += 4;
                                break;
 
                        default:
                                goto bad;
                        }
                                break;
 
                        default:
                                goto bad;
                        }
-                       s = spl6();
-                       *(int *)sp = (time % SECDAY) * 1000 + (lbolt*1000/hz);
-                       splx(s);
-                       cp[1] += 4;
+                       *(n_time *)sp = ip_time();
+                       ipt->ipt_ptr += 4;
                }
        }
                }
        }
-       return (0);
+       return;
 bad:
        /* SHOULD FORCE ICMP MESSAGE */
 bad:
        /* SHOULD FORCE ICMP MESSAGE */
-       return (-1);
+       return;
 }
 
 /*
 }
 
 /*
@@ -449,43 +448,12 @@ ip_stripoptions(ip)
 {
        register int i;
        register struct mbuf *m;
 {
        register int i;
        register struct mbuf *m;
-       char *op;
        int olen;
 COUNT(IP_OPT);
 
        olen = (ip->ip_hl<<2) - sizeof (struct ip);
        int olen;
 COUNT(IP_OPT);
 
        olen = (ip->ip_hl<<2) - sizeof (struct ip);
-       op = (caddr_t)ip + olen;
        m = dtom(++ip);
        i = m->m_len - (sizeof (struct ip) + olen);
        m = dtom(++ip);
        i = m->m_len - (sizeof (struct ip) + olen);
-       bcopy((caddr_t)ip+olen, (caddr_t)ip, i);
+       bcopy((caddr_t)ip+olen, (caddr_t)ip, (unsigned)i);
        m->m_len -= i;
 }
        m->m_len -= i;
 }
-
-/* stubs */
-
-icmp_error(ip, error)
-{
-
-       m_freem(dtom(ip));
-}
-
-icmp_input(m)
-       struct mbuf *m;
-{
-
-       printf("icmp_input %x\n", m);
-}
-
-udp_input(m)
-       struct mbuf *m;
-{
-
-       printf("udp_input %x\n", m);
-}
-
-raw_input(m)
-       struct mbuf *m;
-{
-
-       printf("raw_input %x\n", m);
-}