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_HWADDRHINT 67*10465441SEvalZero #define IP_PCB_ADDRHINT ;u8_t addr_hint 68*10465441SEvalZero #else 69*10465441SEvalZero #define IP_PCB_ADDRHINT 70*10465441SEvalZero #endif /* LWIP_NETIF_HWADDRHINT */ 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 /* Socket options */ \ 81*10465441SEvalZero u8_t so_options; \ 82*10465441SEvalZero /* Type Of Service */ \ 83*10465441SEvalZero u8_t tos; \ 84*10465441SEvalZero /* Time To Live */ \ 85*10465441SEvalZero u8_t ttl \ 86*10465441SEvalZero /* link layer address resolution hint */ \ 87*10465441SEvalZero IP_PCB_ADDRHINT 88*10465441SEvalZero 89*10465441SEvalZero struct ip_pcb { 90*10465441SEvalZero /* Common members of all PCB types */ 91*10465441SEvalZero IP_PCB; 92*10465441SEvalZero }; 93*10465441SEvalZero 94*10465441SEvalZero /* 95*10465441SEvalZero * Option flags per-socket. These are the same like SO_XXX in sockets.h 96*10465441SEvalZero */ 97*10465441SEvalZero #define SOF_REUSEADDR 0x04U /* allow local address reuse */ 98*10465441SEvalZero #define SOF_KEEPALIVE 0x08U /* keep connections alive */ 99*10465441SEvalZero #define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ 100*10465441SEvalZero 101*10465441SEvalZero /* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ 102*10465441SEvalZero #define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE) 103*10465441SEvalZero 104*10465441SEvalZero /** Global variables of this module, kept in a struct for efficient access using base+index. */ 105*10465441SEvalZero struct ip_globals 106*10465441SEvalZero { 107*10465441SEvalZero /** The interface that accepted the packet for the current callback invocation. */ 108*10465441SEvalZero struct netif *current_netif; 109*10465441SEvalZero /** The interface that received the packet for the current callback invocation. */ 110*10465441SEvalZero struct netif *current_input_netif; 111*10465441SEvalZero #if LWIP_IPV4 112*10465441SEvalZero /** Header of the input packet currently being processed. */ 113*10465441SEvalZero struct ip_hdr *current_ip4_header; 114*10465441SEvalZero #endif /* LWIP_IPV4 */ 115*10465441SEvalZero #if LWIP_IPV6 116*10465441SEvalZero /** Header of the input IPv6 packet currently being processed. */ 117*10465441SEvalZero struct ip6_hdr *current_ip6_header; 118*10465441SEvalZero #endif /* LWIP_IPV6 */ 119*10465441SEvalZero /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ 120*10465441SEvalZero u16_t current_ip_header_tot_len; 121*10465441SEvalZero /** Source IP address of current_header */ 122*10465441SEvalZero ip_addr_t current_iphdr_src; 123*10465441SEvalZero /** Destination IP address of current_header */ 124*10465441SEvalZero ip_addr_t current_iphdr_dest; 125*10465441SEvalZero }; 126*10465441SEvalZero extern struct ip_globals ip_data; 127*10465441SEvalZero 128*10465441SEvalZero 129*10465441SEvalZero /** Get the interface that accepted the current packet. 130*10465441SEvalZero * This may or may not be the receiving netif, depending on your netif/network setup. 131*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 132*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 133*10465441SEvalZero #define ip_current_netif() (ip_data.current_netif) 134*10465441SEvalZero /** Get the interface that received the current packet. 135*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 136*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 137*10465441SEvalZero #define ip_current_input_netif() (ip_data.current_input_netif) 138*10465441SEvalZero /** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */ 139*10465441SEvalZero #define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len) 140*10465441SEvalZero /** Source IP address of current_header */ 141*10465441SEvalZero #define ip_current_src_addr() (&ip_data.current_iphdr_src) 142*10465441SEvalZero /** Destination IP address of current_header */ 143*10465441SEvalZero #define ip_current_dest_addr() (&ip_data.current_iphdr_dest) 144*10465441SEvalZero 145*10465441SEvalZero #if LWIP_IPV4 && LWIP_IPV6 146*10465441SEvalZero /** Get the IPv4 header of the current packet. 147*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 148*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 149*10465441SEvalZero #define ip4_current_header() ((const struct ip_hdr*)(ip_data.current_ip4_header)) 150*10465441SEvalZero /** Get the IPv6 header of the current packet. 151*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 152*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 153*10465441SEvalZero #define ip6_current_header() ((const struct ip6_hdr*)(ip_data.current_ip6_header)) 154*10465441SEvalZero /** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ 155*10465441SEvalZero #define ip_current_is_v6() (ip6_current_header() != NULL) 156*10465441SEvalZero /** Source IPv6 address of current_header */ 157*10465441SEvalZero #define ip6_current_src_addr() (ip_2_ip6(&ip_data.current_iphdr_src)) 158*10465441SEvalZero /** Destination IPv6 address of current_header */ 159*10465441SEvalZero #define ip6_current_dest_addr() (ip_2_ip6(&ip_data.current_iphdr_dest)) 160*10465441SEvalZero /** Get the transport layer protocol */ 161*10465441SEvalZero #define ip_current_header_proto() (ip_current_is_v6() ? \ 162*10465441SEvalZero IP6H_NEXTH(ip6_current_header()) :\ 163*10465441SEvalZero IPH_PROTO(ip4_current_header())) 164*10465441SEvalZero /** Get the transport layer header */ 165*10465441SEvalZero #define ip_next_header_ptr() ((const void*)((ip_current_is_v6() ? \ 166*10465441SEvalZero (const u8_t*)ip6_current_header() : (const u8_t*)ip4_current_header()) + ip_current_header_tot_len())) 167*10465441SEvalZero 168*10465441SEvalZero /** Source IP4 address of current_header */ 169*10465441SEvalZero #define ip4_current_src_addr() (ip_2_ip4(&ip_data.current_iphdr_src)) 170*10465441SEvalZero /** Destination IP4 address of current_header */ 171*10465441SEvalZero #define ip4_current_dest_addr() (ip_2_ip4(&ip_data.current_iphdr_dest)) 172*10465441SEvalZero 173*10465441SEvalZero #elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */ 174*10465441SEvalZero 175*10465441SEvalZero /** Get the IPv4 header of the current packet. 176*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 177*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 178*10465441SEvalZero #define ip4_current_header() ((const struct ip_hdr*)(ip_data.current_ip4_header)) 179*10465441SEvalZero /** Always returns FALSE when only supporting IPv4 only */ 180*10465441SEvalZero #define ip_current_is_v6() 0 181*10465441SEvalZero /** Get the transport layer protocol */ 182*10465441SEvalZero #define ip_current_header_proto() IPH_PROTO(ip4_current_header()) 183*10465441SEvalZero /** Get the transport layer header */ 184*10465441SEvalZero #define ip_next_header_ptr() ((const void*)((const u8_t*)ip4_current_header() + ip_current_header_tot_len())) 185*10465441SEvalZero /** Source IP4 address of current_header */ 186*10465441SEvalZero #define ip4_current_src_addr() (&ip_data.current_iphdr_src) 187*10465441SEvalZero /** Destination IP4 address of current_header */ 188*10465441SEvalZero #define ip4_current_dest_addr() (&ip_data.current_iphdr_dest) 189*10465441SEvalZero 190*10465441SEvalZero #elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ 191*10465441SEvalZero 192*10465441SEvalZero /** Get the IPv6 header of the current packet. 193*10465441SEvalZero * This function must only be called from a receive callback (udp_recv, 194*10465441SEvalZero * raw_recv, tcp_accept). It will return NULL otherwise. */ 195*10465441SEvalZero #define ip6_current_header() ((const struct ip6_hdr*)(ip_data.current_ip6_header)) 196*10465441SEvalZero /** Always returns TRUE when only supporting IPv6 only */ 197*10465441SEvalZero #define ip_current_is_v6() 1 198*10465441SEvalZero /** Get the transport layer protocol */ 199*10465441SEvalZero #define ip_current_header_proto() IP6H_NEXTH(ip6_current_header()) 200*10465441SEvalZero /** Get the transport layer header */ 201*10465441SEvalZero #define ip_next_header_ptr() ((const void*)((const u8_t*)ip6_current_header())) 202*10465441SEvalZero /** Source IP6 address of current_header */ 203*10465441SEvalZero #define ip6_current_src_addr() (&ip_data.current_iphdr_src) 204*10465441SEvalZero /** Destination IP6 address of current_header */ 205*10465441SEvalZero #define ip6_current_dest_addr() (&ip_data.current_iphdr_dest) 206*10465441SEvalZero 207*10465441SEvalZero #endif /* LWIP_IPV6 */ 208*10465441SEvalZero 209*10465441SEvalZero /** Union source address of current_header */ 210*10465441SEvalZero #define ip_current_src_addr() (&ip_data.current_iphdr_src) 211*10465441SEvalZero /** Union destination address of current_header */ 212*10465441SEvalZero #define ip_current_dest_addr() (&ip_data.current_iphdr_dest) 213*10465441SEvalZero 214*10465441SEvalZero /** Gets an IP pcb option (SOF_* flags) */ 215*10465441SEvalZero #define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) 216*10465441SEvalZero /** Sets an IP pcb option (SOF_* flags) */ 217*10465441SEvalZero #define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt)) 218*10465441SEvalZero /** Resets an IP pcb option (SOF_* flags) */ 219*10465441SEvalZero #define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) 220*10465441SEvalZero 221*10465441SEvalZero #if LWIP_IPV4 && LWIP_IPV6 222*10465441SEvalZero /** 223*10465441SEvalZero * @ingroup ip 224*10465441SEvalZero * Output IP packet, netif is selected by source address 225*10465441SEvalZero */ 226*10465441SEvalZero #define ip_output(p, src, dest, ttl, tos, proto) \ 227*10465441SEvalZero (IP_IS_V6(dest) ? \ 228*10465441SEvalZero ip6_output(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto) : \ 229*10465441SEvalZero ip4_output(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto)) 230*10465441SEvalZero /** 231*10465441SEvalZero * @ingroup ip 232*10465441SEvalZero * Output IP packet to specified interface 233*10465441SEvalZero */ 234*10465441SEvalZero #define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ 235*10465441SEvalZero (IP_IS_V6(dest) ? \ 236*10465441SEvalZero ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ 237*10465441SEvalZero ip4_output_if(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif)) 238*10465441SEvalZero /** 239*10465441SEvalZero * @ingroup ip 240*10465441SEvalZero * Output IP packet to interface specifying source address 241*10465441SEvalZero */ 242*10465441SEvalZero #define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ 243*10465441SEvalZero (IP_IS_V6(dest) ? \ 244*10465441SEvalZero ip6_output_if_src(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ 245*10465441SEvalZero ip4_output_if_src(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif)) 246*10465441SEvalZero /** Output IP packet with addr_hint */ 247*10465441SEvalZero #define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \ 248*10465441SEvalZero (IP_IS_V6(dest) ? \ 249*10465441SEvalZero ip6_output_hinted(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, addr_hint) : \ 250*10465441SEvalZero ip4_output_hinted(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, addr_hint)) 251*10465441SEvalZero /** 252*10465441SEvalZero * @ingroup ip 253*10465441SEvalZero * Get netif for address combination. See \ref ip6_route and \ref ip4_route 254*10465441SEvalZero */ 255*10465441SEvalZero #define ip_route(src, dest) \ 256*10465441SEvalZero (IP_IS_V6(dest) ? \ 257*10465441SEvalZero ip6_route(ip_2_ip6(src), ip_2_ip6(dest)) : \ 258*10465441SEvalZero ip4_route_src(ip_2_ip4(dest), ip_2_ip4(src))) 259*10465441SEvalZero /** 260*10465441SEvalZero * @ingroup ip 261*10465441SEvalZero * Get netif for IP. 262*10465441SEvalZero */ 263*10465441SEvalZero #define ip_netif_get_local_ip(netif, dest) (IP_IS_V6(dest) ? \ 264*10465441SEvalZero ip6_netif_get_local_ip(netif, ip_2_ip6(dest)) : \ 265*10465441SEvalZero ip4_netif_get_local_ip(netif)) 266*10465441SEvalZero #define ip_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip4_debug_print(p)) 267*10465441SEvalZero 268*10465441SEvalZero err_t ip_input(struct pbuf *p, struct netif *inp); 269*10465441SEvalZero 270*10465441SEvalZero #elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */ 271*10465441SEvalZero 272*10465441SEvalZero #define ip_output(p, src, dest, ttl, tos, proto) \ 273*10465441SEvalZero ip4_output(p, src, dest, ttl, tos, proto) 274*10465441SEvalZero #define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ 275*10465441SEvalZero ip4_output_if(p, src, dest, ttl, tos, proto, netif) 276*10465441SEvalZero #define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ 277*10465441SEvalZero ip4_output_if_src(p, src, dest, ttl, tos, proto, netif) 278*10465441SEvalZero #define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \ 279*10465441SEvalZero ip4_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) 280*10465441SEvalZero #define ip_route(src, dest) \ 281*10465441SEvalZero ip4_route_src(dest, src) 282*10465441SEvalZero #define ip_netif_get_local_ip(netif, dest) \ 283*10465441SEvalZero ip4_netif_get_local_ip(netif) 284*10465441SEvalZero #define ip_debug_print(is_ipv6, p) ip4_debug_print(p) 285*10465441SEvalZero 286*10465441SEvalZero #define ip_input ip4_input 287*10465441SEvalZero 288*10465441SEvalZero #elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ 289*10465441SEvalZero 290*10465441SEvalZero #define ip_output(p, src, dest, ttl, tos, proto) \ 291*10465441SEvalZero ip6_output(p, src, dest, ttl, tos, proto) 292*10465441SEvalZero #define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ 293*10465441SEvalZero ip6_output_if(p, src, dest, ttl, tos, proto, netif) 294*10465441SEvalZero #define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ 295*10465441SEvalZero ip6_output_if_src(p, src, dest, ttl, tos, proto, netif) 296*10465441SEvalZero #define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \ 297*10465441SEvalZero ip6_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) 298*10465441SEvalZero #define ip_route(src, dest) \ 299*10465441SEvalZero ip6_route(src, dest) 300*10465441SEvalZero #define ip_netif_get_local_ip(netif, dest) \ 301*10465441SEvalZero ip6_netif_get_local_ip(netif, dest) 302*10465441SEvalZero #define ip_debug_print(is_ipv6, p) ip6_debug_print(p) 303*10465441SEvalZero 304*10465441SEvalZero #define ip_input ip6_input 305*10465441SEvalZero 306*10465441SEvalZero #endif /* LWIP_IPV6 */ 307*10465441SEvalZero 308*10465441SEvalZero #define ip_route_get_local_ip(src, dest, netif, ipaddr) do { \ 309*10465441SEvalZero (netif) = ip_route(src, dest); \ 310*10465441SEvalZero (ipaddr) = ip_netif_get_local_ip(netif, dest); \ 311*10465441SEvalZero }while(0) 312*10465441SEvalZero 313*10465441SEvalZero #ifdef __cplusplus 314*10465441SEvalZero } 315*10465441SEvalZero #endif 316*10465441SEvalZero 317*10465441SEvalZero #endif /* LWIP_HDR_IP_H */ 318*10465441SEvalZero 319*10465441SEvalZero 320