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

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