source: mainline/uspace/lib/inet/src/inetcfg.c@ d5ed54b

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

Move TCP/IP library support out of libc to separate library

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