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


Ignore:
Timestamp:
2013-06-20T16:45:58Z (11 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
08bb73b
Parents:
19a4f73
Message:

use new network address infrastructure (towards IPv6 support)

File:
1 edited

Legend:

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

    r19a4f73 ra2e3ee6  
    3434
    3535#include <errno.h>
     36#include <unistd.h>
     37#include <net/socket_codes.h>
    3638#include <inet/addr.h>
     39#include <net/inet.h>
    3740#include <stdio.h>
    3841
     42static inet_addr_t inet_addr_any_addr = {
     43        .family = AF_INET,
     44        .addr = {0, 0, 0, 0}
     45};
     46
     47static inet_addr_t inet_addr_any_addr6 = {
     48        .family = AF_INET6,
     49        .addr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
     50};
     51
     52/** Parse network address family.
     53 *
     54 * @param text Network address in common notation.
     55 * @param af   Place to store network address family.
     56 *
     57 * @return EOK on success, EINVAL if input is not in valid format.
     58 *
     59 */
     60int inet_addr_family(const char *text, uint16_t *af)
     61{
     62        char *dot = str_chr(text, '.');
     63        if (dot != NULL) {
     64                *af = AF_INET;
     65                return EOK;
     66        }
     67       
     68        char *collon = str_chr(text, ':');
     69        if (collon != NULL) {
     70                *af = AF_INET6;
     71                return EOK;
     72        }
     73       
     74        *af = AF_NONE;
     75        return EINVAL;
     76}
     77
     78/** Parse node address.
     79 *
     80 * @param text Network address in common notation.
     81 * @param addr Place to store node address.
     82 *
     83 * @return EOK on success, EINVAL if input is not in valid format.
     84 *
     85 */
     86int inet_addr_parse(const char *text, inet_addr_t *addr)
     87{
     88        int rc = inet_addr_family(text, &addr->family);
     89        if (rc != EOK)
     90                return rc;
     91       
     92        rc = inet_pton(addr->family, text, addr->addr);
     93        if (rc != EOK)
     94                return rc;
     95       
     96        return EOK;
     97}
     98
    3999/** Parse network address.
    40100 *
    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
     101 * @param text  Network address in common notation.
     102 * @param naddr Place to store network address.
     103 *
     104 * @return EOK on success, EINVAL if input is not in valid format.
     105 *
    45106 */
    46107int inet_naddr_parse(const char *text, inet_naddr_t *naddr)
    47108{
    48         unsigned long a[4], bits;
    49         char *cp = (char *)text;
    50         int i;
    51 
    52         for (i = 0; i < 3; i++) {
    53                 a[i] = strtoul(cp, &cp, 10);
    54                 if (*cp != '.')
     109        char *slash = str_chr(text, '/');
     110        if (slash == NULL)
     111                return EINVAL;
     112       
     113        *slash = 0;
     114       
     115        int rc = inet_addr_family(text, &naddr->family);
     116        if (rc != EOK)
     117                return rc;
     118       
     119        rc = inet_pton(naddr->family, text, naddr->addr);
     120        *slash = '/';
     121       
     122        if (rc != EOK)
     123                return rc;
     124       
     125        slash++;
     126       
     127        switch (naddr->family) {
     128        case AF_INET:
     129                naddr->prefix = strtoul(slash, &slash, 10);
     130                if (naddr->prefix > 32)
    55131                        return EINVAL;
    56                 ++cp;
    57         }
    58 
    59         a[3] = strtoul(cp, &cp, 10);
    60         if (*cp != '/')
    61                 return EINVAL;
    62         ++cp;
    63 
    64         bits = strtoul(cp, &cp, 10);
    65         if (*cp != '\0')
    66                 return EINVAL;
    67 
    68         naddr->ipv4 = 0;
    69         for (i = 0; i < 4; i++) {
    70                 if (a[i] > 255)
     132                break;
     133        case AF_INET6:
     134                naddr->prefix = strtoul(slash, &slash, 10);
     135                if (naddr->prefix > 128)
    71136                        return EINVAL;
    72                 naddr->ipv4 = (naddr->ipv4 << 8) | a[i];
    73         }
    74 
    75         if (bits > 31)
    76                 return EINVAL;
    77 
    78         naddr->bits = bits;
    79         return EOK;
    80 }
    81 
    82 /** Parse node address.
    83  *
    84  * @param text  Network address in dot notation (a.b.c.d)
    85  * @param addr  Place to store node address
    86  *
    87  * @return      EOK on success, EINVAL if input is not in valid format
    88  */
    89 int inet_addr_parse(const char *text, inet_addr_t *addr)
    90 {
    91         unsigned long a[4];
    92         char *cp = (char *)text;
    93         int i;
    94 
    95         for (i = 0; i < 3; i++) {
    96                 a[i] = strtoul(cp, &cp, 10);
    97                 if (*cp != '.')
    98                         return EINVAL;
    99                 ++cp;
    100         }
    101 
    102         a[3] = strtoul(cp, &cp, 10);
    103         if (*cp != '\0')
    104                 return EINVAL;
    105 
    106         addr->ipv4 = 0;
    107         for (i = 0; i < 4; i++) {
    108                 if (a[i] > 255)
    109                         return EINVAL;
    110                 addr->ipv4 = (addr->ipv4 << 8) | a[i];
    111         }
    112 
    113         return EOK;
    114 }
    115 
    116 /** Format network address.
    117  *
    118  * @param naddr Network address
    119  * @param bufp  Place to store pointer to formatted string (CIDR notation)
    120  *
    121  * @return      EOK on success, ENOMEM if out of memory.
    122  */
    123 int inet_naddr_format(inet_naddr_t *naddr, char **bufp)
     137                break;
     138        default:
     139                return ENOTSUP;
     140        }
     141       
     142        return EOK;
     143}
     144
     145/** Format node address.
     146 *
     147 * @param addr Node address.
     148 * @param bufp Place to store pointer to formatted string.
     149 *
     150 * @return EOK on success.
     151 * @return ENOMEM if out of memory.
     152 * @return ENOTSUP on unsupported address family.
     153 *
     154 */
     155int inet_addr_format(inet_addr_t *addr, char **bufp)
    124156{
    125157        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 
     158       
     159        switch (addr->family) {
     160        case AF_NONE:
     161                rc = asprintf(bufp, "none");
     162                break;
     163        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                break;
     170        default:
     171                return ENOTSUP;
     172        }
     173       
    131174        if (rc < 0)
    132175                return ENOMEM;
    133 
    134         return EOK;
    135 }
    136 
    137 /** Format node address.
    138  *
    139  * @param addr  Node address
    140  * @param bufp  Place to store pointer to formatted string (dot notation)
    141  *
    142  * @return      EOK on success, ENOMEM if out of memory.
    143  */
    144 int inet_addr_format(inet_addr_t *addr, char **bufp)
     176       
     177        return EOK;
     178}
     179
     180/** Format network address.
     181 *
     182 * @param naddr Network address.
     183 * @param bufp  Place to store pointer to formatted string.
     184 *
     185 * @return EOK on success.
     186 * @return ENOMEM if out of memory.
     187 * @return ENOTSUP on unsupported address family.
     188 *
     189 */
     190int inet_naddr_format(inet_naddr_t *naddr, char **bufp)
    145191{
    146192        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 
     193       
     194        switch (naddr->family) {
     195        case AF_NONE:
     196                rc = asprintf(bufp, "none");
     197                break;
     198        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],
     201                    naddr->prefix);
     202                break;
     203        case AF_INET6:
     204                // FIXME TODO
     205                break;
     206        default:
     207                return ENOTSUP;
     208        }
     209       
    152210        if (rc < 0)
    153211                return ENOMEM;
    154 
    155         return EOK;
     212       
     213        return EOK;
     214}
     215
     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 */
     227int 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 */
     249int 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
     261void inet_addr_unpack(uint32_t packed, inet_addr_t *addr)
     262{
     263        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
     270void inet_naddr_unpack(uint32_t packed, uint8_t prefix, inet_naddr_t *naddr)
     271{
     272        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;
     277        naddr->prefix = prefix;
     278}
     279
     280int 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
     292void 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
     298void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
     299{
     300        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
     307void 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;
     315        naddr->prefix = prefix;
     316}
     317
     318void inet_addr_any(inet_addr_t *addr)
     319{
     320        addr->family = 0;
     321        memset(addr->addr, 0, INET_ADDR_SIZE);
     322}
     323
     324void 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
     331int 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
     348int 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)));
    156353}
    157354
Note: See TracChangeset for help on using the changeset viewer.