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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a2e3ee6 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: 9.3 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
57 sysarg_t retval;
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
76 * @return EOK on success or negative error code
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
[0e25780]122 rc = loc_service_get_id(SERVICE_NAME_INETCFG, &inet_svc,
123 IPC_FLAG_BLOCKING);
124 if (rc != EOK)
125 return ENOENT;
[77ad86c]126
[0e25780]127 inetcfg_sess = loc_service_connect(EXCHANGE_SERIALIZE, inet_svc,
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{
[a2e3ee6]138 uint32_t naddr_addr;
139 uint8_t naddr_bits;
140 int rc = inet_naddr_pack(naddr, &naddr_addr, &naddr_bits);
141 if (rc != EOK)
142 return rc;
143
[0e25780]144 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[a2e3ee6]145
[291c792]146 ipc_call_t answer;
[a2e3ee6]147 aid_t req = async_send_3(exch, INETCFG_ADDR_CREATE_STATIC,
148 (sysarg_t) naddr_addr, (sysarg_t) naddr_bits, link_id, &answer);
[291c792]149 sysarg_t retval = async_data_write_start(exch, name, str_size(name));
[a2e3ee6]150
[0e25780]151 async_exchange_end(exch);
[a2e3ee6]152
[291c792]153 if (retval != EOK) {
[50b581d]154 async_forget(req);
[291c792]155 return retval;
156 }
[a2e3ee6]157
[291c792]158 async_wait_for(req, &retval);
159 *addr_id = IPC_GET_ARG1(answer);
[a2e3ee6]160
[291c792]161 return retval;
[0e25780]162}
163
164int inetcfg_addr_delete(sysarg_t addr_id)
165{
166 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
167
168 int rc = async_req_1_0(exch, INETCFG_ADDR_DELETE, addr_id);
169 async_exchange_end(exch);
170
171 return rc;
172}
173
174int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
175{
[0e94b979]176 ipc_call_t dreply;
177 sysarg_t dretval;
178 size_t act_size;
179 char name_buf[LOC_NAME_MAXLEN + 1];
180
[0e25780]181 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
182
[0e94b979]183 ipc_call_t answer;
184 aid_t req = async_send_1(exch, INETCFG_ADDR_GET, addr_id, &answer);
185 aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
186 async_wait_for(dreq, &dretval);
187
[0e25780]188 async_exchange_end(exch);
189
[0e94b979]190 if (dretval != EOK) {
[50b581d]191 async_forget(req);
[0e94b979]192 return dretval;
193 }
194
195 sysarg_t retval;
196 async_wait_for(req, &retval);
197
198 if (retval != EOK)
199 return retval;
200
201 act_size = IPC_GET_ARG2(dreply);
202 assert(act_size <= LOC_NAME_MAXLEN);
203 name_buf[act_size] = '\0';
[a2e3ee6]204
205 inet_naddr_unpack(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
206 &ainfo->naddr);
[0e94b979]207 ainfo->ilink = IPC_GET_ARG3(answer);
208 ainfo->name = str_dup(name_buf);
[0e25780]209
210 return EOK;
211}
212
[fa101c4]213int inetcfg_addr_get_id(const char *name, sysarg_t link_id, sysarg_t *addr_id)
214{
215 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
216
217 ipc_call_t answer;
218 aid_t req = async_send_1(exch, INETCFG_ADDR_GET_ID, link_id, &answer);
219 sysarg_t retval = async_data_write_start(exch, name, str_size(name));
220
221 async_exchange_end(exch);
222
223 if (retval != EOK) {
[50b581d]224 async_forget(req);
[fa101c4]225 return retval;
226 }
227
228 async_wait_for(req, &retval);
229 *addr_id = IPC_GET_ARG1(answer);
230
231 return retval;
232}
233
[0e25780]234int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
235{
236 return inetcfg_get_ids_internal(INETCFG_GET_ADDR_LIST,
237 0, addrs, count);
238}
239
240int inetcfg_get_link_list(sysarg_t **links, size_t *count)
241{
242 return inetcfg_get_ids_internal(INETCFG_GET_LINK_LIST,
243 0, links, count);
244}
245
[8bf672d]246int inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
247{
248 return inetcfg_get_ids_internal(INETCFG_GET_SROUTE_LIST,
249 0, sroutes, count);
250}
251
[0e25780]252int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
253{
[0e94b979]254 ipc_call_t dreply;
255 sysarg_t dretval;
256 size_t act_size;
257 char name_buf[LOC_NAME_MAXLEN + 1];
258
[0e25780]259 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
260
[0e94b979]261 ipc_call_t answer;
262 aid_t req = async_send_1(exch, INETCFG_LINK_GET, link_id, &answer);
263 aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
264 async_wait_for(dreq, &dretval);
265
[0e25780]266 async_exchange_end(exch);
267
[0e94b979]268 if (dretval != EOK) {
[50b581d]269 async_forget(req);
[0e94b979]270 return dretval;
271 }
272
273 sysarg_t retval;
274 async_wait_for(req, &retval);
275
276 if (retval != EOK)
277 return retval;
278
279 act_size = IPC_GET_ARG2(dreply);
280 assert(act_size <= LOC_NAME_MAXLEN);
281 name_buf[act_size] = '\0';
282
283 linfo->name = str_dup(name_buf);
[347768d]284 linfo->def_mtu = IPC_GET_ARG1(answer);
[0e25780]285
286 return EOK;
287}
288
[8bf672d]289int inetcfg_sroute_create(const char *name, inet_naddr_t *dest,
290 inet_addr_t *router, sysarg_t *sroute_id)
291{
[a2e3ee6]292 uint32_t dest_addr;
293 uint8_t dest_bits;
294 int rc = inet_naddr_pack(dest, &dest_addr, &dest_bits);
295 if (rc != EOK)
296 return rc;
297
298 uint32_t router_addr;
299 rc = inet_addr_pack(router, &router_addr);
300 if (rc != EOK)
301 return rc;
302
[8bf672d]303 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
[a2e3ee6]304
[8bf672d]305 ipc_call_t answer;
306 aid_t req = async_send_3(exch, INETCFG_SROUTE_CREATE,
[a2e3ee6]307 (sysarg_t) dest_addr, (sysarg_t) dest_bits, (sysarg_t) router_addr,
308 &answer);
[8bf672d]309 sysarg_t retval = async_data_write_start(exch, name, str_size(name));
[a2e3ee6]310
[8bf672d]311 async_exchange_end(exch);
[a2e3ee6]312
[8bf672d]313 if (retval != EOK) {
[50b581d]314 async_forget(req);
[8bf672d]315 return retval;
316 }
[a2e3ee6]317
[8bf672d]318 async_wait_for(req, &retval);
319 *sroute_id = IPC_GET_ARG1(answer);
[a2e3ee6]320
[8bf672d]321 return retval;
322}
323
324int inetcfg_sroute_delete(sysarg_t sroute_id)
325{
326 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
327
328 int rc = async_req_1_0(exch, INETCFG_SROUTE_DELETE, sroute_id);
329 async_exchange_end(exch);
330
331 return rc;
332}
333
334int inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
335{
336 ipc_call_t dreply;
337 sysarg_t dretval;
338 size_t act_size;
339 char name_buf[LOC_NAME_MAXLEN + 1];
340
341 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
342
343 ipc_call_t answer;
344 aid_t req = async_send_1(exch, INETCFG_SROUTE_GET, sroute_id, &answer);
345 aid_t dreq = async_data_read(exch, name_buf, LOC_NAME_MAXLEN, &dreply);
346 async_wait_for(dreq, &dretval);
347
348 async_exchange_end(exch);
349
350 if (dretval != EOK) {
[50b581d]351 async_forget(req);
[8bf672d]352 return dretval;
353 }
354
355 sysarg_t retval;
356 async_wait_for(req, &retval);
357
358 if (retval != EOK)
359 return retval;
360
361 act_size = IPC_GET_ARG2(dreply);
362 assert(act_size <= LOC_NAME_MAXLEN);
363 name_buf[act_size] = '\0';
364
[a2e3ee6]365 inet_naddr_unpack(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
366 &srinfo->dest);
367 inet_addr_unpack(IPC_GET_ARG3(answer), &srinfo->router);
[8bf672d]368 srinfo->name = str_dup(name_buf);
369
370 return EOK;
371}
372
373int inetcfg_sroute_get_id(const char *name, sysarg_t *sroute_id)
374{
375 async_exch_t *exch = async_exchange_begin(inetcfg_sess);
376
377 ipc_call_t answer;
378 aid_t req = async_send_0(exch, INETCFG_SROUTE_GET_ID, &answer);
379 sysarg_t retval = async_data_write_start(exch, name, str_size(name));
380
381 async_exchange_end(exch);
382
383 if (retval != EOK) {
[50b581d]384 async_forget(req);
[8bf672d]385 return retval;
386 }
387
388 async_wait_for(req, &retval);
389 *sroute_id = IPC_GET_ARG1(answer);
390
391 return retval;
392}
393
[0e25780]394/** @}
395 */
Note: See TracBrowser for help on using the repository browser.