MeterLogger
Data Structures | Macros | Functions | Variables
ip.h File Reference
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/pbuf.h"
#include "lwip/ip_addr.h"
#include "lwip/err.h"
#include "lwip/netif.h"
Include dependency graph for ip.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ip_pcb
 
struct  ip_hdr
 

Macros

#define IP_OPTIONS_SEND   LWIP_IGMP
 
#define IP_HLEN   20
 
#define IP_PROTO_ICMP   1
 
#define IP_PROTO_IGMP   2
 
#define IP_PROTO_UDP   17
 
#define IP_PROTO_UDPLITE   136
 
#define IP_PROTO_TCP   6
 
#define IP_HDRINCL   NULL
 
#define IP_PCB_ADDRHINT
 
#define IP_PCB
 
#define SOF_ACCEPTCONN   (u8_t)0x02U /* socket has had listen() */
 
#define SOF_REUSEADDR   (u8_t)0x04U /* allow local address reuse */
 
#define SOF_KEEPALIVE   (u8_t)0x08U /* keep connections alive */
 
#define SOF_BROADCAST   (u8_t)0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
 
#define SOF_LINGER   (u8_t)0x80U /* linger on close if data present */
 
#define SOF_INHERITED   (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/)
 
#define IP_RF   0x8000 /* reserved fragment flag */
 
#define IP_DF   0x4000 /* dont fragment flag */
 
#define IP_MF   0x2000 /* more fragments flag */
 
#define IP_OFFMASK   0x1fff /* mask for fragmenting bits */
 
#define IPH_V(hdr)   (ntohs((hdr)->_v_hl_tos) >> 12)
 
#define IPH_HL(hdr)   ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)
 
#define IPH_TOS(hdr)   (ntohs((hdr)->_v_hl_tos) & 0xff)
 
#define IPH_LEN(hdr)   ((hdr)->_len)
 
#define IPH_ID(hdr)   ((hdr)->_id)
 
#define IPH_OFFSET(hdr)   ((hdr)->_offset)
 
#define IPH_TTL(hdr)   ((hdr)->_ttl)
 
#define IPH_PROTO(hdr)   ((hdr)->_proto)
 
#define IPH_CHKSUM(hdr)   ((hdr)->_chksum)
 
#define IPH_VHLTOS_SET(hdr, v, hl, tos)   (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos)))
 
#define IPH_LEN_SET(hdr, len)   (hdr)->_len = (len)
 
#define IPH_ID_SET(hdr, id)   (hdr)->_id = (id)
 
#define IPH_OFFSET_SET(hdr, off)   (hdr)->_offset = (off)
 
#define IPH_TTL_SET(hdr, ttl)   (hdr)->_ttl = (u8_t)(ttl)
 
#define IPH_PROTO_SET(hdr, proto)   (hdr)->_proto = (u8_t)(proto)
 
#define IPH_CHKSUM_SET(hdr, chksum)   (hdr)->_chksum = (chksum)
 
#define ip_init()   /* Compatibility define, not init needed. */
 
#define ip_current_netif()   (current_netif)
 
#define ip_current_header()   (current_header)
 
#define ip_current_src_addr()   (&current_iphdr_src)
 
#define ip_current_dest_addr()   (&current_iphdr_dest)
 
#define ip_debug_print(p)
 

Functions

struct netifip_route (ip_addr_t *dest) ICACHE_FLASH_ATTR
 
struct netifip_router (ip_addr_t *dest, ip_addr_t *source)
 
err_t ip_input (struct pbuf *p, struct netif *inp) ICACHE_FLASH_ATTR
 
err_t ip_output (struct pbuf *p, ip_addr_t *src, ip_addr_t *dest, u8_t ttl, u8_t tos, u8_t proto) ICACHE_FLASH_ATTR
 
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) ICACHE_FLASH_ATTR
 

Variables

PACK_STRUCT_BEGIN struct ip_hdr PACK_STRUCT_STRUCT
 
struct netifcurrent_netif
 
const struct ip_hdrcurrent_header
 
ip_addr_t current_iphdr_src
 
ip_addr_t current_iphdr_dest
 

Macro Definition Documentation

◆ ip_current_dest_addr

#define ip_current_dest_addr ( )    (&current_iphdr_dest)

Destination IP address of current_header

Definition at line 201 of file ip.h.

◆ ip_current_header

#define ip_current_header ( )    (current_header)

Get the IP header of the current packet. This function must only be called from a receive callback (udp_recv, raw_recv, tcp_accept). It will return NULL otherwise.

Definition at line 197 of file ip.h.

◆ ip_current_netif

#define ip_current_netif ( )    (current_netif)

Get the interface that received the current packet. This function must only be called from a receive callback (udp_recv, raw_recv, tcp_accept). It will return NULL otherwise.

Definition at line 193 of file ip.h.

◆ ip_current_src_addr

#define ip_current_src_addr ( )    (&current_iphdr_src)

Source IP address of current_header

Definition at line 199 of file ip.h.

◆ ip_debug_print

#define ip_debug_print (   p)

Definition at line 206 of file ip.h.

Referenced by ip_input(), ip_output(), and ip_output_if().

◆ IP_DF

#define IP_DF   0x4000 /* dont fragment flag */

Definition at line 126 of file ip.h.

◆ IP_HDRINCL

#define IP_HDRINCL   NULL

Definition at line 64 of file ip.h.

Referenced by ip_output_if().

◆ IP_HLEN

#define IP_HLEN   20

Definition at line 50 of file ip.h.

Referenced by ip_input(), ip_output(), and ip_output_if().

◆ ip_init

#define ip_init ( )    /* Compatibility define, not init needed. */

Definition at line 171 of file ip.h.

Referenced by lwip_init().

◆ IP_MF

#define IP_MF   0x2000 /* more fragments flag */

Definition at line 127 of file ip.h.

Referenced by ip_input().

◆ IP_OFFMASK

#define IP_OFFMASK   0x1fff /* mask for fragmenting bits */

Definition at line 128 of file ip.h.

Referenced by ip_input(), and ip_output().

◆ IP_OPTIONS_SEND

#define IP_OPTIONS_SEND   LWIP_IGMP

Currently, the function ip_output_if_opt() is only used with IGMP

Definition at line 48 of file ip.h.

◆ IP_PCB

#define IP_PCB
Value:
/* ip addresses in network byte order */ \
ip_addr_t local_ip; \
ip_addr_t remote_ip; \
/* Socket options */ \
u8_t so_options; \
/* Type Of Service */ \
u8_t tos; \
/* Time To Live */ \
u8_t ttl \
/* link layer address resolution hint */ \
IP_PCB_ADDRHINT

Definition at line 76 of file ip.h.

◆ IP_PCB_ADDRHINT

#define IP_PCB_ADDRHINT

Definition at line 69 of file ip.h.

◆ IP_PROTO_ICMP

#define IP_PROTO_ICMP   1

Definition at line 52 of file ip.h.

Referenced by acl_check_packet(), ip_input(), and ip_router().

◆ IP_PROTO_IGMP

#define IP_PROTO_IGMP   2

Definition at line 53 of file ip.h.

Referenced by ip_input().

◆ IP_PROTO_TCP

#define IP_PROTO_TCP   6

Definition at line 56 of file ip.h.

Referenced by acl_check_packet(), ip_input(), and ip_router().

◆ IP_PROTO_UDP

#define IP_PROTO_UDP   17

Definition at line 54 of file ip.h.

Referenced by acl_check_packet(), ip_input(), and ip_router().

◆ IP_PROTO_UDPLITE

#define IP_PROTO_UDPLITE   136

Definition at line 55 of file ip.h.

Referenced by ip_input().

◆ IP_RF

#define IP_RF   0x8000 /* reserved fragment flag */

Definition at line 125 of file ip.h.

◆ IPH_CHKSUM

#define IPH_CHKSUM (   hdr)    ((hdr)->_chksum)

Definition at line 152 of file ip.h.

Referenced by ip_output(), and ip_router().

◆ IPH_CHKSUM_SET

#define IPH_CHKSUM_SET (   hdr,
  chksum 
)    (hdr)->_chksum = (chksum)

Definition at line 160 of file ip.h.

Referenced by ip_output_if(), and ip_router().

◆ IPH_HL

#define IPH_HL (   hdr)    ((ntohs((hdr)->_v_hl_tos) >> 8) & 0x0f)

Definition at line 145 of file ip.h.

Referenced by ip_input(), ip_output(), and ip_router().

◆ IPH_ID

#define IPH_ID (   hdr)    ((hdr)->_id)

Definition at line 148 of file ip.h.

Referenced by ip_input(), and ip_output().

◆ IPH_ID_SET

#define IPH_ID_SET (   hdr,
  id 
)    (hdr)->_id = (id)

Definition at line 156 of file ip.h.

Referenced by ip_output_if().

◆ IPH_LEN

#define IPH_LEN (   hdr)    ((hdr)->_len)

Definition at line 147 of file ip.h.

Referenced by ip_input(), and ip_output().

◆ IPH_LEN_SET

#define IPH_LEN_SET (   hdr,
  len 
)    (hdr)->_len = (len)

Definition at line 155 of file ip.h.

Referenced by ip_output_if().

◆ IPH_OFFSET

#define IPH_OFFSET (   hdr)    ((hdr)->_offset)

Definition at line 149 of file ip.h.

Referenced by ip_input(), and ip_output().

◆ IPH_OFFSET_SET

#define IPH_OFFSET_SET (   hdr,
  off 
)    (hdr)->_offset = (off)

Definition at line 157 of file ip.h.

Referenced by ip_output_if().

◆ IPH_PROTO

#define IPH_PROTO (   hdr)    ((hdr)->_proto)

Definition at line 151 of file ip.h.

Referenced by acl_check_packet(), ip_input(), ip_output(), and ip_router().

◆ IPH_PROTO_SET

#define IPH_PROTO_SET (   hdr,
  proto 
)    (hdr)->_proto = (u8_t)(proto)

Definition at line 159 of file ip.h.

Referenced by ip_output_if().

◆ IPH_TOS

#define IPH_TOS (   hdr)    (ntohs((hdr)->_v_hl_tos) & 0xff)

Definition at line 146 of file ip.h.

Referenced by ip_output().

◆ IPH_TTL

#define IPH_TTL (   hdr)    ((hdr)->_ttl)

Definition at line 150 of file ip.h.

Referenced by ip_output(), and ip_router().

◆ IPH_TTL_SET

#define IPH_TTL_SET (   hdr,
  ttl 
)    (hdr)->_ttl = (u8_t)(ttl)

Definition at line 158 of file ip.h.

Referenced by ip_output_if(), and ip_router().

◆ IPH_V

#define IPH_V (   hdr)    (ntohs((hdr)->_v_hl_tos) >> 12)

Definition at line 144 of file ip.h.

Referenced by ip_input(), and ip_output().

◆ IPH_VHLTOS_SET

#define IPH_VHLTOS_SET (   hdr,
  v,
  hl,
  tos 
)    (hdr)->_v_hl_tos = (htons(((v) << 12) | ((hl) << 8) | (tos)))

Definition at line 154 of file ip.h.

Referenced by ip_output_if().

◆ SOF_ACCEPTCONN

#define SOF_ACCEPTCONN   (u8_t)0x02U /* socket has had listen() */

Definition at line 98 of file ip.h.

◆ SOF_BROADCAST

#define SOF_BROADCAST   (u8_t)0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */

Definition at line 102 of file ip.h.

◆ SOF_INHERITED

#define SOF_INHERITED   (SOF_REUSEADDR|SOF_KEEPALIVE|SOF_LINGER/*|SOF_DEBUG|SOF_DONTROUTE|SOF_OOBINLINE*/)

Definition at line 109 of file ip.h.

◆ SOF_KEEPALIVE

#define SOF_KEEPALIVE   (u8_t)0x08U /* keep connections alive */

Definition at line 100 of file ip.h.

◆ SOF_LINGER

#define SOF_LINGER   (u8_t)0x80U /* linger on close if data present */

Definition at line 104 of file ip.h.

◆ SOF_REUSEADDR

#define SOF_REUSEADDR   (u8_t)0x04U /* allow local address reuse */

Definition at line 99 of file ip.h.

Function Documentation

◆ ip_input()

err_t ip_input ( struct pbuf p,
struct netif inp 
)

This function is called by the network interface device driver when an IP packet is received. The function does the basic checks of the IP header such as packet size being at least larger than the header size etc. If the packet was not destined for us, the packet is forwarded (using ip_forward). The IP checksum is always checked.

Finally, the packet is sent to the upper layer protocol input function.

Parameters
pthe received IP packet (p->payload points to IP header)
inpthe netif on which this packet was received
Returns
ERR_OK if the packet was processed (could return ERR_* if it wasn't processed, but currently always returns ERR_OK)

Definition at line 923 of file ip.c.

References current_iphdr_dest, current_iphdr_src, ERR_OK, netif::flags, ICMP_DUR_PROTO, inet_chksum(), ip4_addr_get_u32, netif::ip_addr, ip_addr_cmp, ip_addr_copy, ip_addr_isany, ip_addr_isbroadcast, ip_addr_ismulticast, ip_addr_set_any, IP_DEBUG, ip_debug_print, IP_HLEN, IP_MF, IP_OFFMASK, IP_PROTO_ICMP, IP_PROTO_IGMP, IP_PROTO_TCP, IP_PROTO_UDP, IP_PROTO_UDPLITE, IP_STATS_INC, IPH_HL, IPH_ID, IPH_LEN, IPH_OFFSET, IPH_PROTO, IPH_V, pbuf::len, LWIP_DBG_LEVEL_SERIOUS, LWIP_DBG_LEVEL_WARNING, LWIP_DBG_TRACE, LWIP_DEBUGF, netif::name, NETIF_FLAG_IGMP, netif_is_up, netif_list, netif::netmask, netif::next, ntohs, NULL, pbuf::payload, pbuf_free(), pbuf_realloc(), PP_HTONS, snmp_inc_ipinaddrerrors, snmp_inc_ipindelivers, snmp_inc_ipindiscards, snmp_inc_ipinhdrerrors, snmp_inc_ipinreceives, snmp_inc_ipinunknownprotos, pbuf::tot_len, U16_F, X16_F, and X32_F.

Referenced by netif_init(), netif_set_link_down(), tcpip_input(), and tcpip_thread().

924 {
925  struct ip_hdr *iphdr;
926  struct netif *netif;
927  u16_t iphdr_hlen;
928  u16_t iphdr_len;
929 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
930  int check_ip_src=1;
931 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
932 
933  IP_STATS_INC(ip.recv);
935 
936  /* identify the IP header */
937  iphdr = (struct ip_hdr *)p->payload;
938  if (IPH_V(iphdr) != 4) {
939  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", IPH_V(iphdr)));
940  ip_debug_print(p);
941  pbuf_free(p);
942  IP_STATS_INC(ip.err);
943  IP_STATS_INC(ip.drop);
945  return ERR_OK;
946  }
947 
948  /* obtain IP header length in number of 32-bit words */
949  iphdr_hlen = IPH_HL(iphdr);
950  /* calculate IP header length in bytes */
951  iphdr_hlen *= 4;
952  /* obtain ip length in bytes */
953  iphdr_len = ntohs(IPH_LEN(iphdr));
954 
955  /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */
956  if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len)) {
957  if (iphdr_hlen > p->len) {
959  ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n",
960  iphdr_hlen, p->len));
961  }
962  if (iphdr_len > p->tot_len) {
964  ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n",
965  iphdr_len, p->tot_len));
966  }
967  /* free (drop) packet pbufs */
968  pbuf_free(p);
969  IP_STATS_INC(ip.lenerr);
970  IP_STATS_INC(ip.drop);
972  return ERR_OK;
973  }
974 
975  /* verify checksum */
976 #if CHECKSUM_CHECK_IP
977  if (inet_chksum(iphdr, iphdr_hlen) != 0) {
978 
980  ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen)));
981  ip_debug_print(p);
982  pbuf_free(p);
983  IP_STATS_INC(ip.chkerr);
984  IP_STATS_INC(ip.drop);
986  return ERR_OK;
987  }
988 #endif
989 
990 #if IP_NAPT
991  /* for unicast packet, check NAPT table and modify dest if needed */
992  if (!inp->napt && ip_addr_cmp(&iphdr->dest, &(inp->ip_addr)))
993  ip_napt_recv(p, iphdr, netif);
994 #endif
995 
996  /* Trim pbuf. This should have been done at the netif layer,
997  * but we'll do it anyway just to be sure that its done. */
998  pbuf_realloc(p, iphdr_len);
999 
1000  /* copy IP addresses to aligned ip_addr_t */
1001  ip_addr_copy(current_iphdr_dest, iphdr->dest);
1002  ip_addr_copy(current_iphdr_src, iphdr->src);
1003 
1004  /* match packet against an interface, i.e. is this packet for us? */
1005 #if LWIP_IGMP
1007  if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, &current_iphdr_dest))) {
1008  netif = inp;
1009  } else {
1010  netif = NULL;
1011  }
1012  } else
1013 #endif /* LWIP_IGMP */
1014  {
1015  /* start trying with inp. if that's not acceptable, start walking the
1016  list of configured netifs.
1017  'first' is used as a boolean to mark whether we started walking the list */
1018  int first = 1;
1019  netif = inp;
1020  do {
1021  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",
1022  ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(&netif->ip_addr),
1023  ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(&netif->netmask),
1024  ip4_addr_get_u32(&netif->ip_addr) & ip4_addr_get_u32(&netif->netmask),
1025  ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(&netif->netmask)));
1026 
1027  /* interface is up and configured? */
1028  if ((netif_is_up(netif)) && (!ip_addr_isany(&(netif->ip_addr)))) {
1029  /* unicast to this interface address? */
1030  if (ip_addr_cmp(&current_iphdr_dest, &(netif->ip_addr)) ||
1031  /* or broadcast on this interface network address? */
1033  LWIP_DEBUGF(IP_DEBUG, ("ip_input: packet accepted on interface %c%c\n",
1034  netif->name[0], netif->name[1]));
1035  /* break out of for loop */
1036  break;
1037  }
1038 #if LWIP_AUTOIP
1039  /* connections to link-local addresses must persist after changing
1040  the netif's address (RFC3927 ch. 1.9) */
1041  if ((netif->autoip != NULL) &&
1042  ip_addr_cmp(&current_iphdr_dest, &(netif->autoip->llipaddr))) {
1043  LWIP_DEBUGF(IP_DEBUG, ("ip_input: LLA packet accepted on interface %c%c\n",
1044  netif->name[0], netif->name[1]));
1045  /* break out of for loop */
1046  break;
1047  }
1048 #endif /* LWIP_AUTOIP */
1049  }
1050  if (first) {
1051  first = 0;
1052  netif = netif_list;
1053  } else {
1054  netif = netif->next;
1055  }
1056  if (netif == inp) {
1057  netif = netif->next;
1058  }
1059  } while(netif != NULL);
1060  }
1061 
1062 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
1063  /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed
1064  * using link layer addressing (such as Ethernet MAC) so we must not filter on IP.
1065  * According to RFC 1542 section 3.1.1, referred by RFC 2131).
1066  *
1067  * If you want to accept private broadcast communication while a netif is down,
1068  * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.:
1069  *
1070  * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345))
1071  */
1072  if (netif == NULL) {
1073  /* remote port is DHCP server? */
1074  if (IPH_PROTO(iphdr) == IP_PROTO_UDP) {
1075  struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen);
1076  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: UDP packet to DHCP client port %"U16_F"\n",
1077  ntohs(udphdr->dest)));
1078  if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) {
1079  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: DHCP packet accepted.\n"));
1080  netif = inp;
1081  check_ip_src = 0;
1082  }
1083  }
1084  }
1085 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
1086 
1087  /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */
1088 #if IP_ACCEPT_LINK_LAYER_ADDRESSING
1089  /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */
1090  if (check_ip_src && !ip_addr_isany(&current_iphdr_src))
1091 #endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */
1092  { if ((ip_addr_isbroadcast(&current_iphdr_src, inp)) ||
1094  /* packet source is not valid */
1095  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip_input: packet source is not valid.\n"));
1096  /* free (drop) packet pbufs */
1097  pbuf_free(p);
1098  IP_STATS_INC(ip.drop);
1101  return ERR_OK;
1102  }
1103  }
1104 
1105  /* packet not for us? */
1106  if (netif == NULL) {
1107  /* packet not for us, route or discard */
1108  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip_input: packet not for us.\n"));
1109 #if IP_FORWARD
1110  /* non-broadcast packet? */
1112  /* try to forward IP packet on (other) interfaces */
1113  ip_forward(p, iphdr, inp);
1114  } else
1115 #endif /* IP_FORWARD */
1116  {
1119  }
1120  pbuf_free(p);
1121  return ERR_OK;
1122  }
1123  /* packet consists of multiple fragments? */
1124  if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) {
1125 #if IP_REASSEMBLY /* packet fragment reassembly code present? */
1126  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",
1127  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));
1128  /* reassemble the packet*/
1129  p = ip_reass(p);
1130  /* packet not fully reassembled yet? */
1131  if (p == NULL) {
1132  return ERR_OK;
1133  }
1134  iphdr = (struct ip_hdr *)p->payload;
1135 #else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */
1136  pbuf_free(p);
1137  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n",
1138  ntohs(IPH_OFFSET(iphdr))));
1139  IP_STATS_INC(ip.opterr);
1140  IP_STATS_INC(ip.drop);
1141  /* unsupported protocol feature */
1143  return ERR_OK;
1144 #endif /* IP_REASSEMBLY */
1145  }
1146 
1147 #if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */
1148 
1149 #if LWIP_IGMP
1150  /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */
1151  if((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) {
1152 #else
1153  if (iphdr_hlen > IP_HLEN) {
1154 #endif /* LWIP_IGMP */
1155  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n"));
1156  pbuf_free(p);
1157  IP_STATS_INC(ip.opterr);
1158  IP_STATS_INC(ip.drop);
1159  /* unsupported protocol feature */
1161  return ERR_OK;
1162  }
1163 #endif /* IP_OPTIONS_ALLOWED == 0 */
1164 
1165  /* send to upper layers */
1166  LWIP_DEBUGF(IP_DEBUG, ("ip_input: \n"));
1167  ip_debug_print(p);
1168  LWIP_DEBUGF(IP_DEBUG, ("ip_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len));
1169 
1170  current_netif = inp;
1171  current_header = iphdr;
1172 
1173 #if LWIP_RAW
1174  /* raw input did not eat the packet? */
1175  if (raw_input(p, inp) == 0)
1176 #endif /* LWIP_RAW */
1177  {
1178 
1179  switch (IPH_PROTO(iphdr)) {
1180 #if LWIP_UDP
1181  case IP_PROTO_UDP:
1182 #if LWIP_UDPLITE
1183  case IP_PROTO_UDPLITE:
1184 #endif /* LWIP_UDPLITE */
1186  udp_input(p, inp);
1187  break;
1188 #endif /* LWIP_UDP */
1189 #if LWIP_TCP
1190  case IP_PROTO_TCP:
1192  tcp_input(p, inp);
1193  break;
1194 #endif /* LWIP_TCP */
1195 #if LWIP_ICMP
1196  case IP_PROTO_ICMP:
1198  icmp_input(p, inp);
1199  break;
1200 #endif /* LWIP_ICMP */
1201 #if LWIP_IGMP
1202  case IP_PROTO_IGMP:
1203  igmp_input(p, inp, &current_iphdr_dest);
1204  break;
1205 #endif /* LWIP_IGMP */
1206  default:
1207 #if LWIP_ICMP
1208  /* send ICMP destination protocol unreachable unless is was a broadcast */
1211  p->payload = iphdr;
1212  icmp_dest_unreach(p, ICMP_DUR_PROTO);
1213  }
1214 #endif /* LWIP_ICMP */
1215  pbuf_free(p);
1216 
1217  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", IPH_PROTO(iphdr)));
1218 
1219  IP_STATS_INC(ip.proterr);
1220  IP_STATS_INC(ip.drop);
1222  }
1223  }
1224 
1225  current_netif = NULL;
1226  current_header = NULL;
1229 
1230  return ERR_OK;
1231 }
#define ip4_addr_get_u32(src_ipaddr)
Definition: ip_addr.h:181
#define IP_PROTO_ICMP
Definition: ip.h:52
u16_t tot_len
Definition: pbuf.h:90
#define IP_MF
Definition: ip.h:127
struct netif * current_netif
Definition: ip.c:101
u16_t len
Definition: pbuf.h:93
#define IPH_V(hdr)
Definition: ip.h:144
u16_t inet_chksum(void *dataptr, u16_t len) ICACHE_FLASH_ATTR
Definition: inet_chksum.c:396
#define U16_F
Definition: cc.h:61
struct netif * netif_list
Definition: netif.c:75
#define NULL
Definition: def.h:47
#define IP_PROTO_TCP
Definition: ip.h:56
#define LWIP_DBG_TRACE
Definition: debug.h:56
#define IPH_HL(hdr)
Definition: ip.h:145
#define IP_PROTO_IGMP
Definition: ip.h:53
#define snmp_inc_ipinreceives()
Definition: snmp.h:261
#define IP_DEBUG
Definition: opt.h:1875
#define PP_HTONS(x)
Definition: def.h:92
#define snmp_inc_ipindelivers()
Definition: snmp.h:267
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
#define ip_addr_cmp(addr1, addr2)
Definition: ip_addr.h:198
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:46
struct netif * next
Definition: netif.h:141
#define ERR_OK
Definition: err.h:52
#define IPH_LEN(hdr)
Definition: ip.h:147
#define IP_OFFMASK
Definition: ip.h:128
u8_t flags
Definition: netif.h:193
#define snmp_inc_ipinhdrerrors()
Definition: snmp.h:262
#define ip_debug_print(p)
Definition: ip.h:206
#define ip_addr_set_any(ipaddr)
Definition: ip_addr.h:170
#define LWIP_DBG_LEVEL_WARNING
Definition: debug.h:45
Definition: netif.h:139
#define NETIF_FLAG_IGMP
Definition: netif.h:95
ip_addr_t ip_addr
Definition: netif.h:144
#define snmp_inc_ipindiscards()
Definition: snmp.h:266
#define ip_addr_isany(addr1)
Definition: ip_addr.h:200
#define snmp_inc_ipinunknownprotos()
Definition: snmp.h:265
u8_t pbuf_free(struct pbuf *p) ICACHE_FLASH_ATTR
Definition: pbuf.c:685
ip_addr_t current_iphdr_src
Definition: ip.c:108
#define IP_PROTO_UDP
Definition: ip.h:54
#define snmp_inc_ipinaddrerrors()
Definition: snmp.h:263
ip_addr_t current_iphdr_dest
Definition: ip.c:110
#define ip_addr_isbroadcast(ipaddr, netif)
Definition: ip_addr.h:202
Definition: ip.h:116
#define IP_HLEN
Definition: ip.h:50
#define IPH_OFFSET(hdr)
Definition: ip.h:149
unsigned char u8_t
Definition: cc.h:52
void * payload
Definition: pbuf.h:81
#define IP_STATS_INC(x)
Definition: stats.h:203
char name[2]
Definition: netif.h:195
#define IP_PROTO_UDPLITE
Definition: ip.h:55
ip_addr_t netmask
Definition: netif.h:145
#define netif_is_up(netif)
Definition: netif.h:286
#define X32_F
Definition: cc.h:66
void pbuf_realloc(struct pbuf *p, u16_t size) ICACHE_FLASH_ATTR
Definition: pbuf.c:492
#define ip_addr_ismulticast(addr1)
Definition: ip_addr.h:208
const struct ip_hdr * current_header
Definition: ip.c:106
#define ntohs(x)
Definition: def.h:82
#define IPH_PROTO(hdr)
Definition: ip.h:151
unsigned short u16_t
Definition: cc.h:54
#define X16_F
Definition: cc.h:62
#define IPH_ID(hdr)
Definition: ip.h:148
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ip_output()

err_t ip_output ( struct pbuf p,
ip_addr_t src,
ip_addr_t dest,
u8_t  ttl,
u8_t  tos,
u8_t  proto 
)

Simple interface to ip_output_if. It finds the outgoing network interface and calls upon ip_output_if to do the actual work.

Parameters
pthe packet to send (p->payload points to the data, e.g. next protocol header; if dest == IP_HDRINCL, p already includes an IP header and p->payload points to that IP header)
srcthe source IP address to send from (if src == IP_ADDR_ANY, the IP address of the netif used to send is used as source address)
destthe destination IP address to send the packet to
ttlthe TTL value to be set in the IP header
tosthe TOS value to be set in the IP header
protothe PROTOCOL to be set in the IP header
Returns
ERR_RTE if no route is found see ip_output_if() for more return values

Definition at line 1435 of file ip.c.

References ERR_RTE, ip4_addr1_16, ip4_addr2_16, ip4_addr3_16, ip4_addr4_16, IP_DEBUG, ip_debug_print, IP_HLEN, IP_OFFMASK, ip_output_if(), ip_route(), IP_STATS_INC, IPH_CHKSUM, IPH_HL, IPH_ID, IPH_LEN, IPH_OFFSET, IPH_PROTO, IPH_TOS, IPH_TTL, IPH_V, LWIP_ASSERT, LWIP_DEBUGF, ntohs, NULL, pbuf::payload, pbuf::ref, S16_F, U16_F, and X16_F.

1437 {
1438  struct netif *netif;
1439 
1440  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
1441  gets altered as the packet is passed down the stack */
1442  LWIP_ASSERT("p->ref == 1", p->ref == 1);
1443 
1444  if ((netif = ip_route(dest)) == NULL) {
1445  LWIP_DEBUGF(IP_DEBUG, ("ip_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
1446  ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
1447  IP_STATS_INC(ip.rterr);
1448  return ERR_RTE;
1449  }
1450 
1451  return ip_output_if(p, src, dest, ttl, tos, proto, netif);
1452 }
#define ip4_addr3_16(ipaddr)
Definition: ip_addr.h:228
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:1259
#define U16_F
Definition: cc.h:61
#define NULL
Definition: def.h:47
#define IP_DEBUG
Definition: opt.h:1875
#define ERR_RTE
Definition: err.h:56
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
struct netif * ip_route(ip_addr_t *dest)
Definition: ip.c:125
Definition: netif.h:139
#define ip4_addr4_16(ipaddr)
Definition: ip_addr.h:229
#define ip4_addr1_16(ipaddr)
Definition: ip_addr.h:226
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:65
#define IP_STATS_INC(x)
Definition: stats.h:203
#define ip4_addr2_16(ipaddr)
Definition: ip_addr.h:227
u16_t ref
Definition: pbuf.h:106
Here is the call graph for this function:

◆ ip_output_if()

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 
)

Sends an IP packet on a network interface. This function constructs the IP header and calculates the IP header checksum. If the source IP address is NULL, the IP address of the outgoing network interface is filled in as source address. If the destination IP address is IP_HDRINCL, p is assumed to already include an IP header and p->payload points to it instead of the data.

Parameters
pthe packet to send (p->payload points to the data, e.g. next protocol header; if dest == IP_HDRINCL, p already includes an IP header and p->payload points to that IP header)
srcthe source IP address to send from (if src == IP_ADDR_ANY, the IP address of the netif used to send is used as source address)
destthe destination IP address to send the packet to
ttlthe TTL value to be set in the IP header
tosthe TOS value to be set in the IP header
protothe PROTOCOL to be set in the IP header
netifthe netif on which to send this packet
Returns
ERR_OK if the packet was sent OK ERR_BUF if p doesn't have enough space for IP/LINK headers returns errors returned by netif->output
Note
ip_id: RFC791 "some host may be able to simply use unique identifiers independent of destination"

Definition at line 1259 of file ip.c.

References ERR_BUF, pbuf::flags, htons, inet_chksum(), ip4_addr_get_u32, netif::ip_addr, ip_addr_cmp, ip_addr_copy, ip_addr_isany, IP_DEBUG, ip_debug_print, IP_HDRINCL, IP_HLEN, ip_id, IP_STATS_INC, IPH_CHKSUM_SET, IPH_ID_SET, IPH_LEN_SET, IPH_OFFSET_SET, IPH_PROTO_SET, IPH_TTL_SET, IPH_VHLTOS_SET, pbuf::len, LWIP_ASSERT, LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF, LWIP_MAKE_U16, MEMCPY, netif::mtu, netif::name, NULL, netif::num, os_memset, netif::output, pbuf::payload, PBUF_FLAG_MCASTLOOP, pbuf_header(), pbuf::ref, snmp_inc_ipoutdiscards, snmp_inc_ipoutrequests, pbuf::tot_len, and U16_F.

Referenced by ip_output().

1262 {
1263 #if IP_OPTIONS_SEND
1264  return ip_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0);
1265 }
1266 
1267 /**
1268  * Same as ip_output_if() but with the possibility to include IP options:
1269  *
1270  * @ param ip_options pointer to the IP options, copied into the IP header
1271  * @ param optlen length of ip_options
1272  */
1273 err_t ip_output_if_opt(struct pbuf *p, ip_addr_t *src, ip_addr_t *dest,
1274  u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options,
1275  u16_t optlen)
1276 {
1277 #endif /* IP_OPTIONS_SEND */
1278  struct ip_hdr *iphdr;
1279  ip_addr_t dest_addr;
1280 #if CHECKSUM_GEN_IP_INLINE
1281  u32_t chk_sum = 0;
1282 #endif /* CHECKSUM_GEN_IP_INLINE */
1283 
1284  /* pbufs passed to IP must have a ref-count of 1 as their payload pointer
1285  gets altered as the packet is passed down the stack */
1286  LWIP_ASSERT("p->ref == 1", p->ref == 1);
1287 
1289 
1290  /* Should the IP header be generated or is it already included in p? */
1291  if (dest != IP_HDRINCL) {
1292  u16_t ip_hlen = IP_HLEN;
1293 #if IP_OPTIONS_SEND
1294  u16_t optlen_aligned = 0;
1295  if (optlen != 0) {
1296 #if CHECKSUM_GEN_IP_INLINE
1297  int i;
1298 #endif /* CHECKSUM_GEN_IP_INLINE */
1299  /* round up to a multiple of 4 */
1300  optlen_aligned = ((optlen + 3) & ~3);
1301  ip_hlen += optlen_aligned;
1302  /* First write in the IP options */
1303  if (pbuf_header(p, optlen_aligned)) {
1304  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output_if_opt: not enough room for IP options in pbuf\n"));
1305  IP_STATS_INC(ip.err);
1307  return ERR_BUF;
1308  }
1309  MEMCPY(p->payload, ip_options, optlen);
1310  if (optlen < optlen_aligned) {
1311  /* zero the remaining bytes */
1312  os_memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen);
1313  }
1314 #if CHECKSUM_GEN_IP_INLINE
1315  for (i = 0; i < optlen_aligned/2; i++) {
1316  chk_sum += ((u16_t*)p->payload)[i];
1317  }
1318 #endif /* CHECKSUM_GEN_IP_INLINE */
1319  }
1320 #endif /* IP_OPTIONS_SEND */
1321  /* generate IP header */
1322  if (pbuf_header(p, IP_HLEN)) {
1323  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_output: not enough room for IP header in pbuf\n"));
1324 
1325  IP_STATS_INC(ip.err);
1327  return ERR_BUF;
1328  }
1329 
1330  iphdr = (struct ip_hdr *)p->payload;
1331  LWIP_ASSERT("check that first pbuf can hold struct ip_hdr",
1332  (p->len >= sizeof(struct ip_hdr)));
1333 
1334  IPH_TTL_SET(iphdr, ttl);
1335  IPH_PROTO_SET(iphdr, proto);
1336 #if CHECKSUM_GEN_IP_INLINE
1337  chk_sum += LWIP_MAKE_U16(proto, ttl);
1338 #endif /* CHECKSUM_GEN_IP_INLINE */
1339 
1340  /* dest cannot be NULL here */
1341  ip_addr_copy(iphdr->dest, *dest);
1342 #if CHECKSUM_GEN_IP_INLINE
1343  chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF;
1344  chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16;
1345 #endif /* CHECKSUM_GEN_IP_INLINE */
1346 
1347  IPH_VHLTOS_SET(iphdr, 4, ip_hlen / 4, tos);
1348 #if CHECKSUM_GEN_IP_INLINE
1349  chk_sum += iphdr->_v_hl_tos;
1350 #endif /* CHECKSUM_GEN_IP_INLINE */
1351  IPH_LEN_SET(iphdr, htons(p->tot_len));
1352 #if CHECKSUM_GEN_IP_INLINE
1353  chk_sum += iphdr->_len;
1354 #endif /* CHECKSUM_GEN_IP_INLINE */
1355  IPH_OFFSET_SET(iphdr, 0);
1356  IPH_ID_SET(iphdr, htons(ip_id));
1357 #if CHECKSUM_GEN_IP_INLINE
1358  chk_sum += iphdr->_id;
1359 #endif /* CHECKSUM_GEN_IP_INLINE */
1360  ++ip_id;
1361 
1362  if (ip_addr_isany(src)) {
1363  ip_addr_copy(iphdr->src, netif->ip_addr);
1364  } else {
1365  /* src cannot be NULL here */
1366  ip_addr_copy(iphdr->src, *src);
1367  }
1368 
1369 #if CHECKSUM_GEN_IP_INLINE
1370  chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF;
1371  chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16;
1372  chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
1373  chk_sum = (chk_sum >> 16) + chk_sum;
1374  chk_sum = ~chk_sum;
1375  iphdr->_chksum = chk_sum; /* network order */
1376 #else /* CHECKSUM_GEN_IP_INLINE */
1377  IPH_CHKSUM_SET(iphdr, 0);
1378 #if CHECKSUM_GEN_IP
1379  IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen));
1380 #endif
1381 #endif /* CHECKSUM_GEN_IP_INLINE */
1382  } else {
1383  /* IP header already included in p */
1384  iphdr = (struct ip_hdr *)p->payload;
1385  ip_addr_copy(dest_addr, iphdr->dest);
1386  dest = &dest_addr;
1387  }
1388 
1389  IP_STATS_INC(ip.xmit);
1390 
1391  LWIP_DEBUGF(IP_DEBUG, ("ip_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], netif->num));
1392  ip_debug_print(p);
1393 
1394 #if ENABLE_LOOPBACK
1395  if (ip_addr_cmp(dest, &netif->ip_addr)) {
1396  /* Packet to self, enqueue it for loopback */
1397  LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()"));
1398  return netif_loop_output(netif, p, dest);
1399  }
1400 #if LWIP_IGMP
1401  if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) {
1402  netif_loop_output(netif, p, dest);
1403  }
1404 #endif /* LWIP_IGMP */
1405 #endif /* ENABLE_LOOPBACK */
1406 #if IP_FRAG
1407  /* don't fragment if interface has mtu set to 0 [loopif] */
1408  if (netif->mtu && (p->tot_len > netif->mtu)) {
1409  return ip_frag(p, netif, dest);
1410  }
1411 #endif /* IP_FRAG */
1412 
1413  LWIP_DEBUGF(IP_DEBUG, ("netif->output()\n"));
1414  return netif->output(netif, p, dest);
1415 }
#define ip4_addr_get_u32(src_ipaddr)
Definition: ip_addr.h:181
static u16_t ip_id
Definition: ip.c:113
u16_t tot_len
Definition: pbuf.h:90
u16_t len
Definition: pbuf.h:93
u16_t inet_chksum(void *dataptr, u16_t len) ICACHE_FLASH_ATTR
Definition: inet_chksum.c:396
#define U16_F
Definition: cc.h:61
#define IPH_VHLTOS_SET(hdr, v, hl, tos)
Definition: ip.h:154
#define NULL
Definition: def.h:47
#define htons(x)
Definition: def.h:81
netif_output_fn output
Definition: netif.h:154
#define snmp_inc_ipoutdiscards()
Definition: snmp.h:269
#define IPH_PROTO_SET(hdr, proto)
Definition: ip.h:159
u8_t num
Definition: netif.h:197
#define IP_HDRINCL
Definition: ip.h:64
#define IP_DEBUG
Definition: opt.h:1875
#define PBUF_FLAG_MCASTLOOP
Definition: pbuf.h:74
u8_t flags
Definition: pbuf.h:99
unsigned long u32_t
Definition: cc.h:56
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
#define os_memset
Definition: osapi.h:38
#define ip_addr_cmp(addr1, addr2)
Definition: ip_addr.h:198
#define IPH_OFFSET_SET(hdr, off)
Definition: ip.h:157
#define ip_addr_copy(dest, src)
Definition: ip_addr.h:162
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:46
Definition: pbuf.h:76
s8_t err_t
Definition: err.h:47
#define ip_debug_print(p)
Definition: ip.h:206
typedefPACK_STRUCT_END struct ip_addr ip_addr_t
Definition: ip_addr.h:64
ip_addr_t ip_addr
Definition: netif.h:144
#define ip_addr_isany(addr1)
Definition: ip_addr.h:200
u16_t mtu
Definition: netif.h:187
#define IPH_CHKSUM_SET(hdr, chksum)
Definition: ip.h:160
#define IPH_TTL_SET(hdr, ttl)
Definition: ip.h:158
Definition: ip.h:116
#define IP_HLEN
Definition: ip.h:50
u8_t pbuf_header(struct pbuf *p, s16_t header_size) ICACHE_FLASH_ATTR
Definition: pbuf.c:573
unsigned char u8_t
Definition: cc.h:52
#define MEMCPY(dst, src, len)
Definition: opt.h:84
#define IPH_ID_SET(hdr, id)
Definition: ip.h:156
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:65
void * payload
Definition: pbuf.h:81
#define IP_STATS_INC(x)
Definition: stats.h:203
char name[2]
Definition: netif.h:195
#define IPH_LEN_SET(hdr, len)
Definition: ip.h:155
u16_t ref
Definition: pbuf.h:106
#define LWIP_MAKE_U16(a, b)
Definition: def.h:56
#define snmp_inc_ipoutrequests()
Definition: snmp.h:268
unsigned short u16_t
Definition: cc.h:54
#define ERR_BUF
Definition: err.h:54
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ip_route()

struct netif* ip_route ( ip_addr_t dest)

Finds the appropriate network interface for a given IP address. It searches the list of network interfaces linearly. A match is found if the masked IP address of the network interface equals the masked IP address given to the function.

Parameters
destthe destination IP address for which to find the route
Returns
the netif on which to send to reach dest

Definition at line 125 of file ip.c.

References eagle_lwip_getif(), ICACHE_FLASH_ATTR, ip4_addr1_16, ip4_addr2_16, ip4_addr3_16, ip4_addr4_16, netif::ip_addr, ip_addr_isbroadcast, ip_addr_netcmp, IP_DEBUG, IP_STATS_INC, LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF, netif_default, netif_is_up, netif_list, netif::netmask, netif::next, NULL, snmp_inc_ipoutnoroutes, and U16_F.

Referenced by ip_output(), and ip_router().

126 {
127  struct netif *netif;
128 
129  /* iterate through netifs */
130  for(netif = netif_list; netif != NULL; netif = netif->next) {
131  /* network mask matches? */
132  if (netif_is_up(netif)) {
133  if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
134  /* return netif on which to forward IP packet */
135  return netif;
136  }
137  }
138  }
139  /* iterate through netifs */
140  for(netif = netif_list; netif != NULL; netif = netif->next) {
141  /* network mask matches? */
142  if (netif_is_up(netif)) {
143  if (!ip_addr_isbroadcast(dest, netif) && netif == (struct netif *)eagle_lwip_getif(0)) {
144  return netif;
145  }
146  }
147  }
148  if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
149  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
150  ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
151  IP_STATS_INC(ip.rterr);
153  return NULL;
154  }
155  /* no matching netif found, use default netif */
156  return netif_default;
157 }
#define ip4_addr3_16(ipaddr)
Definition: ip_addr.h:228
#define ip_addr_netcmp(addr1, addr2, mask)
Definition: ip_addr.h:194
#define U16_F
Definition: cc.h:61
struct netif * netif_list
Definition: netif.c:75
#define NULL
Definition: def.h:47
struct netif * eagle_lwip_getif(uint8 index)
#define IP_DEBUG
Definition: opt.h:1875
#define snmp_inc_ipoutnoroutes()
Definition: snmp.h:270
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:46
struct netif * next
Definition: netif.h:141
struct netif * netif_default
Definition: netif.c:76
Definition: netif.h:139
#define ip4_addr4_16(ipaddr)
Definition: ip_addr.h:229
ip_addr_t ip_addr
Definition: netif.h:144
#define ip_addr_isbroadcast(ipaddr, netif)
Definition: ip_addr.h:202
#define ip4_addr1_16(ipaddr)
Definition: ip_addr.h:226
#define IP_STATS_INC(x)
Definition: stats.h:203
#define ip4_addr2_16(ipaddr)
Definition: ip_addr.h:227
ip_addr_t netmask
Definition: netif.h:145
#define netif_is_up(netif)
Definition: netif.h:286
Here is the call graph for this function:
Here is the caller graph for this function:

◆ ip_router()

struct netif* ip_router ( ip_addr_t dest,
ip_addr_t source 
)

Finds the appropriate network interface for a source IP address. It searches the list of network interfaces linearly. A match is found if the masked IP address of the network interface equals the masked IP address given to the function.

Parameters
sourcethe sourcination IP address for which to find the route
Returns
the netif on which to send to reach source

Definition at line 170 of file ip.c.

References current_iphdr_dest, ERR_OK, ERR_RTE, ICACHE_FLASH_ATTR, ICMP_DUR_PORT, ICMP_ECHO, ICMP_ER, ICMP_TE_TTL, ip4_addr1_16, ip4_addr2_16, ip4_addr3_16, ip4_addr4_16, netif::ip_addr, ip_addr_isany, ip_addr_islinklocal, ip_addr_netcmp, IP_DEBUG, IP_PROTO_ICMP, IP_PROTO_TCP, IP_PROTO_UDP, ip_route(), IP_STATS_INC, IPH_CHKSUM, IPH_CHKSUM_SET, IPH_HL, IPH_PROTO, IPH_TTL, IPH_TTL_SET, LWIP_DBG_LEVEL_SERIOUS, LWIP_DEBUGF, memcpy, netif_default, netif_is_up, netif_list, netif::netmask, netif::next, NULL, netif::num, os_printf, os_random(), os_zalloc, netif::output, pbuf::payload, PERF_START, PERF_STOP, PP_HTONS, PP_NTOHS, snmp_inc_ipforwdatagrams, snmp_inc_ipinhdrerrors, snmp_inc_ipoutnoroutes, sys_now(), and U16_F.

170  {
171  struct netif *netif;
172  /* iterate through netifs */
173  for(netif = netif_list; netif != NULL; netif = netif->next) {
174  /* network mask matches? */
175 
176  if (netif_is_up(netif)) {
177  if (ip_addr_netcmp(dest, &(netif->ip_addr), &(netif->netmask))) {
178  /* return netif on which to forward IP packet */
179  return netif;
180  }
181  }
182 
183  if (netif_is_up(netif)) {
184  if (ip_addr_netcmp(source, &(netif->ip_addr), &(netif->netmask))) {
185  /* return netif on which to forward IP packet */
186  return netif;
187  }
188  }
189  }
190 
191  if ((netif_default == NULL) || (!netif_is_up(netif_default))) {
192  LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
193  ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest)));
194  IP_STATS_INC(ip.rterr);
196  return NULL;
197  }
198  /* no matching netif found, use default netif */
199  os_printf("ip_router %d %p\n", __LINE__, netif_default);
200  return netif_default;
201 }
#define ip4_addr3_16(ipaddr)
Definition: ip_addr.h:228
#define ip_addr_netcmp(addr1, addr2, mask)
Definition: ip_addr.h:194
#define U16_F
Definition: cc.h:61
struct netif * netif_list
Definition: netif.c:75
#define NULL
Definition: def.h:47
#define IP_DEBUG
Definition: opt.h:1875
#define os_printf
Definition: osapi.h:62
#define snmp_inc_ipoutnoroutes()
Definition: snmp.h:270
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:94
#define LWIP_DBG_LEVEL_SERIOUS
Definition: debug.h:46
struct netif * next
Definition: netif.h:141
struct netif * netif_default
Definition: netif.c:76
Definition: netif.h:139
#define ip4_addr4_16(ipaddr)
Definition: ip_addr.h:229
ip_addr_t ip_addr
Definition: netif.h:144
#define ip4_addr1_16(ipaddr)
Definition: ip_addr.h:226
#define IP_STATS_INC(x)
Definition: stats.h:203
#define ip4_addr2_16(ipaddr)
Definition: ip_addr.h:227
ip_addr_t netmask
Definition: netif.h:145
#define netif_is_up(netif)
Definition: netif.h:286
Here is the call graph for this function:

Variable Documentation

◆ current_header

const struct ip_hdr* current_header

Header of the input packet currently being processed.

Definition at line 106 of file ip.c.

◆ current_iphdr_dest

ip_addr_t current_iphdr_dest

Destination IP address of current_header

Definition at line 110 of file ip.c.

Referenced by ip_input(), and ip_router().

◆ current_iphdr_src

ip_addr_t current_iphdr_src

Source IP address of current_header

Definition at line 108 of file ip.c.

Referenced by ip_input().

◆ current_netif

struct netif* current_netif

The interface that provided the packet for the current callback invocation.

Definition at line 101 of file ip.c.

◆ PACK_STRUCT_STRUCT

PACK_STRUCT_BEGIN struct ip_hdr PACK_STRUCT_STRUCT