1*10465441SEvalZero /** 2*10465441SEvalZero * @file 3*10465441SEvalZero * IP API 4*10465441SEvalZero */ 5*10465441SEvalZero 6*10465441SEvalZero /* 7*10465441SEvalZero * Copyright (c) 2001-2004 Swedish Institute of Computer Science. 8*10465441SEvalZero * All rights reserved. 9*10465441SEvalZero * 10*10465441SEvalZero * Redistribution and use in source and binary forms, with or without modification, 11*10465441SEvalZero * are permitted provided that the following conditions are met: 12*10465441SEvalZero * 13*10465441SEvalZero * 1. Redistributions of source code must retain the above copyright notice, 14*10465441SEvalZero * this list of conditions and the following disclaimer. 15*10465441SEvalZero * 2. Redistributions in binary form must reproduce the above copyright notice, 16*10465441SEvalZero * this list of conditions and the following disclaimer in the documentation 17*10465441SEvalZero * and/or other materials provided with the distribution. 18*10465441SEvalZero * 3. The name of the author may not be used to endorse or promote products 19*10465441SEvalZero * derived from this software without specific prior written permission. 20*10465441SEvalZero * 21*10465441SEvalZero * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 22*10465441SEvalZero * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23*10465441SEvalZero * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 24*10465441SEvalZero * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25*10465441SEvalZero * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 26*10465441SEvalZero * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27*10465441SEvalZero * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28*10465441SEvalZero * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29*10465441SEvalZero * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 30*10465441SEvalZero * OF SUCH DAMAGE. 31*10465441SEvalZero * 32*10465441SEvalZero * This file is part of the lwIP TCP/IP stack. 33*10465441SEvalZero * 34*10465441SEvalZero * Author: Adam Dunkels <[email protected]> 35*10465441SEvalZero * 36*10465441SEvalZero */ 37*10465441SEvalZero #ifndef LWIP_HDR_IP_H 38*10465441SEvalZero #define LWIP_HDR_IP_H 39*10465441SEvalZero 40*10465441SEvalZero #include "lwip/opt.h" 41*10465441SEvalZero 42*10465441SEvalZero #include "lwip/def.h" 43*10465441SEvalZero #include "lwip/pbuf.h" 44*10465441SEvalZero #include "lwip/ip_addr.h" 45*10465441SEvalZero #include "lwip/err.h" 46*10465441SEvalZero #include "lwip/netif.h" 47*10465441SEvalZero #include "lwip/ip4.h" 48*10465441SEvalZero #include "lwip/ip6.h" 49*10465441SEvalZero #include "lwip/prot/ip.h" 50*10465441SEvalZero 51*10465441SEvalZero #ifdef __cplusplus 52*10465441SEvalZero extern "C" { 53*10465441SEvalZero #endif 54*10465441SEvalZero 55*10465441SEvalZero /* This is passed as the destination address to ip_output_if (not 56*10465441SEvalZero to ip_output), meaning that an IP header already is constructed 57*10465441SEvalZero in the pbuf. This is used when TCP retransmits. */ 58*10465441SEvalZero #define LWIP_IP_HDRINCL NULL 59*10465441SEvalZero 60*10465441SEvalZero /** pbufs passed to IP must have a ref-count of 1 as their payload pointer 61*10465441SEvalZero gets altered as the packet is passed down the stack */ 62*10465441SEvalZero #ifndef LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX 63*10465441SEvalZero #define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p) LWIP_ASSERT("p->ref == 1", (p)->ref == 1) 64*10465441SEvalZero #endif 65*10465441SEvalZero 66*10465441SEvalZero #if LWIP_NETIF_USE_HINTS 67*10465441SEvalZero #define IP_PCB_NETIFHINT ;struct netif_hint netif_hints 68*10465441SEvalZero #else /* LWIP_NETIF_USE_HINTS */ 69*10465441SEvalZero #define IP_PCB_NETIFHINT 70*10465441SEvalZero #endif /* LWIP_NETIF_USE_HINTS */ 71*10465441SEvalZero 72*10465441SEvalZero /** This is the common part of all PCB types. It needs to be at the 73*10465441SEvalZero beginning of a PCB type definition. It is located here so that 74*10465441SEvalZero changes to this common part are made in one location instead of 75*10465441SEvalZero having to change all PCB structs. */ 76*10465441SEvalZero #define IP_PCB \ 77*10465441SEvalZero /* ip addresses in network byte order */ \ 78*10465441SEvalZero ip_addr_t local_ip; \ 79*10465441SEvalZero ip_addr_t remote_ip; \ 80*10465441SEvalZero /* Bound netif index */ \ 81*10465441SEvalZero u8_t netif_idx; \ 82*10465441SEvalZero /* Socket options */ \ 83*10465441SEvalZero u8_t so_options; \ 84*10465441SEvalZero /* Type Of Service */ \ 85*10465441SEvalZero u8_t tos; \ 86*10465441SEvalZero /* Time To Live */ \ 87*10465441SEvalZero u8_t ttl \ 88*10465441SEvalZero /* link layer address resolution hint */ \ 89*10465441SEvalZero IP_PCB_NETIFHINT 90*10465441SEvalZero 91*10465441SEvalZero struct ip_pcb { 92*10465441SEvalZero /* Common members of all PCB types */ 93*10465441SEvalZero IP_PCB; 94*10465441SEvalZero }; 95*10465441SEvalZero 96*10465441SEvalZero /* 97*10465441SEvalZero * Option flags per-socket. These are the same like SO_XXX in sockets.h 98*10465441SEvalZero */ 99*10465441SEvalZero #define SOF_REUSEADDR 0x04U /* allow local address reuse */ 100*10465441SEvalZero #define SOF_KEEPALIVE 0x08U /* keep connections alive */ 101*10465441SEvalZero #define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ 102*10465441SEvalZero 103*10465441SEvalZero /* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ 104*10465441SEvalZero #define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE) 105*10465441SEvalZero 106*10465441SEvalZero /** Global variables of this module, kept in a struct for efficient access using base+index. */ 107*10465441SEvalZero struct ip_globals 108*10465441SEvalZero { 109*10465441SEvalZero /** The interface that accepted the packet for the current callback invocation. */ 110*10465441SEvalZero struct netif *current_netif; 111*10465441SEvalZero /** The interface that received the packet for the current callback invocation. */ 112*10465441SEvalZero struct netif *current_input_netif; 113*10465441SEvalZero #if LWIP_IPV4 114*10465441SEvalZero /** Header of the input packet currently being processed. */ 115*10465441SEvalZero const struct ip_hdr *current_ip4_header; 116*10465441SEvalZero #endif /* LWIP_IPV4 */ 117*10465441SEvalZero #if LWIP_IPV6 118*10465441SEvalZero /** Header of the input IPv6 packet currently being processed. */ 119*10465441SEvalZero struct ip6_hdr *current_ip6_header; 120*10465441SEvalZero #endif /* LWIP_IPV6 */ 121*10465441SEvalZero /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ 122*10465441SEvalZero u16_t current_ip_header_tot_len; 123*10465441SEvalZero /** Source IP address of current_header */ 124*10465441SEvalZero ip_addr_t current_iphdr_src; 125*10465441SEvalZero /** Destination IP address of current_header */ 126*10465441SEvalZero ip_addr_t current_iphdr_dest; 127*10465441SEvalZero }; 128*10465441SEvalZero extern struct ip_globals ip_data; 129*10465441SEvalZero 130*10465441SEvalZero 131*10465441SEvalZero /** Get the interface that accepted the current packet. 132*10465441SEvalZero * This may or may not be the receiving netif, depending on your netif/network setup. 133*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 134*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 135*10465441SEvalZero #define ip_current_netif() (ip_data.current_netif) 136*10465441SEvalZero /** Get the interface that received the current packet. 137*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 138*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 139*10465441SEvalZero #define ip_current_input_netif() (ip_data.current_input_netif) 140*10465441SEvalZero /** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */ 141*10465441SEvalZero #define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len) 142*10465441SEvalZero /** Source IP address of current_header */ 143*10465441SEvalZero #define ip_current_src_addr() (&ip_data.current_iphdr_src) 144*10465441SEvalZero /** Destination IP address of current_header */ 145*10465441SEvalZero #define ip_current_dest_addr() (&ip_data.current_iphdr_dest) 146*10465441SEvalZero 147*10465441SEvalZero #if LWIP_IPV4 && LWIP_IPV6 148*10465441SEvalZero /** Get the IPv4 header of the current packet. 149*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 150*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 151*10465441SEvalZero #define ip4_current_header() ip_data.current_ip4_header 152*10465441SEvalZero /** Get the IPv6 header of the current packet. 153*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 154*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 155*10465441SEvalZero #define ip6_current_header() ((const struct ip6_hdr*)(ip_data.current_ip6_header)) 156*10465441SEvalZero /** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ 157*10465441SEvalZero #define ip_current_is_v6() (ip6_current_header() != NULL) 158*10465441SEvalZero /** Source IPv6 address of current_header */ 159*10465441SEvalZero #define ip6_current_src_addr() (ip_2_ip6(&ip_data.current_iphdr_src)) 160*10465441SEvalZero /** Destination IPv6 address of current_header */ 161*10465441SEvalZero #define ip6_current_dest_addr() (ip_2_ip6(&ip_data.current_iphdr_dest)) 162*10465441SEvalZero /** Get the transport layer protocol */ 163*10465441SEvalZero #define ip_current_header_proto() (ip_current_is_v6() ? \ 164*10465441SEvalZero IP6H_NEXTH(ip6_current_header()) :\ 165*10465441SEvalZero IPH_PROTO(ip4_current_header())) 166*10465441SEvalZero /** Get the transport layer header */ 167*10465441SEvalZero #define ip_next_header_ptr() ((const void*)((ip_current_is_v6() ? \ 168*10465441SEvalZero (const u8_t*)ip6_current_header() : (const u8_t*)ip4_current_header()) + ip_current_header_tot_len())) 169*10465441SEvalZero 170*10465441SEvalZero /** Source IP4 address of current_header */ 171*10465441SEvalZero #define ip4_current_src_addr() (ip_2_ip4(&ip_data.current_iphdr_src)) 172*10465441SEvalZero /** Destination IP4 address of current_header */ 173*10465441SEvalZero #define ip4_current_dest_addr() (ip_2_ip4(&ip_data.current_iphdr_dest)) 174*10465441SEvalZero 175*10465441SEvalZero #elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */ 176*10465441SEvalZero 177*10465441SEvalZero /** Get the IPv4 header of the current packet. 178*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 179*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 180*10465441SEvalZero #define ip4_current_header() ip_data.current_ip4_header 181*10465441SEvalZero /** Always returns FALSE when only supporting IPv4 only */ 182*10465441SEvalZero #define ip_current_is_v6() 0 183*10465441SEvalZero /** Get the transport layer protocol */ 184*10465441SEvalZero #define ip_current_header_proto() IPH_PROTO(ip4_current_header()) 185*10465441SEvalZero /** Get the transport layer header */ 186*10465441SEvalZero #define ip_next_header_ptr() ((const void*)((const u8_t*)ip4_current_header() + ip_current_header_tot_len())) 187*10465441SEvalZero /** Source IP4 address of current_header */ 188*10465441SEvalZero #define ip4_current_src_addr() (&ip_data.current_iphdr_src) 189*10465441SEvalZero /** Destination IP4 address of current_header */ 190*10465441SEvalZero #define ip4_current_dest_addr() (&ip_data.current_iphdr_dest) 191*10465441SEvalZero 192*10465441SEvalZero #elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ 193*10465441SEvalZero 194*10465441SEvalZero /** Get the IPv6 header of the current packet. 195*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 196*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 197*10465441SEvalZero #define ip6_current_header() ((const struct ip6_hdr*)(ip_data.current_ip6_header)) 198*10465441SEvalZero /** Always returns TRUE when only supporting IPv6 only */ 199*10465441SEvalZero #define ip_current_is_v6() 1 200*10465441SEvalZero /** Get the transport layer protocol */ 201*10465441SEvalZero #define ip_current_header_proto() IP6H_NEXTH(ip6_current_header()) 202*10465441SEvalZero /** Get the transport layer header */ 203*10465441SEvalZero #define ip_next_header_ptr() ((const void*)(((const u8_t*)ip6_current_header()) + ip_current_header_tot_len())) 204*10465441SEvalZero /** Source IP6 address of current_header */ 205*10465441SEvalZero #define ip6_current_src_addr() (&ip_data.current_iphdr_src) 206*10465441SEvalZero /** Destination IP6 address of current_header */ 207*10465441SEvalZero #define ip6_current_dest_addr() (&ip_data.current_iphdr_dest) 208*10465441SEvalZero 209*10465441SEvalZero #endif /* LWIP_IPV6 */ 210*10465441SEvalZero 211*10465441SEvalZero /** Union source address of current_header */ 212*10465441SEvalZero #define ip_current_src_addr() (&ip_data.current_iphdr_src) 213*10465441SEvalZero /** Union destination address of current_header */ 214*10465441SEvalZero #define ip_current_dest_addr() (&ip_data.current_iphdr_dest) 215*10465441SEvalZero 216*10465441SEvalZero /** Gets an IP pcb option (SOF_* flags) */ 217*10465441SEvalZero #define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) 218*10465441SEvalZero /** Sets an IP pcb option (SOF_* flags) */ 219*10465441SEvalZero #define ip_set_option(pcb, opt) ((pcb)->so_options = (u8_t)((pcb)->so_options | (opt))) 220*10465441SEvalZero /** Resets an IP pcb option (SOF_* flags) */ 221*10465441SEvalZero #define ip_reset_option(pcb, opt) ((pcb)->so_options = (u8_t)((pcb)->so_options & ~(opt))) 222*10465441SEvalZero 223*10465441SEvalZero #if LWIP_IPV4 && LWIP_IPV6 224*10465441SEvalZero /** 225*10465441SEvalZero * @ingroup ip 226*10465441SEvalZero * Output IP packet, netif is selected by source address 227*10465441SEvalZero */ 228*10465441SEvalZero #define ip_output(p, src, dest, ttl, tos, proto) \ 229*10465441SEvalZero (IP_IS_V6(dest) ? \ 230*10465441SEvalZero ip6_output(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto) : \ 231*10465441SEvalZero ip4_output(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto)) 232*10465441SEvalZero /** 233*10465441SEvalZero * @ingroup ip 234*10465441SEvalZero * Output IP packet to specified interface 235*10465441SEvalZero */ 236*10465441SEvalZero #define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ 237*10465441SEvalZero (IP_IS_V6(dest) ? \ 238*10465441SEvalZero ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ 239*10465441SEvalZero ip4_output_if(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif)) 240*10465441SEvalZero /** 241*10465441SEvalZero * @ingroup ip 242*10465441SEvalZero * Output IP packet to interface specifying source address 243*10465441SEvalZero */ 244*10465441SEvalZero #define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ 245*10465441SEvalZero (IP_IS_V6(dest) ? \ 246*10465441SEvalZero ip6_output_if_src(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ 247*10465441SEvalZero ip4_output_if_src(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif)) 248*10465441SEvalZero /** Output IP packet that already includes an IP header. */ 249*10465441SEvalZero #define ip_output_if_hdrincl(p, src, dest, netif) \ 250*10465441SEvalZero (IP_IS_V6(dest) ? \ 251*10465441SEvalZero ip6_output_if(p, ip_2_ip6(src), LWIP_IP_HDRINCL, 0, 0, 0, netif) : \ 252*10465441SEvalZero ip4_output_if(p, ip_2_ip4(src), LWIP_IP_HDRINCL, 0, 0, 0, netif)) 253*10465441SEvalZero /** Output IP packet with netif_hint */ 254*10465441SEvalZero #define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \ 255*10465441SEvalZero (IP_IS_V6(dest) ? \ 256*10465441SEvalZero ip6_output_hinted(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif_hint) : \ 257*10465441SEvalZero ip4_output_hinted(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif_hint)) 258*10465441SEvalZero /** 259*10465441SEvalZero * @ingroup ip 260*10465441SEvalZero * Get netif for address combination. See \ref ip6_route and \ref ip4_route 261*10465441SEvalZero */ 262*10465441SEvalZero #define ip_route(src, dest) \ 263*10465441SEvalZero (IP_IS_V6(dest) ? \ 264*10465441SEvalZero ip6_route(ip_2_ip6(src), ip_2_ip6(dest)) : \ 265*10465441SEvalZero ip4_route_src(ip_2_ip4(src), ip_2_ip4(dest))) 266*10465441SEvalZero /** 267*10465441SEvalZero * @ingroup ip 268*10465441SEvalZero * Get netif for IP. 269*10465441SEvalZero */ 270*10465441SEvalZero #define ip_netif_get_local_ip(netif, dest) (IP_IS_V6(dest) ? \ 271*10465441SEvalZero ip6_netif_get_local_ip(netif, ip_2_ip6(dest)) : \ 272*10465441SEvalZero ip4_netif_get_local_ip(netif)) 273*10465441SEvalZero #define ip_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip4_debug_print(p)) 274*10465441SEvalZero 275*10465441SEvalZero err_t ip_input(struct pbuf *p, struct netif *inp); 276*10465441SEvalZero 277*10465441SEvalZero #elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */ 278*10465441SEvalZero 279*10465441SEvalZero #define ip_output(p, src, dest, ttl, tos, proto) \ 280*10465441SEvalZero ip4_output(p, src, dest, ttl, tos, proto) 281*10465441SEvalZero #define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ 282*10465441SEvalZero ip4_output_if(p, src, dest, ttl, tos, proto, netif) 283*10465441SEvalZero #define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ 284*10465441SEvalZero ip4_output_if_src(p, src, dest, ttl, tos, proto, netif) 285*10465441SEvalZero #define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \ 286*10465441SEvalZero ip4_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) 287*10465441SEvalZero #define ip_output_if_hdrincl(p, src, dest, netif) \ 288*10465441SEvalZero ip4_output_if(p, src, LWIP_IP_HDRINCL, 0, 0, 0, netif) 289*10465441SEvalZero #define ip_route(src, dest) \ 290*10465441SEvalZero ip4_route_src(src, dest) 291*10465441SEvalZero #define ip_netif_get_local_ip(netif, dest) \ 292*10465441SEvalZero ip4_netif_get_local_ip(netif) 293*10465441SEvalZero #define ip_debug_print(is_ipv6, p) ip4_debug_print(p) 294*10465441SEvalZero 295*10465441SEvalZero #define ip_input ip4_input 296*10465441SEvalZero 297*10465441SEvalZero #elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ 298*10465441SEvalZero 299*10465441SEvalZero #define ip_output(p, src, dest, ttl, tos, proto) \ 300*10465441SEvalZero ip6_output(p, src, dest, ttl, tos, proto) 301*10465441SEvalZero #define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ 302*10465441SEvalZero ip6_output_if(p, src, dest, ttl, tos, proto, netif) 303*10465441SEvalZero #define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ 304*10465441SEvalZero ip6_output_if_src(p, src, dest, ttl, tos, proto, netif) 305*10465441SEvalZero #define ip_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) \ 306*10465441SEvalZero ip6_output_hinted(p, src, dest, ttl, tos, proto, netif_hint) 307*10465441SEvalZero #define ip_output_if_hdrincl(p, src, dest, netif) \ 308*10465441SEvalZero ip6_output_if(p, src, LWIP_IP_HDRINCL, 0, 0, 0, netif) 309*10465441SEvalZero #define ip_route(src, dest) \ 310*10465441SEvalZero ip6_route(src, dest) 311*10465441SEvalZero #define ip_netif_get_local_ip(netif, dest) \ 312*10465441SEvalZero ip6_netif_get_local_ip(netif, dest) 313*10465441SEvalZero #define ip_debug_print(is_ipv6, p) ip6_debug_print(p) 314*10465441SEvalZero 315*10465441SEvalZero #define ip_input ip6_input 316*10465441SEvalZero 317*10465441SEvalZero #endif /* LWIP_IPV6 */ 318*10465441SEvalZero 319*10465441SEvalZero #define ip_route_get_local_ip(src, dest, netif, ipaddr) do { \ 320*10465441SEvalZero (netif) = ip_route(src, dest); \ 321*10465441SEvalZero (ipaddr) = ip_netif_get_local_ip(netif, dest); \ 322*10465441SEvalZero }while(0) 323*10465441SEvalZero 324*10465441SEvalZero #ifdef __cplusplus 325*10465441SEvalZero } 326*10465441SEvalZero #endif 327*10465441SEvalZero 328*10465441SEvalZero #endif /* LWIP_HDR_IP_H */ 329*10465441SEvalZero 330*10465441SEvalZero 331