source: rtems-libbsd/rtemsbsd/rtems/rtems-bsd-rc-conf-net.c @ 145a821

55-freebsd-126-freebsd-12
Last change on this file since 145a821 was 145a821, checked in by Chris Johns <chrisj@…>, on 04/26/17 at 07:38:50

rc_conf: Minor clean up in the net services.

  • Property mode set to 100644
File size: 18.4 KB
Line 
1/*
2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26/*
27 * Handle the networking directives found in rc.conf.
28 *  - ifconfig_*
29 *  - cloned_interfaces
30 *  - autobridge_interfaces
31 *  - autobridge_bridge*
32 *  - defaultrouter
33 */
34
35#include <rtems/bsd/sys/param.h>
36#include <sys/types.h>
37#include <sys/queue.h>
38#include <sys/kernel.h>
39#include <sysexits.h>
40
41#include <ifaddrs.h>
42#include <net/if.h>
43#include <net/route.h>
44#include <netinet/in.h>
45#include <sys/socket.h>
46
47#include <errno.h>
48#include <stddef.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <sys/stat.h>
52#include <unistd.h>
53
54#include <rtems.h>
55#include <rtems/chain.h>
56
57#include <machine/rtems-bsd-commands.h>
58#include <machine/rtems-bsd-rc-conf-services.h>
59
60#include <rtems/rtems-routes.h>
61
62/*
63 * Default defaultroute_delay is 30seconds.
64 */
65static int defaultroute_delay_secs = 30;
66
67/*
68 * Show a result.
69 */
70static void
71show_result(const char* label, int r)
72{
73  if (r < 0)
74    fprintf(stderr, "error: %s: %s\n", label, strerror(errno));
75}
76
77/*
78 * cloned_interfaces
79 *
80 * eg cloned_interfaces="vlan0 bridge0 tap1 tap2"
81 *
82 * See 'man rc.conf(5)' on FreeBSD.
83 */
84static int
85cloned_interfaces(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
86{
87  int arg;
88  int r = 0;
89
90  r = rtems_bsd_rc_conf_find(rc_conf, "cloned_interfaces", aa);
91  if (r < 0) {
92    if (errno == ENOENT)
93      r = 0;
94    return r;
95  }
96
97  for (arg = 1; arg < aa->argc; ++arg) {
98    const char* ifconfg_args[] = {
99      "ifconfig", aa->argv[arg], "create", NULL
100    };
101    rtems_bsd_rc_conf_print_cmd(rc_conf, "cloning_interfaces", 3, ifconfg_args);
102    rtems_bsd_command_ifconfig(3, (char**) ifconfg_args);
103  }
104
105  return 0;
106}
107
108/*
109 * create_args_'interface'
110 *
111 * eg create_args_myvlan="vlan 102"
112 *
113 * See 'man rc.conf(5)' on FreeBSD.
114 */
115typedef struct {
116  rtems_chain_node node;
117  const char*      label;
118  int              argc;
119  const char**     argv;
120} create_args_item;
121
122static RTEMS_CHAIN_DEFINE_EMPTY(create_args_items);
123
124static int
125load_create_args(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
126{
127  int r = 0;
128
129  r = rtems_bsd_rc_conf_find(rc_conf, "create_args_.*", aa);
130
131  while (r == 0) {
132    rtems_chain_node* node;
133    const char*       label;
134    create_args_item* item;
135    int               arg;
136
137    rtems_bsd_rc_conf_print_cmd(rc_conf, "create_args_", aa->argc, aa->argv);
138
139    label = aa->argv[0] + strlen("create_args_");
140
141    node = rtems_chain_first(&create_args_items);
142
143    while (!rtems_chain_is_tail(&create_args_items, node)) {
144      item = (create_args_item*) node;
145      if (strcasecmp(item->label, label) == 0) {
146        fprintf(stderr, "error: %s:%d: duplicate create args entry: %s\n",
147                rtems_bsd_rc_conf_name(rc_conf),
148                rtems_bsd_rc_conf_line(rc_conf),
149                aa->argv[0]);
150        errno = EEXIST;
151        return -1;
152      }
153      node = rtems_chain_next(node);
154    }
155
156    item = calloc(1, sizeof(*item));
157    if (item == NULL) {
158      errno = ENOMEM;
159      fprintf(stderr, "error: %s:%d: %s\n",
160              rtems_bsd_rc_conf_name(rc_conf),
161              rtems_bsd_rc_conf_line(rc_conf),
162              strerror(errno));
163      return -1;
164    }
165
166    item->argc = aa->argc;
167
168    item->label = strdup(label);
169    if (item->label == NULL) {
170      free(item);
171      errno = ENOMEM;
172      fprintf(stderr, "error: %s:%d: %s\n",
173              rtems_bsd_rc_conf_name(rc_conf),
174              rtems_bsd_rc_conf_line(rc_conf),
175              strerror(errno));
176      return -1;
177    }
178
179    item->argv = calloc(aa->argc + 1, sizeof(char*));
180    if (item->argv == NULL) {
181      free((void*) item->label);
182      free(item);
183      errno = ENOMEM;
184      fprintf(stderr, "error: %s:%d: %s\n",
185              rtems_bsd_rc_conf_name(rc_conf),
186              rtems_bsd_rc_conf_line(rc_conf),
187              strerror(errno));
188      return -1;
189    }
190
191    for (arg = 0; arg < aa->argc; ++arg) {
192      item->argv[arg] = strdup(aa->argv[0]);
193      if (item->argv[arg] == NULL) {
194        int a;
195        for (a = 0; a < arg; ++a)
196          free((void*) item->argv[a]);
197        free(item->argv);
198        free((void*) item->label);
199        free(item);
200        errno = ENOMEM;
201        fprintf(stderr, "error: %s:%d: %s\n",
202                rtems_bsd_rc_conf_name(rc_conf),
203                rtems_bsd_rc_conf_line(rc_conf),
204                strerror(errno));
205        return -1;
206      }
207    }
208
209    rtems_chain_append(&create_args_items, &item->node);
210
211    r = rtems_bsd_rc_conf_find_next(rc_conf, aa);
212  }
213
214  /*
215   * ignore not found.
216   */
217  if (r < 0 && errno == ENOENT)
218    r = 0;
219
220  return 0;
221}
222
223/*
224 * ifconfig_'interface'
225 *
226 * eg ifconfig_em0="inet 10.10.5.33 netmask 255.255.255.0"
227 *
228 * See 'man rc.conf(5)' on FreeBSD.
229 */
230static int
231ifconfig_(rtems_bsd_rc_conf* rc_conf,
232          const char*        ifname,
233          int                argc,
234          const char**       argv)
235{
236  const char**      args;
237  int               arg;
238  int               ifconfig_argc = 0;
239  bool              add_up = true;
240  int               r;
241  const char const* ifconfig_show[] = { "ifconfig", ifname, NULL };
242
243  for (arg = 1; arg < argc; ++arg) {
244    if (strcasecmp(argv[arg], "NOAUTO") == 0)
245      return 0;
246  }
247
248  args = calloc(argc + 3, sizeof(char*));
249  if (args == NULL) {
250    errno = ENOMEM;
251    return -1;
252  }
253
254  args[ifconfig_argc++] = "ifconfig";
255  args[ifconfig_argc++] = ifname;
256
257  for (arg = 1; arg < argc; ++arg) {
258    if (strcasecmp("DHCP",     argv[arg]) == 0 ||
259        strcasecmp("SYNCDHCP", argv[arg]) == 0) {
260      add_up = false;
261    }
262    else {
263      args[ifconfig_argc++] = argv[arg];
264    }
265  }
266
267  if (add_up)
268    args[ifconfig_argc++] = "up";
269
270  rtems_bsd_rc_conf_print_cmd(rc_conf, "ifconfig", ifconfig_argc, args);
271
272  r = rtems_bsd_command_ifconfig(ifconfig_argc, (char**) args);
273
274  free(args);
275
276  if (r != EX_OK) {
277    errno = ECANCELED;
278    return -1;
279  }
280
281  r = rtems_bsd_command_ifconfig(2, (char**) ifconfig_show);
282
283  return r;
284}
285
286/*
287 * hostname
288 *
289 * eg hostname="myhost"
290 *
291 * See 'man rc.conf(5)' on FreeBSD.
292 */
293static int
294hostname(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
295{
296  const char**      argv;
297  int               r;
298  const char const* default_argv[] = { "hostname", "Amnesiac", NULL };
299
300  r = rtems_bsd_rc_conf_find(rc_conf, "hostname", aa);
301  if (r < 0 && errno != ENOENT)
302    return -1;
303
304  if (r < 0 || (r == 0 && aa->argc != 2)) {
305    argv = default_argv;
306  }
307  else {
308    argv = aa->argv;
309  }
310
311  fprintf(stdout, "Setting hostname: %s.\n", argv[1]);
312
313  return sethostname(argv[1], strlen(argv[1]));
314}
315
316/*
317 * defaultrouter
318 *
319 * eg defaultrouter="1.2.3.4"
320 *
321 * See 'man rc.conf(5)' on FreeBSD.
322 */
323static int
324defaultrouter(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
325{
326  int r;
327
328  r = rtems_bsd_rc_conf_find(rc_conf, "defaultrouter", aa);
329  if (r < 0 && errno != ENOENT)
330    return -1;
331
332  if (r == 0) {
333    if (aa->argc > 2) {
334      errno = EINVAL;
335      return -1;
336    }
337
338    if (strcasecmp(aa->argv[1], "NO") != 0) {
339      const char* args[] = { "route", "add", "default", aa->argv[1], NULL };
340      int         r;
341
342      rtems_bsd_rc_conf_print_cmd(rc_conf, "defaultrouter", 4, args);
343
344      r = rtems_bsd_command_route(4, (char**) args);
345      if (r != EX_OK) {
346        errno = ECANCELED;
347        return -1;
348      }
349    }
350  }
351
352  return 0;
353}
354
355static int
356show_interfaces(const char* msg, struct ifaddrs* ifap)
357{
358  struct ifaddrs* ifa;
359
360  fprintf(stdout, msg);
361
362  /*
363   * Always have lo0 first.
364   */
365
366  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
367    if (strcasecmp("lo0", ifa->ifa_name) == 0) {
368      fprintf(stdout, "%s ", ifa->ifa_name);
369      break;
370    }
371  }
372
373  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
374    if (strcasecmp("lo0", ifa->ifa_name) != 0) {
375      fprintf(stdout, "%s ", ifa->ifa_name);
376    }
377  }
378
379  fprintf(stdout, "\b.\n");
380
381  return 0;
382}
383
384static int
385dhcp_check(rtems_bsd_rc_conf_argc_argv* aa)
386{
387  int arg;
388  for (arg = 0; arg < aa->argc; ++arg) {
389    if (strcasestr(aa->argv[1], "DHCP") != NULL ||
390        strcasestr(aa->argv[1], "SYNCDHCP") != NULL)
391      return true;
392  }
393  return false;
394}
395
396static int
397setup_lo0(rtems_bsd_rc_conf* rc_conf, struct ifaddrs* ifap)
398{
399  struct ifaddrs* ifa;
400
401  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
402    if (strcasecmp("lo0", ifa->ifa_name) == 0) {
403      const char* lo0_argv[] = {
404        "ifconfig_lo0", "inet", "127.0.0.1", "netmask", "255.0.0.0", NULL
405      };
406      show_result("lo0", ifconfig_(rc_conf, "lo0", 5, lo0_argv));
407      return 0;
408    }
409  }
410
411  fprintf(stderr, "warning: no loopback interface found\n");
412
413  return -1;
414}
415
416static int
417setup_interfaces(rtems_bsd_rc_conf*           rc_conf,
418                 rtems_bsd_rc_conf_argc_argv* aa,
419                 struct ifaddrs*              ifap,
420                 bool*                        dhcp)
421{
422  struct ifaddrs* ifa;
423  int             r;
424
425  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
426    if (strcasecmp("lo0", ifa->ifa_name) != 0) {
427      char iface[64];
428      snprintf(iface, sizeof(iface), "ifconfig_%s", ifa->ifa_name);
429      r = rtems_bsd_rc_conf_find(rc_conf, iface, aa);
430      if (r == 0) {
431        if (dhcp_check(aa)) {
432          *dhcp = true;
433        }
434        /*
435         * A DHCP ifconfig can have other options we need to set on the
436         * interface.
437         */
438        show_result(iface, ifconfig_(rc_conf, ifa->ifa_name, aa->argc, aa->argv));
439      }
440    }
441  }
442
443  return 0;
444}
445
446static int
447setup_vlans(rtems_bsd_rc_conf*           rc_conf,
448            rtems_bsd_rc_conf_argc_argv* aa,
449            struct ifaddrs*              ifap,
450            bool*                        dhcp)
451{
452  rtems_bsd_rc_conf_argc_argv* vaa;
453  struct ifaddrs*              ifa;
454
455  vaa = rtems_bsd_rc_conf_argc_argv_create();
456  if (vaa == NULL)
457    return -1;
458
459  show_result("create_args", load_create_args(rc_conf, aa));
460
461  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
462    if (strcasecmp("lo0", ifa->ifa_name) != 0) {
463      char expr[128];
464      int  r;
465      /*
466       * Look for vlans_'iface'="101 102 103"
467       */
468      snprintf(expr, sizeof(expr), "vlans_%s", ifa->ifa_name);
469      r = rtems_bsd_rc_conf_find(rc_conf, expr, aa);
470      if (r == 0) {
471        int arg;
472        for (arg = 1; arg < aa->argc; ++arg) {
473          char vlan_name[64];
474          const char* vlan_create[] = {
475            "ifconfig", vlan_name, "create", NULL
476          };
477          /*
478           * Create the VLAN name as 'iface'.'vlan'.
479           */
480          snprintf(vlan_name, sizeof(vlan_name),
481                   "%s.%s", ifa->ifa_name, aa->argv[arg]);
482          rtems_bsd_rc_conf_print_cmd(rc_conf, "vlan", 3, vlan_create);
483          r = rtems_bsd_command_ifconfig(3, (char**) vlan_create);
484          if (r == 0) {
485            /*
486             * Look for ifconfig_'iface'_'vlan'="..."
487             */
488            snprintf(expr, sizeof(expr),
489                     "ifconfig_%s_%s", ifa->ifa_name, aa->argv[arg]);
490            r = rtems_bsd_rc_conf_find(rc_conf, expr, vaa);
491            if (r == 0) {
492              if (dhcp_check(vaa)) {
493                *dhcp = true;
494              }
495              else {
496                show_result(vlan_name, ifconfig_(rc_conf, vlan_name,
497                                                 vaa->argc, vaa->argv));
498              }
499            }
500          }
501        }
502      }
503    }
504  }
505
506  rtems_bsd_rc_conf_argc_argv_destroy(vaa);
507
508  return 0;
509}
510
511/*
512 * The rc_conf struct cannot be passed to a thread as a pointer. It can only be
513 * used in the rc.conf worker thread. As a result the values needed to print a
514 * verbose message to aid debugging need to have local copies made and passed
515 * to the dhcpcd worker. The dhcpcd worker should run for ever. Clean up the
516 * memory if it exits.
517 */
518typedef struct dhcpcd_data {
519  rtems_bsd_rc_conf_argc_argv* argc_argv;
520  bool                         verbose;
521  const char*                  name;
522} dhcpcd_data;
523
524static void
525dhcpcd_worker(rtems_task_argument arg)
526{
527  dhcpcd_data*  dd = (dhcpcd_data*) arg;
528  int           argc;
529  const char**  argv;
530  const char*   dhcpcd_argv[] = { "dhcpcd", NULL };
531  struct stat   sb;
532  int           r;
533
534  r = stat("/var", &sb);
535  if (r < 0) {
536    mkdir("/var", S_IRWXU | S_IRWXG | S_IRWXO);
537  }
538
539  r = stat("/var/db", &sb);
540  if (r < 0) {
541    mkdir("/var/db", S_IRWXU | S_IRWXG | S_IRWXO);
542  }
543
544  if (dd->argc_argv->argc > 0) {
545    argc = dd->argc_argv->argc;
546    argv = dd->argc_argv->argv;
547  }
548  else {
549    argc = 1;
550    argv = dhcpcd_argv;
551  }
552
553  if (dd->verbose) {
554    fprintf(stdout, "rc.conf: %s: dhcpcd ", dd->name);
555    for (r = 1; r < argc; ++r)
556      fprintf(stdout, "%s ", argv[r]);
557    fprintf(stdout, "\n");
558  }
559
560  r = rtems_bsd_command_dhcpcd(argc, argv);
561  if (r != EX_OK)
562    fprintf(stderr, "error: dhcpcd: stopped\n");
563
564  free(dd->name);
565  rtems_bsd_rc_conf_argc_argv_destroy(dd->argc_argv);
566  free(dd);
567
568  rtems_task_delete(RTEMS_SELF);
569}
570
571static int
572run_dhcp(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
573{
574  dhcpcd_data*        dd;
575  rtems_status_code   sc;
576  rtems_id            id;
577  rtems_task_priority priority = RTEMS_MAXIMUM_PRIORITY - 1;
578  char*               end = NULL;
579  int                 delay = 30;
580  int                 r;
581
582  /*
583   * These are passed to the worker and cleaned up there if it ever exits. Do
584   * not destroy here unless an error before the thread runs.
585   */
586  dd = calloc(1, sizeof(*dd));
587  if (dd == NULL) {
588    fprintf(stderr, "error: dhcpcd data: no memory\n");
589    errno = ENOMEM;
590    return -1;
591  }
592
593  dd->name = strdup(rtems_bsd_rc_conf_name(rc_conf));
594  if (dd == NULL) {
595    free(dd);
596    fprintf(stderr, "error: dhcpcd data: no memory\n");
597    errno = ENOMEM;
598    return -1;
599  }
600
601  dd->argc_argv = rtems_bsd_rc_conf_argc_argv_create();
602  if (dd->argc_argv == NULL) {
603    free(dd->name);
604    free(dd);
605    errno = ENOMEM;
606    return -1;
607  }
608
609  dd->verbose = rtems_bsd_rc_conf_verbose(rc_conf);
610
611  r = rtems_bsd_rc_conf_find(rc_conf, "dhcpcd_priority", dd->argc_argv);
612  if (r == 0) {
613    if (dd->argc_argv->argc == 2) {
614      priority = strtoul(dd->argc_argv->argv[1], &end, 10);
615      if (priority == 0 || *end != '\0')
616        priority = RTEMS_MAXIMUM_PRIORITY - 1;
617    }
618  }
619
620  rtems_bsd_rc_conf_find(rc_conf, "dhcpcd_options", dd->argc_argv);
621
622  sc = rtems_task_create(rtems_build_name('D', 'H', 'C', 'P'),
623                         priority,
624                         2 * RTEMS_MINIMUM_STACK_SIZE,
625                         RTEMS_DEFAULT_MODES,
626                         RTEMS_FLOATING_POINT,
627                         &id);
628  if (sc == RTEMS_SUCCESSFUL)
629    sc = rtems_task_start(id, dhcpcd_worker, (rtems_task_argument) dd);
630  if (sc != RTEMS_SUCCESSFUL) {
631    fprintf(stderr,
632            "error: dhcpcd: thread create/start: %s\n", rtems_status_text(sc));
633    rtems_bsd_rc_conf_argc_argv_destroy(dd->argc_argv);
634    free(dd->name);
635    free(dd);
636    errno = EIO;
637    return -1;
638  }
639
640  /*
641   * See if a delay is specified else use default to 30 seconds. Wait for a
642   * valid default route.
643   */
644  r = rtems_bsd_rc_conf_find(rc_conf, "defaultroute_delay", aa);
645  if (r == 0 && aa->argc == 2) {
646    delay = (int) strtol(aa->argv[1], &end, 10);
647    if (*end != '\0') {
648      fprintf(stderr, "error: defaultroute_delay: invalid delay value\n");
649      delay = 30;
650    }
651  }
652
653  printf("Waiting %ds for default route interface: ", delay);
654  fflush(stdout);
655
656  while (delay > 0) {
657    struct sockaddr_in sin;
658    struct sockaddr*   rti_info[RTAX_MAX];
659
660    --delay;
661
662    memset(&sin, 0, sizeof(sin));
663    memset(&rti_info[0], 0, sizeof(rti_info));
664    sin.sin_family = AF_INET;
665    inet_pton(AF_INET, "0.0.0.0", &sin.sin_addr);
666
667    r = rtems_get_route(&sin, rti_info);
668    if (r == 0 && rti_info[RTAX_GATEWAY] != NULL) {
669      break;
670    }
671    else if (r < 0 && errno != ESRCH) {
672      fprintf(stderr,
673              "error: get routes %d: %d %s\n", r, errno, strerror(errno));
674    }
675
676    sleep(1);
677  }
678
679  /*
680   * We should print the interface but I cannot see how to get the interface
681   * with the default route without a lot of code.
682   */
683  if (delay > 0)
684    printf("found.\n");
685  else
686    printf("\nerror: no default route found\n");
687
688  return 0;
689}
690
691static int
692interfaces(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
693{
694  struct ifaddrs* ifap;
695  bool            dhcp = false;
696
697  if (getifaddrs(&ifap) != 0) {
698    fprintf(stderr, "error: interfaces: getifaddrs: %s\n", strerror(errno));
699    return -1;
700  }
701
702  show_interfaces("Starting network: ", ifap);
703  show_result("cloned_interfaces", cloned_interfaces(rc_conf, aa));
704  show_result("lo0", setup_lo0(rc_conf, ifap));
705  show_result("ifaces", setup_interfaces(rc_conf, aa, ifap, &dhcp));
706  show_result("vlans", setup_vlans(rc_conf, aa, ifap, &dhcp));
707  show_result("defaultrouter", defaultrouter(rc_conf, aa));
708  if (dhcp)
709    show_result("dhcp", run_dhcp(rc_conf, aa));
710
711  free(ifap);
712
713  return 0;
714}
715
716static int
717network_service(rtems_bsd_rc_conf* rc_conf)
718{
719  rtems_bsd_rc_conf_argc_argv* aa;
720  int                          r;
721
722  aa = rtems_bsd_rc_conf_argc_argv_create();
723  if (aa == NULL)
724    return -1;
725
726  show_result("hostname", hostname(rc_conf, aa));
727
728  r = interfaces(rc_conf, aa);
729  if (r < 0) {
730    rtems_bsd_rc_conf_argc_argv_destroy(aa);
731    return -1;
732  }
733
734  rtems_bsd_rc_conf_argc_argv_destroy(aa);
735
736  return 0;
737}
738
739void
740rc_conf_net_init(void* arg)
741{
742  int r;
743  r = rtems_bsd_rc_conf_service_add("network",
744                                    "after:first;",
745                                    network_service);
746  if (r < 0)
747    fprintf(stderr,
748            "error: network service add failed: %s\n", strerror(errno));
749}
Note: See TracBrowser for help on using the repository browser.