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:
Fri Jun 22 09:25:39 2012 +0000
Revision:
0:51ac1d130fd4
Initial import from lwip-1.4.0: http://download.savannah.gnu.org/releases/lwip/lwip-1.4.0.zip

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 0:51ac1d130fd4 1 /*
mbed_official 0:51ac1d130fd4 2 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
mbed_official 0:51ac1d130fd4 3 * All rights reserved.
mbed_official 0:51ac1d130fd4 4 *
mbed_official 0:51ac1d130fd4 5 * Redistribution and use in source and binary forms, with or without modification,
mbed_official 0:51ac1d130fd4 6 * are permitted provided that the following conditions are met:
mbed_official 0:51ac1d130fd4 7 *
mbed_official 0:51ac1d130fd4 8 * 1. Redistributions of source code must retain the above copyright notice,
mbed_official 0:51ac1d130fd4 9 * this list of conditions and the following disclaimer.
mbed_official 0:51ac1d130fd4 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
mbed_official 0:51ac1d130fd4 11 * this list of conditions and the following disclaimer in the documentation
mbed_official 0:51ac1d130fd4 12 * and/or other materials provided with the distribution.
mbed_official 0:51ac1d130fd4 13 * 3. The name of the author may not be used to endorse or promote products
mbed_official 0:51ac1d130fd4 14 * derived from this software without specific prior written permission.
mbed_official 0:51ac1d130fd4 15 *
mbed_official 0:51ac1d130fd4 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
mbed_official 0:51ac1d130fd4 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
mbed_official 0:51ac1d130fd4 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
mbed_official 0:51ac1d130fd4 19 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
mbed_official 0:51ac1d130fd4 20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
mbed_official 0:51ac1d130fd4 21 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
mbed_official 0:51ac1d130fd4 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
mbed_official 0:51ac1d130fd4 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
mbed_official 0:51ac1d130fd4 24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
mbed_official 0:51ac1d130fd4 25 * OF SUCH DAMAGE.
mbed_official 0:51ac1d130fd4 26 *
mbed_official 0:51ac1d130fd4 27 * This file is part of the lwIP TCP/IP stack.
mbed_official 0:51ac1d130fd4 28 *
mbed_official 0:51ac1d130fd4 29 * Author: Adam Dunkels <adam@sics.se>
mbed_official 0:51ac1d130fd4 30 *
mbed_official 0:51ac1d130fd4 31 */
mbed_official 0:51ac1d130fd4 32
mbed_official 0:51ac1d130fd4 33
mbed_official 0:51ac1d130fd4 34
mbed_official 0:51ac1d130fd4 35 /* ip.c
mbed_official 0:51ac1d130fd4 36 *
mbed_official 0:51ac1d130fd4 37 * This is the code for the IP layer for IPv6.
mbed_official 0:51ac1d130fd4 38 *
mbed_official 0:51ac1d130fd4 39 */
mbed_official 0:51ac1d130fd4 40
mbed_official 0:51ac1d130fd4 41
mbed_official 0:51ac1d130fd4 42 #include "lwip/opt.h"
mbed_official 0:51ac1d130fd4 43
mbed_official 0:51ac1d130fd4 44 #include "lwip/def.h"
mbed_official 0:51ac1d130fd4 45 #include "lwip/mem.h"
mbed_official 0:51ac1d130fd4 46 #include "lwip/ip.h"
mbed_official 0:51ac1d130fd4 47 #include "lwip/inet.h"
mbed_official 0:51ac1d130fd4 48 #include "lwip/netif.h"
mbed_official 0:51ac1d130fd4 49 #include "lwip/icmp.h"
mbed_official 0:51ac1d130fd4 50 #include "lwip/udp.h"
mbed_official 0:51ac1d130fd4 51 #include "lwip/tcp_impl.h"
mbed_official 0:51ac1d130fd4 52
mbed_official 0:51ac1d130fd4 53 #include "lwip/stats.h"
mbed_official 0:51ac1d130fd4 54
mbed_official 0:51ac1d130fd4 55 #include "arch/perf.h"
mbed_official 0:51ac1d130fd4 56
mbed_official 0:51ac1d130fd4 57 /* ip_init:
mbed_official 0:51ac1d130fd4 58 *
mbed_official 0:51ac1d130fd4 59 * Initializes the IP layer.
mbed_official 0:51ac1d130fd4 60 */
mbed_official 0:51ac1d130fd4 61
mbed_official 0:51ac1d130fd4 62 void
mbed_official 0:51ac1d130fd4 63 ip_init(void)
mbed_official 0:51ac1d130fd4 64 {
mbed_official 0:51ac1d130fd4 65 }
mbed_official 0:51ac1d130fd4 66
mbed_official 0:51ac1d130fd4 67 /* ip_route:
mbed_official 0:51ac1d130fd4 68 *
mbed_official 0:51ac1d130fd4 69 * Finds the appropriate network interface for a given IP address. It searches the
mbed_official 0:51ac1d130fd4 70 * list of network interfaces linearly. A match is found if the masked IP address of
mbed_official 0:51ac1d130fd4 71 * the network interface equals the masked IP address given to the function.
mbed_official 0:51ac1d130fd4 72 */
mbed_official 0:51ac1d130fd4 73
mbed_official 0:51ac1d130fd4 74 struct netif *
mbed_official 0:51ac1d130fd4 75 ip_route(struct ip_addr *dest)
mbed_official 0:51ac1d130fd4 76 {
mbed_official 0:51ac1d130fd4 77 struct netif *netif;
mbed_official 0:51ac1d130fd4 78
mbed_official 0:51ac1d130fd4 79 for(netif = netif_list; netif != NULL; netif = netif->next) {
mbed_official 0:51ac1d130fd4 80 if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
mbed_official 0:51ac1d130fd4 81 return netif;
mbed_official 0:51ac1d130fd4 82 }
mbed_official 0:51ac1d130fd4 83 }
mbed_official 0:51ac1d130fd4 84
mbed_official 0:51ac1d130fd4 85 return netif_default;
mbed_official 0:51ac1d130fd4 86 }
mbed_official 0:51ac1d130fd4 87
mbed_official 0:51ac1d130fd4 88 /* ip_forward:
mbed_official 0:51ac1d130fd4 89 *
mbed_official 0:51ac1d130fd4 90 * Forwards an IP packet. It finds an appropriate route for the packet, decrements
mbed_official 0:51ac1d130fd4 91 * the TTL value of the packet, adjusts the checksum and outputs the packet on the
mbed_official 0:51ac1d130fd4 92 * appropriate interface.
mbed_official 0:51ac1d130fd4 93 */
mbed_official 0:51ac1d130fd4 94
mbed_official 0:51ac1d130fd4 95 static void
mbed_official 0:51ac1d130fd4 96 ip_forward(struct pbuf *p, struct ip_hdr *iphdr)
mbed_official 0:51ac1d130fd4 97 {
mbed_official 0:51ac1d130fd4 98 struct netif *netif;
mbed_official 0:51ac1d130fd4 99
mbed_official 0:51ac1d130fd4 100 PERF_START;
mbed_official 0:51ac1d130fd4 101
mbed_official 0:51ac1d130fd4 102 if ((netif = ip_route((struct ip_addr *)&(iphdr->dest))) == NULL) {
mbed_official 0:51ac1d130fd4 103
mbed_official 0:51ac1d130fd4 104 LWIP_DEBUGF(IP_DEBUG, ("ip_input: no forwarding route found for "));
mbed_official 0:51ac1d130fd4 105 #if IP_DEBUG
mbed_official 0:51ac1d130fd4 106 ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
mbed_official 0:51ac1d130fd4 107 #endif /* IP_DEBUG */
mbed_official 0:51ac1d130fd4 108 LWIP_DEBUGF(IP_DEBUG, ("\n"));
mbed_official 0:51ac1d130fd4 109 pbuf_free(p);
mbed_official 0:51ac1d130fd4 110 return;
mbed_official 0:51ac1d130fd4 111 }
mbed_official 0:51ac1d130fd4 112 /* Decrement TTL and send ICMP if ttl == 0. */
mbed_official 0:51ac1d130fd4 113 if (--iphdr->hoplim == 0) {
mbed_official 0:51ac1d130fd4 114 #if LWIP_ICMP
mbed_official 0:51ac1d130fd4 115 /* Don't send ICMP messages in response to ICMP messages */
mbed_official 0:51ac1d130fd4 116 if (iphdr->nexthdr != IP_PROTO_ICMP) {
mbed_official 0:51ac1d130fd4 117 icmp_time_exceeded(p, ICMP_TE_TTL);
mbed_official 0:51ac1d130fd4 118 }
mbed_official 0:51ac1d130fd4 119 #endif /* LWIP_ICMP */
mbed_official 0:51ac1d130fd4 120 pbuf_free(p);
mbed_official 0:51ac1d130fd4 121 return;
mbed_official 0:51ac1d130fd4 122 }
mbed_official 0:51ac1d130fd4 123
mbed_official 0:51ac1d130fd4 124 /* Incremental update of the IP checksum. */
mbed_official 0:51ac1d130fd4 125 /* if (iphdr->chksum >= htons(0xffff - 0x100)) {
mbed_official 0:51ac1d130fd4 126 iphdr->chksum += htons(0x100) + 1;
mbed_official 0:51ac1d130fd4 127 } else {
mbed_official 0:51ac1d130fd4 128 iphdr->chksum += htons(0x100);
mbed_official 0:51ac1d130fd4 129 }*/
mbed_official 0:51ac1d130fd4 130
mbed_official 0:51ac1d130fd4 131
mbed_official 0:51ac1d130fd4 132 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to "));
mbed_official 0:51ac1d130fd4 133 #if IP_DEBUG
mbed_official 0:51ac1d130fd4 134 ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
mbed_official 0:51ac1d130fd4 135 #endif /* IP_DEBUG */
mbed_official 0:51ac1d130fd4 136 LWIP_DEBUGF(IP_DEBUG, ("\n"));
mbed_official 0:51ac1d130fd4 137
mbed_official 0:51ac1d130fd4 138 IP_STATS_INC(ip.fw);
mbed_official 0:51ac1d130fd4 139 IP_STATS_INC(ip.xmit);
mbed_official 0:51ac1d130fd4 140
mbed_official 0:51ac1d130fd4 141 PERF_STOP("ip_forward");
mbed_official 0:51ac1d130fd4 142
mbed_official 0:51ac1d130fd4 143 netif->output(netif, p, (struct ip_addr *)&(iphdr->dest));
mbed_official 0:51ac1d130fd4 144 }
mbed_official 0:51ac1d130fd4 145
mbed_official 0:51ac1d130fd4 146 /* ip_input:
mbed_official 0:51ac1d130fd4 147 *
mbed_official 0:51ac1d130fd4 148 * This function is called by the network interface device driver when an IP packet is
mbed_official 0:51ac1d130fd4 149 * received. The function does the basic checks of the IP header such as packet size
mbed_official 0:51ac1d130fd4 150 * being at least larger than the header size etc. If the packet was not destined for
mbed_official 0:51ac1d130fd4 151 * us, the packet is forwarded (using ip_forward). The IP checksum is always checked.
mbed_official 0:51ac1d130fd4 152 *
mbed_official 0:51ac1d130fd4 153 * Finally, the packet is sent to the upper layer protocol input function.
mbed_official 0:51ac1d130fd4 154 */
mbed_official 0:51ac1d130fd4 155
mbed_official 0:51ac1d130fd4 156 void
mbed_official 0:51ac1d130fd4 157 ip_input(struct pbuf *p, struct netif *inp) {
mbed_official 0:51ac1d130fd4 158 struct ip_hdr *iphdr;
mbed_official 0:51ac1d130fd4 159 struct netif *netif;
mbed_official 0:51ac1d130fd4 160
mbed_official 0:51ac1d130fd4 161
mbed_official 0:51ac1d130fd4 162 PERF_START;
mbed_official 0:51ac1d130fd4 163
mbed_official 0:51ac1d130fd4 164 #if IP_DEBUG
mbed_official 0:51ac1d130fd4 165 ip_debug_print(p);
mbed_official 0:51ac1d130fd4 166 #endif /* IP_DEBUG */
mbed_official 0:51ac1d130fd4 167
mbed_official 0:51ac1d130fd4 168
mbed_official 0:51ac1d130fd4 169 IP_STATS_INC(ip.recv);
mbed_official 0:51ac1d130fd4 170
mbed_official 0:51ac1d130fd4 171 /* identify the IP header */
mbed_official 0:51ac1d130fd4 172 iphdr = p->payload;
mbed_official 0:51ac1d130fd4 173
mbed_official 0:51ac1d130fd4 174
mbed_official 0:51ac1d130fd4 175 if (iphdr->v != 6) {
mbed_official 0:51ac1d130fd4 176 LWIP_DEBUGF(IP_DEBUG, ("IP packet dropped due to bad version number\n"));
mbed_official 0:51ac1d130fd4 177 #if IP_DEBUG
mbed_official 0:51ac1d130fd4 178 ip_debug_print(p);
mbed_official 0:51ac1d130fd4 179 #endif /* IP_DEBUG */
mbed_official 0:51ac1d130fd4 180 pbuf_free(p);
mbed_official 0:51ac1d130fd4 181 IP_STATS_INC(ip.err);
mbed_official 0:51ac1d130fd4 182 IP_STATS_INC(ip.drop);
mbed_official 0:51ac1d130fd4 183 return;
mbed_official 0:51ac1d130fd4 184 }
mbed_official 0:51ac1d130fd4 185
mbed_official 0:51ac1d130fd4 186 /* is this packet for us? */
mbed_official 0:51ac1d130fd4 187 for(netif = netif_list; netif != NULL; netif = netif->next) {
mbed_official 0:51ac1d130fd4 188 #if IP_DEBUG
mbed_official 0:51ac1d130fd4 189 LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest "));
mbed_official 0:51ac1d130fd4 190 ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
mbed_official 0:51ac1d130fd4 191 LWIP_DEBUGF(IP_DEBUG, ("netif->ip_addr "));
mbed_official 0:51ac1d130fd4 192 ip_addr_debug_print(IP_DEBUG, ((struct ip_addr *)&(iphdr->dest)));
mbed_official 0:51ac1d130fd4 193 LWIP_DEBUGF(IP_DEBUG, ("\n"));
mbed_official 0:51ac1d130fd4 194 #endif /* IP_DEBUG */
mbed_official 0:51ac1d130fd4 195 if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr))) {
mbed_official 0:51ac1d130fd4 196 break;
mbed_official 0:51ac1d130fd4 197 }
mbed_official 0:51ac1d130fd4 198 }
mbed_official 0:51ac1d130fd4 199
mbed_official 0:51ac1d130fd4 200
mbed_official 0:51ac1d130fd4 201 if (netif == NULL) {
mbed_official 0:51ac1d130fd4 202 /* packet not for us, route or discard */
mbed_official 0:51ac1d130fd4 203 #if IP_FORWARD
mbed_official 0:51ac1d130fd4 204 ip_forward(p, iphdr);
mbed_official 0:51ac1d130fd4 205 #endif
mbed_official 0:51ac1d130fd4 206 pbuf_free(p);
mbed_official 0:51ac1d130fd4 207 return;
mbed_official 0:51ac1d130fd4 208 }
mbed_official 0:51ac1d130fd4 209
mbed_official 0:51ac1d130fd4 210 pbuf_realloc(p, IP_HLEN + ntohs(iphdr->len));
mbed_official 0:51ac1d130fd4 211
mbed_official 0:51ac1d130fd4 212 /* send to upper layers */
mbed_official 0:51ac1d130fd4 213 #if IP_DEBUG
mbed_official 0:51ac1d130fd4 214 /* LWIP_DEBUGF("ip_input: \n");
mbed_official 0:51ac1d130fd4 215 ip_debug_print(p);
mbed_official 0:51ac1d130fd4 216 LWIP_DEBUGF("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len);*/
mbed_official 0:51ac1d130fd4 217 #endif /* IP_DEBUG */
mbed_official 0:51ac1d130fd4 218
mbed_official 0:51ac1d130fd4 219 if(pbuf_header(p, -IP_HLEN)) {
mbed_official 0:51ac1d130fd4 220 LWIP_ASSERT("Can't move over header in packet", 0);
mbed_official 0:51ac1d130fd4 221 return;
mbed_official 0:51ac1d130fd4 222 }
mbed_official 0:51ac1d130fd4 223
mbed_official 0:51ac1d130fd4 224 switch (iphdr->nexthdr) {
mbed_official 0:51ac1d130fd4 225 case IP_PROTO_UDP:
mbed_official 0:51ac1d130fd4 226 udp_input(p, inp);
mbed_official 0:51ac1d130fd4 227 break;
mbed_official 0:51ac1d130fd4 228 case IP_PROTO_TCP:
mbed_official 0:51ac1d130fd4 229 tcp_input(p, inp);
mbed_official 0:51ac1d130fd4 230 break;
mbed_official 0:51ac1d130fd4 231 #if LWIP_ICMP
mbed_official 0:51ac1d130fd4 232 case IP_PROTO_ICMP:
mbed_official 0:51ac1d130fd4 233 icmp_input(p, inp);
mbed_official 0:51ac1d130fd4 234 break;
mbed_official 0:51ac1d130fd4 235 #endif /* LWIP_ICMP */
mbed_official 0:51ac1d130fd4 236 default:
mbed_official 0:51ac1d130fd4 237 #if LWIP_ICMP
mbed_official 0:51ac1d130fd4 238 /* send ICMP destination protocol unreachable */
mbed_official 0:51ac1d130fd4 239 icmp_dest_unreach(p, ICMP_DUR_PROTO);
mbed_official 0:51ac1d130fd4 240 #endif /* LWIP_ICMP */
mbed_official 0:51ac1d130fd4 241 pbuf_free(p);
mbed_official 0:51ac1d130fd4 242 LWIP_DEBUGF(IP_DEBUG, ("Unsupported transport protocol %"U16_F"\n",
mbed_official 0:51ac1d130fd4 243 iphdr->nexthdr));
mbed_official 0:51ac1d130fd4 244
mbed_official 0:51ac1d130fd4 245 IP_STATS_INC(ip.proterr);
mbed_official 0:51ac1d130fd4 246 IP_STATS_INC(ip.drop);
mbed_official 0:51ac1d130fd4 247 }
mbed_official 0:51ac1d130fd4 248 PERF_STOP("ip_input");
mbed_official 0:51ac1d130fd4 249 }
mbed_official 0:51ac1d130fd4 250
mbed_official 0:51ac1d130fd4 251
mbed_official 0:51ac1d130fd4 252 /* ip_output_if:
mbed_official 0:51ac1d130fd4 253 *
mbed_official 0:51ac1d130fd4 254 * Sends an IP packet on a network interface. This function constructs the IP header
mbed_official 0:51ac1d130fd4 255 * and calculates the IP header checksum. If the source IP address is NULL,
mbed_official 0:51ac1d130fd4 256 * the IP address of the outgoing network interface is filled in as source address.
mbed_official 0:51ac1d130fd4 257 */
mbed_official 0:51ac1d130fd4 258
mbed_official 0:51ac1d130fd4 259 err_t
mbed_official 0:51ac1d130fd4 260 ip_output_if (struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
mbed_official 0:51ac1d130fd4 261 u8_t ttl,
mbed_official 0:51ac1d130fd4 262 u8_t proto, struct netif *netif)
mbed_official 0:51ac1d130fd4 263 {
mbed_official 0:51ac1d130fd4 264 struct ip_hdr *iphdr;
mbed_official 0:51ac1d130fd4 265
mbed_official 0:51ac1d130fd4 266 PERF_START;
mbed_official 0:51ac1d130fd4 267
mbed_official 0:51ac1d130fd4 268 LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len));
mbed_official 0:51ac1d130fd4 269 if (pbuf_header(p, IP_HLEN)) {
mbed_official 0:51ac1d130fd4 270 LWIP_DEBUGF(IP_DEBUG, ("ip_output: not enough room for IP header in pbuf\n"));
mbed_official 0:51ac1d130fd4 271 IP_STATS_INC(ip.err);
mbed_official 0:51ac1d130fd4 272
mbed_official 0:51ac1d130fd4 273 return ERR_BUF;
mbed_official 0:51ac1d130fd4 274 }
mbed_official 0:51ac1d130fd4 275 LWIP_DEBUGF(IP_DEBUG, ("len %"U16_F" tot_len %"U16_F"\n", p->len, p->tot_len));
mbed_official 0:51ac1d130fd4 276
mbed_official 0:51ac1d130fd4 277 iphdr = p->payload;
mbed_official 0:51ac1d130fd4 278
mbed_official 0:51ac1d130fd4 279
mbed_official 0:51ac1d130fd4 280 if (dest != IP_HDRINCL) {
mbed_official 0:51ac1d130fd4 281 LWIP_DEBUGF(IP_DEBUG, ("!IP_HDRLINCL\n"));
mbed_official 0:51ac1d130fd4 282 iphdr->hoplim = ttl;
mbed_official 0:51ac1d130fd4 283 iphdr->nexthdr = proto;
mbed_official 0:51ac1d130fd4 284 iphdr->len = htons(p->tot_len - IP_HLEN);
mbed_official 0:51ac1d130fd4 285 ip_addr_set(&(iphdr->dest), dest);
mbed_official 0:51ac1d130fd4 286
mbed_official 0:51ac1d130fd4 287 iphdr->v = 6;
mbed_official 0:51ac1d130fd4 288
mbed_official 0:51ac1d130fd4 289 if (ip_addr_isany(src)) {
mbed_official 0:51ac1d130fd4 290 ip_addr_set(&(iphdr->src), &(netif->ip_addr));
mbed_official 0:51ac1d130fd4 291 } else {
mbed_official 0:51ac1d130fd4 292 ip_addr_set(&(iphdr->src), src);
mbed_official 0:51ac1d130fd4 293 }
mbed_official 0:51ac1d130fd4 294
mbed_official 0:51ac1d130fd4 295 } else {
mbed_official 0:51ac1d130fd4 296 dest = &(iphdr->dest);
mbed_official 0:51ac1d130fd4 297 }
mbed_official 0:51ac1d130fd4 298
mbed_official 0:51ac1d130fd4 299 IP_STATS_INC(ip.xmit);
mbed_official 0:51ac1d130fd4 300
mbed_official 0:51ac1d130fd4 301 LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c (len %"U16_F")\n", netif->name[0], netif->name[1], p->tot_len));
mbed_official 0:51ac1d130fd4 302 #if IP_DEBUG
mbed_official 0:51ac1d130fd4 303 ip_debug_print(p);
mbed_official 0:51ac1d130fd4 304 #endif /* IP_DEBUG */
mbed_official 0:51ac1d130fd4 305
mbed_official 0:51ac1d130fd4 306 PERF_STOP("ip_output_if");
mbed_official 0:51ac1d130fd4 307 return netif->output(netif, p, dest);
mbed_official 0:51ac1d130fd4 308 }
mbed_official 0:51ac1d130fd4 309
mbed_official 0:51ac1d130fd4 310 /* ip_output:
mbed_official 0:51ac1d130fd4 311 *
mbed_official 0:51ac1d130fd4 312 * Simple interface to ip_output_if. It finds the outgoing network interface and
mbed_official 0:51ac1d130fd4 313 * calls upon ip_output_if to do the actual work.
mbed_official 0:51ac1d130fd4 314 */
mbed_official 0:51ac1d130fd4 315
mbed_official 0:51ac1d130fd4 316 err_t
mbed_official 0:51ac1d130fd4 317 ip_output(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
mbed_official 0:51ac1d130fd4 318 u8_t ttl, u8_t proto)
mbed_official 0:51ac1d130fd4 319 {
mbed_official 0:51ac1d130fd4 320 struct netif *netif;
mbed_official 0:51ac1d130fd4 321 if ((netif = ip_route(dest)) == NULL) {
mbed_official 0:51ac1d130fd4 322 LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));
mbed_official 0:51ac1d130fd4 323 IP_STATS_INC(ip.rterr);
mbed_official 0:51ac1d130fd4 324 return ERR_RTE;
mbed_official 0:51ac1d130fd4 325 }
mbed_official 0:51ac1d130fd4 326
mbed_official 0:51ac1d130fd4 327 return ip_output_if (p, src, dest, ttl, proto, netif);
mbed_official 0:51ac1d130fd4 328 }
mbed_official 0:51ac1d130fd4 329
mbed_official 0:51ac1d130fd4 330 #if LWIP_NETIF_HWADDRHINT
mbed_official 0:51ac1d130fd4 331 err_t
mbed_official 0:51ac1d130fd4 332 ip_output_hinted(struct pbuf *p, struct ip_addr *src, struct ip_addr *dest,
mbed_official 0:51ac1d130fd4 333 u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint)
mbed_official 0:51ac1d130fd4 334 {
mbed_official 0:51ac1d130fd4 335 struct netif *netif;
mbed_official 0:51ac1d130fd4 336 err_t err;
mbed_official 0:51ac1d130fd4 337
mbed_official 0:51ac1d130fd4 338 if ((netif = ip_route(dest)) == NULL) {
mbed_official 0:51ac1d130fd4 339 LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to 0x%"X32_F"\n", dest->addr));
mbed_official 0:51ac1d130fd4 340 IP_STATS_INC(ip.rterr);
mbed_official 0:51ac1d130fd4 341 return ERR_RTE;
mbed_official 0:51ac1d130fd4 342 }
mbed_official 0:51ac1d130fd4 343
mbed_official 0:51ac1d130fd4 344 netif->addr_hint = addr_hint;
mbed_official 0:51ac1d130fd4 345 err = ip_output_if(p, src, dest, ttl, tos, proto, netif);
mbed_official 0:51ac1d130fd4 346 netif->addr_hint = NULL;
mbed_official 0:51ac1d130fd4 347
mbed_official 0:51ac1d130fd4 348 return err;
mbed_official 0:51ac1d130fd4 349 }
mbed_official 0:51ac1d130fd4 350 #endif /* LWIP_NETIF_HWADDRHINT*/
mbed_official 0:51ac1d130fd4 351
mbed_official 0:51ac1d130fd4 352 #if IP_DEBUG
mbed_official 0:51ac1d130fd4 353 void
mbed_official 0:51ac1d130fd4 354 ip_debug_print(struct pbuf *p)
mbed_official 0:51ac1d130fd4 355 {
mbed_official 0:51ac1d130fd4 356 struct ip_hdr *iphdr = p->payload;
mbed_official 0:51ac1d130fd4 357
mbed_official 0:51ac1d130fd4 358 LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
mbed_official 0:51ac1d130fd4 359 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
mbed_official 0:51ac1d130fd4 360 LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" | %"X16_F"%"X16_F" | %"X16_F"%"X16_F" | (v, traffic class, flow label)\n",
mbed_official 0:51ac1d130fd4 361 iphdr->v,
mbed_official 0:51ac1d130fd4 362 iphdr->tclass1, iphdr->tclass2,
mbed_official 0:51ac1d130fd4 363 iphdr->flow1, iphdr->flow2));
mbed_official 0:51ac1d130fd4 364 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
mbed_official 0:51ac1d130fd4 365 LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" | %2"U16_F" | %2"U16_F" | (len, nexthdr, hoplim)\n",
mbed_official 0:51ac1d130fd4 366 ntohs(iphdr->len),
mbed_official 0:51ac1d130fd4 367 iphdr->nexthdr,
mbed_official 0:51ac1d130fd4 368 iphdr->hoplim));
mbed_official 0:51ac1d130fd4 369 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
mbed_official 0:51ac1d130fd4 370 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n",
mbed_official 0:51ac1d130fd4 371 (ntohl(iphdr->src.addr[0]) >> 16) & 0xffff,
mbed_official 0:51ac1d130fd4 372 ntohl(iphdr->src.addr[0]) & 0xffff));
mbed_official 0:51ac1d130fd4 373 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n",
mbed_official 0:51ac1d130fd4 374 (ntohl(iphdr->src.addr[1]) >> 16) & 0xffff,
mbed_official 0:51ac1d130fd4 375 ntohl(iphdr->src.addr[1]) & 0xffff));
mbed_official 0:51ac1d130fd4 376 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n",
mbed_official 0:51ac1d130fd4 377 (ntohl(iphdr->src.addr[2]) >> 16) & 0xffff,
mbed_official 0:51ac1d130fd4 378 ntohl(iphdr->src.addr[2]) & 0xffff));
mbed_official 0:51ac1d130fd4 379 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (src)\n",
mbed_official 0:51ac1d130fd4 380 (ntohl(iphdr->src.addr[3]) >> 16) & 0xffff,
mbed_official 0:51ac1d130fd4 381 ntohl(iphdr->src.addr[3]) & 0xffff));
mbed_official 0:51ac1d130fd4 382 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
mbed_official 0:51ac1d130fd4 383 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n",
mbed_official 0:51ac1d130fd4 384 (ntohl(iphdr->dest.addr[0]) >> 16) & 0xffff,
mbed_official 0:51ac1d130fd4 385 ntohl(iphdr->dest.addr[0]) & 0xffff));
mbed_official 0:51ac1d130fd4 386 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n",
mbed_official 0:51ac1d130fd4 387 (ntohl(iphdr->dest.addr[1]) >> 16) & 0xffff,
mbed_official 0:51ac1d130fd4 388 ntohl(iphdr->dest.addr[1]) & 0xffff));
mbed_official 0:51ac1d130fd4 389 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n",
mbed_official 0:51ac1d130fd4 390 (ntohl(iphdr->dest.addr[2]) >> 16) & 0xffff,
mbed_official 0:51ac1d130fd4 391 ntohl(iphdr->dest.addr[2]) & 0xffff));
mbed_official 0:51ac1d130fd4 392 LWIP_DEBUGF(IP_DEBUG, ("| %4"X32_F" | %4"X32_F" | (dest)\n",
mbed_official 0:51ac1d130fd4 393 (ntohl(iphdr->dest.addr[3]) >> 16) & 0xffff,
mbed_official 0:51ac1d130fd4 394 ntohl(iphdr->dest.addr[3]) & 0xffff));
mbed_official 0:51ac1d130fd4 395 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
mbed_official 0:51ac1d130fd4 396 }
mbed_official 0:51ac1d130fd4 397 #endif /* IP_DEBUG */