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 
126 static u16_t ip_id;
127 
128 #if LWIP_MULTICAST_TX_OPTIONS
129 
130 static struct netif* ip4_default_multicast_netif;
131 
135 void
136 ip4_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
143 
147 struct netif *
148 ip4_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 
170 struct netif *
171 ip4_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
243 
250 static int
251 ip4_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 
286 static void
287 ip4_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;
373 return_noroute:
374  MIB2_STATS_INC(mib2.ipoutnoroutes);
375 }
376 #endif /* IP_FORWARD */
377 
392 err_t
393 ip4_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;
554  netif = netif_list;
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 
773 err_t
774 ip4_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 
788 err_t
789 ip4_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 
813 err_t
814 ip4_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 
826 err_t
827 ip4_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))
958 #if !LWIP_HAVE_LOOPIF
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 
1000 err_t
1001 ip4_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
1019 
1037 err_t
1038 ip4_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  */
1065 void
1066 ip4_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 */
u16_t tot_len
Definition: pbuf.h:175
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition: pbuf.c:512
struct netif * netif_list
Definition: netif.c:123
#define NETIF_FLAG_IGMP
Definition: netif.h:117
u16_t len
Definition: pbuf.h:178
Definition: err.h:86
struct netif * netif_default
Definition: netif.c:124
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:684
#define netif_is_link_up(netif)
Definition: netif.h:432
#define PBUF_FLAG_LLBCAST
Definition: pbuf.h:154
u8_t num
Definition: netif.h:328
#define NETIF_FLAG_BROADCAST
Definition: netif.h:100
#define IP_DEBUG
Definition: opt.h:2713
#define PBUF_FLAG_MCASTLOOP
Definition: pbuf.h:152
struct netif * current_netif
Definition: ip.h:127
u8_t flags
Definition: pbuf.h:184
#define LWIP_HAVE_LOOPIF
Definition: opt.h:1498
ip_addr_t current_iphdr_dest
Definition: ip.h:143
struct netif * next
Definition: netif.h:246
Definition: pbuf.h:161
u8_t flags
Definition: netif.h:324
u16_t current_ip_header_tot_len
Definition: ip.h:139
Definition: netif.h:244
#define PBUF_FLAG_LLMCAST
Definition: pbuf.h:156
s8_t err_t
Definition: err.h:76
u16_t mtu
Definition: netif.h:318
#define LWIP_DEBUGF(debug, message)
#define netif_is_up(netif)
Definition: netif.h:420
#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p)
Definition: ip.h:82
u8_t pbuf_header_force(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:694
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:327
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:734
Definition: err.h:82
void * payload
Definition: pbuf.h:166
struct netif * current_input_netif
Definition: ip.h:129
char name[2]
Definition: netif.h:326
Definition: err.h:90
ip_addr_t current_iphdr_src
Definition: ip.h:141