source: mainline/uspace/lib/inet/src/inetcfg.c@ d5ed54b

serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d5ed54b was ec7902d, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Move TCP/IP library support out of libc to separate library

  • Property mode set to 100644
File size: 10.6 KB
RevLine 
[0e25780]1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <async.h>
30#include <assert.h>
31#include <errno.h>
32#include <inet/inetcfg.h>
33#include <ipc/inet.h>
34#include <ipc/services.h>
35#include <loc.h>
36#include <stdlib.h>
[0e94b979]37#include <str.h>
[0e25780]38
39static async_sess_t *inetcfg_sess = NULL;
40
[b7fd2a0]41static errno_t inetcfg_get_ids_once(sysarg_t method, sysarg_t arg1,
[0e25780]42 sysarg_t *id_buf, size_t buf_size, size_t *act_size)
43{
44 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
45
46 ipc_call_t answer;
47 aid_t req = async_send_1(exch, method, arg1, &answer);
[b7fd2a0]48 errno_t rc = async_data_read_start(exch, id_buf, buf_size);
[0e25780]49
50 async_exchange_end(exch);
51
52 if (rc != EOK) {
[50b581d]53 async_forget(req);
[0e25780]54 return rc;
55 }
56
[b7fd2a0]57 errno_t retval;
[0e25780]58 async_wait_for(req, &retval);
59
60 if (retval != EOK) {
61 return retval;
62 }
63
[fafb8e5]64 *act_size = ipc_get_arg1(&answer);
[0e25780]65 return EOK;
66}
67
68/** Get list of IDs.
69 *
70 * Returns an allocated array of service IDs.
71 *
72 * @param method IPC method
73 * @param arg1 IPC argument 1
74 * @param data Place to store pointer to array of IDs
75 * @param count Place to store number of IDs
[cde999a]76 * @return EOK on success or an error code
[0e25780]77 */
[b7fd2a0]78static errno_t inetcfg_get_ids_internal(sysarg_t method, sysarg_t arg1,
[0e25780]79 sysarg_t **data, size_t *count)
80{
81 *data = NULL;
82 *count = 0;
83
84 size_t act_size = 0;
[b7fd2a0]85 errno_t rc = inetcfg_get_ids_once(method, arg1, NULL, 0,
[0e25780]86 &act_size);
87 if (rc != EOK)
88 return rc;
89
90 size_t alloc_size = act_size;
91 service_id_t *ids = malloc(alloc_size);
92 if (ids == NULL)
93 return ENOMEM;
94
95 while (true) {
96 rc = inetcfg_get_ids_once(method, arg1, ids, alloc_size,
97 &act_size);
98 if (rc != EOK)
99 return rc;
100
101 if (act_size <= alloc_size)
102 break;
103
104 alloc_size = act_size;
[ec506d49]105 service_id_t *tmp = realloc(ids, alloc_size);
106 if (tmp == NULL) {
107 free(ids);
[0e25780]108 return ENOMEM;
[ec506d49]109 }
110 ids = tmp;
[0e25780]111 }
112
113 *count = act_size / sizeof(sysarg_t);
114 *data = ids;
115 return EOK;
116}
117
[b7fd2a0]118errno_t inetcfg_init(void)
[0e25780]119{
120 service_id_t inet_svc;
[b7fd2a0]121 errno_t rc;
[0e25780]122
123 assert(inetcfg_sess == NULL);
[a35b458]124
[f9b2cb4c]125 rc = loc_service_get_id(SERVICE_NAME_INET, &inet_svc,
[0e25780]126 IPC_FLAG_BLOCKING);
127 if (rc != EOK)
128 return ENOENT;
[a35b458]129
[f9b2cb4c]130 inetcfg_sess = loc_service_connect(inet_svc, INTERFACE_INETCFG,
[0e25780]131 IPC_FLAG_BLOCKING);
132 if (inetcfg_sess == NULL)
133 return ENOENT;
[a35b458]134
[0e25780]135 return EOK;
136}
137
[b7fd2a0]138errno_t inetcfg_addr_create_static(const char *name, inet_naddr_t *naddr,
[45aa22c]139 sysarg_t link_id, sysarg_t *addr_id)
[0e25780]140{
141 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[a35b458]142
[291c792]143 ipc_call_t answer;
[02a09ed]144 aid_t req = async_send_1(exch, INETCFG_ADDR_CREATE_STATIC, link_id,
145 &answer);
[a35b458]146
[b7fd2a0]147 errno_t rc = async_data_write_start(exch, naddr, sizeof(inet_naddr_t));
[02a09ed]148 if (rc != EOK) {
149 async_exchange_end(exch);
150 async_forget(req);
151 return rc;
152 }
[a35b458]153
[02a09ed]154 rc = async_data_write_start(exch, name, str_size(name));
[a35b458]155
[0e25780]156 async_exchange_end(exch);
[a35b458]157
[02a09ed]158 if (rc != EOK) {
[50b581d]159 async_forget(req);
[02a09ed]160 return rc;
[291c792]161 }
[a35b458]162
[b7fd2a0]163 errno_t retval;
[291c792]164 async_wait_for(req, &retval);
[a35b458]165
[fafb8e5]166 *addr_id = ipc_get_arg1(&answer);
[a35b458]167
[25a179e]168 return retval;
[0e25780]169}
170
[b7fd2a0]171errno_t inetcfg_addr_delete(sysarg_t addr_id)
[0e25780]172{
173 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
174
[b7fd2a0]175 errno_t rc = async_req_1_0(exch, INETCFG_ADDR_DELETE, addr_id);
[0e25780]176 async_exchange_end(exch);
177
178 return rc;
179}
180
[b7fd2a0]181errno_t inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
[0e25780]182{
183 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[a35b458]184
[0e94b979]185 ipc_call_t answer;
186 aid_t req = async_send_1(exch, INETCFG_ADDR_GET, addr_id, &answer);
[a35b458]187
[02a09ed]188 ipc_call_t answer_naddr;
189 aid_t req_naddr = async_data_read(exch, &ainfo->naddr,
190 sizeof(inet_naddr_t), &answer_naddr);
[a35b458]191
[b7fd2a0]192 errno_t retval_naddr;
[02a09ed]193 async_wait_for(req_naddr, &retval_naddr);
[a35b458]194
[02a09ed]195 if (retval_naddr != EOK) {
196 async_exchange_end(exch);
197 async_forget(req);
[25a179e]198 return retval_naddr;
[02a09ed]199 }
[a35b458]200
[02a09ed]201 ipc_call_t answer_name;
202 char name_buf[LOC_NAME_MAXLEN + 1];
203 aid_t req_name = async_data_read(exch, name_buf, LOC_NAME_MAXLEN,
204 &answer_name);
[a35b458]205
[0e25780]206 async_exchange_end(exch);
[a35b458]207
[b7fd2a0]208 errno_t retval_name;
[02a09ed]209 async_wait_for(req_name, &retval_name);
[a35b458]210
[02a09ed]211 if (retval_name != EOK) {
[50b581d]212 async_forget(req);
[25a179e]213 return retval_name;
[0e94b979]214 }
[a35b458]215
[b7fd2a0]216 errno_t retval;
[0e94b979]217 async_wait_for(req, &retval);
[a35b458]218
[0e94b979]219 if (retval != EOK)
[25a179e]220 return retval;
[a35b458]221
[fafb8e5]222 size_t act_size = ipc_get_arg2(&answer_name);
[0e94b979]223 assert(act_size <= LOC_NAME_MAXLEN);
[a35b458]224
[0e94b979]225 name_buf[act_size] = '\0';
[a35b458]226
[fafb8e5]227 ainfo->ilink = ipc_get_arg1(&answer);
[0e94b979]228 ainfo->name = str_dup(name_buf);
[a35b458]229
[0e25780]230 return EOK;
231}
232
[b7fd2a0]233errno_t inetcfg_addr_get_id(const char *name, sysarg_t link_id, sysarg_t *addr_id)
[fa101c4]234{
235 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
236
237 ipc_call_t answer;
238 aid_t req = async_send_1(exch, INETCFG_ADDR_GET_ID, link_id, &answer);
[b7fd2a0]239 errno_t retval = async_data_write_start(exch, name, str_size(name));
[fa101c4]240
241 async_exchange_end(exch);
242
243 if (retval != EOK) {
[50b581d]244 async_forget(req);
[fa101c4]245 return retval;
246 }
247
248 async_wait_for(req, &retval);
[fafb8e5]249 *addr_id = ipc_get_arg1(&answer);
[fa101c4]250
251 return retval;
252}
253
[b7fd2a0]254errno_t inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
[0e25780]255{
256 return inetcfg_get_ids_internal(INETCFG_GET_ADDR_LIST,
257 0, addrs, count);
258}
259
[b7fd2a0]260errno_t inetcfg_get_link_list(sysarg_t **links, size_t *count)
[0e25780]261{
262 return inetcfg_get_ids_internal(INETCFG_GET_LINK_LIST,
263 0, links, count);
264}
265
[b7fd2a0]266errno_t inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
[8bf672d]267{
268 return inetcfg_get_ids_internal(INETCFG_GET_SROUTE_LIST,
269 0, sroutes, count);
270}
271
[b7fd2a0]272errno_t inetcfg_link_add(sysarg_t link_id)
[7af0cc5]273{
274 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
275
[b7fd2a0]276 errno_t rc = async_req_1_0(exch, INETCFG_LINK_ADD, link_id);
[7af0cc5]277 async_exchange_end(exch);
278
279 return rc;
280}
281
[b7fd2a0]282errno_t inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
[0e25780]283{
[0e94b979]284 ipc_call_t dreply;
[b7fd2a0]285 errno_t dretval;
[0e94b979]286 size_t act_size;
287 char name_buf[LOC_NAME_MAXLEN + 1];
288
[0e25780]289 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
290
[0e94b979]291 ipc_call_t answer;
292 aid_t req = async_send_1(exch, INETCFG_LINK_GET, link_id, &answer);
293 aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
[b7fd2a0]294 errno_t rc = async_data_read_start(exch, &linfo->mac_addr, sizeof(addr48_t));
[0e94b979]295 async_wait_for(dreq, &dretval);
296
[0e25780]297 async_exchange_end(exch);
298
[b8b1adb1]299 if (dretval != EOK || rc != EOK) {
[50b581d]300 async_forget(req);
[0e94b979]301 return dretval;
302 }
303
[b7fd2a0]304 errno_t retval;
[0e94b979]305 async_wait_for(req, &retval);
306
307 if (retval != EOK)
308 return retval;
309
[fafb8e5]310 act_size = ipc_get_arg2(&dreply);
[0e94b979]311 assert(act_size <= LOC_NAME_MAXLEN);
312 name_buf[act_size] = '\0';
313
314 linfo->name = str_dup(name_buf);
[fafb8e5]315 linfo->def_mtu = ipc_get_arg1(&answer);
[0e25780]316
317 return EOK;
318}
319
[b7fd2a0]320errno_t inetcfg_link_remove(sysarg_t link_id)
[7af0cc5]321{
322 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
323
[b7fd2a0]324 errno_t rc = async_req_1_0(exch, INETCFG_LINK_REMOVE, link_id);
[7af0cc5]325 async_exchange_end(exch);
326
327 return rc;
328}
329
[b7fd2a0]330errno_t inetcfg_sroute_create(const char *name, inet_naddr_t *dest,
[8bf672d]331 inet_addr_t *router, sysarg_t *sroute_id)
332{
[02a09ed]333 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[a35b458]334
[02a09ed]335 ipc_call_t answer;
336 aid_t req = async_send_0(exch, INETCFG_SROUTE_CREATE, &answer);
[a35b458]337
[b7fd2a0]338 errno_t rc = async_data_write_start(exch, dest, sizeof(inet_naddr_t));
[02a09ed]339 if (rc != EOK) {
340 async_exchange_end(exch);
341 async_forget(req);
[a2e3ee6]342 return rc;
[02a09ed]343 }
[a35b458]344
[02a09ed]345 rc = async_data_write_start(exch, router, sizeof(inet_addr_t));
346 if (rc != EOK) {
347 async_exchange_end(exch);
348 async_forget(req);
349 return rc;
350 }
[a35b458]351
[02a09ed]352 rc = async_data_write_start(exch, name, str_size(name));
[a35b458]353
[8bf672d]354 async_exchange_end(exch);
[a35b458]355
[02a09ed]356 if (rc != EOK) {
[50b581d]357 async_forget(req);
[02a09ed]358 return rc;
[8bf672d]359 }
[a35b458]360
[b7fd2a0]361 errno_t retval;
[8bf672d]362 async_wait_for(req, &retval);
[a35b458]363
[fafb8e5]364 *sroute_id = ipc_get_arg1(&answer);
[a35b458]365
[25a179e]366 return retval;
[8bf672d]367}
368
[b7fd2a0]369errno_t inetcfg_sroute_delete(sysarg_t sroute_id)
[8bf672d]370{
371 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
372
[b7fd2a0]373 errno_t rc = async_req_1_0(exch, INETCFG_SROUTE_DELETE, sroute_id);
[8bf672d]374 async_exchange_end(exch);
375
376 return rc;
377}
378
[b7fd2a0]379errno_t inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
[8bf672d]380{
381 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[a35b458]382
[8bf672d]383 ipc_call_t answer;
384 aid_t req = async_send_1(exch, INETCFG_SROUTE_GET, sroute_id, &answer);
[a35b458]385
[02a09ed]386 ipc_call_t answer_dest;
387 aid_t req_dest = async_data_read(exch, &srinfo->dest,
388 sizeof(inet_naddr_t), &answer_dest);
[a35b458]389
[b7fd2a0]390 errno_t retval_dest;
[02a09ed]391 async_wait_for(req_dest, &retval_dest);
[a35b458]392
[02a09ed]393 if (retval_dest != EOK) {
394 async_exchange_end(exch);
395 async_forget(req);
[25a179e]396 return retval_dest;
[02a09ed]397 }
[a35b458]398
[02a09ed]399 ipc_call_t answer_router;
400 aid_t req_router = async_data_read(exch, &srinfo->router,
401 sizeof(inet_addr_t), &answer_router);
[a35b458]402
[b7fd2a0]403 errno_t retval_router;
[02a09ed]404 async_wait_for(req_router, &retval_router);
[a35b458]405
[02a09ed]406 if (retval_router != EOK) {
407 async_exchange_end(exch);
408 async_forget(req);
[25a179e]409 return retval_router;
[02a09ed]410 }
[a35b458]411
[02a09ed]412 ipc_call_t answer_name;
413 char name_buf[LOC_NAME_MAXLEN + 1];
414 aid_t req_name = async_data_read(exch, name_buf, LOC_NAME_MAXLEN,
415 &answer_name);
[a35b458]416
[8bf672d]417 async_exchange_end(exch);
[a35b458]418
[b7fd2a0]419 errno_t retval_name;
[02a09ed]420 async_wait_for(req_name, &retval_name);
[a35b458]421
[02a09ed]422 if (retval_name != EOK) {
[50b581d]423 async_forget(req);
[25a179e]424 return retval_name;
[8bf672d]425 }
[a35b458]426
[b7fd2a0]427 errno_t retval;
[8bf672d]428 async_wait_for(req, &retval);
[a35b458]429
[8bf672d]430 if (retval != EOK)
[25a179e]431 return retval;
[a35b458]432
[fafb8e5]433 size_t act_size = ipc_get_arg2(&answer_name);
[8bf672d]434 assert(act_size <= LOC_NAME_MAXLEN);
[a35b458]435
[8bf672d]436 name_buf[act_size] = '\0';
[a35b458]437
[8bf672d]438 srinfo->name = str_dup(name_buf);
[a35b458]439
[8bf672d]440 return EOK;
441}
442
[b7fd2a0]443errno_t inetcfg_sroute_get_id(const char *name, sysarg_t *sroute_id)
[8bf672d]444{
445 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
446
447 ipc_call_t answer;
448 aid_t req = async_send_0(exch, INETCFG_SROUTE_GET_ID, &answer);
[b7fd2a0]449 errno_t retval = async_data_write_start(exch, name, str_size(name));
[8bf672d]450
451 async_exchange_end(exch);
452
453 if (retval != EOK) {
[50b581d]454 async_forget(req);
[8bf672d]455 return retval;
456 }
457
458 async_wait_for(req, &retval);
[fafb8e5]459 *sroute_id = ipc_get_arg1(&answer);
[8bf672d]460
461 return retval;
462}
463
[0e25780]464/** @}
465 */
Note: See TracBrowser for help on using the repository browser.