commit - 85c6a750079d9a9f6d6d41f565f5eaaa6e11144c
commit + dd054fead9185c4e49b5985abed6b555cd29ecbe
blob - 4f3fda97b1409dd8b3ad816ebd6d0850f149bb4d
blob + 94a5f8d21bdd5c4824a9d3ee370631ebe3743778
--- ctl.c
+++ ctl.c
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/syslimits.h>
+#include <net/if.h>
#include "externs.h"
#include "editing.h"
#include "ctl.h"
void install_crontab(char *);
void edit_motd(char *);
void call_editor(char *, char **, char *);
+void start_dhcpd(char *, char *, char *, char *, char *);
int edit_file(char *, mode_t, char *, char **);
void ctl_symlink(char *, char *, char *);
int rule_writeline(char *, mode_t, char *);
/* dhcpd */
struct ctl2 ctl_dhcp[] = {
{ "enable", "enable DHCPd daemon",
- { DHCPD, "-c", REQTEMP, "-l", DHCPLEASES, NULL }, { NULL, }, NULL,
- DB_X_ENABLE, T_EXEC },
+ { DHCPD, "-c", REQTEMP, "-l", DHCPLEASES, NULL }, { NULL, },
+ start_dhcpd, DB_X_ENABLE, T_HANDLER },
{ "disable", "disable DHCPd daemon",
{ PKILL, table, "dhcpd", NULL }, { NULL, }, NULL,
DB_X_DISABLE, T_EXEC },
if (errno != ENOENT)
printf("%% Unable to remove temporary file %s: %s\n",
file, strerror(errno));
+}
+
+void
+start_dhcpd(char *arg0, char *arg1, char *arg2, char *arg3, char *arg4)
+{
+ struct if_nameindex *ifn_list, *ifnp;
+ char **dhcpd_args = NULL;
+ size_t niface = 0;
+ int ifs, i;
+ char leasedb[PATH_MAX];
+
+ /*
+ * For rdomains other than zero dhcpd(8) expects a list of
+ * interfaces on its command line. If no interface arguments
+ * are given then dhcpd will move itself into rdomain zero
+ * so we really must specify a list here.
+ *
+ * All named interfaces must be part of the same rdomain. We
+ * provide the list of all interfaces in our current rdomain.
+ * dhcpd will listen on any with matching subnets in dhcpd.conf.
+ */
+ if ((ifn_list = if_nameindex()) == NULL) {
+ printf("%% %s: if_nameindex failed\n", __func__);
+ return;
+ }
+
+ if ((ifs = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ printf("%% %s socket: %s\n", __func__, strerror(errno));
+ goto done;
+ }
+
+ for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) {
+ int flags, rdomain;
+
+ flags = get_ifflags(ifnp->if_name, ifs);
+ if ((flags & IFF_LOOPBACK) ||
+ (flags & IFF_POINTOPOINT) ||
+ (!(flags & IFF_BROADCAST)))
+ continue;
+
+ rdomain = get_rdomain(ifs, ifnp->if_name);
+ if (rdomain == cli_rtable)
+ niface++;
+ }
+
+ dhcpd_args = calloc(5 + niface + 1, sizeof(char *));
+ if (dhcpd_args == NULL) {
+ printf("%% calloc: %s\n", strerror(errno));
+ goto done;
+ }
+
+ i = 0;
+ dhcpd_args[i++] = arg0; /* dhcpd */
+ dhcpd_args[i++] = arg1; /* -c */
+ dhcpd_args[i++] = arg2; /* dhcpd.conf */
+ dhcpd_args[i++] = arg3; /* -l */
+ if (cli_rtable != 0) {
+ snprintf(leasedb, sizeof(leasedb), "%s.%d",
+ arg4, cli_rtable);
+ dhcpd_args[i++] = leasedb; /* rdomain's leasedb */
+ } else
+ dhcpd_args[i++] = arg4; /* default leasedb */
+
+ for (ifnp = ifn_list; ifnp->if_name != NULL; ifnp++) {
+ int flags, rdomain;
+
+ flags = get_ifflags(ifnp->if_name, ifs);
+ if ((flags & IFF_LOOPBACK) ||
+ (flags & IFF_POINTOPOINT) ||
+ (!(flags & IFF_BROADCAST)))
+ continue;
+
+ rdomain = get_rdomain(ifs, ifnp->if_name);
+ if (rdomain == cli_rtable)
+ dhcpd_args[i++] = ifnp->if_name;
+ }
+ dhcpd_args[i] = NULL;
+
+ cmdargs(arg0, dhcpd_args);
+done:
+ if_freenameindex(ifn_list);
+ free(dhcpd_args);
}