date and time created 81/10/14 19:16:27 by wnj
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Thu, 15 Oct 1981 11:16:27 +0000 (03:16 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Thu, 15 Oct 1981 11:16:27 +0000 (03:16 -0800)
SCCS-vsn: sys/vax/vax/in_cksum.c 1.1

usr/src/sys/vax/vax/in_cksum.c [new file with mode: 0644]

diff --git a/usr/src/sys/vax/vax/in_cksum.c b/usr/src/sys/vax/vax/in_cksum.c
new file mode 100644 (file)
index 0000000..6976a0c
--- /dev/null
@@ -0,0 +1,147 @@
+/* in_cksum.c 1.1 81/10/14 */
+
+#include <sys/types.h>
+#include "../bbnnet/net.h"
+#include "../bbnnet/count.h"
+
+/*
+ * Network primitives; this file varies per-cpu,
+ * and the code here is for VAX only.
+ */
+cksum(m, len)
+register struct mbuf *m;
+{
+       int i,j;
+       i = ncksum(m, len);
+       j = ocksum(m, len);
+       if (i != j) {
+               printf("old %x new %x \n", i, j);
+               while (m != 0) {
+                       printf("m->m_off %d m->m_len %d\n", m->m_off, m->m_len);
+                       m = m->m_next;
+               }
+       }
+       return (j);
+}
+
+/*
+ * Checksum routine for TCP/IP headers.  This
+ * is very heavily used in the network
+ * code and should be rewritten for each CPU
+ * to be as fast as possible.
+ */
+ncksum(m, len)
+       register struct mbuf *m;
+       register int len;
+{
+       register u_short *w;            /* known to be r9 */
+       register int sum = 0;           /* known to be r8 */
+       register int mlen = 0;
+COUNT(NCKSUM);
+
+       for (;;) {
+               w = (u_short *)((int)m + m->m_off);
+               if (mlen == -1) {
+                       sum += *(u_char *)w << 8;
+                       w = (unsigned short *)((char *)w + 1);
+                       mlen = m->m_len - 1;
+                       len--;
+               } else
+                       mlen = m->m_len;
+               m = m->m_next;
+               if (len < mlen)
+                       mlen = len;
+               len -= mlen;
+               while ((mlen -= 32) >= 0) {
+#define ADD            asm("movzwl (r9)+,r0; addl2 r0,r8");
+                       ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD;
+                       ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD;
+               }
+               mlen += 32;
+               while ((mlen -= 8) >= 0) {
+                       ADD; ADD; ADD; ADD;
+               }
+               mlen += 8;
+               while ((mlen -= 2) >= 0) {
+                       ADD;
+               }
+               if (mlen == -1)
+                       sum += *(u_char *)w;
+               if (len == 0)
+                       break;
+               for (;;) {
+                       if (m == 0)
+                               panic("cksum: out of data");
+                       if (m->m_len)
+                               break;
+                       m = m->m_next;
+               }
+       }
+       return(~(sum + (sum >> 16)) & 0xffff);
+}
+
+/*
+ * These routines are implemented as inline expansions
+ * and are mentioned here for reference only
+ *
+ *     htons and ntohs         do byte reverse of a 16 bit integer
+ *     htonl and ntohl         do byte reverse of a 32 bit integer
+ */
+ocksum(m, len)
+register struct mbuf *m;
+register len;
+{
+       register unsigned short *w;
+       register unsigned long sum;
+       register mlen;
+COUNT(OCKSUM);
+
+       w = (unsigned short *)((int)m + m->m_off);
+       mlen = m->m_len;
+       sum = 0;
+
+       for (; len > 0; len -= 2, mlen -= 2) {
+
+try:            if (mlen > 1) {         /* can get a word */
+
+                       if (len > 1) {
+                               sum += *(w++);
+
+                       } else            /* trailing odd byte */
+
+                               sum += *((char *)w) & 0xff;
+
+               } else if (mlen > 0) {  /* last byte of mbuf */
+
+                       sum += *((char *)w) & 0xff;
+
+                       if (len > 1) {
+
+                               /* get next good mbuf for hi byte */
+        
+                               while ((m = m->m_next) != 0 && 
+                                       (mlen = m->m_len + 1) == 1);
+                               if (m != 0) {
+                                       w = (unsigned short *)((int)m + m->m_off);
+                                       sum += (*((char *)w) & 0xff) << 8;
+                                       w = (unsigned short *)((int)w + 1);
+                               } else
+                                       len = 0;        /* force loop exit */
+                       }
+
+               } else {                /* end of mbuf, get next and try again */
+
+                       while ((m = m->m_next) != 0 && (mlen = m->m_len) == 0);
+                       if (m != 0) {
+                               w = (unsigned short *)((int)m + m->m_off);
+                               goto try;
+                       } else
+                               break;
+               }
+       }
+
+       /* add in one's complement carry */
+
+       sum = (sum + (sum >> 16)) & 0xffff;
+       return(~sum & 0xffff);
+}