Ignore:
File:
1 edited

Legend:

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

    r26de91a r3495654  
    3333 */
    3434
    35 #include <assert.h>
    3635#include <errno.h>
    37 #include <unistd.h>
    38 #include <net/socket_codes.h>
    3936#include <inet/addr.h>
    40 #include <net/inet.h>
    4137#include <stdio.h>
    42 #include <malloc.h>
    43 #include <bitops.h>
    4438
    45 #define INET_PREFIXSTRSIZE  5
     39/** Parse network address.
     40 *
     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
     45 */
     46int inet_naddr_parse(const char *text, inet_naddr_t *naddr)
     47{
     48        unsigned long a[4], bits;
     49        char *cp = (char *)text;
     50        int i;
    4651
    47 #if !(defined(__BE__) ^ defined(__LE__))
    48         #error The architecture must be either big-endian or little-endian.
    49 #endif
    50 
    51 const addr32_t addr32_broadcast_all_hosts = 0xffffffff;
    52 
    53 const addr48_t addr48_broadcast = {
    54         0xff, 0xff, 0xff, 0xff, 0xff, 0xff
    55 };
    56 
    57 static const addr48_t inet_addr48_solicited_node = {
    58         0x33, 0x33, 0xff, 0, 0, 0
    59 };
    60 
    61 static const inet_addr_t inet_addr_any_addr = {
    62         .version = ip_v4,
    63         .addr = 0
    64 };
    65 
    66 static 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 
    71 void addr48(const addr48_t src, addr48_t dst)
    72 {
    73         memcpy(dst, src, 6);
    74 }
    75 
    76 void 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   */
    85 int 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   */
    94 int 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  */
    105 void 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 
    111 void host2addr128_t_be(const addr128_t host, addr128_t be)
    112 {
    113         memcpy(be, host, 16);
    114 }
    115 
    116 void addr128_t_be2host(const addr128_t be, addr128_t host)
    117 {
    118         memcpy(host, be, 16);
    119 }
    120 
    121 void 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 
    128 void 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 
    137 void 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 
    159 void 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  */
    190 static 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;
     52        for (i = 0; i < 3; i++) {
     53                a[i] = strtoul(cp, &cp, 10);
     54                if (*cp != '.')
     55                        return EINVAL;
     56                ++cp;
    19657        }
    19758
    198         char *collon = str_chr(text, ':');
    199         if (collon != NULL) {
    200                 *ver = ip_v6;
    201                 return EOK;
     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)
     71                        return EINVAL;
     72                naddr->ipv4 = (naddr->ipv4 << 8) | a[i];
    20273        }
    20374
    204         return EINVAL;
    205 }
     75        if (bits > 31)
     76                return EINVAL;
    20677
    207 static 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 
    222 ip_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 
    237 void 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 
    243 void 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 
    251 void inet_addr_any(inet_addr_t *addr)
    252 {
    253         addr->version = ip_any;
    254         memset(addr->addr6, 0, 16);
    255 }
    256 
    257 void 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 
    264 int 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 
    279 int 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 
    286 int 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 
    301 int 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         }
     78        naddr->bits = bits;
     79        return EOK;
    34380}
    34481
    34582/** Parse node address.
    34683 *
    347  * @param text Network address in common notation.
    348  * @param addr Place to store node address.
     84 * @param text  Network address in dot notation (a.b.c.d)
     85 * @param addr  Place to store node address
    34986 *
    350  * @return EOK on success, EINVAL if input is not in valid format.
    351  *
     87 * @return      EOK on success, EINVAL if input is not in valid format
    35288 */
    35389int inet_addr_parse(const char *text, inet_addr_t *addr)
    35490{
    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:
     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')
    373104                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];
    374111        }
    375        
     112
    376113        return EOK;
    377114}
    378115
    379 /** Parse network address.
     116/** Format network address.
    380117 *
    381  * @param text  Network address in common notation.
    382  * @param naddr Place to store network address.
     118 * @param naddr Network address
     119 * @param bufp  Place to store pointer to formatted string (CIDR notation)
    383120 *
    384  * @return EOK on success, EINVAL if input is not in valid format.
    385  *
     121 * @return      EOK on success, ENOMEM if out of memory.
    386122 */
    387 int inet_naddr_parse(const char *text, inet_naddr_t *naddr)
     123int inet_naddr_format(inet_naddr_t *naddr, char **bufp)
    388124{
    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)
    413                         return EINVAL;
    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)
    423                         return EINVAL;
    424                
    425                 memcpy(naddr->addr6, buf, 16);
    426                 naddr->prefix = prefix;
    427                
    428                 break;
    429         default:
    430                 return ENOTSUP;
    431         }
    432        
     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
     131        if (rc < 0)
     132                return ENOMEM;
     133
    433134        return EOK;
    434135}
     
    436137/** Format node address.
    437138 *
    438  * @param addr Node address.
    439  * @param bufp Place to store pointer to formatted string.
     139 * @param addr  Node address
     140 * @param bufp  Place to store pointer to formatted string (dot notation)
    440141 *
    441  * @return EOK on success.
    442  * @return ENOMEM if out of memory.
    443  * @return ENOTSUP on unsupported address family.
    444  *
     142 * @return      EOK on success, ENOMEM if out of memory.
    445143 */
    446 int inet_addr_format(const inet_addr_t *addr, char **bufp)
     144int inet_addr_format(inet_addr_t *addr, char **bufp)
    447145{
    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        
     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
    469152        if (rc < 0)
    470153                return ENOMEM;
    471        
    472         return EOK;
    473 }
    474 
    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  */
    485 int 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        
    526         if (rc < 0)
    527                 return ENOMEM;
    528        
    529         return EOK;
    530 }
    531 
    532 ip_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 
    551 ip_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 
    575 void inet_addr_set(addr32_t v4, inet_addr_t *addr)
    576 {
    577         addr->version = ip_v4;
    578         addr->addr = v4;
    579 }
    580 
    581 void 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 
    588 void 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 
    594 void inet_addr_set6(addr128_t v6, inet_addr_t *addr)
    595 {
    596         addr->version = ip_v6;
    597         memcpy(addr->addr6, v6, 16);
    598 }
    599 
    600 void 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 
    607 void 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 
    614 uint16_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 
    638 int 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         }
    675154
    676155        return EOK;
Note: See TracChangeset for help on using the changeset viewer.