Ignore:
File:
1 edited

Legend:

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

    r4802dd7 rc3b25985  
    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{
     47        size_t mtu;
     48        int rc = srv->ops->get_mtu(srv, &mtu);
     49        async_answer_1(callid, rc, mtu);
     50}
     51
     52static void iplink_get_mac48_srv(iplink_srv_t *srv, ipc_callid_t iid,
     53    ipc_call_t *icall)
     54{
     55        addr48_t mac;
     56        int rc = srv->ops->get_mac48(srv, &mac);
     57        if (rc != EOK) {
     58                async_answer_0(iid, rc);
     59                return;
     60        }
     61       
     62        ipc_callid_t callid;
     63        size_t size;
     64        if (!async_data_read_receive(&callid, &size)) {
     65                async_answer_0(callid, EREFUSED);
     66                async_answer_0(iid, EREFUSED);
     67                return;
     68        }
     69       
     70        if (size != sizeof(addr48_t)) {
     71                async_answer_0(callid, EINVAL);
     72                async_answer_0(iid, EINVAL);
     73                return;
     74        }
     75       
     76        rc = async_data_read_finalize(callid, &mac, size);
     77        if (rc != EOK)
     78                async_answer_0(callid, rc);
     79       
     80        async_answer_0(iid, (sysarg_t) rc);
     81}
     82
     83static void iplink_set_mac48_srv(iplink_srv_t *srv, ipc_callid_t iid,
     84    ipc_call_t *icall)
     85{
    4686        int rc;
    47         size_t mtu;
    48 
    49         rc = srv->ops->get_mtu(srv, &mtu);
    50         async_answer_1(callid, rc, mtu);
    51 }
    52 
    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 
     87        size_t size;
     88        addr48_t mac;
     89        ipc_callid_t callid;
     90
     91        rc = async_data_write_receive(&callid, &size);
     92        if (rc != EOK) {
     93                async_answer_0(callid, (sysarg_t) rc);
     94                async_answer_0(iid, (sysarg_t) rc);
     95        }
     96
     97        rc = srv->ops->set_mac48(srv, &mac);
     98        if (rc != EOK) {
     99                async_answer_0(iid, rc);
     100                return;
     101        }
     102       
     103        rc = async_data_read_finalize(callid, &mac, sizeof(addr48_t));
     104        if (rc != EOK)
     105                async_answer_0(callid, rc);
     106       
     107        async_answer_0(iid, (sysarg_t) rc);
     108}
     109
     110static void iplink_addr_add_srv(iplink_srv_t *srv, ipc_callid_t iid,
     111    ipc_call_t *icall)
     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        inet_addr_t addr;
     128        int rc = async_data_write_finalize(callid, &addr, size);
     129        if (rc != EOK) {
     130                async_answer_0(callid, (sysarg_t) rc);
     131                async_answer_0(iid, (sysarg_t) rc);
     132        }
     133       
    61134        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 
     135        async_answer_0(iid, (sysarg_t) rc);
     136}
     137
     138static void iplink_addr_remove_srv(iplink_srv_t *srv, ipc_callid_t iid,
     139    ipc_call_t *icall)
     140{
     141        ipc_callid_t callid;
     142        size_t size;
     143        if (!async_data_write_receive(&callid, &size)) {
     144                async_answer_0(callid, EREFUSED);
     145                async_answer_0(iid, EREFUSED);
     146                return;
     147        }
     148       
     149        if (size != sizeof(inet_addr_t)) {
     150                async_answer_0(callid, EINVAL);
     151                async_answer_0(iid, EINVAL);
     152                return;
     153        }
     154       
     155        inet_addr_t addr;
     156        int rc = async_data_write_finalize(callid, &addr, size);
     157        if (rc != EOK) {
     158                async_answer_0(callid, (sysarg_t) rc);
     159                async_answer_0(iid, (sysarg_t) rc);
     160        }
     161       
    73162        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 
     163        async_answer_0(iid, (sysarg_t) rc);
     164}
     165
     166static void iplink_send_srv(iplink_srv_t *srv, ipc_callid_t iid,
     167    ipc_call_t *icall)
     168{
     169        iplink_sdu_t sdu;
     170       
     171        sdu.src = IPC_GET_ARG1(*icall);
     172        sdu.dest = IPC_GET_ARG2(*icall);
     173       
     174        int rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     175            &sdu.size);
     176        if (rc != EOK) {
     177                async_answer_0(iid, rc);
     178                return;
     179        }
     180       
    92181        rc = srv->ops->send(srv, &sdu);
    93182        free(sdu.data);
    94         async_answer_0(callid, rc);
     183        async_answer_0(iid, rc);
     184}
     185
     186static void iplink_send6_srv(iplink_srv_t *srv, ipc_callid_t iid,
     187    ipc_call_t *icall)
     188{
     189        iplink_sdu6_t sdu;
     190       
     191        ipc_callid_t callid;
     192        size_t size;
     193        if (!async_data_write_receive(&callid, &size)) {
     194                async_answer_0(callid, EREFUSED);
     195                async_answer_0(iid, EREFUSED);
     196                return;
     197        }
     198       
     199        if (size != sizeof(addr48_t)) {
     200                async_answer_0(callid, EINVAL);
     201                async_answer_0(iid, EINVAL);
     202                return;
     203        }
     204       
     205        int rc = async_data_write_finalize(callid, &sdu.dest, size);
     206        if (rc != EOK) {
     207                async_answer_0(callid, (sysarg_t) rc);
     208                async_answer_0(iid, (sysarg_t) rc);
     209        }
     210       
     211        rc = async_data_write_accept(&sdu.data, false, 0, 0, 0,
     212            &sdu.size);
     213        if (rc != EOK) {
     214                async_answer_0(iid, rc);
     215                return;
     216        }
     217       
     218        rc = srv->ops->send6(srv, &sdu);
     219        free(sdu.data);
     220        async_answer_0(iid, rc);
    95221}
    96222
     
    106232int iplink_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    107233{
    108         iplink_srv_t *srv = (iplink_srv_t *)arg;
     234        iplink_srv_t *srv = (iplink_srv_t *) arg;
    109235        int rc;
    110 
     236       
    111237        fibril_mutex_lock(&srv->lock);
    112238        if (srv->connected) {
     
    115241                return EBUSY;
    116242        }
    117 
     243       
    118244        srv->connected = true;
    119245        fibril_mutex_unlock(&srv->lock);
    120 
     246       
    121247        /* Accept the connection */
    122248        async_answer_0(iid, EOK);
    123 
     249       
    124250        async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);
    125251        if (sess == NULL)
    126252                return ENOMEM;
    127 
     253       
    128254        srv->client_sess = sess;
    129 
     255       
    130256        rc = srv->ops->open(srv);
    131257        if (rc != EOK)
    132258                return rc;
    133 
     259       
    134260        while (true) {
    135261                ipc_call_t call;
    136262                ipc_callid_t callid = async_get_call(&call);
    137263                sysarg_t method = IPC_GET_IMETHOD(call);
    138 
     264               
    139265                if (!method) {
    140266                        /* The other side has hung up */
    141                         fibril_mutex_lock(&srv->lock);
     267                        fibril_mutex_lock(&srv->lock);
    142268                        srv->connected = false;
    143                         fibril_mutex_unlock(&srv->lock);
     269                        fibril_mutex_unlock(&srv->lock);
    144270                        async_answer_0(callid, EOK);
    145271                        break;
    146272                }
    147 
     273               
    148274                switch (method) {
    149275                case IPLINK_GET_MTU:
    150276                        iplink_get_mtu_srv(srv, callid, &call);
    151277                        break;
     278                case IPLINK_GET_MAC48:
     279                        iplink_get_mac48_srv(srv, callid, &call);
     280                        break;
     281                case IPLINK_SET_MAC48:
     282                        iplink_set_mac48_srv(srv, callid, &call);
     283                        break;
    152284                case IPLINK_SEND:
    153285                        iplink_send_srv(srv, callid, &call);
     286                        break;
     287                case IPLINK_SEND6:
     288                        iplink_send6_srv(srv, callid, &call);
    154289                        break;
    155290                case IPLINK_ADDR_ADD:
     
    163298                }
    164299        }
    165 
     300       
    166301        return srv->ops->close(srv);
    167302}
    168303
    169 int iplink_ev_recv(iplink_srv_t *srv, iplink_srv_sdu_t *sdu)
     304/* XXX Version should be part of @a sdu */
     305int iplink_ev_recv(iplink_srv_t *srv, iplink_recv_sdu_t *sdu, ip_ver_t ver)
    170306{
    171307        if (srv->client_sess == NULL)
    172308                return EIO;
    173 
     309       
    174310        async_exch_t *exch = async_exchange_begin(srv->client_sess);
    175 
     311       
    176312        ipc_call_t answer;
    177         aid_t req = async_send_2(exch, IPLINK_EV_RECV, sdu->lsrc.ipv4,
    178             sdu->ldest.ipv4, &answer);
     313        aid_t req = async_send_1(exch, IPLINK_EV_RECV, (sysarg_t)ver,
     314            &answer);
     315       
    179316        int rc = async_data_write_start(exch, sdu->data, sdu->size);
    180317        async_exchange_end(exch);
    181 
     318       
    182319        if (rc != EOK) {
    183320                async_forget(req);
    184321                return rc;
    185322        }
    186 
     323       
    187324        sysarg_t retval;
    188325        async_wait_for(req, &retval);
    189326        if (retval != EOK)
    190327                return retval;
    191 
     328       
     329        return EOK;
     330}
     331
     332int iplink_ev_change_addr(iplink_srv_t *srv, addr48_t *addr)
     333{
     334        if (srv->client_sess == NULL)
     335                return EIO;
     336       
     337        async_exch_t *exch = async_exchange_begin(srv->client_sess);
     338       
     339        ipc_call_t answer;
     340        aid_t req = async_send_0(exch, IPLINK_EV_CHANGE_ADDR, &answer);
     341       
     342        int rc = async_data_write_start(exch, addr, sizeof(addr48_t));
     343        async_exchange_end(exch);
     344       
     345        if (rc != EOK) {
     346                async_forget(req);
     347                return rc;
     348        }
     349       
     350        sysarg_t retval;
     351        async_wait_for(req, &retval);
     352        if (retval != EOK)
     353                return retval;
     354       
    192355        return EOK;
    193356}
Note: See TracChangeset for help on using the changeset viewer.