source: mainline/uspace/srv/net/inetsrv/inetcfg.c@ 96cbd18

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 96cbd18 was a2e3ee6, checked in by Martin Decky <martin@…>, 12 years ago

use new network address infrastructure (towards IPv6 support)

  • Property mode set to 100644
File size: 14.5 KB
Line 
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/** @addtogroup inet
30 * @{
31 */
32/**
33 * @file
34 * @brief
35 */
36
37#include <async.h>
38#include <errno.h>
39#include <macros.h>
40#include <io/log.h>
41#include <ipc/inet.h>
42#include <loc.h>
43#include <stdlib.h>
44#include <str.h>
45#include <sys/types.h>
46
47#include "addrobj.h"
48#include "inetsrv.h"
49#include "inet_link.h"
50#include "inetcfg.h"
51#include "sroute.h"
52
53static int inetcfg_addr_create_static(char *name, inet_naddr_t *naddr,
54 sysarg_t link_id, sysarg_t *addr_id)
55{
56 inet_link_t *ilink;
57 inet_addrobj_t *addr;
58 inet_addr_t iaddr;
59 int rc;
60
61 ilink = inet_link_get_by_id(link_id);
62 if (ilink == NULL) {
63 log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %lu not found.",
64 (unsigned long) link_id);
65 return ENOENT;
66 }
67
68 addr = inet_addrobj_new();
69 if (addr == NULL) {
70 *addr_id = 0;
71 return ENOMEM;
72 }
73
74 addr->naddr = *naddr;
75 addr->ilink = ilink;
76 addr->name = str_dup(name);
77 rc = inet_addrobj_add(addr);
78 if (rc != EOK) {
79 log_msg(LOG_DEFAULT, LVL_DEBUG, "Duplicate address name '%s'.", addr->name);
80 inet_addrobj_delete(addr);
81 return rc;
82 }
83
84 inet_naddr_addr(&addr->naddr, &iaddr);
85 rc = iplink_addr_add(ilink->iplink, &iaddr);
86 if (rc != EOK) {
87 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
88 inet_addrobj_remove(addr);
89 inet_addrobj_delete(addr);
90 return rc;
91 }
92
93 return EOK;
94}
95
96static int inetcfg_addr_delete(sysarg_t addr_id)
97{
98 inet_addrobj_t *addr;
99
100 addr = inet_addrobj_get_by_id(addr_id);
101 if (addr == NULL)
102 return ENOENT;
103
104 inet_addrobj_remove(addr);
105 inet_addrobj_delete(addr);
106
107 return EOK;
108}
109
110static int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
111{
112 inet_addrobj_t *addr;
113
114 addr = inet_addrobj_get_by_id(addr_id);
115 if (addr == NULL)
116 return ENOENT;
117
118 ainfo->naddr = addr->naddr;
119 ainfo->ilink = addr->ilink->svc_id;
120 ainfo->name = str_dup(addr->name);
121
122 return EOK;
123}
124
125static int inetcfg_addr_get_id(char *name, sysarg_t link_id, sysarg_t *addr_id)
126{
127 inet_link_t *ilink;
128 inet_addrobj_t *addr;
129
130 ilink = inet_link_get_by_id(link_id);
131 if (ilink == NULL) {
132 log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
133 return ENOENT;
134 }
135
136 addr = inet_addrobj_find_by_name(name, ilink);
137 if (addr == NULL) {
138 log_msg(LOG_DEFAULT, LVL_DEBUG, "Address '%s' not found.", name);
139 return ENOENT;
140 }
141
142 *addr_id = addr->id;
143 return EOK;
144}
145
146static int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
147{
148 return inet_addrobj_get_id_list(addrs, count);
149}
150
151static int inetcfg_get_link_list(sysarg_t **addrs, size_t *count)
152{
153 return ENOTSUP;
154}
155
156static int inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
157{
158 return inet_sroute_get_id_list(sroutes, count);
159}
160
161static int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
162{
163 inet_link_t *ilink;
164
165 ilink = inet_link_get_by_id(link_id);
166 if (ilink == NULL) {
167 return ENOENT;
168 }
169
170 linfo->name = str_dup(ilink->svc_name);
171 linfo->def_mtu = ilink->def_mtu;
172 return EOK;
173}
174
175static int inetcfg_sroute_create(char *name, inet_naddr_t *dest,
176 inet_addr_t *router, sysarg_t *sroute_id)
177{
178 inet_sroute_t *sroute;
179
180 sroute = inet_sroute_new();
181 if (sroute == NULL) {
182 *sroute_id = 0;
183 return ENOMEM;
184 }
185
186 sroute->dest = *dest;
187 sroute->router = *router;
188 sroute->name = str_dup(name);
189 inet_sroute_add(sroute);
190
191 *sroute_id = sroute->id;
192 return EOK;
193}
194
195static int inetcfg_sroute_delete(sysarg_t sroute_id)
196{
197 inet_sroute_t *sroute;
198
199 sroute = inet_sroute_get_by_id(sroute_id);
200 if (sroute == NULL)
201 return ENOENT;
202
203 inet_sroute_remove(sroute);
204 inet_sroute_delete(sroute);
205
206 return EOK;
207}
208
209static int inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
210{
211 inet_sroute_t *sroute;
212
213 sroute = inet_sroute_get_by_id(sroute_id);
214 if (sroute == NULL)
215 return ENOENT;
216
217 srinfo->dest = sroute->dest;
218 srinfo->router = sroute->router;
219 srinfo->name = str_dup(sroute->name);
220
221 return EOK;
222}
223
224static int inetcfg_sroute_get_id(char *name, sysarg_t *sroute_id)
225{
226 inet_sroute_t *sroute;
227
228 sroute = inet_sroute_find_by_name(name);
229 if (sroute == NULL) {
230 log_msg(LOG_DEFAULT, LVL_DEBUG, "Static route '%s' not found.", name);
231 return ENOENT;
232 }
233
234 *sroute_id = sroute->id;
235 return EOK;
236}
237
238static void inetcfg_addr_create_static_srv(ipc_callid_t callid,
239 ipc_call_t *call)
240{
241 char *name;
242 inet_naddr_t naddr;
243 sysarg_t link_id;
244 sysarg_t addr_id;
245 int rc;
246
247 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_create_static_srv()");
248
249 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
250 0, NULL);
251 if (rc != EOK) {
252 async_answer_0(callid, rc);
253 return;
254 }
255
256 inet_naddr_unpack(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call), &naddr);
257 link_id = IPC_GET_ARG3(*call);
258
259 addr_id = 0;
260 rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id);
261 free(name);
262 async_answer_1(callid, rc, addr_id);
263}
264
265static void inetcfg_addr_delete_srv(ipc_callid_t callid, ipc_call_t *call)
266{
267 sysarg_t addr_id;
268 int rc;
269
270 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_delete_srv()");
271
272 addr_id = IPC_GET_ARG1(*call);
273
274 rc = inetcfg_addr_delete(addr_id);
275 async_answer_0(callid, rc);
276}
277
278static void inetcfg_addr_get_srv(ipc_callid_t callid, ipc_call_t *call)
279{
280 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_srv()");
281
282 sysarg_t addr_id = IPC_GET_ARG1(*call);
283
284 inet_addr_info_t ainfo;
285
286 inet_naddr_any(&ainfo.naddr);
287 ainfo.ilink = 0;
288 ainfo.name = NULL;
289
290 ipc_callid_t rcallid;
291 size_t max_size;
292
293 if (!async_data_read_receive(&rcallid, &max_size)) {
294 async_answer_0(rcallid, EREFUSED);
295 async_answer_0(callid, EREFUSED);
296 return;
297 }
298
299 int rc = inetcfg_addr_get(addr_id, &ainfo);
300 if (rc != EOK) {
301 async_answer_0(callid, rc);
302 return;
303 }
304
305 uint32_t naddr_addr;
306 uint8_t naddr_bits;
307 rc = inet_naddr_pack(&ainfo.naddr, &naddr_addr, &naddr_bits);
308 if (rc != EOK) {
309 async_answer_0(callid, rc);
310 return;
311 }
312
313 sysarg_t retval = async_data_read_finalize(rcallid, ainfo.name,
314 min(max_size, str_size(ainfo.name)));
315 free(ainfo.name);
316
317 async_answer_3(callid, retval, (sysarg_t) naddr_addr,
318 (sysarg_t) naddr_bits, ainfo.ilink);
319}
320
321static void inetcfg_addr_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
322{
323 char *name;
324 sysarg_t link_id;
325 sysarg_t addr_id;
326 int rc;
327
328 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_id_srv()");
329
330 link_id = IPC_GET_ARG1(*call);
331
332 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
333 0, NULL);
334 if (rc != EOK) {
335 async_answer_0(callid, rc);
336 return;
337 }
338
339 addr_id = 0;
340 rc = inetcfg_addr_get_id(name, link_id, &addr_id);
341 free(name);
342 async_answer_1(callid, rc, addr_id);
343}
344
345static void inetcfg_get_addr_list_srv(ipc_callid_t callid, ipc_call_t *call)
346{
347 ipc_callid_t rcallid;
348 size_t count;
349 size_t max_size;
350 size_t act_size;
351 size_t size;
352 sysarg_t *id_buf;
353 int rc;
354
355 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_addr_list_srv()");
356
357 if (!async_data_read_receive(&rcallid, &max_size)) {
358 async_answer_0(rcallid, EREFUSED);
359 async_answer_0(callid, EREFUSED);
360 return;
361 }
362
363 rc = inetcfg_get_addr_list(&id_buf, &count);
364 if (rc != EOK) {
365 async_answer_0(rcallid, rc);
366 async_answer_0(callid, rc);
367 return;
368 }
369
370 act_size = count * sizeof(sysarg_t);
371 size = min(act_size, max_size);
372
373 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
374 free(id_buf);
375
376 async_answer_1(callid, retval, act_size);
377}
378
379
380static void inetcfg_get_link_list_srv(ipc_callid_t callid, ipc_call_t *call)
381{
382 ipc_callid_t rcallid;
383 size_t max_size;
384 size_t act_size;
385 size_t size;
386 sysarg_t *id_buf;
387 int rc;
388
389 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_link_list_srv()");
390
391 if (!async_data_read_receive(&rcallid, &max_size)) {
392 async_answer_0(rcallid, EREFUSED);
393 async_answer_0(callid, EREFUSED);
394 return;
395 }
396
397 rc = inetcfg_get_link_list(&id_buf, &act_size);
398 if (rc != EOK) {
399 async_answer_0(rcallid, rc);
400 async_answer_0(callid, rc);
401 return;
402 }
403
404 size = min(act_size, max_size);
405
406 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
407 free(id_buf);
408
409 async_answer_1(callid, retval, act_size);
410}
411
412static void inetcfg_get_sroute_list_srv(ipc_callid_t callid, ipc_call_t *call)
413{
414 ipc_callid_t rcallid;
415 size_t count;
416 size_t max_size;
417 size_t act_size;
418 size_t size;
419 sysarg_t *id_buf;
420 int rc;
421
422 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
423
424 if (!async_data_read_receive(&rcallid, &max_size)) {
425 async_answer_0(rcallid, EREFUSED);
426 async_answer_0(callid, EREFUSED);
427 return;
428 }
429
430 rc = inetcfg_get_sroute_list(&id_buf, &count);
431 if (rc != EOK) {
432 async_answer_0(rcallid, rc);
433 async_answer_0(callid, rc);
434 return;
435 }
436
437 act_size = count * sizeof(sysarg_t);
438 size = min(act_size, max_size);
439
440 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
441 free(id_buf);
442
443 async_answer_1(callid, retval, act_size);
444}
445
446static void inetcfg_link_get_srv(ipc_callid_t callid, ipc_call_t *call)
447{
448 ipc_callid_t rcallid;
449 size_t max_size;
450
451 sysarg_t link_id;
452 inet_link_info_t linfo;
453 int rc;
454
455 link_id = IPC_GET_ARG1(*call);
456 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_get_srv()");
457
458 linfo.name = NULL;
459
460 if (!async_data_read_receive(&rcallid, &max_size)) {
461 async_answer_0(rcallid, EREFUSED);
462 async_answer_0(callid, EREFUSED);
463 return;
464 }
465
466 rc = inetcfg_link_get(link_id, &linfo);
467 if (rc != EOK) {
468 async_answer_0(rcallid, rc);
469 async_answer_0(callid, rc);
470 return;
471 }
472
473 sysarg_t retval = async_data_read_finalize(rcallid, linfo.name,
474 min(max_size, str_size(linfo.name)));
475 free(linfo.name);
476
477 async_answer_1(callid, retval, linfo.def_mtu);
478}
479
480static void inetcfg_sroute_create_srv(ipc_callid_t callid,
481 ipc_call_t *call)
482{
483 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_create_srv()");
484
485 char *name;
486 int rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
487 0, NULL);
488 if (rc != EOK) {
489 async_answer_0(callid, rc);
490 return;
491 }
492
493 inet_naddr_t dest;
494 inet_addr_t router;
495
496 inet_naddr_unpack(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call), &dest);
497 inet_addr_unpack(IPC_GET_ARG3(*call), &router);
498
499 sysarg_t sroute_id = 0;
500 rc = inetcfg_sroute_create(name, &dest, &router, &sroute_id);
501 free(name);
502 async_answer_1(callid, rc, sroute_id);
503}
504
505static void inetcfg_sroute_delete_srv(ipc_callid_t callid, ipc_call_t *call)
506{
507 sysarg_t sroute_id;
508 int rc;
509
510 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_delete_srv()");
511
512 sroute_id = IPC_GET_ARG1(*call);
513
514 rc = inetcfg_sroute_delete(sroute_id);
515 async_answer_0(callid, rc);
516}
517
518static void inetcfg_sroute_get_srv(ipc_callid_t callid, ipc_call_t *call)
519{
520 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_srv()");
521
522 sysarg_t sroute_id = IPC_GET_ARG1(*call);
523
524 inet_sroute_info_t srinfo;
525
526 inet_naddr_any(&srinfo.dest);
527 inet_addr_any(&srinfo.router);
528 srinfo.name = NULL;
529
530 ipc_callid_t rcallid;
531 size_t max_size;
532 if (!async_data_read_receive(&rcallid, &max_size)) {
533 async_answer_0(rcallid, EREFUSED);
534 async_answer_0(callid, EREFUSED);
535 return;
536 }
537
538 int rc = inetcfg_sroute_get(sroute_id, &srinfo);
539 if (rc != EOK) {
540 async_answer_0(callid, rc);
541 return;
542 }
543
544 uint32_t dest_addr;
545 uint8_t dest_bits;
546 rc = inet_naddr_pack(&srinfo.dest, &dest_addr, &dest_bits);
547 if (rc != EOK) {
548 async_answer_0(callid, rc);
549 return;
550 }
551
552 uint32_t router_addr;
553 rc = inet_addr_pack(&srinfo.router, &router_addr);
554 if (rc != EOK) {
555 async_answer_0(callid, rc);
556 return;
557 }
558
559 sysarg_t retval = async_data_read_finalize(rcallid, srinfo.name,
560 min(max_size, str_size(srinfo.name)));
561 free(srinfo.name);
562
563 async_answer_3(callid, retval, (sysarg_t) dest_addr,
564 (sysarg_t) dest_bits, (sysarg_t) router_addr);
565}
566
567static void inetcfg_sroute_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
568{
569 char *name;
570 sysarg_t sroute_id;
571 int rc;
572
573 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
574
575 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
576 0, NULL);
577 if (rc != EOK) {
578 async_answer_0(callid, rc);
579 return;
580 }
581
582 sroute_id = 0;
583 rc = inetcfg_sroute_get_id(name, &sroute_id);
584 free(name);
585 async_answer_1(callid, rc, sroute_id);
586}
587
588void inet_cfg_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
589{
590 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_cfg_conn()");
591
592 /* Accept the connection */
593 async_answer_0(iid, EOK);
594
595 while (true) {
596 ipc_call_t call;
597 ipc_callid_t callid = async_get_call(&call);
598 sysarg_t method = IPC_GET_IMETHOD(call);
599
600 if (!method) {
601 /* The other side has hung up */
602 async_answer_0(callid, EOK);
603 return;
604 }
605
606 switch (method) {
607 case INETCFG_ADDR_CREATE_STATIC:
608 inetcfg_addr_create_static_srv(callid, &call);
609 break;
610 case INETCFG_ADDR_DELETE:
611 inetcfg_addr_delete_srv(callid, &call);
612 break;
613 case INETCFG_ADDR_GET:
614 inetcfg_addr_get_srv(callid, &call);
615 break;
616 case INETCFG_ADDR_GET_ID:
617 inetcfg_addr_get_id_srv(callid, &call);
618 break;
619 case INETCFG_GET_ADDR_LIST:
620 inetcfg_get_addr_list_srv(callid, &call);
621 break;
622 case INETCFG_GET_LINK_LIST:
623 inetcfg_get_link_list_srv(callid, &call);
624 break;
625 case INETCFG_GET_SROUTE_LIST:
626 inetcfg_get_sroute_list_srv(callid, &call);
627 break;
628 case INETCFG_LINK_GET:
629 inetcfg_link_get_srv(callid, &call);
630 break;
631 case INETCFG_SROUTE_CREATE:
632 inetcfg_sroute_create_srv(callid, &call);
633 break;
634 case INETCFG_SROUTE_DELETE:
635 inetcfg_sroute_delete_srv(callid, &call);
636 break;
637 case INETCFG_SROUTE_GET:
638 inetcfg_sroute_get_srv(callid, &call);
639 break;
640 case INETCFG_SROUTE_GET_ID:
641 inetcfg_sroute_get_id_srv(callid, &call);
642 break;
643 default:
644 async_answer_0(callid, EINVAL);
645 }
646 }
647}
648
649/** @}
650 */
Note: See TracBrowser for help on using the repository browser.