A version of LWIP, provided for backwards compatibility.
Dependents: AA_DemoBoard DemoBoard HelloServerDemo DemoBoard_RangeIndicator ... more
ip6.c
00001 /* 00002 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without modification, 00006 * are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright notice, 00011 * this list of conditions and the following disclaimer in the documentation 00012 * and/or other materials provided with the distribution. 00013 * 3. The name of the author may not be used to endorse or promote products 00014 * derived from this software without specific prior written permission. 00015 * 00016 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 00017 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 00018 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 00019 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00020 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 00021 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00022 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00023 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 00024 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 00025 * OF SUCH DAMAGE. 00026 * 00027 * This file is part of the lwIP TCP/IP stack. 00028 * 00029 * Author: Adam Dunkels <adam@sics.se> 00030 * 00031 */ 00032 00033 00034 00035 /* ip.c 00036 * 00037 * This is the code for the IP layer for IPv6. 00038 * 00039 */ 00040 00041 00042 #include "lwip/opt.h" 00043 00044 #if IPv6 00045 00046 #include "lwip/def.h" 00047 #include "lwip/mem.h" 00048 #include "ipv6/lwip/ip.h" 00049 #include "ipv6/lwip/inet.h" 00050 #include "lwip/netif.h" 00051 #include "ipv6/lwip/icmp.h" 00052 #include "lwip/udp.h" 00053 #include "lwip/tcp.h" 00054 00055 #include "lwip/stats.h" 00056 00057 #include "arch/perf.h" 00058 00059 /* ip_init: 00060 * 00061 * Initializes the IP layer. 00062 */ 00063 00064 void 00065 ip_init(void) 00066 { 00067 } 00068 00069 /* ip_route: 00070 * 00071 * Finds the appropriate network interface for a given IP address. It searches the 00072 * list of network interfaces linearly. A match is found if the masked IP address of 00073 * the network interface equals the masked IP address given to the function. 00074 */ 00075 00076 struct netif * 00077 ip_route(struct ip_addr *dest) 00078 { 00079 struct netif *netif; 00080 00081 for(netif = netif_list; netif != NULL; netif = netif->next) { 00082 if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { 00083 return netif; 00084 } 00085 } 00086 00087 return netif_default; 00088 } 00089 00090 /* ip_forward: 00091 * 00092 * Forwards an IP packet. It finds an appropriate route for the packet, decrements 00093 * the TTL value of the packet, adjusts the checksum and outputs the packet on the 00094 * appropriate interface. 00095 */ 00096 00097 static void 00098 ip_forward(struct pbuf *p, struct ip_hdr *iphdr) 00099 { 00100 struct netif *netif; 00101 00102 PERF_START; 00103 00104 if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) { 00105 00106 LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for ")); 00107 #if IP_DEBUG 00108 ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); 00109 #endif /* IP_DEBUG */ 00110 LWIP_DEBUGF(IP_DEBUG, ("\n")); 00111 pbuf_free(p); 00112 return; 00113 } 00114 /* Decrement TTL and send ICMP if ttl == 0. */ 00115 if (--iphdr->hoplim == 0) { 00116 #if LWIP_ICMP 00117 /* Don't send ICMP messages in response to ICMP messages */ 00118 if (iphdr->nexthdr != IP_PROTO_ICMP) { 00119 icmp_time_exceeded(p, ICMP_TE_TTL); 00120 } 00121 #endif /* LWIP_ICMP */ 00122 pbuf_free(p); 00123 return; 00124 } 00125 00126 /* Incremental update of the IP checksum. */ 00127 /* if (iphdr->chksum >= htons(0xffff - 0x100)) { 00128 iphdr->chksum += htons(0x100) + 1; 00129 } else { 00130 iphdr->chksum += htons(0x100); 00131 }*/ 00132 00133 00134 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to ")); 00135 #if IP_DEBUG 00136 ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); 00137 #endif /* IP_DEBUG */ 00138 LWIP_DEBUGF(IP_DEBUG, ("\n")); 00139 00140 IP_STATS_INC(ip.fw); 00141 IP_STATS_INC(ip.xmit); 00142 00143 PERF_STOP("ip_forward"); 00144 00145 netif->output(netif, p, (struct ip_addr *)&(iphdr->dest)); 00146 } 00147 00148 /* ip_input: 00149 * 00150 * This function is called by the network interface device driver when an IP packet is 00151 * received. The function does the basic checks of the IP header such as packet size 00152 * being at least larger than the header size etc. If the packet was not destined for 00153 * us, the packet is forwarded (using ip_forward). The IP checksum is always checked. 00154 * 00155 * Finally, the packet is sent to the upper layer protocol input function. 00156 */ 00157 00158 void 00159 ip_input(struct pbuf *p, struct netif *inp) { 00160 struct ip_hdr *iphdr; 00161 struct netif *netif; 00162 00163 00164 PERF_START; 00165 00166 #if IP_DEBUG 00167 ip_debug_print(p); 00168 #endif /* IP_DEBUG */ 00169 00170 00171 IP_STATS_INC(ip.recv); 00172 00173 /* identify the IP header */ 00174 iphdr = static_cast<struct ip_hdr *>(p->payload); 00175 00176 00177 if (iphdr->v != 6) { 00178 LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n")); 00179 #if IP_DEBUG 00180 ip_debug_print(p); 00181 #endif /* IP_DEBUG */ 00182 pbuf_free(p); 00183 IP_STATS_INC(ip.err); 00184 IP_STATS_INC(ip.drop); 00185 return; 00186 } 00187 00188 /* is this packet for us? */ 00189 for(netif = netif_list; netif != NULL; netif = netif->next) { 00190 #if IP_DEBUG 00191 LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest ")); 00192 ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); 00193 LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr ")); 00194 ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest))); 00195 LWIP_DEBUGF(IP_DEBUG, ("\n")); 00196 #endif /* IP_DEBUG */ 00197 if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) { 00198 break; 00199 } 00200 } 00201 00202 00203 if (netif == NULL) { 00204 /* packet not for us, route or discard */ 00205 #if IP_FORWARD 00206 ip_forward(p, iphdr); 00207 #endif 00208 pbuf_free(p); 00209 return; 00210 } 00211 00212 pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len)); 00213 00214 /* send to upper layers */ 00215 #if IP_DEBUG 00216 /* LWIP_DEBUGF("ip_input: \n"); 00217 ip_debug_print(p); 00218 LWIP_DEBUGF("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/ 00219 #endif /* IP_DEBUG */ 00220 00221 if(pbuf_header(p, -IP_HLEN)) { 00222 LWIP_ASSERT("Can't move over header in packet", 0); 00223 return; 00224 } 00225 00226 switch (iphdr->nexthdr) { 00227 case IP_PROTO_UDP: 00228 udp_input(p, inp); 00229 break; 00230 case IP_PROTO_TCP: 00231 tcp_input(p, inp); 00232 break; 00233 #if LWIP_ICMP 00234 case IP_PROTO_ICMP: 00235 icmp_input(p, inp); 00236 break; 00237 #endif /* LWIP_ICMP */ 00238 default: 00239 #if LWIP_ICMP 00240 /* send ICMP destination protocol unreachable */ 00241 icmp_dest_unreach(p, ICMP_DUR_PROTO); 00242 #endif /* LWIP_ICMP */ 00243 pbuf_free(p); 00244 LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %"U16_F"\n", 00245 iphdr->nexthdr)); 00246 00247 IP_STATS_INC(ip.proterr); 00248 IP_STATS_INC(ip.drop); 00249 } 00250 PERF_STOP("ip_input"); 00251 } 00252 00253 00254 /* ip_output_if: 00255 * 00256 * Sends an IP packet on a network interface. This function constructs the IP header 00257 * and calculates the IP header checksum. If the source IP address is NULL, 00258 * the IP address of the outgoing network interface is filled in as source address. 00259 */ 00260 00261 err_t 00262 ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, 00263 u8_t ttl, 00264 u8_t proto, struct netif *netif) 00265 { 00266 struct ip_hdr *iphdr; 00267 00268 PERF_START; 00269 00270 LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len)); 00271 if (pbuf_header(p, IP_HLEN)) { 00272 LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n")); 00273 IP_STATS_INC(ip.err); 00274 00275 return ERR_BUF; 00276 } 00277 LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len)); 00278 00279 iphdr = static_cast<struct ip_hdr *>(p->payload); 00280 00281 00282 if (dest != IP_HDRINCL) { 00283 LWIP_DEBUGF(IP_DEBUG, ("!IP_HDRLINCL\n")); 00284 iphdr->hoplim = ttl; 00285 iphdr->nexthdr = proto; 00286 iphdr->len = htons(p->tot_len - IP_HLEN); 00287 ip_addr_set(&(iphdr->dest), dest); 00288 00289 iphdr->v = 6; 00290 00291 if (ip_addr_isany(src)) { 00292 ip_addr_set(&(iphdr->src), &(netif->ip_addr)); 00293 } else { 00294 ip_addr_set(&(iphdr->src), src); 00295 } 00296 00297 } else { 00298 dest = &(iphdr->dest); 00299 } 00300 00301 IP_STATS_INC(ip.xmit); 00302 00303 LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %"U16_F")\n", netif->name[0], netif->name[1], p->tot_len)); 00304 #if IP_DEBUG 00305 ip_debug_print(p); 00306 #endif /* IP_DEBUG */ 00307 00308 PERF_STOP("ip_output_if"); 00309 return netif->output(netif, p, dest); 00310 } 00311 00312 /* ip_output: 00313 * 00314 * Simple interface to ip_output_if. It finds the outgoing network interface and 00315 * calls upon ip_output_if to do the actual work. 00316 */ 00317 00318 err_t 00319 ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest, 00320 u8_t ttl, u8_t proto) 00321 { 00322 struct netif *netif; 00323 if ((netif = ip_route(dest)) == NULL) { 00324 LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr)); 00325 IP_STATS_INC(ip.rterr); 00326 return ERR_RTE; 00327 } 00328 00329 return ip_output_if (p, src, dest, ttl, proto, netif); 00330 } 00331 00332 #if IP_DEBUG 00333 void 00334 ip_debug_print(struct pbuf *p) 00335 { 00336 struct ip_hdr *iphdr = p->payload; 00337 00338 LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); 00339 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00340 LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" | %"X16_F"%"X16_F" | %"X16_F"%"X16_F" | (v, traffic class, flow label)\n", 00341 iphdr->v, 00342 iphdr->tclass1, iphdr->tclass2, 00343 iphdr->flow1, iphdr->flow2)); 00344 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00345 LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" | %2"U16_F" | %2"U16_F" | (len, nexthdr, hoplim)\n", 00346 ntohs(iphdr->len), 00347 iphdr->nexthdr, 00348 iphdr->hoplim)); 00349 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00350 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", 00351 (ntohl(iphdr->src.addr[0]) >> 16) & 0xffff, 00352 ntohl(iphdr->src.addr[0]) & 0xffff)); 00353 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", 00354 (ntohl(iphdr->src.addr[1]) >> 16) & 0xffff, 00355 ntohl(iphdr->src.addr[1]) & 0xffff)); 00356 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", 00357 (ntohl(iphdr->src.addr[2]) >> 16) & 0xffff, 00358 ntohl(iphdr->src.addr[2]) & 0xffff)); 00359 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n", 00360 (ntohl(iphdr->src.addr[3]) >> 16) & 0xffff, 00361 ntohl(iphdr->src.addr[3]) & 0xffff)); 00362 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00363 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", 00364 (ntohl(iphdr->dest.addr[0]) >> 16) & 0xffff, 00365 ntohl(iphdr->dest.addr[0]) & 0xffff)); 00366 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", 00367 (ntohl(iphdr->dest.addr[1]) >> 16) & 0xffff, 00368 ntohl(iphdr->dest.addr[1]) & 0xffff)); 00369 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", 00370 (ntohl(iphdr->dest.addr[2]) >> 16) & 0xffff, 00371 ntohl(iphdr->dest.addr[2]) & 0xffff)); 00372 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n", 00373 (ntohl(iphdr->dest.addr[3]) >> 16) & 0xffff, 00374 ntohl(iphdr->dest.addr[3]) & 0xffff)); 00375 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 00376 } 00377 #endif /* IP_DEBUG */ 00378 00379 #endif /* IPv6 */
Generated on Tue Jul 12 2022 16:06:12 by 1.7.2