Changes in uspace/srv/net/inetsrv/inetping.c [9749e47:a1a101d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/inetsrv/inetping.c
r9749e47 ra1a101d 1 1 /* 2 * Copyright (c) 2013 Jiri Svoboda 3 * Copyright (c) 2013 Martin Decky 2 * Copyright (c) 2012 Jiri Svoboda 4 3 * All rights reserved. 5 4 * … … 44 43 #include <stdlib.h> 45 44 #include <sys/types.h> 46 #include <types/inetping.h> 45 47 46 #include "icmp.h" 48 #include "icmpv6.h"49 47 #include "icmp_std.h" 50 48 #include "inetsrv.h" … … 57 55 static uint16_t inetping_ident = 0; 58 56 57 static inetping_client_t *inetping_client_find(uint16_t); 58 59 59 static int inetping_send(inetping_client_t *client, inetping_sdu_t *sdu) 60 60 { 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 74 static int inetping_get_srcaddr(inetping_client_t *client, 75 inet_addr_t *remote, inet_addr_t *local) 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) 76 66 { 77 67 return inet_get_srcaddr(remote, ICMP_TOS, local); 78 68 } 79 69 70 int inetping_recv(uint16_t ident, inetping_sdu_t *sdu) 71 { 72 inetping_client_t *client; 73 async_exch_t *exch; 74 ipc_call_t answer; 75 76 client = inetping_client_find(ident); 77 if (client == NULL) { 78 log_msg(LOG_DEFAULT, LVL_DEBUG, "Unknown ICMP ident. Dropping."); 79 return ENOENT; 80 } 81 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) { 90 async_forget(req); 91 return rc; 92 } 93 94 sysarg_t retval; 95 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 { 106 inetping_sdu_t sdu; 107 int rc; 108 109 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_send_srv()"); 110 111 rc = async_data_write_accept((void **) &sdu.data, false, 0, 0, 0, 112 &sdu.size); 113 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); 121 122 rc = inetping_send(client, &sdu); 123 free(sdu.data); 124 125 async_answer_0(callid, rc); 126 } 127 128 static void inetping_get_srcaddr_srv(inetping_client_t *client, 129 ipc_callid_t callid, ipc_call_t *call) 130 { 131 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; 139 140 rc = inetping_get_srcaddr(client, &remote, &local); 141 async_answer_1(callid, rc, local.ipv4); 142 } 143 144 static int inetping_client_init(inetping_client_t *client) 145 { 146 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE); 147 if (sess == NULL) 148 return ENOMEM; 149 150 client->sess = sess; 151 link_initialize(&client->client_list); 152 153 fibril_mutex_lock(&client_list_lock); 154 client->ident = ++inetping_ident; 155 list_append(&client->client_list, &client_list); 156 fibril_mutex_unlock(&client_list_lock); 157 158 return EOK; 159 } 160 161 static void inetping_client_fini(inetping_client_t *client) 162 { 163 async_hangup(client->sess); 164 client->sess = NULL; 165 166 fibril_mutex_lock(&client_list_lock); 167 list_remove(&client->client_list); 168 fibril_mutex_unlock(&client_list_lock); 169 } 170 80 171 static inetping_client_t *inetping_client_find(uint16_t ident) 81 172 { 82 173 fibril_mutex_lock(&client_list_lock); 83 174 84 list_foreach(client_list, client_list, inetping_client_t, client) { 175 list_foreach(client_list, link) { 176 inetping_client_t *client = list_get_instance(link, 177 inetping_client_t, client_list); 178 85 179 if (client->ident == ident) { 86 180 fibril_mutex_unlock(&client_list_lock); … … 93 187 } 94 188 95 int inetping_recv(uint16_t ident, inetping_sdu_t *sdu) 96 { 97 inetping_client_t *client = inetping_client_find(ident); 98 if (client == NULL) { 99 log_msg(LOG_DEFAULT, LVL_DEBUG, "Unknown ICMP ident. Dropping."); 100 return ENOENT; 101 } 102 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); 111 async_forget(req); 112 return rc; 113 } 114 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 131 sysarg_t retval; 132 async_wait_for(req, &retval); 133 134 return (int) retval; 135 } 136 137 static 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 142 inetping_sdu_t sdu; 189 void inetping_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 190 { 191 inetping_client_t client; 143 192 int rc; 144 193 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 }186 187 rc = async_data_write_accept((void **) &sdu.data, false, 0, 0, 0,188 &sdu.size);189 if (rc != EOK) {190 async_answer_0(iid, rc);191 return;192 }193 194 rc = inetping_send(client, &sdu);195 free(sdu.data);196 197 async_answer_0(iid, rc);198 }199 200 static void inetping_get_srcaddr_srv(inetping_client_t *client,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;209 inet_addr_t remote;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 }229 230 rc = inetping_get_srcaddr(client, &remote, &local);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);253 }254 255 static int inetping_client_init(inetping_client_t *client)256 {257 async_sess_t *sess = async_callback_receive(EXCHANGE_SERIALIZE);258 if (sess == NULL)259 return ENOMEM;260 261 client->sess = sess;262 link_initialize(&client->client_list);263 264 fibril_mutex_lock(&client_list_lock);265 client->ident = ++inetping_ident;266 list_append(&client->client_list, &client_list);267 fibril_mutex_unlock(&client_list_lock);268 269 return EOK;270 }271 272 static void inetping_client_fini(inetping_client_t *client)273 {274 async_hangup(client->sess);275 client->sess = NULL;276 277 fibril_mutex_lock(&client_list_lock);278 list_remove(&client->client_list);279 fibril_mutex_unlock(&client_list_lock);280 }281 282 void inetping_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)283 {284 194 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_conn()"); 285 195 … … 287 197 async_answer_0(iid, EOK); 288 198 289 inetping_client_t client; 290 int rc = inetping_client_init(&client); 199 rc = inetping_client_init(&client); 291 200 if (rc != EOK) 292 201 return;
Note:
See TracChangeset
for help on using the changeset viewer.