sync busybox and udhcp trees

This commit is contained in:
Mike Frysinger 2006-03-23 03:05:05 +00:00
parent 8df074e69a
commit b37705b24e
20 changed files with 208 additions and 166 deletions

View File

@ -27,7 +27,7 @@ struct arpMsg {
uint8_t tHaddr[6]; /* target's hardware address */
uint8_t tInaddr[4]; /* target's IP address */
uint8_t pad[18]; /* pad for min. Ethernet payload (60 bytes) */
} __attribute__ ((packed));
} ATTRIBUTE_PACKED;
/* function prototypes */
int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *arp, char *interface);

View File

@ -42,7 +42,6 @@ enum syslog_levels {
long uptime(void);
void background(const char *pidfile);
void start_log_and_pid(const char *client_server, const char *pidfile);
void background(const char *pidfile);
void udhcp_logging(int level, const char *fmt, ...);
#define LOG(level, str, args...) udhcp_logging(level, str, ## args)

61
dhcpc.c
View File

@ -4,19 +4,7 @@
*
* Russ Dill <Russ.Dill@asu.edu> July 2001
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
*/
#include <sys/time.h>
@ -34,6 +22,7 @@
#include <net/if.h>
#include <errno.h>
#include "common.h"
#include "dhcpd.h"
#include "dhcpc.h"
#include "options.h"
@ -41,7 +30,6 @@
#include "clientsocket.h"
#include "script.h"
#include "socket.h"
#include "common.h"
#include "signalpipe.h"
static int state;
@ -70,11 +58,13 @@ struct client_config_t client_config = {
.hostname = NULL,
.fqdn = NULL,
.ifindex = 0,
.retries = 3,
.timeout = 3,
.arp = "\0\0\0\0\0\0", /* appease gcc-3.0 */
};
#ifndef IN_BUSYBOX
static void __attribute__ ((noreturn)) show_usage(void)
static void ATTRIBUTE_NORETURN show_usage(void)
{
printf(
"Usage: udhcpc [OPTIONS]\n\n"
@ -95,13 +85,15 @@ static void __attribute__ ((noreturn)) show_usage(void)
" -r, --request=IP IP address to request (default: none)\n"
" -s, --script=file Run file at dhcp events (default:\n"
" " DEFAULT_SCRIPT ")\n"
" -T, --timeout=seconds Try to get the lease for the amount of\n"
" seconds (default: 3)\n"
" -v, --version Display version\n"
);
exit(0);
}
#else
#define show_usage bb_show_usage
extern void show_usage(void) __attribute__ ((noreturn));
extern void show_usage(void) ATTRIBUTE_NORETURN;
#endif
@ -213,26 +205,28 @@ int main(int argc, char *argv[])
{"quit", no_argument, 0, 'q'},
{"request", required_argument, 0, 'r'},
{"script", required_argument, 0, 's'},
{"timeout", required_argument, 0, 'T'},
{"version", no_argument, 0, 'v'},
{"retries", required_argument, 0, 't'},
{0, 0, 0, 0}
};
/* get options */
while (1) {
int option_index = 0;
c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qr:s:v", arg_options, &option_index);
c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qr:s:T:t:v", arg_options, &option_index);
if (c == -1) break;
switch (c) {
case 'c':
if (no_clientid) show_usage();
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
if (client_config.clientid) free(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;
client_config.clientid[OPT_DATA] = '\0';
strncpy(client_config.clientid + OPT_DATA, optarg, len);
strncpy((char*)client_config.clientid + OPT_DATA, optarg, len);
break;
case 'C':
if (client_config.clientid) show_usage();
@ -240,11 +234,11 @@ int main(int argc, char *argv[])
break;
case 'V':
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
if (client_config.vendorclass) free(client_config.vendorclass);
free(client_config.vendorclass);
client_config.vendorclass = xmalloc(len + 2);
client_config.vendorclass[OPT_CODE] = DHCP_VENDOR;
client_config.vendorclass[OPT_LEN] = len;
strncpy(client_config.vendorclass + OPT_DATA, optarg, len);
strncpy((char*)client_config.vendorclass + OPT_DATA, optarg, len);
break;
case 'f':
client_config.foreground = 1;
@ -255,15 +249,15 @@ int main(int argc, char *argv[])
case 'h':
case 'H':
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
if (client_config.hostname) free(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);
strncpy((char*)client_config.hostname + 2, optarg, len);
break;
case 'F':
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
if (client_config.fqdn) free(client_config.fqdn);
free(client_config.fqdn);
client_config.fqdn = xmalloc(len + 5);
client_config.fqdn[OPT_CODE] = DHCP_FQDN;
client_config.fqdn[OPT_LEN] = len + 3;
@ -276,7 +270,7 @@ int main(int argc, char *argv[])
client_config.fqdn[OPT_LEN + 1] = 0x1;
client_config.fqdn[OPT_LEN + 2] = 0;
client_config.fqdn[OPT_LEN + 3] = 0;
strncpy(client_config.fqdn + 5, optarg, len);
strncpy((char*)client_config.fqdn + 5, optarg, len);
break;
case 'i':
client_config.interface = optarg;
@ -296,6 +290,12 @@ int main(int argc, char *argv[])
case 's':
client_config.script = optarg;
break;
case 'T':
client_config.timeout = atoi(optarg);
break;
case 't':
client_config.retries = atoi(optarg);
break;
case 'v':
printf("udhcpcd, version %s\n\n", VERSION);
return 0;
@ -365,14 +365,14 @@ int main(int argc, char *argv[])
/* timeout dropped to zero */
switch (state) {
case INIT_SELECTING:
if (packet_num < 3) {
if (packet_num < client_config.retries) {
if (packet_num == 0)
xid = random_xid();
/* send discover packet */
send_discover(xid, requested_ip); /* broadcast */
timeout = now + ((packet_num == 2) ? 4 : 2);
timeout = now + client_config.timeout;
packet_num++;
} else {
run_script(NULL, "leasefail");
@ -390,7 +390,7 @@ int main(int argc, char *argv[])
break;
case RENEW_REQUESTED:
case REQUESTING:
if (packet_num < 3) {
if (packet_num < client_config.retries) {
/* send request packet */
if (state == RENEW_REQUESTED)
send_renew(xid, server_addr, requested_ip); /* unicast */
@ -469,9 +469,12 @@ int main(int argc, char *argv[])
(unsigned long) packet.xid, xid);
continue;
}
/* Ignore packets that aren't for us */
if (memcmp(client_config.arp,packet.chaddr,6))
if (memcmp(packet.chaddr, client_config.arp, 6)) {
DEBUG(LOG_INFO, "packet does not have our chaddr -- ignoring");
continue;
}
if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring");

View File

@ -2,9 +2,7 @@
#ifndef _DHCPC_H
#define _DHCPC_H
#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
/* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */
/* grab define DEFAULT_SCRIPT */
#include "libbb_udhcp.h"
#define INIT_SELECTING 0
@ -30,6 +28,8 @@ struct client_config_t {
uint8_t *hostname; /* Optional hostname to use */
uint8_t *fqdn; /* Optional fully qualified domain name to use */
int ifindex; /* Index number of the interface to use */
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 */
};

View File

@ -88,7 +88,7 @@ int main(int argc, char *argv[])
else server_config.lease = LEASE_TIME;
/* Sanity check */
num_ips = ntohl(server_config.end) - ntohl(server_config.start);
num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1;
if (server_config.max_leases > num_ips) {
LOG(LOG_ERR, "max_leases value (%lu) not sane, "
"setting to %lu instead",

View File

@ -1,3 +1,7 @@
/* vi: set sw=4 ts=4: */
/*
* Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
*/
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
@ -21,7 +25,7 @@
#ifndef IN_BUSYBOX
static void __attribute__ ((noreturn)) show_usage(void)
static void ATTRIBUTE_NORETURN show_usage(void)
{
printf(
"Usage: dumpleases -f <file> -[r|a]\n\n"

51
files.c
View File

@ -15,8 +15,8 @@
#include "static_leases.h"
#include "dhcpd.h"
#include "files.h"
#include "options.h"
#include "files.h"
#include "common.h"
/*
@ -62,7 +62,7 @@ static int read_str(const char *line, void *arg)
{
char **dest = arg;
if (*dest) free(*dest);
free(*dest);
*dest = strdup(line);
return 1;
@ -93,6 +93,53 @@ static int read_yn(const char *line, void *arg)
}
/* find option 'code' in opt_list */
struct option_set *find_option(struct option_set *opt_list, char code)
{
while (opt_list && opt_list->data[OPT_CODE] < code)
opt_list = opt_list->next;
if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list;
else return NULL;
}
/* add an option to the opt_list */
static void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length)
{
struct option_set *existing, *new, **curr;
/* add it to an existing option */
if ((existing = find_option(*opt_list, option->code))) {
DEBUG(LOG_INFO, "Attaching option %s to existing member of list", option->name);
if (option->flags & OPTION_LIST) {
if (existing->data[OPT_LEN] + length <= 255) {
existing->data = realloc(existing->data,
existing->data[OPT_LEN] + length + 2);
memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
existing->data[OPT_LEN] += length;
} /* else, ignore the data, we could put this in a second option in the future */
} /* else, ignore the new data */
} else {
DEBUG(LOG_INFO, "Attaching option %s to list", option->name);
/* make a new option */
new = xmalloc(sizeof(struct option_set));
new->data = xmalloc(length + 2);
new->data[OPT_CODE] = option->code;
new->data[OPT_LEN] = length;
memcpy(new->data + 2, buffer, length);
curr = opt_list;
while (*curr && (*curr)->data[OPT_CODE] < option->code)
curr = &(*curr)->next;
new->next = *curr;
*curr = new;
}
}
/* read a dhcp option and add it to opt_list */
static int read_opt(const char *const_line, void *arg)
{

View File

@ -14,4 +14,6 @@ int read_config(const char *file);
void write_leases(void);
void read_leases(const char *file);
struct option_set *find_option(struct option_set *opt_list, char code);
#endif

View File

@ -3,14 +3,15 @@
/* bit of a hack, do this no matter what the order of the includes.
* (for busybox) */
#ifdef CONFIG_INSTALL_NO_USR
#undef DEFAULT_SCRIPT
#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
#endif
#ifndef _LIBBB_UDHCP_H
#define _LIBBB_UDHCP_H
#ifdef CONFIG_INSTALL_NO_USR
# define DEFAULT_SCRIPT "/share/udhcpc/default.script"
#else
# define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
#endif
#ifdef IN_BUSYBOX
#include "busybox.h"
@ -27,12 +28,49 @@
#define xfopen bb_xfopen
#else /* ! BB_VER */
/* make safe the exported namespace */
/* from common.h */
#define background udhcp_background
#define start_log_and_pid udhcp_start_log_and_pid
/* from script.h */
#define run_script udhcp_run_script
/* from packet.h */
#define init_header udhcp_init_header
#define get_packet udhcp_get_packet
#define checksum udhcp_checksum
#define raw_packet udhcp_raw_packet
#define kernel_packet udhcp_kernel_packet
/* from pidfile.h */
#define pidfile_acquire udhcp_pidfile_acquire
#define pidfile_write_release udhcp_pidfile_write_release
/* from options.h */
#define get_option udhcp_get_option
#define end_option udhcp_end_option
#define add_option_string udhcp_add_option_string
#define add_simple_option udhcp_add_simple_option
#define option_lengths udhcp_option_lengths
/* from socket.h */
#define listen_socket udhcp_listen_socket
#define read_interface udhcp_read_interface
/* from dhcpc.h */
#define client_config udhcp_client_config
/* from dhcpd.h */
#define server_config udhcp_server_config
#else /* ! IN_BUSYBOX */
#include <stdlib.h>
#include <stdio.h>
#include <sys/sysinfo.h>
#ifndef ATTRIBUTE_NORETURN
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
#endif /* ATTRIBUTE_NORETURN */
#ifndef ATTRIBUTE_PACKED
#define ATTRIBUTE_PACKED __attribute__ ((__packed__))
#endif /* ATTRIBUTE_PACKED */
#define TRUE 1
#define FALSE 0
@ -49,6 +87,6 @@ static inline FILE *xfopen(const char *file, const char *mode)
return fp;
}
#endif /* BB_VER */
#endif /* IN_BUSYBOX */
#endif /* _LIBBB_UDHCP_H */

View File

@ -6,10 +6,10 @@
#include <stdlib.h>
#include <string.h>
#include "dhcpd.h"
#include "files.h"
#include "options.h"
#include "common.h"
#include "dhcpd.h"
#include "options.h"
#include "files.h"
/* supported options are easily added here */
@ -149,82 +149,24 @@ int add_option_string(uint8_t *optionptr, uint8_t *string)
/* add a one to four byte option to a packet */
int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data)
{
char length = 0;
int i;
uint8_t option[2 + 4];
uint8_t *u8;
uint16_t *u16;
uint32_t *u32;
uint32_t aligned;
u8 = (uint8_t *) &aligned;
u16 = (uint16_t *) &aligned;
u32 = &aligned;
struct dhcp_option *dh;
for (i = 0; dhcp_options[i].code; i++)
if (dhcp_options[i].code == code) {
length = option_lengths[dhcp_options[i].flags & TYPE_MASK];
for (dh=dhcp_options; dh->code; dh++) {
if (dh->code == code) {
uint8_t option[6], len;
option[OPT_CODE] = code;
len = option_lengths[dh->flags & TYPE_MASK];
option[OPT_LEN] = len;
if (__BYTE_ORDER == __BIG_ENDIAN)
data <<= 8 * (4 - len);
/* This memcpy is for broken processors which can't
* handle a simple unaligned 32-bit assignment */
memcpy(&option[OPT_DATA], &data, 4);
return add_option_string(optionptr, option);
}
}
if (!length) {
DEBUG(LOG_ERR, "Could not add option 0x%02x", code);
return 0;
}
option[OPT_CODE] = code;
option[OPT_LEN] = length;
switch (length) {
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);
}
/* find option 'code' in opt_list */
struct option_set *find_option(struct option_set *opt_list, char code)
{
while (opt_list && opt_list->data[OPT_CODE] < code)
opt_list = opt_list->next;
if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list;
else return NULL;
}
/* add an option to the opt_list */
void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length)
{
struct option_set *existing, *new, **curr;
/* add it to an existing option */
if ((existing = find_option(*opt_list, option->code))) {
DEBUG(LOG_INFO, "Attaching option %s to existing member of list", option->name);
if (option->flags & OPTION_LIST) {
if (existing->data[OPT_LEN] + length <= 255) {
existing->data = realloc(existing->data,
existing->data[OPT_LEN] + length + 2);
memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
existing->data[OPT_LEN] += length;
} /* else, ignore the data, we could put this in a second option in the future */
} /* else, ignore the new data */
} else {
DEBUG(LOG_INFO, "Attaching option %s to list", option->name);
/* make a new option */
new = xmalloc(sizeof(struct option_set));
new->data = xmalloc(length + 2);
new->data[OPT_CODE] = option->code;
new->data[OPT_LEN] = length;
memcpy(new->data + 2, buffer, length);
curr = opt_list;
while (*curr && (*curr)->data[OPT_CODE] < option->code)
curr = &(*curr)->next;
new->next = *curr;
*curr = new;
}
}

View File

@ -34,7 +34,5 @@ uint8_t *get_option(struct dhcpMessage *packet, int code);
int end_option(uint8_t *optionptr);
int add_option_string(uint8_t *optionptr, uint8_t *string);
int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data);
struct option_set *find_option(struct option_set *opt_list, char code);
void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length);
#endif

View File

@ -46,12 +46,12 @@ void init_header(struct dhcpMessage *packet, char type)
/* read a packet from socket fd, return -1 on read error, -2 on packet error */
int get_packet(struct dhcpMessage *packet, int fd)
{
int bytes;
int i;
const char broken_vendors[][8] = {
static const char broken_vendors[][8] = {
"MSFT 98",
""
};
int bytes;
int i;
char unsigned *vendor;
memset(packet, 0, sizeof(struct dhcpMessage));
@ -70,7 +70,7 @@ int get_packet(struct dhcpMessage *packet, int fd)
if (packet->op == BOOTREQUEST && (vendor = get_option(packet, DHCP_VENDOR))) {
for (i = 0; broken_vendors[i][0]; i++) {
if (vendor[OPT_LEN - 2] == (uint8_t) strlen(broken_vendors[i]) &&
!strncmp(vendor, broken_vendors[i], vendor[OPT_LEN - 2])) {
!strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - 2])) {
DEBUG(LOG_INFO, "broken client (%s), forcing broadcast",
broken_vendors[i]);
packet->flags |= htons(BROADCAST_FLAG);
@ -78,7 +78,6 @@ int get_packet(struct dhcpMessage *packet, int fd)
}
}
return bytes;
}
@ -177,24 +176,30 @@ int kernel_packet(struct dhcpMessage *payload, uint32_t source_ip, int source_po
if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
return -1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1)
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) {
close(fd);
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(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
if (bind(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) {
close(fd);
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(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) {
close(fd);
return -1;
}
result = write(fd, payload, sizeof(struct dhcpMessage));
close(fd);

View File

@ -29,10 +29,11 @@
#include <sys/types.h>
#include <sys/wait.h>
#include "common.h"
#include "options.h"
#include "dhcpd.h"
#include "dhcpc.h"
#include "common.h"
#include "script.h"
/* get a rough idea of how long an option will be (rounding up...) */
static const int max_option_length[] = {

View File

@ -1,6 +1,6 @@
#ifndef _SCRIPT_H
#define _SCRIPT_H
void run_script(struct dhcpMessage *packet, const char *name);
extern void run_script(struct dhcpMessage *packet, const char *name);
#endif

View File

@ -25,10 +25,10 @@
#include <string.h>
#include <time.h>
#include "common.h"
#include "serverpacket.h"
#include "dhcpd.h"
#include "options.h"
#include "common.h"
#include "static_leases.h"
/* send a packet to giaddr using the kernel ip stack */
@ -98,9 +98,9 @@ static void add_bootp_options(struct dhcpMessage *packet)
{
packet->siaddr = server_config.siaddr;
if (server_config.sname)
strncpy(packet->sname, server_config.sname, sizeof(packet->sname) - 1);
strncpy((char*)packet->sname, server_config.sname, sizeof(packet->sname) - 1);
if (server_config.boot_file)
strncpy(packet->file, server_config.boot_file, sizeof(packet->file) - 1);
strncpy((char*)packet->file, server_config.boot_file, sizeof(packet->file) - 1);
}

View File

@ -62,6 +62,7 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp)
DEBUG(LOG_INFO, "%s (our ip) = %s", ifr.ifr_name, inet_ntoa(our_ip->sin_addr));
} else {
LOG(LOG_ERR, "SIOCGIFADDR failed, is the interface up and configured?: %m");
close(fd);
return -1;
}
}
@ -71,6 +72,7 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp)
*ifindex = ifr.ifr_ifindex;
} else {
LOG(LOG_ERR, "SIOCGIFINDEX failed!: %m");
close(fd);
return -1;
}
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0) {
@ -79,6 +81,7 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp)
arp[0], arp[1], arp[2], arp[3], arp[4], arp[5]);
} else {
LOG(LOG_ERR, "SIOCGIFHWADDR failed!: %m");
close(fd);
return -1;
}
} else {