Ignore:
File:
1 edited

Legend:

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

    r77ad86c rc3b25985  
    3939#include <errno.h>
    4040#include <inet/iplink.h>
     41#include <inet/addr.h>
    4142#include <ipc/iplink.h>
    4243#include <ipc/services.h>
     
    8384{
    8485        async_exch_t *exch = async_exchange_begin(iplink->sess);
    85 
    86         ipc_call_t answer;
    87         aid_t req = async_send_2(exch, IPLINK_SEND, sdu->lsrc.ipv4,
    88             sdu->ldest.ipv4, &answer);
     86       
     87        ipc_call_t answer;
     88        aid_t req = async_send_2(exch, IPLINK_SEND, (sysarg_t) sdu->src,
     89            (sysarg_t) sdu->dest, &answer);
     90       
    8991        int rc = async_data_write_start(exch, sdu->data, sdu->size);
    90         async_exchange_end(exch);
    91 
    92         if (rc != EOK) {
    93                 async_forget(req);
    94                 return rc;
    95         }
    96 
    97         sysarg_t retval;
    98         async_wait_for(req, &retval);
    99         if (retval != EOK)
    100                 return retval;
    101 
    102         return EOK;
     92       
     93        async_exchange_end(exch);
     94       
     95        if (rc != EOK) {
     96                async_forget(req);
     97                return rc;
     98        }
     99       
     100        sysarg_t retval;
     101        async_wait_for(req, &retval);
     102       
     103        return (int) retval;
     104}
     105
     106int iplink_send6(iplink_t *iplink, iplink_sdu6_t *sdu)
     107{
     108        async_exch_t *exch = async_exchange_begin(iplink->sess);
     109       
     110        ipc_call_t answer;
     111        aid_t req = async_send_0(exch, IPLINK_SEND6, &answer);
     112       
     113        int rc = async_data_write_start(exch, &sdu->dest, sizeof(addr48_t));
     114        if (rc != EOK) {
     115                async_exchange_end(exch);
     116                async_forget(req);
     117                return rc;
     118        }
     119       
     120        rc = async_data_write_start(exch, sdu->data, sdu->size);
     121       
     122        async_exchange_end(exch);
     123       
     124        if (rc != EOK) {
     125                async_forget(req);
     126                return rc;
     127        }
     128       
     129        sysarg_t retval;
     130        async_wait_for(req, &retval);
     131       
     132        return (int) retval;
    103133}
    104134
    105135int iplink_get_mtu(iplink_t *iplink, size_t *rmtu)
    106136{
     137        async_exch_t *exch = async_exchange_begin(iplink->sess);
     138       
    107139        sysarg_t mtu;
    108         async_exch_t *exch = async_exchange_begin(iplink->sess);
    109 
    110140        int rc = async_req_0_1(exch, IPLINK_GET_MTU, &mtu);
    111         async_exchange_end(exch);
    112 
     141       
     142        async_exchange_end(exch);
     143       
    113144        if (rc != EOK)
    114145                return rc;
    115 
     146       
    116147        *rmtu = mtu;
    117148        return EOK;
    118149}
    119150
    120 int iplink_addr_add(iplink_t *iplink, iplink_addr_t *addr)
    121 {
    122         async_exch_t *exch = async_exchange_begin(iplink->sess);
    123 
    124         int rc = async_req_1_0(exch, IPLINK_ADDR_ADD, (sysarg_t)addr->ipv4);
    125         async_exchange_end(exch);
    126 
    127         return rc;
    128 }
    129 
    130 int iplink_addr_remove(iplink_t *iplink, iplink_addr_t *addr)
    131 {
    132         async_exch_t *exch = async_exchange_begin(iplink->sess);
    133 
    134         int rc = async_req_1_0(exch, IPLINK_ADDR_REMOVE, (sysarg_t)addr->ipv4);
    135         async_exchange_end(exch);
    136 
    137         return rc;
    138 }
    139 
    140 static void iplink_ev_recv(iplink_t *iplink, ipc_callid_t callid,
    141     ipc_call_t *call)
    142 {
    143         int rc;
    144         iplink_sdu_t sdu;
    145 
    146         sdu.lsrc.ipv4 = IPC_GET_ARG1(*call);
    147         sdu.ldest.ipv4 = IPC_GET_ARG2(*call);
    148 
    149         rc = async_data_write_accept(&sdu.data, false, 0, 0, 0, &sdu.size);
    150         if (rc != EOK) {
    151                 async_answer_0(callid, rc);
     151int iplink_get_mac48(iplink_t *iplink, addr48_t *mac)
     152{
     153        async_exch_t *exch = async_exchange_begin(iplink->sess);
     154       
     155        ipc_call_t answer;
     156        aid_t req = async_send_0(exch, IPLINK_GET_MAC48, &answer);
     157       
     158        int rc = async_data_read_start(exch, mac, sizeof(addr48_t));
     159       
     160        loc_exchange_end(exch);
     161       
     162        if (rc != EOK) {
     163                async_forget(req);
     164                return rc;
     165        }
     166       
     167        sysarg_t retval;
     168        async_wait_for(req, &retval);
     169       
     170        return (int) retval;
     171}
     172
     173int iplink_set_mac48(iplink_t *iplink, addr48_t mac)
     174{
     175        async_exch_t *exch = async_exchange_begin(iplink->sess);
     176       
     177        ipc_call_t answer;
     178        aid_t req = async_send_0(exch, IPLINK_GET_MAC48, &answer);
     179       
     180        int rc = async_data_read_start(exch, mac, sizeof(addr48_t));
     181       
     182        loc_exchange_end(exch);
     183       
     184        if (rc != EOK) {
     185                async_forget(req);
     186                return rc;
     187        }
     188       
     189        sysarg_t retval;
     190        async_wait_for(req, &retval);
     191       
     192        return (int) retval;
     193}
     194
     195
     196int iplink_addr_add(iplink_t *iplink, inet_addr_t *addr)
     197{
     198        async_exch_t *exch = async_exchange_begin(iplink->sess);
     199       
     200        ipc_call_t answer;
     201        aid_t req = async_send_0(exch, IPLINK_ADDR_ADD, &answer);
     202       
     203        int rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
     204        async_exchange_end(exch);
     205       
     206        if (rc != EOK) {
     207                async_forget(req);
     208                return rc;
     209        }
     210       
     211        sysarg_t retval;
     212        async_wait_for(req, &retval);
     213       
     214        return (int) retval;
     215}
     216
     217int iplink_addr_remove(iplink_t *iplink, inet_addr_t *addr)
     218{
     219        async_exch_t *exch = async_exchange_begin(iplink->sess);
     220       
     221        ipc_call_t answer;
     222        aid_t req = async_send_0(exch, IPLINK_ADDR_REMOVE, &answer);
     223       
     224        int rc = async_data_write_start(exch, addr, sizeof(inet_addr_t));
     225        async_exchange_end(exch);
     226       
     227        if (rc != EOK) {
     228                async_forget(req);
     229                return rc;
     230        }
     231       
     232        sysarg_t retval;
     233        async_wait_for(req, &retval);
     234       
     235        return (int) retval;
     236}
     237
     238static void iplink_ev_recv(iplink_t *iplink, ipc_callid_t iid,
     239    ipc_call_t *icall)
     240{
     241        iplink_recv_sdu_t sdu;
     242       
     243        ip_ver_t ver = IPC_GET_ARG1(*icall);
     244       
     245        int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     246            &sdu.size);
     247        if (rc != EOK) {
     248                async_answer_0(iid, rc);
    152249                return;
    153250        }
    154 
    155         rc = iplink->ev_ops->recv(iplink, &sdu);
     251       
     252        rc = iplink->ev_ops->recv(iplink, &sdu, ver);
    156253        free(sdu.data);
    157         async_answer_0(callid, rc);
     254        async_answer_0(iid, rc);
     255}
     256
     257static void iplink_ev_change_addr(iplink_t *iplink, ipc_callid_t iid,
     258    ipc_call_t *icall)
     259{
     260        addr48_t *addr;
     261        size_t size;
     262       
     263        int rc = async_data_write_accept((void **)&addr, false,
     264            sizeof(addr48_t), sizeof(addr48_t), 0, &size);
     265        if (rc != EOK) {
     266                async_answer_0(iid, rc);
     267                return;
     268        }
     269
     270        rc = iplink->ev_ops->change_addr(iplink, *addr);
     271        free(addr);
     272        async_answer_0(iid, EOK);
    158273}
    159274
    160275static void iplink_cb_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    161276{
    162         iplink_t *iplink = (iplink_t *)arg;
    163 
     277        iplink_t *iplink = (iplink_t *) arg;
     278       
    164279        while (true) {
    165280                ipc_call_t call;
    166281                ipc_callid_t callid = async_get_call(&call);
    167 
     282               
    168283                if (!IPC_GET_IMETHOD(call)) {
    169284                        /* TODO: Handle hangup */
    170285                        return;
    171286                }
    172 
     287               
    173288                switch (IPC_GET_IMETHOD(call)) {
    174289                case IPLINK_EV_RECV:
    175290                        iplink_ev_recv(iplink, callid, &call);
    176291                        break;
     292                case IPLINK_EV_CHANGE_ADDR:
     293                        iplink_ev_change_addr(iplink, callid, &call);
    177294                default:
    178295                        async_answer_0(callid, ENOTSUP);
Note: See TracChangeset for help on using the changeset viewer.