Use static instead of extern, braces around if's, run through indent
This commit is contained in:
parent
50812fff21
commit
0be933b505
@ -58,6 +58,7 @@ static unsigned long server_addr;
|
||||
static unsigned long timeout;
|
||||
static int packet_num; /* = 0 */
|
||||
static int fd_main;
|
||||
|
||||
/* #define DEBUG */
|
||||
|
||||
#define VERSION "0.9.7"
|
||||
@ -189,20 +190,6 @@ enum {
|
||||
# define DEBUG(level, str, args...) do {;} while(0)
|
||||
#endif
|
||||
|
||||
struct client_config_t {
|
||||
char foreground; /* Do not fork */
|
||||
char quit_after_lease; /* Quit after obtaining lease */
|
||||
char abort_if_no_lease; /* Abort if no lease */
|
||||
char *interface; /* The name of the interface to use */
|
||||
char *pidfile; /* Optionally store the process ID */
|
||||
char *script; /* User script to run at dhcp events */
|
||||
unsigned char *clientid; /* Optional client id to use */
|
||||
unsigned char *hostname; /* Optional hostname to use */
|
||||
int ifindex; /* Index number of the interface to use */
|
||||
unsigned char arp[6]; /* Our arp address */
|
||||
};
|
||||
extern struct client_config_t client_config;
|
||||
|
||||
struct dhcpMessage {
|
||||
u_int8_t op;
|
||||
u_int8_t htype;
|
||||
@ -222,6 +209,19 @@ struct dhcpMessage {
|
||||
u_int8_t options[308]; /* 312 - cookie */
|
||||
};
|
||||
|
||||
struct client_config_t {
|
||||
char foreground; /* Do not fork */
|
||||
char quit_after_lease; /* Quit after obtaining lease */
|
||||
char abort_if_no_lease; /* Abort if no lease */
|
||||
char *interface; /* The name of the interface to use */
|
||||
char *pidfile; /* Optionally store the process ID */
|
||||
char *script; /* User script to run at dhcp events */
|
||||
unsigned char *clientid; /* Optional client id to use */
|
||||
unsigned char *hostname; /* Optional hostname to use */
|
||||
int ifindex; /* Index number of the interface to use */
|
||||
unsigned char arp[6]; /* Our arp address */
|
||||
};
|
||||
|
||||
struct client_config_t client_config = {
|
||||
/* Default options. */
|
||||
abort_if_no_lease:0,
|
||||
@ -311,8 +311,10 @@ static int end_option(unsigned char *optionptr)
|
||||
int i = 0;
|
||||
|
||||
while (optionptr[i] != DHCP_END) {
|
||||
if (optionptr[i] == DHCP_PADDING) i++;
|
||||
else i += optionptr[i + OPT_LEN] + 2;
|
||||
if (optionptr[i] == DHCP_PADDING)
|
||||
i++;
|
||||
else
|
||||
i += optionptr[i + OPT_LEN] + 2;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@ -325,7 +327,8 @@ static int add_option_string(unsigned char *optionptr, unsigned char *string)
|
||||
|
||||
/* end position + string length + option code/length + end option */
|
||||
if (end + string[OPT_LEN] + 2 + 1 >= 308) {
|
||||
LOG(LOG_ERR, "Option 0x%02x did not fit into the packet!", string[OPT_CODE]);
|
||||
LOG(LOG_ERR, "Option 0x%02x did not fit into the packet!",
|
||||
string[OPT_CODE]);
|
||||
return 0;
|
||||
}
|
||||
DEBUG(LOG_INFO, "adding option 0x%02x", string[OPT_CODE]);
|
||||
@ -335,7 +338,8 @@ static int add_option_string(unsigned char *optionptr, unsigned char *string)
|
||||
}
|
||||
|
||||
/* add a one to four byte option to a packet */
|
||||
static int add_simple_option(unsigned char *optionptr, unsigned char code, u_int32_t data)
|
||||
static int add_simple_option(unsigned char *optionptr, unsigned char code,
|
||||
u_int32_t data)
|
||||
{
|
||||
char length = 0;
|
||||
int i;
|
||||
@ -344,6 +348,7 @@ static int add_simple_option(unsigned char *optionptr, unsigned char code, u_int
|
||||
u_int16_t *u16;
|
||||
u_int32_t *u32;
|
||||
u_int32_t aligned;
|
||||
|
||||
u8 = (unsigned char *) &aligned;
|
||||
u16 = (u_int16_t *) & aligned;
|
||||
u32 = &aligned;
|
||||
@ -362,37 +367,21 @@ static int add_simple_option(unsigned char *optionptr, unsigned char code, u_int
|
||||
option[OPT_LEN] = length;
|
||||
|
||||
switch (length) {
|
||||
case 1: *u8 = data; break;
|
||||
case 2: *u16 = data; break;
|
||||
case 4: *u32 = data; break;
|
||||
case 1:
|
||||
*u8 = data;
|
||||
break;
|
||||
case 2:
|
||||
*u16 = data;
|
||||
break;
|
||||
case 4:
|
||||
*u32 = data;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(option + 2, &aligned, length);
|
||||
return add_option_string(optionptr, option);
|
||||
}
|
||||
#if 0
|
||||
void init_header(struct dhcpMessage *packet, char type)
|
||||
{
|
||||
memset(packet, 0, sizeof(struct dhcpMessage));
|
||||
switch (type) {
|
||||
case DHCPDISCOVER:
|
||||
case DHCPREQUEST:
|
||||
case DHCPRELEASE:
|
||||
case DHCPINFORM:
|
||||
packet->op = BOOTREQUEST;
|
||||
break;
|
||||
case DHCPOFFER:
|
||||
case DHCPACK:
|
||||
case DHCPNAK:
|
||||
packet->op = BOOTREPLY;
|
||||
}
|
||||
packet->htype = ETH_10MB;
|
||||
packet->hlen = ETH_10MB_LEN;
|
||||
packet->cookie = htonl(DHCP_MAGIC);
|
||||
packet->options[0] = DHCP_END;
|
||||
add_simple_option(packet->options, DHCP_MESSAGE_TYPE, type);
|
||||
}
|
||||
#endif
|
||||
|
||||
static u_int16_t checksum(void *addr, int count)
|
||||
{
|
||||
/* Compute Internet Checksum for "count" bytes
|
||||
@ -408,19 +397,22 @@ static u_int16_t checksum(void *addr, int count)
|
||||
}
|
||||
|
||||
/* Add left-over byte, if any */
|
||||
if( count > 0 )
|
||||
if (count > 0) {
|
||||
sum += *(unsigned char *) source;
|
||||
}
|
||||
|
||||
/* Fold 32-bit sum to 16 bits */
|
||||
while (sum>>16)
|
||||
while (sum >> 16) {
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
}
|
||||
|
||||
return ~sum;
|
||||
}
|
||||
|
||||
/* Constuct a ip/udp header for a packet, and specify the source and dest hardware address */
|
||||
static int raw_packet(struct dhcpMessage *payload, u_int32_t source_ip, int source_port,
|
||||
u_int32_t dest_ip, int dest_port, unsigned char *dest_arp, int ifindex)
|
||||
static int raw_packet(struct dhcpMessage *payload, u_int32_t source_ip,
|
||||
int source_port, u_int32_t dest_ip, int dest_port,
|
||||
unsigned char *dest_arp, int ifindex)
|
||||
{
|
||||
int l_fd;
|
||||
int result;
|
||||
@ -462,7 +454,9 @@ static int raw_packet(struct dhcpMessage *payload, u_int32_t source_ip, int sour
|
||||
packet.ip.ttl = IPDEFTTL;
|
||||
packet.ip.check = checksum(&(packet.ip), sizeof(packet.ip));
|
||||
|
||||
result = sendto(l_fd, &packet, sizeof(struct udp_dhcp_packet), 0, (struct sockaddr *) &dest, sizeof(dest));
|
||||
result =
|
||||
sendto(l_fd, &packet, sizeof(struct udp_dhcp_packet), 0,
|
||||
(struct sockaddr *) &dest, sizeof(dest));
|
||||
if (result <= 0) {
|
||||
DEBUG(LOG_ERR, "write on socket failed: %s", sys_errlist[errno]);
|
||||
}
|
||||
@ -471,34 +465,41 @@ static int raw_packet(struct dhcpMessage *payload, u_int32_t source_ip, int sour
|
||||
}
|
||||
|
||||
/* Let the kernel do all the work for packet generation */
|
||||
static int kernel_packet(struct dhcpMessage *payload, u_int32_t source_ip, int source_port,
|
||||
u_int32_t dest_ip, int dest_port)
|
||||
static int kernel_packet(struct dhcpMessage *payload, u_int32_t source_ip,
|
||||
int source_port, u_int32_t dest_ip, int dest_port)
|
||||
{
|
||||
int n = 1;
|
||||
int l_fd, result;
|
||||
struct sockaddr_in client;
|
||||
|
||||
if ((l_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
||||
if ((l_fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(l_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1)
|
||||
if (setsockopt(l_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) ==
|
||||
-1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&client, 0, sizeof(client));
|
||||
client.sin_family = AF_INET;
|
||||
client.sin_port = htons(source_port);
|
||||
client.sin_addr.s_addr = source_ip;
|
||||
|
||||
if (bind(l_fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
|
||||
if (bind(l_fd, (struct sockaddr *) &client, sizeof(struct sockaddr)) ==
|
||||
-1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&client, 0, sizeof(client));
|
||||
client.sin_family = AF_INET;
|
||||
client.sin_port = htons(dest_port);
|
||||
client.sin_addr.s_addr = dest_ip;
|
||||
|
||||
if (connect(l_fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
|
||||
if (connect(l_fd, (struct sockaddr *) &client, sizeof(struct sockaddr)) ==
|
||||
-1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = write(l_fd, payload, sizeof(struct dhcpMessage));
|
||||
close(l_fd);
|
||||
@ -511,9 +512,10 @@ static void init_packet(struct dhcpMessage *packet, char type)
|
||||
struct vendor {
|
||||
char vendor, length;
|
||||
char str[sizeof("udhcp " VERSION)];
|
||||
} vendor_id = { DHCP_VENDOR, sizeof("udhcp "VERSION) - 1, "udhcp "VERSION};
|
||||
}
|
||||
vendor_id = {
|
||||
DHCP_VENDOR, sizeof("udhcp " VERSION) - 1, "udhcp " VERSION};
|
||||
|
||||
// init_header(packet, type);
|
||||
memset(packet, 0, sizeof(struct dhcpMessage));
|
||||
switch (type) {
|
||||
case DHCPDISCOVER:
|
||||
@ -535,7 +537,9 @@ static void init_packet(struct dhcpMessage *packet, char type)
|
||||
|
||||
memcpy(packet->chaddr, client_config.arp, 6);
|
||||
add_option_string(packet->options, client_config.clientid);
|
||||
if (client_config.hostname) add_option_string(packet->options, client_config.hostname);
|
||||
if (client_config.hostname) {
|
||||
add_option_string(packet->options, client_config.hostname);
|
||||
}
|
||||
add_option_string(packet->options, (unsigned char *) &vendor_id);
|
||||
}
|
||||
|
||||
@ -549,9 +553,11 @@ static void add_requests(struct dhcpMessage *packet)
|
||||
int i, len = 0;
|
||||
|
||||
packet->options[end + OPT_CODE] = DHCP_PARAM_REQ;
|
||||
for (i = 0; options[i].code; i++)
|
||||
if (options[i].flags & OPTION_REQ)
|
||||
for (i = 0; options[i].code; i++) {
|
||||
if (options[i].flags & OPTION_REQ) {
|
||||
packet->options[end + OPT_DATA + len++] = options[i].code;
|
||||
}
|
||||
}
|
||||
packet->options[end + OPT_LEN] = len;
|
||||
packet->options[end + OPT_DATA + len] = DHCP_END;
|
||||
|
||||
@ -564,9 +570,9 @@ static inline int send_discover(unsigned long xid, unsigned long requested)
|
||||
|
||||
init_packet(&packet, DHCPDISCOVER);
|
||||
packet.xid = xid;
|
||||
if (requested)
|
||||
if (requested) {
|
||||
add_simple_option(packet.options, DHCP_REQUESTED_IP, requested);
|
||||
|
||||
}
|
||||
add_requests(&packet);
|
||||
DEBUG(LOG_DEBUG, "Sending discover...");
|
||||
return raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST,
|
||||
@ -574,7 +580,8 @@ static inline int send_discover(unsigned long xid, unsigned long requested)
|
||||
}
|
||||
|
||||
/* Broadcasts a DHCP request message */
|
||||
static inline int send_selecting(unsigned long xid, unsigned long server, unsigned long requested)
|
||||
static inline int send_selecting(unsigned long xid, unsigned long server,
|
||||
unsigned long requested)
|
||||
{
|
||||
struct dhcpMessage packet;
|
||||
struct in_addr addr;
|
||||
@ -594,7 +601,8 @@ static inline int send_selecting(unsigned long xid, unsigned long server, unsign
|
||||
|
||||
|
||||
/* Unicasts or broadcasts a DHCP renew message */
|
||||
static int send_renew(unsigned long xid, unsigned long server, unsigned long ciaddr)
|
||||
static int send_renew(unsigned long xid, unsigned long server,
|
||||
unsigned long ciaddr)
|
||||
{
|
||||
struct dhcpMessage packet;
|
||||
|
||||
@ -604,8 +612,10 @@ static int send_renew(unsigned long xid, unsigned long server, unsigned long cia
|
||||
|
||||
add_requests(&packet);
|
||||
DEBUG(LOG_DEBUG, "Sending renew...");
|
||||
if (server)
|
||||
return kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT);
|
||||
if (server) {
|
||||
return kernel_packet(&packet, ciaddr, CLIENT_PORT, server,
|
||||
SERVER_PORT);
|
||||
}
|
||||
return raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST,
|
||||
SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex);
|
||||
}
|
||||
@ -614,29 +624,13 @@ static int send_renew(unsigned long xid, unsigned long server, unsigned long cia
|
||||
static unsigned long random_xid(void)
|
||||
{
|
||||
static int initialized;
|
||||
|
||||
if (!initialized) {
|
||||
srand(time(0));
|
||||
initialized++;
|
||||
}
|
||||
return rand();
|
||||
}
|
||||
#if 0
|
||||
/* Unicasts a DHCP release message */
|
||||
int send_release(unsigned long server, unsigned long ciaddr)
|
||||
{
|
||||
struct dhcpMessage packet;
|
||||
|
||||
init_packet(&packet, DHCPRELEASE);
|
||||
packet.xid = random_xid();
|
||||
packet.ciaddr = ciaddr;
|
||||
|
||||
add_simple_option(packet.options, DHCP_REQUESTED_IP, ciaddr);
|
||||
add_simple_option(packet.options, DHCP_SERVER_ID, server);
|
||||
|
||||
LOG(LOG_DEBUG, "Sending release...");
|
||||
return kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* just a little helper */
|
||||
static void change_mode(int new_mode)
|
||||
@ -715,7 +709,9 @@ static unsigned char *get_option(struct dhcpMessage *packet, int code)
|
||||
i = 0;
|
||||
length = 64;
|
||||
curr = SNAME_FIELD;
|
||||
} else done = 1;
|
||||
} else {
|
||||
done = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
i += optionptr[OPT_LEN + i] + 2;
|
||||
@ -723,21 +719,16 @@ static unsigned char *get_option(struct dhcpMessage *packet, int code)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#if 0
|
||||
static int upper_length(int length, struct dhcp_option *option)
|
||||
{
|
||||
return max_option_length[option->flags & TYPE_MASK] *
|
||||
(length / option_lengths[option->flags & TYPE_MASK]);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int sprintip(char *dest, char *pre, unsigned char *ip) {
|
||||
static int sprintip(char *dest, char *pre, unsigned char *ip)
|
||||
{
|
||||
return sprintf(dest, "%s%d.%d.%d.%d ", pre, ip[0], ip[1], ip[2], ip[3]);
|
||||
}
|
||||
|
||||
|
||||
/* Fill dest with the text of option 'option'. */
|
||||
extern inline void fill_options(char *dest, unsigned char *option, const struct dhcp_option *type_p)
|
||||
static inline void fill_options(char *dest, unsigned char *option,
|
||||
const struct dhcp_option *type_p)
|
||||
{
|
||||
int type, optlen;
|
||||
u_int16_t val_u16;
|
||||
@ -789,7 +780,9 @@ extern inline void fill_options(char *dest, unsigned char *option, const struct
|
||||
}
|
||||
option += optlen;
|
||||
len -= optlen;
|
||||
if (len <= 0) break;
|
||||
if (len <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -800,9 +793,10 @@ static char *find_env(const char *prefix, char *defaultstr)
|
||||
const int len = strlen(prefix);
|
||||
|
||||
for (ptr = environ; *ptr != NULL; ptr++) {
|
||||
if (strncmp(prefix, *ptr, len) == 0)
|
||||
if (strncmp(prefix, *ptr, len) == 0) {
|
||||
return *ptr;
|
||||
}
|
||||
}
|
||||
return defaultstr;
|
||||
}
|
||||
|
||||
@ -816,17 +810,26 @@ static char **fill_envp(struct dhcpMessage *packet)
|
||||
unsigned char *temp;
|
||||
char over = 0;
|
||||
|
||||
if (packet == NULL)
|
||||
if (packet == NULL) {
|
||||
num_options = 0;
|
||||
else {
|
||||
for (i = 0; options[i].code; i++)
|
||||
if (get_option(packet, options[i].code))
|
||||
} else {
|
||||
for (i = 0; options[i].code; i++) {
|
||||
if (get_option(packet, options[i].code)) {
|
||||
num_options++;
|
||||
if (packet->siaddr) num_options++;
|
||||
if ((temp = get_option(packet, DHCP_OPTION_OVER)))
|
||||
}
|
||||
}
|
||||
if (packet->siaddr) {
|
||||
num_options++;
|
||||
}
|
||||
if ((temp = get_option(packet, DHCP_OPTION_OVER))) {
|
||||
over = *temp;
|
||||
if (!(over & FILE_FIELD) && packet->file[0]) num_options++;
|
||||
if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++;
|
||||
}
|
||||
if (!(over & FILE_FIELD) && packet->file[0]) {
|
||||
num_options++;
|
||||
}
|
||||
if (!(over & SNAME_FIELD) && packet->sname[0]) {
|
||||
num_options++;
|
||||
}
|
||||
}
|
||||
|
||||
envp = xmalloc((num_options + 5) * sizeof(char *));
|
||||
@ -844,8 +847,11 @@ static char **fill_envp(struct dhcpMessage *packet)
|
||||
sprintip(envp[3], "ip=", (unsigned char *) &packet->yiaddr);
|
||||
for (i = 0, j = 4; options[i].code; i++) {
|
||||
if ((temp = get_option(packet, options[i].code))) {
|
||||
envp[j] = xmalloc(max_option_length[(&options[i])->flags & TYPE_MASK] * (temp[OPT_LEN - 2] / option_lengths[(&options[i])->flags & TYPE_MASK]) + strlen((&options[i])->name) + 2);
|
||||
// envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], &options[i]) + strlen(options[i].name) + 2);
|
||||
envp[j] =
|
||||
xmalloc(max_option_length[(&options[i])->flags & TYPE_MASK] *
|
||||
(temp[OPT_LEN - 2] /
|
||||
option_lengths[(&options[i])->flags & TYPE_MASK]) +
|
||||
strlen((&options[i])->name) + 2);
|
||||
fill_options(envp[j], temp, &options[i]);
|
||||
j++;
|
||||
}
|
||||
@ -876,8 +882,9 @@ static void run_script(struct dhcpMessage *packet, const char *name)
|
||||
int pid;
|
||||
char **envp;
|
||||
|
||||
if (client_config.script == NULL)
|
||||
if (client_config.script == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* call script */
|
||||
pid = fork();
|
||||
@ -891,8 +898,7 @@ static void run_script(struct dhcpMessage *packet, const char *name)
|
||||
|
||||
/* exec script */
|
||||
DEBUG(LOG_INFO, "execle'ing %s", client_config.script);
|
||||
execle(client_config.script, client_config.script,
|
||||
name, NULL, envp);
|
||||
execle(client_config.script, client_config.script, name, NULL, envp);
|
||||
LOG(LOG_ERR, "script %s failed: %s",
|
||||
client_config.script, sys_errlist[errno]);
|
||||
exit(1);
|
||||
@ -916,7 +922,8 @@ static void release_requested(int sig)
|
||||
add_simple_option(packet.options, DHCP_SERVER_ID, server_addr);
|
||||
|
||||
DEBUG(LOG_DEBUG, "Sending release...");
|
||||
kernel_packet(&packet, requested_ip, CLIENT_PORT, server_addr, SERVER_PORT);
|
||||
kernel_packet(&packet, requested_ip, CLIENT_PORT, server_addr,
|
||||
SERVER_PORT);
|
||||
run_script(NULL, "deconfig");
|
||||
}
|
||||
|
||||
@ -929,8 +936,10 @@ static void release_requested(int sig)
|
||||
static int pidfile_acquire(char *pidfile)
|
||||
{
|
||||
int pid_fd;
|
||||
if (pidfile == NULL) return -1;
|
||||
|
||||
if (pidfile == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
|
||||
if (pid_fd < 0) {
|
||||
LOG(LOG_ERR, "Unable to open pidfile %s: %s\n",
|
||||
@ -947,8 +956,9 @@ static void pidfile_write_release(int pid_fd)
|
||||
{
|
||||
FILE *out;
|
||||
|
||||
if (pid_fd < 0) return;
|
||||
|
||||
if (pid_fd < 0) {
|
||||
return;
|
||||
}
|
||||
if ((out = fdopen(pid_fd, "w")) != NULL) {
|
||||
fprintf(out, "%d\n", getpid());
|
||||
fclose(out);
|
||||
@ -961,7 +971,9 @@ static void pidfile_write_release(int pid_fd)
|
||||
static void exit_client(int retval)
|
||||
{
|
||||
unlink(client_config.pidfile);
|
||||
if (client_config.pidfile) unlink(client_config.pidfile);
|
||||
if (client_config.pidfile) {
|
||||
unlink(client_config.pidfile);
|
||||
}
|
||||
CLOSE_LOG();
|
||||
exit(retval);
|
||||
}
|
||||
@ -976,7 +988,8 @@ static void terminate(int sig)
|
||||
}
|
||||
|
||||
|
||||
extern inline int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp)
|
||||
static inline int read_interface(char *interface, int *ifindex,
|
||||
u_int32_t * addr, unsigned char *arp)
|
||||
{
|
||||
int l_fd;
|
||||
struct ifreq ifr;
|
||||
@ -991,7 +1004,8 @@ extern inline int read_interface(char *interface, int *ifindex, u_int32_t *addr,
|
||||
if (ioctl(l_fd, SIOCGIFADDR, &ifr) == 0) {
|
||||
s_in = (struct sockaddr_in *) &ifr.ifr_addr;
|
||||
*addr = s_in->sin_addr.s_addr;
|
||||
DEBUG(LOG_INFO, "%s (our ip) = %s", ifr.ifr_name, inet_ntoa(s_in->sin_addr));
|
||||
DEBUG(LOG_INFO, "%s (our ip) = %s", ifr.ifr_name,
|
||||
inet_ntoa(s_in->sin_addr));
|
||||
} else {
|
||||
LOG(LOG_ERR, "SIOCGIFADDR failed!: %s", sys_errlist[errno]);
|
||||
return -1;
|
||||
@ -1007,7 +1021,8 @@ extern inline int read_interface(char *interface, int *ifindex, u_int32_t *addr,
|
||||
}
|
||||
if (ioctl(l_fd, SIOCGIFHWADDR, &ifr) == 0) {
|
||||
memcpy(arp, ifr.ifr_hwaddr.sa_data, 6);
|
||||
DEBUG(LOG_INFO, "adapter hardware address %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
DEBUG(LOG_INFO,
|
||||
"adapter hardware address %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
arp[0], arp[1], arp[2], arp[3], arp[4], arp[5]);
|
||||
} else {
|
||||
LOG(LOG_ERR, "SIOCGIFHWADDR failed!: %s", sys_errlist[errno]);
|
||||
@ -1022,7 +1037,7 @@ extern inline int read_interface(char *interface, int *ifindex, u_int32_t *addr,
|
||||
}
|
||||
|
||||
|
||||
extern inline int listen_socket(unsigned int ip, int port, char *inf)
|
||||
static inline int listen_socket(unsigned int ip, int port, char *inf)
|
||||
{
|
||||
struct ifreq interface;
|
||||
int l_fd;
|
||||
@ -1040,17 +1055,21 @@ extern inline int listen_socket(unsigned int ip, int port, char *inf)
|
||||
addr.sin_port = htons(port);
|
||||
addr.sin_addr.s_addr = ip;
|
||||
|
||||
if (setsockopt(l_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) {
|
||||
if (setsockopt(l_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) ==
|
||||
-1) {
|
||||
close(l_fd);
|
||||
return -1;
|
||||
}
|
||||
if (setsockopt(l_fd, SOL_SOCKET, SO_BROADCAST, (char *) &n, sizeof(n)) == -1) {
|
||||
if (setsockopt(l_fd, SOL_SOCKET, SO_BROADCAST, (char *) &n, sizeof(n)) ==
|
||||
-1) {
|
||||
close(l_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(interface.ifr_ifrn.ifrn_name, inf, IFNAMSIZ);
|
||||
if (setsockopt(l_fd, SOL_SOCKET, SO_BINDTODEVICE,(char *)&interface, sizeof(interface)) < 0) {
|
||||
if (setsockopt
|
||||
(l_fd, SOL_SOCKET, SO_BINDTODEVICE, (char *) &interface,
|
||||
sizeof(interface)) < 0) {
|
||||
close(l_fd);
|
||||
return -1;
|
||||
}
|
||||
@ -1112,10 +1131,12 @@ static int get_packet(struct dhcpMessage *packet, int l_fd)
|
||||
}
|
||||
DEBUG(LOG_INFO, "Received a packet");
|
||||
|
||||
if (packet->op == BOOTREQUEST && (vendor = get_option(packet, DHCP_VENDOR))) {
|
||||
if (packet->op == BOOTREQUEST
|
||||
&& (vendor = get_option(packet, DHCP_VENDOR))) {
|
||||
for (i = 0; broken_vendors[i][0]; i++) {
|
||||
if (vendor[OPT_LEN - 2] == (unsigned char) strlen(broken_vendors[i]) &&
|
||||
!strncmp(vendor, broken_vendors[i], vendor[OPT_LEN - 2])) {
|
||||
if (vendor[OPT_LEN - 2] ==
|
||||
(unsigned char) strlen(broken_vendors[i])
|
||||
&& !strncmp(vendor, broken_vendors[i], vendor[OPT_LEN - 2])) {
|
||||
DEBUG(LOG_INFO, "broken client (%s), forcing broadcast",
|
||||
broken_vendors[i]);
|
||||
packet->flags |= htons(BROADCAST_FLAG);
|
||||
@ -1123,11 +1144,10 @@ static int get_packet(struct dhcpMessage *packet, int l_fd)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
extern inline int get_raw_packet(struct dhcpMessage *payload, int l_fd)
|
||||
static inline int get_raw_packet(struct dhcpMessage *payload, int l_fd)
|
||||
{
|
||||
int bytes;
|
||||
struct udp_dhcp_packet packet;
|
||||
@ -1157,9 +1177,10 @@ extern inline int get_raw_packet(struct dhcpMessage *payload, int l_fd)
|
||||
|
||||
/* Make sure its the right packet for us, and that it passes sanity checks */
|
||||
if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION ||
|
||||
packet.ip.ihl != sizeof(packet.ip) >> 2 || packet.udp.dest != htons(CLIENT_PORT) ||
|
||||
bytes > (int) sizeof(struct udp_dhcp_packet) ||
|
||||
ntohs(packet.udp.len) != (short) (bytes - sizeof(packet.ip))) {
|
||||
packet.ip.ihl != sizeof(packet.ip) >> 2
|
||||
|| packet.udp.dest != htons(CLIENT_PORT)
|
||||
|| bytes > (int) sizeof(struct udp_dhcp_packet)
|
||||
|| ntohs(packet.udp.len) != (short) (bytes - sizeof(packet.ip))) {
|
||||
DEBUG(LOG_INFO, "unrelated/bogus packet");
|
||||
return -1;
|
||||
}
|
||||
@ -1188,7 +1209,8 @@ extern inline int get_raw_packet(struct dhcpMessage *payload, int l_fd)
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(payload, &(packet.data), bytes - (sizeof(packet.ip) + sizeof(packet.udp)));
|
||||
memcpy(payload, &(packet.data),
|
||||
bytes - (sizeof(packet.ip) + sizeof(packet.udp)));
|
||||
|
||||
if (ntohl(payload->cookie) != DHCP_MAGIC) {
|
||||
LOG(LOG_ERR, "received bogus message (bad magic) -- ignoring");
|
||||
@ -1231,14 +1253,22 @@ int udhcpc_main(int argc, char *argv[])
|
||||
/* get options */
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
c = getopt_long(argc, argv, "c:fH:hi:np:qr:s:v", l_options, &option_index);
|
||||
if (c == -1) break;
|
||||
|
||||
c = getopt_long(argc, argv, "c:fH:hi:np:qr:s:v", l_options,
|
||||
&option_index);
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'c':
|
||||
len = strlen(optarg);
|
||||
if (len > 255) len = 255;
|
||||
if (client_config.clientid) free(client_config.clientid);
|
||||
if (len > 255) {
|
||||
len = 255;
|
||||
}
|
||||
if (client_config.clientid) {
|
||||
free(client_config.clientid);
|
||||
}
|
||||
client_config.clientid = xmalloc(len + 2);
|
||||
client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
|
||||
client_config.clientid[OPT_LEN] = len;
|
||||
@ -1250,16 +1280,19 @@ int udhcpc_main(int argc, char *argv[])
|
||||
break;
|
||||
case 'H':
|
||||
len = strlen(optarg);
|
||||
if (len > 255) len = 255;
|
||||
if (client_config.hostname) free(client_config.hostname);
|
||||
if (len > 255) {
|
||||
len = 255;
|
||||
}
|
||||
if (client_config.hostname) {
|
||||
free(client_config.hostname);
|
||||
}
|
||||
client_config.hostname = xmalloc(len + 2);
|
||||
client_config.hostname[OPT_CODE] = DHCP_HOST_NAME;
|
||||
client_config.hostname[OPT_LEN] = len;
|
||||
strncpy(client_config.hostname + 2, optarg, len);
|
||||
break;
|
||||
case 'h':
|
||||
puts(
|
||||
"Usage: udhcpcd [OPTIONS]\n\n"
|
||||
puts("Usage: udhcpcd [OPTIONS]\n\n"
|
||||
" -c, --clientid=CLIENTID Client identifier\n"
|
||||
" -H, --hostname=HOSTNAME Client hostname\n"
|
||||
" -f, --foreground Do not fork after getting lease\n"
|
||||
@ -1271,8 +1304,7 @@ int udhcpc_main(int argc, char *argv[])
|
||||
" -r, --request=IP IP address to request (default: none)\n"
|
||||
" -s, --script=file Run file at dhcp events (default:\n"
|
||||
" " DEFAULT_SCRIPT ")\n"
|
||||
" -v, --version Display version"
|
||||
);
|
||||
" -v, --version Display version");
|
||||
return 0;
|
||||
case 'i':
|
||||
client_config.interface = optarg;
|
||||
@ -1305,7 +1337,9 @@ int udhcpc_main(int argc, char *argv[])
|
||||
pid_fd = pidfile_acquire(client_config.pidfile);
|
||||
pidfile_write_release(pid_fd);
|
||||
|
||||
if (read_interface(client_config.interface, &client_config.ifindex, NULL, client_config.arp) < 0) {
|
||||
if (read_interface
|
||||
(client_config.interface, &client_config.ifindex, NULL,
|
||||
client_config.arp) < 0) {
|
||||
exit_client(1);
|
||||
}
|
||||
|
||||
@ -1333,12 +1367,15 @@ int udhcpc_main(int argc, char *argv[])
|
||||
|
||||
if (listen_mode != LISTEN_NONE && fd_main < 0) {
|
||||
if (listen_mode == LISTEN_KERNEL) {
|
||||
fd_main = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface);
|
||||
fd_main =
|
||||
listen_socket(INADDR_ANY, CLIENT_PORT,
|
||||
client_config.interface);
|
||||
} else {
|
||||
fd_main = raw_socket(client_config.ifindex);
|
||||
}
|
||||
if (fd_main < 0) {
|
||||
LOG(LOG_ERR, "FATAL: couldn't listen on socket, %s", sys_errlist[errno]);
|
||||
LOG(LOG_ERR, "FATAL: couldn't listen on socket, %s",
|
||||
sys_errlist[errno]);
|
||||
exit_client(0);
|
||||
}
|
||||
}
|
||||
@ -1440,7 +1477,8 @@ int udhcpc_main(int argc, char *argv[])
|
||||
timeout = 0x7fffffff;
|
||||
break;
|
||||
}
|
||||
} else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd_main, &rfds)) {
|
||||
} else if (retval > 0 && listen_mode != LISTEN_NONE
|
||||
&& FD_ISSET(fd_main, &rfds)) {
|
||||
/* a packet is ready, read it */
|
||||
|
||||
if (listen_mode == LISTEN_KERNEL) {
|
||||
@ -1449,7 +1487,8 @@ int udhcpc_main(int argc, char *argv[])
|
||||
len = get_raw_packet(&packet, fd_main);
|
||||
}
|
||||
if (len == -1 && errno != EINTR) {
|
||||
DEBUG(LOG_INFO, "error on read, %s, reopening socket", sys_errlist[errno]);
|
||||
DEBUG(LOG_INFO, "error on read, %s, reopening socket",
|
||||
sys_errlist[errno]);
|
||||
change_mode(listen_mode); /* just close and reopen */
|
||||
}
|
||||
if (len < 0) {
|
||||
@ -1491,7 +1530,8 @@ int udhcpc_main(int argc, char *argv[])
|
||||
case REBINDING:
|
||||
if (*message == DHCPACK) {
|
||||
if (!(temp = get_option(&packet, DHCP_LEASE_TIME))) {
|
||||
LOG(LOG_ERR, "No lease time with ACK, using 1 hour lease");
|
||||
LOG(LOG_ERR,
|
||||
"No lease time with ACK, using 1 hour lease");
|
||||
lease = 60 * 60;
|
||||
} else {
|
||||
memcpy(&lease, temp, 4);
|
||||
@ -1504,16 +1544,20 @@ int udhcpc_main(int argc, char *argv[])
|
||||
/* little fixed point for n * .875 */
|
||||
t2 = (lease * 0x7) >> 3;
|
||||
temp_addr.s_addr = packet.yiaddr;
|
||||
LOG(LOG_INFO, "Lease of %s obtained, lease time %ld", inet_ntoa(temp_addr), lease);
|
||||
LOG(LOG_INFO, "Lease of %s obtained, lease time %ld",
|
||||
inet_ntoa(temp_addr), lease);
|
||||
start = now;
|
||||
timeout = t1 + start;
|
||||
requested_ip = packet.yiaddr;
|
||||
run_script(&packet, ((state == RENEWING || state == REBINDING) ? "renew" : "bound"));
|
||||
run_script(&packet,
|
||||
((state == RENEWING
|
||||
|| state == REBINDING) ? "renew" : "bound"));
|
||||
|
||||
state = BOUND;
|
||||
change_mode(LISTEN_NONE);
|
||||
{
|
||||
int pid_fd2;
|
||||
|
||||
if (client_config.quit_after_lease) {
|
||||
exit_client(0);
|
||||
} else if (!client_config.foreground) {
|
||||
@ -1526,8 +1570,7 @@ int udhcpc_main(int argc, char *argv[])
|
||||
pidfile_write_release(pid_fd2);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*message == DHCPNAK) {
|
||||
} else if (*message == DHCPNAK) {
|
||||
/* return to init state */
|
||||
LOG(LOG_INFO, "Received DHCP NAK");
|
||||
run_script(&packet, "nak");
|
||||
@ -1544,8 +1587,7 @@ int udhcpc_main(int argc, char *argv[])
|
||||
break;
|
||||
/* case BOUND, RELEASED: - ignore all packets */
|
||||
}
|
||||
}
|
||||
else if (retval == -1 && errno == EINTR) {
|
||||
} else if (retval == -1 && errno == EINTR) {
|
||||
/* a signal was caught */
|
||||
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user