summaryrefslogtreecommitdiffstats
path: root/workspace/customdhcpcd/src/dhcpcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'workspace/customdhcpcd/src/dhcpcd.c')
-rw-r--r--workspace/customdhcpcd/src/dhcpcd.c329
1 files changed, 312 insertions, 17 deletions
diff --git a/workspace/customdhcpcd/src/dhcpcd.c b/workspace/customdhcpcd/src/dhcpcd.c
index fca0bd4..1fc9040 100644
--- a/workspace/customdhcpcd/src/dhcpcd.c
+++ b/workspace/customdhcpcd/src/dhcpcd.c
@@ -68,6 +68,7 @@ static const struct option longopts[] = {
{"metric", required_argument, NULL, 'm'},
{"renew", no_argument, NULL, 'n'},
{"persistent", no_argument, NULL, 'p'},
+ {"qtsocketaddress", required_argument, NULL, 'q'},
{"inform", optional_argument, NULL, 's'},
{"request", optional_argument, NULL, 'r'},
{"timeout", required_argument, NULL, 't'},
@@ -142,11 +143,11 @@ static void usage (void)
printf ("usage: "PACKAGE" [-adknpEGHMNRSTY] [-c script] [-h hostname] [-i classID]\n"
" [-l leasetime] [-m metric] [-r ipaddress] [-s ipaddress]\n"
" [-t timeout] [-u userclass] [-F none | ptr | both]\n"
- " [-I clientID] <interface>\n");
+ " [-I clientID] [-q qtsocketaddress] <interface>\n");
}
-int nd_main(char *ifname)
+int main (int argc, char **argv)
{
options_t *options;
int userclasses = 0;
@@ -182,6 +183,10 @@ int nd_main(char *ifname)
options->doipv4ll = true;
options->doduid = true;
options->timeout = DEFAULT_TIMEOUT;
+ /* added by Niklas Goby, additional field, storing the socket address path for
+ * communicating with Qt "server"
+ * defined in dhcpcd.h */
+ strcpy(options->qtsocketaddress, DEFAULT_QTSOCKETADDRESS);
gethostname (options->hostname, sizeof (options->hostname));
if (strcmp (options->hostname, "(none)") == 0 ||
@@ -189,7 +194,287 @@ int nd_main(char *ifname)
memset (options->hostname, 0, sizeof (options->hostname));
-/*
+ /* Don't set any optional arguments here so we retain POSIX
+ * compatibility with getopt */
+ while ((opt = getopt_long(argc, argv, EXTRA_OPTS
+ "c:dh:i:kl:m:npr:s:t:u:xAEF:GHI:LMNRSTY",
+ longopts, &option_index)) != -1)
+ {
+ switch (opt) {
+ case 0:
+ if (longopts[option_index].flag)
+ break;
+ logger (LOG_ERR,
+ "option `%s' should set a flag",
+ longopts[option_index].name);
+ goto abort;
+ case 'c':
+ options->script = optarg;
+ break;
+ case 'd':
+ debug++;
+ switch (debug) {
+ case 1:
+ setloglevel (LOG_DEBUG);
+ break;
+ case 2:
+ options->daemonise = false;
+ break;
+ }
+ break;
+ #ifdef THERE_IS_NO_FORK
+ case 'f':
+ options->daemonised = true;
+ close_fds ();
+ break;
+ case 'g':
+ dhcpcd_skiproutes = xstrdup (optarg);
+ break;
+ #endif
+ case 'h':
+ if (! optarg)
+ *options->hostname = '\0';
+ else if (strlen (optarg) > MAXHOSTNAMELEN) {
+ logger (LOG_ERR,
+ "`%s' too long for HostName string, max is %d",
+ optarg, MAXHOSTNAMELEN);
+ goto abort;
+ } else
+ strlcpy (options->hostname, optarg,
+ sizeof (options->hostname));
+ break;
+ case 'i':
+ if (! optarg) {
+ *options->classid = '\0';
+ } else if (strlen (optarg) > CLASS_ID_MAX_LEN) {
+ logger (LOG_ERR,
+ "`%s' too long for ClassID string, max is %d",
+ optarg, CLASS_ID_MAX_LEN);
+ goto abort;
+ } else
+ strlcpy (options->classid, optarg,
+ sizeof (options->classid));
+ break;
+ case 'k':
+ sig = SIGHUP;
+ break;
+ case 'l':
+ if (*optarg == '-') {
+ logger (LOG_ERR,
+ "leasetime must be a positive value");
+ goto abort;
+ }
+ errno = 0;
+ options->leasetime = (uint32_t) strtol (optarg, NULL, 0);
+ if (errno == EINVAL || errno == ERANGE) {
+ logger (LOG_ERR, "`%s' out of range", optarg);
+ goto abort;
+ }
+ break;
+ case 'm':
+ options->metric = atoint (optarg);
+ if (options->metric < 0) {
+ logger (LOG_ERR,
+ "metric must be a positive value");
+ goto abort;
+ }
+ break;
+ case 'n':
+ sig = SIGALRM;
+ break;
+ case 'p':
+ options->persistent = true;
+ break;
+ case 's':
+ options->doinform = true;
+ options->doarp = false;
+ if (! optarg || strlen (optarg) == 0) {
+ options->request_address.s_addr = 0;
+ break;
+ } else {
+ char *slash = strchr (optarg, '/');
+ if (slash) {
+ int cidr;
+ /* nullify the slash, so the -r option can read the
+ * address */
+ *slash++ = '\0';
+ if (sscanf (slash, "%d", &cidr) != 1 ||
+ inet_cidrtoaddr (cidr, &options->request_netmask) != 0) {
+ logger (LOG_ERR, "`%s' is not a valid CIDR", slash);
+ goto abort;
+ }
+ }
+ }
+ /* FALLTHROUGH */
+ case 'r':
+ if (! options->doinform)
+ options->dorequest = true;
+ if (strlen (optarg) > 0 &&
+ ! inet_aton (optarg, &options->request_address))
+ {
+ logger (LOG_ERR, "`%s' is not a valid IP address", optarg);
+ goto abort;
+ }
+ break;
+ case 't':
+ options->timeout = atoint (optarg);
+ if (options->timeout < 0) {
+ logger (LOG_ERR, "timeout must be a positive value");
+ goto abort;
+ }
+ break;
+ case 'q':
+ if (strlen(optarg) > QTSOCKETADDRESSLENGTH) {
+ logger(LOG_ERR, "`%s' too long for an socket address path (max=%d)",
+ optarg, QTSOCKETADDRESSLENGTH);
+ goto abort;
+ }
+ strlcpy(options->qtsocketaddress, optarg, sizeof(options->qtsocketaddress));
+ break;
+ case 'u':
+ {
+ int offset = 0;
+ for (i = 0; i < userclasses; i++)
+ offset += (int) options->userclass[offset] + 1;
+ if (offset + 1 + strlen (optarg) > USERCLASS_MAX_LEN) {
+ logger (LOG_ERR, "userclass overrun, max is %d",
+ USERCLASS_MAX_LEN);
+ goto abort;
+ }
+ userclasses++;
+ memcpy (options->userclass + offset + 1 , optarg, strlen (optarg));
+ options->userclass[offset] = strlen (optarg);
+ options->userclass_len += (strlen (optarg)) + 1;
+ }
+ break;
+ case 'x':
+ sig = SIGTERM;
+ break;
+ case 'A':
+ #ifndef ENABLE_ARP
+ logger (LOG_ERR,
+ "arp not compiled into dhcpcd");
+ goto abort;
+ #endif
+ options->doarp = false;
+ break;
+ case 'E':
+ #ifndef ENABLE_INFO
+ logger (LOG_ERR,
+ "info not compiled into dhcpcd");
+ goto abort;
+ #endif
+ options->dolastlease = true;
+ break;
+ case 'F':
+ if (strncmp (optarg, "none", strlen (optarg)) == 0)
+ options->fqdn = FQDN_NONE;
+ else if (strncmp (optarg, "ptr", strlen (optarg)) == 0)
+ options->fqdn = FQDN_PTR;
+ else if (strncmp (optarg, "both", strlen (optarg)) == 0)
+ options->fqdn = FQDN_BOTH;
+ else {
+ logger (LOG_ERR, "invalid value `%s' for FQDN", optarg);
+ goto abort;
+ }
+ break;
+ case 'G':
+ options->dogateway = false;
+ break;
+ case 'H':
+ options->dohostname++;
+ break;
+ case 'I':
+ if (optarg) {
+ if (strlen (optarg) > CLIENT_ID_MAX_LEN) {
+ logger (LOG_ERR, "`%s' is too long for ClientID, max is %d",
+ optarg, CLIENT_ID_MAX_LEN);
+ goto abort;
+ }
+ if (strlcpy (options->clientid, optarg,
+ sizeof (options->clientid)) == 0)
+ /* empty string disabled duid */
+ options->doduid = false;
+
+ } else {
+ memset (options->clientid, 0, sizeof (options->clientid));
+ options->doduid = false;
+ }
+ break;
+ case 'L':
+ options->doipv4ll = false;
+ break;
+ case 'M':
+ options->domtu = false;
+ break;
+ case 'N':
+ options->dontp = false;
+ break;
+ case 'R':
+ options->dodns = false;
+ break;
+ case 'S':
+ options->domscsr++;
+ break;
+ case 'T':
+ #ifndef ENABLE_INFO
+ logger (LOG_ERR, "info support not compiled into dhcpcd");
+ goto abort;
+ #endif
+ options->test = true;
+ options->persistent = true;
+ break;
+ case 'Y':
+ options->donis = false;
+ break;
+ case '?':
+ usage ();
+ goto abort;
+ default:
+ usage ();
+ goto abort;
+ }
+ }
+ if (doversion) {
+ printf (""PACKAGE" "VERSION"\n");
+ printf ("Compile time options:"
+ #ifdef ENABLE_ARP
+ " ARP"
+ #endif
+ #ifdef ENABLE_DUID
+ " DUID"
+ #endif
+ #ifdef ENABLE_INFO
+ " INFO"
+ #endif
+ #ifdef ENABLE_INFO_COMPAT
+ " INFO_COMPAT"
+ #endif
+ #ifdef ENABLE_IPV4LL
+ " IPV4LL"
+ #endif
+ #ifdef ENABLE_NIS
+ " NIS"
+ #endif
+ #ifdef ENABLE_NTP
+ " NTP"
+ #endif
+ #ifdef SERVICE
+ " " SERVICE
+ #endif
+ #ifdef ENABLE_RESOLVCONF
+ " RESOLVCONF"
+ #endif
+ #ifdef THERE_IS_NO_FORK
+ " THERE_IS_NO_FORK"
+ #endif
+ "\n");
+ }
+
+ if (dohelp)
+ usage ();
+
+
#ifdef THERE_IS_NO_FORK
dhcpcd_argv = argv;
dhcpcd_argc = argc;
@@ -199,34 +484,44 @@ int nd_main(char *ifname)
goto abort;
}
#endif
-*/
/* initializations for the ipc connection to qt*/
- setSocketName("");
- setInterfaceName(ifname);
- initQtLoggerSocket();
+ setSocketName(options->qtsocketaddress);
+ if (initQtLoggerSocket() < 0) {
+ logger(LOG_ERR, "initialization Qt Logger failed: %s ", strerror (errno));
+ goto abort;
+ }
- if (strlen (ifname) > IF_NAMESIZE) {
- logger (LOG_ERR,
- "`%s' too long for an interface name (max=%d)",
- ifname, IF_NAMESIZE);
- logToQt(STAT_ERROR,-1,"interface name is too long");
+ if (optind < argc) {
+ if (strlen(argv[optind]) > IF_NAMESIZE) {
+ logger(LOG_ERR, "`%s' too long for an interface name (max=%d)",
+ argv[optind], IF_NAMESIZE);
goto abort;
+ }
+ strlcpy(options->interface, argv[optind], sizeof(options->interface));
+ setInterfaceName(options->interface);
} else {
- strlcpy (options->interface, ifname,
- sizeof (options->interface));
+ /* If only version was requested then exit now */
+ if (doversion || dohelp) {
+ retval = 0;
+ goto abort;
+ }
+
+ logger(LOG_ERR, "no interface specified");
+ setInterfaceName("no_if");
+ goto abort;
}
- if (strchr (options->hostname, '.')) {
+ if (strchr(options->hostname, '.')) {
if (options->fqdn == FQDN_DISABLE)
options->fqdn = FQDN_BOTH;
} else
options->fqdn = FQDN_DISABLE;
if (options->request_address.s_addr == 0 && options->doinform) {
- if ((options->request_address.s_addr =
- get_address (options->interface)) != 0)
+ if ((options->request_address.s_addr = get_address(options->interface))
+ != 0)
options->keep_address = true;
}