1/** 2 * @file 3 * This is the IPv4 layer implementation for incoming and outgoing IP traffic. 4 * 5 * @see ip_frag.c 6 * 7 */ 8 9/* 10 * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without modification, 14 * are permitted provided that the following conditions are met: 15 * 16 * 1. Redistributions of source code must retain the above copyright notice, 17 * this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright notice, 19 * this list of conditions and the following disclaimer in the documentation 20 * and/or other materials provided with the distribution. 21 * 3. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 27 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 29 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 * OF SUCH DAMAGE. 34 * 35 * This file is part of the lwIP TCP/IP stack. 36 * 37 * Author: Adam Dunkels <adam@sics.se> 38 * 39 */ 40 41#include "lwip/opt.h" 42#include "lwip/ip.h" 43#include "lwip/def.h" 44#include "lwip/mem.h" 45#include "lwip/ip_frag.h" 46#include "lwip/inet.h" 47#include "lwip/inet_chksum.h" 48#include "lwip/netif.h" 49#include "lwip/icmp.h" 50#include "lwip/igmp.h" 51#include "lwip/raw.h" 52#include "lwip/udp.h" 53#include "lwip/tcp.h" 54#include "lwip/snmp.h" 55#include "lwip/dhcp.h" 56#include "lwip/stats.h" 57#include "arch/perf.h" 58#include "lwip/init.h" 59 60#include <string.h> 61 62/** 63 * The interface that provided the packet for the current callback 64 * invocation. 65 */ 66static struct netif *current_netif; 67 68/** 69 * Header of the input packet currently being processed. 70 */ 71static const struct ip_hdr *current_header; 72 73/** 74 * Get the interface that received the current packet. 75 * 76 * This function must only be called from a receive callback (udp_recv, 77 * raw_recv, tcp_accept). It will return NULL otherwise. 78 * 79 * @param pcb Pointer to the pcb receiving a packet. 80 */ 81struct netif *ip_current_netif(void) 82{ 83 return current_netif; 84} 85 86/** 87 * Get the IP header of the current packet. 88 * 89 * This function must only be called from a receive callback (udp_recv, 90 * raw_recv, tcp_accept). It will return NULL otherwise. 91 * 92 * @param pcb Pointer to the pcb receiving a packet. 93 */ 94const struct ip_hdr *ip_current_header(void) 95{ 96 return current_header; 97} 98 99/** 100 * Finds the appropriate network interface for a given IP address. It 101 * searches the list of network interfaces linearly. A match is found 102 * if the masked IP address of the network interface equals the masked 103 * IP address given to the function. 104 * 105 * @param dest the destination IP address for which to find the route 106 * @return the netif on which to send to reach dest 107 */ 108struct netif *ip_route(struct ip_addr *dest) 109{ 110 struct netif *netif; 111 112 /* iterate through netifs */ 113 for (netif = netif_list; netif != NULL; netif = netif->next) { 114 /* network mask matches? */ 115 if (netif_is_up(netif)) { 116 if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) { 117 /* return netif on which to forward IP packet */ 118 return netif; 119 } 120 } 121 } 122 if ((netif_default == NULL) || (!netif_is_up(netif_default))) { 123 LWIP_DEBUGF(IP_DEBUG | 2, 124 ("ip_route: No route to 0x%" X32_F "\n", dest->addr)); 125 IP_STATS_INC(ip.rterr); 126 snmp_inc_ipoutnoroutes(); 127 return NULL; 128 } 129 /* no matching netif found, use default netif */ 130 return netif_default; 131} 132 133#if IP_FORWARD 134/** 135 * Forwards an IP packet. It finds an appropriate route for the 136 * packet, decrements the TTL value of the packet, adjusts the 137 * checksum and outputs the packet on the appropriate interface. 138 * 139 * @param p the packet to forward (p->payload points to IP header) 140 * @param iphdr the IP header of the input packet 141 * @param inp the netif on which this packet was received 142 * @return the netif on which the packet was sent (NULL if it wasn't sent) 143 */ 144static struct netif *ip_forward(struct pbuf *p, struct ip_hdr *iphdr, 145 struct netif *inp) 146{ 147 struct netif *netif; 148 149 PERF_START; 150 /* Find network interface where to forward this IP packet to. */ 151 netif = ip_route((struct ip_addr *) &(iphdr->dest)); 152 if (netif == NULL) { 153 LWIP_DEBUGF(IP_DEBUG, 154 ("ip_forward: no forwarding route for 0x%" X32_F " found\n", 155 iphdr->dest.addr)); 156 snmp_inc_ipoutnoroutes(); 157 return (struct netif *) NULL; 158 } 159 /* Do not forward packets onto the same network interface on which 160 * they arrived. */ 161 if (netif == inp) { 162 LWIP_DEBUGF(IP_DEBUG, 163 ("ip_forward: not bouncing packets back on incoming interface.\n")); 164 snmp_inc_ipoutnoroutes(); 165 return (struct netif *) NULL; 166 } 167 168 /* decrement TTL */ 169 IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); 170 /* send ICMP if TTL == 0 */ 171 if (IPH_TTL(iphdr) == 0) { 172 snmp_inc_ipinhdrerrors(); 173#if LWIP_ICMP 174 /* Don't send ICMP messages in response to ICMP messages */ 175 if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { 176 icmp_time_exceeded(p, ICMP_TE_TTL); 177 } 178#endif /* LWIP_ICMP */ 179 return (struct netif *) NULL; 180 } 181 182 /* Incrementally update the IP checksum. */ 183 if (IPH_CHKSUM(iphdr) >= htons(0xffff - 0x100)) { 184 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100) + 1); 185 } else { 186 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + htons(0x100)); 187 } 188 189 LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to 0x%" X32_F "\n", 190 iphdr->dest.addr)); 191 192 IP_STATS_INC(ip.fw); 193 IP_STATS_INC(ip.xmit); 194 snmp_inc_ipforwdatagrams(); 195 196 PERF_STOP("ip_forward"); 197 /* transmit pbuf on chosen interface */ 198 netif->output(netif, p, (struct ip_addr *) &(iphdr->dest)); 199 return netif; 200} 201#endif /* IP_FORWARD */ 202 203/** 204 * This function is called by the network interface device driver when 205 * an IP packet is received. The function does the basic checks of the 206 * IP header such as packet size being at least larger than the header 207 * size etc. If the packet was not destined for us, the packet is 208 * forwarded (using ip_forward). The IP checksum is always checked. 209 * 210 * Finally, the packet is sent to the upper layer protocol input function. 211 * 212 * @param p the received IP packet (p->payload points to IP header) 213 * @param inp the netif on which this packet was received 214 * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't 215 * processed, but currently always returns ERR_OK) 216 */ 217err_t ip_input(struct pbuf * p, struct netif * inp) 218{ 219 struct ip_hdr *iphdr; 220 struct netif *netif; 221 u16_t iphdr_hlen; 222 u16_t iphdr_len; 223 224#if LWIP_DHCP 225 int check_ip_src = 1; 226#endif /* LWIP_DHCP */ 227 228 IP_STATS_INC(ip.recv); 229 snmp_inc_ipinreceives(); 230 231 /* identify the IP header */ 232 iphdr = p->payload; 233 if (IPH_V(iphdr) != 4) { 234 LWIP_DEBUGF(IP_DEBUG | 1, 235 ("IP packet dropped due to bad version number %" U16_F "\n", 236 IPH_V(iphdr))); 237 ip_debug_print(p); 238 pbuf_free(p); 239 IP_STATS_INC(ip.err); 240 IP_STATS_INC(ip.drop); 241 snmp_inc_ipinhdrerrors(); 242 return ERR_OK; 243 } 244 245 /* obtain IP header length in number of 32-bit words */ 246 iphdr_hlen = IPH_HL(iphdr); 247 /* calculate IP header length in bytes */ 248 iphdr_hlen *= 4; 249 /* obtain ip length in bytes */ 250 iphdr_len = ntohs(IPH_LEN(iphdr)); 251 252 /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ 253 if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) { 254 if (iphdr_hlen > p->len) 255 LWIP_DEBUGF(IP_DEBUG | 2, 256 ("IP header (len %" U16_F 257 ") does not fit in first pbuf (len %" U16_F 258 "), IP packet dropped.\n", iphdr_hlen, p->len)); 259 if (iphdr_len > p->tot_len) 260 LWIP_DEBUGF(IP_DEBUG | 2, 261 ("IP (len %" U16_F ") is longer than pbuf (len %" U16_F 262 "), " "IP packet dropped.\n", iphdr_len, p->tot_len)); 263 /* free (drop) packet pbufs */ 264 pbuf_free(p); 265 IP_STATS_INC(ip.lenerr); 266 IP_STATS_INC(ip.drop); 267 snmp_inc_ipindiscards(); 268 return ERR_OK; 269 } 270 271 /* verify checksum */ 272#if CHECKSUM_CHECK_IP 273 int hwcxs_good = ((p->nicflags & NETIF_RXFLAG_IPCHECKSUM) && 274 (p->nicflags & NETIF_RXFLAG_IPCHECKSUM_GOOD)); 275 if (!hwcxs_good && inet_chksum(iphdr, iphdr_hlen) != 0) { 276 277 LWIP_DEBUGF(IP_DEBUG | 2, 278 ("Checksum (0x%" X16_F ") failed, IP packet dropped.\n", 279 inet_chksum(iphdr, iphdr_hlen))); 280 ip_debug_print(p); 281 pbuf_free(p); 282 IP_STATS_INC(ip.chkerr); 283 IP_STATS_INC(ip.drop); 284 snmp_inc_ipinhdrerrors(); 285 return ERR_OK; 286 } 287#endif 288 289 /* Trim pbuf. This should have been done at the netif layer, 290 * but we'll do it anyway just to be sure that its done. */ 291 pbuf_realloc(p, iphdr_len); 292 293 294 /* match packet against an interface, i.e. is this packet for us? */ 295#if LWIP_IGMP 296 if (ip_addr_ismulticast(&(iphdr->dest))) { 297 if ((inp->flags & NETIF_FLAG_IGMP) 298 && (igmp_lookfor_group(inp, &(iphdr->dest)))) { 299 netif = inp; 300 } else { 301 netif = NULL; 302 } 303 } else 304#endif /* LWIP_IGMP */ 305 { 306 /* start trying with inp. if that's not acceptable, start walking the 307 list of configured netifs. 308 'first' is used as a boolean to mark whether we started walking the list */ 309 int first = 1; 310 311 netif = inp; 312 do { 313 LWIP_DEBUGF(IP_DEBUG, 314 ("ip_input: iphdr->dest 0x%" X32_F " netif->ip_addr 0x%" 315 X32_F " (0x%" X32_F ", 0x%" X32_F ", 0x%" X32_F ")\n", 316 iphdr->dest.addr, netif->ip_addr.addr, 317 iphdr->dest.addr & netif->netmask.addr, 318 netif->ip_addr.addr & netif->netmask.addr, 319 iphdr->dest.addr & ~(netif->netmask.addr))); 320 321 /* interface is up and configured? */ 322 if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) { 323 /* unicast to this interface address? */ 324 if (ip_addr_cmp(&(iphdr->dest), &(netif->ip_addr)) || 325 /* or broadcast on this interface network address? */ 326 ip_addr_isbroadcast(&(iphdr->dest), netif)) { 327 LWIP_DEBUGF(IP_DEBUG, 328 ("ip_input: packet accepted on interface %c%c\n", 329 netif->name[0], netif->name[1])); 330 /* break out of for loop */ 331 break; 332 } 333 } 334 if (first) { 335 first = 0; 336 netif = netif_list; 337 } else { 338 netif = netif->next; 339 } 340 if (netif == inp) { 341 netif = netif->next; 342 } 343 } while (netif != NULL); 344 } 345 346#if LWIP_DHCP 347 /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed 348 * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. 349 * According to RFC 1542 section 3.1.1, referred by RFC 2131). 350 */ 351 if (netif == NULL) { 352 /* remote port is DHCP server? */ 353 if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { 354 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, 355 ("ip_input: UDP packet to DHCP client port %" U16_F 356 "\n", 357 ntohs(((struct udp_hdr *) ((u8_t *) iphdr + 358 iphdr_hlen))->dest))); 359 if (ntohs(((struct udp_hdr *) ((u8_t *) iphdr + iphdr_hlen))->dest) 360 == DHCP_CLIENT_PORT) { 361 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, 362 ("ip_input: DHCP packet accepted.\n")); 363 netif = inp; 364 check_ip_src = 0; 365 } 366 } 367 } 368#endif /* LWIP_DHCP */ 369 370 /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ 371#if LWIP_DHCP 372 if (check_ip_src) 373#endif /* LWIP_DHCP */ 374 { 375 if ((ip_addr_isbroadcast(&(iphdr->src), inp)) || 376 (ip_addr_ismulticast(&(iphdr->src)))) { 377 /* packet source is not valid */ 378 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, 379 ("ip_input: packet source is not valid.\n")); 380 /* free (drop) packet pbufs */ 381 pbuf_free(p); 382 IP_STATS_INC(ip.drop); 383 snmp_inc_ipinaddrerrors(); 384 snmp_inc_ipindiscards(); 385 return ERR_OK; 386 } 387 } 388 389 /* packet not for us? */ 390 if (netif == NULL) { 391 /* packet not for us, route or discard */ 392 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | 1, 393 ("ip_input: packet not for us.\n")); 394#if IP_FORWARD 395 /* non-broadcast packet? */ 396 if (!ip_addr_isbroadcast(&(iphdr->dest), inp)) { 397 /* try to forward IP packet on (other) interfaces */ 398 ip_forward(p, iphdr, inp); 399 } else 400#endif /* IP_FORWARD */ 401 { 402 snmp_inc_ipinaddrerrors(); 403 snmp_inc_ipindiscards(); 404 } 405 pbuf_free(p); 406 return ERR_OK; 407 } 408 /* packet consists of multiple fragments? */ 409 if ((IPH_OFFSET(iphdr) & htons(IP_OFFMASK | IP_MF)) != 0) { 410#if IP_REASSEMBLY /* packet fragment reassembly code present? */ 411 LWIP_DEBUGF(IP_DEBUG, 412 ("IP packet is a fragment (id=0x%04" X16_F " tot_len=%" 413 U16_F " len=%" U16_F " MF=%" U16_F " offset=%" U16_F 414 "), calling ip_reass()\n", ntohs(IPH_ID(iphdr)), 415 p->tot_len, ntohs(IPH_LEN(iphdr)), 416 ! !(IPH_OFFSET(iphdr) & htons(IP_MF)), 417 (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK) * 8)); 418 /* reassemble the packet */ 419 p = ip_reass(p); 420 /* packet not fully reassembled yet? */ 421 if (p == NULL) { 422 return ERR_OK; 423 } 424 iphdr = p->payload; 425#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ 426 pbuf_free(p); 427 LWIP_DEBUGF(IP_DEBUG | 2, 428 ("IP packet dropped since it was fragmented (0x%" X16_F 429 ") (while IP_REASSEMBLY == 0).\n", 430 ntohs(IPH_OFFSET(iphdr)))); 431 IP_STATS_INC(ip.opterr); 432 IP_STATS_INC(ip.drop); 433 /* unsupported protocol feature */ 434 snmp_inc_ipinunknownprotos(); 435 return ERR_OK; 436#endif /* IP_REASSEMBLY */ 437 } 438#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ 439 440#if LWIP_IGMP 441 /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ 442 if ((iphdr_hlen > IP_HLEN && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { 443#else 444 if (iphdr_hlen > IP_HLEN) { 445#endif /* LWIP_IGMP */ 446 LWIP_DEBUGF(IP_DEBUG | 2, 447 ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); 448 pbuf_free(p); 449 IP_STATS_INC(ip.opterr); 450 IP_STATS_INC(ip.drop); 451 /* unsupported protocol feature */ 452 snmp_inc_ipinunknownprotos(); 453 return ERR_OK; 454 } 455#endif /* IP_OPTIONS_ALLOWED == 0 */ 456 457 /* send to upper layers */ 458 LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n")); 459 ip_debug_print(p); 460 LWIP_DEBUGF(IP_DEBUG, 461 ("ip_input: p->len %" U16_F " p->tot_len %" U16_F "\n", p->len, 462 p->tot_len)); 463 464 current_netif = inp; 465 current_header = iphdr; 466 467#if LWIP_RAW 468 /* raw input did not eat the packet? */ 469 if (raw_input(p, inp) == 0) 470#endif /* LWIP_RAW */ 471 { 472 473 switch (IPH_PROTO(iphdr)) { 474#if LWIP_UDP 475 case IP_PROTO_UDP: 476#if LWIP_UDPLITE 477 case IP_PROTO_UDPLITE: 478#endif /* LWIP_UDPLITE */ 479 snmp_inc_ipindelivers(); 480 udp_input(p, inp); 481 break; 482#endif /* LWIP_UDP */ 483#if LWIP_TCP 484 case IP_PROTO_TCP: 485 snmp_inc_ipindelivers(); 486 tcp_input(p, inp); 487 break; 488#endif /* LWIP_TCP */ 489#if LWIP_ICMP 490 case IP_PROTO_ICMP: 491 snmp_inc_ipindelivers(); 492 icmp_input(p, inp); 493 break; 494#endif /* LWIP_ICMP */ 495#if LWIP_IGMP 496 case IP_PROTO_IGMP: 497 igmp_input(p, inp, &(iphdr->dest)); 498 break; 499#endif /* LWIP_IGMP */ 500 default: 501#if LWIP_ICMP 502 /* send ICMP destination protocol unreachable unless is was a broadcast */ 503 if (!ip_addr_isbroadcast(&(iphdr->dest), inp) && 504 !ip_addr_ismulticast(&(iphdr->dest))) { 505 p->payload = iphdr; 506 icmp_dest_unreach(p, ICMP_DUR_PROTO); 507 } 508#endif /* LWIP_ICMP */ 509 pbuf_free(p); 510 511 LWIP_DEBUGF(IP_DEBUG | 2, 512 ("Unsupported transport protocol %" U16_F "\n", 513 IPH_PROTO(iphdr))); 514 515 IP_STATS_INC(ip.proterr); 516 IP_STATS_INC(ip.drop); 517 snmp_inc_ipinunknownprotos(); 518 } 519 } 520 521 current_netif = NULL; 522 current_header = NULL; 523 524 return ERR_OK; 525} 526 527/** 528 * Sends an IP packet on a network interface. This function constructs 529 * the IP header and calculates the IP header checksum. If the source 530 * IP address is NULL, the IP address of the outgoing network 531 * interface is filled in as source address. 532 * If the destination IP address is IP_HDRINCL, p is assumed to already 533 * include an IP header and p->payload points to it instead of the data. 534 * 535 * @param p the packet to send (p->payload points to the data, e.g. next 536 protocol header; if dest == IP_HDRINCL, p already includes an IP 537 header and p->payload points to that IP header) 538 * @param src the source IP address to send from (if src == IP_ADDR_ANY, the 539 * IP address of the netif used to send is used as source address) 540 * @param dest the destination IP address to send the packet to 541 * @param ttl the TTL value to be set in the IP header 542 * @param tos the TOS value to be set in the IP header 543 * @param proto the PROTOCOL to be set in the IP header 544 * @param netif the netif on which to send this packet 545 * @return ERR_OK if the packet was sent OK 546 * ERR_BUF if p doesn't have enough space for IP/LINK headers 547 * returns errors returned by netif->output 548 * 549 * @note ip_id: RFC791 "some host may be able to simply use 550 * unique identifiers independent of destination" 551 */ 552err_t 553ip_output_if(struct pbuf * p, struct ip_addr * src, struct ip_addr * dest, 554 u8_t ttl, u8_t tos, u8_t proto, struct netif * netif) 555{ 556#if IP_OPTIONS_SEND 557 return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); 558} 559 560/** 561 * Same as ip_output_if() but with the possibility to include IP options: 562 * 563 * @ param ip_options pointer to the IP options, copied into the IP header 564 * @ param optlen length of ip_options 565 */ 566err_t ip_output_if_opt(struct pbuf * p, struct ip_addr * src, 567 struct ip_addr * dest, u8_t ttl, u8_t tos, u8_t proto, 568 struct netif * netif, void *ip_options, u16_t optlen) 569{ 570#endif /* IP_OPTIONS_SEND */ 571 struct ip_hdr *iphdr; 572 static u16_t ip_id = 0; 573 574 snmp_inc_ipoutrequests(); 575 576 /* Should the IP header be generated or is it already included in p? */ 577 if (dest != IP_HDRINCL) { 578 u16_t ip_hlen = IP_HLEN; 579 580#if IP_OPTIONS_SEND 581 u16_t optlen_aligned = 0; 582 583 if (optlen != 0) { 584 /* round up to a multiple of 4 */ 585 optlen_aligned = ((optlen + 3) & ~3); 586 ip_hlen += optlen_aligned; 587 /* First write in the IP options */ 588 if (pbuf_header(p, optlen_aligned)) { 589 LWIP_DEBUGF(IP_DEBUG | 2, 590 ("ip_output_if_opt: not enough room for IP options in pbuf\n")); 591 IP_STATS_INC(ip.err); 592 snmp_inc_ipoutdiscards(); 593 return ERR_BUF; 594 } 595 MEMCPY(p->payload, ip_options, optlen); 596 if (optlen < optlen_aligned) { 597 /* zero the remaining bytes */ 598 memset(((char *) p->payload) + optlen, 0, 599 optlen_aligned - optlen); 600 } 601 } 602#endif /* IP_OPTIONS_SEND */ 603 /* generate IP header */ 604 if (pbuf_header(p, IP_HLEN)) { 605 LWIP_DEBUGF(IP_DEBUG | 2, 606 ("ip_output: not enough room for IP header in pbuf\n")); 607 608 IP_STATS_INC(ip.err); 609 snmp_inc_ipoutdiscards(); 610 return ERR_BUF; 611 } 612 613 iphdr = p->payload; 614 LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", 615 (p->len >= sizeof(struct ip_hdr))); 616 617 IPH_TTL_SET(iphdr, ttl); 618 IPH_PROTO_SET(iphdr, proto); 619 620 ip_addr_set(&(iphdr->dest), dest); 621 622 IPH_VHLTOS_SET(iphdr, 4, ip_hlen / 4, tos); 623 IPH_LEN_SET(iphdr, htons(p->tot_len)); 624 IPH_OFFSET_SET(iphdr, 0); 625 IPH_ID_SET(iphdr, htons(ip_id)); 626 ++ip_id; 627 628 if (ip_addr_isany(src)) { 629 ip_addr_set(&(iphdr->src), &(netif->ip_addr)); 630 } else { 631 ip_addr_set(&(iphdr->src), src); 632 } 633 634 IPH_CHKSUM_SET(iphdr, 0); 635#if CHECKSUM_GEN_IP 636 if (is_hw_feature_enabled(IPv4_CHECKSUM_HW)) { 637 p->nicflags |= NETIF_TXFLAG_IPCHECKSUM; 638 } else { 639 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); 640 } 641#endif 642 } else { 643 /* IP header already included in p */ 644 iphdr = p->payload; 645 dest = &(iphdr->dest); 646 } 647 648#if IP_FRAG 649 /* don't fragment if interface has mtu set to 0 [loopif] */ 650 if (netif->mtu && (p->tot_len > netif->mtu)) { 651 return ip_frag(p, netif, dest); 652 } 653#endif 654 655 IP_STATS_INC(ip.xmit); 656 657 LWIP_DEBUGF(IP_DEBUG, 658 ("ip_output_if: %c%c%" U16_F "\n", netif->name[0], 659 netif->name[1], netif->num)); 660 ip_debug_print(p); 661 662#if (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) 663 if (ip_addr_cmp(dest, &netif->ip_addr)) { 664 /* Packet to self, enqueue it for loopback */ 665 LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); 666 return netif_loop_output(netif, p, dest); 667 } else 668#endif /* (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) */ 669 { 670 LWIP_DEBUGF(IP_DEBUG, ("netif->output()")); 671 return netif->output(netif, p, dest); 672 } 673} 674 675/** 676 * Simple interface to ip_output_if. It finds the outgoing network 677 * interface and calls upon ip_output_if to do the actual work. 678 * 679 * @param p the packet to send (p->payload points to the data, e.g. next 680 protocol header; if dest == IP_HDRINCL, p already includes an IP 681 header and p->payload points to that IP header) 682 * @param src the source IP address to send from (if src == IP_ADDR_ANY, the 683 * IP address of the netif used to send is used as source address) 684 * @param dest the destination IP address to send the packet to 685 * @param ttl the TTL value to be set in the IP header 686 * @param tos the TOS value to be set in the IP header 687 * @param proto the PROTOCOL to be set in the IP header 688 * 689 * @return ERR_RTE if no route is found 690 * see ip_output_if() for more return values 691 */ 692err_t 693ip_output(struct pbuf * p, struct ip_addr * src, struct ip_addr * dest, 694 u8_t ttl, u8_t tos, u8_t proto) 695{ 696 struct netif *netif; 697 698 if ((netif = ip_route(dest)) == NULL) { 699 LWIP_DEBUGF(IP_DEBUG, 700 ("ip_output: No route to 0x%" X32_F "\n", dest->addr)); 701 IP_STATS_INC(ip.rterr); 702 return ERR_RTE; 703 } 704 705 return ip_output_if(p, src, dest, ttl, tos, proto, netif); 706} 707 708#if LWIP_NETIF_HWADDRHINT 709/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint 710 * before calling ip_output_if. 711 * 712 * @param p the packet to send (p->payload points to the data, e.g. next 713 protocol header; if dest == IP_HDRINCL, p already includes an IP 714 header and p->payload points to that IP header) 715 * @param src the source IP address to send from (if src == IP_ADDR_ANY, the 716 * IP address of the netif used to send is used as source address) 717 * @param dest the destination IP address to send the packet to 718 * @param ttl the TTL value to be set in the IP header 719 * @param tos the TOS value to be set in the IP header 720 * @param proto the PROTOCOL to be set in the IP header 721 * @param addr_hint address hint pointer set to netif->addr_hint before 722 * calling ip_output_if() 723 * 724 * @return ERR_RTE if no route is found 725 * see ip_output_if() for more return values 726 */ 727err_t 728ip_output_hinted(struct pbuf * p, struct ip_addr * src, struct ip_addr * dest, 729 u8_t ttl, u8_t tos, u8_t proto, u8_t * addr_hint) 730{ 731 struct netif *netif; 732 err_t err; 733 734 if ((netif = ip_route(dest)) == NULL) { 735 LWIP_DEBUGF(IP_DEBUG, 736 ("ip_output: No route to 0x%" X32_F "\n", dest->addr)); 737 IP_STATS_INC(ip.rterr); 738 return ERR_RTE; 739 } 740 741 netif->addr_hint = addr_hint; 742 err = ip_output_if(p, src, dest, ttl, tos, proto, netif); 743 netif->addr_hint = NULL; 744 745 return err; 746} 747#endif /* LWIP_NETIF_HWADDRHINT */ 748 749#if IP_DEBUG 750/* Print an IP header by using LWIP_DEBUGF 751 * @param p an IP packet, p->payload pointing to the IP header 752 */ 753void ip_debug_print(struct pbuf *p) 754{ 755 struct ip_hdr *iphdr = p->payload; 756 u8_t *payload; 757 758 payload = (u8_t *) iphdr + IP_HLEN; 759 760 LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); 761 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 762 LWIP_DEBUGF(IP_DEBUG, 763 ("|%2" S16_F " |%2" S16_F " | 0x%02" X16_F " | %5" U16_F 764 " | (v, hl, tos, len)\n", IPH_V(iphdr), IPH_HL(iphdr), 765 IPH_TOS(iphdr), ntohs(IPH_LEN(iphdr)))); 766 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 767 LWIP_DEBUGF(IP_DEBUG, 768 ("| %5" U16_F " |%" U16_F "%" U16_F "%" U16_F "| %4" 769 U16_F " | (id, flags, offset)\n", ntohs(IPH_ID(iphdr)), 770 ntohs(IPH_OFFSET(iphdr)) >> 15 & 1, 771 ntohs(IPH_OFFSET(iphdr)) >> 14 & 1, 772 ntohs(IPH_OFFSET(iphdr)) >> 13 & 1, 773 ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)); 774 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 775 LWIP_DEBUGF(IP_DEBUG, 776 ("| %3" U16_F " | %3" U16_F " | 0x%04" X16_F 777 " | (ttl, proto, chksum)\n", IPH_TTL(iphdr), 778 IPH_PROTO(iphdr), ntohs(IPH_CHKSUM(iphdr)))); 779 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 780 LWIP_DEBUGF(IP_DEBUG, 781 ("| %3" U16_F " | %3" U16_F " | %3" U16_F " | %3" U16_F 782 " | (src)\n", ip4_addr1(&iphdr->src), ip4_addr2(&iphdr->src), 783 ip4_addr3(&iphdr->src), ip4_addr4(&iphdr->src))); 784 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 785 LWIP_DEBUGF(IP_DEBUG, 786 ("| %3" U16_F " | %3" U16_F " | %3" U16_F " | %3" U16_F 787 " | (dest)\n", ip4_addr1(&iphdr->dest), 788 ip4_addr2(&iphdr->dest), ip4_addr3(&iphdr->dest), 789 ip4_addr4(&iphdr->dest))); 790 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); 791} 792#endif /* IP_DEBUG */ 793