Ignore:
File:
1 edited

Legend:

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

    r30c5d13 ra62ceaf  
    11/*
    22 * Copyright (c) 2013 Jiri Svoboda
     3 * Copyright (c) 2013 Martin Decky
    34 * All rights reserved.
    45 *
     
    3334 */
    3435
     36#include <assert.h>
    3537#include <errno.h>
    3638#include <unistd.h>
    37 #include <net/socket_codes.h>
    3839#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
    4648#if !(defined(__BE__) ^ defined(__LE__))
    4749        #error The architecture must be either big-endian or little-endian.
    4850#endif
    4951
     52const addr32_t addr32_broadcast_all_hosts = 0xffffffff;
     53
    5054const addr48_t addr48_broadcast = {
    5155        0xff, 0xff, 0xff, 0xff, 0xff, 0xff
    5256};
    5357
     58static const addr48_t inet_addr48_solicited_node = {
     59        0x33, 0x33, 0xff, 0, 0, 0
     60};
     61
    5462static const inet_addr_t inet_addr_any_addr = {
    55         .family = AF_INET,
     63        .version = ip_v4,
    5664        .addr = 0
    5765};
    5866
    5967static const inet_addr_t inet_addr_any_addr6 = {
    60         .family = AF_INET6,
     68        .version = ip_v6,
    6169        .addr6 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    6270};
     
    7280}
    7381
     82/** Compare addr48.
     83  *
     84  * @return Non-zero if equal, zero if not equal.
     85  */
     86int 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  */
    7495int addr128_compare(const addr128_t a, const addr128_t b)
    7596{
    76         return memcmp(a, b, 16);
     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 */
     106void 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);
    77110}
    78111
    79112void host2addr128_t_be(const addr128_t host, addr128_t be)
    80113{
    81 #ifdef __BE__
    82114        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
    101115}
    102116
    103117void addr128_t_be2host(const addr128_t be, addr128_t host)
    104118{
    105 #ifdef __BE__
    106119        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
    125120}
    126121
    127122void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
    128123{
    129         addr->family = AF_INET;
     124        addr->version = ip_v4;
    130125        addr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
    131126            ((addr32_t) c << 8) | ((addr32_t) d);
     
    135130    uint8_t prefix)
    136131{
    137         naddr->family = AF_INET;
     132        naddr->version = ip_v4;
    138133        naddr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
    139134            ((addr32_t) c << 8) | ((addr32_t) d);
     
    144139    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h)
    145140{
    146         addr->family = AF_INET6;
     141        addr->version = ip_v6;
    147142        addr->addr6[0] = (a >> 8) & 0xff;
    148143        addr->addr6[1] = a & 0xff;
     
    166161    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h, uint8_t prefix)
    167162{
    168         naddr->family = AF_INET6;
     163        naddr->version = ip_v6;
    169164        naddr->addr6[0] = (a >> 8) & 0xff;
    170165        naddr->addr6[1] = a & 0xff;
     
    186181}
    187182
    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  */
    196 int 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 
    213183void inet_naddr_addr(const inet_naddr_t *naddr, inet_addr_t *addr)
    214184{
    215         addr->family = naddr->family;
     185        addr->version = naddr->version;
    216186        memcpy(addr->addr6, naddr->addr6, 16);
    217187}
     
    220190    inet_naddr_t *naddr)
    221191{
    222         naddr->family = addr->family;
     192        naddr->version = addr->version;
    223193        memcpy(naddr->addr6, addr->addr6, 16);
    224194        naddr->prefix = prefix;
     
    227197void inet_addr_any(inet_addr_t *addr)
    228198{
    229         addr->family = AF_NONE;
     199        addr->version = ip_any;
    230200        memset(addr->addr6, 0, 16);
    231201}
     
    233203void inet_naddr_any(inet_naddr_t *naddr)
    234204{
    235         naddr->family = AF_NONE;
     205        naddr->version = ip_any;
    236206        memset(naddr->addr6, 0, 16);
    237207        naddr->prefix = 0;
     
    240210int inet_addr_compare(const inet_addr_t *a, const inet_addr_t *b)
    241211{
    242         if (a->family != b->family)
     212        if (a->version != b->version)
    243213                return 0;
    244        
    245         switch (a->family) {
    246         case AF_INET:
     214
     215        switch (a->version) {
     216        case ip_v4:
    247217                return (a->addr == b->addr);
    248         case AF_INET6:
     218        case ip_v6:
    249219                return addr128_compare(a->addr6, b->addr6);
    250220        default:
     
    255225int inet_addr_is_any(const inet_addr_t *addr)
    256226{
    257         return ((addr->family == 0) ||
     227        return ((addr->version == ip_any) ||
    258228            (inet_addr_compare(addr, &inet_addr_any_addr)) ||
    259229            (inet_addr_compare(addr, &inet_addr_any_addr6)));
     
    262232int inet_naddr_compare(const inet_naddr_t *naddr, const inet_addr_t *addr)
    263233{
    264         if (naddr->family != addr->family)
     234        if (naddr->version != addr->version)
    265235                return 0;
    266        
    267         switch (naddr->family) {
    268         case AF_INET:
     236
     237        switch (naddr->version) {
     238        case ip_v4:
    269239                return (naddr->addr == addr->addr);
    270         case AF_INET6:
     240        case ip_v6:
    271241                return addr128_compare(naddr->addr6, addr->addr6);
    272242        default:
     
    277247int inet_naddr_compare_mask(const inet_naddr_t *naddr, const inet_addr_t *addr)
    278248{
    279         if (naddr->family != addr->family)
     249        if (naddr->version != addr->version)
    280250                return 0;
    281        
    282         switch (naddr->family) {
    283         case AF_INET:
     251
     252        switch (naddr->version) {
     253        case ip_v4:
    284254                if (naddr->prefix > 32)
    285255                        return 0;
    286                
     256
    287257                addr32_t mask =
    288258                    BIT_RANGE(addr32_t, 31, 31 - (naddr->prefix - 1));
    289259                return ((naddr->addr & mask) == (addr->addr & mask));
    290         case AF_INET6:
     260        case ip_v6:
    291261                if (naddr->prefix > 128)
    292262                        return 0;
    293                
     263
    294264                size_t pos = 0;
    295265                for (size_t i = 0; i < 16; i++) {
     
    297267                        if (naddr->prefix < pos)
    298268                                break;
    299                        
     269
    300270                        if (naddr->prefix - pos > 8) {
    301271                                /* Comparison without masking */
     
    309279                                        return 0;
    310280                        }
    311                        
     281
    312282                        pos += 8;
    313283                }
    314                
     284
    315285                return 1;
    316286        default:
     
    319289}
    320290
     291static 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
     340static 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
    321435/** Parse node address.
     436 *
     437 * Will fail if @a text contains extra characters at the and and @a endptr
     438 * is @c NULL.
    322439 *
    323440 * @param text Network address in common notation.
    324441 * @param addr Place to store node address.
     442 * @param endptr Place to store pointer to next character oc @c NULL
    325443 *
    326444 * @return EOK on success, EINVAL if input is not in valid format.
    327445 *
    328446 */
    329 int 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;
     447int 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;
    353460}
    354461
    355462/** Parse network address.
     463 *
     464 * Will fail if @a text contains extra characters at the and and @a endptr
     465 * is @c NULL.
    356466 *
    357467 * @param text  Network address in common notation.
    358468 * @param naddr Place to store network address.
     469 * @param endptr Place to store pointer to next character oc @c NULL
    359470 *
    360471 * @return EOK on success, EINVAL if input is not in valid format.
    361472 *
    362473 */
    363 int 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)
     474int 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
     495static 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
     507static 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)
    389560                        return EINVAL;
    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        
     561
     562                cur += ret;
     563                rest -= ret;
     564        }
     565
     566        if (tail_zero)
     567                (void) snprintf(cur, rest, ":");
     568
    409569        return EOK;
    410570}
     
    422582int inet_addr_format(const inet_addr_t *addr, char **bufp)
    423583{
    424         int rc = 0;
    425        
    426         switch (addr->family) {
    427         case AF_NONE:
     584        int rc;
     585
     586        rc = ENOTSUP;
     587
     588        switch (addr->version) {
     589        case ip_any:
    428590                rc = asprintf(bufp, "none");
    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)
     591                if (rc < 0)
    438592                        return ENOMEM;
    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;
     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;
    449604}
    450605
     
    461616int inet_naddr_format(const inet_naddr_t *naddr, char **bufp)
    462617{
    463         int rc = 0;
    464         char prefix[INET_PREFIXSTRSIZE];
    465        
    466         switch (naddr->family) {
    467         case AF_NONE:
     618        int rc;
     619        char *astr;
     620
     621        rc = ENOTSUP;
     622
     623        switch (naddr->version) {
     624        case ip_any:
    468625                rc = asprintf(bufp, "none");
    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)
     626                if (rc < 0)
    479627                        return ENOMEM;
    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);
     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);
    490636                if (rc < 0) {
    491                         free(*bufp);
     637                        free(astr);
    492638                        return ENOMEM;
    493639                }
    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 
    508 uint16_t inet_addr_get(const inet_addr_t *addr, addr32_t *v4, addr128_t *v6)
    509 {
    510         switch (addr->family) {
    511         case AF_INET:
     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
     661ip_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:
    512665                if (v4 != NULL)
    513666                        *v4 = addr->addr;
    514                
    515                 break;
    516         case AF_INET6:
     667                break;
     668        case ip_v6:
    517669                if (v6 != NULL)
    518670                        memcpy(*v6, addr->addr6, 16);
    519                
    520                 break;
    521         }
    522        
    523         return addr->family;
    524 }
    525 
    526 uint16_t inet_naddr_get(const inet_naddr_t *naddr, addr32_t *v4, addr128_t *v6,
     671                break;
     672        default:
     673                assert(false);
     674                break;
     675        }
     676
     677        return addr->version;
     678}
     679
     680ip_ver_t inet_naddr_get(const inet_naddr_t *naddr, addr32_t *v4, addr128_t *v6,
    527681    uint8_t *prefix)
    528682{
    529         switch (naddr->family) {
    530         case AF_INET:
     683        switch (naddr->version) {
     684        case ip_v4:
    531685                if (v4 != NULL)
    532686                        *v4 = naddr->addr;
    533                
    534687                if (prefix != NULL)
    535688                        *prefix = naddr->prefix;
    536                
    537                 break;
    538         case AF_INET6:
     689                break;
     690        case ip_v6:
    539691                if (v6 != NULL)
    540692                        memcpy(*v6, naddr->addr6, 16);
    541                
    542693                if (prefix != NULL)
    543694                        *prefix = naddr->prefix;
    544                
    545                 break;
    546         }
    547        
    548         return naddr->family;
     695                break;
     696        default:
     697                assert(false);
     698                break;
     699        }
     700
     701        return naddr->version;
    549702}
    550703
    551704void inet_addr_set(addr32_t v4, inet_addr_t *addr)
    552705{
    553         addr->family = AF_INET;
     706        addr->version = ip_v4;
    554707        addr->addr = v4;
    555708}
     
    557710void inet_naddr_set(addr32_t v4, uint8_t prefix, inet_naddr_t *naddr)
    558711{
    559         naddr->family = AF_INET;
     712        naddr->version = ip_v4;
    560713        naddr->addr = v4;
    561714        naddr->prefix = prefix;
    562715}
    563716
    564 void 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 
    570717void inet_addr_set6(addr128_t v6, inet_addr_t *addr)
    571718{
    572         addr->family = AF_INET6;
     719        addr->version = ip_v6;
    573720        memcpy(addr->addr6, v6, 16);
    574721}
     
    576723void inet_naddr_set6(addr128_t v6, uint8_t prefix, inet_naddr_t *naddr)
    577724{
    578         naddr->family = AF_INET6;
     725        naddr->version = ip_v6;
    579726        memcpy(naddr->addr6, v6, 16);
    580727        naddr->prefix = prefix;
    581728}
    582729
    583 void 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 
    590 uint16_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 
    613730/** @}
    614731 */
Note: See TracChangeset for help on using the changeset viewer.