The Pedigree Project 0.1
ip4.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
28/*
29 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
30 * All rights reserved.
31 *
32 * Redistribution and use in source and binary forms, with or without modification,
33 * are permitted provided that the following conditions are met:
34 *
35 * 1. Redistributions of source code must retain the above copyright notice,
36 * this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following disclaimer in the documentation
39 * and/or other materials provided with the distribution.
40 * 3. The name of the author may not be used to endorse or promote products
41 * derived from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
44 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
45 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
46 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
47 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
48 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
49 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
50 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
51 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
52 * OF SUCH DAMAGE.
53 *
54 * This file is part of the lwIP TCP/IP stack.
55 *
56 * Author: Adam Dunkels <adam@sics.se>
57 *
58 */
59
60#include "lwip/opt.h"
61
62#if LWIP_IPV4
63
64#include "lwip/ip.h"
65#include "lwip/def.h"
66#include "lwip/mem.h"
67#include "lwip/ip4_frag.h"
68#include "lwip/inet_chksum.h"
69#include "lwip/netif.h"
70#include "lwip/icmp.h"
71#include "lwip/igmp.h"
72#include "lwip/raw.h"
73#include "lwip/udp.h"
74#include "lwip/priv/tcp_priv.h"
75#include "lwip/autoip.h"
76#include "lwip/stats.h"
77#include "lwip/prot/dhcp.h"
78
79#include <string.h>
80
81#ifdef LWIP_HOOK_FILENAME
82#include LWIP_HOOK_FILENAME
83#endif
84
87#ifndef LWIP_INLINE_IP_CHKSUM
88#if LWIP_CHECKSUM_CTRL_PER_NETIF
89#define LWIP_INLINE_IP_CHKSUM 0
90#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
91#define LWIP_INLINE_IP_CHKSUM 1
92#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
93#endif
94
95#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
96#define CHECKSUM_GEN_IP_INLINE 1
97#else
98#define CHECKSUM_GEN_IP_INLINE 0
99#endif
100
101#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT)
102#define IP_ACCEPT_LINK_LAYER_ADDRESSING 1
103
109#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT)
110/* accept DHCP client port and custom port */
111#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \
112 || (LWIP_IP_ACCEPT_UDP_PORT(port)))
113#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
114/* accept custom port only */
115#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port))
116#else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
117/* accept DHCP client port only */
118#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT))
119#endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
120
121#else /* LWIP_DHCP */
122#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0
123#endif /* LWIP_DHCP */
124
126static u16_t ip_id;
127
128#if LWIP_MULTICAST_TX_OPTIONS
130static struct netif* ip4_default_multicast_netif;
131
135void
136ip4_set_default_multicast_netif(struct netif* default_multicast_netif)
137{
138 ip4_default_multicast_netif = default_multicast_netif;
139}
140#endif /* LWIP_MULTICAST_TX_OPTIONS */
141
142#ifdef LWIP_HOOK_IP4_ROUTE_SRC
147struct netif *
148ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)
149{
150 if (src != NULL) {
151 /* when src==NULL, the hook is called from ip4_route(dest) */
152 struct netif *netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, src);
153 if (netif != NULL) {
154 return netif;
155 }
156 }
157 return ip4_route(dest);
158}
159#endif /* LWIP_HOOK_IP4_ROUTE_SRC */
160
170struct netif *
171ip4_route(const ip4_addr_t *dest)
172{
173 struct netif *netif;
174
175#if LWIP_MULTICAST_TX_OPTIONS
176 /* Use administratively selected interface for multicast by default */
177 if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) {
178 return ip4_default_multicast_netif;
179 }
180#endif /* LWIP_MULTICAST_TX_OPTIONS */
181
182 /* iterate through netifs */
183 for (netif = netif_list; netif != NULL; netif = netif->next) {
184 /* is the netif up, does it have a link and a valid address? */
185 if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
186 /* network mask matches? */
187 if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {
188 /* return netif on which to forward IP packet */
189 return netif;
190 }
191 /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */
192 if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) {
193 /* return netif on which to forward IP packet */
194 return netif;
195 }
196 }
197 }
198
199#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
200 /* loopif is disabled, looopback traffic is passed through any netif */
201 if (ip4_addr_isloopback(dest)) {
202 /* don't check for link on loopback traffic */
203 if (netif_default != NULL && netif_is_up(netif_default)) {
204 return netif_default;
205 }
206 /* default netif is not up, just use any netif for loopback traffic */
207 for (netif = netif_list; netif != NULL; netif = netif->next) {
208 if (netif_is_up(netif)) {
209 return netif;
210 }
211 }
212 return NULL;
213 }
214#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
215
216#ifdef LWIP_HOOK_IP4_ROUTE_SRC
217 netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, NULL);
218 if (netif != NULL) {
219 return netif;
220 }
221#elif defined(LWIP_HOOK_IP4_ROUTE)
222 netif = LWIP_HOOK_IP4_ROUTE(dest);
223 if (netif != NULL) {
224 return netif;
225 }
226#endif
227
229 ip4_addr_isany_val(*netif_ip4_addr(netif_default))) {
230 /* No matching netif found and default netif is not usable.
231 If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */
232 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
233 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
234 IP_STATS_INC(ip.rterr);
235 MIB2_STATS_INC(mib2.ipoutnoroutes);
236 return NULL;
237 }
238
239 return netif_default;
240}
241
242#if IP_FORWARD
250static int
251ip4_canforward(struct pbuf *p)
252{
253 u32_t addr = lwip_htonl(ip4_addr_get_u32(ip4_current_dest_addr()));
254
255 if (p->flags & PBUF_FLAG_LLBCAST) {
256 /* don't route link-layer broadcasts */
257 return 0;
258 }
259 if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) {
260 /* don't route link-layer multicasts unless the destination address is an IP
261 multicast address */
262 return 0;
263 }
264 if (IP_EXPERIMENTAL(addr)) {
265 return 0;
266 }
267 if (IP_CLASSA(addr)) {
268 u32_t net = addr & IP_CLASSA_NET;
269 if ((net == 0) || (net == ((u32_t)IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) {
270 /* don't route loopback packets */
271 return 0;
272 }
273 }
274 return 1;
275}
276
286static void
287ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
288{
289 struct netif *netif;
290
291 PERF_START;
292 LWIP_UNUSED_ARG(inp);
293
294 if (!ip4_canforward(p)) {
295 goto return_noroute;
296 }
297
298 /* RFC3927 2.7: do not forward link-local addresses */
299 if (ip4_addr_islinklocal(ip4_current_dest_addr())) {
300 LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
301 ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
302 ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
303 goto return_noroute;
304 }
305
306 /* Find network interface where to forward this IP packet to. */
307 netif = ip4_route_src(ip4_current_dest_addr(), ip4_current_src_addr());
308 if (netif == NULL) {
309 LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
310 ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
311 ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
312 /* @todo: send ICMP_DUR_NET? */
313 goto return_noroute;
314 }
315#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF
316 /* Do not forward packets onto the same network interface on which
317 * they arrived. */
318 if (netif == inp) {
319 LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not bouncing packets back on incoming interface.\n"));
320 goto return_noroute;
321 }
322#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */
323
324 /* decrement TTL */
325 IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
326 /* send ICMP if TTL == 0 */
327 if (IPH_TTL(iphdr) == 0) {
328 MIB2_STATS_INC(mib2.ipinhdrerrors);
329#if LWIP_ICMP
330 /* Don't send ICMP messages in response to ICMP messages */
331 if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
332 icmp_time_exceeded(p, ICMP_TE_TTL);
333 }
334#endif /* LWIP_ICMP */
335 return;
336 }
337
338 /* Incrementally update the IP checksum. */
339 if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) {
340 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1);
341 } else {
342 IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100));
343 }
344
345 LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
346 ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
347 ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
348
349 IP_STATS_INC(ip.fw);
350 MIB2_STATS_INC(mib2.ipforwdatagrams);
351 IP_STATS_INC(ip.xmit);
352
353 PERF_STOP("ip4_forward");
354 /* don't fragment if interface has mtu set to 0 [loopif] */
355 if (netif->mtu && (p->tot_len > netif->mtu)) {
356 if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) {
357#if IP_FRAG
358 ip4_frag(p, netif, ip4_current_dest_addr());
359#else /* IP_FRAG */
360 /* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */
361#endif /* IP_FRAG */
362 } else {
363#if LWIP_ICMP
364 /* send ICMP Destination Unreachable code 4: "Fragmentation Needed and DF Set" */
365 icmp_dest_unreach(p, ICMP_DUR_FRAG);
366#endif /* LWIP_ICMP */
367 }
368 return;
369 }
370 /* transmit pbuf on chosen interface */
371 netif->output(netif, p, ip4_current_dest_addr());
372 return;
373return_noroute:
374 MIB2_STATS_INC(mib2.ipoutnoroutes);
375}
376#endif /* IP_FORWARD */
377
392err_t
393ip4_input(struct pbuf *p, struct netif *inp)
394{
395 struct ip_hdr *iphdr;
396 struct netif *netif;
397 u16_t iphdr_hlen;
398 u16_t iphdr_len;
399#if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP
400 int check_ip_src = 1;
401#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */
402
403 IP_STATS_INC(ip.recv);
404 MIB2_STATS_INC(mib2.ipinreceives);
405
406 /* identify the IP header */
407 iphdr = (struct ip_hdr *)p->payload;
408 if (IPH_V(iphdr) != 4) {
409 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", (u16_t)IPH_V(iphdr)));
410 ip4_debug_print(p);
411 pbuf_free(p);
412 IP_STATS_INC(ip.err);
413 IP_STATS_INC(ip.drop);
414 MIB2_STATS_INC(mib2.ipinhdrerrors);
415 return ERR_OK;
416 }
417
418#ifdef LWIP_HOOK_IP4_INPUT
419 if (LWIP_HOOK_IP4_INPUT(p, inp)) {
420 /* the packet has been eaten */
421 return ERR_OK;
422 }
423#endif
424
425 /* obtain IP header length in number of 32-bit words */
426 iphdr_hlen = IPH_HL(iphdr);
427 /* calculate IP header length in bytes */
428 iphdr_hlen *= 4;
429 /* obtain ip length in bytes */
430 iphdr_len = lwip_ntohs(IPH_LEN(iphdr));
431
432 /* Trim pbuf. This is especially required for packets < 60 bytes. */
433 if (iphdr_len < p->tot_len) {
434 pbuf_realloc(p, iphdr_len);
435 }
436
437 /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
438 if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len) || (iphdr_hlen < IP_HLEN)) {
439 if (iphdr_hlen < IP_HLEN) {
441 ("ip4_input: short IP header (%"U16_F" bytes) received, IP packet dropped\n", iphdr_hlen));
442 }
443 if (iphdr_hlen > p->len) {
445 ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
446 iphdr_hlen, p->len));
447 }
448 if (iphdr_len > p->tot_len) {
450 ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
451 iphdr_len, p->tot_len));
452 }
453 /* free (drop) packet pbufs */
454 pbuf_free(p);
455 IP_STATS_INC(ip.lenerr);
456 IP_STATS_INC(ip.drop);
457 MIB2_STATS_INC(mib2.ipindiscards);
458 return ERR_OK;
459 }
460
461 /* verify checksum */
462#if CHECKSUM_CHECK_IP
463 IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) {
464 if (inet_chksum(iphdr, iphdr_hlen) != 0) {
465
467 ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
468 ip4_debug_print(p);
469 pbuf_free(p);
470 IP_STATS_INC(ip.chkerr);
471 IP_STATS_INC(ip.drop);
472 MIB2_STATS_INC(mib2.ipinhdrerrors);
473 return ERR_OK;
474 }
475 }
476#endif
477
478 /* copy IP addresses to aligned ip_addr_t */
479 ip_addr_copy_from_ip4(ip_data.current_iphdr_dest, iphdr->dest);
480 ip_addr_copy_from_ip4(ip_data.current_iphdr_src, iphdr->src);
481
482 /* match packet against an interface, i.e. is this packet for us? */
483 if (ip4_addr_ismulticast(ip4_current_dest_addr())) {
484#if LWIP_IGMP
485 if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip4_current_dest_addr()))) {
486 /* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */
487 ip4_addr_t allsystems;
488 IP4_ADDR(&allsystems, 224, 0, 0, 1);
489 if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) &&
490 ip4_addr_isany(ip4_current_src_addr())) {
491 check_ip_src = 0;
492 }
493 netif = inp;
494 } else {
495 netif = NULL;
496 }
497#else /* LWIP_IGMP */
498 if ((netif_is_up(inp)) && (!ip4_addr_isany_val(*netif_ip4_addr(inp)))) {
499 netif = inp;
500 } else {
501 netif = NULL;
502 }
503#endif /* LWIP_IGMP */
504 } else {
505 /* start trying with inp. if that's not acceptable, start walking the
506 list of configured netifs.
507 'first' is used as a boolean to mark whether we started walking the list */
508 int first = 1;
509 netif = inp;
510 do {
511 LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n",
512 ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(netif_ip4_addr(netif)),
513 ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
514 ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
515 ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(netif_ip4_netmask(netif))));
516
517 /* interface is up and configured? */
518 if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) {
519 /* unicast to this interface address? */
520 if (ip4_addr_cmp(ip4_current_dest_addr(), netif_ip4_addr(netif)) ||
521 /* or broadcast on this interface network address? */
522 ip4_addr_isbroadcast(ip4_current_dest_addr(), netif)
523#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
524 || (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK))
525#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
526 ) {
527 LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n",
528 netif->name[0], netif->name[1]));
529 /* break out of for loop */
530 break;
531 }
532#if LWIP_AUTOIP
533 /* connections to link-local addresses must persist after changing
534 the netif's address (RFC3927 ch. 1.9) */
535 if (autoip_accept_packet(netif, ip4_current_dest_addr())) {
536 LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n",
537 netif->name[0], netif->name[1]));
538 /* break out of for loop */
539 break;
540 }
541#endif /* LWIP_AUTOIP */
542 }
543 if (first) {
544#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
545 /* Packets sent to the loopback address must not be accepted on an
546 * interface that does not have the loopback address assigned to it,
547 * unless a non-loopback interface is used for loopback traffic. */
548 if (ip4_addr_isloopback(ip4_current_dest_addr())) {
549 netif = NULL;
550 break;
551 }
552#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
553 first = 0;
555 } else {
556 netif = netif->next;
557 }
558 if (netif == inp) {
559 netif = netif->next;
560 }
561 } while (netif != NULL);
562 }
563
564#if IP_ACCEPT_LINK_LAYER_ADDRESSING
565 /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
566 * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
567 * According to RFC 1542 section 3.1.1, referred by RFC 2131).
568 *
569 * If you want to accept private broadcast communication while a netif is down,
570 * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.:
571 *
572 * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345))
573 */
574 if (netif == NULL) {
575 /* remote port is DHCP server? */
576 if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
577 struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen);
578 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n",
579 lwip_ntohs(udphdr->dest)));
580 if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
581 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n"));
582 netif = inp;
583 check_ip_src = 0;
584 }
585 }
586 }
587#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
588
589 /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
590#if LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING
591 if (check_ip_src
592#if IP_ACCEPT_LINK_LAYER_ADDRESSING
593 /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
594 && !ip4_addr_isany_val(*ip4_current_src_addr())
595#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
596 )
597#endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */
598 {
599 if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) ||
600 (ip4_addr_ismulticast(ip4_current_src_addr()))) {
601 /* packet source is not valid */
602 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip4_input: packet source is not valid.\n"));
603 /* free (drop) packet pbufs */
604 pbuf_free(p);
605 IP_STATS_INC(ip.drop);
606 MIB2_STATS_INC(mib2.ipinaddrerrors);
607 MIB2_STATS_INC(mib2.ipindiscards);
608 return ERR_OK;
609 }
610 }
611
612 /* packet not for us? */
613 if (netif == NULL) {
614 /* packet not for us, route or discard */
615 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: packet not for us.\n"));
616#if IP_FORWARD
617 /* non-broadcast packet? */
618 if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), inp)) {
619 /* try to forward IP packet on (other) interfaces */
620 ip4_forward(p, iphdr, inp);
621 } else
622#endif /* IP_FORWARD */
623 {
624 IP_STATS_INC(ip.drop);
625 MIB2_STATS_INC(mib2.ipinaddrerrors);
626 MIB2_STATS_INC(mib2.ipindiscards);
627 }
628 pbuf_free(p);
629 return ERR_OK;
630 }
631 /* packet consists of multiple fragments? */
632 if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
633#if IP_REASSEMBLY /* packet fragment reassembly code present? */
634 LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip4_reass()\n",
635 lwip_ntohs(IPH_ID(iphdr)), p->tot_len, lwip_ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8)));
636 /* reassemble the packet*/
637 p = ip4_reass(p);
638 /* packet not fully reassembled yet? */
639 if (p == NULL) {
640 return ERR_OK;
641 }
642 iphdr = (struct ip_hdr *)p->payload;
643#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
644 pbuf_free(p);
645 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
646 lwip_ntohs(IPH_OFFSET(iphdr))));
647 IP_STATS_INC(ip.opterr);
648 IP_STATS_INC(ip.drop);
649 /* unsupported protocol feature */
650 MIB2_STATS_INC(mib2.ipinunknownprotos);
651 return ERR_OK;
652#endif /* IP_REASSEMBLY */
653 }
654
655#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */
656
657#if LWIP_IGMP
658 /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
659 if ((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
660#else
661 if (iphdr_hlen > IP_HLEN) {
662#endif /* LWIP_IGMP */
663 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
664 pbuf_free(p);
665 IP_STATS_INC(ip.opterr);
666 IP_STATS_INC(ip.drop);
667 /* unsupported protocol feature */
668 MIB2_STATS_INC(mib2.ipinunknownprotos);
669 return ERR_OK;
670 }
671#endif /* IP_OPTIONS_ALLOWED == 0 */
672
673 /* send to upper layers */
674 LWIP_DEBUGF(IP_DEBUG, ("ip4_input: \n"));
675 ip4_debug_print(p);
676 LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
677
678 ip_data.current_netif = netif;
679 ip_data.current_input_netif = inp;
680 ip_data.current_ip4_header = iphdr;
681 ip_data.current_ip_header_tot_len = IPH_HL(iphdr) * 4;
682
683#if LWIP_RAW
684 /* raw input did not eat the packet? */
685 if (raw_input(p, inp) == 0)
686#endif /* LWIP_RAW */
687 {
688 pbuf_header(p, -(s16_t)iphdr_hlen); /* Move to payload, no check necessary. */
689
690 switch (IPH_PROTO(iphdr)) {
691#if LWIP_UDP
692 case IP_PROTO_UDP:
693#if LWIP_UDPLITE
694 case IP_PROTO_UDPLITE:
695#endif /* LWIP_UDPLITE */
696 MIB2_STATS_INC(mib2.ipindelivers);
697 udp_input(p, inp);
698 break;
699#endif /* LWIP_UDP */
700#if LWIP_TCP
701 case IP_PROTO_TCP:
702 MIB2_STATS_INC(mib2.ipindelivers);
703 tcp_input(p, inp);
704 break;
705#endif /* LWIP_TCP */
706#if LWIP_ICMP
707 case IP_PROTO_ICMP:
708 MIB2_STATS_INC(mib2.ipindelivers);
709 icmp_input(p, inp);
710 break;
711#endif /* LWIP_ICMP */
712#if LWIP_IGMP
713 case IP_PROTO_IGMP:
714 igmp_input(p, inp, ip4_current_dest_addr());
715 break;
716#endif /* LWIP_IGMP */
717 default:
718#if LWIP_ICMP
719 /* send ICMP destination protocol unreachable unless is was a broadcast */
720 if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) &&
721 !ip4_addr_ismulticast(ip4_current_dest_addr())) {
722 pbuf_header_force(p, iphdr_hlen); /* Move to ip header, no check necessary. */
723 p->payload = iphdr;
724 icmp_dest_unreach(p, ICMP_DUR_PROTO);
725 }
726#endif /* LWIP_ICMP */
727 pbuf_free(p);
728
729 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr)));
730
731 IP_STATS_INC(ip.proterr);
732 IP_STATS_INC(ip.drop);
733 MIB2_STATS_INC(mib2.ipinunknownprotos);
734 }
735 }
736
737 /* @todo: this is not really necessary... */
738 ip_data.current_netif = NULL;
739 ip_data.current_input_netif = NULL;
740 ip_data.current_ip4_header = NULL;
741 ip_data.current_ip_header_tot_len = 0;
742 ip4_addr_set_any(ip4_current_src_addr());
743 ip4_addr_set_any(ip4_current_dest_addr());
744
745 return ERR_OK;
746}
747
773err_t
774ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
775 u8_t ttl, u8_t tos,
776 u8_t proto, struct netif *netif)
777{
778#if IP_OPTIONS_SEND
779 return ip4_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
780}
781
788err_t
789ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
790 u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
791 u16_t optlen)
792{
793#endif /* IP_OPTIONS_SEND */
794 const ip4_addr_t *src_used = src;
795 if (dest != LWIP_IP_HDRINCL) {
796 if (ip4_addr_isany(src)) {
797 src_used = netif_ip4_addr(netif);
798 }
799 }
800
801#if IP_OPTIONS_SEND
802 return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif,
803 ip_options, optlen);
804#else /* IP_OPTIONS_SEND */
805 return ip4_output_if_src(p, src_used, dest, ttl, tos, proto, netif);
806#endif /* IP_OPTIONS_SEND */
807}
808
813err_t
814ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
815 u8_t ttl, u8_t tos,
816 u8_t proto, struct netif *netif)
817{
818#if IP_OPTIONS_SEND
819 return ip4_output_if_opt_src(p, src, dest, ttl, tos, proto, netif, NULL, 0);
820}
821
826err_t
827ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
828 u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
829 u16_t optlen)
830{
831#endif /* IP_OPTIONS_SEND */
832 struct ip_hdr *iphdr;
833 ip4_addr_t dest_addr;
834#if CHECKSUM_GEN_IP_INLINE
835 u32_t chk_sum = 0;
836#endif /* CHECKSUM_GEN_IP_INLINE */
837
839
840 MIB2_STATS_INC(mib2.ipoutrequests);
841
842 /* Should the IP header be generated or is it already included in p? */
843 if (dest != LWIP_IP_HDRINCL) {
844 u16_t ip_hlen = IP_HLEN;
845#if IP_OPTIONS_SEND
846 u16_t optlen_aligned = 0;
847 if (optlen != 0) {
848#if CHECKSUM_GEN_IP_INLINE
849 int i;
850#endif /* CHECKSUM_GEN_IP_INLINE */
851 /* round up to a multiple of 4 */
852 optlen_aligned = ((optlen + 3) & ~3);
853 ip_hlen += optlen_aligned;
854 /* First write in the IP options */
855 if (pbuf_header(p, optlen_aligned)) {
856 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output_if_opt: not enough room for IP options in pbuf\n"));
857 IP_STATS_INC(ip.err);
858 MIB2_STATS_INC(mib2.ipoutdiscards);
859 return ERR_BUF;
860 }
861 MEMCPY(p->payload, ip_options, optlen);
862 if (optlen < optlen_aligned) {
863 /* zero the remaining bytes */
864 memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
865 }
866#if CHECKSUM_GEN_IP_INLINE
867 for (i = 0; i < optlen_aligned/2; i++) {
868 chk_sum += ((u16_t*)p->payload)[i];
869 }
870#endif /* CHECKSUM_GEN_IP_INLINE */
871 }
872#endif /* IP_OPTIONS_SEND */
873 /* generate IP header */
874 if (pbuf_header(p, IP_HLEN)) {
875 LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output: not enough room for IP header in pbuf\n"));
876
877 IP_STATS_INC(ip.err);
878 MIB2_STATS_INC(mib2.ipoutdiscards);
879 return ERR_BUF;
880 }
881
882 iphdr = (struct ip_hdr *)p->payload;
883 LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
884 (p->len >= sizeof(struct ip_hdr)));
885
886 IPH_TTL_SET(iphdr, ttl);
887 IPH_PROTO_SET(iphdr, proto);
888#if CHECKSUM_GEN_IP_INLINE
889 chk_sum += PP_NTOHS(proto | (ttl << 8));
890#endif /* CHECKSUM_GEN_IP_INLINE */
891
892 /* dest cannot be NULL here */
893 ip4_addr_copy(iphdr->dest, *dest);
894#if CHECKSUM_GEN_IP_INLINE
895 chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
896 chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
897#endif /* CHECKSUM_GEN_IP_INLINE */
898
899 IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
900 IPH_TOS_SET(iphdr, tos);
901#if CHECKSUM_GEN_IP_INLINE
902 chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8));
903#endif /* CHECKSUM_GEN_IP_INLINE */
904 IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
905#if CHECKSUM_GEN_IP_INLINE
906 chk_sum += iphdr->_len;
907#endif /* CHECKSUM_GEN_IP_INLINE */
908 IPH_OFFSET_SET(iphdr, 0);
909 IPH_ID_SET(iphdr, lwip_htons(ip_id));
910#if CHECKSUM_GEN_IP_INLINE
911 chk_sum += iphdr->_id;
912#endif /* CHECKSUM_GEN_IP_INLINE */
913 ++ip_id;
914
915 if (src == NULL) {
916 ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY4);
917 } else {
918 /* src cannot be NULL here */
919 ip4_addr_copy(iphdr->src, *src);
920 }
921
922#if CHECKSUM_GEN_IP_INLINE
923 chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
924 chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
925 chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
926 chk_sum = (chk_sum >> 16) + chk_sum;
927 chk_sum = ~chk_sum;
928 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
929 iphdr->_chksum = (u16_t)chk_sum; /* network order */
930 }
931#if LWIP_CHECKSUM_CTRL_PER_NETIF
932 else {
933 IPH_CHKSUM_SET(iphdr, 0);
934 }
935#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
936#else /* CHECKSUM_GEN_IP_INLINE */
937 IPH_CHKSUM_SET(iphdr, 0);
938#if CHECKSUM_GEN_IP
939 IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
940 IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
941 }
942#endif /* CHECKSUM_GEN_IP */
943#endif /* CHECKSUM_GEN_IP_INLINE */
944 } else {
945 /* IP header already included in p */
946 iphdr = (struct ip_hdr *)p->payload;
947 ip4_addr_copy(dest_addr, iphdr->dest);
948 dest = &dest_addr;
949 }
950
951 IP_STATS_INC(ip.xmit);
952
953 LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
954 ip4_debug_print(p);
955
956#if ENABLE_LOOPBACK
957 if (ip4_addr_cmp(dest, netif_ip4_addr(netif))
959 || ip4_addr_isloopback(dest)
960#endif /* !LWIP_HAVE_LOOPIF */
961 ) {
962 /* Packet to self, enqueue it for loopback */
963 LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
964 return netif_loop_output(netif, p);
965 }
966#if LWIP_MULTICAST_TX_OPTIONS
967 if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
968 netif_loop_output(netif, p);
969 }
970#endif /* LWIP_MULTICAST_TX_OPTIONS */
971#endif /* ENABLE_LOOPBACK */
972#if IP_FRAG
973 /* don't fragment if interface has mtu set to 0 [loopif] */
974 if (netif->mtu && (p->tot_len > netif->mtu)) {
975 return ip4_frag(p, netif, dest);
976 }
977#endif /* IP_FRAG */
978
979 LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: call netif->output()\n"));
980 return netif->output(netif, p, dest);
981}
982
1000err_t
1001ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
1002 u8_t ttl, u8_t tos, u8_t proto)
1003{
1004 struct netif *netif;
1005
1007
1008 if ((netif = ip4_route_src(dest, src)) == NULL) {
1009 LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
1010 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
1011 IP_STATS_INC(ip.rterr);
1012 return ERR_RTE;
1013 }
1014
1015 return ip4_output_if(p, src, dest, ttl, tos, proto, netif);
1016}
1017
1018#if LWIP_NETIF_HWADDRHINT
1037err_t
1038ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
1039 u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint)
1040{
1041 struct netif *netif;
1042 err_t err;
1043
1045
1046 if ((netif = ip4_route_src(dest, src)) == NULL) {
1047 LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
1048 ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
1049 IP_STATS_INC(ip.rterr);
1050 return ERR_RTE;
1051 }
1052
1053 NETIF_SET_HWADDRHINT(netif, addr_hint);
1054 err = ip4_output_if(p, src, dest, ttl, tos, proto, netif);
1055 NETIF_SET_HWADDRHINT(netif, NULL);
1056
1057 return err;
1058}
1059#endif /* LWIP_NETIF_HWADDRHINT*/
1060
1061#if IP_DEBUG
1062/* Print an IP header by using LWIP_DEBUGF
1063 * @param p an IP packet, p->payload pointing to the IP header
1064 */
1065void
1066ip4_debug_print(struct pbuf *p)
1067{
1068 struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
1069
1070 LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
1071 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1072 LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n",
1073 (u16_t)IPH_V(iphdr),
1074 (u16_t)IPH_HL(iphdr),
1075 (u16_t)IPH_TOS(iphdr),
1076 lwip_ntohs(IPH_LEN(iphdr))));
1077 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1078 LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n",
1079 lwip_ntohs(IPH_ID(iphdr)),
1080 (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1),
1081 (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1),
1082 (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1),
1083 (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
1084 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1085 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n",
1086 (u16_t)IPH_TTL(iphdr),
1087 (u16_t)IPH_PROTO(iphdr),
1088 lwip_ntohs(IPH_CHKSUM(iphdr))));
1089 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1090 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n",
1091 ip4_addr1_16(&iphdr->src),
1092 ip4_addr2_16(&iphdr->src),
1093 ip4_addr3_16(&iphdr->src),
1094 ip4_addr4_16(&iphdr->src)));
1095 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1096 LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n",
1097 ip4_addr1_16(&iphdr->dest),
1098 ip4_addr2_16(&iphdr->dest),
1099 ip4_addr3_16(&iphdr->dest),
1100 ip4_addr4_16(&iphdr->dest)));
1101 LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1102}
1103#endif /* IP_DEBUG */
1104
1105#endif /* LWIP_IPV4 */
#define LWIP_DEBUGF(debug, message)
Definition debug.h:183
#define LWIP_UNUSED_ARG(x)
Definition arch.h:327
#define LWIP_DBG_LEVEL_SERIOUS
Definition debug.h:76
#define LWIP_DBG_LEVEL_WARNING
Definition debug.h:74
#define LWIP_DBG_TRACE
Definition debug.h:102
s8_t err_t
Definition err.h:76
@ ERR_BUF
Definition err.h:86
@ ERR_RTE
Definition err.h:90
@ ERR_OK
Definition err.h:82
#define IP_DEBUG
Definition opt.h:2713
#define LWIP_HAVE_LOOPIF
Definition opt.h:1498
#define NETIF_FLAG_IGMP
Definition netif.h:117
#define NETIF_FLAG_BROADCAST
Definition netif.h:100
#define netif_is_up(netif)
Definition netif.h:420
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition pbuf.c:512
u8_t pbuf_free(struct pbuf *p)
Definition pbuf.c:734
@ ICMP_TE_TTL
Definition icmp.h:92
@ ICMP_DUR_PROTO
Definition icmp.h:80
@ ICMP_DUR_FRAG
Definition icmp.h:84
#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p)
Definition ip.h:82
struct netif * netif_list
Definition netif.c:123
struct netif * netif_default
Definition netif.c:124
#define netif_is_link_up(netif)
Definition netif.h:432
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition pbuf.c:684
u8_t pbuf_header_force(struct pbuf *p, s16_t header_size_increment)
Definition pbuf.c:694
#define PBUF_FLAG_LLBCAST
Definition pbuf.h:154
#define PBUF_FLAG_MCASTLOOP
Definition pbuf.h:152
#define PBUF_FLAG_LLMCAST
Definition pbuf.h:156
ip_addr_t current_iphdr_src
Definition ip.h:141
ip_addr_t current_iphdr_dest
Definition ip.h:143
u16_t current_ip_header_tot_len
Definition ip.h:139
struct netif * current_netif
Definition ip.h:127
struct netif * current_input_netif
Definition ip.h:129
Definition netif.h:244
u8_t flags
Definition netif.h:324
char name[2]
Definition netif.h:326
u8_t num
Definition netif.h:328
u16_t mtu
Definition netif.h:318
struct netif * next
Definition netif.h:246
Definition pbuf.h:161
u16_t tot_len
Definition pbuf.h:175
u16_t len
Definition pbuf.h:178
void * payload
Definition pbuf.h:166
u8_t flags
Definition pbuf.h:184