1 |
/* |
/* |
2 |
* Copyright (c) 2001-2003 Swedish Institute of Computer Science. |
* Copyright (c) 2001-2003 Swedish Institute of Computer Science. |
3 |
* All rights reserved. |
* All rights reserved. |
4 |
* |
* |
5 |
* Redistribution and use in source and binary forms, with or without modification, |
* Redistribution and use in source and binary forms, with or without modification, |
6 |
* are permitted provided that the following conditions are met: |
* are permitted provided that the following conditions are met: |
7 |
* |
* |
8 |
* 1. Redistributions of source code must retain the above copyright notice, |
* 1. Redistributions of source code must retain the above copyright notice, |
11 |
* this list of conditions and the following disclaimer in the documentation |
* this list of conditions and the following disclaimer in the documentation |
12 |
* and/or other materials provided with the distribution. |
* and/or other materials provided with the distribution. |
13 |
* 3. The name of the author may not be used to endorse or promote products |
* 3. The name of the author may not be used to endorse or promote products |
14 |
* derived from this software without specific prior written permission. |
* derived from this software without specific prior written permission. |
15 |
* |
* |
16 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
17 |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
18 |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT |
19 |
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
20 |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT |
21 |
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
24 |
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY |
25 |
* OF SUCH DAMAGE. |
* OF SUCH DAMAGE. |
26 |
* |
* |
27 |
* This file is part of the lwIP TCP/IP stack. |
* This file is part of the lwIP TCP/IP stack. |
28 |
* |
* |
29 |
* Author: Adam Dunkels <adam@sics.se> |
* Author: Adam Dunkels <adam@sics.se> |
30 |
* |
* |
31 |
*/ |
*/ |
52 |
lwip_chksum(void *dataptr, int len) |
lwip_chksum(void *dataptr, int len) |
53 |
{ |
{ |
54 |
u32_t acc; |
u32_t acc; |
55 |
|
|
56 |
LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", dataptr, len)); |
LWIP_DEBUGF(INET_DEBUG, ("lwip_chksum(%p, %d)\n", (void *)dataptr, len)); |
57 |
for(acc = 0; len > 1; len -= 2) { |
for(acc = 0; len > 1; len -= 2) { |
58 |
/* acc = acc + *((u16_t *)dataptr)++;*/ |
/* acc = acc + *((u16_t *)dataptr)++;*/ |
59 |
acc += *(u16_t *)dataptr; |
acc += *(u16_t *)dataptr; |
63 |
/* add up any odd byte */ |
/* add up any odd byte */ |
64 |
if (len == 1) { |
if (len == 1) { |
65 |
acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8); |
acc += htons((u16_t)((*(u8_t *)dataptr) & 0xff) << 8); |
66 |
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", *(u8_t *)dataptr)); |
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: odd byte %d\n", (unsigned int)(*(u8_t *)dataptr))); |
67 |
} else { |
} else { |
68 |
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n")); |
LWIP_DEBUGF(INET_DEBUG, ("inet: chksum: no odd byte\n")); |
69 |
} |
} |
93 |
acc = 0; |
acc = 0; |
94 |
swapped = 0; |
swapped = 0; |
95 |
/* iterate through all pbuf in chain */ |
/* iterate through all pbuf in chain */ |
96 |
for(q = p; q != NULL; q = q->next) { |
for(q = p; q != NULL; q = q->next) { |
97 |
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", (void *) q, (void *)q->next)); |
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", |
98 |
|
(void *)q, (void *)q->next)); |
99 |
acc += lwip_chksum(q->payload, q->len); |
acc += lwip_chksum(q->payload, q->len); |
100 |
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%lx \n", acc));*/ |
/*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%lx \n", acc));*/ |
101 |
while (acc >> 16) { |
while (acc >> 16) { |
116 |
acc += (dest->addr & 0xffffUL); |
acc += (dest->addr & 0xffffUL); |
117 |
acc += ((dest->addr >> 16) & 0xffffUL); |
acc += ((dest->addr >> 16) & 0xffffUL); |
118 |
acc += (u32_t)htons((u16_t)proto); |
acc += (u32_t)htons((u16_t)proto); |
119 |
acc += (u32_t)htons(proto_len); |
acc += (u32_t)htons(proto_len); |
120 |
|
|
121 |
while (acc >> 16) { |
while (acc >> 16) { |
122 |
acc = (acc & 0xffffUL) + (acc >> 16); |
acc = (acc & 0xffffUL) + (acc >> 16); |
123 |
} |
} |
124 |
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%lx\n", acc)); |
LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%lx\n", acc)); |
125 |
return ~(acc & 0xffffUL); |
return ~(acc & 0xffffUL); |
126 |
} |
} |
139 |
acc = lwip_chksum(dataptr, len); |
acc = lwip_chksum(dataptr, len); |
140 |
while (acc >> 16) { |
while (acc >> 16) { |
141 |
acc = (acc & 0xffff) + (acc >> 16); |
acc = (acc & 0xffff) + (acc >> 16); |
142 |
} |
} |
143 |
return ~(acc & 0xffff); |
return ~(acc & 0xffff); |
144 |
} |
} |
145 |
/*-----------------------------------------------------------------------------------*/ |
/*-----------------------------------------------------------------------------------*/ |
149 |
u32_t acc; |
u32_t acc; |
150 |
struct pbuf *q; |
struct pbuf *q; |
151 |
u8_t swapped; |
u8_t swapped; |
152 |
|
|
153 |
acc = 0; |
acc = 0; |
154 |
swapped = 0; |
swapped = 0; |
155 |
for(q = p; q != NULL; q = q->next) { |
for(q = p; q != NULL; q = q->next) { |
156 |
acc += lwip_chksum(q->payload, q->len); |
acc += lwip_chksum(q->payload, q->len); |
157 |
while (acc >> 16) { |
while (acc >> 16) { |
158 |
acc = (acc & 0xffffUL) + (acc >> 16); |
acc = (acc & 0xffffUL) + (acc >> 16); |
159 |
} |
} |
160 |
if (q->len % 2 != 0) { |
if (q->len % 2 != 0) { |
161 |
swapped = 1 - swapped; |
swapped = 1 - swapped; |
162 |
acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8); |
acc = (acc & 0x00ffUL << 8) | (acc & 0xff00UL >> 8); |
163 |
} |
} |
164 |
} |
} |
165 |
|
|
166 |
if (swapped) { |
if (swapped) { |
167 |
acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8); |
acc = ((acc & 0x00ffUL) << 8) | ((acc & 0xff00UL) >> 8); |
168 |
} |
} |
174 |
* Ascii internet address interpretation routine. |
* Ascii internet address interpretation routine. |
175 |
* The value returned is in network order. |
* The value returned is in network order. |
176 |
*/ |
*/ |
177 |
|
|
178 |
/* */ |
/* */ |
179 |
/* inet_addr */ |
/* inet_addr */ |
180 |
u32_t inet_addr(const char *cp) |
u32_t inet_addr(const char *cp) |
181 |
{ |
{ |
182 |
struct in_addr val; |
struct in_addr val; |
183 |
|
|
184 |
if (inet_aton(cp, &val)) { |
if (inet_aton(cp, &val)) { |
185 |
return (val.s_addr); |
return (val.s_addr); |
186 |
} |
} |
187 |
return (INADDR_NONE); |
return (INADDR_NONE); |
188 |
} |
} |
189 |
|
|
190 |
/* |
/* |
191 |
* Check whether "cp" is a valid ascii representation |
* Check whether "cp" is a valid ascii representation |
192 |
* of an Internet address and convert to a binary address. |
* of an Internet address and convert to a binary address. |
193 |
* Returns 1 if the address is valid, 0 if not. |
* Returns 1 if the address is valid, 0 if not. |
203 |
char c; |
char c; |
204 |
u32_t parts[4]; |
u32_t parts[4]; |
205 |
u32_t* pp = parts; |
u32_t* pp = parts; |
206 |
|
|
207 |
c = *cp; |
c = *cp; |
208 |
for (;;) { |
for (;;) { |
209 |
/* |
/* |
257 |
*/ |
*/ |
258 |
n = pp - parts + 1; |
n = pp - parts + 1; |
259 |
switch (n) { |
switch (n) { |
260 |
|
|
261 |
case 0: |
case 0: |
262 |
return (0); /* initial nondigit */ |
return (0); /* initial nondigit */ |
263 |
|
|
264 |
case 1: /* a -- 32 bits */ |
case 1: /* a -- 32 bits */ |
265 |
break; |
break; |
266 |
|
|
267 |
case 2: /* a.b -- 8.24 bits */ |
case 2: /* a.b -- 8.24 bits */ |
268 |
if (val > 0xffffff) |
if (val > 0xffffff) |
269 |
return (0); |
return (0); |
270 |
val |= parts[0] << 24; |
val |= parts[0] << 24; |
271 |
break; |
break; |
272 |
|
|
273 |
case 3: /* a.b.c -- 8.8.16 bits */ |
case 3: /* a.b.c -- 8.8.16 bits */ |
274 |
if (val > 0xffff) |
if (val > 0xffff) |
275 |
return (0); |
return (0); |
276 |
val |= (parts[0] << 24) | (parts[1] << 16); |
val |= (parts[0] << 24) | (parts[1] << 16); |
277 |
break; |
break; |
278 |
|
|
279 |
case 4: /* a.b.c.d -- 8.8.8.8 bits */ |
case 4: /* a.b.c.d -- 8.8.8.8 bits */ |
280 |
if (val > 0xff) |
if (val > 0xff) |
281 |
return (0); |
return (0); |