Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed OS 5, lwip has been integrated with built-in networking interfaces. The networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of lwIP v1.4.0

Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
All rights reserved. 

Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
Committer:
mbed_official
Date:
Mon Mar 14 16:15:36 2016 +0000
Revision:
20:08f08bfc3f3d
Parent:
0:51ac1d130fd4
Synchronized with git revision fec574a5ed6db26aca1b13992ff271bf527d4a0d

Full URL: https://github.com/mbedmicro/mbed/commit/fec574a5ed6db26aca1b13992ff271bf527d4a0d/

Increased allocated netbufs to handle DTLS handshakes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:51ac1d130fd4 1 /**
mbed_official 0:51ac1d130fd4 2 * @file
mbed_official 0:51ac1d130fd4 3 * Incluse internet checksum functions.
mbed_official 0:51ac1d130fd4 4 *
mbed_official 0:51ac1d130fd4 5 */
mbed_official 0:51ac1d130fd4 6
mbed_official 0:51ac1d130fd4 7 /*
mbed_official 0:51ac1d130fd4 8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
mbed_official 0:51ac1d130fd4 9 * All rights reserved.
mbed_official 0:51ac1d130fd4 10 *
mbed_official 0:51ac1d130fd4 11 * Redistribution and use in source and binary forms, with or without modification,
mbed_official 0:51ac1d130fd4 12 * are permitted provided that the following conditions are met:
mbed_official 0:51ac1d130fd4 13 *
mbed_official 0:51ac1d130fd4 14 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 0:51ac1d130fd4 15 * this list of conditions and the following disclaimer.
mbed_official 0:51ac1d130fd4 16 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 0:51ac1d130fd4 17 * this list of conditions and the following disclaimer in the documentation
mbed_official 0:51ac1d130fd4 18 * and/or other materials provided with the distribution.
mbed_official 0:51ac1d130fd4 19 * 3. The name of the author may not be used to endorse or promote products
mbed_official 0:51ac1d130fd4 20 * derived from this software without specific prior written permission.
mbed_official 0:51ac1d130fd4 21 *
mbed_official 0:51ac1d130fd4 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
mbed_official 0:51ac1d130fd4 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 0:51ac1d130fd4 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
mbed_official 0:51ac1d130fd4 25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
mbed_official 0:51ac1d130fd4 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
mbed_official 0:51ac1d130fd4 27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
mbed_official 0:51ac1d130fd4 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
mbed_official 0:51ac1d130fd4 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
mbed_official 0:51ac1d130fd4 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
mbed_official 0:51ac1d130fd4 31 * OF SUCH DAMAGE.
mbed_official 0:51ac1d130fd4 32 *
mbed_official 0:51ac1d130fd4 33 * This file is part of the lwIP TCP/IP stack.
mbed_official 0:51ac1d130fd4 34 *
mbed_official 0:51ac1d130fd4 35 * Author: Adam Dunkels <adam@sics.se>
mbed_official 0:51ac1d130fd4 36 *
mbed_official 0:51ac1d130fd4 37 */
mbed_official 0:51ac1d130fd4 38
mbed_official 0:51ac1d130fd4 39 #include "lwip/opt.h"
mbed_official 0:51ac1d130fd4 40
mbed_official 0:51ac1d130fd4 41 #include "lwip/inet_chksum.h"
mbed_official 0:51ac1d130fd4 42 #include "lwip/def.h"
mbed_official 0:51ac1d130fd4 43
mbed_official 0:51ac1d130fd4 44 #include <stddef.h>
mbed_official 0:51ac1d130fd4 45 #include <string.h>
mbed_official 0:51ac1d130fd4 46
mbed_official 0:51ac1d130fd4 47 /* These are some reference implementations of the checksum algorithm, with the
mbed_official 0:51ac1d130fd4 48 * aim of being simple, correct and fully portable. Checksumming is the
mbed_official 0:51ac1d130fd4 49 * first thing you would want to optimize for your platform. If you create
mbed_official 0:51ac1d130fd4 50 * your own version, link it in and in your cc.h put:
mbed_official 0:51ac1d130fd4 51 *
mbed_official 0:51ac1d130fd4 52 * #define LWIP_CHKSUM <your_checksum_routine>
mbed_official 0:51ac1d130fd4 53 *
mbed_official 0:51ac1d130fd4 54 * Or you can select from the implementations below by defining
mbed_official 0:51ac1d130fd4 55 * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3.
mbed_official 0:51ac1d130fd4 56 */
mbed_official 0:51ac1d130fd4 57
mbed_official 0:51ac1d130fd4 58 #ifndef LWIP_CHKSUM
mbed_official 0:51ac1d130fd4 59 # define LWIP_CHKSUM lwip_standard_chksum
mbed_official 0:51ac1d130fd4 60 # ifndef LWIP_CHKSUM_ALGORITHM
mbed_official 0:51ac1d130fd4 61 # define LWIP_CHKSUM_ALGORITHM 2
mbed_official 0:51ac1d130fd4 62 # endif
mbed_official 0:51ac1d130fd4 63 #endif
mbed_official 0:51ac1d130fd4 64 /* If none set: */
mbed_official 0:51ac1d130fd4 65 #ifndef LWIP_CHKSUM_ALGORITHM
mbed_official 0:51ac1d130fd4 66 # define LWIP_CHKSUM_ALGORITHM 0
mbed_official 0:51ac1d130fd4 67 #endif
mbed_official 0:51ac1d130fd4 68
mbed_official 0:51ac1d130fd4 69 #if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */
mbed_official 0:51ac1d130fd4 70 /**
mbed_official 0:51ac1d130fd4 71 * lwip checksum
mbed_official 0:51ac1d130fd4 72 *
mbed_official 0:51ac1d130fd4 73 * @param dataptr points to start of data to be summed at any boundary
mbed_official 0:51ac1d130fd4 74 * @param len length of data to be summed
mbed_official 0:51ac1d130fd4 75 * @return host order (!) lwip checksum (non-inverted Internet sum)
mbed_official 0:51ac1d130fd4 76 *
mbed_official 0:51ac1d130fd4 77 * @note accumulator size limits summable length to 64k
mbed_official 0:51ac1d130fd4 78 * @note host endianess is irrelevant (p3 RFC1071)
mbed_official 0:51ac1d130fd4 79 */
mbed_official 0:51ac1d130fd4 80 static u16_t
mbed_official 0:51ac1d130fd4 81 lwip_standard_chksum(void *dataptr, u16_t len)
mbed_official 0:51ac1d130fd4 82 {
mbed_official 0:51ac1d130fd4 83 u32_t acc;
mbed_official 0:51ac1d130fd4 84 u16_t src;
mbed_official 0:51ac1d130fd4 85 u8_t *octetptr;
mbed_official 0:51ac1d130fd4 86
mbed_official 0:51ac1d130fd4 87 acc = 0;
mbed_official 0:51ac1d130fd4 88 /* dataptr may be at odd or even addresses */
mbed_official 0:51ac1d130fd4 89 octetptr = (u8_t*)dataptr;
mbed_official 0:51ac1d130fd4 90 while (len > 1) {
mbed_official 0:51ac1d130fd4 91 /* declare first octet as most significant
mbed_official 0:51ac1d130fd4 92 thus assume network order, ignoring host order */
mbed_official 0:51ac1d130fd4 93 src = (*octetptr) << 8;
mbed_official 0:51ac1d130fd4 94 octetptr++;
mbed_official 0:51ac1d130fd4 95 /* declare second octet as least significant */
mbed_official 0:51ac1d130fd4 96 src |= (*octetptr);
mbed_official 0:51ac1d130fd4 97 octetptr++;
mbed_official 0:51ac1d130fd4 98 acc += src;
mbed_official 0:51ac1d130fd4 99 len -= 2;
mbed_official 0:51ac1d130fd4 100 }
mbed_official 0:51ac1d130fd4 101 if (len > 0) {
mbed_official 0:51ac1d130fd4 102 /* accumulate remaining octet */
mbed_official 0:51ac1d130fd4 103 src = (*octetptr) << 8;
mbed_official 0:51ac1d130fd4 104 acc += src;
mbed_official 0:51ac1d130fd4 105 }
mbed_official 0:51ac1d130fd4 106 /* add deferred carry bits */
mbed_official 0:51ac1d130fd4 107 acc = (acc >> 16) + (acc & 0x0000ffffUL);
mbed_official 0:51ac1d130fd4 108 if ((acc & 0xffff0000UL) != 0) {
mbed_official 0:51ac1d130fd4 109 acc = (acc >> 16) + (acc & 0x0000ffffUL);
mbed_official 0:51ac1d130fd4 110 }
mbed_official 0:51ac1d130fd4 111 /* This maybe a little confusing: reorder sum using htons()
mbed_official 0:51ac1d130fd4 112 instead of ntohs() since it has a little less call overhead.
mbed_official 0:51ac1d130fd4 113 The caller must invert bits for Internet sum ! */
mbed_official 0:51ac1d130fd4 114 return htons((u16_t)acc);
mbed_official 0:51ac1d130fd4 115 }
mbed_official 0:51ac1d130fd4 116 #endif
mbed_official 0:51ac1d130fd4 117
mbed_official 0:51ac1d130fd4 118 #if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */
mbed_official 0:51ac1d130fd4 119 /*
mbed_official 0:51ac1d130fd4 120 * Curt McDowell
mbed_official 0:51ac1d130fd4 121 * Broadcom Corp.
mbed_official 0:51ac1d130fd4 122 * csm@broadcom.com
mbed_official 0:51ac1d130fd4 123 *
mbed_official 0:51ac1d130fd4 124 * IP checksum two bytes at a time with support for
mbed_official 0:51ac1d130fd4 125 * unaligned buffer.
mbed_official 0:51ac1d130fd4 126 * Works for len up to and including 0x20000.
mbed_official 0:51ac1d130fd4 127 * by Curt McDowell, Broadcom Corp. 12/08/2005
mbed_official 0:51ac1d130fd4 128 *
mbed_official 0:51ac1d130fd4 129 * @param dataptr points to start of data to be summed at any boundary
mbed_official 0:51ac1d130fd4 130 * @param len length of data to be summed
mbed_official 0:51ac1d130fd4 131 * @return host order (!) lwip checksum (non-inverted Internet sum)
mbed_official 0:51ac1d130fd4 132 */
mbed_official 0:51ac1d130fd4 133
mbed_official 0:51ac1d130fd4 134 static u16_t
mbed_official 0:51ac1d130fd4 135 lwip_standard_chksum(void *dataptr, int len)
mbed_official 0:51ac1d130fd4 136 {
mbed_official 0:51ac1d130fd4 137 u8_t *pb = (u8_t *)dataptr;
mbed_official 0:51ac1d130fd4 138 u16_t *ps, t = 0;
mbed_official 0:51ac1d130fd4 139 u32_t sum = 0;
mbed_official 0:51ac1d130fd4 140 int odd = ((mem_ptr_t)pb & 1);
mbed_official 0:51ac1d130fd4 141
mbed_official 0:51ac1d130fd4 142 /* Get aligned to u16_t */
mbed_official 0:51ac1d130fd4 143 if (odd && len > 0) {
mbed_official 0:51ac1d130fd4 144 ((u8_t *)&t)[1] = *pb++;
mbed_official 0:51ac1d130fd4 145 len--;
mbed_official 0:51ac1d130fd4 146 }
mbed_official 0:51ac1d130fd4 147
mbed_official 0:51ac1d130fd4 148 /* Add the bulk of the data */
mbed_official 0:51ac1d130fd4 149 ps = (u16_t *)(void *)pb;
mbed_official 0:51ac1d130fd4 150 while (len > 1) {
mbed_official 0:51ac1d130fd4 151 sum += *ps++;
mbed_official 0:51ac1d130fd4 152 len -= 2;
mbed_official 0:51ac1d130fd4 153 }
mbed_official 0:51ac1d130fd4 154
mbed_official 0:51ac1d130fd4 155 /* Consume left-over byte, if any */
mbed_official 0:51ac1d130fd4 156 if (len > 0) {
mbed_official 0:51ac1d130fd4 157 ((u8_t *)&t)[0] = *(u8_t *)ps;
mbed_official 0:51ac1d130fd4 158 }
mbed_official 0:51ac1d130fd4 159
mbed_official 0:51ac1d130fd4 160 /* Add end bytes */
mbed_official 0:51ac1d130fd4 161 sum += t;
mbed_official 0:51ac1d130fd4 162
mbed_official 0:51ac1d130fd4 163 /* Fold 32-bit sum to 16 bits
mbed_official 0:51ac1d130fd4 164 calling this twice is propably faster than if statements... */
mbed_official 0:51ac1d130fd4 165 sum = FOLD_U32T(sum);
mbed_official 0:51ac1d130fd4 166 sum = FOLD_U32T(sum);
mbed_official 0:51ac1d130fd4 167
mbed_official 0:51ac1d130fd4 168 /* Swap if alignment was odd */
mbed_official 0:51ac1d130fd4 169 if (odd) {
mbed_official 0:51ac1d130fd4 170 sum = SWAP_BYTES_IN_WORD(sum);
mbed_official 0:51ac1d130fd4 171 }
mbed_official 0:51ac1d130fd4 172
mbed_official 0:51ac1d130fd4 173 return (u16_t)sum;
mbed_official 0:51ac1d130fd4 174 }
mbed_official 0:51ac1d130fd4 175 #endif
mbed_official 0:51ac1d130fd4 176
mbed_official 0:51ac1d130fd4 177 #if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */
mbed_official 0:51ac1d130fd4 178 /**
mbed_official 0:51ac1d130fd4 179 * An optimized checksum routine. Basically, it uses loop-unrolling on
mbed_official 0:51ac1d130fd4 180 * the checksum loop, treating the head and tail bytes specially, whereas
mbed_official 0:51ac1d130fd4 181 * the inner loop acts on 8 bytes at a time.
mbed_official 0:51ac1d130fd4 182 *
mbed_official 0:51ac1d130fd4 183 * @arg start of buffer to be checksummed. May be an odd byte address.
mbed_official 0:51ac1d130fd4 184 * @len number of bytes in the buffer to be checksummed.
mbed_official 0:51ac1d130fd4 185 * @return host order (!) lwip checksum (non-inverted Internet sum)
mbed_official 0:51ac1d130fd4 186 *
mbed_official 0:51ac1d130fd4 187 * by Curt McDowell, Broadcom Corp. December 8th, 2005
mbed_official 0:51ac1d130fd4 188 */
mbed_official 0:51ac1d130fd4 189
mbed_official 0:51ac1d130fd4 190 static u16_t
mbed_official 0:51ac1d130fd4 191 lwip_standard_chksum(void *dataptr, int len)
mbed_official 0:51ac1d130fd4 192 {
mbed_official 0:51ac1d130fd4 193 u8_t *pb = (u8_t *)dataptr;
mbed_official 0:51ac1d130fd4 194 u16_t *ps, t = 0;
mbed_official 0:51ac1d130fd4 195 u32_t *pl;
mbed_official 0:51ac1d130fd4 196 u32_t sum = 0, tmp;
mbed_official 0:51ac1d130fd4 197 /* starts at odd byte address? */
mbed_official 0:51ac1d130fd4 198 int odd = ((mem_ptr_t)pb & 1);
mbed_official 0:51ac1d130fd4 199
mbed_official 0:51ac1d130fd4 200 if (odd && len > 0) {
mbed_official 0:51ac1d130fd4 201 ((u8_t *)&t)[1] = *pb++;
mbed_official 0:51ac1d130fd4 202 len--;
mbed_official 0:51ac1d130fd4 203 }
mbed_official 0:51ac1d130fd4 204
mbed_official 0:51ac1d130fd4 205 ps = (u16_t *)pb;
mbed_official 0:51ac1d130fd4 206
mbed_official 0:51ac1d130fd4 207 if (((mem_ptr_t)ps & 3) && len > 1) {
mbed_official 0:51ac1d130fd4 208 sum += *ps++;
mbed_official 0:51ac1d130fd4 209 len -= 2;
mbed_official 0:51ac1d130fd4 210 }
mbed_official 0:51ac1d130fd4 211
mbed_official 0:51ac1d130fd4 212 pl = (u32_t *)ps;
mbed_official 0:51ac1d130fd4 213
mbed_official 0:51ac1d130fd4 214 while (len > 7) {
mbed_official 0:51ac1d130fd4 215 tmp = sum + *pl++; /* ping */
mbed_official 0:51ac1d130fd4 216 if (tmp < sum) {
mbed_official 0:51ac1d130fd4 217 tmp++; /* add back carry */
mbed_official 0:51ac1d130fd4 218 }
mbed_official 0:51ac1d130fd4 219
mbed_official 0:51ac1d130fd4 220 sum = tmp + *pl++; /* pong */
mbed_official 0:51ac1d130fd4 221 if (sum < tmp) {
mbed_official 0:51ac1d130fd4 222 sum++; /* add back carry */
mbed_official 0:51ac1d130fd4 223 }
mbed_official 0:51ac1d130fd4 224
mbed_official 0:51ac1d130fd4 225 len -= 8;
mbed_official 0:51ac1d130fd4 226 }
mbed_official 0:51ac1d130fd4 227
mbed_official 0:51ac1d130fd4 228 /* make room in upper bits */
mbed_official 0:51ac1d130fd4 229 sum = FOLD_U32T(sum);
mbed_official 0:51ac1d130fd4 230
mbed_official 0:51ac1d130fd4 231 ps = (u16_t *)pl;
mbed_official 0:51ac1d130fd4 232
mbed_official 0:51ac1d130fd4 233 /* 16-bit aligned word remaining? */
mbed_official 0:51ac1d130fd4 234 while (len > 1) {
mbed_official 0:51ac1d130fd4 235 sum += *ps++;
mbed_official 0:51ac1d130fd4 236 len -= 2;
mbed_official 0:51ac1d130fd4 237 }
mbed_official 0:51ac1d130fd4 238
mbed_official 0:51ac1d130fd4 239 /* dangling tail byte remaining? */
mbed_official 0:51ac1d130fd4 240 if (len > 0) { /* include odd byte */
mbed_official 0:51ac1d130fd4 241 ((u8_t *)&t)[0] = *(u8_t *)ps;
mbed_official 0:51ac1d130fd4 242 }
mbed_official 0:51ac1d130fd4 243
mbed_official 0:51ac1d130fd4 244 sum += t; /* add end bytes */
mbed_official 0:51ac1d130fd4 245
mbed_official 0:51ac1d130fd4 246 /* Fold 32-bit sum to 16 bits
mbed_official 0:51ac1d130fd4 247 calling this twice is propably faster than if statements... */
mbed_official 0:51ac1d130fd4 248 sum = FOLD_U32T(sum);
mbed_official 0:51ac1d130fd4 249 sum = FOLD_U32T(sum);
mbed_official 0:51ac1d130fd4 250
mbed_official 0:51ac1d130fd4 251 if (odd) {
mbed_official 0:51ac1d130fd4 252 sum = SWAP_BYTES_IN_WORD(sum);
mbed_official 0:51ac1d130fd4 253 }
mbed_official 0:51ac1d130fd4 254
mbed_official 0:51ac1d130fd4 255 return (u16_t)sum;
mbed_official 0:51ac1d130fd4 256 }
mbed_official 0:51ac1d130fd4 257 #endif
mbed_official 0:51ac1d130fd4 258
mbed_official 0:51ac1d130fd4 259 /* inet_chksum_pseudo:
mbed_official 0:51ac1d130fd4 260 *
mbed_official 0:51ac1d130fd4 261 * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
mbed_official 0:51ac1d130fd4 262 * IP addresses are expected to be in network byte order.
mbed_official 0:51ac1d130fd4 263 *
mbed_official 0:51ac1d130fd4 264 * @param p chain of pbufs over that a checksum should be calculated (ip data part)
mbed_official 0:51ac1d130fd4 265 * @param src source ip address (used for checksum of pseudo header)
mbed_official 0:51ac1d130fd4 266 * @param dst destination ip address (used for checksum of pseudo header)
mbed_official 0:51ac1d130fd4 267 * @param proto ip protocol (used for checksum of pseudo header)
mbed_official 0:51ac1d130fd4 268 * @param proto_len length of the ip data part (used for checksum of pseudo header)
mbed_official 0:51ac1d130fd4 269 * @return checksum (as u16_t) to be saved directly in the protocol header
mbed_official 0:51ac1d130fd4 270 */
mbed_official 0:51ac1d130fd4 271 u16_t
mbed_official 0:51ac1d130fd4 272 inet_chksum_pseudo(struct pbuf *p,
mbed_official 0:51ac1d130fd4 273 ip_addr_t *src, ip_addr_t *dest,
mbed_official 0:51ac1d130fd4 274 u8_t proto, u16_t proto_len)
mbed_official 0:51ac1d130fd4 275 {
mbed_official 0:51ac1d130fd4 276 u32_t acc;
mbed_official 0:51ac1d130fd4 277 u32_t addr;
mbed_official 0:51ac1d130fd4 278 struct pbuf *q;
mbed_official 0:51ac1d130fd4 279 u8_t swapped;
mbed_official 0:51ac1d130fd4 280
mbed_official 0:51ac1d130fd4 281 acc = 0;
mbed_official 0:51ac1d130fd4 282 swapped = 0;
mbed_official 0:51ac1d130fd4 283 /* iterate through all pbuf in chain */
mbed_official 0:51ac1d130fd4 284 for(q = p; q != NULL; q = q->next) {
mbed_official 0:51ac1d130fd4 285 LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
mbed_official 0:51ac1d130fd4 286 (void *)q, (void *)q->next));
mbed_official 0:51ac1d130fd4 287 acc += LWIP_CHKSUM(q->payload, q->len);
mbed_official 0:51ac1d130fd4 288 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
mbed_official 0:51ac1d130fd4 289 /* just executing this next line is probably faster that the if statement needed
mbed_official 0:51ac1d130fd4 290 to check whether we really need to execute it, and does no harm */
mbed_official 0:51ac1d130fd4 291 acc = FOLD_U32T(acc);
mbed_official 0:51ac1d130fd4 292 if (q->len % 2 != 0) {
mbed_official 0:51ac1d130fd4 293 swapped = 1 - swapped;
mbed_official 0:51ac1d130fd4 294 acc = SWAP_BYTES_IN_WORD(acc);
mbed_official 0:51ac1d130fd4 295 }
mbed_official 0:51ac1d130fd4 296 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
mbed_official 0:51ac1d130fd4 297 }
mbed_official 0:51ac1d130fd4 298
mbed_official 0:51ac1d130fd4 299 if (swapped) {
mbed_official 0:51ac1d130fd4 300 acc = SWAP_BYTES_IN_WORD(acc);
mbed_official 0:51ac1d130fd4 301 }
mbed_official 0:51ac1d130fd4 302 addr = ip4_addr_get_u32(src);
mbed_official 0:51ac1d130fd4 303 acc += (addr & 0xffffUL);
mbed_official 0:51ac1d130fd4 304 acc += ((addr >> 16) & 0xffffUL);
mbed_official 0:51ac1d130fd4 305 addr = ip4_addr_get_u32(dest);
mbed_official 0:51ac1d130fd4 306 acc += (addr & 0xffffUL);
mbed_official 0:51ac1d130fd4 307 acc += ((addr >> 16) & 0xffffUL);
mbed_official 0:51ac1d130fd4 308 acc += (u32_t)htons((u16_t)proto);
mbed_official 0:51ac1d130fd4 309 acc += (u32_t)htons(proto_len);
mbed_official 0:51ac1d130fd4 310
mbed_official 0:51ac1d130fd4 311 /* Fold 32-bit sum to 16 bits
mbed_official 0:51ac1d130fd4 312 calling this twice is propably faster than if statements... */
mbed_official 0:51ac1d130fd4 313 acc = FOLD_U32T(acc);
mbed_official 0:51ac1d130fd4 314 acc = FOLD_U32T(acc);
mbed_official 0:51ac1d130fd4 315 LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
mbed_official 0:51ac1d130fd4 316 return (u16_t)~(acc & 0xffffUL);
mbed_official 0:51ac1d130fd4 317 }
mbed_official 0:51ac1d130fd4 318
mbed_official 0:51ac1d130fd4 319 /* inet_chksum_pseudo:
mbed_official 0:51ac1d130fd4 320 *
mbed_official 0:51ac1d130fd4 321 * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
mbed_official 0:51ac1d130fd4 322 * IP addresses are expected to be in network byte order.
mbed_official 0:51ac1d130fd4 323 *
mbed_official 0:51ac1d130fd4 324 * @param p chain of pbufs over that a checksum should be calculated (ip data part)
mbed_official 0:51ac1d130fd4 325 * @param src source ip address (used for checksum of pseudo header)
mbed_official 0:51ac1d130fd4 326 * @param dst destination ip address (used for checksum of pseudo header)
mbed_official 0:51ac1d130fd4 327 * @param proto ip protocol (used for checksum of pseudo header)
mbed_official 0:51ac1d130fd4 328 * @param proto_len length of the ip data part (used for checksum of pseudo header)
mbed_official 0:51ac1d130fd4 329 * @return checksum (as u16_t) to be saved directly in the protocol header
mbed_official 0:51ac1d130fd4 330 */
mbed_official 0:51ac1d130fd4 331 u16_t
mbed_official 0:51ac1d130fd4 332 inet_chksum_pseudo_partial(struct pbuf *p,
mbed_official 0:51ac1d130fd4 333 ip_addr_t *src, ip_addr_t *dest,
mbed_official 0:51ac1d130fd4 334 u8_t proto, u16_t proto_len, u16_t chksum_len)
mbed_official 0:51ac1d130fd4 335 {
mbed_official 0:51ac1d130fd4 336 u32_t acc;
mbed_official 0:51ac1d130fd4 337 u32_t addr;
mbed_official 0:51ac1d130fd4 338 struct pbuf *q;
mbed_official 0:51ac1d130fd4 339 u8_t swapped;
mbed_official 0:51ac1d130fd4 340 u16_t chklen;
mbed_official 0:51ac1d130fd4 341
mbed_official 0:51ac1d130fd4 342 acc = 0;
mbed_official 0:51ac1d130fd4 343 swapped = 0;
mbed_official 0:51ac1d130fd4 344 /* iterate through all pbuf in chain */
mbed_official 0:51ac1d130fd4 345 for(q = p; (q != NULL) && (chksum_len > 0); q = q->next) {
mbed_official 0:51ac1d130fd4 346 LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n",
mbed_official 0:51ac1d130fd4 347 (void *)q, (void *)q->next));
mbed_official 0:51ac1d130fd4 348 chklen = q->len;
mbed_official 0:51ac1d130fd4 349 if (chklen > chksum_len) {
mbed_official 0:51ac1d130fd4 350 chklen = chksum_len;
mbed_official 0:51ac1d130fd4 351 }
mbed_official 0:51ac1d130fd4 352 acc += LWIP_CHKSUM(q->payload, chklen);
mbed_official 0:51ac1d130fd4 353 chksum_len -= chklen;
mbed_official 0:51ac1d130fd4 354 LWIP_ASSERT("delete me", chksum_len < 0x7fff);
mbed_official 0:51ac1d130fd4 355 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/
mbed_official 0:51ac1d130fd4 356 /* fold the upper bit down */
mbed_official 0:51ac1d130fd4 357 acc = FOLD_U32T(acc);
mbed_official 0:51ac1d130fd4 358 if (q->len % 2 != 0) {
mbed_official 0:51ac1d130fd4 359 swapped = 1 - swapped;
mbed_official 0:51ac1d130fd4 360 acc = SWAP_BYTES_IN_WORD(acc);
mbed_official 0:51ac1d130fd4 361 }
mbed_official 0:51ac1d130fd4 362 /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/
mbed_official 0:51ac1d130fd4 363 }
mbed_official 0:51ac1d130fd4 364
mbed_official 0:51ac1d130fd4 365 if (swapped) {
mbed_official 0:51ac1d130fd4 366 acc = SWAP_BYTES_IN_WORD(acc);
mbed_official 0:51ac1d130fd4 367 }
mbed_official 0:51ac1d130fd4 368 addr = ip4_addr_get_u32(src);
mbed_official 0:51ac1d130fd4 369 acc += (addr & 0xffffUL);
mbed_official 0:51ac1d130fd4 370 acc += ((addr >> 16) & 0xffffUL);
mbed_official 0:51ac1d130fd4 371 addr = ip4_addr_get_u32(dest);
mbed_official 0:51ac1d130fd4 372 acc += (addr & 0xffffUL);
mbed_official 0:51ac1d130fd4 373 acc += ((addr >> 16) & 0xffffUL);
mbed_official 0:51ac1d130fd4 374 acc += (u32_t)htons((u16_t)proto);
mbed_official 0:51ac1d130fd4 375 acc += (u32_t)htons(proto_len);
mbed_official 0:51ac1d130fd4 376
mbed_official 0:51ac1d130fd4 377 /* Fold 32-bit sum to 16 bits
mbed_official 0:51ac1d130fd4 378 calling this twice is propably faster than if statements... */
mbed_official 0:51ac1d130fd4 379 acc = FOLD_U32T(acc);
mbed_official 0:51ac1d130fd4 380 acc = FOLD_U32T(acc);
mbed_official 0:51ac1d130fd4 381 LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc));
mbed_official 0:51ac1d130fd4 382 return (u16_t)~(acc & 0xffffUL);
mbed_official 0:51ac1d130fd4 383 }
mbed_official 0:51ac1d130fd4 384
mbed_official 0:51ac1d130fd4 385 /* inet_chksum:
mbed_official 0:51ac1d130fd4 386 *
mbed_official 0:51ac1d130fd4 387 * Calculates the Internet checksum over a portion of memory. Used primarily for IP
mbed_official 0:51ac1d130fd4 388 * and ICMP.
mbed_official 0:51ac1d130fd4 389 *
mbed_official 0:51ac1d130fd4 390 * @param dataptr start of the buffer to calculate the checksum (no alignment needed)
mbed_official 0:51ac1d130fd4 391 * @param len length of the buffer to calculate the checksum
mbed_official 0:51ac1d130fd4 392 * @return checksum (as u16_t) to be saved directly in the protocol header
mbed_official 0:51ac1d130fd4 393 */
mbed_official 0:51ac1d130fd4 394
mbed_official 0:51ac1d130fd4 395 u16_t
mbed_official 0:51ac1d130fd4 396 inet_chksum(void *dataptr, u16_t len)
mbed_official 0:51ac1d130fd4 397 {
mbed_official 0:51ac1d130fd4 398 return ~LWIP_CHKSUM(dataptr, len);
mbed_official 0:51ac1d130fd4 399 }
mbed_official 0:51ac1d130fd4 400
mbed_official 0:51ac1d130fd4 401 /**
mbed_official 0:51ac1d130fd4 402 * Calculate a checksum over a chain of pbufs (without pseudo-header, much like
mbed_official 0:51ac1d130fd4 403 * inet_chksum only pbufs are used).
mbed_official 0:51ac1d130fd4 404 *
mbed_official 0:51ac1d130fd4 405 * @param p pbuf chain over that the checksum should be calculated
mbed_official 0:51ac1d130fd4 406 * @return checksum (as u16_t) to be saved directly in the protocol header
mbed_official 0:51ac1d130fd4 407 */
mbed_official 0:51ac1d130fd4 408 u16_t
mbed_official 0:51ac1d130fd4 409 inet_chksum_pbuf(struct pbuf *p)
mbed_official 0:51ac1d130fd4 410 {
mbed_official 0:51ac1d130fd4 411 u32_t acc;
mbed_official 0:51ac1d130fd4 412 struct pbuf *q;
mbed_official 0:51ac1d130fd4 413 u8_t swapped;
mbed_official 0:51ac1d130fd4 414
mbed_official 0:51ac1d130fd4 415 acc = 0;
mbed_official 0:51ac1d130fd4 416 swapped = 0;
mbed_official 0:51ac1d130fd4 417 for(q = p; q != NULL; q = q->next) {
mbed_official 0:51ac1d130fd4 418 acc += LWIP_CHKSUM(q->payload, q->len);
mbed_official 0:51ac1d130fd4 419 acc = FOLD_U32T(acc);
mbed_official 0:51ac1d130fd4 420 if (q->len % 2 != 0) {
mbed_official 0:51ac1d130fd4 421 swapped = 1 - swapped;
mbed_official 0:51ac1d130fd4 422 acc = SWAP_BYTES_IN_WORD(acc);
mbed_official 0:51ac1d130fd4 423 }
mbed_official 0:51ac1d130fd4 424 }
mbed_official 0:51ac1d130fd4 425
mbed_official 0:51ac1d130fd4 426 if (swapped) {
mbed_official 0:51ac1d130fd4 427 acc = SWAP_BYTES_IN_WORD(acc);
mbed_official 0:51ac1d130fd4 428 }
mbed_official 0:51ac1d130fd4 429 return (u16_t)~(acc & 0xffffUL);
mbed_official 0:51ac1d130fd4 430 }
mbed_official 0:51ac1d130fd4 431
mbed_official 0:51ac1d130fd4 432 /* These are some implementations for LWIP_CHKSUM_COPY, which copies data
mbed_official 0:51ac1d130fd4 433 * like MEMCPY but generates a checksum at the same time. Since this is a
mbed_official 0:51ac1d130fd4 434 * performance-sensitive function, you might want to create your own version
mbed_official 0:51ac1d130fd4 435 * in assembly targeted at your hardware by defining it in lwipopts.h:
mbed_official 0:51ac1d130fd4 436 * #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len)
mbed_official 0:51ac1d130fd4 437 */
mbed_official 0:51ac1d130fd4 438
mbed_official 0:51ac1d130fd4 439 #if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */
mbed_official 0:51ac1d130fd4 440 /** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM.
mbed_official 0:51ac1d130fd4 441 * For architectures with big caches, data might still be in cache when
mbed_official 0:51ac1d130fd4 442 * generating the checksum after copying.
mbed_official 0:51ac1d130fd4 443 */
mbed_official 0:51ac1d130fd4 444 u16_t
mbed_official 0:51ac1d130fd4 445 lwip_chksum_copy(void *dst, const void *src, u16_t len)
mbed_official 0:51ac1d130fd4 446 {
mbed_official 0:51ac1d130fd4 447 MEMCPY(dst, src, len);
mbed_official 0:51ac1d130fd4 448 return LWIP_CHKSUM(dst, len);
mbed_official 0:51ac1d130fd4 449 }
mbed_official 0:51ac1d130fd4 450 #endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */