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


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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/inet.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
Note: See TracChangeset for help on using the changeset viewer.