Changeset 02a09ed in mainline for uspace/lib/c


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

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

Location:
uspace/lib/c
Files:
9 edited

Legend:

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

    redf0d27 r02a09ed  
    6969int dnsr_name2host(const char *name, dnsr_hostinfo_t **rinfo)
    7070{
     71        dnsr_hostinfo_t *info = calloc(1, sizeof(dnsr_hostinfo_t));
     72        if (info == NULL)
     73                return ENOMEM;
     74       
    7175        async_exch_t *exch = dnsr_exchange_begin();
    72         char cname_buf[DNSR_NAME_MAX_SIZE + 1];
    73         ipc_call_t cnreply;
    74         size_t act_size;
    75         dnsr_hostinfo_t *info;
    76 
     76       
    7777        ipc_call_t answer;
    7878        aid_t req = async_send_0(exch, DNSR_NAME2HOST, &answer);
    79         sysarg_t retval = async_data_write_start(exch, name, str_size(name));
    80         aid_t cnreq = async_data_read(exch, cname_buf, DNSR_NAME_MAX_SIZE,
    81             &cnreply);
    82 
     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       
    83105        dnsr_exchange_end(exch);
    84 
    85         if (retval != EOK) {
     106       
     107        sysarg_t retval_cname;
     108        async_wait_for(req_cname, &retval_cname);
     109       
     110        if (retval_cname != EOK) {
    86111                async_forget(req);
    87                 async_forget(cnreq);
    88                 return retval;
     112                return (int) retval_cname;
    89113        }
    90 
     114       
     115        sysarg_t retval;
    91116        async_wait_for(req, &retval);
    92         if (retval != EOK) {
    93                 async_forget(cnreq);
    94                 return EIO;
    95         }
    96 
    97         async_wait_for(cnreq, &retval);
     117       
    98118        if (retval != EOK)
    99                 return EIO;
    100 
    101         info = calloc(1, sizeof(dnsr_hostinfo_t));
    102         if (info == NULL)
    103                 return ENOMEM;
    104 
    105         act_size = IPC_GET_ARG2(cnreply);
     119                return (int) retval;
     120       
     121        size_t act_size = IPC_GET_ARG2(answer_cname);
    106122        assert(act_size <= DNSR_NAME_MAX_SIZE);
     123       
    107124        cname_buf[act_size] = '\0';
    108 
     125       
    109126        info->cname = str_dup(cname_buf);
    110         inet_addr_unpack(IPC_GET_ARG1(answer), &info->addr);
    111 
     127       
    112128        *rinfo = info;
    113129        return EOK;
  • uspace/lib/c/generic/inet.c

    redf0d27 r02a09ed  
    3030#include <assert.h>
    3131#include <errno.h>
     32#include <net/socket_codes.h>
    3233#include <inet/inet.h>
    3334#include <ipc/inet.h>
     
    107108int inet_send(inet_dgram_t *dgram, uint8_t ttl, inet_df_t df)
    108109{
    109         uint32_t src;
    110         int rc = inet_addr_pack(&dgram->src, &src);
    111         if (rc != EOK)
    112                 return rc;
    113        
    114         uint32_t dest;
    115         rc = inet_addr_pack(&dgram->dest, &dest);
    116         if (rc != EOK)
    117                 return EOK;
    118        
    119         async_exch_t *exch = async_exchange_begin(inet_sess);
    120        
     110        addr32_t src_v4;
     111        addr128_t src_v6;
     112        uint16_t src_af = inet_addr_get(&dgram->src, &src_v4, &src_v6);
     113       
     114        addr32_t dest_v4;
     115        addr128_t dest_v6;
     116        uint16_t dest_af = inet_addr_get(&dgram->dest, &dest_v4, &dest_v6);
     117       
     118        if (src_af != dest_af)
     119                return EINVAL;
     120       
     121        async_exch_t *exch;
    121122        ipc_call_t answer;
    122         aid_t req = async_send_5(exch, INET_SEND, (sysarg_t) src,
    123             (sysarg_t) dest, dgram->tos, ttl, df, &answer);
    124         rc = async_data_write_start(exch, dgram->data, dgram->size);
    125        
    126         async_exchange_end(exch);
     123        aid_t req;
     124        int rc;
     125       
     126        switch (src_af) {
     127        case AF_INET:
     128                exch = async_exchange_begin(inet_sess);
     129               
     130                req = async_send_5(exch, INET_SEND, (sysarg_t) src_v4,
     131                    (sysarg_t) dest_v4, dgram->tos, ttl, df, &answer);
     132                rc = async_data_write_start(exch, dgram->data, dgram->size);
     133               
     134                async_exchange_end(exch);
     135                break;
     136        case AF_INET6:
     137                // FIXME TODO
     138                return ENOTSUP;
     139        default:
     140                return EINVAL;
     141        }
    127142       
    128143        if (rc != EOK) {
     
    133148        sysarg_t retval;
    134149        async_wait_for(req, &retval);
    135         if (retval != EOK)
    136                 return retval;
    137        
    138         return EOK;
     150       
     151        return (int) retval;
    139152}
    140153
    141154int inet_get_srcaddr(inet_addr_t *remote, uint8_t tos, inet_addr_t *local)
    142155{
    143         uint32_t remote_addr;
    144         int rc = inet_addr_pack(remote, &remote_addr);
    145         if (rc != EOK)
    146                 return rc;
    147        
    148         async_exch_t *exch = async_exchange_begin(inet_sess);
    149        
    150         sysarg_t local_addr;
    151         rc = async_req_2_1(exch, INET_GET_SRCADDR, (sysarg_t) remote_addr,
    152             tos, &local_addr);
    153        
    154         async_exchange_end(exch);
    155        
    156         if (rc != EOK)
    157                 return rc;
    158        
    159         inet_addr_unpack(local_addr, local);
    160         return EOK;
    161 }
    162 
    163 static void inet_ev_recv(ipc_callid_t callid, ipc_call_t *call)
    164 {
     156        addr32_t remote_v4;
     157        addr128_t remote_v6;
     158        uint16_t remote_af = inet_addr_get(remote, &remote_v4, &remote_v6);
     159       
     160        async_exch_t *exch;
    165161        int rc;
     162       
     163        switch (remote_af) {
     164        case AF_INET:
     165                exch = async_exchange_begin(inet_sess);
     166               
     167                sysarg_t local_v4;
     168                rc = async_req_2_1(exch, INET_GET_SRCADDR, (sysarg_t) remote_v4,
     169                    tos, &local_v4);
     170               
     171                async_exchange_end(exch);
     172               
     173                if (rc != EOK)
     174                        return rc;
     175               
     176                inet_addr_set(local_v4, local);
     177                return EOK;
     178        case AF_INET6:
     179                // FIXME TODO
     180                return ENOTSUP;
     181        default:
     182                return EINVAL;
     183        }
     184}
     185
     186static void inet_ev_recv(ipc_callid_t iid, ipc_call_t *icall)
     187{
    166188        inet_dgram_t dgram;
    167189       
    168         inet_addr_unpack(IPC_GET_ARG1(*call), &dgram.src);
    169         inet_addr_unpack(IPC_GET_ARG2(*call), &dgram.dest);
    170         dgram.tos = IPC_GET_ARG3(*call);
     190        dgram.tos = IPC_GET_ARG1(*icall);
     191       
     192        ipc_callid_t callid;
     193        size_t size;
     194        if (!async_data_write_receive(&callid, &size)) {
     195                async_answer_0(callid, EINVAL);
     196                async_answer_0(iid, EINVAL);
     197                return;
     198        }
     199       
     200        if (size != sizeof(inet_addr_t)) {
     201                async_answer_0(callid, EINVAL);
     202                async_answer_0(iid, EINVAL);
     203                return;
     204        }
     205       
     206        int rc = async_data_write_finalize(callid, &dgram.src, size);
     207        if (rc != EOK) {
     208                async_answer_0(callid, rc);
     209                async_answer_0(iid, rc);
     210                return;
     211        }
     212       
     213        if (!async_data_write_receive(&callid, &size)) {
     214                async_answer_0(callid, EINVAL);
     215                async_answer_0(iid, EINVAL);
     216                return;
     217        }
     218       
     219        if (size != sizeof(inet_addr_t)) {
     220                async_answer_0(callid, EINVAL);
     221                async_answer_0(iid, EINVAL);
     222                return;
     223        }
     224       
     225        rc = async_data_write_finalize(callid, &dgram.dest, size);
     226        if (rc != EOK) {
     227                async_answer_0(callid, rc);
     228                async_answer_0(iid, rc);
     229                return;
     230        }
    171231       
    172232        rc = async_data_write_accept(&dgram.data, false, 0, 0, 0, &dgram.size);
    173233        if (rc != EOK) {
    174                 async_answer_0(callid, rc);
     234                async_answer_0(iid, rc);
    175235                return;
    176236        }
    177237       
    178238        rc = inet_ev_ops->recv(&dgram);
    179         async_answer_0(callid, rc);
     239        async_answer_0(iid, rc);
    180240}
    181241
  • uspace/lib/c/generic/inet/addr.c

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

    redf0d27 r02a09ed  
    136136    sysarg_t link_id, sysarg_t *addr_id)
    137137{
    138         uint32_t naddr_addr;
    139         uint8_t naddr_bits;
    140         int rc = inet_naddr_pack(naddr, &naddr_addr, &naddr_bits);
    141         if (rc != EOK)
    142                 return rc;
    143        
    144         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    145        
    146         ipc_call_t answer;
    147         aid_t req = async_send_3(exch, INETCFG_ADDR_CREATE_STATIC,
    148             (sysarg_t) naddr_addr, (sysarg_t) naddr_bits, link_id, &answer);
     138        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
     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);
    149236        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
    150        
    151         async_exchange_end(exch);
    152        
     237
     238        async_exchange_end(exch);
     239
    153240        if (retval != EOK) {
    154241                async_forget(req);
    155242                return retval;
    156243        }
    157        
     244
    158245        async_wait_for(req, &retval);
    159246        *addr_id = IPC_GET_ARG1(answer);
    160        
    161         return (int) retval;
    162 }
    163 
    164 int inetcfg_addr_delete(sysarg_t addr_id)
    165 {
    166         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    167 
    168         int rc = async_req_1_0(exch, INETCFG_ADDR_DELETE, addr_id);
    169         async_exchange_end(exch);
    170 
    171         return rc;
    172 }
    173 
    174 int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
     247
     248        return retval;
     249}
     250
     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)
    175270{
    176271        ipc_call_t dreply;
     
    178273        size_t act_size;
    179274        char name_buf[LOC_NAME_MAXLEN + 1];
    180        
    181         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    182        
    183         ipc_call_t answer;
    184         aid_t req = async_send_1(exch, INETCFG_ADDR_GET, addr_id, &answer);
    185         aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
    186         async_wait_for(dreq, &dretval);
    187        
    188         async_exchange_end(exch);
    189        
    190         if (dretval != EOK) {
    191                 async_forget(req);
    192                 return dretval;
    193         }
    194        
    195         sysarg_t retval;
    196         async_wait_for(req, &retval);
    197        
    198         if (retval != EOK)
    199                 return (int) retval;
    200        
    201         act_size = IPC_GET_ARG2(dreply);
    202         assert(act_size <= LOC_NAME_MAXLEN);
    203        
    204         name_buf[act_size] = '\0';
    205        
    206         inet_naddr_unpack(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    207             &ainfo->naddr);
    208         ainfo->ilink = IPC_GET_ARG3(answer);
    209         ainfo->name = str_dup(name_buf);
    210        
    211         return EOK;
    212 }
    213 
    214 int inetcfg_addr_get_id(const char *name, sysarg_t link_id, sysarg_t *addr_id)
    215 {
    216         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    217 
    218         ipc_call_t answer;
    219         aid_t req = async_send_1(exch, INETCFG_ADDR_GET_ID, link_id, &answer);
    220         sysarg_t retval = async_data_write_start(exch, name, str_size(name));
    221 
    222         async_exchange_end(exch);
    223 
    224         if (retval != EOK) {
    225                 async_forget(req);
    226                 return retval;
    227         }
    228 
    229         async_wait_for(req, &retval);
    230         *addr_id = IPC_GET_ARG1(answer);
    231 
    232         return retval;
    233 }
    234 
    235 int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
    236 {
    237         return inetcfg_get_ids_internal(INETCFG_GET_ADDR_LIST,
    238             0, addrs, count);
    239 }
    240 
    241 int inetcfg_get_link_list(sysarg_t **links, size_t *count)
    242 {
    243         return inetcfg_get_ids_internal(INETCFG_GET_LINK_LIST,
    244             0, links, count);
    245 }
    246 
    247 int inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
    248 {
    249         return inetcfg_get_ids_internal(INETCFG_GET_SROUTE_LIST,
    250             0, sroutes, count);
    251 }
    252 
    253 int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
    254 {
    255         ipc_call_t dreply;
    256         sysarg_t dretval;
    257         size_t act_size;
    258         char name_buf[LOC_NAME_MAXLEN + 1];
    259275
    260276        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
     
    291307    inet_addr_t *router, sysarg_t *sroute_id)
    292308{
    293         uint32_t dest_addr;
    294         uint8_t dest_bits;
    295         int rc = inet_naddr_pack(dest, &dest_addr, &dest_bits);
    296         if (rc != EOK)
    297                 return rc;
    298        
    299         uint32_t router_addr;
    300         rc = inet_addr_pack(router, &router_addr);
    301         if (rc != EOK)
    302                 return rc;
    303        
    304         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    305        
    306         ipc_call_t answer;
    307         aid_t req = async_send_3(exch, INETCFG_SROUTE_CREATE,
    308             (sysarg_t) dest_addr, (sysarg_t) dest_bits, (sysarg_t) router_addr,
    309             &answer);
    310         sysarg_t retval = async_data_write_start(exch, name, str_size(name));
    311        
    312         async_exchange_end(exch);
    313        
    314         if (retval != EOK) {
    315                 async_forget(req);
    316                 return retval;
    317         }
    318        
    319         async_wait_for(req, &retval);
     309        async_exch_t *exch = async_exchange_begin(inetcfg_sess);
     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       
    320340        *sroute_id = IPC_GET_ARG1(answer);
    321341       
    322         return retval;
     342        return (int) retval;
    323343}
    324344
     
    335355int inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
    336356{
    337         ipc_call_t dreply;
    338         sysarg_t dretval;
    339         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;
    340389        char name_buf[LOC_NAME_MAXLEN + 1];
    341 
    342         async_exch_t *exch = async_exchange_begin(inetcfg_sess);
    343        
    344         ipc_call_t answer;
    345         aid_t req = async_send_1(exch, INETCFG_SROUTE_GET, sroute_id, &answer);
    346         aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
    347         async_wait_for(dreq, &dretval);
    348        
    349         async_exchange_end(exch);
    350        
    351         if (dretval != EOK) {
    352                 async_forget(req);
    353                 return dretval;
     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;
    354401        }
    355402       
     
    360407                return (int) retval;
    361408       
    362         act_size = IPC_GET_ARG2(dreply);
     409        size_t act_size = IPC_GET_ARG2(answer_name);
    363410        assert(act_size <= LOC_NAME_MAXLEN);
     411       
    364412        name_buf[act_size] = '\0';
    365 
    366         inet_naddr_unpack(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    367             &srinfo->dest);
    368         inet_addr_unpack(IPC_GET_ARG3(answer), &srinfo->router);
     413       
    369414        srinfo->name = str_dup(name_buf);
    370415       
  • uspace/lib/c/generic/iplink.c

    redf0d27 r02a09ed  
    8686       
    8787        ipc_call_t answer;
    88         aid_t req = async_send_2(exch, IPLINK_SEND, (sysarg_t) sdu->lsrc,
    89             (sysarg_t) sdu->ldest, &answer);
    90         int rc = async_data_write_start(exch, sdu->data, sdu->size);
     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);
    91105       
    92106        async_exchange_end(exch);
     
    120134int iplink_addr_add(iplink_t *iplink, inet_addr_t *addr)
    121135{
    122         uint32_t addr_addr;
    123         int rc = inet_addr_pack(addr, &addr_addr);
    124         if (rc != EOK)
    125                 return rc;
    126        
    127         async_exch_t *exch = async_exchange_begin(iplink->sess);
    128         rc = async_req_1_0(exch, IPLINK_ADDR_ADD, (sysarg_t) addr_addr);
    129         async_exchange_end(exch);
    130        
    131         return rc;
     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;
    132153}
    133154
    134155int iplink_addr_remove(iplink_t *iplink, inet_addr_t *addr)
    135156{
    136         uint32_t addr_addr;
    137         int rc = inet_addr_pack(addr, &addr_addr);
    138         if (rc != EOK)
    139                 return rc;
    140        
    141         async_exch_t *exch = async_exchange_begin(iplink->sess);
    142         rc = async_req_1_0(exch, IPLINK_ADDR_REMOVE, (sysarg_t) addr_addr);
    143         async_exchange_end(exch);
    144        
    145         return rc;
    146 }
    147 
    148 static void iplink_ev_recv(iplink_t *iplink, ipc_callid_t callid,
    149     ipc_call_t *call)
    150 {
    151         iplink_sdu_t sdu;
    152        
    153         sdu.lsrc = IPC_GET_ARG1(*call);
    154         sdu.ldest = IPC_GET_ARG2(*call);
    155        
    156         int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
    157         if (rc != EOK) {
    158                 async_answer_0(callid, rc);
     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);
    159187                return;
    160188        }
    161189       
    162         rc = iplink->ev_ops->recv(iplink, &sdu);
     190        rc = iplink->ev_ops->recv(iplink, &sdu, af);
    163191        free(sdu.data);
    164         async_answer_0(callid, rc);
     192        async_answer_0(iid, rc);
    165193}
    166194
  • uspace/lib/c/generic/iplink_srv.c

    redf0d27 r02a09ed  
    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
     
    4950}
    5051
    51 static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t callid,
    52     ipc_call_t *call)
    53 {
    54         int rc = srv->ops->addr_add(srv, IPC_GET_ARG1(*call));
    55         async_answer_0(callid, rc);
    56 }
    57 
    58 static void iplink_addr_remove_srv(iplink_srv_t *srv, ipc_callid_t callid,
    59     ipc_call_t *call)
    60 {
    61         int rc = srv->ops->addr_remove(srv, IPC_GET_ARG1(*call));
    62         async_answer_0(callid, rc);
    63 }
    64 
    65 static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t callid,
    66     ipc_call_t *call)
    67 {
    68         iplink_srv_sdu_t sdu;
    69         int rc;
    70        
    71         sdu.lsrc = IPC_GET_ARG1(*call);
    72         sdu.ldest = IPC_GET_ARG2(*call);
    73        
    74         rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
    75         if (rc != EOK) {
    76                 async_answer_0(callid, rc);
    77                 return;
    78         }
     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       
     76        rc = srv->ops->addr_add(srv, &addr);
     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       
     104        rc = srv->ops->addr_remove(srv, &addr);
     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;
    79155       
    80156        rc = srv->ops->send(srv, &sdu);
    81157        free(sdu.data);
    82         async_answer_0(callid, rc);
     158        async_answer_0(iid, rc);
    83159}
    84160
     
    155231}
    156232
    157 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)
    158234{
    159235        if (srv->client_sess == NULL)
     
    163239       
    164240        ipc_call_t answer;
    165         aid_t req = async_send_2(exch, IPLINK_EV_RECV, (sysarg_t) sdu->lsrc,
    166             (sysarg_t) sdu->ldest, &answer);
     241        aid_t req = async_send_1(exch, IPLINK_EV_RECV, (sysarg_t) af,
     242            &answer);
     243       
    167244        int rc = async_data_write_start(exch, sdu->data, sdu->size);
    168245        async_exchange_end(exch);
  • uspace/lib/c/include/inet/addr.h

    redf0d27 r02a09ed  
    3838#include <stdint.h>
    3939#include <net/in.h>
     40#include <net/in6.h>
    4041
    41 #define INET_ADDR_SIZE  16
     42typedef uint32_t addr32_t;
     43typedef uint8_t addr48_t[6];
     44typedef uint8_t addr128_t[16];
    4245
    4346/** Node address */
    4447typedef struct {
    4548        uint16_t family;
    46         uint8_t addr[INET_ADDR_SIZE];
     49        union {
     50                addr32_t addr;
     51                addr128_t addr6;
     52        };
    4753} inet_addr_t;
    4854
     
    5359       
    5460        /** Address */
    55         uint8_t addr[INET_ADDR_SIZE];
     61        union {
     62                addr32_t addr;
     63                addr128_t addr6;
     64        };
    5665       
    5766        /** Number of valid bits */
     
    5968} inet_naddr_t;
    6069
    61 extern int inet_addr_family(const char *, uint16_t *);
     70extern const addr48_t addr48_broadcast;
    6271
    63 extern int inet_addr_parse(const char *, inet_addr_t *);
    64 extern int inet_naddr_parse(const char *, inet_naddr_t *);
     72extern void addr48(const addr48_t, addr48_t);
     73extern void addr128(const addr128_t, addr128_t);
    6574
    66 extern int inet_addr_format(inet_addr_t *, char **);
    67 extern int inet_naddr_format(inet_naddr_t *, char **);
    68 
    69 extern int inet_addr_pack(inet_addr_t *, uint32_t *);
    70 extern int inet_naddr_pack(inet_naddr_t *, uint32_t *, uint8_t *);
    71 
    72 extern void inet_addr_unpack(uint32_t, inet_addr_t *);
    73 extern void inet_naddr_unpack(uint32_t, uint8_t, inet_naddr_t *);
    74 
    75 extern int inet_addr_sockaddr_in(inet_addr_t *, sockaddr_in_t *);
    76 extern void inet_naddr_addr(inet_naddr_t *, inet_addr_t *);
     75extern void host2addr128_t_be(const addr128_t, addr128_t);
     76extern void addr128_t_be2host(const addr128_t, addr128_t);
    7777
    7878extern void inet_addr(inet_addr_t *, uint8_t, uint8_t, uint8_t, uint8_t);
     
    8080    uint8_t);
    8181
     82extern void inet_addr6(inet_addr_t *, uint16_t, uint16_t, uint16_t, uint16_t,
     83    uint16_t, uint16_t, uint16_t, uint16_t);
     84extern void inet_naddr6(inet_naddr_t *, uint16_t, uint16_t, uint16_t, uint16_t,
     85    uint16_t, uint16_t, uint16_t, uint16_t, uint8_t);
     86
     87extern int inet_addr_family(const char *, uint16_t *);
     88extern void inet_naddr_addr(const inet_naddr_t *, inet_addr_t *);
     89
    8290extern void inet_addr_any(inet_addr_t *);
    8391extern void inet_naddr_any(inet_naddr_t *);
    8492
    85 extern int inet_addr_compare(inet_addr_t *, inet_addr_t *);
    86 extern int inet_addr_is_any(inet_addr_t *);
     93extern int inet_addr_compare(const inet_addr_t *, const inet_addr_t *);
     94extern int inet_addr_is_any(const inet_addr_t *);
     95
     96extern int inet_naddr_compare_mask(const inet_naddr_t *, const inet_addr_t *);
     97
     98extern int inet_addr_parse(const char *, inet_addr_t *);
     99extern int inet_naddr_parse(const char *, inet_naddr_t *);
     100
     101extern int inet_addr_format(const inet_addr_t *, char **);
     102extern int inet_naddr_format(const inet_naddr_t *, char **);
     103
     104extern uint16_t inet_addr_get(const inet_addr_t *, addr32_t *, addr128_t *);
     105extern uint16_t inet_naddr_get(const inet_naddr_t *, addr32_t *, addr128_t *,
     106    uint8_t *);
     107
     108extern void inet_addr_set(addr32_t, inet_addr_t *);
     109extern void inet_naddr_set(addr32_t, uint8_t, inet_naddr_t *);
     110extern void inet_sockaddr_in_addr(const sockaddr_in_t *, inet_addr_t *);
     111
     112extern void inet_addr_set6(addr128_t, inet_addr_t *);
     113extern void inet_naddr_set6(addr128_t, uint8_t, inet_naddr_t *);
     114extern void inet_sockaddr_in6_addr(const sockaddr_in6_t *, inet_addr_t *);
     115
     116extern uint16_t inet_addr_sockaddr_in(const inet_addr_t *, sockaddr_in_t *,
     117    sockaddr_in6_t *);
    87118
    88119#endif
  • uspace/lib/c/include/inet/iplink.h

    redf0d27 r02a09ed  
    4747} iplink_t;
    4848
    49 /** IPv4 link Service Data Unit */
     49/** Internet link Service Data Unit */
    5050typedef struct {
    5151        /** Local source address */
    52         uint32_t lsrc;
     52        inet_addr_t src;
    5353        /** Local destination address */
    54         uint32_t ldest;
     54        inet_addr_t dest;
    5555        /** Serialized IP packet */
    5656        void *data;
     
    5959} iplink_sdu_t;
    6060
    61 /** IPv6 link Service Data Unit */
     61/** Internet link receive Service Data Unit */
    6262typedef struct {
    63         /** Target MAC address */
    64         uint64_t hwaddr;
    65         /** Serialized IP packet */
     63        /** Serialized datagram */
    6664        void *data;
    6765        /** Size of @c data in bytes */
    6866        size_t size;
    69 } iplink_sdu6_t;
     67} iplink_recv_sdu_t;
    7068
    7169typedef struct iplink_ev_ops {
    72         int (*recv)(iplink_t *, iplink_sdu_t *);
     70        int (*recv)(iplink_t *, iplink_recv_sdu_t *, uint16_t);
    7371} iplink_ev_ops_t;
    7472
  • uspace/lib/c/include/inet/iplink_srv.h

    redf0d27 r02a09ed  
    4040#include <stdbool.h>
    4141#include <sys/types.h>
     42#include <inet/addr.h>
     43#include <inet/iplink.h>
    4244
    4345struct iplink_ops;
     
    5153} iplink_srv_t;
    5254
    53 /** IP link Service Data Unit */
    54 typedef struct {
    55         /** Local source address */
    56         uint32_t lsrc;
    57         /** Local destination address */
    58         uint32_t ldest;
    59         /** Serialized IP packet */
    60         void *data;
    61         /** Size of @c data in bytes */
    62         size_t size;
    63 } iplink_srv_sdu_t;
    64 
    6555typedef struct iplink_ops {
    6656        int (*open)(iplink_srv_t *);
    6757        int (*close)(iplink_srv_t *);
    68         int (*send)(iplink_srv_t *, iplink_srv_sdu_t *);
     58        int (*send)(iplink_srv_t *, iplink_sdu_t *);
    6959        int (*get_mtu)(iplink_srv_t *, size_t *);
    70         int (*addr_add)(iplink_srv_t *, uint32_t);
    71         int (*addr_remove)(iplink_srv_t *, uint32_t);
     60        int (*addr_add)(iplink_srv_t *, inet_addr_t *);
     61        int (*addr_remove)(iplink_srv_t *, inet_addr_t *);
    7262} iplink_ops_t;
    7363
     
    7565
    7666extern int iplink_conn(ipc_callid_t, ipc_call_t *, void *);
    77 extern int iplink_ev_recv(iplink_srv_t *, iplink_srv_sdu_t *);
     67extern int iplink_ev_recv(iplink_srv_t *, iplink_recv_sdu_t *, uint16_t);
    7868
    7969#endif
Note: See TracChangeset for help on using the changeset viewer.