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