Ignore:
File:
1 edited

Legend:

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

    ra62ceaf r30c5d13  
    11/*
    22 * Copyright (c) 2013 Jiri Svoboda
    3  * Copyright (c) 2013 Martin Decky
    43 * All rights reserved.
    54 *
     
    3433 */
    3534
    36 #include <assert.h>
    3735#include <errno.h>
    3836#include <unistd.h>
     37#include <net/socket_codes.h>
    3938#include <inet/addr.h>
     39#include <net/inet.h>
    4040#include <stdio.h>
    4141#include <malloc.h>
     
    4444#define INET_PREFIXSTRSIZE  5
    4545
    46 #define INET6_ADDRSTRLEN (8 * 4 + 7 + 1)
    47 
    4846#if !(defined(__BE__) ^ defined(__LE__))
    4947        #error The architecture must be either big-endian or little-endian.
    5048#endif
    5149
    52 const addr32_t addr32_broadcast_all_hosts = 0xffffffff;
    53 
    5450const addr48_t addr48_broadcast = {
    5551        0xff, 0xff, 0xff, 0xff, 0xff, 0xff
    5652};
    5753
    58 static const addr48_t inet_addr48_solicited_node = {
    59         0x33, 0x33, 0xff, 0, 0, 0
    60 };
    61 
    6254static const inet_addr_t inet_addr_any_addr = {
    63         .version = ip_v4,
     55        .family = AF_INET,
    6456        .addr = 0
    6557};
    6658
    6759static const inet_addr_t inet_addr_any_addr6 = {
    68         .version = ip_v6,
     60        .family = AF_INET6,
    6961        .addr6 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    7062};
     
    8072}
    8173
    82 /** Compare addr48.
    83   *
    84   * @return Non-zero if equal, zero if not equal.
    85   */
    86 int addr48_compare(const addr48_t a, const addr48_t b)
    87 {
    88         return memcmp(a, b, 6) == 0;
    89 }
    90 
    91 /** Compare addr128.
    92   *
    93   * @return Non-zero if equal, zero if not equal.
    94   */
    9574int addr128_compare(const addr128_t a, const addr128_t b)
    9675{
    97         return memcmp(a, b, 16) == 0;
    98 }
    99 
    100 /** Compute solicited node MAC multicast address from target IPv6 address
    101  *
    102  * @param ip  Target IPv6 address
    103  * @param mac Solicited MAC address to be assigned
    104  *
    105  */
    106 void addr48_solicited_node(const addr128_t ip, addr48_t mac)
    107 {
    108         memcpy(mac, inet_addr48_solicited_node, 3);
    109         memcpy(mac + 3, ip + 13, 3);
     76        return memcmp(a, b, 16);
    11077}
    11178
    11279void host2addr128_t_be(const addr128_t host, addr128_t be)
    11380{
     81#ifdef __BE__
    11482        memcpy(be, host, 16);
     83#else
     84        be[0] = host[15];
     85        be[1] = host[14];
     86        be[2] = host[13];
     87        be[3] = host[12];
     88        be[4] = host[11];
     89        be[5] = host[10];
     90        be[6] = host[9];
     91        be[7] = host[8];
     92        be[8] = host[7];
     93        be[9] = host[6];
     94        be[10] = host[5];
     95        be[11] = host[4];
     96        be[12] = host[3];
     97        be[13] = host[2];
     98        be[14] = host[1];
     99        be[15] = host[0];
     100#endif
    115101}
    116102
    117103void addr128_t_be2host(const addr128_t be, addr128_t host)
    118104{
     105#ifdef __BE__
    119106        memcpy(host, be, 16);
     107#else
     108        host[0] = be[15];
     109        host[1] = be[14];
     110        host[2] = be[13];
     111        host[3] = be[12];
     112        host[4] = be[11];
     113        host[5] = be[10];
     114        host[6] = be[9];
     115        host[7] = be[8];
     116        host[8] = be[7];
     117        host[9] = be[6];
     118        host[10] = be[5];
     119        host[11] = be[4];
     120        host[12] = be[3];
     121        host[13] = be[2];
     122        host[14] = be[1];
     123        host[15] = be[0];
     124#endif
    120125}
    121126
    122127void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
    123128{
    124         addr->version = ip_v4;
     129        addr->family = AF_INET;
    125130        addr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
    126131            ((addr32_t) c << 8) | ((addr32_t) d);
     
    130135    uint8_t prefix)
    131136{
    132         naddr->version = ip_v4;
     137        naddr->family = AF_INET;
    133138        naddr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
    134139            ((addr32_t) c << 8) | ((addr32_t) d);
     
    139144    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h)
    140145{
    141         addr->version = ip_v6;
     146        addr->family = AF_INET6;
    142147        addr->addr6[0] = (a >> 8) & 0xff;
    143148        addr->addr6[1] = a & 0xff;
     
    161166    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h, uint8_t prefix)
    162167{
    163         naddr->version = ip_v6;
     168        naddr->family = AF_INET6;
    164169        naddr->addr6[0] = (a >> 8) & 0xff;
    165170        naddr->addr6[1] = a & 0xff;
     
    181186}
    182187
     188/** Parse network address family.
     189 *
     190 * @param text Network address in common notation.
     191 * @param af   Place to store network address family.
     192 *
     193 * @return EOK on success, EINVAL if input is not in valid format.
     194 *
     195 */
     196int inet_addr_family(const char *text, uint16_t *af)
     197{
     198        char *dot = str_chr(text, '.');
     199        if (dot != NULL) {
     200                *af = AF_INET;
     201                return EOK;
     202        }
     203       
     204        char *collon = str_chr(text, ':');
     205        if (collon != NULL) {
     206                *af = AF_INET6;
     207                return EOK;
     208        }
     209       
     210        return EINVAL;
     211}
     212
    183213void inet_naddr_addr(const inet_naddr_t *naddr, inet_addr_t *addr)
    184214{
    185         addr->version = naddr->version;
     215        addr->family = naddr->family;
    186216        memcpy(addr->addr6, naddr->addr6, 16);
    187217}
     
    190220    inet_naddr_t *naddr)
    191221{
    192         naddr->version = addr->version;
     222        naddr->family = addr->family;
    193223        memcpy(naddr->addr6, addr->addr6, 16);
    194224        naddr->prefix = prefix;
     
    197227void inet_addr_any(inet_addr_t *addr)
    198228{
    199         addr->version = ip_any;
     229        addr->family = AF_NONE;
    200230        memset(addr->addr6, 0, 16);
    201231}
     
    203233void inet_naddr_any(inet_naddr_t *naddr)
    204234{
    205         naddr->version = ip_any;
     235        naddr->family = AF_NONE;
    206236        memset(naddr->addr6, 0, 16);
    207237        naddr->prefix = 0;
     
    210240int inet_addr_compare(const inet_addr_t *a, const inet_addr_t *b)
    211241{
    212         if (a->version != b->version)
     242        if (a->family != b->family)
    213243                return 0;
    214 
    215         switch (a->version) {
    216         case ip_v4:
     244       
     245        switch (a->family) {
     246        case AF_INET:
    217247                return (a->addr == b->addr);
    218         case ip_v6:
     248        case AF_INET6:
    219249                return addr128_compare(a->addr6, b->addr6);
    220250        default:
     
    225255int inet_addr_is_any(const inet_addr_t *addr)
    226256{
    227         return ((addr->version == ip_any) ||
     257        return ((addr->family == 0) ||
    228258            (inet_addr_compare(addr, &inet_addr_any_addr)) ||
    229259            (inet_addr_compare(addr, &inet_addr_any_addr6)));
     
    232262int inet_naddr_compare(const inet_naddr_t *naddr, const inet_addr_t *addr)
    233263{
    234         if (naddr->version != addr->version)
     264        if (naddr->family != addr->family)
    235265                return 0;
    236 
    237         switch (naddr->version) {
    238         case ip_v4:
     266       
     267        switch (naddr->family) {
     268        case AF_INET:
    239269                return (naddr->addr == addr->addr);
    240         case ip_v6:
     270        case AF_INET6:
    241271                return addr128_compare(naddr->addr6, addr->addr6);
    242272        default:
     
    247277int inet_naddr_compare_mask(const inet_naddr_t *naddr, const inet_addr_t *addr)
    248278{
    249         if (naddr->version != addr->version)
     279        if (naddr->family != addr->family)
    250280                return 0;
    251 
    252         switch (naddr->version) {
    253         case ip_v4:
     281       
     282        switch (naddr->family) {
     283        case AF_INET:
    254284                if (naddr->prefix > 32)
    255285                        return 0;
    256 
     286               
    257287                addr32_t mask =
    258288                    BIT_RANGE(addr32_t, 31, 31 - (naddr->prefix - 1));
    259289                return ((naddr->addr & mask) == (addr->addr & mask));
    260         case ip_v6:
     290        case AF_INET6:
    261291                if (naddr->prefix > 128)
    262292                        return 0;
    263 
     293               
    264294                size_t pos = 0;
    265295                for (size_t i = 0; i < 16; i++) {
     
    267297                        if (naddr->prefix < pos)
    268298                                break;
    269 
     299                       
    270300                        if (naddr->prefix - pos > 8) {
    271301                                /* Comparison without masking */
     
    279309                                        return 0;
    280310                        }
    281 
     311                       
    282312                        pos += 8;
    283313                }
    284 
     314               
    285315                return 1;
    286316        default:
     
    289319}
    290320
    291 static int inet_addr_parse_v4(const char *str, inet_addr_t *raddr,
    292     int *prefix, char **endptr)
    293 {
    294         uint32_t a = 0;
    295         uint8_t b;
    296         char *cur = (char *)str;
    297         size_t i = 0;
    298 
    299         while (i < 4) {
    300                 int rc = str_uint8_t(cur, (const char **)&cur, 10, false, &b);
    301                 if (rc != EOK)
    302                         return rc;
    303 
    304                 a = (a << 8) + b;
    305 
    306                 i++;
    307 
    308                 if (*cur != '.')
    309                         break;
    310 
    311                 if (i < 4)
    312                         cur++;
    313         }
    314 
    315         if (prefix != NULL) {
    316                 if (*cur != '/')
    317                         return EINVAL;
    318                 cur++;
    319 
    320                 *prefix = strtoul(cur, &cur, 10);
    321                 if (*prefix > 32)
    322                         return EINVAL;
    323         }
    324 
    325         if (i != 4)
    326                 return EINVAL;
    327 
    328         if (endptr == NULL && *cur != '\0')
    329                 return EINVAL;
    330 
    331         raddr->version = ip_v4;
    332         raddr->addr = a;
    333 
    334         if (endptr != NULL)
    335                 *endptr = cur;
    336 
    337         return EOK;
    338 }
    339 
    340 static int inet_addr_parse_v6(const char *str, inet_addr_t *raddr, int *prefix,
    341     char **endptr)
    342 {
    343         uint8_t data[16];
    344         int explicit_groups;
    345 
    346         memset(data, 0, 16);
    347 
    348         const char *cur = str;
    349         size_t i = 0;
    350         size_t wildcard_pos = (size_t) -1;
    351         size_t wildcard_size = 0;
    352 
    353         /* Handle initial wildcard */
    354         if ((str[0] == ':') && (str[1] == ':')) {
    355                 cur = str + 2;
    356                 wildcard_pos = 0;
    357                 wildcard_size = 16;
    358         }
    359 
    360         while (i < 16) {
    361                 uint16_t bioctet;
    362                 const char *gend;
    363                 int rc = str_uint16_t(cur, &gend, 16, false, &bioctet);
    364                 if (rc != EOK)
    365                         break;
    366 
    367                 data[i] = (bioctet >> 8) & 0xff;
    368                 data[i + 1] = bioctet & 0xff;
    369 
    370                 if (wildcard_pos != (size_t) -1) {
    371                         if (wildcard_size < 2)
    372                                 return EINVAL;
    373 
    374                         wildcard_size -= 2;
    375                 }
    376 
    377                 i += 2;
    378 
    379                 if (*gend != ':') {
    380                         cur = gend;
    381                         break;
    382                 }
    383 
    384                 if (i < 16) {
    385                         /* Handle wildcard */
    386                         if (gend[1] == ':') {
    387                                 if (wildcard_pos != (size_t) -1)
    388                                         return EINVAL;
    389 
    390                                 wildcard_pos = i;
    391                                 wildcard_size = 16 - i;
    392                                 cur = gend + 2;
    393                         }
    394                 }
    395         }
    396 
    397         /* Number of explicitly specified groups */
    398         explicit_groups = i;
    399 
    400         if (prefix != NULL) {
    401                 if (*cur != '/')
    402                         return EINVAL;
    403                 cur++;
    404 
    405                 *prefix = strtoul(cur, (char **)&cur, 10);
    406                 if (*prefix > 128)
    407                         return EINVAL;
    408         }
    409 
    410         if (endptr == NULL && *cur != '\0')
    411                 return EINVAL;
    412 
    413         /* Create wildcard positions */
    414         if ((wildcard_pos != (size_t) -1) && (wildcard_size > 0)) {
    415                 size_t wildcard_shift = 16 - wildcard_size;
    416 
    417                 for (i = wildcard_pos + wildcard_shift; i > wildcard_pos; i--) {
    418                         size_t j = i - 1;
    419                         data[j + wildcard_size] = data[j];
    420                         data[j] = 0;
    421                 }
    422         } else {
    423                 /* Verify that all groups have been specified */
    424                 if (explicit_groups != 16)
    425                         return EINVAL;
    426         }
    427 
    428         raddr->version = ip_v6;
    429         memcpy(raddr->addr6, data, 16);
    430         if (endptr != NULL)
    431                 *endptr = (char *)cur;
    432         return EOK;
    433 }
    434 
    435321/** Parse node address.
    436  *
    437  * Will fail if @a text contains extra characters at the and and @a endptr
    438  * is @c NULL.
    439322 *
    440323 * @param text Network address in common notation.
    441324 * @param addr Place to store node address.
    442  * @param endptr Place to store pointer to next character oc @c NULL
    443325 *
    444326 * @return EOK on success, EINVAL if input is not in valid format.
    445327 *
    446328 */
    447 int inet_addr_parse(const char *text, inet_addr_t *addr, char **endptr)
    448 {
    449         int rc;
    450 
    451         rc = inet_addr_parse_v4(text, addr, NULL, endptr);
    452         if (rc == EOK)
    453                 return EOK;
    454 
    455         rc = inet_addr_parse_v6(text, addr, NULL, endptr);
    456         if (rc == EOK)
    457                 return EOK;
    458 
    459         return EINVAL;
     329int inet_addr_parse(const char *text, inet_addr_t *addr)
     330{
     331        int rc = inet_addr_family(text, &addr->family);
     332        if (rc != EOK)
     333                return rc;
     334       
     335        uint8_t buf[16];
     336        rc = inet_pton(addr->family, text, buf);
     337        if (rc != EOK)
     338                return rc;
     339       
     340        switch (addr->family) {
     341        case AF_INET:
     342                addr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
     343                    buf[3];
     344                break;
     345        case AF_INET6:
     346                memcpy(addr->addr6, buf, 16);
     347                break;
     348        default:
     349                return EINVAL;
     350        }
     351       
     352        return EOK;
    460353}
    461354
    462355/** Parse network address.
    463  *
    464  * Will fail if @a text contains extra characters at the and and @a endptr
    465  * is @c NULL.
    466356 *
    467357 * @param text  Network address in common notation.
    468358 * @param naddr Place to store network address.
    469  * @param endptr Place to store pointer to next character oc @c NULL
    470359 *
    471360 * @return EOK on success, EINVAL if input is not in valid format.
    472361 *
    473362 */
    474 int inet_naddr_parse(const char *text, inet_naddr_t *naddr, char **endptr)
    475 {
    476         int rc;
    477         inet_addr_t addr;
    478         int prefix;
    479 
    480         rc = inet_addr_parse_v4(text, &addr, &prefix, endptr);
    481         if (rc == EOK) {
    482                 inet_addr_naddr(&addr, prefix, naddr);
    483                 return EOK;
    484         }
    485 
    486         rc = inet_addr_parse_v6(text, &addr, &prefix, endptr);
    487         if (rc == EOK) {
    488                 inet_addr_naddr(&addr, prefix, naddr);
    489                 return EOK;
    490         }
    491 
    492         return EINVAL;
    493 }
    494 
    495 static int inet_addr_format_v4(addr32_t addr, char **bufp)
    496 {
    497         int rc;
    498 
    499         rc = asprintf(bufp, "%u.%u.%u.%u", (addr >> 24) & 0xff,
    500             (addr >> 16) & 0xff, (addr >> 8) & 0xff, addr & 0xff);
    501         if (rc < 0)
    502                 return ENOMEM;
    503 
    504         return EOK;
    505 }
    506 
    507 static int inet_addr_format_v6(const addr128_t addr, char **bufp)
    508 {
    509         *bufp = (char *) malloc(INET6_ADDRSTRLEN);
    510         if (*bufp == NULL)
    511                 return ENOMEM;
    512 
    513         /* Find the longest zero subsequence */
    514 
    515         uint16_t zeroes[8];
    516         uint16_t bioctets[8];
    517 
    518         for (size_t i = 8; i > 0; i--) {
    519                 size_t j = i - 1;
    520 
    521                 bioctets[j] = (addr[j << 1] << 8) | addr[(j << 1) + 1];
    522 
    523                 if (bioctets[j] == 0) {
    524                         zeroes[j] = 1;
    525                         if (j < 7)
    526                                 zeroes[j] += zeroes[j + 1];
    527                 } else
    528                         zeroes[j] = 0;
    529         }
    530 
    531         size_t wildcard_pos = (size_t) -1;
    532         size_t wildcard_size = 0;
    533 
    534         for (size_t i = 0; i < 8; i++) {
    535                 if (zeroes[i] > wildcard_size) {
    536                         wildcard_pos = i;
    537                         wildcard_size = zeroes[i];
    538                 }
    539         }
    540 
    541         char *cur = *bufp;
    542         size_t rest = INET6_ADDRSTRLEN;
    543         bool tail_zero = false;
    544         int ret;
    545 
    546         for (size_t i = 0; i < 8; i++) {
    547                 if ((i == wildcard_pos) && (wildcard_size > 1)) {
    548                         ret = snprintf(cur, rest, ":");
    549                         i += wildcard_size - 1;
    550                         tail_zero = true;
    551                 } else if (i == 0) {
    552                         ret = snprintf(cur, rest, "%" PRIx16, bioctets[i]);
    553                         tail_zero = false;
    554                 } else {
    555                         ret = snprintf(cur, rest, ":%" PRIx16, bioctets[i]);
    556                         tail_zero = false;
    557                 }
    558 
    559                 if (ret < 0)
     363int inet_naddr_parse(const char *text, inet_naddr_t *naddr)
     364{
     365        char *slash = str_chr(text, '/');
     366        if (slash == NULL)
     367                return EINVAL;
     368       
     369        *slash = 0;
     370       
     371        int rc = inet_addr_family(text, &naddr->family);
     372        if (rc != EOK)
     373                return rc;
     374       
     375        uint8_t buf[16];
     376        rc = inet_pton(naddr->family, text, buf);
     377        *slash = '/';
     378       
     379        if (rc != EOK)
     380                return rc;
     381       
     382        slash++;
     383        uint8_t prefix;
     384       
     385        switch (naddr->family) {
     386        case AF_INET:
     387                prefix = strtoul(slash, &slash, 10);
     388                if (prefix > 32)
    560389                        return EINVAL;
    561 
    562                 cur += ret;
    563                 rest -= ret;
    564         }
    565 
    566         if (tail_zero)
    567                 (void) snprintf(cur, rest, ":");
    568 
     390               
     391                naddr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
     392                    buf[3];
     393                naddr->prefix = prefix;
     394               
     395                break;
     396        case AF_INET6:
     397                prefix = strtoul(slash, &slash, 10);
     398                if (prefix > 128)
     399                        return EINVAL;
     400               
     401                memcpy(naddr->addr6, buf, 16);
     402                naddr->prefix = prefix;
     403               
     404                break;
     405        default:
     406                return ENOTSUP;
     407        }
     408       
    569409        return EOK;
    570410}
     
    582422int inet_addr_format(const inet_addr_t *addr, char **bufp)
    583423{
    584         int rc;
    585 
    586         rc = ENOTSUP;
    587 
    588         switch (addr->version) {
    589         case ip_any:
     424        int rc = 0;
     425       
     426        switch (addr->family) {
     427        case AF_NONE:
    590428                rc = asprintf(bufp, "none");
    591                 if (rc < 0)
     429                break;
     430        case AF_INET:
     431                rc = asprintf(bufp, "%u.%u.%u.%u", (addr->addr >> 24) & 0xff,
     432                    (addr->addr >> 16) & 0xff, (addr->addr >> 8) & 0xff,
     433                    addr->addr & 0xff);
     434                break;
     435        case AF_INET6:
     436                *bufp = (char *) malloc(INET6_ADDRSTRLEN);
     437                if (*bufp == NULL)
    592438                        return ENOMEM;
    593                 rc = EOK;
    594                 break;
    595         case ip_v4:
    596                 rc = inet_addr_format_v4(addr->addr, bufp);
    597                 break;
    598         case ip_v6:
    599                 rc = inet_addr_format_v6(addr->addr6, bufp);
    600                 break;
    601         }
    602 
    603         return rc;
     439               
     440                return inet_ntop(AF_INET6, addr->addr6, *bufp, INET6_ADDRSTRLEN);
     441        default:
     442                return ENOTSUP;
     443        }
     444       
     445        if (rc < 0)
     446                return ENOMEM;
     447       
     448        return EOK;
    604449}
    605450
     
    616461int inet_naddr_format(const inet_naddr_t *naddr, char **bufp)
    617462{
    618         int rc;
    619         char *astr;
    620 
    621         rc = ENOTSUP;
    622 
    623         switch (naddr->version) {
    624         case ip_any:
     463        int rc = 0;
     464        char prefix[INET_PREFIXSTRSIZE];
     465       
     466        switch (naddr->family) {
     467        case AF_NONE:
    625468                rc = asprintf(bufp, "none");
    626                 if (rc < 0)
     469                break;
     470        case AF_INET:
     471                rc = asprintf(bufp, "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8
     472                    "/%" PRIu8, (naddr->addr >> 24) & 0xff,
     473                    (naddr->addr >> 16) & 0xff, (naddr->addr >> 8) & 0xff,
     474                    naddr->addr & 0xff, naddr->prefix);
     475                break;
     476        case AF_INET6:
     477                *bufp = (char *) malloc(INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
     478                if (*bufp == NULL)
    627479                        return ENOMEM;
    628                 rc = EOK;
    629                 break;
    630         case ip_v4:
    631                 rc = inet_addr_format_v4(naddr->addr, &astr);
    632                 if (rc != EOK)
    633                         return ENOMEM;
    634 
    635                 rc = asprintf(bufp, "%s/%" PRIu8, astr, naddr->prefix);
     480               
     481                rc = inet_ntop(AF_INET6, naddr->addr6, *bufp,
     482                    INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
     483                if (rc != EOK) {
     484                        free(*bufp);
     485                        return rc;
     486                }
     487               
     488                rc = snprintf(prefix, INET_PREFIXSTRSIZE, "/%" PRIu8,
     489                    naddr->prefix);
    636490                if (rc < 0) {
    637                         free(astr);
     491                        free(*bufp);
    638492                        return ENOMEM;
    639493                }
    640 
    641                 rc = EOK;
    642                 break;
    643         case ip_v6:
    644                 rc = inet_addr_format_v6(naddr->addr6, &astr);
    645                 if (rc != EOK)
    646                         return ENOMEM;
    647 
    648                 rc = asprintf(bufp, "%s/%" PRIu8, astr, naddr->prefix);
    649                 if (rc < 0) {
    650                         free(astr);
    651                         return ENOMEM;
    652                 }
    653 
    654                 rc = EOK;
    655                 break;
    656         }
    657 
    658         return rc;
    659 }
    660 
    661 ip_ver_t inet_addr_get(const inet_addr_t *addr, addr32_t *v4, addr128_t *v6)
    662 {
    663         switch (addr->version) {
    664         case ip_v4:
     494               
     495                str_append(*bufp, INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE, prefix);
     496               
     497                break;
     498        default:
     499                return ENOTSUP;
     500        }
     501       
     502        if (rc < 0)
     503                return ENOMEM;
     504       
     505        return EOK;
     506}
     507
     508uint16_t inet_addr_get(const inet_addr_t *addr, addr32_t *v4, addr128_t *v6)
     509{
     510        switch (addr->family) {
     511        case AF_INET:
    665512                if (v4 != NULL)
    666513                        *v4 = addr->addr;
    667                 break;
    668         case ip_v6:
     514               
     515                break;
     516        case AF_INET6:
    669517                if (v6 != NULL)
    670518                        memcpy(*v6, addr->addr6, 16);
    671                 break;
    672         default:
    673                 assert(false);
    674                 break;
    675         }
    676 
    677         return addr->version;
    678 }
    679 
    680 ip_ver_t inet_naddr_get(const inet_naddr_t *naddr, addr32_t *v4, addr128_t *v6,
     519               
     520                break;
     521        }
     522       
     523        return addr->family;
     524}
     525
     526uint16_t inet_naddr_get(const inet_naddr_t *naddr, addr32_t *v4, addr128_t *v6,
    681527    uint8_t *prefix)
    682528{
    683         switch (naddr->version) {
    684         case ip_v4:
     529        switch (naddr->family) {
     530        case AF_INET:
    685531                if (v4 != NULL)
    686532                        *v4 = naddr->addr;
     533               
    687534                if (prefix != NULL)
    688535                        *prefix = naddr->prefix;
    689                 break;
    690         case ip_v6:
     536               
     537                break;
     538        case AF_INET6:
    691539                if (v6 != NULL)
    692540                        memcpy(*v6, naddr->addr6, 16);
     541               
    693542                if (prefix != NULL)
    694543                        *prefix = naddr->prefix;
    695                 break;
    696         default:
    697                 assert(false);
    698                 break;
    699         }
    700 
    701         return naddr->version;
     544               
     545                break;
     546        }
     547       
     548        return naddr->family;
    702549}
    703550
    704551void inet_addr_set(addr32_t v4, inet_addr_t *addr)
    705552{
    706         addr->version = ip_v4;
     553        addr->family = AF_INET;
    707554        addr->addr = v4;
    708555}
     
    710557void inet_naddr_set(addr32_t v4, uint8_t prefix, inet_naddr_t *naddr)
    711558{
    712         naddr->version = ip_v4;
     559        naddr->family = AF_INET;
    713560        naddr->addr = v4;
    714561        naddr->prefix = prefix;
    715562}
    716563
     564void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr)
     565{
     566        addr->family = AF_INET;
     567        addr->addr = uint32_t_be2host(sockaddr_in->sin_addr.s_addr);
     568}
     569
    717570void inet_addr_set6(addr128_t v6, inet_addr_t *addr)
    718571{
    719         addr->version = ip_v6;
     572        addr->family = AF_INET6;
    720573        memcpy(addr->addr6, v6, 16);
    721574}
     
    723576void inet_naddr_set6(addr128_t v6, uint8_t prefix, inet_naddr_t *naddr)
    724577{
    725         naddr->version = ip_v6;
     578        naddr->family = AF_INET6;
    726579        memcpy(naddr->addr6, v6, 16);
    727580        naddr->prefix = prefix;
    728581}
    729582
     583void inet_sockaddr_in6_addr(const sockaddr_in6_t *sockaddr_in6,
     584    inet_addr_t *addr)
     585{
     586        addr->family = AF_INET6;
     587        addr128_t_be2host(sockaddr_in6->sin6_addr.s6_addr, addr->addr6);
     588}
     589
     590uint16_t inet_addr_sockaddr_in(const inet_addr_t *addr,
     591    sockaddr_in_t *sockaddr_in, sockaddr_in6_t *sockaddr_in6)
     592{
     593        switch (addr->family) {
     594        case AF_INET:
     595                if (sockaddr_in != NULL) {
     596                        sockaddr_in->sin_family = AF_INET;
     597                        sockaddr_in->sin_addr.s_addr = host2uint32_t_be(addr->addr);
     598                }
     599               
     600                break;
     601        case AF_INET6:
     602                if (sockaddr_in6 != NULL) {
     603                        sockaddr_in6->sin6_family = AF_INET6;
     604                        host2addr128_t_be(addr->addr6, sockaddr_in6->sin6_addr.s6_addr);
     605                }
     606               
     607                break;
     608        }
     609       
     610        return addr->family;
     611}
     612
    730613/** @}
    731614 */
Note: See TracChangeset for help on using the changeset viewer.