A version of LWIP, provided for backwards compatibility.

Dependents:   AA_DemoBoard DemoBoard HelloServerDemo DemoBoard_RangeIndicator ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers inet6.c Source File

inet6.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * Functions common to all TCP/IPv6 modules, such as the Internet checksum and the
00004  * byte order functions.
00005  *
00006  */
00007 
00008 /*
00009  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00010  * All rights reserved. 
00011  * 
00012  * Redistribution and use in source and binary forms, with or without modification, 
00013  * are permitted provided that the following conditions are met:
00014  *
00015  * 1. Redistributions of source code must retain the above copyright notice,
00016  *    this list of conditions and the following disclaimer.
00017  * 2. Redistributions in binary form must reproduce the above copyright notice,
00018  *    this list of conditions and the following disclaimer in the documentation
00019  *    and/or other materials provided with the distribution.
00020  * 3. The name of the author may not be used to endorse or promote products
00021  *    derived from this software without specific prior written permission. 
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
00024  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
00025  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
00026  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00027  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
00028  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
00031  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
00032  * OF SUCH DAMAGE.
00033  *
00034  * This file is part of the lwIP TCP/IP stack.
00035  * 
00036  * Author: Adam Dunkels <adam@sics.se>
00037  *
00038  */
00039 
00040 #include "lwip/opt.h"
00041 
00042 #if IPv6
00043 
00044 #include "lwip/def.h"
00045 #include "ipv6/lwip/inet.h"
00046 
00047 /* chksum:
00048  *
00049  * Sums up all 16 bit words in a memory portion. Also includes any odd byte.
00050  * This function is used by the other checksum functions.
00051  *
00052  * For now, this is not optimized. Must be optimized for the particular processor
00053  * arcitecture on which it is to run. Preferebly coded in assembler.
00054  */
00055 
00056 static u32_t
00057 chksum(void *dataptr, u16_t len)
00058 {
00059   u16_t *sdataptr = (u16_t *)dataptr;
00060   u32_t acc;
00061   
00062   
00063   for(acc = 0; len > 1; len -= 2) {
00064     acc += *sdataptr++;
00065   }
00066 
00067   /* add up any odd byte */
00068   if (len == 1) {
00069     acc += htons((u16_t)(*(u8_t *)dataptr) << 8);
00070   }
00071 
00072   return acc;
00073 
00074 }
00075 
00076 /* inet_chksum_pseudo:
00077  *
00078  * Calculates the pseudo Internet checksum used by TCP and UDP for a pbuf chain.
00079  */
00080 
00081 u16_t
00082 inet_chksum_pseudo(struct pbuf *p,
00083        struct ip_addr *src, struct ip_addr *dest,
00084        u8_t proto, u32_t proto_len)
00085 {
00086   u32_t acc;
00087   struct pbuf *q;
00088   u8_t swapped, i;
00089 
00090   acc = 0;
00091   swapped = 0;
00092   for(q = p; q != NULL; q = q->next) {
00093     acc += chksum((void *)q->payload, q->len);
00094     while (acc >> 16) {
00095       acc = (acc & 0xffff) + (acc >> 16);
00096     }
00097     if (q->len % 2 != 0) {
00098       swapped = 1 - swapped;
00099       acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
00100     }
00101   }
00102 
00103   if (swapped) {
00104     acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
00105   }
00106   
00107   for(i = 0; i < 8; i++) {
00108     acc += ((u16_t *)src->addr)[i] & 0xffff;
00109     acc += ((u16_t *)dest->addr)[i] & 0xffff;
00110     while (acc >> 16) {
00111       acc = (acc & 0xffff) + (acc >> 16);
00112     }
00113   }
00114   acc += (u16_t)htons((u16_t)proto);
00115   acc += ((u16_t *)&proto_len)[0] & 0xffff;
00116   acc += ((u16_t *)&proto_len)[1] & 0xffff;
00117 
00118   while (acc >> 16) {
00119     acc = (acc & 0xffff) + (acc >> 16);
00120   }
00121   return ~(acc & 0xffff);
00122 }
00123 
00124 /* inet_chksum:
00125  *
00126  * Calculates the Internet checksum over a portion of memory. Used primarely for IP
00127  * and ICMP.
00128  */
00129 
00130 u16_t
00131 inet_chksum(void *dataptr, u16_t len)
00132 {
00133   u32_t acc, sum;
00134 
00135   acc = chksum(dataptr, len);
00136   sum = (acc & 0xffff) + (acc >> 16);
00137   sum += (sum >> 16);
00138   return ~(sum & 0xffff);
00139 }
00140 
00141 u16_t
00142 inet_chksum_pbuf(struct pbuf *p)
00143 {
00144   u32_t acc;
00145   struct pbuf *q;
00146   u8_t swapped;
00147   
00148   acc = 0;
00149   swapped = 0;
00150   for(q = p; q != static_cast<struct pbuf *>(NULL); q = q->next) {
00151     acc += chksum(q->payload, q->len);
00152     while (acc >> 16) {
00153       acc = (acc & 0xffff) + (acc >> 16);
00154     }    
00155     if (q->len % 2 != 0) {
00156       swapped = 1 - swapped;
00157       acc = (acc & 0xff << 8) | (acc & 0xff00 >> 8);
00158     }
00159   }
00160  
00161   if (swapped) {
00162     acc = ((acc & 0xff) << 8) | ((acc & 0xff00) >> 8);
00163   }
00164   return ~(acc & 0xffff);
00165 }
00166 
00167 #endif /* IPv6 */