[0e25780] | 1 | /*
|
---|
[7af0cc5] | 2 | * Copyright (c) 2013 Jiri Svoboda
|
---|
[0e25780] | 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>
|
---|
[8d2dd7f2] | 45 | #include <stddef.h>
|
---|
[b8b1adb1] | 46 | #include <types/inetcfg.h>
|
---|
[0e25780] | 47 |
|
---|
[45aa22c] | 48 | #include "addrobj.h"
|
---|
[b4ec1ea] | 49 | #include "inetsrv.h"
|
---|
[45aa22c] | 50 | #include "inet_link.h"
|
---|
[0e25780] | 51 | #include "inetcfg.h"
|
---|
[8bf672d] | 52 | #include "sroute.h"
|
---|
[0e25780] | 53 |
|
---|
[b7fd2a0] | 54 | static errno_t inetcfg_addr_create_static(char *name, inet_naddr_t *naddr,
|
---|
[291c792] | 55 | sysarg_t link_id, sysarg_t *addr_id)
|
---|
[0e25780] | 56 | {
|
---|
[45aa22c] | 57 | inet_link_t *ilink;
|
---|
| 58 | inet_addrobj_t *addr;
|
---|
[a2e3ee6] | 59 | inet_addr_t iaddr;
|
---|
[b7fd2a0] | 60 | errno_t rc;
|
---|
[45aa22c] | 61 |
|
---|
| 62 | ilink = inet_link_get_by_id(link_id);
|
---|
| 63 | if (ilink == NULL) {
|
---|
[a1a101d] | 64 | log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %lu not found.",
|
---|
[45aa22c] | 65 | (unsigned long) link_id);
|
---|
| 66 | return ENOENT;
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | addr = inet_addrobj_new();
|
---|
[8bf672d] | 70 | if (addr == NULL) {
|
---|
| 71 | *addr_id = 0;
|
---|
| 72 | return ENOMEM;
|
---|
| 73 | }
|
---|
| 74 |
|
---|
[45aa22c] | 75 | addr->naddr = *naddr;
|
---|
| 76 | addr->ilink = ilink;
|
---|
[291c792] | 77 | addr->name = str_dup(name);
|
---|
[bf9e6fc] | 78 | rc = inet_addrobj_add(addr);
|
---|
| 79 | if (rc != EOK) {
|
---|
[a1a101d] | 80 | log_msg(LOG_DEFAULT, LVL_DEBUG, "Duplicate address name '%s'.", addr->name);
|
---|
[bf9e6fc] | 81 | inet_addrobj_delete(addr);
|
---|
| 82 | return rc;
|
---|
| 83 | }
|
---|
[45aa22c] | 84 |
|
---|
[a2e3ee6] | 85 | inet_naddr_addr(&addr->naddr, &iaddr);
|
---|
[45aa22c] | 86 | rc = iplink_addr_add(ilink->iplink, &iaddr);
|
---|
| 87 | if (rc != EOK) {
|
---|
[a1a101d] | 88 | log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
|
---|
[45aa22c] | 89 | inet_addrobj_remove(addr);
|
---|
| 90 | inet_addrobj_delete(addr);
|
---|
| 91 | return rc;
|
---|
| 92 | }
|
---|
| 93 |
|
---|
| 94 | return EOK;
|
---|
[0e25780] | 95 | }
|
---|
| 96 |
|
---|
[b7fd2a0] | 97 | static errno_t inetcfg_addr_delete(sysarg_t addr_id)
|
---|
[0e25780] | 98 | {
|
---|
[fa101c4] | 99 | inet_addrobj_t *addr;
|
---|
| 100 |
|
---|
| 101 | addr = inet_addrobj_get_by_id(addr_id);
|
---|
| 102 | if (addr == NULL)
|
---|
| 103 | return ENOENT;
|
---|
| 104 |
|
---|
| 105 | inet_addrobj_remove(addr);
|
---|
| 106 | inet_addrobj_delete(addr);
|
---|
| 107 |
|
---|
| 108 | return EOK;
|
---|
[0e25780] | 109 | }
|
---|
| 110 |
|
---|
[b7fd2a0] | 111 | static errno_t inetcfg_addr_get(sysarg_t addr_id, inet_addr_info_t *ainfo)
|
---|
[0e25780] | 112 | {
|
---|
[0e94b979] | 113 | inet_addrobj_t *addr;
|
---|
| 114 |
|
---|
| 115 | addr = inet_addrobj_get_by_id(addr_id);
|
---|
| 116 | if (addr == NULL)
|
---|
| 117 | return ENOENT;
|
---|
| 118 |
|
---|
| 119 | ainfo->naddr = addr->naddr;
|
---|
| 120 | ainfo->ilink = addr->ilink->svc_id;
|
---|
| 121 | ainfo->name = str_dup(addr->name);
|
---|
| 122 |
|
---|
| 123 | return EOK;
|
---|
[0e25780] | 124 | }
|
---|
| 125 |
|
---|
[b7fd2a0] | 126 | static errno_t inetcfg_addr_get_id(char *name, sysarg_t link_id, sysarg_t *addr_id)
|
---|
[fa101c4] | 127 | {
|
---|
| 128 | inet_link_t *ilink;
|
---|
| 129 | inet_addrobj_t *addr;
|
---|
| 130 |
|
---|
| 131 | ilink = inet_link_get_by_id(link_id);
|
---|
| 132 | if (ilink == NULL) {
|
---|
[a1a101d] | 133 | log_msg(LOG_DEFAULT, LVL_DEBUG, "Link %zu not found.", (size_t) link_id);
|
---|
[fa101c4] | 134 | return ENOENT;
|
---|
| 135 | }
|
---|
| 136 |
|
---|
| 137 | addr = inet_addrobj_find_by_name(name, ilink);
|
---|
| 138 | if (addr == NULL) {
|
---|
[a1a101d] | 139 | log_msg(LOG_DEFAULT, LVL_DEBUG, "Address '%s' not found.", name);
|
---|
[fa101c4] | 140 | return ENOENT;
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | *addr_id = addr->id;
|
---|
| 144 | return EOK;
|
---|
| 145 | }
|
---|
| 146 |
|
---|
[b7fd2a0] | 147 | static errno_t inetcfg_get_addr_list(sysarg_t **addrs, size_t *count)
|
---|
[0e25780] | 148 | {
|
---|
[0e94b979] | 149 | return inet_addrobj_get_id_list(addrs, count);
|
---|
[0e25780] | 150 | }
|
---|
| 151 |
|
---|
[b7fd2a0] | 152 | static errno_t inetcfg_get_link_list(sysarg_t **addrs, size_t *count)
|
---|
[0e25780] | 153 | {
|
---|
[b8b1adb1] | 154 | return inet_link_get_id_list(addrs, count);
|
---|
[0e25780] | 155 | }
|
---|
| 156 |
|
---|
[b7fd2a0] | 157 | static errno_t inetcfg_get_sroute_list(sysarg_t **sroutes, size_t *count)
|
---|
[8bf672d] | 158 | {
|
---|
| 159 | return inet_sroute_get_id_list(sroutes, count);
|
---|
| 160 | }
|
---|
| 161 |
|
---|
[b7fd2a0] | 162 | static errno_t inetcfg_link_add(sysarg_t link_id)
|
---|
[7af0cc5] | 163 | {
|
---|
| 164 | return inet_link_open(link_id);
|
---|
| 165 | }
|
---|
| 166 |
|
---|
[b7fd2a0] | 167 | static errno_t inetcfg_link_get(sysarg_t link_id, inet_link_info_t *linfo)
|
---|
[0e25780] | 168 | {
|
---|
[0e94b979] | 169 | inet_link_t *ilink;
|
---|
| 170 |
|
---|
| 171 | ilink = inet_link_get_by_id(link_id);
|
---|
| 172 | if (ilink == NULL) {
|
---|
| 173 | return ENOENT;
|
---|
| 174 | }
|
---|
| 175 |
|
---|
| 176 | linfo->name = str_dup(ilink->svc_name);
|
---|
[347768d] | 177 | linfo->def_mtu = ilink->def_mtu;
|
---|
[b8b1adb1] | 178 | if (ilink->mac_valid) {
|
---|
| 179 | addr48(ilink->mac, linfo->mac_addr);
|
---|
| 180 | } else {
|
---|
| 181 | memset(linfo->mac_addr, 0, sizeof(linfo->mac_addr));
|
---|
| 182 | }
|
---|
| 183 |
|
---|
[0e94b979] | 184 | return EOK;
|
---|
[0e25780] | 185 | }
|
---|
| 186 |
|
---|
[b7fd2a0] | 187 | static errno_t inetcfg_link_remove(sysarg_t link_id)
|
---|
[7af0cc5] | 188 | {
|
---|
| 189 | return ENOTSUP;
|
---|
| 190 | }
|
---|
| 191 |
|
---|
[b7fd2a0] | 192 | static errno_t inetcfg_sroute_create(char *name, inet_naddr_t *dest,
|
---|
[8bf672d] | 193 | inet_addr_t *router, sysarg_t *sroute_id)
|
---|
| 194 | {
|
---|
| 195 | inet_sroute_t *sroute;
|
---|
| 196 |
|
---|
| 197 | sroute = inet_sroute_new();
|
---|
| 198 | if (sroute == NULL) {
|
---|
| 199 | *sroute_id = 0;
|
---|
| 200 | return ENOMEM;
|
---|
| 201 | }
|
---|
| 202 |
|
---|
| 203 | sroute->dest = *dest;
|
---|
| 204 | sroute->router = *router;
|
---|
| 205 | sroute->name = str_dup(name);
|
---|
| 206 | inet_sroute_add(sroute);
|
---|
| 207 |
|
---|
| 208 | *sroute_id = sroute->id;
|
---|
| 209 | return EOK;
|
---|
| 210 | }
|
---|
| 211 |
|
---|
[b7fd2a0] | 212 | static errno_t inetcfg_sroute_delete(sysarg_t sroute_id)
|
---|
[8bf672d] | 213 | {
|
---|
| 214 | inet_sroute_t *sroute;
|
---|
| 215 |
|
---|
| 216 | sroute = inet_sroute_get_by_id(sroute_id);
|
---|
| 217 | if (sroute == NULL)
|
---|
| 218 | return ENOENT;
|
---|
| 219 |
|
---|
| 220 | inet_sroute_remove(sroute);
|
---|
| 221 | inet_sroute_delete(sroute);
|
---|
| 222 |
|
---|
| 223 | return EOK;
|
---|
| 224 | }
|
---|
| 225 |
|
---|
[b7fd2a0] | 226 | static errno_t inetcfg_sroute_get(sysarg_t sroute_id, inet_sroute_info_t *srinfo)
|
---|
[8bf672d] | 227 | {
|
---|
| 228 | inet_sroute_t *sroute;
|
---|
| 229 |
|
---|
| 230 | sroute = inet_sroute_get_by_id(sroute_id);
|
---|
| 231 | if (sroute == NULL)
|
---|
| 232 | return ENOENT;
|
---|
| 233 |
|
---|
| 234 | srinfo->dest = sroute->dest;
|
---|
| 235 | srinfo->router = sroute->router;
|
---|
| 236 | srinfo->name = str_dup(sroute->name);
|
---|
| 237 |
|
---|
| 238 | return EOK;
|
---|
| 239 | }
|
---|
| 240 |
|
---|
[b7fd2a0] | 241 | static errno_t inetcfg_sroute_get_id(char *name, sysarg_t *sroute_id)
|
---|
[8bf672d] | 242 | {
|
---|
| 243 | inet_sroute_t *sroute;
|
---|
| 244 |
|
---|
| 245 | sroute = inet_sroute_find_by_name(name);
|
---|
| 246 | if (sroute == NULL) {
|
---|
[a1a101d] | 247 | log_msg(LOG_DEFAULT, LVL_DEBUG, "Static route '%s' not found.", name);
|
---|
[8bf672d] | 248 | return ENOENT;
|
---|
| 249 | }
|
---|
| 250 |
|
---|
| 251 | *sroute_id = sroute->id;
|
---|
| 252 | return EOK;
|
---|
| 253 | }
|
---|
| 254 |
|
---|
[984a9ba] | 255 | static void inetcfg_addr_create_static_srv(ipc_call_t *icall)
|
---|
[0e25780] | 256 | {
|
---|
[a1a101d] | 257 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_create_static_srv()");
|
---|
[a35b458] | 258 |
|
---|
[02a09ed] | 259 | sysarg_t link_id = IPC_GET_ARG1(*icall);
|
---|
[a35b458] | 260 |
|
---|
[984a9ba] | 261 | ipc_call_t call;
|
---|
[02a09ed] | 262 | size_t size;
|
---|
[984a9ba] | 263 | if (!async_data_write_receive(&call, &size)) {
|
---|
| 264 | async_answer_0(&call, EINVAL);
|
---|
| 265 | async_answer_0(icall, EINVAL);
|
---|
[02a09ed] | 266 | return;
|
---|
| 267 | }
|
---|
[a35b458] | 268 |
|
---|
[02a09ed] | 269 | if (size != sizeof(inet_naddr_t)) {
|
---|
[984a9ba] | 270 | async_answer_0(&call, EINVAL);
|
---|
| 271 | async_answer_0(icall, EINVAL);
|
---|
[02a09ed] | 272 | return;
|
---|
| 273 | }
|
---|
[a35b458] | 274 |
|
---|
[02a09ed] | 275 | inet_naddr_t naddr;
|
---|
[984a9ba] | 276 | errno_t rc = async_data_write_finalize(&call, &naddr, size);
|
---|
[02a09ed] | 277 | if (rc != EOK) {
|
---|
[984a9ba] | 278 | async_answer_0(&call, rc);
|
---|
| 279 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 280 | return;
|
---|
| 281 | }
|
---|
[a35b458] | 282 |
|
---|
[02a09ed] | 283 | char *name;
|
---|
[291c792] | 284 | rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
|
---|
| 285 | 0, NULL);
|
---|
| 286 | if (rc != EOK) {
|
---|
[984a9ba] | 287 | async_answer_0(icall, rc);
|
---|
[291c792] | 288 | return;
|
---|
| 289 | }
|
---|
[a35b458] | 290 |
|
---|
[02a09ed] | 291 | sysarg_t addr_id = 0;
|
---|
[291c792] | 292 | rc = inetcfg_addr_create_static(name, &naddr, link_id, &addr_id);
|
---|
| 293 | free(name);
|
---|
[984a9ba] | 294 | async_answer_1(icall, rc, addr_id);
|
---|
[0e25780] | 295 | }
|
---|
| 296 |
|
---|
[984a9ba] | 297 | static void inetcfg_addr_delete_srv(ipc_call_t *call)
|
---|
[0e25780] | 298 | {
|
---|
| 299 | sysarg_t addr_id;
|
---|
[b7fd2a0] | 300 | errno_t rc;
|
---|
[0e25780] | 301 |
|
---|
[a1a101d] | 302 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_delete_srv()");
|
---|
[0e25780] | 303 |
|
---|
| 304 | addr_id = IPC_GET_ARG1(*call);
|
---|
| 305 |
|
---|
| 306 | rc = inetcfg_addr_delete(addr_id);
|
---|
[984a9ba] | 307 | async_answer_0(call, rc);
|
---|
[0e25780] | 308 | }
|
---|
| 309 |
|
---|
[984a9ba] | 310 | static void inetcfg_addr_get_srv(ipc_call_t *icall)
|
---|
[0e25780] | 311 | {
|
---|
[a1a101d] | 312 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_srv()");
|
---|
[a35b458] | 313 |
|
---|
[02a09ed] | 314 | sysarg_t addr_id = IPC_GET_ARG1(*icall);
|
---|
[a35b458] | 315 |
|
---|
[a2e3ee6] | 316 | inet_addr_info_t ainfo;
|
---|
[a35b458] | 317 |
|
---|
[a2e3ee6] | 318 | inet_naddr_any(&ainfo.naddr);
|
---|
[0e94b979] | 319 | ainfo.ilink = 0;
|
---|
| 320 | ainfo.name = NULL;
|
---|
[a35b458] | 321 |
|
---|
[b7fd2a0] | 322 | errno_t rc = inetcfg_addr_get(addr_id, &ainfo);
|
---|
[02a09ed] | 323 | if (rc != EOK) {
|
---|
[984a9ba] | 324 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 325 | return;
|
---|
| 326 | }
|
---|
[a35b458] | 327 |
|
---|
[984a9ba] | 328 | ipc_call_t call;
|
---|
[02a09ed] | 329 | size_t size;
|
---|
[984a9ba] | 330 | if (!async_data_read_receive(&call, &size)) {
|
---|
| 331 | async_answer_0(&call, EREFUSED);
|
---|
| 332 | async_answer_0(icall, EREFUSED);
|
---|
[0e94b979] | 333 | return;
|
---|
| 334 | }
|
---|
[a35b458] | 335 |
|
---|
[02a09ed] | 336 | if (size != sizeof(inet_naddr_t)) {
|
---|
[984a9ba] | 337 | async_answer_0(&call, EINVAL);
|
---|
| 338 | async_answer_0(icall, EINVAL);
|
---|
[0e94b979] | 339 | return;
|
---|
| 340 | }
|
---|
[a35b458] | 341 |
|
---|
[984a9ba] | 342 | rc = async_data_read_finalize(&call, &ainfo.naddr, size);
|
---|
[a2e3ee6] | 343 | if (rc != EOK) {
|
---|
[984a9ba] | 344 | async_answer_0(&call, rc);
|
---|
| 345 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 346 | return;
|
---|
| 347 | }
|
---|
[a35b458] | 348 |
|
---|
[984a9ba] | 349 | if (!async_data_read_receive(&call, &size)) {
|
---|
| 350 | async_answer_0(&call, EREFUSED);
|
---|
| 351 | async_answer_0(icall, EREFUSED);
|
---|
[a2e3ee6] | 352 | return;
|
---|
| 353 | }
|
---|
[a35b458] | 354 |
|
---|
[984a9ba] | 355 | rc = async_data_read_finalize(&call, ainfo.name,
|
---|
[02a09ed] | 356 | min(size, str_size(ainfo.name)));
|
---|
[0e94b979] | 357 | free(ainfo.name);
|
---|
[a35b458] | 358 |
|
---|
[02a09ed] | 359 | if (rc != EOK) {
|
---|
[984a9ba] | 360 | async_answer_0(&call, rc);
|
---|
| 361 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 362 | return;
|
---|
| 363 | }
|
---|
[a35b458] | 364 |
|
---|
[984a9ba] | 365 | async_answer_1(icall, rc, ainfo.ilink);
|
---|
[0e25780] | 366 | }
|
---|
| 367 |
|
---|
[984a9ba] | 368 | static void inetcfg_addr_get_id_srv(ipc_call_t *call)
|
---|
[fa101c4] | 369 | {
|
---|
| 370 | char *name;
|
---|
| 371 | sysarg_t link_id;
|
---|
| 372 | sysarg_t addr_id;
|
---|
[b7fd2a0] | 373 | errno_t rc;
|
---|
[fa101c4] | 374 |
|
---|
[a1a101d] | 375 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_addr_get_id_srv()");
|
---|
[fa101c4] | 376 |
|
---|
| 377 | link_id = IPC_GET_ARG1(*call);
|
---|
| 378 |
|
---|
| 379 | rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
|
---|
| 380 | 0, NULL);
|
---|
| 381 | if (rc != EOK) {
|
---|
[984a9ba] | 382 | async_answer_0(call, rc);
|
---|
[fa101c4] | 383 | return;
|
---|
| 384 | }
|
---|
| 385 |
|
---|
| 386 | addr_id = 0;
|
---|
| 387 | rc = inetcfg_addr_get_id(name, link_id, &addr_id);
|
---|
| 388 | free(name);
|
---|
[984a9ba] | 389 | async_answer_1(call, rc, addr_id);
|
---|
[fa101c4] | 390 | }
|
---|
| 391 |
|
---|
[984a9ba] | 392 | static void inetcfg_get_addr_list_srv(ipc_call_t *call)
|
---|
[0e25780] | 393 | {
|
---|
[984a9ba] | 394 | ipc_call_t rcall;
|
---|
[0e94b979] | 395 | size_t count;
|
---|
[0e25780] | 396 | size_t max_size;
|
---|
| 397 | size_t act_size;
|
---|
| 398 | size_t size;
|
---|
| 399 | sysarg_t *id_buf;
|
---|
[b7fd2a0] | 400 | errno_t rc;
|
---|
[0e25780] | 401 |
|
---|
[a1a101d] | 402 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_addr_list_srv()");
|
---|
[0e25780] | 403 |
|
---|
[984a9ba] | 404 | if (!async_data_read_receive(&rcall, &max_size)) {
|
---|
| 405 | async_answer_0(&rcall, EREFUSED);
|
---|
| 406 | async_answer_0(call, EREFUSED);
|
---|
[0e25780] | 407 | return;
|
---|
| 408 | }
|
---|
| 409 |
|
---|
[0e94b979] | 410 | rc = inetcfg_get_addr_list(&id_buf, &count);
|
---|
[0e25780] | 411 | if (rc != EOK) {
|
---|
[984a9ba] | 412 | async_answer_0(&rcall, rc);
|
---|
| 413 | async_answer_0(call, rc);
|
---|
[0e25780] | 414 | return;
|
---|
| 415 | }
|
---|
| 416 |
|
---|
[0e94b979] | 417 | act_size = count * sizeof(sysarg_t);
|
---|
[0e25780] | 418 | size = min(act_size, max_size);
|
---|
| 419 |
|
---|
[984a9ba] | 420 | errno_t retval = async_data_read_finalize(&rcall, id_buf, size);
|
---|
[0e25780] | 421 | free(id_buf);
|
---|
| 422 |
|
---|
[984a9ba] | 423 | async_answer_1(call, retval, act_size);
|
---|
[0e25780] | 424 | }
|
---|
| 425 |
|
---|
[984a9ba] | 426 | static void inetcfg_get_link_list_srv(ipc_call_t *call)
|
---|
[8bf672d] | 427 | {
|
---|
[984a9ba] | 428 | ipc_call_t rcall;
|
---|
[b8b1adb1] | 429 | size_t count;
|
---|
[8bf672d] | 430 | size_t max_size;
|
---|
| 431 | size_t act_size;
|
---|
| 432 | size_t size;
|
---|
| 433 | sysarg_t *id_buf;
|
---|
[b7fd2a0] | 434 | errno_t rc;
|
---|
[8bf672d] | 435 |
|
---|
[b8b1adb1] | 436 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_addr_list_srv()");
|
---|
[8bf672d] | 437 |
|
---|
[984a9ba] | 438 | if (!async_data_read_receive(&rcall, &max_size)) {
|
---|
| 439 | async_answer_0(&rcall, EREFUSED);
|
---|
| 440 | async_answer_0(call, EREFUSED);
|
---|
[8bf672d] | 441 | return;
|
---|
| 442 | }
|
---|
| 443 |
|
---|
[b8b1adb1] | 444 | rc = inetcfg_get_link_list(&id_buf, &count);
|
---|
[8bf672d] | 445 | if (rc != EOK) {
|
---|
[984a9ba] | 446 | async_answer_0(&rcall, rc);
|
---|
| 447 | async_answer_0(call, rc);
|
---|
[8bf672d] | 448 | return;
|
---|
| 449 | }
|
---|
| 450 |
|
---|
[b8b1adb1] | 451 | act_size = count * sizeof(sysarg_t);
|
---|
[8bf672d] | 452 | size = min(act_size, max_size);
|
---|
| 453 |
|
---|
[984a9ba] | 454 | errno_t retval = async_data_read_finalize(&rcall, id_buf, size);
|
---|
[8bf672d] | 455 | free(id_buf);
|
---|
| 456 |
|
---|
[984a9ba] | 457 | async_answer_1(call, retval, act_size);
|
---|
[8bf672d] | 458 | }
|
---|
| 459 |
|
---|
[984a9ba] | 460 | static void inetcfg_get_sroute_list_srv(ipc_call_t *call)
|
---|
[8bf672d] | 461 | {
|
---|
[984a9ba] | 462 | ipc_call_t rcall;
|
---|
[8bf672d] | 463 | size_t count;
|
---|
| 464 | size_t max_size;
|
---|
| 465 | size_t act_size;
|
---|
| 466 | size_t size;
|
---|
| 467 | sysarg_t *id_buf;
|
---|
[b7fd2a0] | 468 | errno_t rc;
|
---|
[8bf672d] | 469 |
|
---|
[a1a101d] | 470 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_get_sroute_list_srv()");
|
---|
[8bf672d] | 471 |
|
---|
[984a9ba] | 472 | if (!async_data_read_receive(&rcall, &max_size)) {
|
---|
| 473 | async_answer_0(&rcall, EREFUSED);
|
---|
| 474 | async_answer_0(call, EREFUSED);
|
---|
[8bf672d] | 475 | return;
|
---|
| 476 | }
|
---|
| 477 |
|
---|
| 478 | rc = inetcfg_get_sroute_list(&id_buf, &count);
|
---|
| 479 | if (rc != EOK) {
|
---|
[984a9ba] | 480 | async_answer_0(&rcall, rc);
|
---|
| 481 | async_answer_0(call, rc);
|
---|
[8bf672d] | 482 | return;
|
---|
| 483 | }
|
---|
| 484 |
|
---|
| 485 | act_size = count * sizeof(sysarg_t);
|
---|
| 486 | size = min(act_size, max_size);
|
---|
| 487 |
|
---|
[984a9ba] | 488 | errno_t retval = async_data_read_finalize(&rcall, id_buf, size);
|
---|
[8bf672d] | 489 | free(id_buf);
|
---|
| 490 |
|
---|
[984a9ba] | 491 | async_answer_1(call, retval, act_size);
|
---|
[8bf672d] | 492 | }
|
---|
| 493 |
|
---|
[984a9ba] | 494 | static void inetcfg_link_add_srv(ipc_call_t *call)
|
---|
[7af0cc5] | 495 | {
|
---|
| 496 | sysarg_t link_id;
|
---|
[b7fd2a0] | 497 | errno_t rc;
|
---|
[7af0cc5] | 498 |
|
---|
| 499 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_add_srv()");
|
---|
| 500 |
|
---|
| 501 | link_id = IPC_GET_ARG1(*call);
|
---|
| 502 |
|
---|
| 503 | rc = inetcfg_link_add(link_id);
|
---|
[984a9ba] | 504 | async_answer_0(call, rc);
|
---|
[7af0cc5] | 505 | }
|
---|
| 506 |
|
---|
[984a9ba] | 507 | static void inetcfg_link_get_srv(ipc_call_t *call)
|
---|
[0e25780] | 508 | {
|
---|
[984a9ba] | 509 | ipc_call_t name;
|
---|
| 510 | ipc_call_t laddr;
|
---|
[b8b1adb1] | 511 | size_t name_max_size;
|
---|
| 512 | size_t laddr_max_size;
|
---|
[0e94b979] | 513 |
|
---|
[0e25780] | 514 | sysarg_t link_id;
|
---|
| 515 | inet_link_info_t linfo;
|
---|
[b7fd2a0] | 516 | errno_t rc;
|
---|
[0e25780] | 517 |
|
---|
| 518 | link_id = IPC_GET_ARG1(*call);
|
---|
[a1a101d] | 519 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_get_srv()");
|
---|
[0e25780] | 520 |
|
---|
[0e94b979] | 521 | linfo.name = NULL;
|
---|
| 522 |
|
---|
[984a9ba] | 523 | if (!async_data_read_receive(&name, &name_max_size)) {
|
---|
| 524 | async_answer_0(&name, EREFUSED);
|
---|
| 525 | async_answer_0(call, EREFUSED);
|
---|
[b8b1adb1] | 526 | return;
|
---|
| 527 | }
|
---|
| 528 |
|
---|
[984a9ba] | 529 | if (!async_data_read_receive(&laddr, &laddr_max_size)) {
|
---|
| 530 | async_answer_0(&laddr, EREFUSED);
|
---|
| 531 | async_answer_0(&name, EREFUSED);
|
---|
| 532 | async_answer_0(call, EREFUSED);
|
---|
[0e94b979] | 533 | return;
|
---|
| 534 | }
|
---|
| 535 |
|
---|
[0e25780] | 536 | rc = inetcfg_link_get(link_id, &linfo);
|
---|
[0e94b979] | 537 | if (rc != EOK) {
|
---|
[984a9ba] | 538 | async_answer_0(&laddr, rc);
|
---|
| 539 | async_answer_0(&name, rc);
|
---|
| 540 | async_answer_0(call, rc);
|
---|
[0e94b979] | 541 | return;
|
---|
| 542 | }
|
---|
| 543 |
|
---|
[984a9ba] | 544 | errno_t retval = async_data_read_finalize(&name, linfo.name,
|
---|
[b8b1adb1] | 545 | min(name_max_size, str_size(linfo.name)));
|
---|
| 546 | if (retval != EOK) {
|
---|
| 547 | free(linfo.name);
|
---|
[984a9ba] | 548 | async_answer_0(&laddr, retval);
|
---|
| 549 | async_answer_0(call, retval);
|
---|
[b8b1adb1] | 550 | return;
|
---|
| 551 | }
|
---|
| 552 |
|
---|
[984a9ba] | 553 | retval = async_data_read_finalize(&laddr, &linfo.mac_addr,
|
---|
[b8b1adb1] | 554 | min(laddr_max_size, sizeof(linfo.mac_addr)));
|
---|
| 555 |
|
---|
[0e94b979] | 556 | free(linfo.name);
|
---|
| 557 |
|
---|
[984a9ba] | 558 | async_answer_1(call, retval, linfo.def_mtu);
|
---|
[0e25780] | 559 | }
|
---|
| 560 |
|
---|
[984a9ba] | 561 | static void inetcfg_link_remove_srv(ipc_call_t *call)
|
---|
[7af0cc5] | 562 | {
|
---|
| 563 | sysarg_t link_id;
|
---|
[b7fd2a0] | 564 | errno_t rc;
|
---|
[7af0cc5] | 565 |
|
---|
| 566 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_link_remove_srv()");
|
---|
| 567 |
|
---|
| 568 | link_id = IPC_GET_ARG1(*call);
|
---|
| 569 |
|
---|
| 570 | rc = inetcfg_link_remove(link_id);
|
---|
[984a9ba] | 571 | async_answer_0(call, rc);
|
---|
[7af0cc5] | 572 | }
|
---|
| 573 |
|
---|
[984a9ba] | 574 | static void inetcfg_sroute_create_srv(ipc_call_t *icall)
|
---|
[8bf672d] | 575 | {
|
---|
[a1a101d] | 576 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_create_srv()");
|
---|
[02a09ed] | 577 |
|
---|
[984a9ba] | 578 | ipc_call_t call;
|
---|
[02a09ed] | 579 | size_t size;
|
---|
[984a9ba] | 580 | if (!async_data_write_receive(&call, &size)) {
|
---|
| 581 | async_answer_0(&call, EINVAL);
|
---|
| 582 | async_answer_0(icall, EINVAL);
|
---|
[02a09ed] | 583 | return;
|
---|
| 584 | }
|
---|
[a35b458] | 585 |
|
---|
[02a09ed] | 586 | if (size != sizeof(inet_naddr_t)) {
|
---|
[984a9ba] | 587 | async_answer_0(&call, EINVAL);
|
---|
| 588 | async_answer_0(icall, EINVAL);
|
---|
[02a09ed] | 589 | return;
|
---|
| 590 | }
|
---|
[a35b458] | 591 |
|
---|
[02a09ed] | 592 | inet_naddr_t dest;
|
---|
[984a9ba] | 593 | errno_t rc = async_data_write_finalize(&call, &dest, size);
|
---|
[8bf672d] | 594 | if (rc != EOK) {
|
---|
[984a9ba] | 595 | async_answer_0(&call, rc);
|
---|
| 596 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 597 | return;
|
---|
| 598 | }
|
---|
[a35b458] | 599 |
|
---|
[984a9ba] | 600 | if (!async_data_write_receive(&call, &size)) {
|
---|
| 601 | async_answer_0(&call, EINVAL);
|
---|
| 602 | async_answer_0(icall, EINVAL);
|
---|
[02a09ed] | 603 | return;
|
---|
| 604 | }
|
---|
[a35b458] | 605 |
|
---|
[02a09ed] | 606 | if (size != sizeof(inet_addr_t)) {
|
---|
[984a9ba] | 607 | async_answer_0(&call, EINVAL);
|
---|
| 608 | async_answer_0(icall, EINVAL);
|
---|
[8bf672d] | 609 | return;
|
---|
| 610 | }
|
---|
[a35b458] | 611 |
|
---|
[a2e3ee6] | 612 | inet_addr_t router;
|
---|
[984a9ba] | 613 | rc = async_data_write_finalize(&call, &router, size);
|
---|
[02a09ed] | 614 | if (rc != EOK) {
|
---|
[984a9ba] | 615 | async_answer_0(&call, rc);
|
---|
| 616 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 617 | return;
|
---|
| 618 | }
|
---|
[a35b458] | 619 |
|
---|
[02a09ed] | 620 | char *name;
|
---|
| 621 | rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
|
---|
| 622 | 0, NULL);
|
---|
| 623 | if (rc != EOK) {
|
---|
[984a9ba] | 624 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 625 | return;
|
---|
| 626 | }
|
---|
[a35b458] | 627 |
|
---|
[a2e3ee6] | 628 | sysarg_t sroute_id = 0;
|
---|
[8bf672d] | 629 | rc = inetcfg_sroute_create(name, &dest, &router, &sroute_id);
|
---|
| 630 | free(name);
|
---|
[984a9ba] | 631 | async_answer_1(icall, rc, sroute_id);
|
---|
[8bf672d] | 632 | }
|
---|
| 633 |
|
---|
[984a9ba] | 634 | static void inetcfg_sroute_delete_srv(ipc_call_t *call)
|
---|
[8bf672d] | 635 | {
|
---|
| 636 | sysarg_t sroute_id;
|
---|
[b7fd2a0] | 637 | errno_t rc;
|
---|
[8bf672d] | 638 |
|
---|
[a1a101d] | 639 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_delete_srv()");
|
---|
[8bf672d] | 640 |
|
---|
| 641 | sroute_id = IPC_GET_ARG1(*call);
|
---|
| 642 |
|
---|
| 643 | rc = inetcfg_sroute_delete(sroute_id);
|
---|
[984a9ba] | 644 | async_answer_0(call, rc);
|
---|
[8bf672d] | 645 | }
|
---|
| 646 |
|
---|
[984a9ba] | 647 | static void inetcfg_sroute_get_srv(ipc_call_t *icall)
|
---|
[0e25780] | 648 | {
|
---|
[a1a101d] | 649 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_srv()");
|
---|
[a35b458] | 650 |
|
---|
[02a09ed] | 651 | sysarg_t sroute_id = IPC_GET_ARG1(*icall);
|
---|
[a35b458] | 652 |
|
---|
[a2e3ee6] | 653 | inet_sroute_info_t srinfo;
|
---|
[a35b458] | 654 |
|
---|
[a2e3ee6] | 655 | inet_naddr_any(&srinfo.dest);
|
---|
| 656 | inet_addr_any(&srinfo.router);
|
---|
[8bf672d] | 657 | srinfo.name = NULL;
|
---|
[a35b458] | 658 |
|
---|
[b7fd2a0] | 659 | errno_t rc = inetcfg_sroute_get(sroute_id, &srinfo);
|
---|
[02a09ed] | 660 | if (rc != EOK) {
|
---|
[984a9ba] | 661 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 662 | return;
|
---|
| 663 | }
|
---|
[a35b458] | 664 |
|
---|
[984a9ba] | 665 | ipc_call_t call;
|
---|
[02a09ed] | 666 | size_t size;
|
---|
[984a9ba] | 667 | if (!async_data_read_receive(&call, &size)) {
|
---|
| 668 | async_answer_0(&call, EREFUSED);
|
---|
| 669 | async_answer_0(icall, EREFUSED);
|
---|
[0e25780] | 670 | return;
|
---|
| 671 | }
|
---|
[a35b458] | 672 |
|
---|
[02a09ed] | 673 | if (size != sizeof(inet_naddr_t)) {
|
---|
[984a9ba] | 674 | async_answer_0(&call, EINVAL);
|
---|
| 675 | async_answer_0(icall, EINVAL);
|
---|
[0e25780] | 676 | return;
|
---|
| 677 | }
|
---|
[a35b458] | 678 |
|
---|
[984a9ba] | 679 | rc = async_data_read_finalize(&call, &srinfo.dest, size);
|
---|
[a2e3ee6] | 680 | if (rc != EOK) {
|
---|
[984a9ba] | 681 | async_answer_0(&call, rc);
|
---|
| 682 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 683 | return;
|
---|
| 684 | }
|
---|
[a35b458] | 685 |
|
---|
[984a9ba] | 686 | if (!async_data_read_receive(&call, &size)) {
|
---|
| 687 | async_answer_0(&call, EREFUSED);
|
---|
| 688 | async_answer_0(icall, EREFUSED);
|
---|
[02a09ed] | 689 | return;
|
---|
| 690 | }
|
---|
[a35b458] | 691 |
|
---|
[02a09ed] | 692 | if (size != sizeof(inet_addr_t)) {
|
---|
[984a9ba] | 693 | async_answer_0(&call, EINVAL);
|
---|
| 694 | async_answer_0(icall, EINVAL);
|
---|
[a2e3ee6] | 695 | return;
|
---|
| 696 | }
|
---|
[a35b458] | 697 |
|
---|
[984a9ba] | 698 | rc = async_data_read_finalize(&call, &srinfo.router, size);
|
---|
[a2e3ee6] | 699 | if (rc != EOK) {
|
---|
[984a9ba] | 700 | async_answer_0(&call, rc);
|
---|
| 701 | async_answer_0(icall, rc);
|
---|
[02a09ed] | 702 | return;
|
---|
| 703 | }
|
---|
[a35b458] | 704 |
|
---|
[984a9ba] | 705 | if (!async_data_read_receive(&call, &size)) {
|
---|
| 706 | async_answer_0(&call, EREFUSED);
|
---|
| 707 | async_answer_0(icall, EREFUSED);
|
---|
[a2e3ee6] | 708 | return;
|
---|
| 709 | }
|
---|
[a35b458] | 710 |
|
---|
[984a9ba] | 711 | rc = async_data_read_finalize(&call, srinfo.name,
|
---|
[02a09ed] | 712 | min(size, str_size(srinfo.name)));
|
---|
[8bf672d] | 713 | free(srinfo.name);
|
---|
[a35b458] | 714 |
|
---|
[984a9ba] | 715 | async_answer_0(icall, rc);
|
---|
[8bf672d] | 716 | }
|
---|
[0e25780] | 717 |
|
---|
[984a9ba] | 718 | static void inetcfg_sroute_get_id_srv(ipc_call_t *call)
|
---|
[8bf672d] | 719 | {
|
---|
| 720 | char *name;
|
---|
| 721 | sysarg_t sroute_id;
|
---|
[b7fd2a0] | 722 | errno_t rc;
|
---|
[8bf672d] | 723 |
|
---|
[a1a101d] | 724 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inetcfg_sroute_get_id_srv()");
|
---|
[8bf672d] | 725 |
|
---|
| 726 | rc = async_data_write_accept((void **) &name, true, 0, LOC_NAME_MAXLEN,
|
---|
| 727 | 0, NULL);
|
---|
| 728 | if (rc != EOK) {
|
---|
[984a9ba] | 729 | async_answer_0(call, rc);
|
---|
[8bf672d] | 730 | return;
|
---|
| 731 | }
|
---|
| 732 |
|
---|
| 733 | sroute_id = 0;
|
---|
| 734 | rc = inetcfg_sroute_get_id(name, &sroute_id);
|
---|
| 735 | free(name);
|
---|
[984a9ba] | 736 | async_answer_1(call, rc, sroute_id);
|
---|
[0e25780] | 737 | }
|
---|
| 738 |
|
---|
[984a9ba] | 739 | void inet_cfg_conn(ipc_call_t *icall, void *arg)
|
---|
[0e25780] | 740 | {
|
---|
[a1a101d] | 741 | log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_cfg_conn()");
|
---|
[0e25780] | 742 |
|
---|
| 743 | /* Accept the connection */
|
---|
[59ff52d] | 744 | async_accept_0(icall);
|
---|
[0e25780] | 745 |
|
---|
| 746 | while (true) {
|
---|
| 747 | ipc_call_t call;
|
---|
[984a9ba] | 748 | async_get_call(&call);
|
---|
[0e25780] | 749 | sysarg_t method = IPC_GET_IMETHOD(call);
|
---|
| 750 |
|
---|
[bd88bee] | 751 | log_msg(LOG_DEFAULT, LVL_DEBUG, "method %d", (int)method);
|
---|
[0e25780] | 752 | if (!method) {
|
---|
| 753 | /* The other side has hung up */
|
---|
[984a9ba] | 754 | async_answer_0(&call, EOK);
|
---|
[0e25780] | 755 | return;
|
---|
| 756 | }
|
---|
| 757 |
|
---|
| 758 | switch (method) {
|
---|
| 759 | case INETCFG_ADDR_CREATE_STATIC:
|
---|
[984a9ba] | 760 | inetcfg_addr_create_static_srv(&call);
|
---|
[0e25780] | 761 | break;
|
---|
| 762 | case INETCFG_ADDR_DELETE:
|
---|
[984a9ba] | 763 | inetcfg_addr_delete_srv(&call);
|
---|
[0e25780] | 764 | break;
|
---|
| 765 | case INETCFG_ADDR_GET:
|
---|
[984a9ba] | 766 | inetcfg_addr_get_srv(&call);
|
---|
[0e25780] | 767 | break;
|
---|
[fa101c4] | 768 | case INETCFG_ADDR_GET_ID:
|
---|
[984a9ba] | 769 | inetcfg_addr_get_id_srv(&call);
|
---|
[fa101c4] | 770 | break;
|
---|
[0e25780] | 771 | case INETCFG_GET_ADDR_LIST:
|
---|
[984a9ba] | 772 | inetcfg_get_addr_list_srv(&call);
|
---|
[0e25780] | 773 | break;
|
---|
| 774 | case INETCFG_GET_LINK_LIST:
|
---|
[984a9ba] | 775 | inetcfg_get_link_list_srv(&call);
|
---|
[0e25780] | 776 | break;
|
---|
[8bf672d] | 777 | case INETCFG_GET_SROUTE_LIST:
|
---|
[984a9ba] | 778 | inetcfg_get_sroute_list_srv(&call);
|
---|
[8bf672d] | 779 | break;
|
---|
[7af0cc5] | 780 | case INETCFG_LINK_ADD:
|
---|
[984a9ba] | 781 | inetcfg_link_add_srv(&call);
|
---|
[7af0cc5] | 782 | break;
|
---|
[0e25780] | 783 | case INETCFG_LINK_GET:
|
---|
[984a9ba] | 784 | inetcfg_link_get_srv(&call);
|
---|
[0e25780] | 785 | break;
|
---|
[7af0cc5] | 786 | case INETCFG_LINK_REMOVE:
|
---|
[984a9ba] | 787 | inetcfg_link_remove_srv(&call);
|
---|
[7af0cc5] | 788 | break;
|
---|
[8bf672d] | 789 | case INETCFG_SROUTE_CREATE:
|
---|
[984a9ba] | 790 | inetcfg_sroute_create_srv(&call);
|
---|
[8bf672d] | 791 | break;
|
---|
| 792 | case INETCFG_SROUTE_DELETE:
|
---|
[984a9ba] | 793 | inetcfg_sroute_delete_srv(&call);
|
---|
[8bf672d] | 794 | break;
|
---|
| 795 | case INETCFG_SROUTE_GET:
|
---|
[984a9ba] | 796 | inetcfg_sroute_get_srv(&call);
|
---|
[8bf672d] | 797 | break;
|
---|
| 798 | case INETCFG_SROUTE_GET_ID:
|
---|
[984a9ba] | 799 | inetcfg_sroute_get_id_srv(&call);
|
---|
[8bf672d] | 800 | break;
|
---|
[0e25780] | 801 | default:
|
---|
[984a9ba] | 802 | async_answer_0(&call, EINVAL);
|
---|
[0e25780] | 803 | }
|
---|
| 804 | }
|
---|
| 805 | }
|
---|
| 806 |
|
---|
| 807 | /** @}
|
---|
| 808 | */
|
---|