Changeset 02a09ed in mainline for uspace/lib/c/generic/inet/addr.c


Ignore:
Timestamp:
2013-06-28T20:20:03Z (11 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1d24ad3
Parents:
edf0d27
Message:

add basic infrastructure for IPv6 (inactive)
make inet_addr_t a universal address type

File:
1 edited

Legend:

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

    redf0d27 r02a09ed  
    3939#include <net/inet.h>
    4040#include <stdio.h>
    41 
    42 static inet_addr_t inet_addr_any_addr = {
     41#include <malloc.h>
     42#include <bitops.h>
     43
     44#define INET_PREFIXSTRSIZE  5
     45
     46#if !(defined(__BE__) ^ defined(__LE__))
     47        #error The architecture must be either big-endian or little-endian.
     48#endif
     49
     50const addr48_t addr48_broadcast = {
     51        0xff, 0xff, 0xff, 0xff, 0xff, 0xff
     52};
     53
     54static const inet_addr_t inet_addr_any_addr = {
    4355        .family = AF_INET,
    44         .addr = {0, 0, 0, 0}
     56        .addr = 0
    4557};
    4658
    47 static inet_addr_t inet_addr_any_addr6 = {
     59static const inet_addr_t inet_addr_any_addr6 = {
    4860        .family = AF_INET6,
    49         .addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
     61        .addr6 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
    5062};
     63
     64void addr48(const addr48_t src, addr48_t dst)
     65{
     66        memcpy(dst, src, 6);
     67}
     68
     69void addr128(const addr128_t src, addr128_t dst)
     70{
     71        memcpy(dst, src, 16);
     72}
     73
     74void host2addr128_t_be(const addr128_t host, addr128_t be)
     75{
     76#ifdef __BE__
     77        memcpy(be, host, 16);
     78#else
     79        be[0] = host[15];
     80        be[1] = host[14];
     81        be[2] = host[13];
     82        be[3] = host[12];
     83        be[4] = host[11];
     84        be[5] = host[10];
     85        be[6] = host[9];
     86        be[7] = host[8];
     87        be[8] = host[7];
     88        be[9] = host[6];
     89        be[10] = host[5];
     90        be[11] = host[4];
     91        be[12] = host[3];
     92        be[13] = host[2];
     93        be[14] = host[1];
     94        be[15] = host[0];
     95#endif
     96}
     97
     98void addr128_t_be2host(const addr128_t be, addr128_t host)
     99{
     100#ifdef __BE__
     101        memcpy(host, be, 16);
     102#else
     103        host[0] = be[15];
     104        host[1] = be[14];
     105        host[2] = be[13];
     106        host[3] = be[12];
     107        host[4] = be[11];
     108        host[5] = be[10];
     109        host[6] = be[9];
     110        host[7] = be[8];
     111        host[8] = be[7];
     112        host[9] = be[6];
     113        host[10] = be[5];
     114        host[11] = be[4];
     115        host[12] = be[3];
     116        host[13] = be[2];
     117        host[14] = be[1];
     118        host[15] = be[0];
     119#endif
     120}
     121
     122void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
     123{
     124        addr->family = AF_INET;
     125        addr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
     126            ((addr32_t) c << 8) | ((addr32_t) d);
     127}
     128
     129void inet_naddr(inet_naddr_t *naddr, uint8_t a, uint8_t b, uint8_t c, uint8_t d,
     130    uint8_t prefix)
     131{
     132        naddr->family = AF_INET;
     133        naddr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
     134            ((addr32_t) c << 8) | ((addr32_t) d);
     135        naddr->prefix = prefix;
     136}
     137
     138void inet_addr6(inet_addr_t *addr, uint16_t a, uint16_t b, uint16_t c,
     139    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h)
     140{
     141        addr->family = AF_INET6;
     142        addr->addr6[0] = (a >> 8) & 0xff;
     143        addr->addr6[1] = a & 0xff;
     144        addr->addr6[2] = (b >> 8) & 0xff;
     145        addr->addr6[3] = b & 0xff;
     146        addr->addr6[4] = (c >> 8) & 0xff;
     147        addr->addr6[5] = c & 0xff;
     148        addr->addr6[6] = (d >> 8) & 0xff;
     149        addr->addr6[7] = d & 0xff;
     150        addr->addr6[8] = (e >> 8) & 0xff;
     151        addr->addr6[9] = e & 0xff;
     152        addr->addr6[10] = (f >> 8) & 0xff;
     153        addr->addr6[11] = f & 0xff;
     154        addr->addr6[12] = (g >> 8) & 0xff;
     155        addr->addr6[13] = g & 0xff;
     156        addr->addr6[14] = (h >> 8) & 0xff;
     157        addr->addr6[15] = h & 0xff;
     158}
     159
     160void inet_naddr6(inet_naddr_t *naddr, uint16_t a, uint16_t b, uint16_t c,
     161    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h, uint8_t prefix)
     162{
     163        naddr->family = AF_INET6;
     164        naddr->addr6[0] = (a >> 8) & 0xff;
     165        naddr->addr6[1] = a & 0xff;
     166        naddr->addr6[2] = (b >> 8) & 0xff;
     167        naddr->addr6[3] = b & 0xff;
     168        naddr->addr6[4] = (c >> 8) & 0xff;
     169        naddr->addr6[5] = c & 0xff;
     170        naddr->addr6[6] = (d >> 8) & 0xff;
     171        naddr->addr6[7] = d & 0xff;
     172        naddr->addr6[8] = (e >> 8) & 0xff;
     173        naddr->addr6[9] = e & 0xff;
     174        naddr->addr6[10] = (f >> 8) & 0xff;
     175        naddr->addr6[11] = f & 0xff;
     176        naddr->addr6[12] = (g >> 8) & 0xff;
     177        naddr->addr6[13] = g & 0xff;
     178        naddr->addr6[14] = (h >> 8) & 0xff;
     179        naddr->addr6[15] = h & 0xff;
     180        naddr->prefix = prefix;
     181}
    51182
    52183/** Parse network address family.
     
    72203        }
    73204       
    74         *af = AF_NONE;
    75205        return EINVAL;
     206}
     207
     208void inet_naddr_addr(const inet_naddr_t *naddr, inet_addr_t *addr)
     209{
     210        addr->family = naddr->family;
     211        memcpy(addr->addr6, naddr->addr6, 16);
     212}
     213
     214void inet_addr_any(inet_addr_t *addr)
     215{
     216        addr->family = AF_NONE;
     217        memset(addr->addr6, 0, 16);
     218}
     219
     220void inet_naddr_any(inet_naddr_t *naddr)
     221{
     222        naddr->family = AF_NONE;
     223        memset(naddr->addr6, 0, 16);
     224        naddr->prefix = 0;
     225}
     226
     227int inet_addr_compare(const inet_addr_t *a, const inet_addr_t *b)
     228{
     229        if (a->family != b->family)
     230                return 0;
     231       
     232        switch (a->family) {
     233        case AF_INET:
     234                return (a->addr == b->addr);
     235        case AF_INET6:
     236                return memcmp(&a->addr6, &b->addr6, 16);
     237        default:
     238                return 0;
     239        }
     240}
     241
     242int inet_addr_is_any(const inet_addr_t *addr)
     243{
     244        return ((addr->family == 0) ||
     245            (inet_addr_compare(addr, &inet_addr_any_addr)) ||
     246            (inet_addr_compare(addr, &inet_addr_any_addr6)));
     247}
     248
     249int inet_naddr_compare_mask(const inet_naddr_t *naddr, const inet_addr_t *addr)
     250{
     251        if (naddr->family != addr->family)
     252                return 0;
     253       
     254        switch (naddr->family) {
     255        case AF_INET:
     256                if (naddr->prefix > 32)
     257                        return 0;
     258               
     259                addr32_t mask =
     260                    BIT_RANGE(addr32_t, 31, 31 - (naddr->prefix - 1));
     261                return ((naddr->addr & mask) == (addr->addr & mask));
     262        case AF_INET6:
     263                if (naddr->prefix > 128)
     264                        return 0;
     265               
     266                size_t pos = 0;
     267                for (size_t i = 0; i < 16; i++) {
     268                        /* Further bits do not matter */
     269                        if (naddr->prefix < pos)
     270                                break;
     271                       
     272                        if (naddr->prefix - pos > 8) {
     273                                /* Comparison without masking */
     274                                if (naddr->addr6[i] != addr->addr6[i])
     275                                        return 0;
     276                        } else {
     277                                /* Comparison with masking */
     278                                uint8_t mask =
     279                                    BIT_RANGE(uint8_t, 8, 8 - (naddr->prefix - pos - 1));
     280                                if ((naddr->addr6[i] & mask) != (addr->addr6[i] & mask))
     281                                        return 0;
     282                        }
     283                       
     284                        pos += 8;
     285                }
     286               
     287                return 1;
     288        default:
     289                return 0;
     290        }
    76291}
    77292
     
    90305                return rc;
    91306       
    92         rc = inet_pton(addr->family, text, addr->addr);
     307        uint8_t buf[16];
     308        rc = inet_pton(addr->family, text, buf);
    93309        if (rc != EOK)
    94310                return rc;
     311       
     312        switch (addr->family) {
     313        case AF_INET:
     314                addr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
     315                    buf[3];
     316                break;
     317        case AF_INET6:
     318                memcpy(addr->addr6, buf, 16);
     319                break;
     320        default:
     321                return EINVAL;
     322        }
    95323       
    96324        return EOK;
     
    117345                return rc;
    118346       
    119         rc = inet_pton(naddr->family, text, naddr->addr);
     347        uint8_t buf[16];
     348        rc = inet_pton(naddr->family, text, buf);
    120349        *slash = '/';
    121350       
     
    124353       
    125354        slash++;
     355        uint8_t prefix;
    126356       
    127357        switch (naddr->family) {
    128358        case AF_INET:
    129                 naddr->prefix = strtoul(slash, &slash, 10);
    130                 if (naddr->prefix > 32)
     359                prefix = strtoul(slash, &slash, 10);
     360                if (prefix > 32)
    131361                        return EINVAL;
    132                 break;
    133         case AF_INET6:
    134                 naddr->prefix = strtoul(slash, &slash, 10);
    135                 if (naddr->prefix > 128)
     362               
     363                naddr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
     364                    buf[3];
     365                naddr->prefix = prefix;
     366               
     367                break;
     368        case AF_INET6:
     369                prefix = strtoul(slash, &slash, 10);
     370                if (prefix > 128)
    136371                        return EINVAL;
     372               
     373                memcpy(naddr->addr6, buf, 16);
     374                naddr->prefix = prefix;
     375               
    137376                break;
    138377        default:
     
    153392 *
    154393 */
    155 int inet_addr_format(inet_addr_t *addr, char **bufp)
    156 {
    157         int rc;
     394int inet_addr_format(const inet_addr_t *addr, char **bufp)
     395{
     396        int rc = 0;
    158397       
    159398        switch (addr->family) {
     
    162401                break;
    163402        case AF_INET:
    164                 rc = asprintf(bufp, "%u.%u.%u.%u", addr->addr[0],
    165                     addr->addr[1], addr->addr[2], addr->addr[3]);
    166                 break;
    167         case AF_INET6:
    168                 // FIXME TODO
    169                 return ENOTSUP;
     403                rc = asprintf(bufp, "%u.%u.%u.%u", (addr->addr >> 24) & 0xff,
     404                    (addr->addr >> 16) & 0xff, (addr->addr >> 8) & 0xff,
     405                    addr->addr & 0xff);
     406                break;
     407        case AF_INET6:
     408                *bufp = (char *) malloc(INET6_ADDRSTRLEN);
     409                if (*bufp == NULL)
     410                        return ENOMEM;
     411               
     412                return inet_ntop(AF_INET6, addr->addr6, *bufp, INET6_ADDRSTRLEN);
    170413        default:
    171414                return ENOTSUP;
     
    188431 *
    189432 */
    190 int inet_naddr_format(inet_naddr_t *naddr, char **bufp)
    191 {
    192         int rc;
     433int inet_naddr_format(const inet_naddr_t *naddr, char **bufp)
     434{
     435        int rc = 0;
     436        char prefix[INET_PREFIXSTRSIZE];
    193437       
    194438        switch (naddr->family) {
     
    197441                break;
    198442        case AF_INET:
    199                 rc = asprintf(bufp, "%u.%u.%u.%u/%u", naddr->addr[0],
    200                     naddr->addr[1], naddr->addr[2], naddr->addr[3],
     443                rc = asprintf(bufp, "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8
     444                    "/%" PRIu8, (naddr->addr >> 24) & 0xff,
     445                    (naddr->addr >> 16) & 0xff, (naddr->addr >> 8) & 0xff,
     446                    naddr->addr & 0xff, naddr->prefix);
     447                break;
     448        case AF_INET6:
     449                *bufp = (char *) malloc(INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
     450                if (*bufp == NULL)
     451                        return ENOMEM;
     452               
     453                rc = inet_ntop(AF_INET6, naddr->addr6, *bufp,
     454                    INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
     455                if (rc != EOK) {
     456                        free(*bufp);
     457                        return rc;
     458                }
     459               
     460                rc = snprintf(prefix, INET_PREFIXSTRSIZE, "/%" PRIu8,
    201461                    naddr->prefix);
    202                 break;
    203         case AF_INET6:
    204                 // FIXME TODO
    205                 return ENOTSUP;
     462                if (rc < 0) {
     463                        free(*bufp);
     464                        return ENOMEM;
     465                }
     466               
     467                str_append(*bufp, INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE, prefix);
     468               
     469                break;
    206470        default:
    207471                return ENOTSUP;
     
    214478}
    215479
    216 /** Create packed IPv4 address
    217  *
    218  * Convert an IPv4 address to a packed 32 bit representation.
    219  *
    220  * @param addr   Source address.
    221  * @param packed Place to store the packed 32 bit representation.
    222  *
    223  * @return EOK on success.
    224  * @return EINVAL if addr is not an IPv4 address.
    225  *
    226  */
    227 int inet_addr_pack(inet_addr_t *addr, uint32_t *packed)
    228 {
    229         if (addr->family != AF_INET)
    230                 return EINVAL;
    231        
    232         *packed = (addr->addr[0] << 24) | (addr->addr[1] << 16) |
    233             (addr->addr[2] << 8) | addr->addr[3];
    234         return EOK;
    235 }
    236 
    237 /** Create packed IPv4 address
    238  *
    239  * Convert an IPv4 address to a packed 32 bit representation.
    240  *
    241  * @param naddr  Source address.
    242  * @param packed Place to store the packed 32 bit representation.
    243  * @param prefix Place to store the number of valid bits.
    244  *
    245  * @return EOK on success.
    246  * @return EINVAL if addr is not an IPv4 address.
    247  *
    248  */
    249 int inet_naddr_pack(inet_naddr_t *naddr, uint32_t *packed, uint8_t *prefix)
    250 {
    251         if (naddr->family != AF_INET)
    252                 return EINVAL;
    253        
    254         *packed = (naddr->addr[0] << 24) | (naddr->addr[1] << 16) |
    255             (naddr->addr[2] << 8) | naddr->addr[3];
    256         *prefix = naddr->prefix;
    257        
    258         return EOK;
    259 }
    260 
    261 void inet_addr_unpack(uint32_t packed, inet_addr_t *addr)
     480uint16_t inet_addr_get(const inet_addr_t *addr, addr32_t *v4, addr128_t *v6)
     481{
     482        switch (addr->family) {
     483        case AF_INET:
     484                if (v4 != NULL)
     485                        *v4 = addr->addr;
     486               
     487                break;
     488        case AF_INET6:
     489                if (v6 != NULL)
     490                        memcpy(*v6, addr->addr6, 16);
     491               
     492                break;
     493        }
     494       
     495        return addr->family;
     496}
     497
     498uint16_t inet_naddr_get(const inet_naddr_t *naddr, addr32_t *v4, addr128_t *v6,
     499    uint8_t *prefix)
     500{
     501        switch (naddr->family) {
     502        case AF_INET:
     503                if (v4 != NULL)
     504                        *v4 = naddr->addr;
     505               
     506                if (prefix != NULL)
     507                        *prefix = naddr->prefix;
     508               
     509                break;
     510        case AF_INET6:
     511                if (v6 != NULL)
     512                        memcpy(*v6, naddr->addr6, 16);
     513               
     514                if (prefix != NULL)
     515                        *prefix = naddr->prefix;
     516               
     517                break;
     518        }
     519       
     520        return naddr->family;
     521}
     522
     523void inet_addr_set(addr32_t v4, inet_addr_t *addr)
    262524{
    263525        addr->family = AF_INET;
    264         addr->addr[0] = (packed >> 24) & 0xff;
    265         addr->addr[1] = (packed >> 16) & 0xff;
    266         addr->addr[2] = (packed >> 8) & 0xff;
    267         addr->addr[3] = packed & 0xff;
    268 }
    269 
    270 void inet_naddr_unpack(uint32_t packed, uint8_t prefix, inet_naddr_t *naddr)
     526        addr->addr = v4;
     527}
     528
     529void inet_naddr_set(addr32_t v4, uint8_t prefix, inet_naddr_t *naddr)
    271530{
    272531        naddr->family = AF_INET;
    273         naddr->addr[0] = (packed >> 24) & 0xff;
    274         naddr->addr[1] = (packed >> 16) & 0xff;
    275         naddr->addr[2] = (packed >> 8) & 0xff;
    276         naddr->addr[3] = packed & 0xff;
     532        naddr->addr = v4;
    277533        naddr->prefix = prefix;
    278534}
    279535
    280 int inet_addr_sockaddr_in(inet_addr_t *addr, sockaddr_in_t *sockaddr_in)
    281 {
    282         uint32_t packed;
    283         int rc = inet_addr_pack(addr, &packed);
    284         if (rc != EOK)
    285                 return rc;
    286        
    287         sockaddr_in->sin_family = AF_INET;
    288         sockaddr_in->sin_addr.s_addr = host2uint32_t_be(packed);
    289         return EOK;
    290 }
    291 
    292 void inet_naddr_addr(inet_naddr_t *naddr, inet_addr_t *addr)
    293 {
    294         addr->family = naddr->family;
    295         memcpy(addr->addr, naddr->addr, INET_ADDR_SIZE);
    296 }
    297 
    298 void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
     536void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr)
    299537{
    300538        addr->family = AF_INET;
    301         addr->addr[0] = a;
    302         addr->addr[1] = b;
    303         addr->addr[2] = c;
    304         addr->addr[3] = d;
    305 }
    306 
    307 void inet_naddr(inet_naddr_t *naddr, uint8_t a, uint8_t b, uint8_t c, uint8_t d,
    308     uint8_t prefix)
    309 {
    310         naddr->family = AF_INET;
    311         naddr->addr[0] = a;
    312         naddr->addr[1] = b;
    313         naddr->addr[2] = c;
    314         naddr->addr[3] = d;
     539        addr->addr = uint32_t_be2host(sockaddr_in->sin_addr.s_addr);
     540}
     541
     542void inet_addr_set6(addr128_t v6, inet_addr_t *addr)
     543{
     544        addr->family = AF_INET6;
     545        memcpy(addr->addr6, v6, 16);
     546}
     547
     548void inet_naddr_set6(addr128_t v6, uint8_t prefix, inet_naddr_t *naddr)
     549{
     550        naddr->family = AF_INET6;
     551        memcpy(naddr->addr6, v6, 16);
    315552        naddr->prefix = prefix;
    316553}
    317554
    318 void inet_addr_any(inet_addr_t *addr)
    319 {
    320         addr->family = 0;
    321         memset(addr->addr, 0, INET_ADDR_SIZE);
    322 }
    323 
    324 void inet_naddr_any(inet_naddr_t *naddr)
    325 {
    326         naddr->family = 0;
    327         memset(naddr->addr, 0, INET_ADDR_SIZE);
    328         naddr->prefix = 0;
    329 }
    330 
    331 int inet_addr_compare(inet_addr_t *a, inet_addr_t *b)
    332 {
    333         if (a->family != b->family)
    334                 return 0;
    335        
    336         switch (a->family) {
    337         case AF_INET:
    338                 return ((a->addr[0] == b->addr[0]) && (a->addr[1] == b->addr[1]) &&
    339                     (a->addr[2] == b->addr[2]) && (a->addr[3] == b->addr[3]));
    340         case AF_INET6:
    341                 // FIXME TODO
    342                 return 0;
    343         default:
    344                 return 0;
    345         }
    346 }
    347 
    348 int inet_addr_is_any(inet_addr_t *addr)
    349 {
    350         return ((addr->family == 0) ||
    351             (inet_addr_compare(addr, &inet_addr_any_addr)) ||
    352             (inet_addr_compare(addr, &inet_addr_any_addr6)));
     555void inet_sockaddr_in6_addr(const sockaddr_in6_t *sockaddr_in6,
     556    inet_addr_t *addr)
     557{
     558        addr->family = AF_INET6;
     559        addr128_t_be2host(sockaddr_in6->sin6_addr.s6_addr, addr->addr6);
     560}
     561
     562uint16_t inet_addr_sockaddr_in(const inet_addr_t *addr,
     563    sockaddr_in_t *sockaddr_in, sockaddr_in6_t *sockaddr_in6)
     564{
     565        switch (addr->family) {
     566        case AF_INET:
     567                if (sockaddr_in != NULL) {
     568                        sockaddr_in->sin_family = AF_INET;
     569                        sockaddr_in->sin_addr.s_addr = host2uint32_t_be(addr->addr);
     570                }
     571               
     572                break;
     573        case AF_INET6:
     574                if (sockaddr_in6 != NULL) {
     575                        sockaddr_in6->sin6_family = AF_INET6;
     576                        host2addr128_t_be(addr->addr6, sockaddr_in6->sin6_addr.s6_addr);
     577                }
     578               
     579                break;
     580        }
     581       
     582        return addr->family;
    353583}
    354584
Note: See TracChangeset for help on using the changeset viewer.