Changes in uspace/srv/net/inetsrv/inetping.c [a1a101d:9749e47] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/inetsrv/inetping.c
ra1a101d r9749e47 1 1 /* 2 * Copyright (c) 2012 Jiri Svoboda 2 * Copyright (c) 2013 Jiri Svoboda 3 * Copyright (c) 2013 Martin Decky 3 4 * All rights reserved. 4 5 * … … 43 44 #include <stdlib.h> 44 45 #include <sys/types.h> 45 46 #include <types/inetping.h> 46 47 #include "icmp.h" 48 #include "icmpv6.h" 47 49 #include "icmp_std.h" 48 50 #include "inetsrv.h" … … 55 57 static uint16_t inetping_ident = 0; 56 58 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 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 74 static int inetping_get_srcaddr(inetping_client_t *client, 75 inet_addr_t *remote, inet_addr_t *local) 66 76 { 67 77 return inet_get_srcaddr(remote, ICMP_TOS, local); 68 78 } 69 79 80 static 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 70 95 int inetping_recv(uint16_t ident, inetping_sdu_t *sdu) 71 96 { 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); 77 98 if (client == NULL) { 78 99 log_msg(LOG_DEFAULT, LVL_DEBUG, "Unknown ICMP ident. Dropping."); … … 80 101 } 81 102 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); 90 111 async_forget(req); 91 112 return rc; 92 113 } 93 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 94 131 sysarg_t retval; 95 132 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 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 106 142 inetping_sdu_t sdu; 107 143 int rc; 108 144 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 } 110 186 111 187 rc = async_data_write_accept((void **) &sdu.data, false, 0, 0, 0, 112 188 &sdu.size); 113 189 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 } 121 193 122 194 rc = inetping_send(client, &sdu); 123 195 free(sdu.data); 124 196 125 async_answer_0( callid, rc);197 async_answer_0(iid, rc); 126 198 } 127 199 128 200 static 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; 131 209 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 } 139 229 140 230 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); 142 253 } 143 254 … … 169 280 } 170 281 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 189 282 void inetping_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 190 283 { 191 inetping_client_t client;192 int rc;193 194 284 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetping_conn()"); 195 285 … … 197 287 async_answer_0(iid, EOK); 198 288 199 rc = inetping_client_init(&client); 289 inetping_client_t client; 290 int rc = inetping_client_init(&client); 200 291 if (rc != EOK) 201 292 return;
Note:
See TracChangeset
for help on using the changeset viewer.