diff options
| author | Roy Marples <roy@marples.name> | 2008-09-04 11:30:11 +0000 |
|---|---|---|
| committer | Roy Marples <roy@marples.name> | 2008-09-04 11:30:11 +0000 |
| commit | 96d0673a2cd58d50f0e4c8e0c60b332a7fff92a8 (patch) | |
| tree | 1ca3996de4d29132abaca0a485c47b3e6509a47c /dhcpcd.c | |
| parent | 4570862e65882adb2b2b60e45b6ba7e6dec21229 (diff) | |
| download | dhcpcd-96d0673a2cd58d50f0e4c8e0c60b332a7fff92a8.tar.xz | |
When OS reports new and removed interfaces, dhcpcd sees this and either starts or stops watching them. BSD only, Linux to follow.
Diffstat (limited to 'dhcpcd.c')
| -rw-r--r-- | dhcpcd.c | 109 |
1 files changed, 67 insertions, 42 deletions
@@ -66,6 +66,8 @@ const char copyright[] = "Copyright (c) 2006-2008 Roy Marples"; int master = 0; int pidfd = -1; +static char **ifv = NULL; +static int ifc = 0; static int linkfd = -1; static char cffile[PATH_MAX]; static char pidfile[PATH_MAX] = { '\0' }; @@ -195,6 +197,7 @@ stop_interface(struct interface *iface) { struct interface *ifp, *ifl = NULL; + logger(LOG_ERR, "%s: removing interface", iface->name); drop_config(iface, "STOP"); close_sockets(iface); delete_timeout(NULL, iface); @@ -272,8 +275,6 @@ send_message(struct interface *iface, int type, } free(dhcp); if (r == -1) { - logger(LOG_ERR, "%s: removing interface from dhcpcd", - iface->name); stop_interface(iface); } else { if (callback) @@ -592,44 +593,29 @@ open_sockets(struct interface *iface) } static void -handle_link(_unused void *arg) +handle_carrier(struct interface *iface) { - struct interface *iface; - int retval; - - retval = link_changed(linkfd, ifaces); - if (retval == -1) { - logger(LOG_ERR, "link_changed: %s", strerror(errno)); + if (!(iface->state->options->options & DHCPCD_LINK)) return; - } - if (retval == 0) - return; - for (iface = ifaces; iface; iface = iface->next) { - if (iface->state->options->options & DHCPCD_LINK) { - switch (carrier_status(iface->name)) { - case -1: - logger(LOG_ERR, "carrier_status: %s", - strerror(errno)); - break; - case 0: - if (iface->state->carrier != LINK_DOWN) { - iface->state->carrier = LINK_DOWN; - logger(LOG_INFO, "%s: carrier lost", - iface->name); - close_sockets(iface); - delete_timeouts(iface, start_expire, NULL); - } - break; - default: - if (iface->state->carrier != LINK_UP) { - iface->state->carrier = LINK_UP; - logger(LOG_INFO, "%s: carrier acquired", - iface->name); - start_interface(iface); - } - break; - } + switch (carrier_status(iface->name)) { + case -1: + logger(LOG_ERR, "carrier_status: %s", strerror(errno)); + break; + case 0: + if (iface->state->carrier != LINK_DOWN) { + iface->state->carrier = LINK_DOWN; + logger(LOG_INFO, "%s: carrier lost", iface->name); + close_sockets(iface); + delete_timeouts(iface, start_expire, NULL); + } + break; + default: + if (iface->state->carrier != LINK_UP) { + iface->state->carrier = LINK_UP; + logger(LOG_INFO, "%s: carrier acquired", iface->name); + start_interface(iface); } + break; } } @@ -786,6 +772,43 @@ init_state(struct interface *iface, int argc, char **argv) } static void +handle_new_interface(const char *name) +{ + struct interface *ifs, *ifp; + const char * const argv[] = { "dhcpcd", name }; + int i; + + /* If running off an interface list, check it's in it. */ + if (ifc) { + for (i = 0; i < ifc; i++) + if (strcmp(ifv[i], name) == 0) + break; + if (i >= ifc) + return; + } + + if ((ifs = discover_interfaces(2, UNCONST(argv)))) { + for (ifp = ifs; ifp; ifp = ifp->next) + init_state(ifp, 2, UNCONST(argv)); + if (ifaces) { + ifp = ifaces; + while (ifp->next) + ifp = ifp->next; + ifp->next = ifs; + } else + ifaces = ifs; + } +} + +static void +handle_link(_unused void *arg) +{ + if (manage_link(linkfd, ifaces, handle_carrier, + handle_new_interface, stop_interface) == -1) + logger(LOG_ERR, "manage_link: %s", strerror(errno)); +} + +static void handle_signal(_unused void *arg) { struct interface *iface; @@ -1091,13 +1114,15 @@ main(int argc, char **argv) } free_options(ifo); - argc -= optind; - argv += optind; - ifaces = discover_interfaces(argc, argv); - argc += optind; - argv -= optind; + ifc = argc - optind; + ifv = argv + optind; + ifaces = discover_interfaces(ifc, ifv); for (iface = ifaces; iface; iface = iface->next) init_state(iface, argc, argv); + if (!ifaces && ifc == 1) { + logger(LOG_ERR, "interface `%s' does not exist", ifv[0]); + exit(EXIT_FAILURE); + } start_eloop(); /* NOTREACHED */ } |
