Changeset 03c971f in mainline for uspace/lib/c/generic


Ignore:
Timestamp:
2013-08-15T14:20:16Z (12 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bb2a5b2
Parents:
f2c19b0 (diff), 2921602 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Mainline changes.

Location:
uspace/lib/c/generic
Files:
1 added
13 edited
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/bitops.c

    rf2c19b0 r03c971f  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2013 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup inet
     29/** @addtogroup libc
    3030 * @{
    3131 */
    32 /**
    33  * @file
    34  * @brief
    35  */
    3632
    37 #ifndef INET_UTIL_H_
    38 #define INET_UTIL_H_
     33#include <bitops.h>
    3934
    40 #include <sys/types.h>
     35extern int __popcountsi2(int a)
     36{
     37        return __builtin_popcount(a);
     38}
    4139
    42 uint32_t inet_netmask(int bits);
    43 
    44 #endif
    4540
    4641/** @}
  • uspace/lib/c/generic/devman.c

    rf2c19b0 r03c971f  
    413413        sysarg_t dretval;
    414414       
    415         exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER);
     415        exch = devman_exchange_begin_blocking(DEVMAN_CLIENT);
    416416       
    417417        ipc_call_t answer;
  • uspace/lib/c/generic/dnsr.c

    rf2c19b0 r03c971f  
    4444static async_exch_t *dnsr_exchange_begin(void)
    4545{
    46         async_sess_t *sess;
    47         service_id_t dnsr_svc;
    48 
    4946        fibril_mutex_lock(&dnsr_sess_mutex);
    50 
     47       
    5148        if (dnsr_sess == NULL) {
     49                service_id_t dnsr_svc;
     50               
    5251                (void) loc_service_get_id(SERVICE_NAME_DNSR, &dnsr_svc,
    5352                    IPC_FLAG_BLOCKING);
    54 
     53               
    5554                dnsr_sess = loc_service_connect(EXCHANGE_SERIALIZE, dnsr_svc,
    5655                    IPC_FLAG_BLOCKING);
    5756        }
    58 
    59         sess = dnsr_sess;
     57       
     58        async_sess_t *sess = dnsr_sess;
    6059        fibril_mutex_unlock(&dnsr_sess_mutex);
    61 
     60       
    6261        return async_exchange_begin(sess);
    6362}
     
    6867}
    6968
    70 int dnsr_name2host(const char *name, dnsr_hostinfo_t **rinfo)
     69int dnsr_name2host(const char *name, dnsr_hostinfo_t **rinfo, uint16_t af)
    7170{
    72         async_exch_t *exch = dnsr_exchange_begin();
    73         char cname_buf[DNSR_NAME_MAX_SIZE + 1];
    74         ipc_call_t cnreply;
    75         size_t act_size;
    76         dnsr_hostinfo_t *info;
    77 
    78         ipc_call_t answer;
    79         aid_t req = async_send_0(exch, DNSR_NAME2HOST, &answer);
    80         sysarg_t retval = async_data_write_start(exch, name, str_size(name));
    81         aid_t cnreq = async_data_read(exch, cname_buf, DNSR_NAME_MAX_SIZE,
    82             &cnreply);
    83 
    84         dnsr_exchange_end(exch);
    85 
    86         if (retval != EOK) {
    87                 async_forget(req);
    88                 async_forget(cnreq);
    89                 return retval;
    90         }
    91 
    92         async_wait_for(req, &retval);
    93         if (retval != EOK) {
    94                 async_forget(cnreq);
    95                 return EIO;
    96         }
    97 
    98         async_wait_for(cnreq, &retval);
    99         if (retval != EOK)
    100                 return EIO;
    101 
    102         info = calloc(1, sizeof(dnsr_hostinfo_t));
     71        dnsr_hostinfo_t *info = calloc(1, sizeof(dnsr_hostinfo_t));
    10372        if (info == NULL)
    10473                return ENOMEM;
    105 
    106         act_size = IPC_GET_ARG2(cnreply);
     74       
     75        async_exch_t *exch = dnsr_exchange_begin();
     76       
     77        ipc_call_t answer;
     78        aid_t req = async_send_1(exch, DNSR_NAME2HOST, (sysarg_t) af,
     79            &answer);
     80       
     81        int rc = async_data_write_start(exch, name, str_size(name));
     82        if (rc != EOK) {
     83                async_exchange_end(exch);
     84                async_forget(req);
     85                return rc;
     86        }
     87       
     88        ipc_call_t answer_addr;
     89        aid_t req_addr = async_data_read(exch, &info->addr,
     90            sizeof(inet_addr_t), &answer_addr);
     91       
     92        sysarg_t retval_addr;
     93        async_wait_for(req_addr, &retval_addr);
     94       
     95        if (retval_addr != EOK) {
     96                async_exchange_end(exch);
     97                async_forget(req);
     98                return (int) retval_addr;
     99        }
     100       
     101        ipc_call_t answer_cname;
     102        char cname_buf[DNSR_NAME_MAX_SIZE + 1];
     103        aid_t req_cname = async_data_read(exch, cname_buf, DNSR_NAME_MAX_SIZE,
     104            &answer_cname);
     105       
     106        dnsr_exchange_end(exch);
     107       
     108        sysarg_t retval_cname;
     109        async_wait_for(req_cname, &retval_cname);
     110       
     111        if (retval_cname != EOK) {
     112                async_forget(req);
     113                return (int) retval_cname;
     114        }
     115       
     116        sysarg_t retval;
     117        async_wait_for(req, &retval);
     118       
     119        if (retval != EOK)
     120                return (int) retval;
     121       
     122        size_t act_size = IPC_GET_ARG2(answer_cname);
    107123        assert(act_size <= DNSR_NAME_MAX_SIZE);
     124       
    108125        cname_buf[act_size] = '\0';
    109 
     126       
    110127        info->cname = str_dup(cname_buf);
    111         info->addr.ipv4 = IPC_GET_ARG1(answer);
    112 
     128       
    113129        *rinfo = info;
    114130        return EOK;
     
    119135        if (info == NULL)
    120136                return;
    121 
     137       
    122138        free(info->cname);
    123139        free(info);
     
    126142int dnsr_get_srvaddr(inet_addr_t *srvaddr)
    127143{
    128         sysarg_t addr;
    129144        async_exch_t *exch = dnsr_exchange_begin();
    130 
    131         int rc = async_req_0_1(exch, DNSR_GET_SRVADDR, &addr);
    132         dnsr_exchange_end(exch);
    133 
    134         if (rc != EOK)
     145       
     146        ipc_call_t answer;
     147        aid_t req = async_send_0(exch, DNSR_GET_SRVADDR, &answer);
     148        int rc = async_data_read_start(exch, srvaddr, sizeof(inet_addr_t));
     149       
     150        loc_exchange_end(exch);
     151       
     152        if (rc != EOK) {
     153                async_forget(req);
    135154                return rc;
    136 
    137         srvaddr->ipv4 = addr;
    138         return EOK;
     155        }
     156       
     157        sysarg_t retval;
     158        async_wait_for(req, &retval);
     159       
     160        return (int) retval;
    139161}
    140162
     
    142164{
    143165        async_exch_t *exch = dnsr_exchange_begin();
    144 
    145         int rc = async_req_1_0(exch, DNSR_SET_SRVADDR, srvaddr->ipv4);
    146         dnsr_exchange_end(exch);
    147 
    148         if (rc != EOK)
     166       
     167        ipc_call_t answer;
     168        aid_t req = async_send_0(exch, DNSR_SET_SRVADDR, &answer);
     169        int rc = async_data_write_start(exch, srvaddr, sizeof(inet_addr_t));
     170       
     171        loc_exchange_end(exch);
     172       
     173        if (rc != EOK) {
     174                async_forget(req);
    149175                return rc;
    150 
    151         return EOK;
     176        }
     177       
     178        sysarg_t retval;
     179        async_wait_for(req, &retval);
     180       
     181        return (int) retval;
    152182}
    153183
  • uspace/lib/c/generic/inet.c

    rf2c19b0 r03c971f  
    3030#include <assert.h>
    3131#include <errno.h>
     32#include <net/socket_codes.h>
    3233#include <inet/inet.h>
    3334#include <ipc/inet.h>
     
    108109{
    109110        async_exch_t *exch = async_exchange_begin(inet_sess);
    110 
     111       
    111112        ipc_call_t answer;
    112         aid_t req = async_send_5(exch, INET_SEND, dgram->src.ipv4,
    113             dgram->dest.ipv4, dgram->tos, ttl, df, &answer);
    114         int rc = async_data_write_start(exch, dgram->data, dgram->size);
    115         async_exchange_end(exch);
    116 
    117         if (rc != EOK) {
    118                 async_forget(req);
    119                 return rc;
    120         }
    121 
     113        aid_t req = async_send_3(exch, INET_SEND, dgram->tos, ttl, df,
     114            &answer);
     115       
     116        int rc = async_data_write_start(exch, &dgram->src, sizeof(inet_addr_t));
     117        if (rc != EOK) {
     118                async_exchange_end(exch);
     119                async_forget(req);
     120                return rc;
     121        }
     122       
     123        rc = async_data_write_start(exch, &dgram->dest, sizeof(inet_addr_t));
     124        if (rc != EOK) {
     125                async_exchange_end(exch);
     126                async_forget(req);
     127                return rc;
     128        }
     129       
     130        rc = async_data_write_start(exch, dgram->data, dgram->size);
     131       
     132        async_exchange_end(exch);
     133       
     134        if (rc != EOK) {
     135                async_forget(req);
     136                return rc;
     137        }
     138       
    122139        sysarg_t retval;
    123140        async_wait_for(req, &retval);
    124         if (retval != EOK)
    125                 return retval;
    126 
    127         return EOK;
     141       
     142        return (int) retval;
    128143}
    129144
    130145int inet_get_srcaddr(inet_addr_t *remote, uint8_t tos, inet_addr_t *local)
    131146{
    132         sysarg_t local_addr;
    133         async_exch_t *exch = async_exchange_begin(inet_sess);
    134 
    135         int rc = async_req_2_1(exch, INET_GET_SRCADDR, remote->ipv4,
    136             tos, &local_addr);
    137         async_exchange_end(exch);
    138 
    139         if (rc != EOK)
    140                 return rc;
    141 
    142         local->ipv4 = local_addr;
    143         return EOK;
    144 }
    145 
    146 static void inet_ev_recv(ipc_callid_t callid, ipc_call_t *call)
    147 {
    148         int rc;
     147        async_exch_t *exch = async_exchange_begin(inet_sess);
     148       
     149        ipc_call_t answer;
     150        aid_t req = async_send_1(exch, INET_GET_SRCADDR, tos, &answer);
     151       
     152        int rc = async_data_write_start(exch, remote, sizeof(inet_addr_t));
     153        if (rc != EOK) {
     154                async_exchange_end(exch);
     155                async_forget(req);
     156                return rc;
     157        }
     158       
     159        rc = async_data_read_start(exch, local, sizeof(inet_addr_t));
     160       
     161        async_exchange_end(exch);
     162       
     163        if (rc != EOK) {
     164                async_forget(req);
     165                return rc;
     166        }
     167       
     168        sysarg_t retval;
     169        async_wait_for(req, &retval);
     170       
     171        return (int) retval;
     172}
     173
     174static void inet_ev_recv(ipc_callid_t iid, ipc_call_t *icall)
     175{
    149176        inet_dgram_t dgram;
    150 
    151         dgram.src.ipv4 = IPC_GET_ARG1(*call);
    152         dgram.dest.ipv4 = IPC_GET_ARG2(*call);
    153         dgram.tos = IPC_GET_ARG3(*call);
    154 
     177       
     178        dgram.tos = IPC_GET_ARG1(*icall);
     179       
     180        ipc_callid_t callid;
     181        size_t size;
     182        if (!async_data_write_receive(&callid, &size)) {
     183                async_answer_0(callid, EINVAL);
     184                async_answer_0(iid, EINVAL);
     185                return;
     186        }
     187       
     188        if (size != sizeof(inet_addr_t)) {
     189                async_answer_0(callid, EINVAL);
     190                async_answer_0(iid, EINVAL);
     191                return;
     192        }
     193       
     194        int rc = async_data_write_finalize(callid, &dgram.src, size);
     195        if (rc != EOK) {
     196                async_answer_0(callid, rc);
     197                async_answer_0(iid, rc);
     198                return;
     199        }
     200       
     201        if (!async_data_write_receive(&callid, &size)) {
     202                async_answer_0(callid, EINVAL);
     203                async_answer_0(iid, EINVAL);
     204                return;
     205        }
     206       
     207        if (size != sizeof(inet_addr_t)) {
     208                async_answer_0(callid, EINVAL);
     209                async_answer_0(iid, EINVAL);
     210                return;
     211        }
     212       
     213        rc = async_data_write_finalize(callid, &dgram.dest, size);
     214        if (rc != EOK) {
     215                async_answer_0(callid, rc);
     216                async_answer_0(iid, rc);
     217                return;
     218        }
     219       
    155220        rc = async_data_write_accept(&dgram.data, false, 0, 0, 0, &dgram.size);
    156221        if (rc != EOK) {
    157                 async_answer_0(callid, rc);
    158                 return;
    159         }
    160 
     222                async_answer_0(iid, rc);
     223                return;
     224        }
     225       
    161226        rc = inet_ev_ops->recv(&dgram);
    162         async_answer_0(callid, rc);
     227        async_answer_0(iid, rc);
    163228}
    164229
     
    168233                ipc_call_t call;
    169234                ipc_callid_t callid = async_get_call(&call);
    170 
     235               
    171236                if (!IPC_GET_IMETHOD(call)) {
    172237                        /* TODO: Handle hangup */
    173238                        return;
    174239                }
    175 
     240               
    176241                switch (IPC_GET_IMETHOD(call)) {
    177242                case INET_EV_RECV:
  • uspace/lib/c/generic/inet/addr.c

    rf2c19b0 r03c971f  
    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>
     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 addr48_t inet_addr48_solicited_node = {
     55        0x33, 0x33, 0xff, 0, 0, 0
     56};
     57
     58static const inet_addr_t inet_addr_any_addr = {
     59        .family = AF_INET,
     60        .addr = 0
     61};
     62
     63static const inet_addr_t inet_addr_any_addr6 = {
     64        .family = AF_INET6,
     65        .addr6 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
     66};
     67
     68void addr48(const addr48_t src, addr48_t dst)
     69{
     70        memcpy(dst, src, 6);
     71}
     72
     73void addr128(const addr128_t src, addr128_t dst)
     74{
     75        memcpy(dst, src, 16);
     76}
     77
     78int addr48_compare(const addr48_t a, const addr48_t b)
     79{
     80        return memcmp(a, b, 6);
     81}
     82
     83int addr128_compare(const addr128_t a, const addr128_t b)
     84{
     85        return memcmp(a, b, 16);
     86}
     87
     88/** Compute solicited node MAC multicast address from target IPv6 address
     89 *
     90 * @param ip  Target IPv6 address
     91 * @param mac Solicited MAC address to be assigned
     92 *
     93 */
     94void addr48_solicited_node(const addr128_t ip, addr48_t mac)
     95{
     96        memcpy(mac, inet_addr48_solicited_node, 3);
     97        memcpy(mac + 3, ip + 13, 3);
     98}
     99
     100void host2addr128_t_be(const addr128_t host, addr128_t be)
     101{
     102#ifdef __BE__
     103        memcpy(be, host, 16);
     104#else
     105        be[0] = host[15];
     106        be[1] = host[14];
     107        be[2] = host[13];
     108        be[3] = host[12];
     109        be[4] = host[11];
     110        be[5] = host[10];
     111        be[6] = host[9];
     112        be[7] = host[8];
     113        be[8] = host[7];
     114        be[9] = host[6];
     115        be[10] = host[5];
     116        be[11] = host[4];
     117        be[12] = host[3];
     118        be[13] = host[2];
     119        be[14] = host[1];
     120        be[15] = host[0];
     121#endif
     122}
     123
     124void addr128_t_be2host(const addr128_t be, addr128_t host)
     125{
     126#ifdef __BE__
     127        memcpy(host, be, 16);
     128#else
     129        host[0] = be[15];
     130        host[1] = be[14];
     131        host[2] = be[13];
     132        host[3] = be[12];
     133        host[4] = be[11];
     134        host[5] = be[10];
     135        host[6] = be[9];
     136        host[7] = be[8];
     137        host[8] = be[7];
     138        host[9] = be[6];
     139        host[10] = be[5];
     140        host[11] = be[4];
     141        host[12] = be[3];
     142        host[13] = be[2];
     143        host[14] = be[1];
     144        host[15] = be[0];
     145#endif
     146}
     147
     148void inet_addr(inet_addr_t *addr, uint8_t a, uint8_t b, uint8_t c, uint8_t d)
     149{
     150        addr->family = AF_INET;
     151        addr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
     152            ((addr32_t) c << 8) | ((addr32_t) d);
     153}
     154
     155void inet_naddr(inet_naddr_t *naddr, uint8_t a, uint8_t b, uint8_t c, uint8_t d,
     156    uint8_t prefix)
     157{
     158        naddr->family = AF_INET;
     159        naddr->addr = ((addr32_t) a << 24) | ((addr32_t) b << 16) |
     160            ((addr32_t) c << 8) | ((addr32_t) d);
     161        naddr->prefix = prefix;
     162}
     163
     164void inet_addr6(inet_addr_t *addr, uint16_t a, uint16_t b, uint16_t c,
     165    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h)
     166{
     167        addr->family = AF_INET6;
     168        addr->addr6[0] = (a >> 8) & 0xff;
     169        addr->addr6[1] = a & 0xff;
     170        addr->addr6[2] = (b >> 8) & 0xff;
     171        addr->addr6[3] = b & 0xff;
     172        addr->addr6[4] = (c >> 8) & 0xff;
     173        addr->addr6[5] = c & 0xff;
     174        addr->addr6[6] = (d >> 8) & 0xff;
     175        addr->addr6[7] = d & 0xff;
     176        addr->addr6[8] = (e >> 8) & 0xff;
     177        addr->addr6[9] = e & 0xff;
     178        addr->addr6[10] = (f >> 8) & 0xff;
     179        addr->addr6[11] = f & 0xff;
     180        addr->addr6[12] = (g >> 8) & 0xff;
     181        addr->addr6[13] = g & 0xff;
     182        addr->addr6[14] = (h >> 8) & 0xff;
     183        addr->addr6[15] = h & 0xff;
     184}
     185
     186void inet_naddr6(inet_naddr_t *naddr, uint16_t a, uint16_t b, uint16_t c,
     187    uint16_t d, uint16_t e, uint16_t f, uint16_t g, uint16_t h, uint8_t prefix)
     188{
     189        naddr->family = AF_INET6;
     190        naddr->addr6[0] = (a >> 8) & 0xff;
     191        naddr->addr6[1] = a & 0xff;
     192        naddr->addr6[2] = (b >> 8) & 0xff;
     193        naddr->addr6[3] = b & 0xff;
     194        naddr->addr6[4] = (c >> 8) & 0xff;
     195        naddr->addr6[5] = c & 0xff;
     196        naddr->addr6[6] = (d >> 8) & 0xff;
     197        naddr->addr6[7] = d & 0xff;
     198        naddr->addr6[8] = (e >> 8) & 0xff;
     199        naddr->addr6[9] = e & 0xff;
     200        naddr->addr6[10] = (f >> 8) & 0xff;
     201        naddr->addr6[11] = f & 0xff;
     202        naddr->addr6[12] = (g >> 8) & 0xff;
     203        naddr->addr6[13] = g & 0xff;
     204        naddr->addr6[14] = (h >> 8) & 0xff;
     205        naddr->addr6[15] = h & 0xff;
     206        naddr->prefix = prefix;
     207}
     208
     209/** Parse network address family.
     210 *
     211 * @param text Network address in common notation.
     212 * @param af   Place to store network address family.
     213 *
     214 * @return EOK on success, EINVAL if input is not in valid format.
     215 *
     216 */
     217int inet_addr_family(const char *text, uint16_t *af)
     218{
     219        char *dot = str_chr(text, '.');
     220        if (dot != NULL) {
     221                *af = AF_INET;
     222                return EOK;
     223        }
     224       
     225        char *collon = str_chr(text, ':');
     226        if (collon != NULL) {
     227                *af = AF_INET6;
     228                return EOK;
     229        }
     230       
     231        return EINVAL;
     232}
     233
     234void inet_naddr_addr(const inet_naddr_t *naddr, inet_addr_t *addr)
     235{
     236        addr->family = naddr->family;
     237        memcpy(addr->addr6, naddr->addr6, 16);
     238}
     239
     240void inet_addr_naddr(const inet_addr_t *addr, uint8_t prefix,
     241    inet_naddr_t *naddr)
     242{
     243        naddr->family = addr->family;
     244        memcpy(naddr->addr6, addr->addr6, 16);
     245        naddr->prefix = prefix;
     246}
     247
     248void inet_addr_any(inet_addr_t *addr)
     249{
     250        addr->family = AF_NONE;
     251        memset(addr->addr6, 0, 16);
     252}
     253
     254void inet_naddr_any(inet_naddr_t *naddr)
     255{
     256        naddr->family = AF_NONE;
     257        memset(naddr->addr6, 0, 16);
     258        naddr->prefix = 0;
     259}
     260
     261int inet_addr_compare(const inet_addr_t *a, const inet_addr_t *b)
     262{
     263        if (a->family != b->family)
     264                return 0;
     265       
     266        switch (a->family) {
     267        case AF_INET:
     268                return (a->addr == b->addr);
     269        case AF_INET6:
     270                return addr128_compare(a->addr6, b->addr6);
     271        default:
     272                return 0;
     273        }
     274}
     275
     276int inet_addr_is_any(const inet_addr_t *addr)
     277{
     278        return ((addr->family == 0) ||
     279            (inet_addr_compare(addr, &inet_addr_any_addr)) ||
     280            (inet_addr_compare(addr, &inet_addr_any_addr6)));
     281}
     282
     283int inet_naddr_compare(const inet_naddr_t *naddr, const inet_addr_t *addr)
     284{
     285        if (naddr->family != addr->family)
     286                return 0;
     287       
     288        switch (naddr->family) {
     289        case AF_INET:
     290                return (naddr->addr == addr->addr);
     291        case AF_INET6:
     292                return addr128_compare(naddr->addr6, addr->addr6);
     293        default:
     294                return 0;
     295        }
     296}
     297
     298int inet_naddr_compare_mask(const inet_naddr_t *naddr, const inet_addr_t *addr)
     299{
     300        if (naddr->family != addr->family)
     301                return 0;
     302       
     303        switch (naddr->family) {
     304        case AF_INET:
     305                if (naddr->prefix > 32)
     306                        return 0;
     307               
     308                addr32_t mask =
     309                    BIT_RANGE(addr32_t, 31, 31 - (naddr->prefix - 1));
     310                return ((naddr->addr & mask) == (addr->addr & mask));
     311        case AF_INET6:
     312                if (naddr->prefix > 128)
     313                        return 0;
     314               
     315                size_t pos = 0;
     316                for (size_t i = 0; i < 16; i++) {
     317                        /* Further bits do not matter */
     318                        if (naddr->prefix < pos)
     319                                break;
     320                       
     321                        if (naddr->prefix - pos > 8) {
     322                                /* Comparison without masking */
     323                                if (naddr->addr6[i] != addr->addr6[i])
     324                                        return 0;
     325                        } else {
     326                                /* Comparison with masking */
     327                                uint8_t mask =
     328                                    BIT_RANGE(uint8_t, 8, 8 - (naddr->prefix - pos - 1));
     329                                if ((naddr->addr6[i] & mask) != (addr->addr6[i] & mask))
     330                                        return 0;
     331                        }
     332                       
     333                        pos += 8;
     334                }
     335               
     336                return 1;
     337        default:
     338                return 0;
     339        }
     340}
     341
     342/** Parse node address.
     343 *
     344 * @param text Network address in common notation.
     345 * @param addr Place to store node address.
     346 *
     347 * @return EOK on success, EINVAL if input is not in valid format.
     348 *
     349 */
     350int inet_addr_parse(const char *text, inet_addr_t *addr)
     351{
     352        int rc = inet_addr_family(text, &addr->family);
     353        if (rc != EOK)
     354                return rc;
     355       
     356        uint8_t buf[16];
     357        rc = inet_pton(addr->family, text, buf);
     358        if (rc != EOK)
     359                return rc;
     360       
     361        switch (addr->family) {
     362        case AF_INET:
     363                addr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
     364                    buf[3];
     365                break;
     366        case AF_INET6:
     367                memcpy(addr->addr6, buf, 16);
     368                break;
     369        default:
     370                return EINVAL;
     371        }
     372       
     373        return EOK;
     374}
    38375
    39376/** Parse network address.
    40377 *
    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
     378 * @param text  Network address in common notation.
     379 * @param naddr Place to store network address.
     380 *
     381 * @return EOK on success, EINVAL if input is not in valid format.
     382 *
    45383 */
    46384int inet_naddr_parse(const char *text, inet_naddr_t *naddr)
    47385{
    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 != '.')
     386        char *slash = str_chr(text, '/');
     387        if (slash == NULL)
     388                return EINVAL;
     389       
     390        *slash = 0;
     391       
     392        int rc = inet_addr_family(text, &naddr->family);
     393        if (rc != EOK)
     394                return rc;
     395       
     396        uint8_t buf[16];
     397        rc = inet_pton(naddr->family, text, buf);
     398        *slash = '/';
     399       
     400        if (rc != EOK)
     401                return rc;
     402       
     403        slash++;
     404        uint8_t prefix;
     405       
     406        switch (naddr->family) {
     407        case AF_INET:
     408                prefix = strtoul(slash, &slash, 10);
     409                if (prefix > 32)
    55410                        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)
     411               
     412                naddr->addr = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) |
     413                    buf[3];
     414                naddr->prefix = prefix;
     415               
     416                break;
     417        case AF_INET6:
     418                prefix = strtoul(slash, &slash, 10);
     419                if (prefix > 128)
    71420                        return EINVAL;
    72                 naddr->ipv4 = (naddr->ipv4 << 8) | a[i];
    73         }
    74 
    75         if (bits > 31)
    76                 return EINVAL;
    77 
    78         naddr->bits = bits;
     421               
     422                memcpy(naddr->addr6, buf, 16);
     423                naddr->prefix = prefix;
     424               
     425                break;
     426        default:
     427                return ENOTSUP;
     428        }
     429       
    79430        return EOK;
    80431}
    81432
    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)
    124 {
    125         int rc;
    126 
    127         rc = asprintf(bufp, "%d.%d.%d.%d/%d", naddr->ipv4 >> 24,
    128             (naddr->ipv4 >> 16) & 0xff, (naddr->ipv4 >> 8) & 0xff,
    129             naddr->ipv4 & 0xff, naddr->bits);
    130 
     433/** Format node address.
     434 *
     435 * @param addr Node address.
     436 * @param bufp Place to store pointer to formatted string.
     437 *
     438 * @return EOK on success.
     439 * @return ENOMEM if out of memory.
     440 * @return ENOTSUP on unsupported address family.
     441 *
     442 */
     443int inet_addr_format(const inet_addr_t *addr, char **bufp)
     444{
     445        int rc = 0;
     446       
     447        switch (addr->family) {
     448        case AF_NONE:
     449                rc = asprintf(bufp, "none");
     450                break;
     451        case AF_INET:
     452                rc = asprintf(bufp, "%u.%u.%u.%u", (addr->addr >> 24) & 0xff,
     453                    (addr->addr >> 16) & 0xff, (addr->addr >> 8) & 0xff,
     454                    addr->addr & 0xff);
     455                break;
     456        case AF_INET6:
     457                *bufp = (char *) malloc(INET6_ADDRSTRLEN);
     458                if (*bufp == NULL)
     459                        return ENOMEM;
     460               
     461                return inet_ntop(AF_INET6, addr->addr6, *bufp, INET6_ADDRSTRLEN);
     462        default:
     463                return ENOTSUP;
     464        }
     465       
    131466        if (rc < 0)
    132467                return ENOMEM;
    133 
     468       
    134469        return EOK;
    135470}
    136471
    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)
    145 {
    146         int rc;
    147 
    148         rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
    149             (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
    150             addr->ipv4 & 0xff);
    151 
     472/** Format network address.
     473 *
     474 * @param naddr Network address.
     475 * @param bufp  Place to store pointer to formatted string.
     476 *
     477 * @return EOK on success.
     478 * @return ENOMEM if out of memory.
     479 * @return ENOTSUP on unsupported address family.
     480 *
     481 */
     482int inet_naddr_format(const inet_naddr_t *naddr, char **bufp)
     483{
     484        int rc = 0;
     485        char prefix[INET_PREFIXSTRSIZE];
     486       
     487        switch (naddr->family) {
     488        case AF_NONE:
     489                rc = asprintf(bufp, "none");
     490                break;
     491        case AF_INET:
     492                rc = asprintf(bufp, "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8
     493                    "/%" PRIu8, (naddr->addr >> 24) & 0xff,
     494                    (naddr->addr >> 16) & 0xff, (naddr->addr >> 8) & 0xff,
     495                    naddr->addr & 0xff, naddr->prefix);
     496                break;
     497        case AF_INET6:
     498                *bufp = (char *) malloc(INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
     499                if (*bufp == NULL)
     500                        return ENOMEM;
     501               
     502                rc = inet_ntop(AF_INET6, naddr->addr6, *bufp,
     503                    INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE);
     504                if (rc != EOK) {
     505                        free(*bufp);
     506                        return rc;
     507                }
     508               
     509                rc = snprintf(prefix, INET_PREFIXSTRSIZE, "/%" PRIu8,
     510                    naddr->prefix);
     511                if (rc < 0) {
     512                        free(*bufp);
     513                        return ENOMEM;
     514                }
     515               
     516                str_append(*bufp, INET6_ADDRSTRLEN + INET_PREFIXSTRSIZE, prefix);
     517               
     518                break;
     519        default:
     520                return ENOTSUP;
     521        }
     522       
    152523        if (rc < 0)
    153524                return ENOMEM;
    154 
     525       
    155526        return EOK;
    156527}
    157528
     529uint16_t inet_addr_get(const inet_addr_t *addr, addr32_t *v4, addr128_t *v6)
     530{
     531        switch (addr->family) {
     532        case AF_INET:
     533                if (v4 != NULL)
     534                        *v4 = addr->addr;
     535               
     536                break;
     537        case AF_INET6:
     538                if (v6 != NULL)
     539                        memcpy(*v6, addr->addr6, 16);
     540               
     541                break;
     542        }
     543       
     544        return addr->family;
     545}
     546
     547uint16_t inet_naddr_get(const inet_naddr_t *naddr, addr32_t *v4, addr128_t *v6,
     548    uint8_t *prefix)
     549{
     550        switch (naddr->family) {
     551        case AF_INET:
     552                if (v4 != NULL)
     553                        *v4 = naddr->addr;
     554               
     555                if (prefix != NULL)
     556                        *prefix = naddr->prefix;
     557               
     558                break;
     559        case AF_INET6:
     560                if (v6 != NULL)
     561                        memcpy(*v6, naddr->addr6, 16);
     562               
     563                if (prefix != NULL)
     564                        *prefix = naddr->prefix;
     565               
     566                break;
     567        }
     568       
     569        return naddr->family;
     570}
     571
     572void inet_addr_set(addr32_t v4, inet_addr_t *addr)
     573{
     574        addr->family = AF_INET;
     575        addr->addr = v4;
     576}
     577
     578void inet_naddr_set(addr32_t v4, uint8_t prefix, inet_naddr_t *naddr)
     579{
     580        naddr->family = AF_INET;
     581        naddr->addr = v4;
     582        naddr->prefix = prefix;
     583}
     584
     585void inet_sockaddr_in_addr(const sockaddr_in_t *sockaddr_in, inet_addr_t *addr)
     586{
     587        addr->family = AF_INET;
     588        addr->addr = uint32_t_be2host(sockaddr_in->sin_addr.s_addr);
     589}
     590
     591void inet_addr_set6(addr128_t v6, inet_addr_t *addr)
     592{
     593        addr->family = AF_INET6;
     594        memcpy(addr->addr6, v6, 16);
     595}
     596
     597void inet_naddr_set6(addr128_t v6, uint8_t prefix, inet_naddr_t *naddr)
     598{
     599        naddr->family = AF_INET6;
     600        memcpy(naddr->addr6, v6, 16);
     601        naddr->prefix = prefix;
     602}
     603
     604void inet_sockaddr_in6_addr(const sockaddr_in6_t *sockaddr_in6,
     605    inet_addr_t *addr)
     606{
     607        addr->family = AF_INET6;
     608        addr128_t_be2host(sockaddr_in6->sin6_addr.s6_addr, addr->addr6);
     609}
     610
     611uint16_t inet_addr_sockaddr_in(const inet_addr_t *addr,
     612    sockaddr_in_t *sockaddr_in, sockaddr_in6_t *sockaddr_in6)
     613{
     614        switch (addr->family) {
     615        case AF_INET:
     616                if (sockaddr_in != NULL) {
     617                        sockaddr_in->sin_family = AF_INET;
     618                        sockaddr_in->sin_addr.s_addr = host2uint32_t_be(addr->addr);
     619                }
     620               
     621                break;
     622        case AF_INET6:
     623                if (sockaddr_in6 != NULL) {
     624                        sockaddr_in6->sin6_family = AF_INET6;
     625                        host2addr128_t_be(addr->addr6, sockaddr_in6->sin6_addr.s6_addr);
     626                }
     627               
     628                break;
     629        }
     630       
     631        return addr->family;
     632}
     633
    158634/** @}
    159635 */
  • uspace/lib/c/generic/inetcfg.c

    rf2c19b0 r03c971f  
    137137{
    138138        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    139 
    140         ipc_call_t answer;
    141         aid_t req = async_send_3(exch, INETCFG_ADDR_CREATE_STATIC, naddr->ipv4,
    142             naddr->bits, link_id, &answer);
     139       
     140        ipc_call_t answer;
     141        aid_t req = async_send_1(exch, INETCFG_ADDR_CREATE_STATIC, link_id,
     142            &answer);
     143       
     144        int rc = async_data_write_start(exch, naddr, sizeof(inet_naddr_t));
     145        if (rc != EOK) {
     146                async_exchange_end(exch);
     147                async_forget(req);
     148                return rc;
     149        }
     150       
     151        rc = async_data_write_start(exch, name, str_size(name));
     152       
     153        async_exchange_end(exch);
     154       
     155        if (rc != EOK) {
     156                async_forget(req);
     157                return rc;
     158        }
     159       
     160        sysarg_t retval;
     161        async_wait_for(req, &retval);
     162       
     163        *addr_id = IPC_GET_ARG1(answer);
     164       
     165        return (int) retval;
     166}
     167
     168int inetcfg_addr_delete(sysarg_t addr_id)
     169{
     170        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
     171
     172        int rc = async_req_1_0(exch, INETCFG_ADDR_DELETE, addr_id);
     173        async_exchange_end(exch);
     174
     175        return rc;
     176}
     177
     178int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
     179{
     180        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
     181       
     182        ipc_call_t answer;
     183        aid_t req = async_send_1(exch, INETCFG_ADDR_GET, addr_id, &answer);
     184       
     185        ipc_call_t answer_naddr;
     186        aid_t req_naddr = async_data_read(exch, &ainfo->naddr,
     187            sizeof(inet_naddr_t), &answer_naddr);
     188       
     189        sysarg_t retval_naddr;
     190        async_wait_for(req_naddr, &retval_naddr);
     191       
     192        if (retval_naddr != EOK) {
     193                async_exchange_end(exch);
     194                async_forget(req);
     195                return (int) retval_naddr;
     196        }
     197       
     198        ipc_call_t answer_name;
     199        char name_buf[LOC_NAME_MAXLEN + 1];
     200        aid_t req_name = async_data_read(exch, name_buf, LOC_NAME_MAXLEN,
     201            &answer_name);
     202       
     203        async_exchange_end(exch);
     204       
     205        sysarg_t retval_name;
     206        async_wait_for(req_name, &retval_name);
     207       
     208        if (retval_name != EOK) {
     209                async_forget(req);
     210                return (int) retval_name;
     211        }
     212       
     213        sysarg_t retval;
     214        async_wait_for(req, &retval);
     215       
     216        if (retval != EOK)
     217                return (int) retval;
     218       
     219        size_t act_size = IPC_GET_ARG2(answer_name);
     220        assert(act_size <= LOC_NAME_MAXLEN);
     221       
     222        name_buf[act_size] = '\0';
     223       
     224        ainfo->ilink = IPC_GET_ARG1(answer);
     225        ainfo->name = str_dup(name_buf);
     226       
     227        return EOK;
     228}
     229
     230int inetcfg_addr_get_id(const char *name, sysarg_t link_id, sysarg_t *addr_id)
     231{
     232        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
     233
     234        ipc_call_t answer;
     235        aid_t req = async_send_1(exch, INETCFG_ADDR_GET_ID, link_id, &answer);
    143236        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
    144237
     
    156249}
    157250
    158 int inetcfg_addr_delete(sysarg_t addr_id)
    159 {
    160         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    161 
    162         int rc = async_req_1_0(exch, INETCFG_ADDR_DELETE, addr_id);
    163         async_exchange_end(exch);
    164 
    165         return rc;
    166 }
    167 
    168 int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
     251int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
     252{
     253        return inetcfg_get_ids_internal(INETCFG_GET_ADDR_LIST,
     254            0, addrs, count);
     255}
     256
     257int inetcfg_get_link_list(sysarg_t **links, size_t *count)
     258{
     259        return inetcfg_get_ids_internal(INETCFG_GET_LINK_LIST,
     260            0, links, count);
     261}
     262
     263int inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
     264{
     265        return inetcfg_get_ids_internal(INETCFG_GET_SROUTE_LIST,
     266            0, sroutes, count);
     267}
     268
     269int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
    169270{
    170271        ipc_call_t dreply;
     
    176277
    177278        ipc_call_t answer;
    178         aid_t req = async_send_1(exch, INETCFG_ADDR_GET, addr_id, &answer);
     279        aid_t req = async_send_1(exch, INETCFG_LINK_GET, link_id, &answer);
    179280        aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
    180281        async_wait_for(dreq, &dretval);
     
    197298        name_buf[act_size] = '\0';
    198299
    199         ainfo->naddr.ipv4 = IPC_GET_ARG1(answer);
    200         ainfo->naddr.bits = IPC_GET_ARG2(answer);
    201         ainfo->ilink = IPC_GET_ARG3(answer);
    202         ainfo->name = str_dup(name_buf);
    203 
    204         return EOK;
    205 }
    206 
    207 int inetcfg_addr_get_id(const char *name, sysarg_t link_id, sysarg_t *addr_id)
    208 {
    209         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    210 
    211         ipc_call_t answer;
    212         aid_t req = async_send_1(exch, INETCFG_ADDR_GET_ID, link_id, &answer);
    213         sysarg_t retval = async_data_write_start(exch, name, str_size(name));
    214 
    215         async_exchange_end(exch);
    216 
    217         if (retval != EOK) {
    218                 async_forget(req);
    219                 return retval;
    220         }
    221 
    222         async_wait_for(req, &retval);
    223         *addr_id = IPC_GET_ARG1(answer);
    224 
    225         return retval;
    226 }
    227 
    228 int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
    229 {
    230         return inetcfg_get_ids_internal(INETCFG_GET_ADDR_LIST,
    231             0, addrs, count);
    232 }
    233 
    234 int inetcfg_get_link_list(sysarg_t **links, size_t *count)
    235 {
    236         return inetcfg_get_ids_internal(INETCFG_GET_LINK_LIST,
    237             0, links, count);
    238 }
    239 
    240 int inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
    241 {
    242         return inetcfg_get_ids_internal(INETCFG_GET_SROUTE_LIST,
    243             0, sroutes, count);
    244 }
    245 
    246 int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
    247 {
    248         ipc_call_t dreply;
    249         sysarg_t dretval;
    250         size_t act_size;
    251         char name_buf[LOC_NAME_MAXLEN + 1];
    252 
    253         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    254 
    255         ipc_call_t answer;
    256         aid_t req = async_send_1(exch, INETCFG_LINK_GET, link_id, &answer);
    257         aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
    258         async_wait_for(dreq, &dretval);
    259 
    260         async_exchange_end(exch);
    261 
    262         if (dretval != EOK) {
    263                 async_forget(req);
    264                 return dretval;
    265         }
    266 
    267         sysarg_t retval;
    268         async_wait_for(req, &retval);
    269 
    270         if (retval != EOK)
    271                 return retval;
    272 
    273         act_size = IPC_GET_ARG2(dreply);
    274         assert(act_size <= LOC_NAME_MAXLEN);
    275         name_buf[act_size] = '\0';
    276 
    277300        linfo->name = str_dup(name_buf);
    278301        linfo->def_mtu = IPC_GET_ARG1(answer);
     
    285308{
    286309        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    287 
    288         ipc_call_t answer;
    289         aid_t req = async_send_3(exch, INETCFG_SROUTE_CREATE,
    290             dest->ipv4, dest->bits, router->ipv4, &answer);
    291         sysarg_t retval = async_data_write_start(exch, name, str_size(name));
    292 
    293         async_exchange_end(exch);
    294 
    295         if (retval != EOK) {
    296                 async_forget(req);
    297                 return retval;
    298         }
    299 
    300         async_wait_for(req, &retval);
     310       
     311        ipc_call_t answer;
     312        aid_t req = async_send_0(exch, INETCFG_SROUTE_CREATE, &answer);
     313       
     314        int rc = async_data_write_start(exch, dest, sizeof(inet_naddr_t));
     315        if (rc != EOK) {
     316                async_exchange_end(exch);
     317                async_forget(req);
     318                return rc;
     319        }
     320       
     321        rc = async_data_write_start(exch, router, sizeof(inet_addr_t));
     322        if (rc != EOK) {
     323                async_exchange_end(exch);
     324                async_forget(req);
     325                return rc;
     326        }
     327       
     328        rc = async_data_write_start(exch, name, str_size(name));
     329       
     330        async_exchange_end(exch);
     331       
     332        if (rc != EOK) {
     333                async_forget(req);
     334                return rc;
     335        }
     336       
     337        sysarg_t retval;
     338        async_wait_for(req, &retval);
     339       
    301340        *sroute_id = IPC_GET_ARG1(answer);
    302 
    303         return retval;
     341       
     342        return (int) retval;
    304343}
    305344
     
    316355int inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
    317356{
    318         ipc_call_t dreply;
    319         sysarg_t dretval;
    320         size_t act_size;
     357        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
     358       
     359        ipc_call_t answer;
     360        aid_t req = async_send_1(exch, INETCFG_SROUTE_GET, sroute_id, &answer);
     361       
     362        ipc_call_t answer_dest;
     363        aid_t req_dest = async_data_read(exch, &srinfo->dest,
     364            sizeof(inet_naddr_t), &answer_dest);
     365       
     366        sysarg_t retval_dest;
     367        async_wait_for(req_dest, &retval_dest);
     368       
     369        if (retval_dest != EOK) {
     370                async_exchange_end(exch);
     371                async_forget(req);
     372                return (int) retval_dest;
     373        }
     374       
     375        ipc_call_t answer_router;
     376        aid_t req_router = async_data_read(exch, &srinfo->router,
     377            sizeof(inet_addr_t), &answer_router);
     378       
     379        sysarg_t retval_router;
     380        async_wait_for(req_router, &retval_router);
     381       
     382        if (retval_router != EOK) {
     383                async_exchange_end(exch);
     384                async_forget(req);
     385                return (int) retval_router;
     386        }
     387       
     388        ipc_call_t answer_name;
    321389        char name_buf[LOC_NAME_MAXLEN + 1];
    322 
    323         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    324 
    325         ipc_call_t answer;
    326         aid_t req = async_send_1(exch, INETCFG_SROUTE_GET, sroute_id, &answer);
    327         aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
    328         async_wait_for(dreq, &dretval);
    329 
    330         async_exchange_end(exch);
    331 
    332         if (dretval != EOK) {
    333                 async_forget(req);
    334                 return dretval;
    335         }
    336 
    337         sysarg_t retval;
    338         async_wait_for(req, &retval);
    339 
     390        aid_t req_name = async_data_read(exch, name_buf, LOC_NAME_MAXLEN,
     391            &answer_name);
     392       
     393        async_exchange_end(exch);
     394       
     395        sysarg_t retval_name;
     396        async_wait_for(req_name, &retval_name);
     397       
     398        if (retval_name != EOK) {
     399                async_forget(req);
     400                return (int) retval_name;
     401        }
     402       
     403        sysarg_t retval;
     404        async_wait_for(req, &retval);
     405       
    340406        if (retval != EOK)
    341                 return retval;
    342 
    343         act_size = IPC_GET_ARG2(dreply);
     407                return (int) retval;
     408       
     409        size_t act_size = IPC_GET_ARG2(answer_name);
    344410        assert(act_size <= LOC_NAME_MAXLEN);
     411       
    345412        name_buf[act_size] = '\0';
    346 
    347         srinfo->dest.ipv4 = IPC_GET_ARG1(answer);
    348         srinfo->dest.bits = IPC_GET_ARG2(answer);
    349         srinfo->router.ipv4 = IPC_GET_ARG3(answer);
     413       
    350414        srinfo->name = str_dup(name_buf);
    351 
     415       
    352416        return EOK;
    353417}
  • uspace/lib/c/generic/inetping.c

    rf2c19b0 r03c971f  
    7979{
    8080        async_exch_t *exch = async_exchange_begin(inetping_sess);
    81 
     81       
    8282        ipc_call_t answer;
    83         aid_t req = async_send_3(exch, INETPING_SEND, sdu->src.ipv4,
    84             sdu->dest.ipv4, sdu->seq_no, &answer);
     83        aid_t req = async_send_3(exch, INETPING_SEND, (sysarg_t) sdu->src,
     84            (sysarg_t) sdu->dest, sdu->seq_no, &answer);
    8585        sysarg_t retval = async_data_write_start(exch, sdu->data, sdu->size);
    86 
     86       
    8787        async_exchange_end(exch);
    88 
     88       
    8989        if (retval != EOK) {
    9090                async_forget(req);
    9191                return retval;
    9292        }
    93 
     93       
    9494        async_wait_for(req, &retval);
    9595        return retval;
    9696}
    9797
    98 int inetping_get_srcaddr(inet_addr_t *remote, inet_addr_t *local)
     98int inetping_get_srcaddr(uint32_t remote, uint32_t *local)
    9999{
     100        async_exch_t *exch = async_exchange_begin(inetping_sess);
     101       
    100102        sysarg_t local_addr;
    101         async_exch_t *exch = async_exchange_begin(inetping_sess);
    102 
    103         int rc = async_req_1_1(exch, INETPING_GET_SRCADDR, remote->ipv4,
     103        int rc = async_req_1_1(exch, INETPING_GET_SRCADDR, (sysarg_t) remote,
    104104            &local_addr);
     105       
    105106        async_exchange_end(exch);
    106 
     107       
    107108        if (rc != EOK)
    108109                return rc;
    109 
    110         local->ipv4 = local_addr;
     110       
     111        *local = (uint32_t) local_addr;
    111112        return EOK;
    112113}
     
    114115static void inetping_ev_recv(ipc_callid_t callid, ipc_call_t *call)
    115116{
    116         int rc;
    117117        inetping_sdu_t sdu;
    118 
    119         sdu.src.ipv4 = IPC_GET_ARG1(*call);
    120         sdu.dest.ipv4 = IPC_GET_ARG2(*call);
     118       
     119        sdu.src = IPC_GET_ARG1(*call);
     120        sdu.dest = IPC_GET_ARG2(*call);
    121121        sdu.seq_no = IPC_GET_ARG3(*call);
    122 
    123         rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
     122       
     123        int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
    124124        if (rc != EOK) {
    125125                async_answer_0(callid, rc);
    126126                return;
    127127        }
    128 
     128       
    129129        rc = inetping_ev_ops->recv(&sdu);
    130130        free(sdu.data);
  • uspace/lib/c/generic/io/io.c

    rf2c19b0 r03c971f  
    192192}
    193193
     194/** Set stream buffer.
     195 *
     196 * When @p buf is NULL, the stream is set as unbuffered, otherwise
     197 * full buffering is enabled.
     198 */
     199void setbuf(FILE *stream, void *buf)
     200{
     201        if (buf == NULL) {
     202                setvbuf(stream, NULL, _IONBF, BUFSIZ);
     203        } else {
     204                setvbuf(stream, buf, _IOFBF, BUFSIZ);
     205        }
     206}
     207
    194208static void _setvbuf(FILE *stream)
    195209{
  • uspace/lib/c/generic/iplink.c

    rf2c19b0 r03c971f  
    3939#include <errno.h>
    4040#include <inet/iplink.h>
     41#include <inet/addr.h>
    4142#include <ipc/iplink.h>
    4243#include <ipc/services.h>
     
    8384{
    8485        async_exch_t *exch = async_exchange_begin(iplink->sess);
    85 
    86         ipc_call_t answer;
    87         aid_t req = async_send_2(exch, IPLINK_SEND, sdu->lsrc.ipv4,
    88             sdu->ldest.ipv4, &answer);
     86       
     87        ipc_call_t answer;
     88        aid_t req = async_send_2(exch, IPLINK_SEND, (sysarg_t) sdu->src,
     89            (sysarg_t) sdu->dest, &answer);
     90       
    8991        int rc = async_data_write_start(exch, sdu->data, sdu->size);
    90         async_exchange_end(exch);
    91 
    92         if (rc != EOK) {
    93                 async_forget(req);
    94                 return rc;
    95         }
    96 
    97         sysarg_t retval;
    98         async_wait_for(req, &retval);
    99         if (retval != EOK)
    100                 return retval;
    101 
    102         return EOK;
     92       
     93        async_exchange_end(exch);
     94       
     95        if (rc != EOK) {
     96                async_forget(req);
     97                return rc;
     98        }
     99       
     100        sysarg_t retval;
     101        async_wait_for(req, &retval);
     102       
     103        return (int) retval;
     104}
     105
     106int iplink_send6(iplink_t *iplink, iplink_sdu6_t *sdu)
     107{
     108        async_exch_t *exch = async_exchange_begin(iplink->sess);
     109       
     110        ipc_call_t answer;
     111        aid_t req = async_send_0(exch, IPLINK_SEND6, &answer);
     112       
     113        int rc = async_data_write_start(exch, &sdu->dest, sizeof(addr48_t));
     114        if (rc != EOK) {
     115                async_exchange_end(exch);
     116                async_forget(req);
     117                return rc;
     118        }
     119       
     120        rc = async_data_write_start(exch, sdu->data, sdu->size);
     121       
     122        async_exchange_end(exch);
     123       
     124        if (rc != EOK) {
     125                async_forget(req);
     126                return rc;
     127        }
     128       
     129        sysarg_t retval;
     130        async_wait_for(req, &retval);
     131       
     132        return (int) retval;
    103133}
    104134
    105135int iplink_get_mtu(iplink_t *iplink, size_t *rmtu)
    106136{
     137        async_exch_t *exch = async_exchange_begin(iplink->sess);
     138       
    107139        sysarg_t mtu;
    108         async_exch_t *exch = async_exchange_begin(iplink->sess);
    109 
    110140        int rc = async_req_0_1(exch, IPLINK_GET_MTU, &mtu);
    111         async_exchange_end(exch);
    112 
     141       
     142        async_exchange_end(exch);
     143       
    113144        if (rc != EOK)
    114145                return rc;
    115 
     146       
    116147        *rmtu = mtu;
    117148        return EOK;
    118149}
    119150
    120 int iplink_addr_add(iplink_t *iplink, iplink_addr_t *addr)
    121 {
    122         async_exch_t *exch = async_exchange_begin(iplink->sess);
    123 
    124         int rc = async_req_1_0(exch, IPLINK_ADDR_ADD, (sysarg_t)addr->ipv4);
    125         async_exchange_end(exch);
    126 
    127         return rc;
    128 }
    129 
    130 int iplink_addr_remove(iplink_t *iplink, iplink_addr_t *addr)
    131 {
    132         async_exch_t *exch = async_exchange_begin(iplink->sess);
    133 
    134         int rc = async_req_1_0(exch, IPLINK_ADDR_REMOVE, (sysarg_t)addr->ipv4);
    135         async_exchange_end(exch);
    136 
    137         return rc;
    138 }
    139 
    140 static void iplink_ev_recv(iplink_t *iplink, ipc_callid_t callid,
    141     ipc_call_t *call)
    142 {
    143         int rc;
    144         iplink_sdu_t sdu;
    145 
    146         sdu.lsrc.ipv4 = IPC_GET_ARG1(*call);
    147         sdu.ldest.ipv4 = IPC_GET_ARG2(*call);
    148 
    149         rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
    150         if (rc != EOK) {
    151                 async_answer_0(callid, rc);
     151int iplink_get_mac48(iplink_t *iplink, addr48_t *mac)
     152{
     153        async_exch_t *exch = async_exchange_begin(iplink->sess);
     154       
     155        ipc_call_t answer;
     156        aid_t req = async_send_0(exch, IPLINK_GET_MAC48, &answer);
     157       
     158        int rc = async_data_read_start(exch, mac, sizeof(addr48_t));
     159       
     160        loc_exchange_end(exch);
     161       
     162        if (rc != EOK) {
     163                async_forget(req);
     164                return rc;
     165        }
     166       
     167        sysarg_t retval;
     168        async_wait_for(req, &retval);
     169       
     170        return (int) retval;
     171}
     172
     173int iplink_addr_add(iplink_t *iplink, inet_addr_t *addr)
     174{
     175        async_exch_t *exch = async_exchange_begin(iplink->sess);
     176       
     177        ipc_call_t answer;
     178        aid_t req = async_send_0(exch, IPLINK_ADDR_ADD, &answer);
     179       
     180        int rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
     181        async_exchange_end(exch);
     182       
     183        if (rc != EOK) {
     184                async_forget(req);
     185                return rc;
     186        }
     187       
     188        sysarg_t retval;
     189        async_wait_for(req, &retval);
     190       
     191        return (int) retval;
     192}
     193
     194int iplink_addr_remove(iplink_t *iplink, inet_addr_t *addr)
     195{
     196        async_exch_t *exch = async_exchange_begin(iplink->sess);
     197       
     198        ipc_call_t answer;
     199        aid_t req = async_send_0(exch, IPLINK_ADDR_REMOVE, &answer);
     200       
     201        int rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
     202        async_exchange_end(exch);
     203       
     204        if (rc != EOK) {
     205                async_forget(req);
     206                return rc;
     207        }
     208       
     209        sysarg_t retval;
     210        async_wait_for(req, &retval);
     211       
     212        return (int) retval;
     213}
     214
     215static void iplink_ev_recv(iplink_t *iplink, ipc_callid_t iid,
     216    ipc_call_t *icall)
     217{
     218        iplink_recv_sdu_t sdu;
     219       
     220        uint16_t af = IPC_GET_ARG1(*icall);
     221       
     222        int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     223            &sdu.size);
     224        if (rc != EOK) {
     225                async_answer_0(iid, rc);
    152226                return;
    153227        }
    154 
    155         rc = iplink->ev_ops->recv(iplink, &sdu);
     228       
     229        rc = iplink->ev_ops->recv(iplink, &sdu, af);
    156230        free(sdu.data);
    157         async_answer_0(callid, rc);
     231        async_answer_0(iid, rc);
    158232}
    159233
    160234static void iplink_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    161235{
    162         iplink_t *iplink = (iplink_t *)arg;
    163 
     236        iplink_t *iplink = (iplink_t *) arg;
     237       
    164238        while (true) {
    165239                ipc_call_t call;
    166240                ipc_callid_t callid = async_get_call(&call);
    167 
     241               
    168242                if (!IPC_GET_IMETHOD(call)) {
    169243                        /* TODO: Handle hangup */
    170244                        return;
    171245                }
    172 
     246               
    173247                switch (IPC_GET_IMETHOD(call)) {
    174248                case IPLINK_EV_RECV:
  • uspace/lib/c/generic/iplink_srv.c

    rf2c19b0 r03c971f  
    3434 * @brief IP link server stub
    3535 */
     36
    3637#include <errno.h>
    3738#include <ipc/iplink.h>
    3839#include <stdlib.h>
    3940#include <sys/types.h>
    40 
     41#include <inet/addr.h>
    4142#include <inet/iplink_srv.h>
    4243
     
    4445    ipc_call_t *call)
    4546{
    46         int rc;
    4747        size_t mtu;
    48 
    49         rc = srv->ops->get_mtu(srv, &mtu);
     48        int rc = srv->ops->get_mtu(srv, &mtu);
    5049        async_answer_1(callid, rc, mtu);
    5150}
    5251
    53 static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t callid,
    54     ipc_call_t *call)
    55 {
    56         int rc;
    57         iplink_srv_addr_t addr;
    58 
    59         addr.ipv4 = IPC_GET_ARG1(*call);
    60 
     52static void iplink_get_mac48_srv(iplink_srv_t *srv, ipc_callid_t iid,
     53    ipc_call_t *icall)
     54{
     55        addr48_t mac;
     56        int rc = srv->ops->get_mac48(srv, &mac);
     57        if (rc != EOK) {
     58                async_answer_0(iid, rc);
     59                return;
     60        }
     61       
     62        ipc_callid_t callid;
     63        size_t size;
     64        if (!async_data_read_receive(&callid, &size)) {
     65                async_answer_0(callid, EREFUSED);
     66                async_answer_0(iid, EREFUSED);
     67                return;
     68        }
     69       
     70        if (size != sizeof(addr48_t)) {
     71                async_answer_0(callid, EINVAL);
     72                async_answer_0(iid, EINVAL);
     73                return;
     74        }
     75       
     76        rc = async_data_read_finalize(callid, &mac, size);
     77        if (rc != EOK)
     78                async_answer_0(callid, rc);
     79       
     80        async_answer_0(iid, (sysarg_t) rc);
     81}
     82
     83static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t iid,
     84    ipc_call_t *icall)
     85{
     86        ipc_callid_t callid;
     87        size_t size;
     88        if (!async_data_write_receive(&callid, &size)) {
     89                async_answer_0(callid, EREFUSED);
     90                async_answer_0(iid, EREFUSED);
     91                return;
     92        }
     93       
     94        if (size != sizeof(inet_addr_t)) {
     95                async_answer_0(callid, EINVAL);
     96                async_answer_0(iid, EINVAL);
     97                return;
     98        }
     99       
     100        inet_addr_t addr;
     101        int rc = async_data_write_finalize(callid, &addr, size);
     102        if (rc != EOK) {
     103                async_answer_0(callid, (sysarg_t) rc);
     104                async_answer_0(iid, (sysarg_t) rc);
     105        }
     106       
    61107        rc = srv->ops->addr_add(srv, &addr);
    62         async_answer_0(callid, rc);
    63 }
    64 
    65 static void iplink_addr_remove_srv(iplink_srv_t *srv, ipc_callid_t callid,
    66     ipc_call_t *call)
    67 {
    68         int rc;
    69         iplink_srv_addr_t addr;
    70 
    71         addr.ipv4 = IPC_GET_ARG1(*call);
    72 
     108        async_answer_0(iid, (sysarg_t) rc);
     109}
     110
     111static void iplink_addr_remove_srv(iplink_srv_t *srv, ipc_callid_t iid,
     112    ipc_call_t *icall)
     113{
     114        ipc_callid_t callid;
     115        size_t size;
     116        if (!async_data_write_receive(&callid, &size)) {
     117                async_answer_0(callid, EREFUSED);
     118                async_answer_0(iid, EREFUSED);
     119                return;
     120        }
     121       
     122        if (size != sizeof(inet_addr_t)) {
     123                async_answer_0(callid, EINVAL);
     124                async_answer_0(iid, EINVAL);
     125                return;
     126        }
     127       
     128        inet_addr_t addr;
     129        int rc = async_data_write_finalize(callid, &addr, size);
     130        if (rc != EOK) {
     131                async_answer_0(callid, (sysarg_t) rc);
     132                async_answer_0(iid, (sysarg_t) rc);
     133        }
     134       
    73135        rc = srv->ops->addr_remove(srv, &addr);
    74         async_answer_0(callid, rc);
    75 }
    76 
    77 static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t callid,
    78     ipc_call_t *call)
    79 {
    80         iplink_srv_sdu_t sdu;
    81         int rc;
    82 
    83         sdu.lsrc.ipv4 = IPC_GET_ARG1(*call);
    84         sdu.ldest.ipv4 = IPC_GET_ARG2(*call);
    85 
    86         rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
    87         if (rc != EOK) {
    88                 async_answer_0(callid, rc);
    89                 return;
    90         }
    91 
     136        async_answer_0(iid, (sysarg_t) rc);
     137}
     138
     139static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t iid,
     140    ipc_call_t *icall)
     141{
     142        iplink_sdu_t sdu;
     143       
     144        sdu.src = IPC_GET_ARG1(*icall);
     145        sdu.dest = IPC_GET_ARG2(*icall);
     146       
     147        int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     148            &sdu.size);
     149        if (rc != EOK) {
     150                async_answer_0(iid, rc);
     151                return;
     152        }
     153       
    92154        rc = srv->ops->send(srv, &sdu);
    93155        free(sdu.data);
    94         async_answer_0(callid, rc);
     156        async_answer_0(iid, rc);
     157}
     158
     159static void iplink_send6_srv(iplink_srv_t *srv, ipc_callid_t iid,
     160    ipc_call_t *icall)
     161{
     162        iplink_sdu6_t sdu;
     163       
     164        ipc_callid_t callid;
     165        size_t size;
     166        if (!async_data_write_receive(&callid, &size)) {
     167                async_answer_0(callid, EREFUSED);
     168                async_answer_0(iid, EREFUSED);
     169                return;
     170        }
     171       
     172        if (size != sizeof(addr48_t)) {
     173                async_answer_0(callid, EINVAL);
     174                async_answer_0(iid, EINVAL);
     175                return;
     176        }
     177       
     178        int rc = async_data_write_finalize(callid, &sdu.dest, size);
     179        if (rc != EOK) {
     180                async_answer_0(callid, (sysarg_t) rc);
     181                async_answer_0(iid, (sysarg_t) rc);
     182        }
     183       
     184        rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     185            &sdu.size);
     186        if (rc != EOK) {
     187                async_answer_0(iid, rc);
     188                return;
     189        }
     190       
     191        rc = srv->ops->send6(srv, &sdu);
     192        free(sdu.data);
     193        async_answer_0(iid, rc);
    95194}
    96195
     
    106205int iplink_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    107206{
    108         iplink_srv_t *srv = (iplink_srv_t *)arg;
     207        iplink_srv_t *srv = (iplink_srv_t *) arg;
    109208        int rc;
    110 
     209       
    111210        fibril_mutex_lock(&srv->lock);
    112211        if (srv->connected) {
     
    115214                return EBUSY;
    116215        }
    117 
     216       
    118217        srv->connected = true;
    119218        fibril_mutex_unlock(&srv->lock);
    120 
     219       
    121220        /* Accept the connection */
    122221        async_answer_0(iid, EOK);
    123 
     222       
    124223        async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
    125224        if (sess == NULL)
    126225                return ENOMEM;
    127 
     226       
    128227        srv->client_sess = sess;
    129 
     228       
    130229        rc = srv->ops->open(srv);
    131230        if (rc != EOK)
    132231                return rc;
    133 
     232       
    134233        while (true) {
    135234                ipc_call_t call;
    136235                ipc_callid_t callid = async_get_call(&call);
    137236                sysarg_t method = IPC_GET_IMETHOD(call);
    138 
     237               
    139238                if (!method) {
    140239                        /* The other side has hung up */
    141                         fibril_mutex_lock(&srv->lock);
     240                        fibril_mutex_lock(&srv->lock);
    142241                        srv->connected = false;
    143                         fibril_mutex_unlock(&srv->lock);
     242                        fibril_mutex_unlock(&srv->lock);
    144243                        async_answer_0(callid, EOK);
    145244                        break;
    146245                }
    147 
     246               
    148247                switch (method) {
    149248                case IPLINK_GET_MTU:
    150249                        iplink_get_mtu_srv(srv, callid, &call);
    151250                        break;
     251                case IPLINK_GET_MAC48:
     252                        iplink_get_mac48_srv(srv, callid, &call);
     253                        break;
    152254                case IPLINK_SEND:
    153255                        iplink_send_srv(srv, callid, &call);
     256                        break;
     257                case IPLINK_SEND6:
     258                        iplink_send6_srv(srv, callid, &call);
    154259                        break;
    155260                case IPLINK_ADDR_ADD:
     
    163268                }
    164269        }
    165 
     270       
    166271        return srv->ops->close(srv);
    167272}
    168273
    169 int iplink_ev_recv(iplink_srv_t *srv, iplink_srv_sdu_t *sdu)
     274int iplink_ev_recv(iplink_srv_t *srv, iplink_recv_sdu_t *sdu, uint16_t af)
    170275{
    171276        if (srv->client_sess == NULL)
    172277                return EIO;
    173 
     278       
    174279        async_exch_t *exch = async_exchange_begin(srv->client_sess);
    175 
     280       
    176281        ipc_call_t answer;
    177         aid_t req = async_send_2(exch, IPLINK_EV_RECV, sdu->lsrc.ipv4,
    178             sdu->ldest.ipv4, &answer);
     282        aid_t req = async_send_1(exch, IPLINK_EV_RECV, (sysarg_t) af,
     283            &answer);
     284       
    179285        int rc = async_data_write_start(exch, sdu->data, sdu->size);
    180286        async_exchange_end(exch);
    181 
     287       
    182288        if (rc != EOK) {
    183289                async_forget(req);
    184290                return rc;
    185291        }
    186 
     292       
    187293        sysarg_t retval;
    188294        async_wait_for(req, &retval);
    189295        if (retval != EOK)
    190296                return retval;
    191 
     297       
    192298        return EOK;
    193299}
  • uspace/lib/c/generic/net/inet.c

    rf2c19b0 r03c971f  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2013 Martin Decky
    33 * All rights reserved.
    44 *
     
    3939#include <net/in6.h>
    4040#include <net/inet.h>
    41 
     41#include <inet/addr.h>
    4242#include <errno.h>
    4343#include <mem.h>
     
    4545#include <str.h>
    4646
     47const in6_addr_t in6addr_any = {
     48        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
     49};
     50
     51static int inet_ntop4(const uint8_t *data, char *address, size_t length)
     52{
     53        /* Check output buffer size */
     54        if (length < INET_ADDRSTRLEN)
     55                return ENOMEM;
     56       
     57        /* Fill buffer with IPv4 address */
     58        snprintf(address, length,
     59            "%" PRIu8 ".%" PRIu8 ".%" PRIu8 ".%" PRIu8,
     60            data[0], data[1], data[2], data[3]);
     61       
     62        return EOK;
     63}
     64
     65static int inet_ntop6(const uint8_t *data, char *address, size_t length)
     66{
     67        /* Check output buffer size */
     68        if (length < INET6_ADDRSTRLEN)
     69                return ENOMEM;
     70       
     71        /* Find the longest zero subsequence */
     72       
     73        uint16_t zeroes[8];
     74        uint16_t bioctets[8];
     75       
     76        for (size_t i = 8; i > 0; i--) {
     77                size_t j = i - 1;
     78               
     79                bioctets[j] = (data[j << 1] << 8) | data[(j << 1) + 1];
     80               
     81                if (bioctets[j] == 0) {
     82                        zeroes[j] = 1;
     83                        if (j < 7)
     84                                zeroes[j] += zeroes[j + 1];
     85                } else
     86                        zeroes[j] = 0;
     87        }
     88       
     89        size_t wildcard_pos = (size_t) -1;
     90        size_t wildcard_size = 0;
     91       
     92        for (size_t i = 0; i < 8; i++) {
     93                if (zeroes[i] > wildcard_size) {
     94                        wildcard_pos = i;
     95                        wildcard_size = zeroes[i];
     96                }
     97        }
     98       
     99        char *cur = address;
     100        size_t rest = length;
     101        bool tail_zero = false;
     102        int ret;
     103       
     104        for (size_t i = 0; i < 8; i++) {
     105                if ((i == wildcard_pos) && (wildcard_size > 1)) {
     106                        ret = snprintf(cur, rest, ":");
     107                        i += wildcard_size - 1;
     108                        tail_zero = true;
     109                } else if (i == 0) {
     110                        ret = snprintf(cur, rest, "%" PRIx16, bioctets[i]);
     111                        tail_zero = false;
     112                } else {
     113                        ret = snprintf(cur, rest, ":%" PRIx16, bioctets[i]);
     114                        tail_zero = false;
     115                }
     116               
     117                if (ret < 0)
     118                        return EINVAL;
     119               
     120                cur += ret;
     121                rest -= ret;
     122        }
     123       
     124        if (tail_zero) {
     125                ret = snprintf(cur, rest, ":");
     126                if (ret < 0)
     127                        return EINVAL;
     128        }
     129       
     130        return EOK;
     131}
     132
    47133/** Prints the address into the character buffer.
    48134 *
    49  *  @param[in] family   The address family.
    50  *  @param[in] data     The address data.
    51  *  @param[out] address The character buffer to be filled.
    52  *  @param[in] length   The buffer length.
    53  *  @return             EOK on success.
    54  *  @return             EINVAL if the data or address parameter is NULL.
    55  *  @return             ENOMEM if the character buffer is not long enough.
    56  *  @return             ENOTSUP if the address family is not supported.
    57  */
    58 int
    59 inet_ntop(uint16_t family, const uint8_t *data, char *address, size_t length)
    60 {
    61         if ((!data) || (!address))
    62                 return EINVAL;
    63 
     135 * @param[in]  family  Address family.
     136 * @param[in]  data    Address data.
     137 * @param[out] address Character buffer to be filled.
     138 * @param[in]  length  Buffer length.
     139 *
     140 * @return EOK on success.
     141 * @return EINVAL if the data or address parameter is NULL.
     142 * @return ENOMEM if the character buffer is not long enough.
     143 * @return ENOTSUP if the address family is not supported.
     144 *
     145 */
     146int inet_ntop(uint16_t family, const uint8_t *data, char *address, size_t length)
     147{
    64148        switch (family) {
    65149        case AF_INET:
    66                 /* Check output buffer size */
    67                 if (length < INET_ADDRSTRLEN)
    68                         return ENOMEM;
    69                        
    70                 /* Fill buffer with IPv4 address */
    71                 snprintf(address, length, "%hhu.%hhu.%hhu.%hhu",
    72                     data[0], data[1], data[2], data[3]);
    73 
    74                 return EOK;
    75 
     150                return inet_ntop4(data, address, length);
    76151        case AF_INET6:
    77                 /* Check output buffer size */
    78                 if (length < INET6_ADDRSTRLEN)
    79                         return ENOMEM;
    80                
    81                 /* Fill buffer with IPv6 address */
    82                 snprintf(address, length,
    83                     "%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:"
    84                     "%hhx%hhx:%hhx%hhx",
    85                     data[0], data[1], data[2], data[3], data[4], data[5],
    86                     data[6], data[7], data[8], data[9], data[10], data[11],
    87                     data[12], data[13], data[14], data[15]);
    88                
    89                 return EOK;
    90 
     152                return inet_ntop6(data, address, length);
    91153        default:
    92154                return ENOTSUP;
     
    94156}
    95157
     158static int inet_pton4(const char *address, uint8_t *data)
     159{
     160        memset(data, 0, 4);
     161       
     162        const char *cur = address;
     163        size_t i = 0;
     164       
     165        while (i < 4) {
     166                int rc = str_uint8_t(cur, &cur, 10, false, &data[i]);
     167                if (rc != EOK)
     168                        return rc;
     169               
     170                i++;
     171               
     172                if (*cur == 0)
     173                        break;
     174               
     175                if (*cur != '.')
     176                        return EINVAL;
     177               
     178                if (i < 4)
     179                        cur++;
     180        }
     181       
     182        if ((i == 4) && (*cur != 0))
     183                return EINVAL;
     184       
     185        return EOK;
     186}
     187
     188static int inet_pton6(const char *address, uint8_t *data)
     189{
     190        memset(data, 0, 16);
     191       
     192        const char *cur = address;
     193        size_t i = 0;
     194        size_t wildcard_pos = (size_t) -1;
     195        size_t wildcard_size = 0;
     196       
     197        /* Handle initial wildcard */
     198        if ((address[0] == ':') && (address[1] == ':')) {
     199                cur = address + 2;
     200                wildcard_pos = 0;
     201                wildcard_size = 16;
     202               
     203                /* Handle empty address */
     204                if (*cur == 0)
     205                        return EOK;
     206        }
     207       
     208        while (i < 16) {
     209                uint16_t bioctet;
     210                int rc = str_uint16_t(cur, &cur, 16, false, &bioctet);
     211                if (rc != EOK)
     212                        return rc;
     213               
     214                data[i] = (bioctet >> 8) & 0xff;
     215                data[i + 1] = bioctet & 0xff;
     216               
     217                if (wildcard_pos != (size_t) -1) {
     218                        if (wildcard_size < 2)
     219                                return EINVAL;
     220                       
     221                        wildcard_size -= 2;
     222                }
     223               
     224                i += 2;
     225               
     226                if (*cur == 0)
     227                        break;
     228               
     229                if (*cur != ':')
     230                        return EINVAL;
     231               
     232                if (i < 16) {
     233                        cur++;
     234                       
     235                        /* Handle wildcard */
     236                        if (*cur == ':') {
     237                                if (wildcard_pos != (size_t) -1)
     238                                        return EINVAL;
     239                               
     240                                wildcard_pos = i;
     241                                wildcard_size = 16 - i;
     242                                cur++;
     243                               
     244                                if (*cur == 0)
     245                                        break;
     246                        }
     247                }
     248        }
     249       
     250        if ((i == 16) && (*cur != 0))
     251                return EINVAL;
     252       
     253        /* Create wildcard positions */
     254        if ((wildcard_pos != (size_t) -1) && (wildcard_size > 0)) {
     255                size_t wildcard_shift = 16 - wildcard_size;
     256               
     257                for (i = wildcard_pos + wildcard_shift; i > wildcard_pos; i--) {
     258                        size_t j = i - 1;
     259                        data[j + wildcard_size] = data[j];
     260                        data[j] = 0;
     261                }
     262        }
     263       
     264        return EOK;
     265}
     266
    96267/** Parses the character string into the address.
    97268 *
    98  *  If the string is shorter than the full address, zero bytes are added.
    99  *
    100  *  @param[in] family   The address family.
    101  *  @param[in] address  The character buffer to be parsed.
    102  *  @param[out] data    The address data to be filled.
    103  *  @return             EOK on success.
    104  *  @return             EINVAL if the data parameter is NULL.
    105  *  @return             ENOENT if the address parameter is NULL.
    106  *  @return             ENOTSUP if the address family is not supported.
     269 * @param[in]  family  The address family.
     270 * @param[in]  address The character buffer to be parsed.
     271 * @param[out] data    The address data to be filled.
     272 *
     273 * @return EOK on success.
     274 * @return EINVAL if the data parameter is NULL.
     275 * @return ENOENT if the address parameter is NULL.
     276 * @return ENOTSUP if the address family is not supported.
     277 *
    107278 */
    108279int inet_pton(uint16_t family, const char *address, uint8_t *data)
    109280{
    110         /** The base number of the values. */
    111         int base;
    112         /** The number of bytes per a section. */
    113         size_t bytes;
    114         /** The number of bytes of the address data. */
    115         int count;
    116 
    117         const char *next;
    118         char *last;
    119         int index;
    120         size_t shift;
    121         unsigned long value;
    122 
    123         if (!data)
    124                 return EINVAL;
    125 
    126         /* Set processing parameters */
    127281        switch (family) {
    128282        case AF_INET:
    129                 count = 4;
    130                 base = 10;
    131                 bytes = 1;
    132                 break;
    133 
     283                return inet_pton4(address, data);
    134284        case AF_INET6:
    135                 count = 16;
    136                 base = 16;
    137                 bytes = 4;
    138                 break;
    139 
     285                return inet_pton6(address, data);
    140286        default:
     287                /** Unknown address family */
    141288                return ENOTSUP;
    142289        }
    143 
    144         /* Erase if no address */
    145         if (!address) {
    146                 memset(data, 0, count);
    147                 return ENOENT;
    148         }
    149 
    150         /* Process string from the beginning */
    151         next = address;
    152         index = 0;
    153         do {
    154                 /* If the actual character is set */
    155                 if (next && *next) {
    156 
    157                         /* If not on the first character */
    158                         if (index) {
    159                                 /* Move to the next character */
    160                                 ++next;
    161                         }
    162 
    163                         /* Parse the actual integral value */
    164                         value = strtoul(next, &last, base);
    165                         /*
    166                          * Remember the last problematic character
    167                          * should be either '.' or ':' but is ignored to be
    168                          * more generic
    169                          */
    170                         next = last;
    171 
    172                         /* Fill the address data byte by byte */
    173                         shift = bytes - 1;
    174                         do {
    175                                 /* like little endian */
    176                                 data[index + shift] = value;
    177                                 value >>= 8;
    178                         } while(shift --);
    179 
    180                         index += bytes;
    181                 } else {
    182                         /* Erase the rest of the address */
    183                         memset(data + index, 0, count - index);
    184                         return EOK;
    185                 }
    186         } while (index < count);
    187 
    188         return EOK;
    189290}
    190291
  • uspace/lib/c/generic/net/socket_client.c

    rf2c19b0 r03c971f  
    8787        /** Parent module service. */
    8888        services_t service;
     89        /** Socket family */
     90        int family;
    8991
    9092        /**
     
    395397        switch (domain) {
    396398        case PF_INET:
     399        case PF_INET6:
    397400                switch (type) {
    398401                case SOCK_STREAM:
     
    433436                break;
    434437
    435         case PF_INET6:
    436438        default:
    437439                return EPFNOSUPPORT;
     
    447449
    448450        memset(socket, 0, sizeof(*socket));
     451        socket->family = domain;
    449452        fibril_rwlock_write_lock(&socket_globals.lock);
    450453
  • uspace/lib/c/generic/net/socket_parse.c

    rf2c19b0 r03c971f  
    5353int socket_parse_address_family(const char *name, int *af)
    5454{
    55         if (str_lcmp(name, "AF_INET", 7) == 0) {
    56                 *af = AF_INET;
     55        if (str_lcmp(name, "AF_INET6", 8) == 0) {
     56                *af = AF_INET6;
    5757                return EOK;
    5858        }
    5959       
    60         if (str_lcmp(name, "AF_INET6", 8) == 0) {
    61                 *af = AF_INET6;
     60        if (str_lcmp(name, "AF_INET", 7) == 0) {
     61                *af = AF_INET;
    6262                return EOK;
    6363        }
     
    7979int socket_parse_protocol_family(const char *name, int *pf)
    8080{
     81        if (str_lcmp(name, "PF_INET6", 8) == 0) {
     82                *pf = PF_INET6;
     83                return EOK;
     84        }
     85
    8186        if (str_lcmp(name, "PF_INET", 7) == 0) {
    8287                *pf = PF_INET;
    83                 return EOK;
    84         }
    85        
    86         if (str_lcmp(name, "PF_INET6", 8) == 0) {
    87                 *pf = PF_INET6;
    8888                return EOK;
    8989        }
  • uspace/lib/c/generic/str.c

    rf2c19b0 r03c971f  
    15241524 *
    15251525 */
    1526 int str_uint8_t(const char *nptr, char **endptr, unsigned int base,
     1526int str_uint8_t(const char *nptr, const char **endptr, unsigned int base,
    15271527    bool strict, uint8_t *result)
    15281528{
     
    15711571 *
    15721572 */
    1573 int str_uint16_t(const char *nptr, char **endptr, unsigned int base,
     1573int str_uint16_t(const char *nptr, const char **endptr, unsigned int base,
    15741574    bool strict, uint16_t *result)
    15751575{
     
    16181618 *
    16191619 */
    1620 int str_uint32_t(const char *nptr, char **endptr, unsigned int base,
     1620int str_uint32_t(const char *nptr, const char **endptr, unsigned int base,
    16211621    bool strict, uint32_t *result)
    16221622{
     
    16651665 *
    16661666 */
    1667 int str_uint64_t(const char *nptr, char **endptr, unsigned int base,
     1667int str_uint64_t(const char *nptr, const char **endptr, unsigned int base,
    16681668    bool strict, uint64_t *result)
    16691669{
     
    17041704 *
    17051705 */
    1706 int str_size_t(const char *nptr, char **endptr, unsigned int base,
     1706int str_size_t(const char *nptr, const char **endptr, unsigned int base,
    17071707    bool strict, size_t *result)
    17081708{
Note: See TracChangeset for help on using the changeset viewer.