Changeset 98abd40 in mainline for uspace/lib/c/generic


Ignore:
Timestamp:
2013-07-06T21:57:22Z (12 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c8bb1633, cdc8a391
Parents:
b8e72fd1 (diff), 507c6f3 (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:

Merge mainline changes

Location:
uspace/lib/c/generic
Files:
1 added
12 edited

Legend:

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

    rb8e72fd1 r98abd40  
    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

    rb8e72fd1 r98abd40  
    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}
     
    7069int dnsr_name2host(const char *name, dnsr_hostinfo_t **rinfo)
    7170{
     71        dnsr_hostinfo_t *info = calloc(1, sizeof(dnsr_hostinfo_t));
     72        if (info == NULL)
     73                return ENOMEM;
     74       
    7275        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 
     76       
    7877        ipc_call_t answer;
    7978        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 
     79       
     80        int rc = async_data_write_start(exch, name, str_size(name));
     81        if (rc != EOK) {
     82                async_exchange_end(exch);
     83                async_forget(req);
     84                return rc;
     85        }
     86       
     87        ipc_call_t answer_addr;
     88        aid_t req_addr = async_data_read(exch, &info->addr,
     89            sizeof(inet_addr_t), &answer_addr);
     90       
     91        sysarg_t retval_addr;
     92        async_wait_for(req_addr, &retval_addr);
     93       
     94        if (retval_addr != EOK) {
     95                async_exchange_end(exch);
     96                async_forget(req);
     97                return (int) retval_addr;
     98        }
     99       
     100        ipc_call_t answer_cname;
     101        char cname_buf[DNSR_NAME_MAX_SIZE + 1];
     102        aid_t req_cname = async_data_read(exch, cname_buf, DNSR_NAME_MAX_SIZE,
     103            &answer_cname);
     104       
    84105        dnsr_exchange_end(exch);
    85 
    86         if (retval != EOK) {
     106       
     107        sysarg_t retval_cname;
     108        async_wait_for(req_cname, &retval_cname);
     109       
     110        if (retval_cname != EOK) {
    87111                async_forget(req);
    88                 async_forget(cnreq);
    89                 return retval;
     112                return (int) retval_cname;
    90113        }
    91 
     114       
     115        sysarg_t retval;
    92116        async_wait_for(req, &retval);
    93         if (retval != EOK) {
    94                 async_forget(cnreq);
    95                 return EIO;
    96         }
    97 
    98         async_wait_for(cnreq, &retval);
     117       
    99118        if (retval != EOK)
    100                 return EIO;
    101 
    102         info = calloc(1, sizeof(dnsr_hostinfo_t));
    103         if (info == NULL)
    104                 return ENOMEM;
    105 
    106         act_size = IPC_GET_ARG2(cnreply);
     119                return (int) retval;
     120       
     121        size_t act_size = IPC_GET_ARG2(answer_cname);
    107122        assert(act_size <= DNSR_NAME_MAX_SIZE);
     123       
    108124        cname_buf[act_size] = '\0';
    109 
     125       
    110126        info->cname = str_dup(cname_buf);
    111         info->addr.ipv4 = IPC_GET_ARG1(answer);
    112 
     127       
    113128        *rinfo = info;
    114129        return EOK;
     
    119134        if (info == NULL)
    120135                return;
    121 
     136       
    122137        free(info->cname);
    123138        free(info);
     
    126141int dnsr_get_srvaddr(inet_addr_t *srvaddr)
    127142{
    128         sysarg_t addr;
    129143        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)
     144       
     145        ipc_call_t answer;
     146        aid_t req = async_send_0(exch, DNSR_GET_SRVADDR, &answer);
     147        int rc = async_data_read_start(exch, srvaddr, sizeof(inet_addr_t));
     148       
     149        loc_exchange_end(exch);
     150       
     151        if (rc != EOK) {
     152                async_forget(req);
    135153                return rc;
    136 
    137         srvaddr->ipv4 = addr;
    138         return EOK;
     154        }
     155       
     156        sysarg_t retval;
     157        async_wait_for(req, &retval);
     158       
     159        return (int) retval;
    139160}
    140161
     
    142163{
    143164        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)
     165       
     166        ipc_call_t answer;
     167        aid_t req = async_send_0(exch, DNSR_SET_SRVADDR, &answer);
     168        int rc = async_data_write_start(exch, srvaddr, sizeof(inet_addr_t));
     169       
     170        loc_exchange_end(exch);
     171       
     172        if (rc != EOK) {
     173                async_forget(req);
    149174                return rc;
    150 
    151         return EOK;
     175        }
     176       
     177        sysarg_t retval;
     178        async_wait_for(req, &retval);
     179       
     180        return (int) retval;
    152181}
    153182
  • uspace/lib/c/generic/inet.c

    rb8e72fd1 r98abd40  
    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

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

    rb8e72fd1 r98abd40  
    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

    rb8e72fd1 r98abd40  
    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/iplink.c

    rb8e72fd1 r98abd40  
    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       
    8687        ipc_call_t answer;
    87         aid_t req = async_send_2(exch, IPLINK_SEND, sdu->lsrc.ipv4,
    88             sdu->ldest.ipv4, &answer);
    89         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 
     88        aid_t req = async_send_0(exch, IPLINK_SEND, &answer);
     89       
     90        int rc = async_data_write_start(exch, &sdu->src, sizeof(inet_addr_t));
     91        if (rc != EOK) {
     92                async_exchange_end(exch);
     93                async_forget(req);
     94                return rc;
     95        }
     96       
     97        rc = async_data_write_start(exch, &sdu->dest, sizeof(inet_addr_t));
     98        if (rc != EOK) {
     99                async_exchange_end(exch);
     100                async_forget(req);
     101                return rc;
     102        }
     103       
     104        rc = async_data_write_start(exch, sdu->data, sdu->size);
     105       
     106        async_exchange_end(exch);
     107       
     108        if (rc != EOK) {
     109                async_forget(req);
     110                return rc;
     111        }
     112       
    97113        sysarg_t retval;
    98114        async_wait_for(req, &retval);
    99         if (retval != EOK)
    100                 return retval;
    101 
    102         return EOK;
     115       
     116        return (int) retval;
    103117}
    104118
     
    118132}
    119133
    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);
     134int iplink_addr_add(iplink_t *iplink, inet_addr_t *addr)
     135{
     136        async_exch_t *exch = async_exchange_begin(iplink->sess);
     137       
     138        ipc_call_t answer;
     139        aid_t req = async_send_0(exch, IPLINK_ADDR_ADD, &answer);
     140       
     141        int rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
     142        async_exchange_end(exch);
     143       
     144        if (rc != EOK) {
     145                async_forget(req);
     146                return rc;
     147        }
     148       
     149        sysarg_t retval;
     150        async_wait_for(req, &retval);
     151       
     152        return (int) retval;
     153}
     154
     155int iplink_addr_remove(iplink_t *iplink, inet_addr_t *addr)
     156{
     157        async_exch_t *exch = async_exchange_begin(iplink->sess);
     158       
     159        ipc_call_t answer;
     160        aid_t req = async_send_0(exch, IPLINK_ADDR_REMOVE, &answer);
     161       
     162        int rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
     163        async_exchange_end(exch);
     164       
     165        if (rc != EOK) {
     166                async_forget(req);
     167                return rc;
     168        }
     169       
     170        sysarg_t retval;
     171        async_wait_for(req, &retval);
     172       
     173        return (int) retval;
     174}
     175
     176static void iplink_ev_recv(iplink_t *iplink, ipc_callid_t iid,
     177    ipc_call_t *icall)
     178{
     179        iplink_recv_sdu_t sdu;
     180       
     181        uint16_t af = IPC_GET_ARG1(*icall);
     182       
     183        int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     184            &sdu.size);
     185        if (rc != EOK) {
     186                async_answer_0(iid, rc);
    152187                return;
    153188        }
    154 
    155         rc = iplink->ev_ops->recv(iplink, &sdu);
     189       
     190        rc = iplink->ev_ops->recv(iplink, &sdu, af);
    156191        free(sdu.data);
    157         async_answer_0(callid, rc);
     192        async_answer_0(iid, rc);
    158193}
    159194
    160195static void iplink_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    161196{
    162         iplink_t *iplink = (iplink_t *)arg;
    163 
     197        iplink_t *iplink = (iplink_t *) arg;
     198       
    164199        while (true) {
    165200                ipc_call_t call;
    166201                ipc_callid_t callid = async_get_call(&call);
    167 
     202               
    168203                if (!IPC_GET_IMETHOD(call)) {
    169204                        /* TODO: Handle hangup */
    170205                        return;
    171206                }
    172 
     207               
    173208                switch (IPC_GET_IMETHOD(call)) {
    174209                case IPLINK_EV_RECV:
  • uspace/lib/c/generic/iplink_srv.c

    rb8e72fd1 r98abd40  
    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_addr_add_srv(iplink_srv_t *srv, ipc_callid_t iid,
     53    ipc_call_t *icall)
     54{
     55        ipc_callid_t callid;
     56        size_t size;
     57        if (!async_data_write_receive(&callid, &size)) {
     58                async_answer_0(callid, EREFUSED);
     59                async_answer_0(iid, EREFUSED);
     60                return;
     61        }
     62       
     63        if (size != sizeof(inet_addr_t)) {
     64                async_answer_0(callid, EINVAL);
     65                async_answer_0(iid, EINVAL);
     66                return;
     67        }
     68       
     69        inet_addr_t addr;
     70        int rc = async_data_write_finalize(callid, &addr, size);
     71        if (rc != EOK) {
     72                async_answer_0(callid, (sysarg_t) rc);
     73                async_answer_0(iid, (sysarg_t) rc);
     74        }
     75       
    6176        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 
     77        async_answer_0(iid, (sysarg_t) rc);
     78}
     79
     80static void iplink_addr_remove_srv(iplink_srv_t *srv, ipc_callid_t iid,
     81    ipc_call_t *icall)
     82{
     83        ipc_callid_t callid;
     84        size_t size;
     85        if (!async_data_write_receive(&callid, &size)) {
     86                async_answer_0(callid, EREFUSED);
     87                async_answer_0(iid, EREFUSED);
     88                return;
     89        }
     90       
     91        if (size != sizeof(inet_addr_t)) {
     92                async_answer_0(callid, EINVAL);
     93                async_answer_0(iid, EINVAL);
     94                return;
     95        }
     96       
     97        inet_addr_t addr;
     98        int rc = async_data_write_finalize(callid, &addr, size);
     99        if (rc != EOK) {
     100                async_answer_0(callid, (sysarg_t) rc);
     101                async_answer_0(iid, (sysarg_t) rc);
     102        }
     103       
    73104        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 
     105        async_answer_0(iid, (sysarg_t) rc);
     106}
     107
     108static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t iid,
     109    ipc_call_t *icall)
     110{
     111        iplink_sdu_t sdu;
     112       
     113        ipc_callid_t callid;
     114        size_t size;
     115        if (!async_data_write_receive(&callid, &size)) {
     116                async_answer_0(callid, EREFUSED);
     117                async_answer_0(iid, EREFUSED);
     118                return;
     119        }
     120       
     121        if (size != sizeof(inet_addr_t)) {
     122                async_answer_0(callid, EINVAL);
     123                async_answer_0(iid, EINVAL);
     124                return;
     125        }
     126       
     127        int rc = async_data_write_finalize(callid, &sdu.src, size);
     128        if (rc != EOK) {
     129                async_answer_0(callid, (sysarg_t) rc);
     130                async_answer_0(iid, (sysarg_t) rc);
     131        }
     132       
     133        if (!async_data_write_receive(&callid, &size)) {
     134                async_answer_0(callid, EREFUSED);
     135                async_answer_0(iid, EREFUSED);
     136                return;
     137        }
     138       
     139        if (size != sizeof(inet_addr_t)) {
     140                async_answer_0(callid, EINVAL);
     141                async_answer_0(iid, EINVAL);
     142                return;
     143        }
     144       
     145        rc = async_data_write_finalize(callid, &sdu.dest, size);
     146        if (rc != EOK) {
     147                async_answer_0(callid, (sysarg_t) rc);
     148                async_answer_0(iid, (sysarg_t) rc);
     149        }
     150       
     151        rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     152            &sdu.size);
     153        if (rc != EOK)
     154                return;
     155       
    92156        rc = srv->ops->send(srv, &sdu);
    93157        free(sdu.data);
    94         async_answer_0(callid, rc);
     158        async_answer_0(iid, rc);
    95159}
    96160
     
    108172        iplink_srv_t *srv = (iplink_srv_t *)arg;
    109173        int rc;
    110 
     174       
    111175        fibril_mutex_lock(&srv->lock);
    112176        if (srv->connected) {
     
    115179                return EBUSY;
    116180        }
    117 
     181       
    118182        srv->connected = true;
    119183        fibril_mutex_unlock(&srv->lock);
    120 
     184       
    121185        /* Accept the connection */
    122186        async_answer_0(iid, EOK);
    123 
     187       
    124188        async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
    125189        if (sess == NULL)
    126190                return ENOMEM;
    127 
     191       
    128192        srv->client_sess = sess;
    129 
     193       
    130194        rc = srv->ops->open(srv);
    131195        if (rc != EOK)
    132196                return rc;
    133 
     197       
    134198        while (true) {
    135199                ipc_call_t call;
    136200                ipc_callid_t callid = async_get_call(&call);
    137201                sysarg_t method = IPC_GET_IMETHOD(call);
    138 
     202               
    139203                if (!method) {
    140204                        /* The other side has hung up */
    141                         fibril_mutex_lock(&srv->lock);
     205                        fibril_mutex_lock(&srv->lock);
    142206                        srv->connected = false;
    143                         fibril_mutex_unlock(&srv->lock);
     207                        fibril_mutex_unlock(&srv->lock);
    144208                        async_answer_0(callid, EOK);
    145209                        break;
    146210                }
    147 
     211               
    148212                switch (method) {
    149213                case IPLINK_GET_MTU:
     
    163227                }
    164228        }
    165 
     229       
    166230        return srv->ops->close(srv);
    167231}
    168232
    169 int iplink_ev_recv(iplink_srv_t *srv, iplink_srv_sdu_t *sdu)
     233int iplink_ev_recv(iplink_srv_t *srv, iplink_recv_sdu_t *sdu, uint16_t af)
    170234{
    171235        if (srv->client_sess == NULL)
    172236                return EIO;
    173 
     237       
    174238        async_exch_t *exch = async_exchange_begin(srv->client_sess);
    175 
     239       
    176240        ipc_call_t answer;
    177         aid_t req = async_send_2(exch, IPLINK_EV_RECV, sdu->lsrc.ipv4,
    178             sdu->ldest.ipv4, &answer);
     241        aid_t req = async_send_1(exch, IPLINK_EV_RECV, (sysarg_t) af,
     242            &answer);
     243       
    179244        int rc = async_data_write_start(exch, sdu->data, sdu->size);
    180245        async_exchange_end(exch);
    181 
     246       
    182247        if (rc != EOK) {
    183248                async_forget(req);
    184249                return rc;
    185250        }
    186 
     251       
    187252        sysarg_t retval;
    188253        async_wait_for(req, &retval);
    189254        if (retval != EOK)
    190255                return retval;
    191 
     256       
    192257        return EOK;
    193258}
  • uspace/lib/c/generic/net/inet.c

    rb8e72fd1 r98abd40  
    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

    rb8e72fd1 r98abd40  
    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

    rb8e72fd1 r98abd40  
    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

    rb8e72fd1 r98abd40  
    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.