Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/inetsrv/inetping.c

    ra1a101d r9749e47  
    11/*
    2  * Copyright (c) 2012 Jiri Svoboda
     2 * Copyright (c) 2013 Jiri Svoboda
     3 * Copyright (c) 2013 Martin Decky
    34 * All rights reserved.
    45 *
     
    4344#include <stdlib.h>
    4445#include <sys/types.h>
    45 
     46#include <types/inetping.h>
    4647#include "icmp.h"
     48#include "icmpv6.h"
    4749#include "icmp_std.h"
    4850#include "inetsrv.h"
     
    5557static uint16_t inetping_ident = 0;
    5658
    57 static inetping_client_t *inetping_client_find(uint16_t);
    58 
    5959static int inetping_send(inetping_client_t *client, inetping_sdu_t *sdu)
    6060{
    61         return icmp_ping_send(client->ident, sdu);
    62 }
    63 
    64 static int inetping_get_srcaddr(inetping_client_t *client, inet_addr_t *remote,
    65     inet_addr_t *local)
     61        if (sdu->src.version != sdu->dest.version)
     62                return EINVAL;
     63
     64        switch (sdu->src.version) {
     65        case ip_v4:
     66                return icmp_ping_send(client->ident, sdu);
     67        case ip_v6:
     68                return icmpv6_ping_send(client->ident, sdu);
     69        default:
     70                return EINVAL;
     71        }
     72}
     73
     74static int inetping_get_srcaddr(inetping_client_t *client,
     75    inet_addr_t *remote, inet_addr_t *local)
    6676{
    6777        return inet_get_srcaddr(remote, ICMP_TOS, local);
    6878}
    6979
     80static inetping_client_t *inetping_client_find(uint16_t ident)
     81{
     82        fibril_mutex_lock(&client_list_lock);
     83
     84        list_foreach(client_list, client_list, inetping_client_t, client) {
     85                if (client->ident == ident) {
     86                        fibril_mutex_unlock(&client_list_lock);
     87                        return client;
     88                }
     89        }
     90
     91        fibril_mutex_unlock(&client_list_lock);
     92        return NULL;
     93}
     94
    7095int inetping_recv(uint16_t ident, inetping_sdu_t *sdu)
    7196{
    72         inetping_client_t *client;
    73         async_exch_t *exch;
    74         ipc_call_t answer;
    75 
    76         client = inetping_client_find(ident);
     97        inetping_client_t *client = inetping_client_find(ident);
    7798        if (client == NULL) {
    7899                log_msg(LOG_DEFAULT, LVL_DEBUG, "Unknown ICMP ident. Dropping.");
     
    80101        }
    81102
    82         exch = async_exchange_begin(client->sess);
    83 
    84         aid_t req = async_send_3(exch, INETPING_EV_RECV, sdu->src.ipv4,
    85             sdu->dest.ipv4, sdu->seq_no, &answer);
    86         int rc = async_data_write_start(exch, sdu->data, sdu->size);
    87         async_exchange_end(exch);
    88 
    89         if (rc != EOK) {
     103        async_exch_t *exch = async_exchange_begin(client->sess);
     104
     105        ipc_call_t answer;
     106        aid_t req = async_send_1(exch, INETPING_EV_RECV, sdu->seq_no, &answer);
     107
     108        int rc = async_data_write_start(exch, &sdu->src, sizeof(sdu->src));
     109        if (rc != EOK) {
     110                async_exchange_end(exch);
    90111                async_forget(req);
    91112                return rc;
    92113        }
    93114
     115        rc = async_data_write_start(exch, &sdu->dest, sizeof(sdu->dest));
     116        if (rc != EOK) {
     117                async_exchange_end(exch);
     118                async_forget(req);
     119                return rc;
     120        }
     121
     122        rc = async_data_write_start(exch, sdu->data, sdu->size);
     123
     124        async_exchange_end(exch);
     125
     126        if (rc != EOK) {
     127                async_forget(req);
     128                return rc;
     129        }
     130
    94131        sysarg_t retval;
    95132        async_wait_for(req, &retval);
    96         if (retval != EOK) {
    97                 return retval;
    98         }
    99 
    100         return EOK;
    101 }
    102 
    103 static void inetping_send_srv(inetping_client_t *client, ipc_callid_t callid,
    104     ipc_call_t *call)
    105 {
     133
     134        return (int) retval;
     135}
     136
     137static void inetping_send_srv(inetping_client_t *client, ipc_callid_t iid,
     138    ipc_call_t *icall)
     139{
     140        log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_send_srv()");
     141
    106142        inetping_sdu_t sdu;
    107143        int rc;
    108144
    109         log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_send_srv()");
     145        sdu.seq_no = IPC_GET_ARG1(*icall);
     146
     147        ipc_callid_t callid;
     148        size_t size;
     149        if (!async_data_write_receive(&callid, &size)) {
     150                async_answer_0(callid, EREFUSED);
     151                async_answer_0(iid, EREFUSED);
     152                return;
     153        }
     154
     155        if (size != sizeof(sdu.src)) {
     156                async_answer_0(callid, EINVAL);
     157                async_answer_0(iid, EINVAL);
     158                return;
     159        }
     160
     161        rc = async_data_write_finalize(callid, &sdu.src, size);
     162        if (rc != EOK) {
     163                async_answer_0(callid, rc);
     164                async_answer_0(iid, rc);
     165                return;
     166        }
     167
     168        if (!async_data_write_receive(&callid, &size)) {
     169                async_answer_0(callid, EREFUSED);
     170                async_answer_0(iid, EREFUSED);
     171                return;
     172        }
     173
     174        if (size != sizeof(sdu.dest)) {
     175                async_answer_0(callid, EINVAL);
     176                async_answer_0(iid, EINVAL);
     177                return;
     178        }
     179
     180        rc = async_data_write_finalize(callid, &sdu.dest, size);
     181        if (rc != EOK) {
     182                async_answer_0(callid, rc);
     183                async_answer_0(iid, rc);
     184                return;
     185        }
    110186
    111187        rc = async_data_write_accept((void **) &sdu.data, false, 0, 0, 0,
    112188            &sdu.size);
    113189        if (rc != EOK) {
    114                 async_answer_0(callid, rc);
    115                 return;
    116         }
    117 
    118         sdu.src.ipv4 = IPC_GET_ARG1(*call);
    119         sdu.dest.ipv4 = IPC_GET_ARG2(*call);
    120         sdu.seq_no = IPC_GET_ARG3(*call);
     190                async_answer_0(iid, rc);
     191                return;
     192        }
    121193
    122194        rc = inetping_send(client, &sdu);
    123195        free(sdu.data);
    124196
    125         async_answer_0(callid, rc);
     197        async_answer_0(iid, rc);
    126198}
    127199
    128200static void inetping_get_srcaddr_srv(inetping_client_t *client,
    129     ipc_callid_t callid, ipc_call_t *call)
    130 {
     201    ipc_callid_t iid, ipc_call_t *icall)
     202{
     203        log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_get_srcaddr_srv()");
     204
     205        ipc_callid_t callid;
     206        size_t size;
     207
     208        inet_addr_t local;
    131209        inet_addr_t remote;
    132         inet_addr_t local;
    133         int rc;
    134 
    135         log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_get_srcaddr_srv()");
    136 
    137         remote.ipv4 = IPC_GET_ARG1(*call);
    138         local.ipv4 = 0;
     210
     211        if (!async_data_write_receive(&callid, &size)) {
     212                async_answer_0(callid, EREFUSED);
     213                async_answer_0(iid, EREFUSED);
     214                return;
     215        }
     216
     217        if (size != sizeof(remote)) {
     218                async_answer_0(callid, EINVAL);
     219                async_answer_0(iid, EINVAL);
     220                return;
     221        }
     222
     223        int rc = async_data_write_finalize(callid, &remote, size);
     224        if (rc != EOK) {
     225                async_answer_0(callid, rc);
     226                async_answer_0(iid, rc);
     227                return;
     228        }
    139229
    140230        rc = inetping_get_srcaddr(client, &remote, &local);
    141         async_answer_1(callid, rc, local.ipv4);
     231        if (rc != EOK) {
     232                async_answer_0(iid, rc);
     233                return;
     234        }
     235
     236        if (!async_data_read_receive(&callid, &size)) {
     237                async_answer_0(callid, EREFUSED);
     238                async_answer_0(iid, EREFUSED);
     239                return;
     240        }
     241
     242        if (size != sizeof(local)) {
     243                async_answer_0(callid, EINVAL);
     244                async_answer_0(iid, EINVAL);
     245                return;
     246        }
     247
     248        rc = async_data_read_finalize(callid, &local, size);
     249        if (rc != EOK)
     250                async_answer_0(callid, rc);
     251
     252        async_answer_0(iid, rc);
    142253}
    143254
     
    169280}
    170281
    171 static inetping_client_t *inetping_client_find(uint16_t ident)
    172 {
    173         fibril_mutex_lock(&client_list_lock);
    174 
    175         list_foreach(client_list, link) {
    176                 inetping_client_t *client = list_get_instance(link,
    177                     inetping_client_t, client_list);
    178 
    179                 if (client->ident == ident) {
    180                         fibril_mutex_unlock(&client_list_lock);
    181                         return client;
    182                 }
    183         }
    184 
    185         fibril_mutex_unlock(&client_list_lock);
    186         return NULL;
    187 }
    188 
    189282void inetping_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    190283{
    191         inetping_client_t client;
    192         int rc;
    193 
    194284        log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_conn()");
    195285
     
    197287        async_answer_0(iid, EOK);
    198288
    199         rc = inetping_client_init(&client);
     289        inetping_client_t client;
     290        int rc = inetping_client_init(&client);
    200291        if (rc != EOK)
    201292                return;
Note: See TracChangeset for help on using the changeset viewer.