source: mainline/uspace/lib/c/generic/inetcfg.c@ cde999a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since cde999a was cde999a, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Fix comments to stop referring to error codes as negative.

  • Property mode set to 100644
File size: 10.4 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#include <async.h>
30#include <assert.h>
31#include <errno.h>
32#include <inet/inetcfg.h>
33#include <ipc/inet.h>
34#include <ipc/services.h>
35#include <loc.h>
36#include <stdlib.h>
[0e94b979]37#include <str.h>
[0e25780]38
39static async_sess_t *inetcfg_sess = NULL;
40
41static int inetcfg_get_ids_once(sysarg_t method, sysarg_t arg1,
42 sysarg_t *id_buf, size_t buf_size, size_t *act_size)
43{
44 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
45
46 ipc_call_t answer;
47 aid_t req = async_send_1(exch, method, arg1, &answer);
48 int rc = async_data_read_start(exch, id_buf, buf_size);
49
50 async_exchange_end(exch);
51
52 if (rc != EOK) {
[50b581d]53 async_forget(req);
[0e25780]54 return rc;
55 }
56
[25a179e]57 int retval;
[0e25780]58 async_wait_for(req, &retval);
59
60 if (retval != EOK) {
61 return retval;
62 }
63
64 *act_size = IPC_GET_ARG1(answer);
65 return EOK;
66}
67
68/** Get list of IDs.
69 *
70 * Returns an allocated array of service IDs.
71 *
72 * @param method IPC method
73 * @param arg1 IPC argument 1
74 * @param data Place to store pointer to array of IDs
75 * @param count Place to store number of IDs
[cde999a]76 * @return EOK on success or an error code
[0e25780]77 */
78static int inetcfg_get_ids_internal(sysarg_t method, sysarg_t arg1,
79 sysarg_t **data, size_t *count)
80{
81 *data = NULL;
82 *count = 0;
83
84 size_t act_size = 0;
85 int rc = inetcfg_get_ids_once(method, arg1, NULL, 0,
86 &act_size);
87 if (rc != EOK)
88 return rc;
89
90 size_t alloc_size = act_size;
91 service_id_t *ids = malloc(alloc_size);
92 if (ids == NULL)
93 return ENOMEM;
94
95 while (true) {
96 rc = inetcfg_get_ids_once(method, arg1, ids, alloc_size,
97 &act_size);
98 if (rc != EOK)
99 return rc;
100
101 if (act_size <= alloc_size)
102 break;
103
104 alloc_size = act_size;
105 ids = realloc(ids, alloc_size);
106 if (ids == NULL)
107 return ENOMEM;
108 }
109
110 *count = act_size / sizeof(sysarg_t);
111 *data = ids;
112 return EOK;
113}
114
115int inetcfg_init(void)
116{
117 service_id_t inet_svc;
118 int rc;
119
120 assert(inetcfg_sess == NULL);
[77ad86c]121
[f9b2cb4c]122 rc = loc_service_get_id(SERVICE_NAME_INET, &inet_svc,
[0e25780]123 IPC_FLAG_BLOCKING);
124 if (rc != EOK)
125 return ENOENT;
[77ad86c]126
[f9b2cb4c]127 inetcfg_sess = loc_service_connect(inet_svc, INTERFACE_INETCFG,
[0e25780]128 IPC_FLAG_BLOCKING);
129 if (inetcfg_sess == NULL)
130 return ENOENT;
[77ad86c]131
[0e25780]132 return EOK;
133}
134
135int inetcfg_addr_create_static(const char *name, inet_naddr_t *naddr,
[45aa22c]136 sysarg_t link_id, sysarg_t *addr_id)
[0e25780]137{
138 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[a2e3ee6]139
[291c792]140 ipc_call_t answer;
[02a09ed]141 aid_t req = async_send_1(exch, INETCFG_ADDR_CREATE_STATIC, link_id,
142 &answer);
143
144 int rc = async_data_write_start(exch, naddr, sizeof(inet_naddr_t));
145 if (rc != EOK) {
146 async_exchange_end(exch);
147 async_forget(req);
148 return rc;
149 }
150
151 rc = async_data_write_start(exch, name, str_size(name));
[a2e3ee6]152
[0e25780]153 async_exchange_end(exch);
[a2e3ee6]154
[02a09ed]155 if (rc != EOK) {
[50b581d]156 async_forget(req);
[02a09ed]157 return rc;
[291c792]158 }
[a2e3ee6]159
[25a179e]160 int retval;
[291c792]161 async_wait_for(req, &retval);
[02a09ed]162
[291c792]163 *addr_id = IPC_GET_ARG1(answer);
[a2e3ee6]164
[25a179e]165 return retval;
[0e25780]166}
167
168int inetcfg_addr_delete(sysarg_t addr_id)
169{
170 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
171
172 int rc = async_req_1_0(exch, INETCFG_ADDR_DELETE, addr_id);
173 async_exchange_end(exch);
174
175 return rc;
176}
177
178int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
179{
180 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[b5cf742a]181
[0e94b979]182 ipc_call_t answer;
183 aid_t req = async_send_1(exch, INETCFG_ADDR_GET, addr_id, &answer);
[02a09ed]184
185 ipc_call_t answer_naddr;
186 aid_t req_naddr = async_data_read(exch, &ainfo->naddr,
187 sizeof(inet_naddr_t), &answer_naddr);
188
[25a179e]189 int retval_naddr;
[02a09ed]190 async_wait_for(req_naddr, &retval_naddr);
191
192 if (retval_naddr != EOK) {
193 async_exchange_end(exch);
194 async_forget(req);
[25a179e]195 return retval_naddr;
[02a09ed]196 }
197
198 ipc_call_t answer_name;
199 char name_buf[LOC_NAME_MAXLEN + 1];
200 aid_t req_name = async_data_read(exch, name_buf, LOC_NAME_MAXLEN,
201 &answer_name);
[b5cf742a]202
[0e25780]203 async_exchange_end(exch);
[b5cf742a]204
[25a179e]205 int retval_name;
[02a09ed]206 async_wait_for(req_name, &retval_name);
207
208 if (retval_name != EOK) {
[50b581d]209 async_forget(req);
[25a179e]210 return retval_name;
[0e94b979]211 }
[b5cf742a]212
[25a179e]213 int retval;
[0e94b979]214 async_wait_for(req, &retval);
[b5cf742a]215
[0e94b979]216 if (retval != EOK)
[25a179e]217 return retval;
[b5cf742a]218
[02a09ed]219 size_t act_size = IPC_GET_ARG2(answer_name);
[0e94b979]220 assert(act_size <= LOC_NAME_MAXLEN);
[b5cf742a]221
[0e94b979]222 name_buf[act_size] = '\0';
[a2e3ee6]223
[02a09ed]224 ainfo->ilink = IPC_GET_ARG1(answer);
[0e94b979]225 ainfo->name = str_dup(name_buf);
[b5cf742a]226
[0e25780]227 return EOK;
228}
229
[fa101c4]230int inetcfg_addr_get_id(const char *name, sysarg_t link_id, sysarg_t *addr_id)
231{
232 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
233
234 ipc_call_t answer;
235 aid_t req = async_send_1(exch, INETCFG_ADDR_GET_ID, link_id, &answer);
[25a179e]236 int retval = async_data_write_start(exch, name, str_size(name));
[fa101c4]237
238 async_exchange_end(exch);
239
240 if (retval != EOK) {
[50b581d]241 async_forget(req);
[fa101c4]242 return retval;
243 }
244
245 async_wait_for(req, &retval);
246 *addr_id = IPC_GET_ARG1(answer);
247
248 return retval;
249}
250
[0e25780]251int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
252{
253 return inetcfg_get_ids_internal(INETCFG_GET_ADDR_LIST,
254 0, addrs, count);
255}
256
257int inetcfg_get_link_list(sysarg_t **links, size_t *count)
258{
259 return inetcfg_get_ids_internal(INETCFG_GET_LINK_LIST,
260 0, links, count);
261}
262
[8bf672d]263int inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
264{
265 return inetcfg_get_ids_internal(INETCFG_GET_SROUTE_LIST,
266 0, sroutes, count);
267}
268
[7af0cc5]269int inetcfg_link_add(sysarg_t link_id)
270{
271 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
272
273 int rc = async_req_1_0(exch, INETCFG_LINK_ADD, link_id);
274 async_exchange_end(exch);
275
276 return rc;
277}
278
[0e25780]279int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
280{
[0e94b979]281 ipc_call_t dreply;
[25a179e]282 int dretval;
[0e94b979]283 size_t act_size;
284 char name_buf[LOC_NAME_MAXLEN + 1];
285
[0e25780]286 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
287
[0e94b979]288 ipc_call_t answer;
289 aid_t req = async_send_1(exch, INETCFG_LINK_GET, link_id, &answer);
290 aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
[b8b1adb1]291 int rc = async_data_read_start(exch, &linfo->mac_addr, sizeof(addr48_t));
[0e94b979]292 async_wait_for(dreq, &dretval);
293
[0e25780]294 async_exchange_end(exch);
295
[b8b1adb1]296 if (dretval != EOK || rc != EOK) {
[50b581d]297 async_forget(req);
[0e94b979]298 return dretval;
299 }
300
[25a179e]301 int retval;
[0e94b979]302 async_wait_for(req, &retval);
303
304 if (retval != EOK)
305 return retval;
306
307 act_size = IPC_GET_ARG2(dreply);
308 assert(act_size <= LOC_NAME_MAXLEN);
309 name_buf[act_size] = '\0';
310
311 linfo->name = str_dup(name_buf);
[347768d]312 linfo->def_mtu = IPC_GET_ARG1(answer);
[0e25780]313
314 return EOK;
315}
316
[7af0cc5]317int inetcfg_link_remove(sysarg_t link_id)
318{
319 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
320
321 int rc = async_req_1_0(exch, INETCFG_LINK_REMOVE, link_id);
322 async_exchange_end(exch);
323
324 return rc;
325}
326
[8bf672d]327int inetcfg_sroute_create(const char *name, inet_naddr_t *dest,
328 inet_addr_t *router, sysarg_t *sroute_id)
329{
[02a09ed]330 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[a2e3ee6]331
[02a09ed]332 ipc_call_t answer;
333 aid_t req = async_send_0(exch, INETCFG_SROUTE_CREATE, &answer);
334
335 int rc = async_data_write_start(exch, dest, sizeof(inet_naddr_t));
336 if (rc != EOK) {
337 async_exchange_end(exch);
338 async_forget(req);
[a2e3ee6]339 return rc;
[02a09ed]340 }
[a2e3ee6]341
[02a09ed]342 rc = async_data_write_start(exch, router, sizeof(inet_addr_t));
343 if (rc != EOK) {
344 async_exchange_end(exch);
345 async_forget(req);
346 return rc;
347 }
[a2e3ee6]348
[02a09ed]349 rc = async_data_write_start(exch, name, str_size(name));
[a2e3ee6]350
[8bf672d]351 async_exchange_end(exch);
[a2e3ee6]352
[02a09ed]353 if (rc != EOK) {
[50b581d]354 async_forget(req);
[02a09ed]355 return rc;
[8bf672d]356 }
[a2e3ee6]357
[25a179e]358 int retval;
[8bf672d]359 async_wait_for(req, &retval);
[02a09ed]360
[8bf672d]361 *sroute_id = IPC_GET_ARG1(answer);
[a2e3ee6]362
[25a179e]363 return retval;
[8bf672d]364}
365
366int inetcfg_sroute_delete(sysarg_t sroute_id)
367{
368 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
369
370 int rc = async_req_1_0(exch, INETCFG_SROUTE_DELETE, sroute_id);
371 async_exchange_end(exch);
372
373 return rc;
374}
375
376int inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
377{
378 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[b5cf742a]379
[8bf672d]380 ipc_call_t answer;
381 aid_t req = async_send_1(exch, INETCFG_SROUTE_GET, sroute_id, &answer);
[02a09ed]382
383 ipc_call_t answer_dest;
384 aid_t req_dest = async_data_read(exch, &srinfo->dest,
385 sizeof(inet_naddr_t), &answer_dest);
386
[25a179e]387 int retval_dest;
[02a09ed]388 async_wait_for(req_dest, &retval_dest);
389
390 if (retval_dest != EOK) {
391 async_exchange_end(exch);
392 async_forget(req);
[25a179e]393 return retval_dest;
[02a09ed]394 }
395
396 ipc_call_t answer_router;
397 aid_t req_router = async_data_read(exch, &srinfo->router,
398 sizeof(inet_addr_t), &answer_router);
399
[25a179e]400 int retval_router;
[02a09ed]401 async_wait_for(req_router, &retval_router);
402
403 if (retval_router != EOK) {
404 async_exchange_end(exch);
405 async_forget(req);
[25a179e]406 return retval_router;
[02a09ed]407 }
408
409 ipc_call_t answer_name;
410 char name_buf[LOC_NAME_MAXLEN + 1];
411 aid_t req_name = async_data_read(exch, name_buf, LOC_NAME_MAXLEN,
412 &answer_name);
[b5cf742a]413
[8bf672d]414 async_exchange_end(exch);
[b5cf742a]415
[25a179e]416 int retval_name;
[02a09ed]417 async_wait_for(req_name, &retval_name);
418
419 if (retval_name != EOK) {
[50b581d]420 async_forget(req);
[25a179e]421 return retval_name;
[8bf672d]422 }
[b5cf742a]423
[25a179e]424 int retval;
[8bf672d]425 async_wait_for(req, &retval);
[b5cf742a]426
[8bf672d]427 if (retval != EOK)
[25a179e]428 return retval;
[b5cf742a]429
[02a09ed]430 size_t act_size = IPC_GET_ARG2(answer_name);
[8bf672d]431 assert(act_size <= LOC_NAME_MAXLEN);
[02a09ed]432
[8bf672d]433 name_buf[act_size] = '\0';
[02a09ed]434
[8bf672d]435 srinfo->name = str_dup(name_buf);
[b5cf742a]436
[8bf672d]437 return EOK;
438}
439
440int inetcfg_sroute_get_id(const char *name, sysarg_t *sroute_id)
441{
442 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
443
444 ipc_call_t answer;
445 aid_t req = async_send_0(exch, INETCFG_SROUTE_GET_ID, &answer);
[25a179e]446 int retval = async_data_write_start(exch, name, str_size(name));
[8bf672d]447
448 async_exchange_end(exch);
449
450 if (retval != EOK) {
[50b581d]451 async_forget(req);
[8bf672d]452 return retval;
453 }
454
455 async_wait_for(req, &retval);
456 *sroute_id = IPC_GET_ARG1(answer);
457
458 return retval;
459}
460
[0e25780]461/** @}
462 */
Note: See TracBrowser for help on using the repository browser.