Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/inet/addr.c

    r3495654 r26de91a  
    3333 */
    3434
     35#include <assert.h>
    3536#include <errno.h>
     37#include <unistd.h>
     38#include <net/socket_codes.h>
    3639#include <inet/addr.h>
     40#include <net/inet.h>
    3741#include <stdio.h>
     42#include <malloc.h>
     43#include <bitops.h>
     44
     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
     51const addr32_t addr32_broadcast_all_hosts = 0xffffffff;
     52
     53const addr48_t addr48_broadcast = {
     54        0xff, 0xff, 0xff, 0xff, 0xff, 0xff
     55};
     56
     57static const addr48_t inet_addr48_solicited_node = {
     58        0x33, 0x33, 0xff, 0, 0, 0
     59};
     60
     61static const inet_addr_t inet_addr_any_addr = {
     62        .version = ip_v4,
     63        .addr = 0
     64};
     65
     66static const inet_addr_t inet_addr_any_addr6 = {
     67        .version = ip_v6,
     68        .addr6 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
     69};
     70
     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
     81/** Compare addr48.
     82  *
     83  * @return Non-zero if equal, zero if not equal.
     84  */
     85int addr48_compare(const addr48_t a, const addr48_t b)
     86{
     87        return memcmp(a, b, 6) == 0;
     88}
     89
     90/** Compare addr128.
     91  *
     92  * @return Non-zero if equal, zero if not equal.
     93  */
     94int addr128_compare(const addr128_t a, const addr128_t b)
     95{
     96        return memcmp(a, b, 16) == 0;
     97}
     98
     99/** Compute solicited node MAC multicast address from target IPv6 address
     100 *
     101 * @param ip  Target IPv6 address
     102 * @param mac Solicited MAC address to be assigned
     103 *
     104 */
     105void addr48_solicited_node(const addr128_t ip, addr48_t mac)
     106{
     107        memcpy(mac, inet_addr48_solicited_node, 3);
     108        memcpy(mac + 3, ip + 13, 3);
     109}
     110
     111void host2addr128_t_be(const addr128_t host, addr128_t be)
     112{
     113        memcpy(be, host, 16);
     114}
     115
     116void addr128_t_be2host(const addr128_t be, addr128_t host)
     117{
     118        memcpy(host, be, 16);
     119}
     120
     121void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
     122{
     123        addr->version = ip_v4;
     124        addr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
     125            ((addr32_t) c << 8) | ((addr32_t) d);
     126}
     127
     128void inet_naddr(inet_naddr_t *naddr, uint8_t a, uint8_t b, uint8_t c, uint8_t d,
     129    uint8_t prefix)
     130{
     131        naddr->version = ip_v4;
     132        naddr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
     133            ((addr32_t) c << 8) | ((addr32_t) d);
     134        naddr->prefix = prefix;
     135}
     136
     137void inet_addr6(inet_addr_t *addr, uint16_t a, uint16_t b, uint16_t c,
     138    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h)
     139{
     140        addr->version = ip_v6;
     141        addr->addr6[0] = (a >> 8) & 0xff;
     142        addr->addr6[1] = a & 0xff;
     143        addr->addr6[2] = (b >> 8) & 0xff;
     144        addr->addr6[3] = b & 0xff;
     145        addr->addr6[4] = (c >> 8) & 0xff;
     146        addr->addr6[5] = c & 0xff;
     147        addr->addr6[6] = (d >> 8) & 0xff;
     148        addr->addr6[7] = d & 0xff;
     149        addr->addr6[8] = (e >> 8) & 0xff;
     150        addr->addr6[9] = e & 0xff;
     151        addr->addr6[10] = (f >> 8) & 0xff;
     152        addr->addr6[11] = f & 0xff;
     153        addr->addr6[12] = (g >> 8) & 0xff;
     154        addr->addr6[13] = g & 0xff;
     155        addr->addr6[14] = (h >> 8) & 0xff;
     156        addr->addr6[15] = h & 0xff;
     157}
     158
     159void inet_naddr6(inet_naddr_t *naddr, uint16_t a, uint16_t b, uint16_t c,
     160    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h, uint8_t prefix)
     161{
     162        naddr->version = ip_v6;
     163        naddr->addr6[0] = (a >> 8) & 0xff;
     164        naddr->addr6[1] = a & 0xff;
     165        naddr->addr6[2] = (b >> 8) & 0xff;
     166        naddr->addr6[3] = b & 0xff;
     167        naddr->addr6[4] = (c >> 8) & 0xff;
     168        naddr->addr6[5] = c & 0xff;
     169        naddr->addr6[6] = (d >> 8) & 0xff;
     170        naddr->addr6[7] = d & 0xff;
     171        naddr->addr6[8] = (e >> 8) & 0xff;
     172        naddr->addr6[9] = e & 0xff;
     173        naddr->addr6[10] = (f >> 8) & 0xff;
     174        naddr->addr6[11] = f & 0xff;
     175        naddr->addr6[12] = (g >> 8) & 0xff;
     176        naddr->addr6[13] = g & 0xff;
     177        naddr->addr6[14] = (h >> 8) & 0xff;
     178        naddr->addr6[15] = h & 0xff;
     179        naddr->prefix = prefix;
     180}
     181
     182/** Determine address version.
     183 *
     184 * @param text Address in common notation.
     185 * @param af   Place to store address version.
     186 *
     187 * @return EOK on success, EINVAL if input is not in valid format.
     188 *
     189 */
     190static int inet_addr_version(const char *text, ip_ver_t *ver)
     191{
     192        char *dot = str_chr(text, '.');
     193        if (dot != NULL) {
     194                *ver = ip_v4;
     195                return EOK;
     196        }
     197
     198        char *collon = str_chr(text, ':');
     199        if (collon != NULL) {
     200                *ver = ip_v6;
     201                return EOK;
     202        }
     203
     204        return EINVAL;
     205}
     206
     207static int ipver_af(ip_ver_t ver)
     208{
     209        switch (ver) {
     210        case ip_any:
     211                return AF_NONE;
     212        case ip_v4:
     213                return AF_INET;
     214        case ip_v6:
     215                return AF_INET6;
     216        default:
     217                assert(false);
     218                return EINVAL;
     219        }
     220}
     221
     222ip_ver_t ipver_from_af(int af)
     223{
     224        switch (af) {
     225        case AF_NONE:
     226                return ip_any;
     227        case AF_INET:
     228                return ip_v4;
     229        case AF_INET6:
     230                return ip_v6;
     231        default:
     232                assert(false);
     233                return EINVAL;
     234        }
     235}
     236
     237void inet_naddr_addr(const inet_naddr_t *naddr, inet_addr_t *addr)
     238{
     239        addr->version = naddr->version;
     240        memcpy(addr->addr6, naddr->addr6, 16);
     241}
     242
     243void inet_addr_naddr(const inet_addr_t *addr, uint8_t prefix,
     244    inet_naddr_t *naddr)
     245{
     246        naddr->version = addr->version;
     247        memcpy(naddr->addr6, addr->addr6, 16);
     248        naddr->prefix = prefix;
     249}
     250
     251void inet_addr_any(inet_addr_t *addr)
     252{
     253        addr->version = ip_any;
     254        memset(addr->addr6, 0, 16);
     255}
     256
     257void inet_naddr_any(inet_naddr_t *naddr)
     258{
     259        naddr->version = ip_any;
     260        memset(naddr->addr6, 0, 16);
     261        naddr->prefix = 0;
     262}
     263
     264int inet_addr_compare(const inet_addr_t *a, const inet_addr_t *b)
     265{
     266        if (a->version != b->version)
     267                return 0;
     268
     269        switch (a->version) {
     270        case ip_v4:
     271                return (a->addr == b->addr);
     272        case ip_v6:
     273                return addr128_compare(a->addr6, b->addr6);
     274        default:
     275                return 0;
     276        }
     277}
     278
     279int inet_addr_is_any(const inet_addr_t *addr)
     280{
     281        return ((addr->version == ip_any) ||
     282            (inet_addr_compare(addr, &inet_addr_any_addr)) ||
     283            (inet_addr_compare(addr, &inet_addr_any_addr6)));
     284}
     285
     286int inet_naddr_compare(const inet_naddr_t *naddr, const inet_addr_t *addr)
     287{
     288        if (naddr->version != addr->version)
     289                return 0;
     290       
     291        switch (naddr->version) {
     292        case ip_v4:
     293                return (naddr->addr == addr->addr);
     294        case ip_v6:
     295                return addr128_compare(naddr->addr6, addr->addr6);
     296        default:
     297                return 0;
     298        }
     299}
     300
     301int inet_naddr_compare_mask(const inet_naddr_t *naddr, const inet_addr_t *addr)
     302{
     303        if (naddr->version != addr->version)
     304                return 0;
     305
     306        switch (naddr->version) {
     307        case ip_v4:
     308                if (naddr->prefix > 32)
     309                        return 0;
     310
     311                addr32_t mask =
     312                    BIT_RANGE(addr32_t, 31, 31 - (naddr->prefix - 1));
     313                return ((naddr->addr & mask) == (addr->addr & mask));
     314        case ip_v6:
     315                if (naddr->prefix > 128)
     316                        return 0;
     317               
     318                size_t pos = 0;
     319                for (size_t i = 0; i < 16; i++) {
     320                        /* Further bits do not matter */
     321                        if (naddr->prefix < pos)
     322                                break;
     323                       
     324                        if (naddr->prefix - pos > 8) {
     325                                /* Comparison without masking */
     326                                if (naddr->addr6[i] != addr->addr6[i])
     327                                        return 0;
     328                        } else {
     329                                /* Comparison with masking */
     330                                uint8_t mask =
     331                                    BIT_RANGE(uint8_t, 8, 8 - (naddr->prefix - pos - 1));
     332                                if ((naddr->addr6[i] & mask) != (addr->addr6[i] & mask))
     333                                        return 0;
     334                        }
     335                       
     336                        pos += 8;
     337                }
     338               
     339                return 1;
     340        default:
     341                return 0;
     342        }
     343}
     344
     345/** Parse node address.
     346 *
     347 * @param text Network address in common notation.
     348 * @param addr Place to store node address.
     349 *
     350 * @return EOK on success, EINVAL if input is not in valid format.
     351 *
     352 */
     353int inet_addr_parse(const char *text, inet_addr_t *addr)
     354{
     355        int rc = inet_addr_version(text, &addr->version);
     356        if (rc != EOK)
     357                return rc;
     358       
     359        uint8_t buf[16];
     360        rc = inet_pton(ipver_af(addr->version), text, buf);
     361        if (rc != EOK)
     362                return rc;
     363       
     364        switch (addr->version) {
     365        case ip_v4:
     366                addr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
     367                    buf[3];
     368                break;
     369        case ip_v6:
     370                memcpy(addr->addr6, buf, 16);
     371                break;
     372        default:
     373                return EINVAL;
     374        }
     375       
     376        return EOK;
     377}
    38378
    39379/** Parse network address.
    40380 *
    41  * @param text  Network address in CIDR notation (a.b.c.d/w)
    42  * @param naddr Place to store network address
    43  *
    44  * @return      EOK on success, EINVAL if input is not in valid format
     381 * @param text  Network address in common notation.
     382 * @param naddr Place to store network address.
     383 *
     384 * @return EOK on success, EINVAL if input is not in valid format.
     385 *
    45386 */
    46387int inet_naddr_parse(const char *text, inet_naddr_t *naddr)
    47388{
    48         unsigned long a[4], bits;
    49         char *cp = (char *)text;
    50         int i;
    51 
    52         for (i = 0; i < 3; i++) {
    53                 a[i] = strtoul(cp, &cp, 10);
    54                 if (*cp != '.')
     389        char *slash = str_chr(text, '/');
     390        if (slash == NULL)
     391                return EINVAL;
     392       
     393        *slash = 0;
     394       
     395        int rc = inet_addr_version(text, &naddr->version);
     396        if (rc != EOK)
     397                return rc;
     398       
     399        uint8_t buf[16];
     400        rc = inet_pton(ipver_af(naddr->version), text, buf);
     401        *slash = '/';
     402       
     403        if (rc != EOK)
     404                return rc;
     405       
     406        slash++;
     407        uint8_t prefix;
     408       
     409        switch (naddr->version) {
     410        case ip_v4:
     411                prefix = strtoul(slash, &slash, 10);
     412                if (prefix > 32)
    55413                        return EINVAL;
    56                 ++cp;
    57         }
    58 
    59         a[3] = strtoul(cp, &cp, 10);
    60         if (*cp != '/')
    61                 return EINVAL;
    62         ++cp;
    63 
    64         bits = strtoul(cp, &cp, 10);
    65         if (*cp != '\0')
    66                 return EINVAL;
    67 
    68         naddr->ipv4 = 0;
    69         for (i = 0; i < 4; i++) {
    70                 if (a[i] > 255)
     414               
     415                naddr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
     416                    buf[3];
     417                naddr->prefix = prefix;
     418               
     419                break;
     420        case ip_v6:
     421                prefix = strtoul(slash, &slash, 10);
     422                if (prefix > 128)
    71423                        return EINVAL;
    72                 naddr->ipv4 = (naddr->ipv4 << 8) | a[i];
    73         }
    74 
    75         if (bits > 31)
    76                 return EINVAL;
    77 
    78         naddr->bits = bits;
     424               
     425                memcpy(naddr->addr6, buf, 16);
     426                naddr->prefix = prefix;
     427               
     428                break;
     429        default:
     430                return ENOTSUP;
     431        }
     432       
    79433        return EOK;
    80434}
    81435
    82 /** Parse node address.
    83  *
    84  * @param text  Network address in dot notation (a.b.c.d)
    85  * @param addr  Place to store node address
    86  *
    87  * @return      EOK on success, EINVAL if input is not in valid format
    88  */
    89 int inet_addr_parse(const char *text, inet_addr_t *addr)
    90 {
    91         unsigned long a[4];
    92         char *cp = (char *)text;
    93         int i;
    94 
    95         for (i = 0; i < 3; i++) {
    96                 a[i] = strtoul(cp, &cp, 10);
    97                 if (*cp != '.')
    98                         return EINVAL;
    99                 ++cp;
    100         }
    101 
    102         a[3] = strtoul(cp, &cp, 10);
    103         if (*cp != '\0')
    104                 return EINVAL;
    105 
    106         addr->ipv4 = 0;
    107         for (i = 0; i < 4; i++) {
    108                 if (a[i] > 255)
    109                         return EINVAL;
    110                 addr->ipv4 = (addr->ipv4 << 8) | a[i];
    111         }
    112 
    113         return EOK;
    114 }
    115 
    116 /** Format network address.
    117  *
    118  * @param naddr Network address
    119  * @param bufp  Place to store pointer to formatted string (CIDR notation)
    120  *
    121  * @return      EOK on success, ENOMEM if out of memory.
    122  */
    123 int inet_naddr_format(inet_naddr_t *naddr, char **bufp)
    124 {
    125         int rc;
    126 
    127         rc = asprintf(bufp, "%d.%d.%d.%d/%d", naddr->ipv4 >> 24,
    128             (naddr->ipv4 >> 16) & 0xff, (naddr->ipv4 >> 8) & 0xff,
    129             naddr->ipv4 & 0xff, naddr->bits);
    130 
     436/** Format node address.
     437 *
     438 * @param addr Node address.
     439 * @param bufp Place to store pointer to formatted string.
     440 *
     441 * @return EOK on success.
     442 * @return ENOMEM if out of memory.
     443 * @return ENOTSUP on unsupported address family.
     444 *
     445 */
     446int inet_addr_format(const inet_addr_t *addr, char **bufp)
     447{
     448        int rc = 0;
     449       
     450        switch (addr->version) {
     451        case ip_any:
     452                rc = asprintf(bufp, "none");
     453                break;
     454        case ip_v4:
     455                rc = asprintf(bufp, "%u.%u.%u.%u", (addr->addr >> 24) & 0xff,
     456                    (addr->addr >> 16) & 0xff, (addr->addr >> 8) & 0xff,
     457                    addr->addr & 0xff);
     458                break;
     459        case ip_v6:
     460                *bufp = (char *) malloc(INET6_ADDRSTRLEN);
     461                if (*bufp == NULL)
     462                        return ENOMEM;
     463               
     464                return inet_ntop(AF_INET6, addr->addr6, *bufp, INET6_ADDRSTRLEN);
     465        default:
     466                return ENOTSUP;
     467        }
     468       
    131469        if (rc < 0)
    132470                return ENOMEM;
    133 
     471       
    134472        return EOK;
    135473}
    136474
    137 /** Format node address.
    138  *
    139  * @param addr  Node address
    140  * @param bufp  Place to store pointer to formatted string (dot notation)
    141  *
    142  * @return      EOK on success, ENOMEM if out of memory.
    143  */
    144 int inet_addr_format(inet_addr_t *addr, char **bufp)
    145 {
    146         int rc;
    147 
    148         rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
    149             (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
    150             addr->ipv4 & 0xff);
    151 
     475/** Format network address.
     476 *
     477 * @param naddr Network address.
     478 * @param bufp  Place to store pointer to formatted string.
     479 *
     480 * @return EOK on success.
     481 * @return ENOMEM if out of memory.
     482 * @return ENOTSUP on unsupported address family.
     483 *
     484 */
     485int inet_naddr_format(const inet_naddr_t *naddr, char **bufp)
     486{
     487        int rc = 0;
     488        char prefix[INET_PREFIXSTRSIZE];
     489       
     490        switch (naddr->version) {
     491        case ip_any:
     492                rc = asprintf(bufp, "none");
     493                break;
     494        case ip_v4:
     495                rc = asprintf(bufp, "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8
     496                    "/%" PRIu8, (naddr->addr >> 24) & 0xff,
     497                    (naddr->addr >> 16) & 0xff, (naddr->addr >> 8) & 0xff,
     498                    naddr->addr & 0xff, naddr->prefix);
     499                break;
     500        case ip_v6:
     501                *bufp = (char *) malloc(INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
     502                if (*bufp == NULL)
     503                        return ENOMEM;
     504               
     505                rc = inet_ntop(AF_INET6, naddr->addr6, *bufp,
     506                    INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
     507                if (rc != EOK) {
     508                        free(*bufp);
     509                        return rc;
     510                }
     511               
     512                rc = snprintf(prefix, INET_PREFIXSTRSIZE, "/%" PRIu8,
     513                    naddr->prefix);
     514                if (rc < 0) {
     515                        free(*bufp);
     516                        return ENOMEM;
     517                }
     518               
     519                str_append(*bufp, INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE, prefix);
     520               
     521                break;
     522        default:
     523                return ENOTSUP;
     524        }
     525       
    152526        if (rc < 0)
    153527                return ENOMEM;
    154 
     528       
    155529        return EOK;
    156530}
    157531
     532ip_ver_t inet_addr_get(const inet_addr_t *addr, addr32_t *v4, addr128_t *v6)
     533{
     534        switch (addr->version) {
     535        case ip_v4:
     536                if (v4 != NULL)
     537                        *v4 = addr->addr;
     538                break;
     539        case ip_v6:
     540                if (v6 != NULL)
     541                        memcpy(*v6, addr->addr6, 16);
     542                break;
     543        default:
     544                assert(false);
     545                break;
     546        }
     547
     548        return addr->version;
     549}
     550
     551ip_ver_t inet_naddr_get(const inet_naddr_t *naddr, addr32_t *v4, addr128_t *v6,
     552    uint8_t *prefix)
     553{
     554        switch (naddr->version) {
     555        case ip_v4:
     556                if (v4 != NULL)
     557                        *v4 = naddr->addr;
     558                if (prefix != NULL)
     559                        *prefix = naddr->prefix;
     560                break;
     561        case ip_v6:
     562                if (v6 != NULL)
     563                        memcpy(*v6, naddr->addr6, 16);
     564                if (prefix != NULL)
     565                        *prefix = naddr->prefix;
     566                break;
     567        default:
     568                assert(false);
     569                break;
     570        }
     571
     572        return naddr->version;
     573}
     574
     575void inet_addr_set(addr32_t v4, inet_addr_t *addr)
     576{
     577        addr->version = ip_v4;
     578        addr->addr = v4;
     579}
     580
     581void inet_naddr_set(addr32_t v4, uint8_t prefix, inet_naddr_t *naddr)
     582{
     583        naddr->version = ip_v4;
     584        naddr->addr = v4;
     585        naddr->prefix = prefix;
     586}
     587
     588void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr)
     589{
     590        addr->version = ip_v4;
     591        addr->addr = uint32_t_be2host(sockaddr_in->sin_addr.s_addr);
     592}
     593
     594void inet_addr_set6(addr128_t v6, inet_addr_t *addr)
     595{
     596        addr->version = ip_v6;
     597        memcpy(addr->addr6, v6, 16);
     598}
     599
     600void inet_naddr_set6(addr128_t v6, uint8_t prefix, inet_naddr_t *naddr)
     601{
     602        naddr->version = ip_v6;
     603        memcpy(naddr->addr6, v6, 16);
     604        naddr->prefix = prefix;
     605}
     606
     607void inet_sockaddr_in6_addr(const sockaddr_in6_t *sockaddr_in6,
     608    inet_addr_t *addr)
     609{
     610        addr->version = ip_v6;
     611        addr128_t_be2host(sockaddr_in6->sin6_addr.s6_addr, addr->addr6);
     612}
     613
     614uint16_t inet_addr_sockaddr_in(const inet_addr_t *addr,
     615    sockaddr_in_t *sockaddr_in, sockaddr_in6_t *sockaddr_in6)
     616{
     617        switch (addr->version) {
     618        case ip_v4:
     619                if (sockaddr_in != NULL) {
     620                        sockaddr_in->sin_family = AF_INET;
     621                        sockaddr_in->sin_addr.s_addr = host2uint32_t_be(addr->addr);
     622                }
     623                break;
     624        case ip_v6:
     625                if (sockaddr_in6 != NULL) {
     626                        sockaddr_in6->sin6_family = AF_INET6;
     627                        host2addr128_t_be(addr->addr6, sockaddr_in6->sin6_addr.s6_addr);
     628                }
     629                break;
     630        default:
     631                assert(false);
     632                break;
     633        }
     634
     635        return ipver_af(addr->version);
     636}
     637
     638int inet_addr_sockaddr(const inet_addr_t *addr, uint16_t port,
     639    sockaddr_t **nsockaddr, socklen_t *naddrlen)
     640{
     641        sockaddr_in_t *sa4;
     642        sockaddr_in6_t *sa6;
     643
     644        switch (addr->version) {
     645        case ip_v4:
     646                sa4 = calloc(1, sizeof(sockaddr_in_t));
     647                if (sa4 == NULL)
     648                        return ENOMEM;
     649
     650                sa4->sin_family = AF_INET;
     651                sa4->sin_port = host2uint16_t_be(port);
     652                sa4->sin_addr.s_addr = host2uint32_t_be(addr->addr);
     653                if (nsockaddr != NULL)
     654                        *nsockaddr = (sockaddr_t *)sa4;
     655                if (naddrlen != NULL)
     656                        *naddrlen = sizeof(*sa4);
     657                break;
     658        case ip_v6:
     659                sa6 = calloc(1, sizeof(sockaddr_in6_t));
     660                if (sa6 == NULL)
     661                        return ENOMEM;
     662
     663                sa6->sin6_family = AF_INET6;
     664                sa6->sin6_port = host2uint16_t_be(port);
     665                host2addr128_t_be(addr->addr6, sa6->sin6_addr.s6_addr);
     666                if (nsockaddr != NULL)
     667                        *nsockaddr = (sockaddr_t *)sa6;
     668                if (naddrlen != NULL)
     669                        *naddrlen = sizeof(*sa6);
     670                break;
     671        default:
     672                assert(false);
     673                break;
     674        }
     675
     676        return EOK;
     677}
     678
    158679/** @}
    159680 */
Note: See TracChangeset for help on using the changeset viewer.