1 #ifndef CONNECT___NCBI_IPV6__H
2 #define CONNECT___NCBI_IPV6__H
3 
4 /* $Id: ncbi_ipv6.h 598940 2019-12-17 16:10:55Z lavr $
5  * ===========================================================================
6  *
7  *                            PUBLIC DOMAIN NOTICE
8  *               National Center for Biotechnology Information
9  *
10  *  This software/database is a "United States Government Work" under the
11  *  terms of the United States Copyright Act.  It was written as part of
12  *  the author's official duties as a United States Government employee and
13  *  thus cannot be copyrighted.  This software/database is freely available
14  *  to the public for use. The National Library of Medicine and the U.S.
15  *  Government have not placed any restriction on its use or reproduction.
16  *
17  *  Although all reasonable efforts have been taken to ensure the accuracy
18  *  and reliability of the software and data, the NLM and the U.S.
19  *  Government do not and cannot warrant the performance or results that
20  *  may be obtained by using this software or data. The NLM and the U.S.
21  *  Government disclaim all warranties, express or implied, including
22  *  warranties of performance, merchantability or fitness for any particular
23  *  purpose.
24  *
25  *  Please cite the author in any work or product based on this material.
26  *
27  * ===========================================================================
28  *
29  * Author:  Anton Lavrentiev
30  *
31  * File Description:
32  * @file ncbi_ipv6.h
33  *   IPv6 addressing support
34  *
35  */
36 
37 #include <connect/connect_export.h>
38 #include <stddef.h>
39 
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif /*__cplusplus*/
44 
45 
46 typedef struct {
47     unsigned char octet[16];  /* assume no alignment */
48 } TNCBI_IPv6Addr;
49 
50 
51 /** Return non-zero if the address is empty (either as IPv6 or IPv4);  return
52  *  zero otherwise.
53  * @sa
54  *  NcbiIsIPv4
55  */
56 extern NCBI_XCONNECT_EXPORT
57 int/*bool*/ NcbiIsEmptyIPv6(const TNCBI_IPv6Addr* addr);
58 
59 
60 /** Return non-zero(true) if the address is a true IPv4 address (a mapped IPv4
61  *  address);  return zero(false) otherwise.
62  * @sa
63  *  NcbiIsIPv4Ex, NcbiIPv4ToIPv6, NcbiIPv6ToIPv4
64  */
65 extern NCBI_XCONNECT_EXPORT
66 int/*bool*/  NcbiIsIPv4    (const TNCBI_IPv6Addr* addr);
67 
68 
69 /** Return non-zero(true) if the address is either a mapped IPv4 address or
70  * (optionally) an IPv4-compatible IPv6 address;  return zero(false) otherwise.
71  * @param compat
72  *  non-zero causes IPv4-compatible IPv6 addresses to pass the test
73  * @note
74  *  NcbiIsIPv4Ex(, 0) is equivalent to NcbiIsIPv4()
75  * @sa
76  *  NcbiIsIPv4, NcbiIPv4ToIPv6, NcbiIPv6ToIPv4
77  */
78 extern NCBI_XCONNECT_EXPORT
79 int/*bool*/  NcbiIsIPv4Ex  (const TNCBI_IPv6Addr* addr, int/*bool*/ compat);
80 
81 
82 /** Extract and return a network byte order IPv4 embedded address from an IPv6
83  *  address, using the specified prefix length (RFC6052).  Return INADDR_NONE
84  *  (-1 = 255.255.255.255) when the specified prefix length is not valid.  A
85  *  special case (and the most anticipated common use-case) is to use prefix
86  *  length 0, which checks that the passed IPv6 address is actually a mapped or
87  *  compatible IPv4 address, then extracts it using the prefix length 96.
88  *  Return 0 if the extraction cannot be made (not an IPv4 mapped/compatible
89  *  address).
90  * @sa
91  *  NcbiIsIPv4, NcbiIPv4ToIPv6
92  */
93 extern NCBI_XCONNECT_EXPORT
94 unsigned int NcbiIPv6ToIPv4(const TNCBI_IPv6Addr* addr, size_t pfxlen);
95 
96 
97 /** Embed a passed network byte order IPv4 address into an IPv6 address using
98  *  the specified prefix length (RFC6052).  Return zero when the specified
99  *  prefix length is not valid, non-zero otherwise.  A special case (and the
100  *  most anticipated common use-case) is to use prefix length 0, which first
101  *  clears the passed IPv6 address, then embeds the IPv4 address as a mapped
102  *  address using the prefix length 96.
103  * @sa
104  *  NcbiIsIPv4, NcbiIPv6ToIPv4
105  */
106 extern NCBI_XCONNECT_EXPORT
107 int/*bool*/  NcbiIPv4ToIPv6(TNCBI_IPv6Addr* addr,
108                             unsigned int ipv4, size_t pfxlen);
109 
110 
111 /** Convert into a network byte order IPv4 address, the first "len" (or
112  *  "strlen(str)" if "len" is 0) bytes of "str" from a full-quad decimal
113  *  notation; return a non-zero string pointer to the first non-converted
114  *  character (which is neither a digit nor a dot); return 0 if conversion
115  *  failed and no IPv4 address had been found.
116  * @sa
117  *  NcbiIPToAddr, NcbiIPv4ToIPv6, NcbiStringToAddr,
118  *  SOCK_StringToHostPort, SOCK_gethostbyname
119  */
120 extern NCBI_XCONNECT_EXPORT
121 const char*  NcbiStringToIPv4(unsigned int* addr,
122                               const char* str, size_t len);
123 
124 
125 /** Convert into an IPv6 address, the first "len" (or "strlen(str)" if "len" is
126  *  0) bytes of "str" from a hexadecimal colon-separated notation (including
127  *  full-quad trailing IPv4); return a non-zero string pointer to the first
128  *  non-converted character (which is neither a hex-digit, nor a colon, nor a
129  *  dot); return 0 if conversion failed and no IPv6 address had been found.
130  * @sa
131  *  NcbiIPToAddr, NcbiStringToAddr
132  */
133 extern NCBI_XCONNECT_EXPORT
134 const char*  NcbiStringToIPv6(TNCBI_IPv6Addr* addr,
135                               const char* str, size_t len);
136 
137 
138 /** Convert into an IPv6 address, the first "len" (or "strlen(str)" if "len" is
139  *  0) bytes of "str" from either a full-quad decimal IPv4 or a hexadecimal
140  *  colon-separated IPv6; return a non-zero string pointer to the first
141  *  non-converted character (which is neither a [hex-]digit, nor a colon, nor a
142  *  dot); return 0 if  no conversion can be made.
143  * @sa
144  *  NcbiStringToIPv4, NcbiStringToIPv6, NcbiStingToAddr, NcbiAddrToString
145  */
146 extern NCBI_XCONNECT_EXPORT
147 const char*  NcbiIPToAddr(TNCBI_IPv6Addr* addr,
148                           const char* str, size_t len);
149 
150 
151 /** Convert into an IPv6 address, the first "len" (or "strlen(str)" if "len" is
152  *  0) bytes of "str", which can be either an .in-addr.arpa- or an
153  *  .in6.arpa-domain names; return a non-zero string pointer to the first
154  *  non-converted character; return 0 if no conversion can be made.
155  * @sa
156  *  NcbiAddrToDNS, NcbiStringToAddr
157  */
158 extern NCBI_XCONNECT_EXPORT
159 const char*  NcbiDNSIPToAddr(TNCBI_IPv6Addr* addr,
160                              const char* str, size_t len);
161 
162 
163 /** Convert into an IPv6 address, the first "len" (or "strlen(str)" if "len" is
164  *  0) bytes of "str", which can be either of a full-quad decimal IPv4, a
165  *  hexadecimal colon-separated IPv6, an .in-addr.arpa- or an .in6.arpa-domain
166  *  names; return a non-zero string pointer to the first non-converted
167  *  character (which is neither a [hex-]digit, nor a colon, nor a dot); return
168  *  0 if no conversion can be made.
169  * @sa
170  *  NcbiAddrToString, NcbiAddrToDNS
171  */
172 extern NCBI_XCONNECT_EXPORT
173 const char*  NcbiStringToAddr(TNCBI_IPv6Addr* addr,
174                               const char* str, size_t len);
175 
176 
177 /** Convert a network byte order IPv4 into a full-quad text form and store the
178  *  result in the "buf" of size "bufsize".  Return non-zero string address
179  *  past the stored result, or 0 when the conversion failed for buffer being
180  *  too small.
181  * @sa
182  *  NcbiStringToIPv4, SOCK_ntoa, SOCK_HostPortToString
183  */
184 extern NCBI_XCONNECT_EXPORT
185 char*        NcbiIPv4ToString(char* buf, size_t bufsize,
186                               unsigned int addr);
187 
188 
189 /** Convert an IPv6 address into a hex colon-separated text form and store the
190  *  result in the "buf" of size "bufsize".  Return non-zero string address
191  *  past the stored result, or 0 when the conversion failed for buffer being
192  *  too small.
193  * @sa
194  *  NcbiStringToIPv6, NcbiStringToAddr, NcbiAddrToString
195  */
196 extern NCBI_XCONNECT_EXPORT
197 char*        NcbiIPv6ToString(char* buf, size_t bufsize,
198                               const TNCBI_IPv6Addr* addr);
199 
200 
201 /** Convert an IPv6 address into either a full-quad text IPv4 (for IPv4-mapped
202  *  IPv6 addresses) or a hex colon-separated text form (for all other), and
203  *  store the result in the "buf" of size "bufsize".  Return non-zero string
204  *  address past the stored result, or 0 when the conversion failed for buffer
205  *  being too small.
206  * @sa
207  *  NcbiStringToAddr, NcbiAddrToDNS, SOCK_ntoa, SOCK_HostPortToString
208  */
209 extern NCBI_XCONNECT_EXPORT
210 char*        NcbiAddrToString(char* buf, size_t bufsize,
211                               const TNCBI_IPv6Addr* addr);
212 
213 
214 /** Convert an IPv6 address into either .in-addr.arpa domain (for IPv4-mapped
215  *  IPv6 addresses) or .ip6.arpa domain (for all other), and store the result
216  *  in the "buf" of size "bufsize".  Return non-zero string address past the
217  *  stored result, or 0 when the conversion failed for buffer being too small.
218  * @sa
219  *  NcbiAddrToString, NcbiDNSIPToAddr
220  */
221 extern NCBI_XCONNECT_EXPORT
222 const char*  NcbiAddrToDNS(char* buf, size_t bufsize,
223                            const TNCBI_IPv6Addr* addr);
224 
225 
226 /** Return non-zero(true) if "addr" belongs to the network specified as CIDR
227  *  "base/bits"; return zero(false) otherwise.
228  * @note "base" is not checked to contain all zero bits beyond "bits" (as it
229  *  should), but if it does not then the return value will always be false.
230  * @sa
231  *  NcbiIPv6Subnet
232  */
233 extern NCBI_XCONNECT_EXPORT
234 int/*bool*/  NcbiIsInIPv6Network(const TNCBI_IPv6Addr* base,
235                                  unsigned int          bits,
236                                  const TNCBI_IPv6Addr* addr);
237 
238 
239 /** Retain first "bits" in a given "addr", resetting all remaining bits to 0.
240  *  Return non-zero(true) if the resultant "addr" is non-empty; return
241  *  zero(false) otherwise.
242  * @sa
243  *  NcbiIsEmptyIPv6, NcbiIsInIPv6Network
244  */
245 extern NCBI_XCONNECT_EXPORT
246 int/*bool*/  NcbiIPv6Subnet(TNCBI_IPv6Addr* addr,
247                             unsigned int    bits);
248 
249 
250 #ifdef __cplusplus
251 }
252 #endif /*__cplusplus*/
253 
254 
255 #endif  /* CONNECT___NCBI_IPV6__H */
256