Simon Cooksey / mbed-os
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ip.h Source File

ip.h

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * IP API
00004  */
00005 
00006 /*
00007  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00008  * All rights reserved.
00009  *
00010  * Redistribution and use in source and binary forms, with or without modification,
00011  * are permitted provided that the following conditions are met:
00012  *
00013  * 1. Redistributions of source code must retain the above copyright notice,
00014  *    this list of conditions and the following disclaimer.
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  *    this list of conditions and the following disclaimer in the documentation
00017  *    and/or other materials provided with the distribution.
00018  * 3. The name of the author may not be used to endorse or promote products
00019  *    derived from this software without specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00022  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00023  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00024  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00025  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00026  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00027  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00028  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00029  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00030  * OF SUCH DAMAGE.
00031  *
00032  * This file is part of the lwIP TCP/IP stack.
00033  *
00034  * Author: Adam Dunkels <adam@sics.se>
00035  *
00036  */
00037 #ifndef LWIP_HDR_IP_H__
00038 #define LWIP_HDR_IP_H__
00039 
00040 #include "lwip/opt.h"
00041 
00042 #include "lwip/def.h"
00043 #include "lwip/pbuf.h"
00044 #include "lwip/ip_addr.h"
00045 #include "lwip/err.h"
00046 #include "lwip/netif.h"
00047 #include "lwip/ip4.h"
00048 #include "lwip/ip6.h"
00049 
00050 #ifdef __cplusplus
00051 extern "C" {
00052 #endif
00053 
00054 #define IP_PROTO_ICMP    1
00055 #define IP_PROTO_IGMP    2
00056 #define IP_PROTO_UDP     17
00057 #define IP_PROTO_UDPLITE 136
00058 #define IP_PROTO_TCP     6
00059 
00060 /** This operates on a void* by loading the first byte */
00061 #define IP_HDR_GET_VERSION(ptr)   ((*(u8_t*)(ptr)) >> 4)
00062 
00063 /* This is passed as the destination address to ip_output_if (not
00064    to ip_output), meaning that an IP header already is constructed
00065    in the pbuf. This is used when TCP retransmits. */
00066 #ifdef IP_HDRINCL
00067 #undef IP_HDRINCL
00068 #endif /* IP_HDRINCL */
00069 #define IP_HDRINCL  NULL
00070 
00071 /** pbufs passed to IP must have a ref-count of 1 as their payload pointer
00072     gets altered as the packet is passed down the stack */
00073 #ifndef LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX
00074 #define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p) LWIP_ASSERT("p->ref == 1", (p)->ref == 1)
00075 #endif
00076 
00077 #if LWIP_NETIF_HWADDRHINT
00078 #define IP_PCB_ADDRHINT ;u8_t addr_hint
00079 #else
00080 #define IP_PCB_ADDRHINT
00081 #endif /* LWIP_NETIF_HWADDRHINT */
00082 
00083 /** This is the common part of all PCB types. It needs to be at the
00084    beginning of a PCB type definition. It is located here so that
00085    changes to this common part are made in one location instead of
00086    having to change all PCB structs. */
00087 #define IP_PCB \
00088   /* ip addresses in network byte order */ \
00089   ip_addr_t local_ip; \
00090   ip_addr_t remote_ip; \
00091    /* Socket options */  \
00092   u8_t so_options;      \
00093    /* Type Of Service */ \
00094   u8_t tos;              \
00095   /* Time To Live */     \
00096   u8_t ttl               \
00097   /* link layer address resolution hint */ \
00098   IP_PCB_ADDRHINT
00099 
00100 struct ip_pcb {
00101 /* Common members of all PCB types */
00102   IP_PCB;
00103 };
00104 
00105 /*
00106  * Option flags per-socket. These are the same like SO_XXX in sockets.h
00107  */
00108 #define SOF_REUSEADDR     0x04U  /* allow local address reuse */
00109 #define SOF_KEEPALIVE     0x08U  /* keep connections alive */
00110 #define SOF_BROADCAST     0x20U  /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */
00111 
00112 /* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */
00113 #define SOF_INHERITED   (SOF_REUSEADDR|SOF_KEEPALIVE)
00114 
00115 /** Global variables of this module, kept in a struct for efficient access using base+index. */
00116 struct ip_globals
00117 {
00118   /** The interface that accepted the packet for the current callback invocation. */
00119   struct netif *current_netif;
00120   /** The interface that received the packet for the current callback invocation. */
00121   struct netif *current_input_netif;
00122 #if LWIP_IPV4
00123   /** Header of the input packet currently being processed. */
00124   struct ip_hdr *current_ip4_header;
00125 #endif /* LWIP_IPV4 */
00126 #if LWIP_IPV6
00127   /** Header of the input IPv6 packet currently being processed. */
00128   struct ip6_hdr *current_ip6_header;
00129 #endif /* LWIP_IPV6 */
00130   /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */
00131   u16_t current_ip_header_tot_len;
00132   /** Source IP address of current_header */
00133   ip_addr_t current_iphdr_src;
00134   /** Destination IP address of current_header */
00135   ip_addr_t current_iphdr_dest;
00136 };
00137 extern struct ip_globals ip_data;
00138 
00139 
00140 /** Get the interface that accepted the current packet.
00141  * This may or may not be the receiving netif, depending on your netif/network setup.
00142  * This function must only be called from a receive callback (udp_recv,
00143  * raw_recv, tcp_accept). It will return NULL otherwise. */
00144 #define ip_current_netif()      (ip_data.current_netif)
00145 /** Get the interface that received the current packet.
00146  * This function must only be called from a receive callback (udp_recv,
00147  * raw_recv, tcp_accept). It will return NULL otherwise. */
00148 #define ip_current_input_netif() (ip_data.current_input_netif)
00149 /** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */
00150 #define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len)
00151 /** Source IP address of current_header */
00152 #define ip_current_src_addr()   (&ip_data.current_iphdr_src)
00153 /** Destination IP address of current_header */
00154 #define ip_current_dest_addr()  (&ip_data.current_iphdr_dest)
00155 
00156 #if LWIP_IPV4 && LWIP_IPV6
00157 /** Get the IPv4 header of the current packet.
00158  * This function must only be called from a receive callback (udp_recv,
00159  * raw_recv, tcp_accept). It will return NULL otherwise. */
00160 #define ip4_current_header()     ((const struct ip_hdr*)(ip_data.current_ip4_header))
00161 /** Get the IPv6 header of the current packet.
00162  * This function must only be called from a receive callback (udp_recv,
00163  * raw_recv, tcp_accept). It will return NULL otherwise. */
00164 #define ip6_current_header()      ((const struct ip6_hdr*)(ip_data.current_ip6_header))
00165 /** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */
00166 #define ip_current_is_v6()        (ip6_current_header() != NULL)
00167 /** Source IPv6 address of current_header */
00168 #define ip6_current_src_addr()    (ip_2_ip6(&ip_data.current_iphdr_src))
00169 /** Destination IPv6 address of current_header */
00170 #define ip6_current_dest_addr()   (ip_2_ip6(&ip_data.current_iphdr_dest))
00171 /** Get the transport layer protocol */
00172 #define ip_current_header_proto() (ip_current_is_v6() ? \
00173                                    IP6H_NEXTH(ip6_current_header()) :\
00174                                    IPH_PROTO(ip4_current_header()))
00175 /** Get the transport layer header */
00176 #define ip_next_header_ptr()     ((const void*)((ip_current_is_v6() ? \
00177   (const u8_t*)ip6_current_header() : (const u8_t*)ip4_current_header())  + ip_current_header_tot_len()))
00178 
00179 /** Source IP4 address of current_header */
00180 #define ip4_current_src_addr()     (ip_2_ip4(&ip_data.current_iphdr_src))
00181 /** Destination IP4 address of current_header */
00182 #define ip4_current_dest_addr()    (ip_2_ip4(&ip_data.current_iphdr_dest))
00183 
00184 #elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
00185 
00186 /** Get the IPv4 header of the current packet.
00187  * This function must only be called from a receive callback (udp_recv,
00188  * raw_recv, tcp_accept). It will return NULL otherwise. */
00189 #define ip4_current_header()     ((const struct ip_hdr*)(ip_data.current_ip4_header))
00190 /** Always returns FALSE when only supporting IPv4 only */
00191 #define ip_current_is_v6()        0
00192 /** Get the transport layer protocol */
00193 #define ip_current_header_proto() IPH_PROTO(ip4_current_header())
00194 /** Get the transport layer header */
00195 #define ip_next_header_ptr()     ((const void*)((const u8_t*)ip4_current_header() + ip_current_header_tot_len()))
00196 /** Source IP4 address of current_header */
00197 #define ip4_current_src_addr()     (&ip_data.current_iphdr_src)
00198 /** Destination IP4 address of current_header */
00199 #define ip4_current_dest_addr()    (&ip_data.current_iphdr_dest)
00200 
00201 #elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */
00202 
00203 /** Get the IPv6 header of the current packet.
00204  * This function must only be called from a receive callback (udp_recv,
00205  * raw_recv, tcp_accept). It will return NULL otherwise. */
00206 #define ip6_current_header()      ((const struct ip6_hdr*)(ip_data.current_ip6_header))
00207 /** Always returns TRUE when only supporting IPv6 only */
00208 #define ip_current_is_v6()        1
00209 /** Get the transport layer protocol */
00210 #define ip_current_header_proto() IP6H_NEXTH(ip6_current_header())
00211 /** Get the transport layer header */
00212 #define ip_next_header_ptr()     ((const void*)((const u8_t*)ip6_current_header()))
00213 /** Source IP6 address of current_header */
00214 #define ip6_current_src_addr()    (&ip_data.current_iphdr_src)
00215 /** Destination IP6 address of current_header */
00216 #define ip6_current_dest_addr()   (&ip_data.current_iphdr_dest)
00217 
00218 #endif /* LWIP_IPV6 */
00219 
00220 /** Union source address of current_header */
00221 #define ip_current_src_addr()    (&ip_data.current_iphdr_src)
00222 /** Union destination address of current_header */
00223 #define ip_current_dest_addr()   (&ip_data.current_iphdr_dest)
00224 
00225 /** Gets an IP pcb option (SOF_* flags) */
00226 #define ip_get_option(pcb, opt)   ((pcb)->so_options & (opt))
00227 /** Sets an IP pcb option (SOF_* flags) */
00228 #define ip_set_option(pcb, opt)   ((pcb)->so_options |= (opt))
00229 /** Resets an IP pcb option (SOF_* flags) */
00230 #define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt))
00231 
00232 #if LWIP_IPV4 && LWIP_IPV6
00233 /** Output IP packet, netif is selected by source address */
00234 #define ip_output(p, src, dest, ttl, tos, proto) \
00235         (IP_IS_V6(dest) ? \
00236         ip6_output(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto) : \
00237         ip4_output(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto))
00238 /** Output IP packet to specified interface */
00239 #define ip_output_if(p, src, dest, ttl, tos, proto, netif) \
00240         (IP_IS_V6(dest) ? \
00241         ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \
00242         ip4_output_if(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif))
00243 /** Output IP packet to interface specifying source address */
00244 #define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \
00245         (IP_IS_V6(dest) ? \
00246         ip6_output_if_src(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \
00247         ip4_output_if_src(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif))
00248 /** Output IP packet with addr_hint */
00249 #define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \
00250         (IP_IS_V6(dest) ? \
00251         ip6_output_hinted(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, addr_hint) : \
00252         ip4_output_hinted(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, addr_hint))
00253 /** Get netif for address combination. See \ref ip6_route and \ref ip4_route */
00254 #define ip_route(src, dest) \
00255         (IP_IS_V6(dest) ? \
00256         ip6_route(ip_2_ip6(src), ip_2_ip6(dest)) : \
00257         ip4_route_src(ip_2_ip4(dest), ip_2_ip4(src)))
00258 /** Get netif for IP.*/
00259 #define ip_netif_get_local_ip(netif, dest) (IP_IS_V6(dest) ? \
00260         ip6_netif_get_local_ip(netif, ip_2_ip6(dest)) : \
00261         ip4_netif_get_local_ip(netif))
00262 #define ip_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip4_debug_print(p))
00263 
00264 err_t ip_input(struct pbuf *p, struct netif *inp);
00265 
00266 #elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */
00267 
00268 #define ip_output(p, src, dest, ttl, tos, proto) \
00269         ip4_output(p, src, dest, ttl, tos, proto)
00270 #define ip_output_if(p, src, dest, ttl, tos, proto, netif) \
00271         ip4_output_if(p, src, dest, ttl, tos, proto, netif)
00272 #define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \
00273         ip4_output_if_src(p, src, dest, ttl, tos, proto, netif)
00274 #define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \
00275         ip4_output_hinted(p, src, dest, ttl, tos, proto, addr_hint)
00276 #define ip_route(src, dest) \
00277         ip4_route_src(dest, src)
00278 #define ip_netif_get_local_ip(netif, dest) \
00279         ip4_netif_get_local_ip(netif)
00280 #define ip_debug_print(is_ipv6, p) ip4_debug_print(p)
00281 
00282 #define ip_input ip4_input
00283 
00284 #elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */
00285 
00286 #define ip_output(p, src, dest, ttl, tos, proto) \
00287         ip6_output(p, src, dest, ttl, tos, proto)
00288 #define ip_output_if(p, src, dest, ttl, tos, proto, netif) \
00289         ip6_output_if(p, src, dest, ttl, tos, proto, netif)
00290 #define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \
00291         ip6_output_if_src(p, src, dest, ttl, tos, proto, netif)
00292 #define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \
00293         ip6_output_hinted(p, src, dest, ttl, tos, proto, addr_hint)
00294 #define ip_route(src, dest) \
00295         ip6_route(src, dest)
00296 #define ip_netif_get_local_ip(netif, dest) \
00297         ip6_netif_get_local_ip(netif, dest)
00298 #define ip_debug_print(is_ipv6, p) ip6_debug_print(p)
00299 
00300 #define ip_input ip6_input
00301 
00302 #endif /* LWIP_IPV6 */
00303 
00304 #define ip_route_get_local_ip(src, dest, netif, ipaddr) do { \
00305   (netif) = ip_route(src, dest); \
00306   (ipaddr) = ip_netif_get_local_ip(netif, dest); \
00307 }while(0)
00308 
00309 #ifdef __cplusplus
00310 }
00311 #endif
00312 
00313 #endif /* LWIP_HDR_IP_H__ */
00314 
00315