source: mainline/uspace/srv/net/inet/inetcfg.c@ af42a2b

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

Move network-related servers to srv/net.

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