Changes in uspace/srv/net/inetsrv/inetping.c [9749e47:02a09ed] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/inetsrv/inetping.c
r9749e47 r02a09ed 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 #include <net/socket_codes.h> 47 46 #include "icmp.h" 48 #include "icmpv6.h"49 47 #include "icmp_std.h" 50 48 #include "inetsrv.h" … … 59 57 static int inetping_send(inetping_client_t *client, inetping_sdu_t *sdu) 60 58 { 61 if (sdu->src.version != sdu->dest.version) 59 return icmp_ping_send(client->ident, sdu); 60 } 61 62 static int inetping_get_srcaddr(inetping_client_t *client, addr32_t remote, 63 addr32_t *local) 64 { 65 inet_addr_t remote_addr; 66 inet_addr_set(remote, &remote_addr); 67 68 inet_addr_t local_addr; 69 int rc = inet_get_srcaddr(&remote_addr, ICMP_TOS, &local_addr); 70 if (rc != EOK) 71 return rc; 72 73 uint16_t family = inet_addr_get(&local_addr, local, NULL); 74 if (family != AF_INET) 62 75 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) 76 { 77 return inet_get_srcaddr(remote, ICMP_TOS, local); 76 77 return EOK; 78 78 } 79 79 … … 81 81 { 82 82 fibril_mutex_lock(&client_list_lock); 83 84 list_foreach(client_list, client_list, inetping_client_t, client) { 83 84 list_foreach(client_list, link) { 85 inetping_client_t *client = list_get_instance(link, 86 inetping_client_t, client_list); 87 85 88 if (client->ident == ident) { 86 89 fibril_mutex_unlock(&client_list_lock); … … 88 91 } 89 92 } 90 93 91 94 fibril_mutex_unlock(&client_list_lock); 92 95 return NULL; … … 100 103 return ENOENT; 101 104 } 102 105 103 106 async_exch_t *exch = async_exchange_begin(client->sess); 104 107 105 108 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 109 aid_t req = async_send_3(exch, INETPING_EV_RECV, (sysarg_t) sdu->src, 110 (sysarg_t) sdu->dest, sdu->seq_no, &answer); 111 int rc = async_data_write_start(exch, sdu->data, sdu->size); 112 124 113 async_exchange_end(exch); 125 114 126 115 if (rc != EOK) { 127 116 async_forget(req); 128 117 return rc; 129 118 } 130 119 131 120 sysarg_t retval; 132 121 async_wait_for(req, &retval); 133 122 134 123 return (int) retval; 135 124 } 136 125 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 126 static void inetping_send_srv(inetping_client_t *client, ipc_callid_t callid, 127 ipc_call_t *call) 128 { 142 129 inetping_sdu_t sdu; 143 130 int rc; 144 131 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 } 132 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_send_srv()"); 186 133 187 134 rc = async_data_write_accept((void **) &sdu.data, false, 0, 0, 0, 188 135 &sdu.size); 189 136 if (rc != EOK) { 190 async_answer_0( iid, rc);137 async_answer_0(callid, rc); 191 138 return; 192 139 } 140 141 sdu.src = IPC_GET_ARG1(*call); 142 sdu.dest = IPC_GET_ARG2(*call); 143 sdu.seq_no = IPC_GET_ARG3(*call); 193 144 194 145 rc = inetping_send(client, &sdu); 195 146 free(sdu.data); 196 147 197 async_answer_0( iid, rc);148 async_answer_0(callid, rc); 198 149 } 199 150 200 151 static void inetping_get_srcaddr_srv(inetping_client_t *client, 201 ipc_callid_t iid, ipc_call_t *icall)152 ipc_callid_t callid, ipc_call_t *call) 202 153 { 203 154 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); 155 156 uint32_t remote = IPC_GET_ARG1(*call); 157 uint32_t local = 0; 158 159 int rc = inetping_get_srcaddr(client, remote, &local); 160 async_answer_1(callid, rc, (sysarg_t) local); 253 161 } 254 162 … … 258 166 if (sess == NULL) 259 167 return ENOMEM; 260 168 261 169 client->sess = sess; 262 170 link_initialize(&client->client_list); 263 171 264 172 fibril_mutex_lock(&client_list_lock); 265 173 client->ident = ++inetping_ident; 266 174 list_append(&client->client_list, &client_list); 267 175 fibril_mutex_unlock(&client_list_lock); 268 176 269 177 return EOK; 270 178 } … … 274 182 async_hangup(client->sess); 275 183 client->sess = NULL; 276 184 277 185 fibril_mutex_lock(&client_list_lock); 278 186 list_remove(&client->client_list); … … 283 191 { 284 192 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_conn()"); 285 193 286 194 /* Accept the connection */ 287 195 async_answer_0(iid, EOK); 288 196 289 197 inetping_client_t client; 290 198 int rc = inetping_client_init(&client); 291 199 if (rc != EOK) 292 200 return; 293 201 294 202 while (true) { 295 203 ipc_call_t call; 296 204 ipc_callid_t callid = async_get_call(&call); 297 205 sysarg_t method = IPC_GET_IMETHOD(call); 298 206 299 207 if (!method) { 300 208 /* The other side has hung up */ … … 302 210 break; 303 211 } 304 212 305 213 switch (method) { 306 214 case INETPING_SEND: … … 314 222 } 315 223 } 316 224 317 225 inetping_client_fini(&client); 318 226 }
Note:
See TracChangeset
for help on using the changeset viewer.