source: mainline/uspace/srv/net/inetsrv/inetcfg.c@ 257feec

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

cstyle (no change in functionality)

  • Property mode set to 100644
File size: 14.5 KB
RevLine 
[0e25780]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>
[0e94b979]44#include <str.h>
[0e25780]45#include <sys/types.h>
46
[45aa22c]47#include "addrobj.h"
[b4ec1ea]48#include "inetsrv.h"
[45aa22c]49#include "inet_link.h"
[0e25780]50#include "inetcfg.h"
[8bf672d]51#include "sroute.h"
[0e25780]52
[291c792]53static int inetcfg_addr_create_static(char *name, inet_naddr_t *naddr,
54 sysarg_t link_id, sysarg_t *addr_id)
[0e25780]55{
[45aa22c]56 inet_link_t *ilink;
57 inet_addrobj_t *addr;
[a2e3ee6]58 inet_addr_t iaddr;
[45aa22c]59 int rc;
60
61 ilink = inet_link_get_by_id(link_id);
62 if (ilink == NULL) {
[a1a101d]63 log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %lu not found.",
[45aa22c]64 (unsigned long) link_id);
65 return ENOENT;
66 }
67
68 addr = inet_addrobj_new();
[8bf672d]69 if (addr == NULL) {
70 *addr_id = 0;
71 return ENOMEM;
72 }
73
[45aa22c]74 addr->naddr = *naddr;
75 addr->ilink = ilink;
[291c792]76 addr->name = str_dup(name);
[bf9e6fc]77 rc = inet_addrobj_add(addr);
78 if (rc != EOK) {
[a1a101d]79 log_msg(LOG_DEFAULT, LVL_DEBUG, "Duplicate address name '%s'.", addr->name);
[bf9e6fc]80 inet_addrobj_delete(addr);
81 return rc;
82 }
[45aa22c]83
[a2e3ee6]84 inet_naddr_addr(&addr->naddr, &iaddr);
[45aa22c]85 rc = iplink_addr_add(ilink->iplink, &iaddr);
86 if (rc != EOK) {
[a1a101d]87 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
[45aa22c]88 inet_addrobj_remove(addr);
89 inet_addrobj_delete(addr);
90 return rc;
91 }
92
93 return EOK;
[0e25780]94}
95
96static int inetcfg_addr_delete(sysarg_t addr_id)
97{
[fa101c4]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;
[0e25780]108}
109
110static int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
111{
[0e94b979]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;
[0e25780]123}
124
[fa101c4]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) {
[a1a101d]132 log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
[fa101c4]133 return ENOENT;
134 }
135
136 addr = inet_addrobj_find_by_name(name, ilink);
137 if (addr == NULL) {
[a1a101d]138 log_msg(LOG_DEFAULT, LVL_DEBUG, "Address '%s' not found.", name);
[fa101c4]139 return ENOENT;
140 }
141
142 *addr_id = addr->id;
143 return EOK;
144}
145
[0e25780]146static int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
147{
[0e94b979]148 return inet_addrobj_get_id_list(addrs, count);
[0e25780]149}
150
151static int inetcfg_get_link_list(sysarg_t **addrs, size_t *count)
152{
153 return ENOTSUP;
154}
155
[8bf672d]156static int inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
157{
158 return inet_sroute_get_id_list(sroutes, count);
159}
160
[0e94b979]161static int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
[0e25780]162{
[0e94b979]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);
[347768d]171 linfo->def_mtu = ilink->def_mtu;
[0e94b979]172 return EOK;
[0e25780]173}
174
[8bf672d]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) {
[a1a101d]230 log_msg(LOG_DEFAULT, LVL_DEBUG, "Static route '%s' not found.", name);
[8bf672d]231 return ENOENT;
232 }
233
234 *sroute_id = sroute->id;
235 return EOK;
236}
237
[0e25780]238static void inetcfg_addr_create_static_srv(ipc_callid_t callid,
239 ipc_call_t *call)
240{
[291c792]241 char *name;
[0e25780]242 inet_naddr_t naddr;
[45aa22c]243 sysarg_t link_id;
[0e25780]244 sysarg_t addr_id;
245 int rc;
246
[a1a101d]247 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_create_static_srv()");
[0e25780]248
[291c792]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
[a2e3ee6]256 inet_naddr_unpack(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call), &naddr);
257 link_id = IPC_GET_ARG3(*call);
[0e25780]258
259 addr_id = 0;
[291c792]260 rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id);
261 free(name);
[0e25780]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
[a1a101d]270 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_delete_srv()");
[0e25780]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{
[a1a101d]280 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_srv()");
[a2e3ee6]281
282 sysarg_t addr_id = IPC_GET_ARG1(*call);
283
284 inet_addr_info_t ainfo;
285
286 inet_naddr_any(&ainfo.naddr);
[0e94b979]287 ainfo.ilink = 0;
288 ainfo.name = NULL;
[a2e3ee6]289
290 ipc_callid_t rcallid;
291 size_t max_size;
292
[0e94b979]293 if (!async_data_read_receive(&rcallid, &max_size)) {
294 async_answer_0(rcallid, EREFUSED);
295 async_answer_0(callid, EREFUSED);
296 return;
297 }
[a2e3ee6]298
299 int rc = inetcfg_addr_get(addr_id, &ainfo);
[0e94b979]300 if (rc != EOK) {
301 async_answer_0(callid, rc);
302 return;
303 }
[a2e3ee6]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
[0e94b979]313 sysarg_t retval = async_data_read_finalize(rcallid, ainfo.name,
314 min(max_size, str_size(ainfo.name)));
315 free(ainfo.name);
[a2e3ee6]316
317 async_answer_3(callid, retval, (sysarg_t) naddr_addr,
318 (sysarg_t) naddr_bits, ainfo.ilink);
[0e25780]319}
320
[fa101c4]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
[a1a101d]328 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_id_srv()");
[fa101c4]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
[0e25780]345static void inetcfg_get_addr_list_srv(ipc_callid_t callid, ipc_call_t *call)
346{
347 ipc_callid_t rcallid;
[0e94b979]348 size_t count;
[0e25780]349 size_t max_size;
350 size_t act_size;
351 size_t size;
352 sysarg_t *id_buf;
353 int rc;
354
[a1a101d]355 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_addr_list_srv()");
[0e25780]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
[0e94b979]363 rc = inetcfg_get_addr_list(&id_buf, &count);
[0e25780]364 if (rc != EOK) {
365 async_answer_0(rcallid, rc);
366 async_answer_0(callid, rc);
367 return;
368 }
369
[0e94b979]370 act_size = count * sizeof(sysarg_t);
[0e25780]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
[8bf672d]379static void inetcfg_get_link_list_srv(ipc_callid_t callid, ipc_call_t *call)
380{
381 ipc_callid_t rcallid;
382 size_t max_size;
383 size_t act_size;
384 size_t size;
385 sysarg_t *id_buf;
386 int rc;
387
[a1a101d]388 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_link_list_srv()");
[8bf672d]389
390 if (!async_data_read_receive(&rcallid, &max_size)) {
391 async_answer_0(rcallid, EREFUSED);
392 async_answer_0(callid, EREFUSED);
393 return;
394 }
395
396 rc = inetcfg_get_link_list(&id_buf, &act_size);
397 if (rc != EOK) {
398 async_answer_0(rcallid, rc);
399 async_answer_0(callid, rc);
400 return;
401 }
402
403 size = min(act_size, max_size);
404
405 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
406 free(id_buf);
407
408 async_answer_1(callid, retval, act_size);
409}
410
411static void inetcfg_get_sroute_list_srv(ipc_callid_t callid, ipc_call_t *call)
412{
413 ipc_callid_t rcallid;
414 size_t count;
415 size_t max_size;
416 size_t act_size;
417 size_t size;
418 sysarg_t *id_buf;
419 int rc;
420
[a1a101d]421 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
[8bf672d]422
423 if (!async_data_read_receive(&rcallid, &max_size)) {
424 async_answer_0(rcallid, EREFUSED);
425 async_answer_0(callid, EREFUSED);
426 return;
427 }
428
429 rc = inetcfg_get_sroute_list(&id_buf, &count);
430 if (rc != EOK) {
431 async_answer_0(rcallid, rc);
432 async_answer_0(callid, rc);
433 return;
434 }
435
436 act_size = count * sizeof(sysarg_t);
437 size = min(act_size, max_size);
438
439 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
440 free(id_buf);
441
442 async_answer_1(callid, retval, act_size);
443}
444
[0e25780]445static void inetcfg_link_get_srv(ipc_callid_t callid, ipc_call_t *call)
446{
[0e94b979]447 ipc_callid_t rcallid;
448 size_t max_size;
449
[0e25780]450 sysarg_t link_id;
451 inet_link_info_t linfo;
452 int rc;
453
454 link_id = IPC_GET_ARG1(*call);
[a1a101d]455 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_get_srv()");
[0e25780]456
[0e94b979]457 linfo.name = NULL;
458
459 if (!async_data_read_receive(&rcallid, &max_size)) {
460 async_answer_0(rcallid, EREFUSED);
461 async_answer_0(callid, EREFUSED);
462 return;
463 }
464
[0e25780]465 rc = inetcfg_link_get(link_id, &linfo);
[0e94b979]466 if (rc != EOK) {
467 async_answer_0(rcallid, rc);
468 async_answer_0(callid, rc);
469 return;
470 }
471
472 sysarg_t retval = async_data_read_finalize(rcallid, linfo.name,
473 min(max_size, str_size(linfo.name)));
474 free(linfo.name);
475
[347768d]476 async_answer_1(callid, retval, linfo.def_mtu);
[0e25780]477}
478
[8bf672d]479static void inetcfg_sroute_create_srv(ipc_callid_t callid,
480 ipc_call_t *call)
481{
[a1a101d]482 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_create_srv()");
[a2e3ee6]483
484 char *name;
485 int rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
[8bf672d]486 0, NULL);
487 if (rc != EOK) {
488 async_answer_0(callid, rc);
489 return;
490 }
[a2e3ee6]491
492 inet_naddr_t dest;
493 inet_addr_t router;
494
495 inet_naddr_unpack(IPC_GET_ARG1(*call), IPC_GET_ARG2(*call), &dest);
496 inet_addr_unpack(IPC_GET_ARG3(*call), &router);
497
498 sysarg_t sroute_id = 0;
[8bf672d]499 rc = inetcfg_sroute_create(name, &dest, &router, &sroute_id);
500 free(name);
501 async_answer_1(callid, rc, sroute_id);
502}
503
504static void inetcfg_sroute_delete_srv(ipc_callid_t callid, ipc_call_t *call)
505{
506 sysarg_t sroute_id;
507 int rc;
508
[a1a101d]509 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_delete_srv()");
[8bf672d]510
511 sroute_id = IPC_GET_ARG1(*call);
512
513 rc = inetcfg_sroute_delete(sroute_id);
514 async_answer_0(callid, rc);
515}
516
517static void inetcfg_sroute_get_srv(ipc_callid_t callid, ipc_call_t *call)
[0e25780]518{
[a1a101d]519 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_srv()");
[a2e3ee6]520
521 sysarg_t sroute_id = IPC_GET_ARG1(*call);
522
523 inet_sroute_info_t srinfo;
524
525 inet_naddr_any(&srinfo.dest);
526 inet_addr_any(&srinfo.router);
[8bf672d]527 srinfo.name = NULL;
[a2e3ee6]528
529 ipc_callid_t rcallid;
530 size_t max_size;
[0e25780]531 if (!async_data_read_receive(&rcallid, &max_size)) {
532 async_answer_0(rcallid, EREFUSED);
533 async_answer_0(callid, EREFUSED);
534 return;
535 }
[a2e3ee6]536
537 int rc = inetcfg_sroute_get(sroute_id, &srinfo);
[0e25780]538 if (rc != EOK) {
539 async_answer_0(callid, rc);
540 return;
541 }
[a2e3ee6]542
543 uint32_t dest_addr;
544 uint8_t dest_bits;
545 rc = inet_naddr_pack(&srinfo.dest, &dest_addr, &dest_bits);
546 if (rc != EOK) {
547 async_answer_0(callid, rc);
548 return;
549 }
550
551 uint32_t router_addr;
552 rc = inet_addr_pack(&srinfo.router, &router_addr);
553 if (rc != EOK) {
554 async_answer_0(callid, rc);
555 return;
556 }
557
[8bf672d]558 sysarg_t retval = async_data_read_finalize(rcallid, srinfo.name,
559 min(max_size, str_size(srinfo.name)));
560 free(srinfo.name);
[a2e3ee6]561
562 async_answer_3(callid, retval, (sysarg_t) dest_addr,
563 (sysarg_t) dest_bits, (sysarg_t) router_addr);
[8bf672d]564}
[0e25780]565
[8bf672d]566static void inetcfg_sroute_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
567{
568 char *name;
569 sysarg_t sroute_id;
570 int rc;
571
[a1a101d]572 log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
[8bf672d]573
574 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
575 0, NULL);
576 if (rc != EOK) {
577 async_answer_0(callid, rc);
578 return;
579 }
580
581 sroute_id = 0;
582 rc = inetcfg_sroute_get_id(name, &sroute_id);
583 free(name);
584 async_answer_1(callid, rc, sroute_id);
[0e25780]585}
586
587void inet_cfg_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
588{
[a1a101d]589 log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_cfg_conn()");
[0e25780]590
591 /* Accept the connection */
592 async_answer_0(iid, EOK);
593
594 while (true) {
595 ipc_call_t call;
596 ipc_callid_t callid = async_get_call(&call);
597 sysarg_t method = IPC_GET_IMETHOD(call);
598
599 if (!method) {
600 /* The other side has hung up */
601 async_answer_0(callid, EOK);
602 return;
603 }
604
605 switch (method) {
606 case INETCFG_ADDR_CREATE_STATIC:
607 inetcfg_addr_create_static_srv(callid, &call);
608 break;
609 case INETCFG_ADDR_DELETE:
610 inetcfg_addr_delete_srv(callid, &call);
611 break;
612 case INETCFG_ADDR_GET:
613 inetcfg_addr_get_srv(callid, &call);
614 break;
[fa101c4]615 case INETCFG_ADDR_GET_ID:
616 inetcfg_addr_get_id_srv(callid, &call);
617 break;
[0e25780]618 case INETCFG_GET_ADDR_LIST:
619 inetcfg_get_addr_list_srv(callid, &call);
620 break;
621 case INETCFG_GET_LINK_LIST:
622 inetcfg_get_link_list_srv(callid, &call);
623 break;
[8bf672d]624 case INETCFG_GET_SROUTE_LIST:
625 inetcfg_get_sroute_list_srv(callid, &call);
626 break;
[0e25780]627 case INETCFG_LINK_GET:
628 inetcfg_link_get_srv(callid, &call);
629 break;
[8bf672d]630 case INETCFG_SROUTE_CREATE:
631 inetcfg_sroute_create_srv(callid, &call);
632 break;
633 case INETCFG_SROUTE_DELETE:
634 inetcfg_sroute_delete_srv(callid, &call);
635 break;
636 case INETCFG_SROUTE_GET:
637 inetcfg_sroute_get_srv(callid, &call);
638 break;
639 case INETCFG_SROUTE_GET_ID:
640 inetcfg_sroute_get_id_srv(callid, &call);
641 break;
[0e25780]642 default:
643 async_answer_0(callid, EINVAL);
644 }
645 }
646}
647
648/** @}
649 */
Note: See TracBrowser for help on using the repository browser.