This source file includes following definitions.
- in6_cksum
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 #include <sys/param.h>
65 #include <sys/mbuf.h>
66 #include <sys/systm.h>
67 #include <netinet/in.h>
68 #include <netinet/ip6.h>
69
70
71
72
73
74
75
76
77 #define ADDCARRY(x) (x > 65535 ? x -= 65535 : x)
78 #define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
79
80
81
82
83
84
85
86
87 int
88 in6_cksum(m, nxt, off, len)
89 struct mbuf *m;
90 u_int8_t nxt;
91 u_int32_t off, len;
92 {
93 u_int16_t *w;
94 int sum = 0;
95 int mlen = 0;
96 int byte_swapped = 0;
97 struct ip6_hdr *ip6;
98 union {
99 u_int16_t phs[4];
100 struct {
101 u_int32_t ph_len;
102 u_int8_t ph_zero[3];
103 u_int8_t ph_nxt;
104 } ph __packed;
105 } uph;
106 union {
107 u_int8_t c[2];
108 u_int16_t s;
109 } s_util;
110 union {
111 u_int16_t s[2];
112 u_int32_t l;
113 } l_util;
114
115
116 if (m->m_pkthdr.len < off + len) {
117 panic("in6_cksum: mbuf len (%d) < off+len (%d+%d)",
118 m->m_pkthdr.len, off, len);
119 }
120
121 bzero(&uph, sizeof(uph));
122
123
124
125
126 ip6 = mtod(m, struct ip6_hdr *);
127 w = (u_int16_t *)&ip6->ip6_src;
128 uph.ph.ph_len = htonl(len);
129 uph.ph.ph_nxt = nxt;
130
131
132 sum += w[0];
133 if (!IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
134 sum += w[1];
135 sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5];
136 sum += w[6]; sum += w[7];
137
138 sum += w[8];
139 if (!IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
140 sum += w[9];
141 sum += w[10]; sum += w[11]; sum += w[12]; sum += w[13];
142 sum += w[14]; sum += w[15];
143
144 sum += uph.phs[0]; sum += uph.phs[1];
145 sum += uph.phs[2]; sum += uph.phs[3];
146
147
148
149
150 while (m != NULL && off > 0) {
151 if (m->m_len <= off)
152 off -= m->m_len;
153 else
154 break;
155 m = m->m_next;
156 }
157 w = (u_int16_t *)(mtod(m, u_char *) + off);
158 mlen = m->m_len - off;
159 if (len < mlen)
160 mlen = len;
161 len -= mlen;
162
163
164
165 if ((1 & (long) w) && (mlen > 0)) {
166 REDUCE;
167 sum <<= 8;
168 s_util.c[0] = *(u_char *)w;
169 w = (u_int16_t *)((char *)w + 1);
170 mlen--;
171 byte_swapped = 1;
172 }
173
174
175
176
177 while ((mlen -= 32) >= 0) {
178 sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
179 sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
180 sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
181 sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
182 w += 16;
183 }
184 mlen += 32;
185 while ((mlen -= 8) >= 0) {
186 sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
187 w += 4;
188 }
189 mlen += 8;
190 if (mlen == 0 && byte_swapped == 0)
191 goto next;
192 REDUCE;
193 while ((mlen -= 2) >= 0) {
194 sum += *w++;
195 }
196 if (byte_swapped) {
197 REDUCE;
198 sum <<= 8;
199 byte_swapped = 0;
200 if (mlen == -1) {
201 s_util.c[1] = *(char *)w;
202 sum += s_util.s;
203 mlen = 0;
204 } else
205 mlen = -1;
206 } else if (mlen == -1)
207 s_util.c[0] = *(char *)w;
208 next:
209 m = m->m_next;
210
211
212
213
214
215 for (;m && len; m = m->m_next) {
216 if (m->m_len == 0)
217 continue;
218 w = mtod(m, u_int16_t *);
219 if (mlen == -1) {
220
221
222
223
224
225
226
227
228 s_util.c[1] = *(char *)w;
229 sum += s_util.s;
230 w = (u_int16_t *)((char *)w + 1);
231 mlen = m->m_len - 1;
232 len--;
233 } else
234 mlen = m->m_len;
235 if (len < mlen)
236 mlen = len;
237 len -= mlen;
238
239
240
241 if ((1 & (long) w) && (mlen > 0)) {
242 REDUCE;
243 sum <<= 8;
244 s_util.c[0] = *(u_char *)w;
245 w = (u_int16_t *)((char *)w + 1);
246 mlen--;
247 byte_swapped = 1;
248 }
249
250
251
252
253 while ((mlen -= 32) >= 0) {
254 sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
255 sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
256 sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
257 sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
258 w += 16;
259 }
260 mlen += 32;
261 while ((mlen -= 8) >= 0) {
262 sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
263 w += 4;
264 }
265 mlen += 8;
266 if (mlen == 0 && byte_swapped == 0)
267 continue;
268 REDUCE;
269 while ((mlen -= 2) >= 0) {
270 sum += *w++;
271 }
272 if (byte_swapped) {
273 REDUCE;
274 sum <<= 8;
275 byte_swapped = 0;
276 if (mlen == -1) {
277 s_util.c[1] = *(char *)w;
278 sum += s_util.s;
279 mlen = 0;
280 } else
281 mlen = -1;
282 } else if (mlen == -1)
283 s_util.c[0] = *(char *)w;
284 }
285 if (len)
286 panic("in6_cksum: out of data");
287 if (mlen == -1) {
288
289
290
291 s_util.c[1] = 0;
292 sum += s_util.s;
293 }
294 REDUCE;
295 return (~sum & 0xffff);
296 }