UbixOS  2.0
ip4.c
Go to the documentation of this file.
1 
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 "net/opt.h"
42 
43 #if LWIP_IPV4
44 
45 #include "net/ip.h"
46 #include "net/def.h"
47 #include "net/mem.h"
48 #include "net/ip4_frag.h"
49 #include "net/inet_chksum.h"
50 #include "net/netif.h"
51 #include "net/icmp.h"
52 #include "net/igmp.h"
53 #include "net/raw.h"
54 #include "net/udp.h"
55 #include "net/priv/tcp_priv.h"
56 #include "net/autoip.h"
57 #include "net/stats.h"
58 #include "net/prot/dhcp.h"
59 
60 #include <string.h>
61 
62 #ifdef LWIP_HOOK_FILENAME
63 #include LWIP_HOOK_FILENAME
64 #endif
65 
68 #ifndef LWIP_INLINE_IP_CHKSUM
69 #if LWIP_CHECKSUM_CTRL_PER_NETIF
70 #define LWIP_INLINE_IP_CHKSUM 0
71 #else /* LWIP_CHECKSUM_CTRL_PER_NETIF */
72 #define LWIP_INLINE_IP_CHKSUM 1
73 #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */
74 #endif
75 
76 #if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
77 #define CHECKSUM_GEN_IP_INLINE 1
78 #else
79 #define CHECKSUM_GEN_IP_INLINE 0
80 #endif
81 
82 #if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT)
83 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 1
84 
90 #if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT)
91 /* accept DHCP client port and custom port */
92 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \
93  || (LWIP_IP_ACCEPT_UDP_PORT(port)))
94 #elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
95 /* accept custom port only */
96 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port))
97 #else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
98 /* accept DHCP client port only */
99 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT))
100 #endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
101 
102 #else /* LWIP_DHCP */
103 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 0
104 #endif /* LWIP_DHCP */
105 
107 static u16_t ip_id;
108 
109 #if LWIP_MULTICAST_TX_OPTIONS
110 
111 static struct netif* ip4_default_multicast_netif;
112 
116 void
117 ip4_set_default_multicast_netif(struct netif* default_multicast_netif)
118 {
119  ip4_default_multicast_netif = default_multicast_netif;
120 }
121 #endif /* LWIP_MULTICAST_TX_OPTIONS */
122 
123 #ifdef LWIP_HOOK_IP4_ROUTE_SRC
124 
128 struct netif *
129 ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)
130 {
131  if (src != NULL) {
132  /* when src==NULL, the hook is called from ip4_route(dest) */
133  struct netif *netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, src);
134  if (netif != NULL) {
135  return netif;
136  }
137  }
138  return ip4_route(dest);
139 }
140 #endif /* LWIP_HOOK_IP4_ROUTE_SRC */
141 
151 struct netif *
152 ip4_route(const ip4_addr_t *dest)
153 {
154  struct netif *netif;
155 
156 #if LWIP_MULTICAST_TX_OPTIONS
157  /* Use administratively selected interface for multicast by default */
158  if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) {
159  return ip4_default_multicast_netif;
160  }
161 #endif /* LWIP_MULTICAST_TX_OPTIONS */
162 
163  /* iterate through netifs */
164  for (netif = netif_list; netif != NULL; netif = netif->next) {
165  /* is the netif up, does it have a link and a valid address? */
166  if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
167  /* network mask matches? */
168  if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {
169  /* return netif on which to forward IP packet */
170  return netif;
171  }
172  /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */
173  if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) {
174  /* return netif on which to forward IP packet */
175  return netif;
176  }
177  }
178  }
179 
180 #if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF
181  /* loopif is disabled, looopback traffic is passed through any netif */
182  if (ip4_addr_isloopback(dest)) {
183  /* don't check for link on loopback traffic */
185  return netif_default;
186  }
187  /* default netif is not up, just use any netif for loopback traffic */
188  for (netif = netif_list; netif != NULL; netif = netif->next) {
189  if (netif_is_up(netif)) {
190  return netif;
191  }
192  }
193  return NULL;
194  }
195 #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
196 
197 #ifdef LWIP_HOOK_IP4_ROUTE_SRC
198  netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, NULL);
199  if (netif != NULL) {
200  return netif;
201  }
202 #elif defined(LWIP_HOOK_IP4_ROUTE)
203  netif = LWIP_HOOK_IP4_ROUTE(dest);
204  if (netif != NULL) {
205  return netif;
206  }
207 #endif
208 
210  ip4_addr_isany_val(*netif_ip4_addr(netif_default))) {
211  /* No matching netif found and default netif is not usable.
212  If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */
213  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
214  ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
215  IP_STATS_INC(ip.rterr);
216  MIB2_STATS_INC(mib2.ipoutnoroutes);
217  return NULL;
218  }
219 
220  return netif_default;
221 }
222 
223 #if IP_FORWARD
224 
231 static int
232 ip4_canforward(struct pbuf *p)
233 {
234  u32_t addr = lwip_htonl(ip4_addr_get_u32(ip4_current_dest_addr()));
235 
236  if (p->flags & PBUF_FLAG_LLBCAST) {
237  /* don't route link-layer broadcasts */
238  return 0;
239  }
240  if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) {
241  /* don't route link-layer multicasts unless the destination address is an IP
242  multicast address */
243  return 0;
244  }
245  if (IP_EXPERIMENTAL(addr)) {
246  return 0;
247  }
248  if (IP_CLASSA(addr)) {
249  u32_t net = addr & IP_CLASSA_NET;
250  if ((net == 0) || (net == ((u32_t)IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) {
251  /* don't route loopback packets */
252  return 0;
253  }
254  }
255  return 1;
256 }
257 
267 static void
268 ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
269 {
270  struct netif *netif;
271 
272  PERF_START;
273  LWIP_UNUSED_ARG(inp);
274 
275  if (!ip4_canforward(p)) {
276  goto return_noroute;
277  }
278 
279  /* RFC3927 2.7: do not forward link-local addresses */
280  if (ip4_addr_islinklocal(ip4_current_dest_addr())) {
281  LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
282  ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
283  ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
284  goto return_noroute;
285  }
286 
287  /* Find network interface where to forward this IP packet to. */
288  netif = ip4_route_src(ip4_current_dest_addr(), ip4_current_src_addr());
289  if (netif == NULL) {
290  LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
291  ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
292  ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
293  /* @todo: send ICMP_DUR_NET? */
294  goto return_noroute;
295  }
296 #if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF
297  /* Do not forward packets onto the same network interface on which
298  * they arrived. */
299  if (netif == inp) {
300  LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not bouncing packets back on incoming interface.\n"));
301  goto return_noroute;
302  }
303 #endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */
304 
305  /* decrement TTL */
306  IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
307  /* send ICMP if TTL == 0 */
308  if (IPH_TTL(iphdr) == 0) {
309  MIB2_STATS_INC(mib2.ipinhdrerrors);
310 #if LWIP_ICMP
311  /* Don't send ICMP messages in response to ICMP messages */
312  if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
313  icmp_time_exceeded(p, ICMP_TE_TTL);
314  }
315 #endif /* LWIP_ICMP */
316  return;
317  }
318 
319  /* Incrementally update the IP checksum. */
320  if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) {
321  IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1);
322  } else {
323  IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100));
324  }
325 
326  LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
327  ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()),
328  ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr())));
329 
330  IP_STATS_INC(ip.fw);
331  MIB2_STATS_INC(mib2.ipforwdatagrams);
332  IP_STATS_INC(ip.xmit);
333 
334  PERF_STOP("ip4_forward");
335  /* don't fragment if interface has mtu set to 0 [loopif] */
336  if (netif->mtu && (p->tot_len > netif->mtu)) {
337  if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) {
338 #if IP_FRAG
339  ip4_frag(p, netif, ip4_current_dest_addr());
340 #else /* IP_FRAG */
341  /* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */
342 #endif /* IP_FRAG */
343  } else {
344 #if LWIP_ICMP
345  /* send ICMP Destination Unreachable code 4: "Fragmentation Needed and DF Set" */
346  icmp_dest_unreach(p, ICMP_DUR_FRAG);
347 #endif /* LWIP_ICMP */
348  }
349  return;
350  }
351  /* transmit pbuf on chosen interface */
352  netif->output(netif, p, ip4_current_dest_addr());
353  return;
354 return_noroute:
355  MIB2_STATS_INC(mib2.ipoutnoroutes);
356 }
357 #endif /* IP_FORWARD */
358 
373 err_t
374 ip4_input(struct pbuf *p, struct netif *inp)
375 {
376  struct ip_hdr *iphdr;
377  struct netif *netif;
378  u16_t iphdr_hlen;
379  u16_t iphdr_len;
380 #if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP
381  int check_ip_src = 1;
382 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */
383 
384  IP_STATS_INC(ip.recv);
385  MIB2_STATS_INC(mib2.ipinreceives);
386 
387  /* identify the IP header */
388  iphdr = (struct ip_hdr *)p->payload;
389  if (IPH_V(iphdr) != 4) {
390  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", (u16_t)IPH_V(iphdr)));
391  ip4_debug_print(p);
392  pbuf_free(p);
393  IP_STATS_INC(ip.err);
394  IP_STATS_INC(ip.drop);
395  MIB2_STATS_INC(mib2.ipinhdrerrors);
396  return ERR_OK;
397  }
398 
399 #ifdef LWIP_HOOK_IP4_INPUT
400  if (LWIP_HOOK_IP4_INPUT(p, inp)) {
401  /* the packet has been eaten */
402  return ERR_OK;
403  }
404 #endif
405 
406  /* obtain IP header length in number of 32-bit words */
407  iphdr_hlen = IPH_HL(iphdr);
408  /* calculate IP header length in bytes */
409  iphdr_hlen *= 4;
410  /* obtain ip length in bytes */
411  iphdr_len = lwip_ntohs(IPH_LEN(iphdr));
412 
413  /* Trim pbuf. This is especially required for packets < 60 bytes. */
414  if (iphdr_len < p->tot_len) {
415  pbuf_realloc(p, iphdr_len);
416  }
417 
418  /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
419  if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len) || (iphdr_hlen < IP_HLEN)) {
420  if (iphdr_hlen < IP_HLEN) {
422  ("ip4_input: short IP header (%"U16_F" bytes) received, IP packet dropped\n", iphdr_hlen));
423  }
424  if (iphdr_hlen > p->len) {
426  ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
427  iphdr_hlen, p->len));
428  }
429  if (iphdr_len > p->tot_len) {
431  ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
432  iphdr_len, p->tot_len));
433  }
434  /* free (drop) packet pbufs */
435  pbuf_free(p);
436  IP_STATS_INC(ip.lenerr);
437  IP_STATS_INC(ip.drop);
438  MIB2_STATS_INC(mib2.ipindiscards);
439  return ERR_OK;
440  }
441 
442  /* verify checksum */
443 #if CHECKSUM_CHECK_IP
444  IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) {
445  if (inet_chksum(iphdr, iphdr_hlen) != 0) {
446 
448  ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
449  ip4_debug_print(p);
450  pbuf_free(p);
451  IP_STATS_INC(ip.chkerr);
452  IP_STATS_INC(ip.drop);
453  MIB2_STATS_INC(mib2.ipinhdrerrors);
454  return ERR_OK;
455  }
456  }
457 #endif
458 
459  /* copy IP addresses to aligned ip_addr_t */
460  ip_addr_copy_from_ip4(ip_data.current_iphdr_dest, iphdr->dest);
461  ip_addr_copy_from_ip4(ip_data.current_iphdr_src, iphdr->src);
462 
463  /* match packet against an interface, i.e. is this packet for us? */
464  if (ip4_addr_ismulticast(ip4_current_dest_addr())) {
465 #if LWIP_IGMP
466 kpanic("A");
467  if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip4_current_dest_addr()))) {
468  /* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */
469  ip4_addr_t allsystems;
470  IP4_ADDR(&allsystems, 224, 0, 0, 1);
471  if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) &&
472  ip4_addr_isany(ip4_current_src_addr())) {
473  check_ip_src = 0;
474  }
475  netif = inp;
476  } else {
477  netif = NULL;
478  }
479 #else /* LWIP_IGMP */
480 kpanic("B");
481  if ((netif_is_up(inp)) && (!ip4_addr_isany_val(*netif_ip4_addr(inp)))) {
482  netif = inp;
483  } else {
484  netif = NULL;
485  }
486 #endif /* LWIP_IGMP */
487  } else {
488  /* start trying with inp. if that's not acceptable, start walking the
489  list of configured netifs.
490  'first' is used as a boolean to mark whether we started walking the list */
491  int first = 1;
492  netif = inp;
493  do {
494 if (ip4_addr_get_u32(&iphdr->dest) == ip4_addr_get_u32(netif_ip4_addr(netif)))
495  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",
496  ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(netif_ip4_addr(netif)),
497  ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
498  ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)),
499  ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(netif_ip4_netmask(netif))));
500 
501  /* interface is up and configured? */
502  if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) {
503  /* unicast to this interface address? */
504  if (ip4_addr_cmp(ip4_current_dest_addr(), netif_ip4_addr(netif)) ||
505  /* or broadcast on this interface network address? */
506  ip4_addr_isbroadcast(ip4_current_dest_addr(), netif)
508  || (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK))
509 #endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */
510  ) {
511  LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n",
512  netif->name[0], netif->name[1]));
513  /* break out of for loop */
514  break;
515  }
516 #if LWIP_AUTOIP
517  /* connections to link-local addresses must persist after changing
518  the netif's address (RFC3927 ch. 1.9) */
519  if (autoip_accept_packet(netif, ip4_current_dest_addr())) {
520  LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n",
521  netif->name[0], netif->name[1]));
522  /* break out of for loop */
523  break;
524  }
525 #endif /* LWIP_AUTOIP */
526  }
527  if (first) {
528 #if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF
529  /* Packets sent to the loopback address must not be accepted on an
530  * interface that does not have the loopback address assigned to it,
531  * unless a non-loopback interface is used for loopback traffic. */
532  if (ip4_addr_isloopback(ip4_current_dest_addr())) {
533 kpanic("D");
534  netif = NULL;
535  break;
536  }
537 #endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */
538  first = 0;
539  netif = netif_list;
540  } else {
541  netif = netif->next;
542  }
543  if (netif == inp) {
544  netif = netif->next;
545  }
546  } while (netif != NULL);
547  }
548 
549 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
550  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
551  * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
552  * According to RFC 1542 section 3.1.1, referred by RFC 2131).
553  *
554  * If you want to accept private broadcast communication while a netif is down,
555  * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.:
556  *
557  * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345))
558  */
559  if (netif == NULL) {
560  /* remote port is DHCP server? */
561  if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
562  struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen);
563  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n",
564  lwip_ntohs(udphdr->dest)));
565  if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
566  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n"));
567  netif = inp;
568  check_ip_src = 0;
569  }
570  }
571  }
572 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
573 
574  /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
575 #if LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING
576  if (check_ip_src
577 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
578  /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
579  && !ip4_addr_isany_val(*ip4_current_src_addr())
580 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
581  )
582 #endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */
583  {
584  if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) ||
585  (ip4_addr_ismulticast(ip4_current_src_addr()))) {
586  /* packet source is not valid */
587  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip4_input: packet source is not valid.\n"));
588  /* free (drop) packet pbufs */
589  pbuf_free(p);
590  IP_STATS_INC(ip.drop);
591  MIB2_STATS_INC(mib2.ipinaddrerrors);
592  MIB2_STATS_INC(mib2.ipindiscards);
593  return ERR_OK;
594  }
595  }
596 
597  /* packet not for us? */
598  if (netif == NULL) {
599  /* packet not for us, route or discard */
600  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: packet not for us.\n"));
601 #if IP_FORWARD
602  /* non-broadcast packet? */
603  if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), inp)) {
604  /* try to forward IP packet on (other) interfaces */
605  ip4_forward(p, iphdr, inp);
606  } else
607 #endif /* IP_FORWARD */
608  {
609  IP_STATS_INC(ip.drop);
610  MIB2_STATS_INC(mib2.ipinaddrerrors);
611  MIB2_STATS_INC(mib2.ipindiscards);
612  }
613  pbuf_free(p);
614  return ERR_OK;
615  }
616  /* packet consists of multiple fragments? */
617  if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
618 #if IP_REASSEMBLY /* packet fragment reassembly code present? */
619  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",
620  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)));
621  /* reassemble the packet*/
622  p = ip4_reass(p);
623  /* packet not fully reassembled yet? */
624  if (p == NULL) {
625  return ERR_OK;
626  }
627  iphdr = (struct ip_hdr *)p->payload;
628 #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
629  pbuf_free(p);
630  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
631  lwip_ntohs(IPH_OFFSET(iphdr))));
632  IP_STATS_INC(ip.opterr);
633  IP_STATS_INC(ip.drop);
634  /* unsupported protocol feature */
635  MIB2_STATS_INC(mib2.ipinunknownprotos);
636  return ERR_OK;
637 #endif /* IP_REASSEMBLY */
638  }
639 
640 #if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */
641 
642 #if LWIP_IGMP
643  /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
644  if ((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
645 #else
646  if (iphdr_hlen > IP_HLEN) {
647 #endif /* LWIP_IGMP */
648  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
649  pbuf_free(p);
650  IP_STATS_INC(ip.opterr);
651  IP_STATS_INC(ip.drop);
652  /* unsupported protocol feature */
653  MIB2_STATS_INC(mib2.ipinunknownprotos);
654  return ERR_OK;
655  }
656 #endif /* IP_OPTIONS_ALLOWED == 0 */
657 
658  /* send to upper layers */
659  LWIP_DEBUGF(IP_DEBUG, ("ip4_input: \n"));
660  ip4_debug_print(p);
661  LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
662 
665  ip_data.current_ip4_header = iphdr;
667 
668 #if LWIP_RAW
669  /* raw input did not eat the packet? */
670  if (raw_input(p, inp) == 0)
671 #endif /* LWIP_RAW */
672  {
673  pbuf_header(p, -(s16_t)iphdr_hlen); /* Move to payload, no check necessary. */
674 
675 
676  switch (IPH_PROTO(iphdr)) {
677 #if LWIP_UDP
678  case IP_PROTO_UDP:
679 #if LWIP_UDPLITE
680  case IP_PROTO_UDPLITE:
681 #endif /* LWIP_UDPLITE */
682  MIB2_STATS_INC(mib2.ipindelivers);
683  udp_input(p, inp);
684  break;
685 #endif /* LWIP_UDP */
686 #if LWIP_TCP
687  case IP_PROTO_TCP:
688  MIB2_STATS_INC(mib2.ipindelivers);
689  tcp_input(p, inp);
690  break;
691 #endif /* LWIP_TCP */
692 #if LWIP_ICMP
693  case IP_PROTO_ICMP:
694  MIB2_STATS_INC(mib2.ipindelivers);
695  icmp_input(p, inp);
696  break;
697 #endif /* LWIP_ICMP */
698 #if LWIP_IGMP
699  case IP_PROTO_IGMP:
700  igmp_input(p, inp, ip4_current_dest_addr());
701  break;
702 #endif /* LWIP_IGMP */
703  default:
704 #if LWIP_ICMP
705  /* send ICMP destination protocol unreachable unless is was a broadcast */
706  if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) &&
707  !ip4_addr_ismulticast(ip4_current_dest_addr())) {
708  pbuf_header_force(p, iphdr_hlen); /* Move to ip header, no check necessary. */
709  p->payload = iphdr;
710  icmp_dest_unreach(p, ICMP_DUR_PROTO);
711  }
712 #endif /* LWIP_ICMP */
713  pbuf_free(p);
714 
715  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr)));
716 
717  IP_STATS_INC(ip.proterr);
718  IP_STATS_INC(ip.drop);
719  MIB2_STATS_INC(mib2.ipinunknownprotos);
720  }
721  }
722 
723  /* @todo: this is not really necessary... */
726  ip_data.current_ip4_header = NULL;
728  ip4_addr_set_any(ip4_current_src_addr());
729  ip4_addr_set_any(ip4_current_dest_addr());
730 
731  return ERR_OK;
732 }
733 
759 err_t
760 ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
761  u8_t ttl, u8_t tos,
762  u8_t proto, struct netif *netif)
763 {
764 #if IP_OPTIONS_SEND
765  return ip4_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
766 }
767 
774 err_t
775 ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
776  u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
777  u16_t optlen)
778 {
779 #endif /* IP_OPTIONS_SEND */
780  const ip4_addr_t *src_used = src;
781  if (dest != LWIP_IP_HDRINCL) {
782  if (ip4_addr_isany(src)) {
783  src_used = netif_ip4_addr(netif);
784  }
785  }
786 
787 #if IP_OPTIONS_SEND
788  return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif,
789  ip_options, optlen);
790 #else /* IP_OPTIONS_SEND */
791  return ip4_output_if_src(p, src_used, dest, ttl, tos, proto, netif);
792 #endif /* IP_OPTIONS_SEND */
793 }
794 
799 err_t
800 ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
801  u8_t ttl, u8_t tos,
802  u8_t proto, struct netif *netif)
803 {
804 #if IP_OPTIONS_SEND
805  return ip4_output_if_opt_src(p, src, dest, ttl, tos, proto, netif, NULL, 0);
806 }
807 
812 err_t
813 ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
814  u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
815  u16_t optlen)
816 {
817 #endif /* IP_OPTIONS_SEND */
818  struct ip_hdr *iphdr;
819  ip4_addr_t dest_addr;
820 #if CHECKSUM_GEN_IP_INLINE
821  u32_t chk_sum = 0;
822 #endif /* CHECKSUM_GEN_IP_INLINE */
823 
825 
826  MIB2_STATS_INC(mib2.ipoutrequests);
827 
828  /* Should the IP header be generated or is it already included in p? */
829  if (dest != LWIP_IP_HDRINCL) {
830  u16_t ip_hlen = IP_HLEN;
831 #if IP_OPTIONS_SEND
832  u16_t optlen_aligned = 0;
833  if (optlen != 0) {
834 #if CHECKSUM_GEN_IP_INLINE
835  int i;
836 #endif /* CHECKSUM_GEN_IP_INLINE */
837  /* round up to a multiple of 4 */
838  optlen_aligned = ((optlen + 3) & ~3);
839  ip_hlen += optlen_aligned;
840  /* First write in the IP options */
841  if (pbuf_header(p, optlen_aligned)) {
842  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output_if_opt: not enough room for IP options in pbuf\n"));
843  IP_STATS_INC(ip.err);
844  MIB2_STATS_INC(mib2.ipoutdiscards);
845  return ERR_BUF;
846  }
847  MEMCPY(p->payload, ip_options, optlen);
848  if (optlen < optlen_aligned) {
849  /* zero the remaining bytes */
850  memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
851  }
852 #if CHECKSUM_GEN_IP_INLINE
853  for (i = 0; i < optlen_aligned/2; i++) {
854  chk_sum += ((u16_t*)p->payload)[i];
855  }
856 #endif /* CHECKSUM_GEN_IP_INLINE */
857  }
858 #endif /* IP_OPTIONS_SEND */
859  /* generate IP header */
860  if (pbuf_header(p, IP_HLEN)) {
861  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output: not enough room for IP header in pbuf\n"));
862 
863  IP_STATS_INC(ip.err);
864  MIB2_STATS_INC(mib2.ipoutdiscards);
865  return ERR_BUF;
866  }
867 
868  iphdr = (struct ip_hdr *)p->payload;
869  LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
870  (p->len >= sizeof(struct ip_hdr)));
871 
872  IPH_TTL_SET(iphdr, ttl);
873  IPH_PROTO_SET(iphdr, proto);
874 #if CHECKSUM_GEN_IP_INLINE
875  chk_sum += PP_NTOHS(proto | (ttl << 8));
876 #endif /* CHECKSUM_GEN_IP_INLINE */
877 
878  /* dest cannot be NULL here */
879  ip4_addr_copy(iphdr->dest, *dest);
880 #if CHECKSUM_GEN_IP_INLINE
881  chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
882  chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
883 #endif /* CHECKSUM_GEN_IP_INLINE */
884 
885  IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
886  IPH_TOS_SET(iphdr, tos);
887 #if CHECKSUM_GEN_IP_INLINE
888  chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8));
889 #endif /* CHECKSUM_GEN_IP_INLINE */
890  IPH_LEN_SET(iphdr, lwip_htons(p->tot_len));
891 #if CHECKSUM_GEN_IP_INLINE
892  chk_sum += iphdr->_len;
893 #endif /* CHECKSUM_GEN_IP_INLINE */
894  IPH_OFFSET_SET(iphdr, 0);
895  IPH_ID_SET(iphdr, lwip_htons(ip_id));
896 #if CHECKSUM_GEN_IP_INLINE
897  chk_sum += iphdr->_id;
898 #endif /* CHECKSUM_GEN_IP_INLINE */
899  ++ip_id;
900 
901  if (src == NULL) {
902  ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY4);
903  } else {
904  /* src cannot be NULL here */
905  ip4_addr_copy(iphdr->src, *src);
906  }
907 
908 #if CHECKSUM_GEN_IP_INLINE
909  chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
910  chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
911  chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
912  chk_sum = (chk_sum >> 16) + chk_sum;
913  chk_sum = ~chk_sum;
914  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
915  iphdr->_chksum = (u16_t)chk_sum; /* network order */
916  }
917 #if LWIP_CHECKSUM_CTRL_PER_NETIF
918  else {
919  IPH_CHKSUM_SET(iphdr, 0);
920  }
921 #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/
922 #else /* CHECKSUM_GEN_IP_INLINE */
923  IPH_CHKSUM_SET(iphdr, 0);
924 #if CHECKSUM_GEN_IP
925  IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) {
926  IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
927  }
928 #endif /* CHECKSUM_GEN_IP */
929 #endif /* CHECKSUM_GEN_IP_INLINE */
930  } else {
931  /* IP header already included in p */
932  iphdr = (struct ip_hdr *)p->payload;
933  ip4_addr_copy(dest_addr, iphdr->dest);
934  dest = &dest_addr;
935  }
936 
937  IP_STATS_INC(ip.xmit);
938 
939  LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num));
940  ip4_debug_print(p);
941 
942 #if ENABLE_LOOPBACK
943  if (ip4_addr_cmp(dest, netif_ip4_addr(netif))
944 #if !LWIP_HAVE_LOOPIF
945  || ip4_addr_isloopback(dest)
946 #endif /* !LWIP_HAVE_LOOPIF */
947  ) {
948  /* Packet to self, enqueue it for loopback */
949  LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
950  return netif_loop_output(netif, p);
951  }
952 #if LWIP_MULTICAST_TX_OPTIONS
953  if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
954  netif_loop_output(netif, p);
955  }
956 #endif /* LWIP_MULTICAST_TX_OPTIONS */
957 #endif /* ENABLE_LOOPBACK */
958 #if IP_FRAG
959  /* don't fragment if interface has mtu set to 0 [loopif] */
960  if (netif->mtu && (p->tot_len > netif->mtu)) {
961  return ip4_frag(p, netif, dest);
962  }
963 #endif /* IP_FRAG */
964 
965  LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: call netif->output()\n"));
966  return netif->output(netif, p, dest);
967 }
968 
986 err_t
987 ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
988  u8_t ttl, u8_t tos, u8_t proto)
989 {
990  struct netif *netif;
991 
993 
994  if ((netif = ip4_route_src(dest, src)) == NULL) {
995  LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
996  ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
997  IP_STATS_INC(ip.rterr);
998  return ERR_RTE;
999  }
1000 
1001  return ip4_output_if(p, src, dest, ttl, tos, proto, netif);
1002 }
1003 
1004 #if LWIP_NETIF_HWADDRHINT
1005 
1023 err_t
1024 ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest,
1025  u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint)
1026 {
1027  struct netif *netif;
1028  err_t err;
1029 
1031 
1032  if ((netif = ip4_route_src(dest, src)) == NULL) {
1033  LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
1034  ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
1035  IP_STATS_INC(ip.rterr);
1036  return ERR_RTE;
1037  }
1038 
1039  NETIF_SET_HWADDRHINT(netif, addr_hint);
1040  err = ip4_output_if(p, src, dest, ttl, tos, proto, netif);
1042 
1043  return err;
1044 }
1045 #endif /* LWIP_NETIF_HWADDRHINT*/
1046 
1047 #if IP_DEBUG
1048 /* Print an IP header by using LWIP_DEBUGF
1049  * @param p an IP packet, p->payload pointing to the IP header
1050  */
1051 void
1052 ip4_debug_print(struct pbuf *p)
1053 {
1054  struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
1055 
1056  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
1057  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1058  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n",
1059  (u16_t)IPH_V(iphdr),
1060  (u16_t)IPH_HL(iphdr),
1061  (u16_t)IPH_TOS(iphdr),
1062  lwip_ntohs(IPH_LEN(iphdr))));
1063  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1064  LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n",
1065  lwip_ntohs(IPH_ID(iphdr)),
1066  (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1),
1067  (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1),
1068  (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1),
1069  (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)));
1070  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1071  LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n",
1072  (u16_t)IPH_TTL(iphdr),
1073  (u16_t)IPH_PROTO(iphdr),
1074  lwip_ntohs(IPH_CHKSUM(iphdr))));
1075  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1076  LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n",
1077  ip4_addr1_16(&iphdr->src),
1078  ip4_addr2_16(&iphdr->src),
1079  ip4_addr3_16(&iphdr->src),
1080  ip4_addr4_16(&iphdr->src)));
1081  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1082  LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n",
1083  ip4_addr1_16(&iphdr->dest),
1084  ip4_addr2_16(&iphdr->dest),
1085  ip4_addr3_16(&iphdr->dest),
1086  ip4_addr4_16(&iphdr->dest)));
1087  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
1088 }
1089 #endif /* IP_DEBUG */
1090 
1091 #endif /* LWIP_IPV4 */
IPH_TTL_SET
#define IPH_TTL_SET(hdr, ttl)
Definition: ip4.h:118
S16_F
#define S16_F
Definition: arch.h:151
lwip_ntohs
#define lwip_ntohs(x)
Definition: def.h:76
opt.h
pbuf::len
u16_t len
Definition: pbuf.h:159
udp_hdr
Definition: udp.h:53
s16_t
int16_t s16_t
Definition: arch.h:125
def.h
NETIF_FLAG_IGMP
#define NETIF_FLAG_IGMP
Definition: netif.h:106
PERF_STOP
#define PERF_STOP(x)
Definition: perf.h:21
PBUF_FLAG_LLBCAST
#define PBUF_FLAG_LLBCAST
Definition: pbuf.h:135
LWIP_ASSERT
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
ICMP_TE_TTL
Definition: icmp.h:73
LWIP_HAVE_LOOPIF
#define LWIP_HAVE_LOOPIF
Definition: lwipopts.h:231
ERR_BUF
Definition: err.h:67
u16_t
uint16_t u16_t
Definition: arch.h:124
string.h
PERF_START
#define PERF_START
Definition: perf.h:20
igmp.h
ip_globals::current_ip_header_tot_len
u16_t current_ip_header_tot_len
Definition: ip.h:120
ip4_frag.h
autoip.h
pbuf::tot_len
u16_t tot_len
Definition: pbuf.h:156
IPH_ID_SET
#define IPH_ID_SET(hdr, id)
Definition: ip4.h:116
u32_t
uint32_t u32_t
Definition: arch.h:126
PBUF_FLAG_MCASTLOOP
#define PBUF_FLAG_MCASTLOOP
Definition: pbuf.h:133
pbuf_free
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:715
netif::mtu
u16_t mtu
Definition: netif.h:307
LWIP_DBG_TRACE
#define LWIP_DBG_TRACE
Definition: debug.h:83
ip_data
struct ip_globals ip_data
raw.h
IP_STATS_INC
#define IP_STATS_INC(x)
Definition: stats.h:360
netif::flags
u8_t flags
Definition: netif.h:313
kpanic
void kpanic(const char *fmt,...)
print panic message and halt system
Definition: kpanic.c:41
NETIF_SET_HWADDRHINT
#define NETIF_SET_HWADDRHINT(netif, hint)
Definition: netif.h:475
X16_F
#define X16_F
Definition: arch.h:154
IP_HLEN
#define IP_HLEN
Definition: ip4.h:64
IF__NETIF_CHECKSUM_ENABLED
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag)
Definition: netif.h:357
icmp.h
pbuf::flags
u8_t flags
Definition: pbuf.h:165
ip_hdr
Definition: ip4.h:71
stats.h
IPH_HL
#define IPH_HL(hdr)
Definition: ip4.h:103
LWIP_DBG_LEVEL_SERIOUS
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:57
netif.h
IPH_V
#define IPH_V(hdr)
Definition: ip4.h:102
IP_PROTO_TCP
#define IP_PROTO_TCP
Definition: ip.h:46
netif::num
u8_t num
Definition: netif.h:317
IP_OFFMASK
#define IP_OFFMASK
Definition: ip4.h:85
netif_is_link_up
#define netif_is_link_up(netif)
Definition: netif.h:421
PBUF_FLAG_LLMCAST
#define PBUF_FLAG_LLMCAST
Definition: pbuf.h:137
u8_t
uint8_t u8_t
Definition: arch.h:122
IP_PROTO_ICMP
#define IP_PROTO_ICMP
Definition: ip.h:42
ICMP_DUR_FRAG
Definition: icmp.h:65
tcp_priv.h
ip_globals::current_input_netif
struct netif * current_input_netif
Definition: ip.h:110
ICMP_DUR_PROTO
Definition: icmp.h:61
netif
Definition: netif.h:233
pbuf_realloc
void pbuf_realloc(struct pbuf *p, u16_t size)
Definition: pbuf.c:493
ip_globals::current_iphdr_src
ip_addr_t current_iphdr_src
Definition: ip.h:122
MIB2_STATS_INC
#define MIB2_STATS_INC(x)
Definition: stats.h:467
LWIP_UNUSED_ARG
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:315
IPH_LEN_SET
#define IPH_LEN_SET(hdr, len)
Definition: ip4.h:115
lwip_htonl
u32_t lwip_htonl(u32_t n)
Definition: def.c:88
netif::name
char name[2]
Definition: netif.h:315
IP_MF
#define IP_MF
Definition: ip4.h:84
IPH_ID
#define IPH_ID(hdr)
Definition: ip4.h:106
lwip_htons
u16_t lwip_htons(u16_t n)
Definition: def.c:75
IPH_TOS
#define IPH_TOS(hdr)
Definition: ip4.h:104
netif::next
struct netif * next
Definition: netif.h:235
PP_NTOHS
#define PP_NTOHS(x)
Definition: def.h:80
IPH_VHL_SET
#define IPH_VHL_SET(hdr, v, hl)
Definition: ip4.h:113
IPH_PROTO
#define IPH_PROTO(hdr)
Definition: ip4.h:109
netif_list
struct netif * netif_list
Definition: netif.c:104
U16_F
#define U16_F
Definition: arch.h:148
ERR_OK
Definition: err.h:63
dhcp.h
IP_PROTO_UDPLITE
#define IP_PROTO_UDPLITE
Definition: ip.h:45
err_t
s8_t err_t
Definition: err.h:57
ip.h
IPH_TOS_SET
#define IPH_TOS_SET(hdr, tos)
Definition: ip4.h:114
IPH_CHKSUM_SET
#define IPH_CHKSUM_SET(hdr, chksum)
Definition: ip4.h:120
IPH_TTL
#define IPH_TTL(hdr)
Definition: ip4.h:108
IPH_OFFSET
#define IPH_OFFSET(hdr)
Definition: ip4.h:107
IP_DF
#define IP_DF
Definition: ip4.h:83
udp.h
IP_PROTO_IGMP
#define IP_PROTO_IGMP
Definition: ip.h:43
inet_chksum
u16_t inet_chksum(const void *dataptr, u16_t len)
Definition: inet_chksum.c:555
ip_globals::current_iphdr_dest
ip_addr_t current_iphdr_dest
Definition: ip.h:124
MEMCPY
#define MEMCPY(dst, src, len)
Definition: lwipopts.h:43
LWIP_DBG_LEVEL_WARNING
#define LWIP_DBG_LEVEL_WARNING
Definition: debug.h:55
memset
void * memset(void *dst, int c, size_t length)
LWIP_NETIF_LOOPBACK
#define LWIP_NETIF_LOOPBACK
Definition: lwipopts.h:235
IPH_LEN
#define IPH_LEN(hdr)
Definition: ip4.h:105
IPH_PROTO_SET
#define IPH_PROTO_SET(hdr, proto)
Definition: ip4.h:119
net
Definition: device.old.h:42
LWIP_IP_HDRINCL
#define LWIP_IP_HDRINCL
Definition: ip.h:58
IP_DEBUG
#define IP_DEBUG
Definition: lwipopts.h:449
X32_F
#define X32_F
Definition: arch.h:163
pbuf_header_force
u8_t pbuf_header_force(struct pbuf *p, s16_t header_size)
Definition: pbuf.c:675
mem.h
PP_HTONL
#define PP_HTONL(x)
Definition: def.h:81
LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX
#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p)
Definition: ip.h:63
ERR_RTE
Definition: err.h:71
ip_globals::current_netif
struct netif * current_netif
Definition: ip.h:108
pbuf
Definition: pbuf.h:142
LWIP_DEBUGF
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:164
IPH_CHKSUM
#define IPH_CHKSUM(hdr)
Definition: ip4.h:110
IPH_OFFSET_SET
#define IPH_OFFSET_SET(hdr, off)
Definition: ip4.h:117
inet_chksum.h
pbuf_header
u8_t pbuf_header(struct pbuf *p, s16_t header_size)
Definition: pbuf.c:665
pbuf::payload
void * payload
Definition: pbuf.h:147
netif_is_up
#define netif_is_up(netif)
Definition: netif.h:409
IP_PROTO_UDP
#define IP_PROTO_UDP
Definition: ip.h:44
PP_HTONS
#define PP_HTONS(x)
Definition: def.h:79
NETIF_FLAG_BROADCAST
#define NETIF_FLAG_BROADCAST
Definition: netif.h:89
netif_default
struct netif * netif_default
Definition: netif.c:105
NULL
#define NULL
Definition: fat_string.h:17