mirror of
https://github.com/sheumann/hush.git
synced 2024-12-22 14:30:31 +00:00
udhcpc: convert to getopt32
This commit is contained in:
parent
30d7a346e6
commit
e2d3ded354
@ -1,4 +1,13 @@
|
|||||||
/* vi: set sw=4 ts=4: */
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* This file suffers from chronically incorrect tabification
|
||||||
|
* of messages. Before editing this file:
|
||||||
|
* 1. Switch you editor to 8-space tab mode.
|
||||||
|
* 2. Do not use \t in messages, use real tab character.
|
||||||
|
* 3. Start each source line with message as follows:
|
||||||
|
* |<7 spaces>"text with tabs"
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __BB_USAGE_H__
|
#ifndef __BB_USAGE_H__
|
||||||
#define __BB_USAGE_H__
|
#define __BB_USAGE_H__
|
||||||
|
|
||||||
|
@ -33,25 +33,8 @@ static int fd = -1;
|
|||||||
#define LISTEN_RAW 2
|
#define LISTEN_RAW 2
|
||||||
static int listen_mode;
|
static int listen_mode;
|
||||||
|
|
||||||
struct client_config_t client_config = {
|
struct client_config_t client_config;
|
||||||
/* Default options. */
|
|
||||||
.abort_if_no_lease = 0,
|
|
||||||
.foreground = 0,
|
|
||||||
.quit_after_lease = 0,
|
|
||||||
.release_on_quit = 0,
|
|
||||||
.background_if_no_lease = 0,
|
|
||||||
.interface = "eth0",
|
|
||||||
.pidfile = NULL,
|
|
||||||
.script = DEFAULT_SCRIPT,
|
|
||||||
.clientid = NULL,
|
|
||||||
.vendorclass = NULL,
|
|
||||||
.hostname = NULL,
|
|
||||||
.fqdn = NULL,
|
|
||||||
.ifindex = 0,
|
|
||||||
.retries = 3,
|
|
||||||
.timeout = 3,
|
|
||||||
.arp = "\0\0\0\0\0\0", /* appease gcc-3.0 */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* just a little helper */
|
/* just a little helper */
|
||||||
static void change_mode(int new_mode)
|
static void change_mode(int new_mode)
|
||||||
@ -126,139 +109,137 @@ static void client_background(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint8_t* alloc_dhcp_option(int code, const char *str, int extra)
|
||||||
|
{
|
||||||
|
uint8_t *storage;
|
||||||
|
int len = strlen(str);
|
||||||
|
if (len > 255) len = 255;
|
||||||
|
storage = xzalloc(len + extra + OPT_DATA);
|
||||||
|
storage[OPT_CODE] = code;
|
||||||
|
storage[OPT_LEN] = len + extra;
|
||||||
|
memcpy(storage + extra + OPT_DATA, str, len);
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int udhcpc_main(int argc, char *argv[])
|
int udhcpc_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
uint8_t *temp, *message;
|
uint8_t *temp, *message;
|
||||||
|
char *str_c, *str_V, *str_h, *str_F, *str_r, *str_T, *str_t;
|
||||||
unsigned long t1 = 0, t2 = 0, xid = 0;
|
unsigned long t1 = 0, t2 = 0, xid = 0;
|
||||||
unsigned long start = 0, lease = 0;
|
unsigned long start = 0, lease = 0;
|
||||||
fd_set rfds;
|
|
||||||
int retval;
|
|
||||||
struct timeval tv;
|
|
||||||
int c, len;
|
|
||||||
struct dhcpMessage packet;
|
|
||||||
struct in_addr temp_addr;
|
|
||||||
long now;
|
long now;
|
||||||
|
unsigned opt;
|
||||||
int max_fd;
|
int max_fd;
|
||||||
int sig;
|
int sig;
|
||||||
|
int retval;
|
||||||
|
int len;
|
||||||
int no_clientid = 0;
|
int no_clientid = 0;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
struct dhcpMessage packet;
|
||||||
|
struct in_addr temp_addr;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
OPT_c = 1 << 0,
|
||||||
|
OPT_C = 1 << 1,
|
||||||
|
OPT_V = 1 << 2,
|
||||||
|
OPT_f = 1 << 3,
|
||||||
|
OPT_b = 1 << 4,
|
||||||
|
OPT_H = 1 << 5,
|
||||||
|
OPT_h = 1 << 6,
|
||||||
|
OPT_F = 1 << 7,
|
||||||
|
OPT_i = 1 << 8,
|
||||||
|
OPT_n = 1 << 9,
|
||||||
|
OPT_p = 1 << 10,
|
||||||
|
OPT_q = 1 << 11,
|
||||||
|
OPT_R = 1 << 12,
|
||||||
|
OPT_r = 1 << 13,
|
||||||
|
OPT_s = 1 << 14,
|
||||||
|
OPT_T = 1 << 15,
|
||||||
|
OPT_t = 1 << 16,
|
||||||
|
OPT_v = 1 << 17,
|
||||||
|
};
|
||||||
static const struct option arg_options[] = {
|
static const struct option arg_options[] = {
|
||||||
{"clientid", required_argument, 0, 'c'},
|
{ "clientid", required_argument, 0, 'c' },
|
||||||
{"clientid-none", no_argument, 0, 'C'},
|
{ "clientid-none", no_argument, 0, 'C' },
|
||||||
{"vendorclass", required_argument, 0, 'V'},
|
{ "vendorclass", required_argument, 0, 'V' },
|
||||||
{"foreground", no_argument, 0, 'f'},
|
{ "foreground", no_argument, 0, 'f' },
|
||||||
{"background", no_argument, 0, 'b'},
|
{ "background", no_argument, 0, 'b' },
|
||||||
{"hostname", required_argument, 0, 'H'},
|
{ "hostname", required_argument, 0, 'H' },
|
||||||
{"hostname", required_argument, 0, 'h'},
|
{ "hostname", required_argument, 0, 'h' },
|
||||||
{"fqdn", required_argument, 0, 'F'},
|
{ "fqdn", required_argument, 0, 'F' },
|
||||||
{"interface", required_argument, 0, 'i'},
|
{ "interface", required_argument, 0, 'i' },
|
||||||
{"now", no_argument, 0, 'n'},
|
{ "now", no_argument, 0, 'n' },
|
||||||
{"pidfile", required_argument, 0, 'p'},
|
{ "pidfile", required_argument, 0, 'p' },
|
||||||
{"quit", no_argument, 0, 'q'},
|
{ "quit", no_argument, 0, 'q' },
|
||||||
{"release", no_argument, 0, 'R'},
|
{ "release", no_argument, 0, 'R' },
|
||||||
{"request", required_argument, 0, 'r'},
|
{ "request", required_argument, 0, 'r' },
|
||||||
{"script", required_argument, 0, 's'},
|
{ "script", required_argument, 0, 's' },
|
||||||
{"timeout", required_argument, 0, 'T'},
|
{ "timeout", required_argument, 0, 'T' },
|
||||||
{"version", no_argument, 0, 'v'},
|
{ "version", no_argument, 0, 'v' },
|
||||||
{"retries", required_argument, 0, 't'},
|
{ "retries", required_argument, 0, 't' },
|
||||||
{0, 0, 0, 0}
|
{ 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* get options */
|
/* Default options. */
|
||||||
while (1) {
|
client_config.interface = "eth0";
|
||||||
int option_index = 0;
|
client_config.script = DEFAULT_SCRIPT;
|
||||||
c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:v", arg_options, &option_index);
|
client_config.retries = 3;
|
||||||
if (c == -1) break;
|
client_config.timeout = 3;
|
||||||
|
|
||||||
switch (c) {
|
/* Parse command line */
|
||||||
case 'c':
|
opt_complementary = "?:c--C:C--c" // mutually exclusive
|
||||||
if (no_clientid) bb_show_usage();
|
":hH:Hh"; // -h and -H are the same
|
||||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
applet_long_options = arg_options;
|
||||||
free(client_config.clientid);
|
opt = getopt32(argc, argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:v",
|
||||||
client_config.clientid = xmalloc(len + 2);
|
&str_c, &str_V, &str_h, &str_h, &str_F,
|
||||||
client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
|
&client_config.interface, &client_config.pidfile, &str_r,
|
||||||
client_config.clientid[OPT_LEN] = len;
|
&client_config.script, &str_T, &str_t
|
||||||
client_config.clientid[OPT_DATA] = '\0';
|
);
|
||||||
strncpy((char*)client_config.clientid + OPT_DATA, optarg, len);
|
|
||||||
break;
|
if (opt & OPT_c)
|
||||||
case 'C':
|
client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, str_c, 0);
|
||||||
if (client_config.clientid) bb_show_usage();
|
if (opt & OPT_C)
|
||||||
no_clientid = 1;
|
no_clientid = 1;
|
||||||
break;
|
if (opt & OPT_V)
|
||||||
case 'V':
|
client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0);
|
||||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
if (opt & OPT_f)
|
||||||
free(client_config.vendorclass);
|
client_config.foreground = 1;
|
||||||
client_config.vendorclass = xmalloc(len + 2);
|
if (opt & OPT_b)
|
||||||
client_config.vendorclass[OPT_CODE] = DHCP_VENDOR;
|
client_config.background_if_no_lease = 1;
|
||||||
client_config.vendorclass[OPT_LEN] = len;
|
if (opt & OPT_h)
|
||||||
strncpy((char*)client_config.vendorclass + OPT_DATA, optarg, len);
|
client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0);
|
||||||
break;
|
if (opt & OPT_F) {
|
||||||
case 'f':
|
client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3);
|
||||||
client_config.foreground = 1;
|
/* Flags: 0000NEOS
|
||||||
break;
|
S: 1 => Client requests Server to update A RR in DNS as well as PTR
|
||||||
case 'b':
|
O: 1 => Server indicates to client that DNS has been updated regardless
|
||||||
client_config.background_if_no_lease = 1;
|
E: 1 => Name data is DNS format, i.e. <4>host<6>domain<4>com<0> not "host.domain.com"
|
||||||
break;
|
N: 1 => Client requests Server to not update DNS
|
||||||
case 'h':
|
*/
|
||||||
case 'H':
|
client_config.fqdn[OPT_DATA + 0] = 0x1;
|
||||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
/* client_config.fqdn[OPT_DATA + 1] = 0; - redundant */
|
||||||
free(client_config.hostname);
|
/* client_config.fqdn[OPT_DATA + 2] = 0; - redundant */
|
||||||
client_config.hostname = xmalloc(len + 2);
|
}
|
||||||
client_config.hostname[OPT_CODE] = DHCP_HOST_NAME;
|
// if (opt & OPT_i) client_config.interface = ...
|
||||||
client_config.hostname[OPT_LEN] = len;
|
if (opt & OPT_n)
|
||||||
strncpy((char*)client_config.hostname + 2, optarg, len);
|
client_config.abort_if_no_lease = 1;
|
||||||
break;
|
// if (opt & OPT_p) client_config.pidfile = ...
|
||||||
case 'F':
|
if (opt & OPT_q)
|
||||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
client_config.quit_after_lease = 1;
|
||||||
free(client_config.fqdn);
|
if (opt & OPT_R)
|
||||||
client_config.fqdn = xmalloc(len + 5);
|
client_config.release_on_quit = 1;
|
||||||
client_config.fqdn[OPT_CODE] = DHCP_FQDN;
|
if (opt & OPT_r)
|
||||||
client_config.fqdn[OPT_LEN] = len + 3;
|
requested_ip = inet_addr(str_r);
|
||||||
/* Flags: 0000NEOS
|
// if (opt & OPT_s) client_config.script = ...
|
||||||
S: 1 => Client requests Server to update A RR in DNS as well as PTR
|
if (opt & OPT_T)
|
||||||
O: 1 => Server indicates to client that DNS has been updated regardless
|
client_config.timeout = xatoi_u(str_T);
|
||||||
E: 1 => Name data is DNS format, i.e. <4>host<6>domain<4>com<0> not "host.domain.com"
|
if (opt & OPT_t)
|
||||||
N: 1 => Client requests Server to not update DNS
|
client_config.retries = xatoi_u(str_t);
|
||||||
*/
|
if (opt & OPT_v) {
|
||||||
client_config.fqdn[OPT_LEN + 1] = 0x1;
|
printf("version %s\n\n", BB_VER);
|
||||||
client_config.fqdn[OPT_LEN + 2] = 0;
|
return 0;
|
||||||
client_config.fqdn[OPT_LEN + 3] = 0;
|
|
||||||
strncpy((char*)client_config.fqdn + 5, optarg, len);
|
|
||||||
break;
|
|
||||||
case 'i':
|
|
||||||
client_config.interface = optarg;
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
client_config.abort_if_no_lease = 1;
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
client_config.pidfile = optarg;
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
client_config.quit_after_lease = 1;
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
client_config.release_on_quit = 1;
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
requested_ip = inet_addr(optarg);
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
client_config.script = optarg;
|
|
||||||
break;
|
|
||||||
case 'T':
|
|
||||||
client_config.timeout = xatoi_u(optarg);
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
client_config.retries = xatoi_u(optarg);
|
|
||||||
break;
|
|
||||||
case 'v':
|
|
||||||
printf("version %s\n\n", BB_VER);
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
bb_show_usage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Start the log, sanitize fd's, and write a pid file */
|
/* Start the log, sanitize fd's, and write a pid file */
|
||||||
@ -270,22 +251,13 @@ int udhcpc_main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* if not set, and not suppressed, setup the default client ID */
|
/* if not set, and not suppressed, setup the default client ID */
|
||||||
if (!client_config.clientid && !no_clientid) {
|
if (!client_config.clientid && !no_clientid) {
|
||||||
client_config.clientid = xmalloc(6 + 3);
|
client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
|
||||||
client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
|
|
||||||
client_config.clientid[OPT_LEN] = 7;
|
|
||||||
client_config.clientid[OPT_DATA] = 1;
|
client_config.clientid[OPT_DATA] = 1;
|
||||||
memcpy(client_config.clientid + 3, client_config.arp, 6);
|
memcpy(client_config.clientid + OPT_DATA+1, client_config.arp, 6);
|
||||||
}
|
|
||||||
|
|
||||||
if (!client_config.vendorclass) {
|
|
||||||
client_config.vendorclass = xmalloc(sizeof("udhcp "BB_VER) + 2);
|
|
||||||
client_config.vendorclass[OPT_CODE] = DHCP_VENDOR;
|
|
||||||
client_config.vendorclass[OPT_LEN] = sizeof("udhcp "BB_VER) - 1;
|
|
||||||
client_config.vendorclass[OPT_DATA] = 1;
|
|
||||||
memcpy(&client_config.vendorclass[OPT_DATA],
|
|
||||||
"udhcp "BB_VER, sizeof("udhcp "BB_VER) - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!client_config.vendorclass)
|
||||||
|
client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, "udhcp "BB_VER, 0);
|
||||||
|
|
||||||
/* setup the signal pipe */
|
/* setup the signal pipe */
|
||||||
udhcp_sp_setup();
|
udhcp_sp_setup();
|
||||||
@ -295,7 +267,6 @@ int udhcpc_main(int argc, char *argv[])
|
|||||||
change_mode(LISTEN_RAW);
|
change_mode(LISTEN_RAW);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
tv.tv_sec = timeout - uptime();
|
tv.tv_sec = timeout - uptime();
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
@ -13,22 +13,24 @@
|
|||||||
#define RELEASED 7
|
#define RELEASED 7
|
||||||
|
|
||||||
struct client_config_t {
|
struct client_config_t {
|
||||||
char foreground; /* Do not fork */
|
/* TODO: combine flag fields into single "unsigned opt" */
|
||||||
char quit_after_lease; /* Quit after obtaining lease */
|
/* (can be set directly to the result of getopt32) */
|
||||||
char release_on_quit; /* perform release on quit */
|
char foreground; /* Do not fork */
|
||||||
char abort_if_no_lease; /* Abort if no lease */
|
char quit_after_lease; /* Quit after obtaining lease */
|
||||||
char background_if_no_lease; /* Fork to background if no lease */
|
char release_on_quit; /* perform release on quit */
|
||||||
char *interface; /* The name of the interface to use */
|
char abort_if_no_lease; /* Abort if no lease */
|
||||||
char *pidfile; /* Optionally store the process ID */
|
char background_if_no_lease; /* Fork to background if no lease */
|
||||||
char *script; /* User script to run at dhcp events */
|
char *interface; /* The name of the interface to use */
|
||||||
uint8_t *clientid; /* Optional client id to use */
|
char *pidfile; /* Optionally store the process ID */
|
||||||
uint8_t *vendorclass; /* Optional vendor class-id to use */
|
char *script; /* User script to run at dhcp events */
|
||||||
uint8_t *hostname; /* Optional hostname to use */
|
uint8_t *clientid; /* Optional client id to use */
|
||||||
uint8_t *fqdn; /* Optional fully qualified domain name to use */
|
uint8_t *vendorclass; /* Optional vendor class-id to use */
|
||||||
int ifindex; /* Index number of the interface to use */
|
uint8_t *hostname; /* Optional hostname to use */
|
||||||
int retries; /* Max number of request packets */
|
uint8_t *fqdn; /* Optional fully qualified domain name to use */
|
||||||
int timeout; /* Number of seconds to try to get a lease */
|
int ifindex; /* Index number of the interface to use */
|
||||||
uint8_t arp[6]; /* Our arp address */
|
int retries; /* Max number of request packets */
|
||||||
|
int timeout; /* Number of seconds to try to get a lease */
|
||||||
|
uint8_t arp[6]; /* Our arp address */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct client_config_t client_config;
|
extern struct client_config_t client_config;
|
||||||
|
@ -68,11 +68,13 @@ int udhcpd_main(int argc, char *argv[])
|
|||||||
timeout_end = time(0) + server_config.auto_time;
|
timeout_end = time(0) + server_config.auto_time;
|
||||||
while (1) { /* loop until universe collapses */
|
while (1) { /* loop until universe collapses */
|
||||||
|
|
||||||
if (server_socket < 0)
|
if (server_socket < 0) {
|
||||||
if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
|
server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface);
|
||||||
|
if (server_socket < 0) {
|
||||||
bb_perror_msg("FATAL: cannot create server socket");
|
bb_perror_msg("FATAL: cannot create server socket");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
max_sock = udhcp_sp_fd_set(&rfds, server_socket);
|
max_sock = udhcp_sp_fd_set(&rfds, server_socket);
|
||||||
if (server_config.auto_time) {
|
if (server_config.auto_time) {
|
||||||
|
Loading…
Reference in New Issue
Block a user