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

55-freebsd-126-freebsd-12
Last change on this file since 8bd38d6 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
RevLine 
[f5c6651]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
[9c570da]35#define _GNU_SOURCE
36
[0237319]37#include <sys/param.h>
[3d1e767]38#include <sys/types.h>
[f5c6651]39#include <sys/queue.h>
40#include <sys/kernel.h>
41#include <sysexits.h>
42
[55c564a]43#include <ifaddrs.h>
[9c570da]44#include <arpa/inet.h>
[573b1982]45#include <net/if.h>
46#include <net/route.h>
47#include <netinet/in.h>
48#include <sys/socket.h>
[55c564a]49
[f5c6651]50#include <errno.h>
51#include <stddef.h>
52#include <stdio.h>
53#include <stdlib.h>
[9c570da]54#include <string.h>
[f5c6651]55#include <unistd.h>
56
57#include <rtems.h>
58#include <rtems/chain.h>
59
60#include <machine/rtems-bsd-commands.h>
[55c564a]61#include <machine/rtems-bsd-rc-conf-services.h>
62
[573b1982]63#include <rtems/rtems-routes.h>
[8bd38d6]64#include <rtems/dhcpcd.h>
[573b1982]65
[55c564a]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}
[f5c6651]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
[55c564a]89cloned_interfaces(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
[f5c6651]90{
91  int arg;
[55c564a]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) {
[f5c6651]102    const char* ifconfg_args[] = {
[55c564a]103      "ifconfig", aa->argv[arg], "create", NULL
[f5c6651]104    };
105    rtems_bsd_rc_conf_print_cmd(rc_conf, "cloning_interfaces", 3, ifconfg_args);
[55c564a]106    rtems_bsd_command_ifconfig(3, (char**) ifconfg_args);
[f5c6651]107  }
[55c564a]108
[f5c6651]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
[55c564a]129load_create_args(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
[f5c6651]130{
[55c564a]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",
[f5c6651]164              rtems_bsd_rc_conf_name(rc_conf),
165              rtems_bsd_rc_conf_line(rc_conf),
[55c564a]166              strerror(errno));
[f5c6651]167      return -1;
168    }
169
[55c564a]170    item->argc = aa->argc;
[f5c6651]171
[55c564a]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    }
[f5c6651]182
[55c564a]183    item->argv = calloc(aa->argc + 1, sizeof(char*));
184    if (item->argv == NULL) {
[f5c6651]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    }
[55c564a]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);
[f5c6651]216  }
217
[55c564a]218  /*
219   * ignore not found.
220   */
221  if (r < 0 && errno == ENOENT)
222    r = 0;
[f5c6651]223
224  return 0;
225}
226
[4437573]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
[f5c6651]238/*
239 * ifconfig_'interface'
240 *
241 * eg ifconfig_em0="inet 10.10.5.33 netmask 255.255.255.0"
[4437573]242 *    ifconfig_em0_alias0="ether 10:22:33:44:55:66"
243 *    ifconfig_em0_alias1="inet 10.1.1.111 netmask 0xffffffff"
[f5c6651]244 *
245 * See 'man rc.conf(5)' on FreeBSD.
246 */
247static int
248ifconfig_(rtems_bsd_rc_conf* rc_conf,
[55c564a]249          const char*        ifname,
[f5c6651]250          int                argc,
[4437573]251          const char**       argv,
252          int                opt_argc,
253          const char**       opt_argv,
254          bool               add_up)
[f5c6651]255{
[55c564a]256  const char**      args;
257  int               arg;
[ab7739a]258  int               ifconfig_argc = 0;
[55c564a]259  int               r;
[f5c6651]260
261  for (arg = 1; arg < argc; ++arg) {
262    if (strcasecmp(argv[arg], "NOAUTO") == 0)
263      return 0;
264  }
265
[4437573]266  args = calloc(argc + opt_argc + 3, sizeof(char*));
[f5c6651]267  if (args == NULL) {
268    errno = ENOMEM;
269    return -1;
270  }
271
[ab7739a]272  args[ifconfig_argc++] = "ifconfig";
273  args[ifconfig_argc++] = ifname;
[f5c6651]274
[ab7739a]275  for (arg = 1; arg < argc; ++arg) {
276    if (strcasecmp("DHCP",     argv[arg]) == 0 ||
[4437573]277        strcasecmp("SYNCDHCP", argv[arg]) == 0 ||
278        strcasecmp("UP",       argv[arg]) == 0) {
[ab7739a]279      add_up = false;
280    }
281    else {
282      args[ifconfig_argc++] = argv[arg];
283    }
284  }
[f5c6651]285
[4437573]286  if (opt_argv != NULL) {
287    for (arg = 0; arg < opt_argc; ++arg) {
288      args[ifconfig_argc++] = opt_argv[arg];
289    }
290  }
291
[ab7739a]292  if (add_up)
293    args[ifconfig_argc++] = "up";
[f5c6651]294
[ab7739a]295  rtems_bsd_rc_conf_print_cmd(rc_conf, "ifconfig", ifconfig_argc, args);
[f5c6651]296
[ab7739a]297  r = rtems_bsd_command_ifconfig(ifconfig_argc, (char**) args);
[f5c6651]298
299  free(args);
300
301  if (r != EX_OK) {
302    errno = ECANCELED;
303    return -1;
304  }
305
[55c564a]306  return r;
[f5c6651]307}
308
309/*
310 * hostname
311 *
312 * eg hostname="myhost"
313 *
314 * See 'man rc.conf(5)' on FreeBSD.
315 */
316static int
[55c564a]317hostname(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
[f5c6651]318{
[55c564a]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)
[f5c6651]325    return -1;
[55c564a]326
327  if (r < 0 || (r == 0 && aa->argc != 2)) {
328    argv = default_argv;
329  }
330  else {
331    argv = aa->argv;
[f5c6651]332  }
333
[55c564a]334  fprintf(stdout, "Setting hostname: %s.\n", argv[1]);
[f5c6651]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
[53914f2]347defaultrouter(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa, bool dhcp)
[f5c6651]348{
[55c564a]349  int r;
350
[53914f2]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
[55c564a]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
[4437573]433list_interfaces(const char* msg, struct ifaddrs* ifap)
[55c564a]434{
435  struct ifaddrs* ifa;
436
437  fprintf(stdout, msg);
438
[573b1982]439  /*
440   * Always have lo0 first.
441   */
442
[55c564a]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;
[f5c6651]447    }
448  }
449
[55c564a]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
[f5c6651]458  return 0;
459}
460
[4437573]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
[573b1982]473static int
474dhcp_check(rtems_bsd_rc_conf_argc_argv* aa)
475{
[ab7739a]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  }
[573b1982]482  return false;
483}
484
[55c564a]485static int
486setup_lo0(rtems_bsd_rc_conf* rc_conf, struct ifaddrs* ifap)
[f5c6651]487{
[55c564a]488  struct ifaddrs* ifa;
[573b1982]489
[55c564a]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      };
[4437573]495      show_result("lo0",
496                  ifconfig_(rc_conf, "lo0",
497                            5, lo0_argv,
498                            0, NULL,
499                            true));
[55c564a]500      return 0;
501    }
502  }
[573b1982]503
[55c564a]504  fprintf(stderr, "warning: no loopback interface found\n");
[573b1982]505
[55c564a]506  return -1;
507}
508
509static int
510setup_interfaces(rtems_bsd_rc_conf*           rc_conf,
511                 rtems_bsd_rc_conf_argc_argv* aa,
[573b1982]512                 struct ifaddrs*              ifap,
513                 bool*                        dhcp)
[55c564a]514{
515  struct ifaddrs* ifa;
[573b1982]516  int             r;
517
[55c564a]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) {
[573b1982]524        if (dhcp_check(aa)) {
525          *dhcp = true;
526        }
[ab7739a]527        /*
528         * A DHCP ifconfig can have other options we need to set on the
529         * interface.
530         */
[4437573]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        }
[55c564a]548      }
549    }
550  }
[573b1982]551
[55c564a]552  return 0;
553}
554
555static int
556setup_vlans(rtems_bsd_rc_conf*           rc_conf,
557            rtems_bsd_rc_conf_argc_argv* aa,
[573b1982]558            struct ifaddrs*              ifap,
559            bool*                        dhcp)
[55c564a]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) {
[573b1982]601              if (dhcp_check(vaa)) {
602                *dhcp = true;
603              }
604              else {
[4437573]605                show_result(vlan_name,
606                            ifconfig_(rc_conf, vlan_name,
607                                      vaa->argc, vaa->argv,
608                                      0, NULL,
609                                      true));
[573b1982]610              }
[55c564a]611            }
612          }
613        }
614      }
615    }
616  }
617
618  rtems_bsd_rc_conf_argc_argv_destroy(vaa);
619
620  return 0;
621}
622
[573b1982]623/*
624 * The rc_conf struct cannot be passed to a thread as a pointer. It can only be
[dc5b267]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.
[573b1982]629 */
630typedef struct dhcpcd_data {
[8bd38d6]631  rtems_dhcpcd_config          config;
[573b1982]632  rtems_bsd_rc_conf_argc_argv* argc_argv;
633  bool                         verbose;
634  const char*                  name;
635} dhcpcd_data;
636
637static void
[8bd38d6]638dhcpcd_prepare(const rtems_dhcpcd_config *config, int argc, char **argv)
[573b1982]639{
[8bd38d6]640  const dhcpcd_data* dd = (const dhcpcd_data*) config;
[573b1982]641
642  if (dd->verbose) {
[8bd38d6]643    int r;
644
[573b1982]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  }
[8bd38d6]650}
[573b1982]651
[8bd38d6]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)
[573b1982]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;
[8bd38d6]670  rtems_task_priority priority = 0;
[573b1982]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);
[8bd38d6]707      if (*end != '\0')
708        priority = 0;
[573b1982]709    }
710  }
[8bd38d6]711  dd->config.priority = priority;
[573b1982]712
713  rtems_bsd_rc_conf_find(rc_conf, "dhcpcd_options", dd->argc_argv);
714
[8bd38d6]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);
[573b1982]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  /*
[53914f2]735   * Let it run before moving on.
[573b1982]736   */
[53914f2]737  sleep(1);
[573b1982]738
739  return 0;
740}
741
[55c564a]742static int
743interfaces(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
744{
745  struct ifaddrs* ifap;
[573b1982]746  bool            dhcp = false;
[55c564a]747
748  if (getifaddrs(&ifap) != 0) {
749    fprintf(stderr, "error: interfaces: getifaddrs: %s\n", strerror(errno));
750    return -1;
751  }
752
[4437573]753  list_interfaces("Starting network: ", ifap);
[55c564a]754  show_result("cloned_interfaces", cloned_interfaces(rc_conf, aa));
755  show_result("lo0", setup_lo0(rc_conf, ifap));
[573b1982]756  show_result("ifaces", setup_interfaces(rc_conf, aa, ifap, &dhcp));
757  show_result("vlans", setup_vlans(rc_conf, aa, ifap, &dhcp));
[4437573]758  show_interfaces(ifap);
[53914f2]759
[573b1982]760  if (dhcp)
761    show_result("dhcp", run_dhcp(rc_conf, aa));
[53914f2]762  show_result("defaultrouter", defaultrouter(rc_conf, aa, dhcp));
[55c564a]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
[145a821]779  show_result("hostname", hostname(rc_conf, aa));
[55c564a]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;
[f5c6651]790}
791
792void
793rc_conf_net_init(void* arg)
794{
[55c564a]795  int r;
796  r = rtems_bsd_rc_conf_service_add("network",
797                                    "after:first;",
798                                    network_service);
799  if (r < 0)
[573b1982]800    fprintf(stderr,
801            "error: network service add failed: %s\n", strerror(errno));
[f5c6651]802}
Note: See TracBrowser for help on using the repository browser.