Mistake on this page?
Report an issue in GitHub or email us
ip6_addr.h
Go to the documentation of this file.
1 /**
2  * @file
3  *
4  * IPv6 addresses.
5  */
6 
7 /*
8  * Copyright (c) 2010 Inico Technologies Ltd.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without modification,
12  * are permitted provided that the following conditions are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  * this list of conditions and the following disclaimer in the documentation
18  * and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  * derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31  * OF SUCH DAMAGE.
32  *
33  * This file is part of the lwIP TCP/IP stack.
34  *
35  * Author: Ivan Delamer <delamer@inicotech.com>
36  *
37  * Structs and macros for handling IPv6 addresses.
38  *
39  * Please coordinate changes and requests with Ivan Delamer
40  * <delamer@inicotech.com>
41  */
42 #ifndef LWIP_HDR_IP6_ADDR_H
43 #define LWIP_HDR_IP6_ADDR_H
44 
45 #include "lwip/opt.h"
46 #include "def.h"
47 
48 #if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */
49 
50 #include "lwip/ip6_zone.h"
51 
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55 
56 
57 /** This is the aligned version of ip6_addr_t,
58  used as local variable, on the stack, etc. */
59 struct ip6_addr {
60  u32_t addr[4];
61 #if LWIP_IPV6_SCOPES
62  u8_t zone;
63 #endif /* LWIP_IPV6_SCOPES */
64 };
65 
66 /** IPv6 address */
67 typedef struct ip6_addr ip6_addr_t;
68 
69 /** Set an IPv6 partial address given by byte-parts */
70 #define IP6_ADDR_PART(ip6addr, index, a,b,c,d) \
71  (ip6addr)->addr[index] = PP_HTONL(LWIP_MAKEU32(a,b,c,d))
72 
73 /** Set a full IPv6 address by passing the 4 u32_t indices in network byte order
74  (use PP_HTONL() for constants) */
75 #define IP6_ADDR(ip6addr, idx0, idx1, idx2, idx3) do { \
76  (ip6addr)->addr[0] = idx0; \
77  (ip6addr)->addr[1] = idx1; \
78  (ip6addr)->addr[2] = idx2; \
79  (ip6addr)->addr[3] = idx3; \
80  ip6_addr_clear_zone(ip6addr); } while(0)
81 
82 /** Access address in 16-bit block */
83 #define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xffff))
84 /** Access address in 16-bit block */
85 #define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0])) & 0xffff))
86 /** Access address in 16-bit block */
87 #define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1]) >> 16) & 0xffff))
88 /** Access address in 16-bit block */
89 #define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1])) & 0xffff))
90 /** Access address in 16-bit block */
91 #define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2]) >> 16) & 0xffff))
92 /** Access address in 16-bit block */
93 #define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2])) & 0xffff))
94 /** Access address in 16-bit block */
95 #define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3]) >> 16) & 0xffff))
96 /** Access address in 16-bit block */
97 #define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3])) & 0xffff))
98 
99 /** Copy IPv6 address - faster than ip6_addr_set: no NULL check */
100 #define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \
101  (dest).addr[1] = (src).addr[1]; \
102  (dest).addr[2] = (src).addr[2]; \
103  (dest).addr[3] = (src).addr[3]; \
104  ip6_addr_copy_zone((dest), (src)); }while(0)
105 /** Safely copy one IPv6 address to another (src may be NULL) */
106 #define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \
107  (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \
108  (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \
109  (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3]; \
110  ip6_addr_set_zone((dest), (src) == NULL ? IP6_NO_ZONE : ip6_addr_zone(src)); }while(0)
111 
112 /** Copy packed IPv6 address to unpacked IPv6 address; zone is not set */
113 #define ip6_addr_copy_from_packed(dest, src) do{(dest).addr[0] = (src).addr[0]; \
114  (dest).addr[1] = (src).addr[1]; \
115  (dest).addr[2] = (src).addr[2]; \
116  (dest).addr[3] = (src).addr[3]; \
117  ip6_addr_clear_zone(&dest); }while(0)
118 
119 /** Copy unpacked IPv6 address to packed IPv6 address; zone is lost */
120 #define ip6_addr_copy_to_packed(dest, src) do{(dest).addr[0] = (src).addr[0]; \
121  (dest).addr[1] = (src).addr[1]; \
122  (dest).addr[2] = (src).addr[2]; \
123  (dest).addr[3] = (src).addr[3]; }while(0)
124 
125 /** Set complete address to zero */
126 #define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \
127  (ip6addr)->addr[1] = 0; \
128  (ip6addr)->addr[2] = 0; \
129  (ip6addr)->addr[3] = 0; \
130  ip6_addr_clear_zone(ip6addr);}while(0)
131 
132 /** Set address to ipv6 'any' (no need for lwip_htonl()) */
133 #define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr)
134 /** Set address to ipv6 loopback address */
135 #define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \
136  (ip6addr)->addr[1] = 0; \
137  (ip6addr)->addr[2] = 0; \
138  (ip6addr)->addr[3] = PP_HTONL(0x00000001UL); \
139  ip6_addr_clear_zone(ip6addr);}while(0)
140 /** Safely copy one IPv6 address to another and change byte order
141  * from host- to network-order. */
142 #define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : lwip_htonl((src)->addr[0]); \
143  (dest)->addr[1] = (src) == NULL ? 0 : lwip_htonl((src)->addr[1]); \
144  (dest)->addr[2] = (src) == NULL ? 0 : lwip_htonl((src)->addr[2]); \
145  (dest)->addr[3] = (src) == NULL ? 0 : lwip_htonl((src)->addr[3]); \
146  ip6_addr_set_zone((dest), (src) == NULL ? IP6_NO_ZONE : ip6_addr_zone(src));}while(0)
147 
148 
149 /** Compare IPv6 networks, ignoring zone information. To be used sparingly! */
150 #define ip6_addr_netcmp_zoneless(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
151  ((addr1)->addr[1] == (addr2)->addr[1]))
152 
153 /**
154  * Determine if two IPv6 address are on the same network.
155  *
156  * @param addr1 IPv6 address 1
157  * @param addr2 IPv6 address 2
158  * @return 1 if the network identifiers of both address match, 0 if not
159  */
160 #define ip6_addr_netcmp(addr1, addr2) (ip6_addr_netcmp_zoneless((addr1), (addr2)) && \
161  ip6_addr_cmp_zone((addr1), (addr2)))
162 
163 /* Exact-host comparison *after* ip6_addr_netcmp() succeeded, for efficiency. */
164 #define ip6_addr_nethostcmp(addr1, addr2) (((addr1)->addr[2] == (addr2)->addr[2]) && \
165  ((addr1)->addr[3] == (addr2)->addr[3]))
166 
167 /** Compare IPv6 addresses, ignoring zone information. To be used sparingly! */
168 #define ip6_addr_cmp_zoneless(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \
169  ((addr1)->addr[1] == (addr2)->addr[1]) && \
170  ((addr1)->addr[2] == (addr2)->addr[2]) && \
171  ((addr1)->addr[3] == (addr2)->addr[3]))
172 /**
173  * Determine if two IPv6 addresses are the same. In particular, the address
174  * part of both must be the same, and the zone must be compatible.
175  *
176  * @param addr1 IPv6 address 1
177  * @param addr2 IPv6 address 2
178  * @return 1 if the addresses are considered equal, 0 if not
179  */
180 #define ip6_addr_cmp(addr1, addr2) (ip6_addr_cmp_zoneless((addr1), (addr2)) && \
181  ip6_addr_cmp_zone((addr1), (addr2)))
182 
183 /** Compare IPv6 address to packed address and zone */
184 #define ip6_addr_cmp_packed(ip6addr, paddr, zone_idx) (((ip6addr)->addr[0] == (paddr)->addr[0]) && \
185  ((ip6addr)->addr[1] == (paddr)->addr[1]) && \
186  ((ip6addr)->addr[2] == (paddr)->addr[2]) && \
187  ((ip6addr)->addr[3] == (paddr)->addr[3]) && \
188  ip6_addr_equals_zone((ip6addr), (zone_idx)))
189 
190 #define ip6_get_subnet_id(ip6addr) (lwip_htonl((ip6addr)->addr[2]) & 0x0000ffffUL)
191 
192 #define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \
193  ((ip6addr).addr[1] == 0) && \
194  ((ip6addr).addr[2] == 0) && \
195  ((ip6addr).addr[3] == 0))
196 #define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || ip6_addr_isany_val(*(ip6addr)))
197 
198 #define ip6_addr_isloopback(ip6addr) (((ip6addr)->addr[0] == 0UL) && \
199  ((ip6addr)->addr[1] == 0UL) && \
200  ((ip6addr)->addr[2] == 0UL) && \
201  ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
202 
203 #define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL))
204 
205 #define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL))
206 
207 #define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL))
208 
209 #define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL))
210 
211 #define ip6_addr_isipv4mappedipv6(ip6addr) (((ip6addr)->addr[0] == 0) && ((ip6addr)->addr[1] == 0) && (((ip6addr)->addr[2]) == PP_HTONL(0x0000FFFFUL)))
212 
213 #define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL))
214 #define ip6_addr_multicast_transient_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL))
215 #define ip6_addr_multicast_prefix_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00200000UL))
216 #define ip6_addr_multicast_rendezvous_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00400000UL))
217 #define ip6_addr_multicast_scope(ip6addr) ((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xf)
218 #define IP6_MULTICAST_SCOPE_RESERVED 0x0
219 #define IP6_MULTICAST_SCOPE_RESERVED0 0x0
220 #define IP6_MULTICAST_SCOPE_INTERFACE_LOCAL 0x1
221 #define IP6_MULTICAST_SCOPE_LINK_LOCAL 0x2
222 #define IP6_MULTICAST_SCOPE_RESERVED3 0x3
223 #define IP6_MULTICAST_SCOPE_ADMIN_LOCAL 0x4
224 #define IP6_MULTICAST_SCOPE_SITE_LOCAL 0x5
225 #define IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL 0x8
226 #define IP6_MULTICAST_SCOPE_GLOBAL 0xe
227 #define IP6_MULTICAST_SCOPE_RESERVEDF 0xf
228 #define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff010000UL))
229 #define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff020000UL))
230 #define ip6_addr_ismulticast_adminlocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff040000UL))
231 #define ip6_addr_ismulticast_sitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff050000UL))
232 #define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff080000UL))
233 #define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff0e0000UL))
234 
235 /* Scoping note: while interface-local and link-local multicast addresses do
236  * have a scope (i.e., they are meaningful only in the context of a particular
237  * interface), the following functions are not assigning or comparing zone
238  * indices. The reason for this is backward compatibility. Any call site that
239  * produces a non-global multicast address must assign a multicast address as
240  * appropriate itself. */
241 
242 #define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \
243  ((ip6addr)->addr[1] == 0UL) && \
244  ((ip6addr)->addr[2] == 0UL) && \
245  ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
246 
247 #define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
248  ((ip6addr)->addr[1] == 0UL) && \
249  ((ip6addr)->addr[2] == 0UL) && \
250  ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL)))
251 #define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
252  (ip6addr)->addr[1] = 0; \
253  (ip6addr)->addr[2] = 0; \
254  (ip6addr)->addr[3] = PP_HTONL(0x00000001UL); \
255  ip6_addr_clear_zone(ip6addr); }while(0)
256 
257 #define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
258  ((ip6addr)->addr[1] == 0UL) && \
259  ((ip6addr)->addr[2] == 0UL) && \
260  ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL)))
261 #define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
262  (ip6addr)->addr[1] = 0; \
263  (ip6addr)->addr[2] = 0; \
264  (ip6addr)->addr[3] = PP_HTONL(0x00000002UL); \
265  ip6_addr_clear_zone(ip6addr); }while(0)
266 
267 #define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
268  ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \
269  (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) )
270 
271 #define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \
272  (ip6addr)->addr[1] = 0; \
273  (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \
274  (ip6addr)->addr[3] = (PP_HTONL(0xff000000UL) | (if_id)); \
275  ip6_addr_clear_zone(ip6addr); }while(0)
276 
277 #define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \
278  ((ip6addr)->addr[1] == 0) && \
279  ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \
280  ((ip6addr)->addr[3] == (PP_HTONL(0xff000000UL) | (sn_addr)->addr[3])))
281 
282 /* IPv6 address states. */
283 #define IP6_ADDR_INVALID 0x00
284 #define IP6_ADDR_TENTATIVE 0x08
285 #define IP6_ADDR_TENTATIVE_1 0x09 /* 1 probe sent */
286 #define IP6_ADDR_TENTATIVE_2 0x0a /* 2 probes sent */
287 #define IP6_ADDR_TENTATIVE_3 0x0b /* 3 probes sent */
288 #define IP6_ADDR_TENTATIVE_4 0x0c /* 4 probes sent */
289 #define IP6_ADDR_TENTATIVE_5 0x0d /* 5 probes sent */
290 #define IP6_ADDR_TENTATIVE_6 0x0e /* 6 probes sent */
291 #define IP6_ADDR_TENTATIVE_7 0x0f /* 7 probes sent */
292 #define IP6_ADDR_VALID 0x10 /* This bit marks an address as valid (preferred or deprecated) */
293 #define IP6_ADDR_PREFERRED 0x30
294 #define IP6_ADDR_DEPRECATED 0x10 /* Same as VALID (valid but not preferred) */
295 #define IP6_ADDR_DUPLICATED 0x40 /* Failed DAD test, not valid */
296 
297 #define IP6_ADDR_TENTATIVE_COUNT_MASK 0x07 /* 1-7 probes sent */
298 
299 #define ip6_addr_isinvalid(addr_state) (addr_state == IP6_ADDR_INVALID)
300 #define ip6_addr_istentative(addr_state) (addr_state & IP6_ADDR_TENTATIVE)
301 #define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */
302 #define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED)
303 #define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED)
304 #define ip6_addr_isduplicated(addr_state) (addr_state == IP6_ADDR_DUPLICATED)
305 
306 #if LWIP_IPV6_ADDRESS_LIFETIMES
307 #define IP6_ADDR_LIFE_STATIC (0)
308 #define IP6_ADDR_LIFE_INFINITE (0xffffffffUL)
309 #define ip6_addr_life_isstatic(addr_life) ((addr_life) == IP6_ADDR_LIFE_STATIC)
310 #define ip6_addr_life_isinfinite(addr_life) ((addr_life) == IP6_ADDR_LIFE_INFINITE)
311 #endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
312 
313 #define ip6_addr_debug_print_parts(debug, a, b, c, d, e, f, g, h) \
314  LWIP_DEBUGF(debug, ("%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F, \
315  a, b, c, d, e, f, g, h))
316 #define ip6_addr_debug_print(debug, ipaddr) \
317  ip6_addr_debug_print_parts(debug, \
318  (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK1(ipaddr) : 0), \
319  (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK2(ipaddr) : 0), \
320  (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK3(ipaddr) : 0), \
321  (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK4(ipaddr) : 0), \
322  (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK5(ipaddr) : 0), \
323  (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK6(ipaddr) : 0), \
324  (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0), \
325  (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0))
326 #define ip6_addr_debug_print_val(debug, ipaddr) \
327  ip6_addr_debug_print_parts(debug, \
328  IP6_ADDR_BLOCK1(&(ipaddr)), \
329  IP6_ADDR_BLOCK2(&(ipaddr)), \
330  IP6_ADDR_BLOCK3(&(ipaddr)), \
331  IP6_ADDR_BLOCK4(&(ipaddr)), \
332  IP6_ADDR_BLOCK5(&(ipaddr)), \
333  IP6_ADDR_BLOCK6(&(ipaddr)), \
334  IP6_ADDR_BLOCK7(&(ipaddr)), \
335  IP6_ADDR_BLOCK8(&(ipaddr)))
336 
337 #define IP6ADDR_STRLEN_MAX 46
338 
339 int ip6addr_aton(const char *cp, ip6_addr_t *addr);
340 /** returns ptr to static buffer; not reentrant! */
341 char *ip6addr_ntoa(const ip6_addr_t *addr);
342 char *ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen);
343 
344 
345 
346 #ifdef __cplusplus
347 }
348 #endif
349 
350 #endif /* LWIP_IPV6 */
351 
352 #endif /* LWIP_HDR_IP6_ADDR_H */
various utility macros
lwIP Options Configuration
IP address structure for passing IP addresses by value.
Definition: nsapi_types.h:190
IPv6 address scopes, zones, and scoping policy.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.