#include "sys/param.h" #include "sys/config.h" #include "sys/errno.h" #include "sys/types.h" #include "sys/systm.h" #include "net/misc.h" #include "net/mbuf.h" #include "net/in.h" #include "net/in_systm.h" #define M68000 #define bswap(x) (((((int)(x))>>8)&0xff)|((((int)(x))&0xff)<<8)) /* * Checksum routine for Internet Protocol family headers. * This routine is very heavily used in the network * code and should be rewritten for each CPU to be as fast as possible. * * billn: This shows the main outline for a prospective algorithm on * a prospective machine. I suppose one could try to outline * general guidelines for writing this routine, ie, if the machine * is byte-swapped, etc, etc. In practice, what one does is find * a machine which is known to conform to the "standard" and * beat on the code of the new machine till it works with the * known ok machine. */ /* int in_ckodd; /* number of calls on odd start add */ /* int in_ckprint = 0; /* print sums */ /* 68k */ union w { unsigned short wword; unsigned char wchar[2]; }; in_cksum(m, len) register struct mbuf *m; register short len; { register unsigned short *ptr; /* "unsigned" is important... */ register short mlen = 0; register long result = 0; register unsigned short r; register char * cptr; register unsigned short wasodd; register unsigned short thisodd; union w w; extern short tcpcksum; extern short ipcksum; /* if (in_ckprint) printf("ck m%o l%o",m,len); */ if (!tcpcksum) /* not checksumming? */ if (!ipcksum) return 0; wasodd = 0; for (;;) { /* * Each trip around loop adds in * words from one mbuf segment. */ thisodd = 0; ptr = mtod(m, unsigned short *); mlen = m->m_len; if (len < mlen) mlen = len; len -= mlen; if (mlen > 0) { if (wasodd) { /* "last mbuf odd" code... */ cptr = (char *)ptr; w.wchar[1] = *cptr++; result += w.wword; while (--mlen) { w.wchar[0] = *cptr++; mlen--; if (mlen) { w.wchar[1] = *cptr++; result += w.wword; } else /* note wasodd still set */ goto nextbuf; /* next mbuf */ } wasodd = 0; goto nextbuf; /* next mbuf */ } /* main line... check odd byte count */ if(mlen & 01) { thisodd++; mlen--; if (mlen == 0) goto lastbyte; } /* make wc a word count */ mlen >>= 1; /* * this is the main loop of the algorithm. */ mlen -= 1; do { result += *ptr++; } while(--mlen != -1); if (thisodd) { lastbyte: wasodd++; cptr = (char *) ptr; w.wchar[0] = *cptr++; } else wasodd = 0; } nextbuf: if (len <= 0) break; m = m->m_next; /* * Locate the next block with some data. */ for (;;) { if (m == 0) { printf("cksum: out of data\n"); goto done; } if (m->m_len) break; m = m->m_next; } } if (wasodd) { w.wchar[1] = 0; result += w.wword; } done: if (r = (result >> 16)) { result &= 0xffff; result += (unsigned)r; goto done; } /* if (in_ckprint) printf(" s%o\n",~result); */ return ((~((unsigned short)result)) & 0xffff); }