source: mainline/uspace/srv/inet/inetcfg.c@ fa101c4

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

Address deletion (needs better synchronization).

  • Property mode set to 100644
File size: 9.1 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
52static int inetcfg_addr_create_static(char *name, inet_naddr_t *naddr,
53 sysarg_t link_id, sysarg_t *addr_id)
54{
55 inet_link_t *ilink;
56 inet_addrobj_t *addr;
57 iplink_addr_t iaddr;
58 int rc;
59
60 ilink = inet_link_get_by_id(link_id);
61 if (ilink == NULL) {
62 log_msg(LVL_DEBUG, "Link %lu not found.",
63 (unsigned long) link_id);
64 return ENOENT;
65 }
66
67 addr = inet_addrobj_new();
68 addr->naddr = *naddr;
69 addr->ilink = ilink;
70 addr->name = str_dup(name);
71 inet_addrobj_add(addr);
72
73 iaddr.ipv4 = addr->naddr.ipv4;
74 rc = iplink_addr_add(ilink->iplink, &iaddr);
75 if (rc != EOK) {
76 log_msg(LVL_ERROR, "Failed setting IP address on internet link.");
77 inet_addrobj_remove(addr);
78 inet_addrobj_delete(addr);
79 return rc;
80 }
81
82 return EOK;
83}
84
85static int inetcfg_addr_delete(sysarg_t addr_id)
86{
87 inet_addrobj_t *addr;
88
89 addr = inet_addrobj_get_by_id(addr_id);
90 if (addr == NULL)
91 return ENOENT;
92
93 inet_addrobj_remove(addr);
94 inet_addrobj_delete(addr);
95
96 return EOK;
97}
98
99static int inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
100{
101 inet_addrobj_t *addr;
102
103 addr = inet_addrobj_get_by_id(addr_id);
104 if (addr == NULL)
105 return ENOENT;
106
107 ainfo->naddr = addr->naddr;
108 ainfo->ilink = addr->ilink->svc_id;
109 ainfo->name = str_dup(addr->name);
110
111 return EOK;
112}
113
114static int inetcfg_addr_get_id(char *name, sysarg_t link_id, sysarg_t *addr_id)
115{
116 inet_link_t *ilink;
117 inet_addrobj_t *addr;
118
119 ilink = inet_link_get_by_id(link_id);
120 if (ilink == NULL) {
121 log_msg(LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
122 return ENOENT;
123 }
124
125 addr = inet_addrobj_find_by_name(name, ilink);
126 if (addr == NULL) {
127 log_msg(LVL_DEBUG, "Address '%s' not found.", name);
128 return ENOENT;
129 }
130
131 *addr_id = addr->id;
132 return EOK;
133}
134
135static int inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
136{
137 return inet_addrobj_get_id_list(addrs, count);
138}
139
140static int inetcfg_get_link_list(sysarg_t **addrs, size_t *count)
141{
142 return ENOTSUP;
143}
144
145static int inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
146{
147 inet_link_t *ilink;
148
149 ilink = inet_link_get_by_id(link_id);
150 if (ilink == NULL) {
151 return ENOENT;
152 }
153
154 linfo->name = str_dup(ilink->svc_name);
155 return EOK;
156}
157
158static void inetcfg_addr_create_static_srv(ipc_callid_t callid,
159 ipc_call_t *call)
160{
161 char *name;
162 inet_naddr_t naddr;
163 sysarg_t link_id;
164 sysarg_t addr_id;
165 int rc;
166
167 log_msg(LVL_DEBUG, "inetcfg_addr_create_static_srv()");
168
169 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
170 0, NULL);
171 if (rc != EOK) {
172 async_answer_0(callid, rc);
173 return;
174 }
175
176 naddr.ipv4 = IPC_GET_ARG1(*call);
177 naddr.bits = IPC_GET_ARG2(*call);
178 link_id = IPC_GET_ARG3(*call);
179
180 addr_id = 0;
181 rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id);
182 free(name);
183 async_answer_1(callid, rc, addr_id);
184}
185
186static void inetcfg_addr_delete_srv(ipc_callid_t callid, ipc_call_t *call)
187{
188 sysarg_t addr_id;
189 int rc;
190
191 log_msg(LVL_DEBUG, "inetcfg_addr_delete_srv()");
192
193 addr_id = IPC_GET_ARG1(*call);
194
195 rc = inetcfg_addr_delete(addr_id);
196 async_answer_0(callid, rc);
197}
198
199static void inetcfg_addr_get_srv(ipc_callid_t callid, ipc_call_t *call)
200{
201 ipc_callid_t rcallid;
202 size_t max_size;
203
204 sysarg_t addr_id;
205 inet_addr_info_t ainfo;
206 int rc;
207
208 addr_id = IPC_GET_ARG1(*call);
209 log_msg(LVL_DEBUG, "inetcfg_addr_get_srv()");
210
211 ainfo.naddr.ipv4 = 0;
212 ainfo.naddr.bits = 0;
213 ainfo.ilink = 0;
214 ainfo.name = NULL;
215
216 if (!async_data_read_receive(&rcallid, &max_size)) {
217 async_answer_0(rcallid, EREFUSED);
218 async_answer_0(callid, EREFUSED);
219 return;
220 }
221
222 rc = inetcfg_addr_get(addr_id, &ainfo);
223 if (rc != EOK) {
224 async_answer_0(callid, rc);
225 return;
226 }
227
228 sysarg_t retval = async_data_read_finalize(rcallid, ainfo.name,
229 min(max_size, str_size(ainfo.name)));
230 free(ainfo.name);
231
232 async_answer_3(callid, retval, ainfo.naddr.ipv4, ainfo.naddr.bits,
233 ainfo.ilink);
234}
235
236static void inetcfg_addr_get_id_srv(ipc_callid_t callid, ipc_call_t *call)
237{
238 char *name;
239 sysarg_t link_id;
240 sysarg_t addr_id;
241 int rc;
242
243 log_msg(LVL_DEBUG, "inetcfg_addr_get_id_srv()");
244
245 link_id = IPC_GET_ARG1(*call);
246
247 rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
248 0, NULL);
249 if (rc != EOK) {
250 async_answer_0(callid, rc);
251 return;
252 }
253
254 addr_id = 0;
255 rc = inetcfg_addr_get_id(name, link_id, &addr_id);
256 free(name);
257 async_answer_1(callid, rc, addr_id);
258}
259
260
261static void inetcfg_get_addr_list_srv(ipc_callid_t callid, ipc_call_t *call)
262{
263 ipc_callid_t rcallid;
264 size_t count;
265 size_t max_size;
266 size_t act_size;
267 size_t size;
268 sysarg_t *id_buf;
269 int rc;
270
271 log_msg(LVL_DEBUG, "inetcfg_get_addr_list_srv()");
272
273 if (!async_data_read_receive(&rcallid, &max_size)) {
274 async_answer_0(rcallid, EREFUSED);
275 async_answer_0(callid, EREFUSED);
276 return;
277 }
278
279 rc = inetcfg_get_addr_list(&id_buf, &count);
280 if (rc != EOK) {
281 async_answer_0(rcallid, rc);
282 async_answer_0(callid, rc);
283 return;
284 }
285
286 act_size = count * sizeof(sysarg_t);
287 size = min(act_size, max_size);
288
289 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
290 free(id_buf);
291
292 async_answer_1(callid, retval, act_size);
293}
294
295static void inetcfg_link_get_srv(ipc_callid_t callid, ipc_call_t *call)
296{
297 ipc_callid_t rcallid;
298 size_t max_size;
299
300 sysarg_t link_id;
301 inet_link_info_t linfo;
302 int rc;
303
304 link_id = IPC_GET_ARG1(*call);
305 log_msg(LVL_DEBUG, "inetcfg_link_get_srv()");
306
307 linfo.name = NULL;
308
309 if (!async_data_read_receive(&rcallid, &max_size)) {
310 async_answer_0(rcallid, EREFUSED);
311 async_answer_0(callid, EREFUSED);
312 return;
313 }
314
315 rc = inetcfg_link_get(link_id, &linfo);
316 if (rc != EOK) {
317 async_answer_0(rcallid, rc);
318 async_answer_0(callid, rc);
319 return;
320 }
321
322 sysarg_t retval = async_data_read_finalize(rcallid, linfo.name,
323 min(max_size, str_size(linfo.name)));
324 free(linfo.name);
325
326 async_answer_0(callid, retval);
327}
328
329static void inetcfg_get_link_list_srv(ipc_callid_t callid, ipc_call_t *call)
330{
331 ipc_callid_t rcallid;
332 size_t max_size;
333 size_t act_size;
334 size_t size;
335 sysarg_t *id_buf;
336 int rc;
337
338 log_msg(LVL_DEBUG, "inetcfg_get_link_list_srv()");
339
340 if (!async_data_read_receive(&rcallid, &max_size)) {
341 async_answer_0(rcallid, EREFUSED);
342 async_answer_0(callid, EREFUSED);
343 return;
344 }
345
346 rc = inetcfg_get_link_list(&id_buf, &act_size);
347 if (rc != EOK) {
348 async_answer_0(rcallid, rc);
349 async_answer_0(callid, rc);
350 return;
351 }
352
353 size = min(act_size, max_size);
354
355 sysarg_t retval = async_data_read_finalize(rcallid, id_buf, size);
356 free(id_buf);
357
358 async_answer_1(callid, retval, act_size);
359}
360
361void inet_cfg_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg)
362{
363 log_msg(LVL_DEBUG, "inet_cfg_conn()");
364
365 /* Accept the connection */
366 async_answer_0(iid, EOK);
367
368 while (true) {
369 ipc_call_t call;
370 ipc_callid_t callid = async_get_call(&call);
371 sysarg_t method = IPC_GET_IMETHOD(call);
372
373 if (!method) {
374 /* The other side has hung up */
375 async_answer_0(callid, EOK);
376 return;
377 }
378
379 switch (method) {
380 case INETCFG_ADDR_CREATE_STATIC:
381 inetcfg_addr_create_static_srv(callid, &call);
382 break;
383 case INETCFG_ADDR_DELETE:
384 inetcfg_addr_delete_srv(callid, &call);
385 break;
386 case INETCFG_ADDR_GET:
387 inetcfg_addr_get_srv(callid, &call);
388 break;
389 case INETCFG_ADDR_GET_ID:
390 inetcfg_addr_get_id_srv(callid, &call);
391 break;
392 case INETCFG_GET_ADDR_LIST:
393 inetcfg_get_addr_list_srv(callid, &call);
394 break;
395 case INETCFG_GET_LINK_LIST:
396 inetcfg_get_link_list_srv(callid, &call);
397 break;
398 case INETCFG_LINK_GET:
399 inetcfg_link_get_srv(callid, &call);
400 break;
401 default:
402 async_answer_0(callid, EINVAL);
403 }
404 }
405}
406
407/** @}
408 */
Note: See TracBrowser for help on using the repository browser.