|
|
1.1 root 1: /*
2: * Copyright (c) 1988, 1990 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution is only permitted until one year after the first shipment
6: * of 4.4BSD by the Regents. Otherwise, redistribution and use in source and
7: * binary forms are permitted provided that: (1) source distributions retain
8: * this entire copyright notice and comment, and (2) distributions including
9: * binaries display the following acknowledgement: This product includes
10: * software developed by the University of California, Berkeley and its
11: * contributors'' in the documentation or other materials provided with the
12: * distribution and in all advertising materials mentioning features or use
13: * of this software. Neither the name of the University nor the names of
14: * its contributors may be used to endorse or promote products derived from
15: * this software without specific prior written permission.
16: * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
17: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
18: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19: *
20: * from: Utah $Hdr: in_cksum.c 1.6 89/08/24$
21: *
22: * @(#)in_cksum.c 7.1 (Berkeley) 5/8/90
23: */
24:
25: /*
26: * in_cksum - checksum routine for the Internet Protocol family.
27: */
28:
29: #include "param.h"
30: #include "mbuf.h"
31: #include "../netinet/in.h"
32: #include "../netinet/in_systm.h"
33:
34: extern int oc_cksum();
35:
36: /*
37: * Checksum routine for the Internet Protocol family.
38: *
39: * This isn't as bad as it looks. For ip headers the "while" isn't
40: * executed and we just drop through to the return statement at the
41: * end. For the usual tcp or udp packet (a single header mbuf
42: * chained onto a cluster of data, we make exactly one trip through
43: * the while (for the header mbuf) and never do the hairy code
44: * inside the "if". If fact, if m_copydata & sb_compact are doing
45: * their job, we should never do the hairy code inside the "if".
46: */
47: in_cksum(m, len)
48: register struct mbuf *m;
49: register int len;
50: {
51: register int sum = 0;
52: register int i;
53:
54: while (len > m->m_len) {
55: sum = oc_cksum(mtod(m, u_char *), i = m->m_len, sum);
56: m = m->m_next;
57: len -= i;
58: if (i & 1) {
59: /*
60: * ouch - we ended on an odd byte with more
61: * to do. This xfer is obviously not interested
62: * in performance so finish things slowly.
63: */
64: register u_char *cp;
65:
66: while (len > m->m_len) {
67: cp = mtod(m, u_char *);
68: if (i & 1) {
69: i = m->m_len - 1;
70: --len;
71: sum += *cp++;
72: } else
73: i = m->m_len;
74:
75: sum = oc_cksum(cp, i, sum);
76: m = m->m_next;
77: len -= i;
78: }
79: if (i & 1) {
80: cp = mtod(m, u_char *);
81: sum += *cp++;
82: return (0xffff & ~oc_cksum(cp, len - 1, sum));
83: }
84: }
85: }
86: return (0xffff & ~oc_cksum(mtod(m, u_char *), len, sum));
87: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.