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

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

Rename and move addr48_t to eth_addr_t

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