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

55-freebsd-126-freebsd-12
Last change on this file since c7eec93 was 8bd38d6, checked in by Sebastian Huber <sebastian.huber@…>, on 05/02/18 at 06:58:48

dhcpcd: Add rtems_dhcpcd_start()

Use it throughout to start the DHCP client (dhcpcd).

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