source: mainline/uspace/lib/c/generic/inet/addr.c@ e948fde

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since e948fde was e948fde, checked in by Jiri Svoboda <jiri@…>, 12 years ago

dnsr_name2host should use ip_ver_t instead of AF.

  • Property mode set to 100644
File size: 14.4 KB
RevLine 
[3495654]1/*
2 * Copyright (c) 2013 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/** @file Internet address parsing and formatting.
33 */
34
[f023251]35#include <assert.h>
[3495654]36#include <errno.h>
[a2e3ee6]37#include <unistd.h>
38#include <net/socket_codes.h>
[3495654]39#include <inet/addr.h>
[a2e3ee6]40#include <net/inet.h>
[3495654]41#include <stdio.h>
[02a09ed]42#include <malloc.h>
43#include <bitops.h>
[3495654]44
[02a09ed]45#define INET_PREFIXSTRSIZE 5
46
47#if !(defined(__BE__) ^ defined(__LE__))
48 #error The architecture must be either big-endian or little-endian.
49#endif
50
[695b6ff]51const addr32_t addr32_broadcast_all_hosts = 0xffffffff;
52
[02a09ed]53const addr48_t addr48_broadcast = {
54 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
55};
56
[83781a22]57static const addr48_t inet_addr48_solicited_node = {
58 0x33, 0x33, 0xff, 0, 0, 0
59};
60
[02a09ed]61static const inet_addr_t inet_addr_any_addr = {
[f023251]62 .version = ip_v4,
[02a09ed]63 .addr = 0
[a2e3ee6]64};
65
[02a09ed]66static const inet_addr_t inet_addr_any_addr6 = {
[f023251]67 .version = ip_v6,
[02a09ed]68 .addr6 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
[a2e3ee6]69};
70
[02a09ed]71void addr48(const addr48_t src, addr48_t dst)
72{
73 memcpy(dst, src, 6);
74}
75
76void addr128(const addr128_t src, addr128_t dst)
77{
78 memcpy(dst, src, 16);
79}
80
[83781a22]81int addr48_compare(const addr48_t a, const addr48_t b)
82{
83 return memcmp(a, b, 6);
84}
85
[671b546]86int addr128_compare(const addr128_t a, const addr128_t b)
87{
88 return memcmp(a, b, 16);
89}
90
[83781a22]91/** Compute solicited node MAC multicast address from target IPv6 address
92 *
93 * @param ip Target IPv6 address
94 * @param mac Solicited MAC address to be assigned
95 *
96 */
97void addr48_solicited_node(const addr128_t ip, addr48_t mac)
98{
99 memcpy(mac, inet_addr48_solicited_node, 3);
100 memcpy(mac + 3, ip + 13, 3);
101}
102
[02a09ed]103void host2addr128_t_be(const addr128_t host, addr128_t be)
104{
105#ifdef __BE__
106 memcpy(be, host, 16);
107#else
108 be[0] = host[15];
109 be[1] = host[14];
110 be[2] = host[13];
111 be[3] = host[12];
112 be[4] = host[11];
113 be[5] = host[10];
114 be[6] = host[9];
115 be[7] = host[8];
116 be[8] = host[7];
117 be[9] = host[6];
118 be[10] = host[5];
119 be[11] = host[4];
120 be[12] = host[3];
121 be[13] = host[2];
122 be[14] = host[1];
123 be[15] = host[0];
124#endif
125}
126
127void addr128_t_be2host(const addr128_t be, addr128_t host)
128{
129#ifdef __BE__
130 memcpy(host, be, 16);
131#else
132 host[0] = be[15];
133 host[1] = be[14];
134 host[2] = be[13];
135 host[3] = be[12];
136 host[4] = be[11];
137 host[5] = be[10];
138 host[6] = be[9];
139 host[7] = be[8];
140 host[8] = be[7];
141 host[9] = be[6];
142 host[10] = be[5];
143 host[11] = be[4];
144 host[12] = be[3];
145 host[13] = be[2];
146 host[14] = be[1];
147 host[15] = be[0];
148#endif
149}
150
151void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
152{
[f023251]153 addr->version = ip_v4;
[02a09ed]154 addr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
155 ((addr32_t) c << 8) | ((addr32_t) d);
156}
157
158void inet_naddr(inet_naddr_t *naddr, uint8_t a, uint8_t b, uint8_t c, uint8_t d,
159 uint8_t prefix)
160{
[f023251]161 naddr->version = ip_v4;
[02a09ed]162 naddr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
163 ((addr32_t) c << 8) | ((addr32_t) d);
164 naddr->prefix = prefix;
165}
166
167void inet_addr6(inet_addr_t *addr, uint16_t a, uint16_t b, uint16_t c,
168 uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h)
169{
[f023251]170 addr->version = ip_v6;
[02a09ed]171 addr->addr6[0] = (a >> 8) & 0xff;
172 addr->addr6[1] = a & 0xff;
173 addr->addr6[2] = (b >> 8) & 0xff;
174 addr->addr6[3] = b & 0xff;
175 addr->addr6[4] = (c >> 8) & 0xff;
176 addr->addr6[5] = c & 0xff;
177 addr->addr6[6] = (d >> 8) & 0xff;
178 addr->addr6[7] = d & 0xff;
179 addr->addr6[8] = (e >> 8) & 0xff;
180 addr->addr6[9] = e & 0xff;
181 addr->addr6[10] = (f >> 8) & 0xff;
182 addr->addr6[11] = f & 0xff;
183 addr->addr6[12] = (g >> 8) & 0xff;
184 addr->addr6[13] = g & 0xff;
185 addr->addr6[14] = (h >> 8) & 0xff;
186 addr->addr6[15] = h & 0xff;
187}
188
189void inet_naddr6(inet_naddr_t *naddr, uint16_t a, uint16_t b, uint16_t c,
190 uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h, uint8_t prefix)
191{
[f023251]192 naddr->version = ip_v6;
[02a09ed]193 naddr->addr6[0] = (a >> 8) & 0xff;
194 naddr->addr6[1] = a & 0xff;
195 naddr->addr6[2] = (b >> 8) & 0xff;
196 naddr->addr6[3] = b & 0xff;
197 naddr->addr6[4] = (c >> 8) & 0xff;
198 naddr->addr6[5] = c & 0xff;
199 naddr->addr6[6] = (d >> 8) & 0xff;
200 naddr->addr6[7] = d & 0xff;
201 naddr->addr6[8] = (e >> 8) & 0xff;
202 naddr->addr6[9] = e & 0xff;
203 naddr->addr6[10] = (f >> 8) & 0xff;
204 naddr->addr6[11] = f & 0xff;
205 naddr->addr6[12] = (g >> 8) & 0xff;
206 naddr->addr6[13] = g & 0xff;
207 naddr->addr6[14] = (h >> 8) & 0xff;
208 naddr->addr6[15] = h & 0xff;
209 naddr->prefix = prefix;
210}
211
[f023251]212/** Determine address version.
[3495654]213 *
[f023251]214 * @param text Address in common notation.
215 * @param af Place to store address version.
[a2e3ee6]216 *
217 * @return EOK on success, EINVAL if input is not in valid format.
[3495654]218 *
219 */
[f023251]220static int inet_addr_version(const char *text, ip_ver_t *ver)
[3495654]221{
[a2e3ee6]222 char *dot = str_chr(text, '.');
223 if (dot != NULL) {
[f023251]224 *ver = ip_v4;
[a2e3ee6]225 return EOK;
[3495654]226 }
[f023251]227
[a2e3ee6]228 char *collon = str_chr(text, ':');
229 if (collon != NULL) {
[f023251]230 *ver = ip_v6;
[a2e3ee6]231 return EOK;
[3495654]232 }
[f023251]233
[a2e3ee6]234 return EINVAL;
[3495654]235}
236
[f023251]237static int ipver_af(ip_ver_t ver)
238{
239 switch (ver) {
240 case ip_any:
241 return AF_NONE;
242 case ip_v4:
243 return AF_INET;
244 case ip_v6:
245 return AF_INET6;
246 default:
247 assert(false);
248 return EINVAL;
[e948fde]249 }
250}
251
252ip_ver_t ipver_from_af(int af)
253{
254 switch (af) {
255 case AF_NONE:
256 return ip_any;
257 case AF_INET:
258 return ip_v4;
259 case AF_INET6:
260 return ip_v6;
261 default:
262 assert(false);
263 return EINVAL;
[f023251]264 }
265}
266
[02a09ed]267void inet_naddr_addr(const inet_naddr_t *naddr, inet_addr_t *addr)
268{
[f023251]269 addr->version = naddr->version;
[02a09ed]270 memcpy(addr->addr6, naddr->addr6, 16);
271}
272
[bb9b0c6]273void inet_addr_naddr(const inet_addr_t *addr, uint8_t prefix,
274 inet_naddr_t *naddr)
275{
[f023251]276 naddr->version = addr->version;
[bb9b0c6]277 memcpy(naddr->addr6, addr->addr6, 16);
278 naddr->prefix = prefix;
279}
280
[02a09ed]281void inet_addr_any(inet_addr_t *addr)
282{
[f023251]283 addr->version = ip_any;
[02a09ed]284 memset(addr->addr6, 0, 16);
285}
286
287void inet_naddr_any(inet_naddr_t *naddr)
288{
[f023251]289 naddr->version = ip_any;
[02a09ed]290 memset(naddr->addr6, 0, 16);
291 naddr->prefix = 0;
292}
293
294int inet_addr_compare(const inet_addr_t *a, const inet_addr_t *b)
295{
[f023251]296 if (a->version != b->version)
[02a09ed]297 return 0;
[f023251]298
299 switch (a->version) {
300 case ip_v4:
[02a09ed]301 return (a->addr == b->addr);
[f023251]302 case ip_v6:
[671b546]303 return addr128_compare(a->addr6, b->addr6);
[02a09ed]304 default:
305 return 0;
306 }
307}
308
309int inet_addr_is_any(const inet_addr_t *addr)
310{
[f023251]311 return ((addr->version == ip_any) ||
[02a09ed]312 (inet_addr_compare(addr, &inet_addr_any_addr)) ||
313 (inet_addr_compare(addr, &inet_addr_any_addr6)));
314}
315
[30c5d13]316int inet_naddr_compare(const inet_naddr_t *naddr, const inet_addr_t *addr)
317{
[f023251]318 if (naddr->version != addr->version)
[30c5d13]319 return 0;
320
[f023251]321 switch (naddr->version) {
322 case ip_v4:
[30c5d13]323 return (naddr->addr == addr->addr);
[f023251]324 case ip_v6:
[30c5d13]325 return addr128_compare(naddr->addr6, addr->addr6);
326 default:
327 return 0;
328 }
329}
330
[02a09ed]331int inet_naddr_compare_mask(const inet_naddr_t *naddr, const inet_addr_t *addr)
332{
[f023251]333 if (naddr->version != addr->version)
[02a09ed]334 return 0;
[f023251]335
336 switch (naddr->version) {
337 case ip_v4:
[02a09ed]338 if (naddr->prefix > 32)
339 return 0;
[f023251]340
[02a09ed]341 addr32_t mask =
342 BIT_RANGE(addr32_t, 31, 31 - (naddr->prefix - 1));
343 return ((naddr->addr & mask) == (addr->addr & mask));
[f023251]344 case ip_v6:
[02a09ed]345 if (naddr->prefix > 128)
346 return 0;
347
348 size_t pos = 0;
349 for (size_t i = 0; i < 16; i++) {
350 /* Further bits do not matter */
351 if (naddr->prefix < pos)
352 break;
353
354 if (naddr->prefix - pos > 8) {
355 /* Comparison without masking */
356 if (naddr->addr6[i] != addr->addr6[i])
357 return 0;
358 } else {
359 /* Comparison with masking */
360 uint8_t mask =
361 BIT_RANGE(uint8_t, 8, 8 - (naddr->prefix - pos - 1));
362 if ((naddr->addr6[i] & mask) != (addr->addr6[i] & mask))
363 return 0;
364 }
365
366 pos += 8;
367 }
368
369 return 1;
370 default:
371 return 0;
372 }
373}
374
[3495654]375/** Parse node address.
376 *
[a2e3ee6]377 * @param text Network address in common notation.
378 * @param addr Place to store node address.
379 *
380 * @return EOK on success, EINVAL if input is not in valid format.
[3495654]381 *
382 */
383int inet_addr_parse(const char *text, inet_addr_t *addr)
384{
[f023251]385 int rc = inet_addr_version(text, &addr->version);
[a2e3ee6]386 if (rc != EOK)
387 return rc;
388
[02a09ed]389 uint8_t buf[16];
[f023251]390 rc = inet_pton(ipver_af(addr->version), text, buf);
[a2e3ee6]391 if (rc != EOK)
392 return rc;
393
[f023251]394 switch (addr->version) {
395 case ip_v4:
[02a09ed]396 addr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
397 buf[3];
398 break;
[f023251]399 case ip_v6:
[02a09ed]400 memcpy(addr->addr6, buf, 16);
401 break;
402 default:
403 return EINVAL;
404 }
405
[a2e3ee6]406 return EOK;
407}
[3495654]408
[a2e3ee6]409/** Parse network address.
410 *
411 * @param text Network address in common notation.
412 * @param naddr Place to store network address.
413 *
414 * @return EOK on success, EINVAL if input is not in valid format.
415 *
416 */
417int inet_naddr_parse(const char *text, inet_naddr_t *naddr)
418{
419 char *slash = str_chr(text, '/');
420 if (slash == NULL)
[3495654]421 return EINVAL;
[a2e3ee6]422
423 *slash = 0;
424
[f023251]425 int rc = inet_addr_version(text, &naddr->version);
[a2e3ee6]426 if (rc != EOK)
427 return rc;
428
[02a09ed]429 uint8_t buf[16];
[f023251]430 rc = inet_pton(ipver_af(naddr->version), text, buf);
[a2e3ee6]431 *slash = '/';
432
433 if (rc != EOK)
434 return rc;
435
436 slash++;
[02a09ed]437 uint8_t prefix;
[a2e3ee6]438
[f023251]439 switch (naddr->version) {
440 case ip_v4:
[02a09ed]441 prefix = strtoul(slash, &slash, 10);
442 if (prefix > 32)
[a2e3ee6]443 return EINVAL;
[02a09ed]444
445 naddr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
446 buf[3];
447 naddr->prefix = prefix;
448
[a2e3ee6]449 break;
[f023251]450 case ip_v6:
[02a09ed]451 prefix = strtoul(slash, &slash, 10);
452 if (prefix > 128)
[3495654]453 return EINVAL;
[02a09ed]454
455 memcpy(naddr->addr6, buf, 16);
456 naddr->prefix = prefix;
457
[a2e3ee6]458 break;
459 default:
460 return ENOTSUP;
[3495654]461 }
[a2e3ee6]462
463 return EOK;
464}
[3495654]465
[a2e3ee6]466/** Format node address.
467 *
468 * @param addr Node address.
469 * @param bufp Place to store pointer to formatted string.
470 *
471 * @return EOK on success.
472 * @return ENOMEM if out of memory.
473 * @return ENOTSUP on unsupported address family.
474 *
475 */
[02a09ed]476int inet_addr_format(const inet_addr_t *addr, char **bufp)
[a2e3ee6]477{
[02a09ed]478 int rc = 0;
[a2e3ee6]479
[f023251]480 switch (addr->version) {
481 case ip_any:
[a2e3ee6]482 rc = asprintf(bufp, "none");
483 break;
[f023251]484 case ip_v4:
[02a09ed]485 rc = asprintf(bufp, "%u.%u.%u.%u", (addr->addr >> 24) & 0xff,
486 (addr->addr >> 16) & 0xff, (addr->addr >> 8) & 0xff,
487 addr->addr & 0xff);
[a2e3ee6]488 break;
[f023251]489 case ip_v6:
[02a09ed]490 *bufp = (char *) malloc(INET6_ADDRSTRLEN);
491 if (*bufp == NULL)
492 return ENOMEM;
493
494 return inet_ntop(AF_INET6, addr->addr6, *bufp, INET6_ADDRSTRLEN);
[a2e3ee6]495 default:
496 return ENOTSUP;
497 }
498
499 if (rc < 0)
500 return ENOMEM;
501
[3495654]502 return EOK;
503}
504
505/** Format network address.
506 *
[a2e3ee6]507 * @param naddr Network address.
508 * @param bufp Place to store pointer to formatted string.
509 *
510 * @return EOK on success.
511 * @return ENOMEM if out of memory.
512 * @return ENOTSUP on unsupported address family.
[3495654]513 *
514 */
[02a09ed]515int inet_naddr_format(const inet_naddr_t *naddr, char **bufp)
[3495654]516{
[02a09ed]517 int rc = 0;
518 char prefix[INET_PREFIXSTRSIZE];
[a2e3ee6]519
[f023251]520 switch (naddr->version) {
521 case ip_any:
[a2e3ee6]522 rc = asprintf(bufp, "none");
523 break;
[f023251]524 case ip_v4:
[02a09ed]525 rc = asprintf(bufp, "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8
526 "/%" PRIu8, (naddr->addr >> 24) & 0xff,
527 (naddr->addr >> 16) & 0xff, (naddr->addr >> 8) & 0xff,
528 naddr->addr & 0xff, naddr->prefix);
[a2e3ee6]529 break;
[f023251]530 case ip_v6:
[02a09ed]531 *bufp = (char *) malloc(INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
532 if (*bufp == NULL)
533 return ENOMEM;
534
535 rc = inet_ntop(AF_INET6, naddr->addr6, *bufp,
536 INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
537 if (rc != EOK) {
538 free(*bufp);
539 return rc;
540 }
541
542 rc = snprintf(prefix, INET_PREFIXSTRSIZE, "/%" PRIu8,
543 naddr->prefix);
544 if (rc < 0) {
545 free(*bufp);
546 return ENOMEM;
547 }
548
549 str_append(*bufp, INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE, prefix);
550
551 break;
[a2e3ee6]552 default:
553 return ENOTSUP;
554 }
555
[3495654]556 if (rc < 0)
557 return ENOMEM;
[a2e3ee6]558
559 return EOK;
560}
[3495654]561
[f023251]562ip_ver_t inet_addr_get(const inet_addr_t *addr, addr32_t *v4, addr128_t *v6)
[a2e3ee6]563{
[f023251]564 switch (addr->version) {
565 case ip_v4:
[02a09ed]566 if (v4 != NULL)
567 *v4 = addr->addr;
568 break;
[f023251]569 case ip_v6:
[02a09ed]570 if (v6 != NULL)
571 memcpy(*v6, addr->addr6, 16);
[f023251]572 break;
573 default:
574 assert(false);
[02a09ed]575 break;
576 }
[f023251]577
578 return addr->version;
[3495654]579}
580
[f023251]581ip_ver_t inet_naddr_get(const inet_naddr_t *naddr, addr32_t *v4, addr128_t *v6,
[02a09ed]582 uint8_t *prefix)
[3495654]583{
[f023251]584 switch (naddr->version) {
585 case ip_v4:
[02a09ed]586 if (v4 != NULL)
587 *v4 = naddr->addr;
588 if (prefix != NULL)
589 *prefix = naddr->prefix;
590 break;
[f023251]591 case ip_v6:
[02a09ed]592 if (v6 != NULL)
593 memcpy(*v6, naddr->addr6, 16);
594 if (prefix != NULL)
595 *prefix = naddr->prefix;
[f023251]596 break;
597 default:
598 assert(false);
[02a09ed]599 break;
600 }
[f023251]601
602 return naddr->version;
[a2e3ee6]603}
[3495654]604
[02a09ed]605void inet_addr_set(addr32_t v4, inet_addr_t *addr)
[a2e3ee6]606{
[f023251]607 addr->version = ip_v4;
[02a09ed]608 addr->addr = v4;
[a2e3ee6]609}
[3495654]610
[02a09ed]611void inet_naddr_set(addr32_t v4, uint8_t prefix, inet_naddr_t *naddr)
[a2e3ee6]612{
[f023251]613 naddr->version = ip_v4;
[02a09ed]614 naddr->addr = v4;
[a2e3ee6]615 naddr->prefix = prefix;
616}
[3495654]617
[02a09ed]618void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr)
[a2e3ee6]619{
[f023251]620 addr->version = ip_v4;
[02a09ed]621 addr->addr = uint32_t_be2host(sockaddr_in->sin_addr.s_addr);
[a2e3ee6]622}
623
[02a09ed]624void inet_addr_set6(addr128_t v6, inet_addr_t *addr)
[a2e3ee6]625{
[f023251]626 addr->version = ip_v6;
[02a09ed]627 memcpy(addr->addr6, v6, 16);
[a2e3ee6]628}
629
[02a09ed]630void inet_naddr_set6(addr128_t v6, uint8_t prefix, inet_naddr_t *naddr)
[a2e3ee6]631{
[f023251]632 naddr->version = ip_v6;
[02a09ed]633 memcpy(naddr->addr6, v6, 16);
634 naddr->prefix = prefix;
[a2e3ee6]635}
636
[02a09ed]637void inet_sockaddr_in6_addr(const sockaddr_in6_t *sockaddr_in6,
638 inet_addr_t *addr)
[a2e3ee6]639{
[f023251]640 addr->version = ip_v6;
[02a09ed]641 addr128_t_be2host(sockaddr_in6->sin6_addr.s6_addr, addr->addr6);
[a2e3ee6]642}
643
[02a09ed]644uint16_t inet_addr_sockaddr_in(const inet_addr_t *addr,
645 sockaddr_in_t *sockaddr_in, sockaddr_in6_t *sockaddr_in6)
[a2e3ee6]646{
[f023251]647 switch (addr->version) {
648 case ip_v4:
[02a09ed]649 if (sockaddr_in != NULL) {
650 sockaddr_in->sin_family = AF_INET;
651 sockaddr_in->sin_addr.s_addr = host2uint32_t_be(addr->addr);
652 }
653 break;
[f023251]654 case ip_v6:
[02a09ed]655 if (sockaddr_in6 != NULL) {
656 sockaddr_in6->sin6_family = AF_INET6;
657 host2addr128_t_be(addr->addr6, sockaddr_in6->sin6_addr.s6_addr);
658 }
[f023251]659 break;
660 default:
661 assert(false);
[02a09ed]662 break;
[a2e3ee6]663 }
[f023251]664
665 return ipver_af(addr->version);
[a2e3ee6]666}
667
[3495654]668/** @}
669 */
Note: See TracBrowser for help on using the repository browser.