ReactOS  0.4.13-dev-479-gec9c8fd
ip.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 "lwip/opt.h"
42 #include "lwip/ip.h"
43 #include "lwip/def.h"
44 #include "lwip/mem.h"
45 #include "lwip/ip_frag.h"
46 #include "lwip/inet_chksum.h"
47 #include "lwip/netif.h"
48 #include "lwip/icmp.h"
49 #include "lwip/igmp.h"
50 #include "lwip/raw.h"
51 #include "lwip/udp.h"
52 #include "lwip/tcp_impl.h"
53 #include "lwip/snmp.h"
54 #include "lwip/dhcp.h"
55 #include "lwip/autoip.h"
56 #include "lwip/stats.h"
57 #include "arch/perf.h"
58 
59 #include <string.h>
60 
63 #ifndef LWIP_INLINE_IP_CHKSUM
64 #define LWIP_INLINE_IP_CHKSUM 1
65 #endif
66 #if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP
67 #define CHECKSUM_GEN_IP_INLINE 1
68 #else
69 #define CHECKSUM_GEN_IP_INLINE 0
70 #endif
71 
72 #if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT)
73 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 1
74 
80 #if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT)
81 /* accept DHCP client port and custom port */
82 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \
83  || (LWIP_IP_ACCEPT_UDP_PORT(port)))
84 #elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
85 /* accept custom port only */
86 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port))
87 #else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
88 /* accept DHCP client port only */
89 #define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT))
90 #endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */
91 
92 #else /* LWIP_DHCP */
93 #define IP_ACCEPT_LINK_LAYER_ADDRESSING 0
94 #endif /* LWIP_DHCP */
95 
101 
105 const struct ip_hdr *current_header;
110 
112 static u16_t ip_id;
113 
123 struct netif *
125 {
126  struct netif *netif;
127 
128 #ifdef LWIP_HOOK_IP4_ROUTE
129  netif = LWIP_HOOK_IP4_ROUTE(dest);
130  if (netif != NULL) {
131  return netif;
132  }
133 #endif
134 
135  /* iterate through netifs */
136  for (netif = netif_list; netif != NULL; netif = netif->next) {
137  /* network mask matches? */
138  if (netif_is_up(netif)) {
139  if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
140  /* return netif on which to forward IP packet */
141  return netif;
142  }
143  }
144  }
145  if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
146  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
148  IP_STATS_INC(ip.rterr);
150  return NULL;
151  }
152  /* no matching netif found, use default netif */
153  return netif_default;
154 }
155 
156 #if IP_FORWARD
157 
165 static int
166 ip_canforward(struct pbuf *p)
167 {
169 
170  if (p->flags & PBUF_FLAG_LLBCAST) {
171  /* don't route link-layer broadcasts */
172  return 0;
173  }
174  if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) {
175  /* don't route link-layer multicasts unless the destination address is an IP
176  multicast address */
177  return 0;
178  }
179  if (IP_EXPERIMENTAL(addr)) {
180  return 0;
181  }
182  if (IP_CLASSA(addr)) {
184  if ((net == 0) || (net == (IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) {
185  /* don't route loopback packets */
186  return 0;
187  }
188  }
189  return 1;
190 }
191 
201 static void
202 ip_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp)
203 {
204  struct netif *netif;
205 
206  PERF_START;
207 
208  if (!ip_canforward(p)) {
209  goto return_noroute;
210  }
211 
212  /* RFC3927 2.7: do not forward link-local addresses */
214  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
217  goto return_noroute;
218  }
219 
220  /* Find network interface where to forward this IP packet to. */
222  if (netif == NULL) {
223  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n",
226  /* @todo: send ICMP_DUR_NET? */
227  goto return_noroute;
228  }
229 #if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF
230  /* Do not forward packets onto the same network interface on which
231  * they arrived. */
232  if (netif == inp) {
233  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: not bouncing packets back on incoming interface.\n"));
234  goto return_noroute;
235  }
236 #endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */
237 
238  /* decrement TTL */
239  IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1);
240  /* send ICMP if TTL == 0 */
241  if (IPH_TTL(iphdr) == 0) {
243 #if LWIP_ICMP
244  /* Don't send ICMP messages in response to ICMP messages */
245  if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) {
246  icmp_time_exceeded(p, ICMP_TE_TTL);
247  }
248 #endif /* LWIP_ICMP */
249  return;
250  }
251 
252  /* Incrementally update the IP checksum. */
253  if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) {
254  IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1);
255  } else {
256  IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100));
257  }
258 
259  LWIP_DEBUGF(IP_DEBUG, ("ip_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
262 
263  IP_STATS_INC(ip.fw);
264  IP_STATS_INC(ip.xmit);
266 
267  PERF_STOP("ip_forward");
268  /* don't fragment if interface has mtu set to 0 [loopif] */
269  if (netif->mtu && (p->tot_len > netif->mtu)) {
270  if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) {
271 #if IP_FRAG
272  ip_frag(p, netif, ip_current_dest_addr());
273 #else /* IP_FRAG */
274  /* @todo: send ICMP Destination Unreacheable code 13 "Communication administratively prohibited"? */
275 #endif /* IP_FRAG */
276  } else {
277  /* send ICMP Destination Unreacheable code 4: "Fragmentation Needed and DF Set" */
278  icmp_dest_unreach(p, ICMP_DUR_FRAG);
279  }
280  return;
281  }
282  /* transmit pbuf on chosen interface */
284  return;
285 return_noroute:
287 }
288 #endif /* IP_FORWARD */
289 
304 err_t
305 ip_input(struct pbuf *p, struct netif *inp)
306 {
307  struct ip_hdr *iphdr;
308  struct netif *netif;
309  u16_t iphdr_hlen;
310  u16_t iphdr_len;
311 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
312  int check_ip_src=1;
313 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
314 
315  IP_STATS_INC(ip.recv);
317 
318  /* identify the IP header */
319  iphdr = (struct ip_hdr *)p->payload;
320  if (IPH_V(iphdr) != 4) {
321  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
322  ip_debug_print(p);
323  pbuf_free(p);
324  IP_STATS_INC(ip.err);
325  IP_STATS_INC(ip.drop);
327  return ERR_OK;
328  }
329 
330 #ifdef LWIP_HOOK_IP4_INPUT
331  if (LWIP_HOOK_IP4_INPUT(p, inp)) {
332  /* the packet has been eaten */
333  return ERR_OK;
334  }
335 #endif
336 
337  /* obtain IP header length in number of 32-bit words */
338  iphdr_hlen = IPH_HL(iphdr);
339  /* calculate IP header length in bytes */
340  iphdr_hlen *= 4;
341  /* obtain ip length in bytes */
342  iphdr_len = ntohs(IPH_LEN(iphdr));
343 
344  /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
345  if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) {
346  if (iphdr_hlen > p->len) {
348  ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
349  iphdr_hlen, p->len));
350  }
351  if (iphdr_len > p->tot_len) {
353  ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
354  iphdr_len, p->tot_len));
355  }
356  /* free (drop) packet pbufs */
357  pbuf_free(p);
358  IP_STATS_INC(ip.lenerr);
359  IP_STATS_INC(ip.drop);
361  return ERR_OK;
362  }
363 
364  /* verify checksum */
365 #if CHECKSUM_CHECK_IP
366  if (inet_chksum(iphdr, iphdr_hlen) != 0) {
367 
369  ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
370  ip_debug_print(p);
371  pbuf_free(p);
372  IP_STATS_INC(ip.chkerr);
373  IP_STATS_INC(ip.drop);
375  return ERR_OK;
376  }
377 #endif
378 
379  /* Trim pbuf. This should have been done at the netif layer,
380  * but we'll do it anyway just to be sure that its done. */
381  pbuf_realloc(p, iphdr_len);
382 
383  /* copy IP addresses to aligned ip_addr_t */
385  ip_addr_copy(current_iphdr_src, iphdr->src);
386 
387  /* match packet against an interface, i.e. is this packet for us? */
388 #if LWIP_IGMP
390  if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &current_iphdr_dest))) {
391  netif = inp;
392  } else {
393  netif = NULL;
394  }
395  } else
396 #endif /* LWIP_IGMP */
397  {
398  /* start trying with inp. if that's not acceptable, start walking the
399  list of configured netifs.
400  'first' is used as a boolean to mark whether we started walking the list */
401  int first = 1;
402  netif = inp;
403  do {
404  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",
409 
410  /* interface is up and configured? */
411  if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) {
412  /* unicast to this interface address? */
414  /* or broadcast on this interface network address? */
416  LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
417  netif->name[0], netif->name[1]));
418  /* break out of for loop */
419  break;
420  }
421 #if LWIP_AUTOIP
422  /* connections to link-local addresses must persist after changing
423  the netif's address (RFC3927 ch. 1.9) */
424  if ((netif->autoip != NULL) &&
425  ip_addr_cmp(&current_iphdr_dest, &(netif->autoip->llipaddr))) {
426  LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n",
427  netif->name[0], netif->name[1]));
428  /* break out of for loop */
429  break;
430  }
431 #endif /* LWIP_AUTOIP */
432  }
433  if (first) {
434  first = 0;
435  netif = netif_list;
436  } else {
437  netif = netif->next;
438  }
439  if (netif == inp) {
440  netif = netif->next;
441  }
442  } while(netif != NULL);
443  }
444 
445 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
446  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
447  * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
448  * According to RFC 1542 section 3.1.1, referred by RFC 2131).
449  *
450  * If you want to accept private broadcast communication while a netif is down,
451  * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.:
452  *
453  * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345))
454  */
455  if (netif == NULL) {
456  /* remote port is DHCP server? */
457  if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
458  struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen);
459  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
460  ntohs(udphdr->dest)));
461  if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
462  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n"));
463  netif = inp;
464  check_ip_src = 0;
465  }
466  }
467  }
468 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
469 
470  /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
471 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
472  /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
473  if (check_ip_src && !ip_addr_isany(&current_iphdr_src))
474 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
475  { if ((ip_addr_isbroadcast(&current_iphdr_src, inp)) ||
477  /* packet source is not valid */
478  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n"));
479  /* free (drop) packet pbufs */
480  pbuf_free(p);
481  IP_STATS_INC(ip.drop);
484  return ERR_OK;
485  }
486  }
487 
488  /* packet not for us? */
489  if (netif == NULL) {
490  /* packet not for us, route or discard */
491  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n"));
492 #if IP_FORWARD
493  /* non-broadcast packet? */
495  /* try to forward IP packet on (other) interfaces */
496  ip_forward(p, iphdr, inp);
497  } else
498 #endif /* IP_FORWARD */
499  {
502  }
503  pbuf_free(p);
504  return ERR_OK;
505  }
506  /* packet consists of multiple fragments? */
507  if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
508 #if IP_REASSEMBLY /* packet fragment reassembly code present? */
509  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 ip_reass()\n",
510  ntohs(IPH_ID(iphdr)), p->tot_len, ntohs(IPH_LEN(iphdr)), !!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8));
511  /* reassemble the packet*/
512  p = ip_reass(p);
513  /* packet not fully reassembled yet? */
514  if (p == NULL) {
515  return ERR_OK;
516  }
517  iphdr = (struct ip_hdr *)p->payload;
518 #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
519  pbuf_free(p);
520  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
521  ntohs(IPH_OFFSET(iphdr))));
522  IP_STATS_INC(ip.opterr);
523  IP_STATS_INC(ip.drop);
524  /* unsupported protocol feature */
526  return ERR_OK;
527 #endif /* IP_REASSEMBLY */
528  }
529 
530 #if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */
531 
532 #if LWIP_IGMP
533  /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
534  if((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
535 #else
536  if (iphdr_hlen > IP_HLEN) {
537 #endif /* LWIP_IGMP */
538  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
539  pbuf_free(p);
540  IP_STATS_INC(ip.opterr);
541  IP_STATS_INC(ip.drop);
542  /* unsupported protocol feature */
544  return ERR_OK;
545  }
546 #endif /* IP_OPTIONS_ALLOWED == 0 */
547 
548  /* send to upper layers */
549  LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
550  ip_debug_print(p);
551  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
552 
553  current_netif = inp;
554  current_header = iphdr;
555 
556 #if LWIP_RAW
557  /* raw input did not eat the packet? */
558  if (raw_input(p, inp) == 0)
559 #endif /* LWIP_RAW */
560  {
561  switch (IPH_PROTO(iphdr)) {
562 #if LWIP_UDP
563  case IP_PROTO_UDP:
564 #if LWIP_UDPLITE
565  case IP_PROTO_UDPLITE:
566 #endif /* LWIP_UDPLITE */
568  udp_input(p, inp);
569  break;
570 #endif /* LWIP_UDP */
571 #if LWIP_TCP
572  case IP_PROTO_TCP:
574  tcp_input(p, inp);
575  break;
576 #endif /* LWIP_TCP */
577 #if LWIP_ICMP
578  case IP_PROTO_ICMP:
580  icmp_input(p, inp);
581  break;
582 #endif /* LWIP_ICMP */
583 #if LWIP_IGMP
584  case IP_PROTO_IGMP:
585  igmp_input(p, inp, &current_iphdr_dest);
586  break;
587 #endif /* LWIP_IGMP */
588  default:
589 #if LWIP_ICMP
590  /* send ICMP destination protocol unreachable unless is was a broadcast */
593  p->payload = iphdr;
594  icmp_dest_unreach(p, ICMP_DUR_PROTO);
595  }
596 #endif /* LWIP_ICMP */
597  pbuf_free(p);
598 
599  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));
600 
601  IP_STATS_INC(ip.proterr);
602  IP_STATS_INC(ip.drop);
604  }
605  }
606 
611 
612  return ERR_OK;
613 }
614 
640 err_t
642  u8_t ttl, u8_t tos,
643  u8_t proto, struct netif *netif)
644 {
645 #if IP_OPTIONS_SEND
646  return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
647 }
648 
655 err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
656  u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
657  u16_t optlen)
658 {
659 #endif /* IP_OPTIONS_SEND */
660  struct ip_hdr *iphdr;
661  ip_addr_t dest_addr;
662 #if CHECKSUM_GEN_IP_INLINE
663  u32_t chk_sum = 0;
664 #endif /* CHECKSUM_GEN_IP_INLINE */
665 
666  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
667  gets altered as the packet is passed down the stack */
668  LWIP_ASSERT("p->ref == 1", p->ref == 1);
669 
671 
672  /* Should the IP header be generated or is it already included in p? */
673  if (dest != IP_HDRINCL) {
674  u16_t ip_hlen = IP_HLEN;
675 #if IP_OPTIONS_SEND
676  u16_t optlen_aligned = 0;
677  if (optlen != 0) {
678 #if CHECKSUM_GEN_IP_INLINE
679  int i;
680 #endif /* CHECKSUM_GEN_IP_INLINE */
681  /* round up to a multiple of 4 */
682  optlen_aligned = ((optlen + 3) & ~3);
683  ip_hlen += optlen_aligned;
684  /* First write in the IP options */
685  if (pbuf_header(p, optlen_aligned)) {
686  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n"));
687  IP_STATS_INC(ip.err);
689  return ERR_BUF;
690  }
691  MEMCPY(p->payload, ip_options, optlen);
692  if (optlen < optlen_aligned) {
693  /* zero the remaining bytes */
694  memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
695  }
696 #if CHECKSUM_GEN_IP_INLINE
697  for (i = 0; i < optlen_aligned/2; i++) {
698  chk_sum += ((u16_t*)p->payload)[i];
699  }
700 #endif /* CHECKSUM_GEN_IP_INLINE */
701  }
702 #endif /* IP_OPTIONS_SEND */
703  /* generate IP header */
704  if (pbuf_header(p, IP_HLEN)) {
705  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n"));
706 
707  IP_STATS_INC(ip.err);
709  return ERR_BUF;
710  }
711 
712  iphdr = (struct ip_hdr *)p->payload;
713  LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
714  (p->len >= sizeof(struct ip_hdr)));
715 
716  IPH_TTL_SET(iphdr, ttl);
717  IPH_PROTO_SET(iphdr, proto);
718 #if CHECKSUM_GEN_IP_INLINE
719  chk_sum += LWIP_MAKE_U16(proto, ttl);
720 #endif /* CHECKSUM_GEN_IP_INLINE */
721 
722  /* dest cannot be NULL here */
723  ip_addr_copy(iphdr->dest, *dest);
724 #if CHECKSUM_GEN_IP_INLINE
725  chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
726  chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
727 #endif /* CHECKSUM_GEN_IP_INLINE */
728 
729  IPH_VHL_SET(iphdr, 4, ip_hlen / 4);
730  IPH_TOS_SET(iphdr, tos);
731 #if CHECKSUM_GEN_IP_INLINE
732  chk_sum += LWIP_MAKE_U16(tos, iphdr->_v_hl);
733 #endif /* CHECKSUM_GEN_IP_INLINE */
734  IPH_LEN_SET(iphdr, htons(p->tot_len));
735 #if CHECKSUM_GEN_IP_INLINE
736  chk_sum += iphdr->_len;
737 #endif /* CHECKSUM_GEN_IP_INLINE */
738  IPH_OFFSET_SET(iphdr, 0);
739  IPH_ID_SET(iphdr, htons(ip_id));
740 #if CHECKSUM_GEN_IP_INLINE
741  chk_sum += iphdr->_id;
742 #endif /* CHECKSUM_GEN_IP_INLINE */
743  ++ip_id;
744 
745  if (ip_addr_isany(src)) {
746  ip_addr_copy(iphdr->src, netif->ip_addr);
747  } else {
748  /* src cannot be NULL here */
749  ip_addr_copy(iphdr->src, *src);
750  }
751 
752 #if CHECKSUM_GEN_IP_INLINE
753  chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
754  chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
755  chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
756  chk_sum = (chk_sum >> 16) + chk_sum;
757  chk_sum = ~chk_sum;
758  iphdr->_chksum = chk_sum; /* network order */
759 #else /* CHECKSUM_GEN_IP_INLINE */
760  IPH_CHKSUM_SET(iphdr, 0);
761 #if CHECKSUM_GEN_IP
762  IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
763 #endif
764 #endif /* CHECKSUM_GEN_IP_INLINE */
765  } else {
766  /* IP header already included in p */
767  iphdr = (struct ip_hdr *)p->payload;
768  ip_addr_copy(dest_addr, iphdr->dest);
769  dest = &dest_addr;
770  }
771 
772  IP_STATS_INC(ip.xmit);
773 
774  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
775  ip_debug_print(p);
776 
777 #if ENABLE_LOOPBACK
778  if (ip_addr_cmp(dest, &netif->ip_addr)) {
779  /* Packet to self, enqueue it for loopback */
780  LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
781  return netif_loop_output(netif, p, dest);
782  }
783 #if LWIP_IGMP
784  if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
785  netif_loop_output(netif, p, dest);
786  }
787 #endif /* LWIP_IGMP */
788 #endif /* ENABLE_LOOPBACK */
789 #if IP_FRAG
790  /* don't fragment if interface has mtu set to 0 [loopif] */
791  if (netif->mtu && (p->tot_len > netif->mtu)) {
792  return ip_frag(p, netif, dest);
793  }
794 #endif /* IP_FRAG */
795 
796  LWIP_DEBUGF(IP_DEBUG, ("netif->output()"));
797  return netif->output(netif, p, dest);
798 }
799 
817 err_t
819  u8_t ttl, u8_t tos, u8_t proto)
820 {
821  struct netif *netif;
822 
823  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
824  gets altered as the packet is passed down the stack */
825  LWIP_ASSERT("p->ref == 1", p->ref == 1);
826 
827  if ((netif = ip_route(dest)) == NULL) {
828  LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
830  IP_STATS_INC(ip.rterr);
831  return ERR_RTE;
832  }
833 
834  return ip_output_if(p, src, dest, ttl, tos, proto, netif);
835 }
836 
837 #if LWIP_NETIF_HWADDRHINT
838 
856 err_t
857 ip_output_hinted(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
858  u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint)
859 {
860  struct netif *netif;
861  err_t err;
862 
863  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
864  gets altered as the packet is passed down the stack */
865  LWIP_ASSERT("p->ref == 1", p->ref == 1);
866 
867  if ((netif = ip_route(dest)) == NULL) {
868  LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
870  IP_STATS_INC(ip.rterr);
871  return ERR_RTE;
872  }
873 
874  NETIF_SET_HWADDRHINT(netif, addr_hint);
875  err = ip_output_if(p, src, dest, ttl, tos, proto, netif);
877 
878  return err;
879 }
880 #endif /* LWIP_NETIF_HWADDRHINT*/
881 
882 #if IP_DEBUG
883 /* Print an IP header by using LWIP_DEBUGF
884  * @param p an IP packet, p->payload pointing to the IP header
885  */
886 void
887 ip_debug_print(struct pbuf *p)
888 {
889  struct ip_hdr *iphdr = (struct ip_hdr *)p->payload;
890 
891  LWIP_DEBUGF(IP_DEBUG, ("IP header:\n"));
892  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
893  LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n",
894  IPH_V(iphdr),
895  IPH_HL(iphdr),
896  IPH_TOS(iphdr),
897  ntohs(IPH_LEN(iphdr))));
898  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
899  LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n",
900  ntohs(IPH_ID(iphdr)),
901  ntohs(IPH_OFFSET(iphdr)) >> 15 & 1,
902  ntohs(IPH_OFFSET(iphdr)) >> 14 & 1,
903  ntohs(IPH_OFFSET(iphdr)) >> 13 & 1,
904  ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK));
905  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
906  LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n",
907  IPH_TTL(iphdr),
908  IPH_PROTO(iphdr),
909  ntohs(IPH_CHKSUM(iphdr))));
910  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
911  LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n",
912  ip4_addr1_16(&iphdr->src),
913  ip4_addr2_16(&iphdr->src),
914  ip4_addr3_16(&iphdr->src),
915  ip4_addr4_16(&iphdr->src)));
916  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
917  LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n",
918  ip4_addr1_16(&iphdr->dest),
919  ip4_addr2_16(&iphdr->dest),
920  ip4_addr3_16(&iphdr->dest),
921  ip4_addr4_16(&iphdr->dest)));
922  LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n"));
923 }
924 #endif /* IP_DEBUG */
#define ip_addr_islinklocal(addr1)
Definition: ip_addr.h:210
#define X32_F
Definition: cc.h:41
struct netif * netif_list
Definition: netif.c:75
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
#define IP_LOOPBACKNET
Definition: ip_addr.h:134
#define IPH_TTL(hdr)
Definition: ip.h:152
#define IPH_ID(hdr)
Definition: ip.h:150
#define snmp_inc_ipinunknownprotos()
Definition: snmp.h:265
#define ERR_RTE
Definition: err.h:56
#define IP_PROTO_UDPLITE
Definition: ip.h:55
#define S16_F
Definition: cc.h:37
struct netif * netif_default
Definition: netif.c:76
#define IPH_PROTO(hdr)
Definition: ip.h:153
#define IPH_OFFSET(hdr)
Definition: ip.h:151
#define IP_PROTO_ICMP
Definition: ip.h:52
const GLint * first
Definition: glext.h:5794
const struct ip_hdr * current_header
Definition: ip.c:105
#define IPH_TOS_SET(hdr, tos)
Definition: ip.h:157
#define IPH_TTL_SET(hdr, ttl)
Definition: ip.h:161
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
Definition: pbuf.c:511
void pbuf_realloc(struct pbuf *p, u16_t new_len)
Definition: pbuf.c:430
err_t ip_input(struct pbuf *p, struct netif *inp)
Definition: ip.c:305
#define snmp_inc_ipoutnoroutes()
Definition: snmp.h:270
#define ip4_addr1_16(ipaddr)
Definition: ip_addr.h:226
#define snmp_inc_ipoutdiscards()
Definition: snmp.h:269
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
#define PBUF_FLAG_LLBCAST
Definition: pbuf.h:73
netif_output_fn output
Definition: netif.h:151
#define IP_EXPERIMENTAL(a)
Definition: ip_addr.h:131
#define IP_CLASSA_NSHIFT
Definition: ip_addr.h:110
static u16_t ip_id
Definition: ip.c:112
u8_t num
Definition: netif.h:196
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
#define ntohs(x)
Definition: module.h:208
#define IP_DF
Definition: dhcpd.h:70
#define IPH_VHL_SET(hdr, v, hl)
Definition: ip.h:156
struct netif * ip_route(ip_addr_t *dest)
Definition: ip.c:124
ip_addr_t current_iphdr_dest
Definition: ip.c:109
#define IP_PROTO_IGMP
Definition: ip.h:53
#define PERF_START
Definition: perf.h:3
#define ip_addr_isbroadcast(ipaddr, netif)
Definition: ip_addr.h:202
#define IP_DEBUG
Definition: opt.h:1961
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IPH_TOS(hdr)
Definition: ip.h:148
#define IP_HDRINCL
Definition: ws2ipdef.h:28
#define IP_PROTO_TCP
Definition: ip.h:56
#define snmp_inc_ipindiscards()
Definition: snmp.h:266
#define IP_MULTICAST(a)
Definition: ip_addr.h:129
#define PBUF_FLAG_MCASTLOOP
Definition: pbuf.h:71
smooth NULL
Definition: ftsmooth.c:416
#define snmp_inc_ipinreceives()
Definition: snmp.h:261
#define IPH_CHKSUM(hdr)
Definition: ip.h:154
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
s8_t err_t
Definition: err.h:47
#define IP_HLEN
Definition: ip.h:50
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:95
#define PP_HTONS(x)
Definition: def.h:88
err_t ip_output_if(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto, struct netif *netif)
Definition: ip.c:641
#define snmp_inc_ipindelivers()
Definition: snmp.h:267
#define snmp_inc_ipoutrequests()
Definition: snmp.h:268
#define ip4_addr2_16(ipaddr)
Definition: ip_addr.h:227
u16_t inet_chksum(void *dataptr, u16_t len)
Definition: inet_chksum.c:396
Definition: dhcpd.h:79
#define U16_F
Definition: cc.h:36
#define snmp_inc_ipinhdrerrors()
Definition: snmp.h:262
#define ERR_OK
Definition: err.h:52
struct netif * next
Definition: netif.h:138
Definition: dhcpd.h:61
#define NETIF_SET_HWADDRHINT(netif, hint)
Definition: netif.h:321
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define ip_addr_ismulticast(addr1)
Definition: ip_addr.h:208
Definition: pbuf.h:79
#define IPH_V(hdr)
Definition: ip.h:146
unsigned long u32_t
Definition: cc.h:25
u8_t flags
Definition: netif.h:192
#define MEMCPY(DST, SRC, BYTES)
Definition: macros.h:231
#define X16_F
Definition: cc.h:38
#define IP_PROTO_UDP
Definition: ip.h:54
Definition: netif.h:136
#define NETIF_FLAG_IGMP
Definition: netif.h:95
ip_addr_t ip_addr
Definition: netif.h:141
#define LWIP_DBG_LEVEL_WARNING
Definition: debug.h:46
#define ip4_addr3_16(ipaddr)
Definition: ip_addr.h:228
GLenum const GLvoid * addr
Definition: glext.h:9621
#define PBUF_FLAG_LLMCAST
Definition: pbuf.h:75
#define snmp_inc_ipinaddrerrors()
Definition: snmp.h:263
struct ip_addr src dest
Definition: ip.h:96
u16_t mtu
Definition: netif.h:186
GLenum src
Definition: glext.h:6340
#define err(...)
static TNetwork net
Definition: tncon.cpp:351
err_t ip_output(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto)
Definition: ip.c:818
#define ip4_addr4_16(ipaddr)
Definition: ip_addr.h:229
#define IP_MF
Definition: dhcpd.h:71
#define IPH_OFFSET_SET(hdr, off)
Definition: ip.h:160
#define IPH_ID_SET(hdr, id)
Definition: ip.h:159
#define ip_addr_isany(addr1)
Definition: ip_addr.h:200
Definition: ip.h:116
#define PP_NTOHS(x)
Definition: def.h:89
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:47
#define ip_addr_cmp(addr1, addr2)
Definition: ip_addr.h:198
#define IPH_HL(hdr)
Definition: ip.h:147
#define ERR_BUF
Definition: err.h:54
ip_addr_t current_iphdr_src
Definition: ip.c:107
unsigned char u8_t
Definition: cc.h:23
#define LWIP_DBG_TRACE
Definition: debug.h:57
#define IPH_LEN(hdr)
Definition: ip.h:149
#define IP_STATS_INC(x)
Definition: stats.h:203
struct netif * current_netif
Definition: ip.c:100
char name[2]
Definition: netif.h:194
#define IP_CLASSA(a)
Definition: ip_addr.h:108
#define IPH_CHKSUM_SET(hdr, chksum)
Definition: ip.h:163
ip_addr_t netmask
Definition: netif.h:142
#define ip_debug_print(p)
Definition: ip.h:214
#define netif_is_up(netif)
Definition: netif.h:282
#define IPH_PROTO_SET(hdr, proto)
Definition: ip.h:162
#define IP_CLASSA_NET
Definition: ip_addr.h:109
static char * dest
Definition: rtl.c:135
unsigned short u16_t
Definition: cc.h:24
#define IP_OFFMASK
Definition: dhcpd.h:72
static void ip_forward(struct pbuf *p, struct ip_hdr *iphdr)
Definition: ip6.c:96
GLfloat GLfloat p
Definition: glext.h:8902
#define htons(x)
Definition: module.h:213
#define LWIP_MAKE_U16(a, b)
Definition: def.h:52
#define ip_current_dest_addr()
Definition: ip.h:202
#define memset(x, y, z)
Definition: compat.h:39
#define ip_addr_netcmp(addr1, addr2, mask)
Definition: ip_addr.h:194
#define IPH_LEN_SET(hdr, len)
Definition: ip.h:158
#define ip4_addr_get_u32(src_ipaddr)
Definition: ip_addr.h:181
#define snmp_inc_ipforwdatagrams()
Definition: snmp.h:264
#define ip_addr_set_any(ipaddr)
Definition: ip_addr.h:170