source: mainline/uspace/srv/net/inetsrv/inetcfg.c@ 1038a9c

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

Detect duplicate address names.

  • Property mode set to 100644
File size: 13.9 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 iplink_addr_t iaddr;
59 int rc;
60
61 ilink = inet_link_get_by_id(link_id);
62 if (ilink == NULL) {
63 log_msg(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(LVL_DEBUG, "Duplicate address name '%s'.", addr->name);
80 inet_addrobj_delete(addr);
81 return rc;
82 }
83
84 iaddr.ipv4 = addr->naddr.ipv4;
85 rc = iplink_addr_add(ilink->iplink, &iaddr);
86 if (rc != EOK) {
87 log_msg(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(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(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(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(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 naddr.ipv4 = IPC_GET_ARG1(*call);
257 naddr.bits = IPC_GET_ARG2(*call);
258 link_id = IPC_GET_ARG3(*call);
259
260 addr_id = 0;
261 rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id);
262 free(name);
263 async_answer_1(callid, rc, addr_id);
264}
265
266static void inetcfg_addr_delete_srv(ipc_callid_t callid, ipc_call_t *call)
267{
268 sysarg_t addr_id;
269 int rc;
270
271 log_msg(LVL_DEBUG, "inetcfg_addr_delete_srv()");
272
273 addr_id = IPC_GET_ARG1(*call);
274
275 rc = inetcfg_addr_delete(addr_id);
276 async_answer_0(callid, rc);
277}
278
279static void inetcfg_addr_get_srv(ipc_callid_t callid, ipc_call_t *call)
280{
281 ipc_callid_t rcallid;
282 size_t max_size;
283
284 sysarg_t addr_id;
285 inet_addr_info_t ainfo;
286 int rc;
287
288 addr_id = IPC_GET_ARG1(*call);
289 log_msg(LVL_DEBUG, "inetcfg_addr_get_srv()");
290
291 ainfo.naddr.ipv4 = 0;
292 ainfo.naddr.bits = 0;
293 ainfo.ilink = 0;
294 ainfo.name = NULL;
295
296 if (!async_data_read_receive(&rcallid, &max_size)) {
297 async_answer_0(rcallid, EREFUSED);
298 async_answer_0(callid, EREFUSED);
299 return;
300 }
301
302 rc = inetcfg_addr_get(addr_id, &ainfo);
303 if (rc != EOK) {
304 async_answer_0(callid, rc);
305 return;
306 }
307
308 sysarg_t retval = async_data_read_finalize(rcallid, ainfo.name,
309 min(max_size, str_size(ainfo.name)));
310 free(ainfo.name);
311
312 async_answer_3(callid, retval, ainfo.naddr.ipv4, ainfo.naddr.bits,
313 ainfo.ilink);
314}
315
316static void inetcfg_addr_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
317{
318 char *name;
319 sysarg_t link_id;
320 sysarg_t addr_id;
321 int rc;
322
323 log_msg(LVL_DEBUG, "inetcfg_addr_get_id_srv()");
324
325 link_id = IPC_GET_ARG1(*call);
326
327 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
328 0, NULL);
329 if (rc != EOK) {
330 async_answer_0(callid, rc);
331 return;
332 }
333
334 addr_id = 0;
335 rc = inetcfg_addr_get_id(name, link_id, &addr_id);
336 free(name);
337 async_answer_1(callid, rc, addr_id);
338}
339
340static void inetcfg_get_addr_list_srv(ipc_callid_t callid, ipc_call_t *call)
341{
342 ipc_callid_t rcallid;
343 size_t count;
344 size_t max_size;
345 size_t act_size;
346 size_t size;
347 sysarg_t *id_buf;
348 int rc;
349
350 log_msg(LVL_DEBUG, "inetcfg_get_addr_list_srv()");
351
352 if (!async_data_read_receive(&rcallid, &max_size)) {
353 async_answer_0(rcallid, EREFUSED);
354 async_answer_0(callid, EREFUSED);
355 return;
356 }
357
358 rc = inetcfg_get_addr_list(&id_buf, &count);
359 if (rc != EOK) {
360 async_answer_0(rcallid, rc);
361 async_answer_0(callid, rc);
362 return;
363 }
364
365 act_size = count * sizeof(sysarg_t);
366 size = min(act_size, max_size);
367
368 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
369 free(id_buf);
370
371 async_answer_1(callid, retval, act_size);
372}
373
374
375static void inetcfg_get_link_list_srv(ipc_callid_t callid, ipc_call_t *call)
376{
377 ipc_callid_t rcallid;
378 size_t max_size;
379 size_t act_size;
380 size_t size;
381 sysarg_t *id_buf;
382 int rc;
383
384 log_msg(LVL_DEBUG, "inetcfg_get_link_list_srv()");
385
386 if (!async_data_read_receive(&rcallid, &max_size)) {
387 async_answer_0(rcallid, EREFUSED);
388 async_answer_0(callid, EREFUSED);
389 return;
390 }
391
392 rc = inetcfg_get_link_list(&id_buf, &act_size);
393 if (rc != EOK) {
394 async_answer_0(rcallid, rc);
395 async_answer_0(callid, rc);
396 return;
397 }
398
399 size = min(act_size, max_size);
400
401 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
402 free(id_buf);
403
404 async_answer_1(callid, retval, act_size);
405}
406
407static void inetcfg_get_sroute_list_srv(ipc_callid_t callid, ipc_call_t *call)
408{
409 ipc_callid_t rcallid;
410 size_t count;
411 size_t max_size;
412 size_t act_size;
413 size_t size;
414 sysarg_t *id_buf;
415 int rc;
416
417 log_msg(LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
418
419 if (!async_data_read_receive(&rcallid, &max_size)) {
420 async_answer_0(rcallid, EREFUSED);
421 async_answer_0(callid, EREFUSED);
422 return;
423 }
424
425 rc = inetcfg_get_sroute_list(&id_buf, &count);
426 if (rc != EOK) {
427 async_answer_0(rcallid, rc);
428 async_answer_0(callid, rc);
429 return;
430 }
431
432 act_size = count * sizeof(sysarg_t);
433 size = min(act_size, max_size);
434
435 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
436 free(id_buf);
437
438 async_answer_1(callid, retval, act_size);
439}
440
441static void inetcfg_link_get_srv(ipc_callid_t callid, ipc_call_t *call)
442{
443 ipc_callid_t rcallid;
444 size_t max_size;
445
446 sysarg_t link_id;
447 inet_link_info_t linfo;
448 int rc;
449
450 link_id = IPC_GET_ARG1(*call);
451 log_msg(LVL_DEBUG, "inetcfg_link_get_srv()");
452
453 linfo.name = NULL;
454
455 if (!async_data_read_receive(&rcallid, &max_size)) {
456 async_answer_0(rcallid, EREFUSED);
457 async_answer_0(callid, EREFUSED);
458 return;
459 }
460
461 rc = inetcfg_link_get(link_id, &linfo);
462 if (rc != EOK) {
463 async_answer_0(rcallid, rc);
464 async_answer_0(callid, rc);
465 return;
466 }
467
468 sysarg_t retval = async_data_read_finalize(rcallid, linfo.name,
469 min(max_size, str_size(linfo.name)));
470 free(linfo.name);
471
472 async_answer_1(callid, retval, linfo.def_mtu);
473}
474
475static void inetcfg_sroute_create_srv(ipc_callid_t callid,
476 ipc_call_t *call)
477{
478 char *name;
479 inet_naddr_t dest;
480 inet_addr_t router;
481 sysarg_t sroute_id;
482 int rc;
483
484 log_msg(LVL_DEBUG, "inetcfg_sroute_create_srv()");
485
486 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 dest.ipv4 = IPC_GET_ARG1(*call);
494 dest.bits = IPC_GET_ARG2(*call);
495 router.ipv4 = IPC_GET_ARG3(*call);
496
497 sroute_id = 0;
498 rc = inetcfg_sroute_create(name, &dest, &router, &sroute_id);
499 free(name);
500 async_answer_1(callid, rc, sroute_id);
501}
502
503static void inetcfg_sroute_delete_srv(ipc_callid_t callid, ipc_call_t *call)
504{
505 sysarg_t sroute_id;
506 int rc;
507
508 log_msg(LVL_DEBUG, "inetcfg_sroute_delete_srv()");
509
510 sroute_id = IPC_GET_ARG1(*call);
511
512 rc = inetcfg_sroute_delete(sroute_id);
513 async_answer_0(callid, rc);
514}
515
516static void inetcfg_sroute_get_srv(ipc_callid_t callid, ipc_call_t *call)
517{
518 ipc_callid_t rcallid;
519 size_t max_size;
520
521 sysarg_t sroute_id;
522 inet_sroute_info_t srinfo;
523 int rc;
524
525 sroute_id = IPC_GET_ARG1(*call);
526 log_msg(LVL_DEBUG, "inetcfg_sroute_get_srv()");
527
528 srinfo.dest.ipv4 = 0;
529 srinfo.dest.bits = 0;
530 srinfo.router.ipv4 = 0;
531 srinfo.name = NULL;
532
533 if (!async_data_read_receive(&rcallid, &max_size)) {
534 async_answer_0(rcallid, EREFUSED);
535 async_answer_0(callid, EREFUSED);
536 return;
537 }
538
539 rc = inetcfg_sroute_get(sroute_id, &srinfo);
540 if (rc != EOK) {
541 async_answer_0(callid, rc);
542 return;
543 }
544
545 sysarg_t retval = async_data_read_finalize(rcallid, srinfo.name,
546 min(max_size, str_size(srinfo.name)));
547 free(srinfo.name);
548
549 async_answer_3(callid, retval, srinfo.dest.ipv4, srinfo.dest.bits,
550 srinfo.router.ipv4);
551}
552
553static void inetcfg_sroute_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
554{
555 char *name;
556 sysarg_t sroute_id;
557 int rc;
558
559 log_msg(LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
560
561 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
562 0, NULL);
563 if (rc != EOK) {
564 async_answer_0(callid, rc);
565 return;
566 }
567
568 sroute_id = 0;
569 rc = inetcfg_sroute_get_id(name, &sroute_id);
570 free(name);
571 async_answer_1(callid, rc, sroute_id);
572}
573
574void inet_cfg_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
575{
576 log_msg(LVL_DEBUG, "inet_cfg_conn()");
577
578 /* Accept the connection */
579 async_answer_0(iid, EOK);
580
581 while (true) {
582 ipc_call_t call;
583 ipc_callid_t callid = async_get_call(&call);
584 sysarg_t method = IPC_GET_IMETHOD(call);
585
586 if (!method) {
587 /* The other side has hung up */
588 async_answer_0(callid, EOK);
589 return;
590 }
591
592 switch (method) {
593 case INETCFG_ADDR_CREATE_STATIC:
594 inetcfg_addr_create_static_srv(callid, &call);
595 break;
596 case INETCFG_ADDR_DELETE:
597 inetcfg_addr_delete_srv(callid, &call);
598 break;
599 case INETCFG_ADDR_GET:
600 inetcfg_addr_get_srv(callid, &call);
601 break;
602 case INETCFG_ADDR_GET_ID:
603 inetcfg_addr_get_id_srv(callid, &call);
604 break;
605 case INETCFG_GET_ADDR_LIST:
606 inetcfg_get_addr_list_srv(callid, &call);
607 break;
608 case INETCFG_GET_LINK_LIST:
609 inetcfg_get_link_list_srv(callid, &call);
610 break;
611 case INETCFG_GET_SROUTE_LIST:
612 inetcfg_get_sroute_list_srv(callid, &call);
613 break;
614 case INETCFG_LINK_GET:
615 inetcfg_link_get_srv(callid, &call);
616 break;
617 case INETCFG_SROUTE_CREATE:
618 inetcfg_sroute_create_srv(callid, &call);
619 break;
620 case INETCFG_SROUTE_DELETE:
621 inetcfg_sroute_delete_srv(callid, &call);
622 break;
623 case INETCFG_SROUTE_GET:
624 inetcfg_sroute_get_srv(callid, &call);
625 break;
626 case INETCFG_SROUTE_GET_ID:
627 inetcfg_sroute_get_id_srv(callid, &call);
628 break;
629 default:
630 async_answer_0(callid, EINVAL);
631 }
632 }
633}
634
635/** @}
636 */
Note: See TracBrowser for help on using the repository browser.