Vodz, last_patch_88

This commit is contained in:
Glenn L McGrath 2003-06-10 17:22:49 +00:00
parent 6c43f743a3
commit 24833430bc
22 changed files with 211 additions and 365 deletions

View File

@ -283,12 +283,12 @@
#ifdef CONFIG_IP
APPLET(ip, ip_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif
#ifdef CONFIG_IPCALC
APPLET(ipcalc, ipcalc_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif
#ifdef CONFIG_IPADDRESS
APPLET(ipaddr, ipaddr_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif
#ifdef CONFIG_IPCALC
APPLET(ipcalc, ipcalc_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif
#ifdef CONFIG_IPLINK
APPLET(iplink, iplink_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif
@ -386,7 +386,7 @@
APPLET(more, more_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif
#ifdef CONFIG_MOUNT
APPLET(mount, mount_main, _BB_DIR_BIN, _BB_SUID_NEVER)
APPLET(mount, mount_main, _BB_DIR_BIN, _BB_SUID_MAYBE)
#endif
#ifdef CONFIG_MSH
APPLET_NOUSAGE("msh", msh_main, _BB_DIR_BIN, _BB_SUID_NEVER)
@ -428,7 +428,7 @@
APPLET(pidof, pidof_main, _BB_DIR_BIN, _BB_SUID_NEVER)
#endif
#ifdef CONFIG_PING
APPLET(ping, ping_main, _BB_DIR_BIN, _BB_SUID_NEVER)
APPLET(ping, ping_main, _BB_DIR_BIN, _BB_SUID_MAYBE)
#endif
#ifdef CONFIG_PING6
APPLET(ping6, ping6_main, _BB_DIR_BIN, _BB_SUID_NEVER)
@ -572,7 +572,7 @@
APPLET(tr, tr_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
#endif
#ifdef CONFIG_TRACEROUTE
APPLET(traceroute, traceroute_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
APPLET(traceroute, traceroute_main, _BB_DIR_USR_BIN, _BB_SUID_MAYBE)
#endif
#ifdef CONFIG_TRUE
APPLET(true, true_main, _BB_DIR_BIN, _BB_SUID_NEVER)

View File

@ -48,11 +48,14 @@ extern char *find_real_root_device_name(const char* name)
bb_perror_msg("could not open '/dev'");
else {
while((entry = readdir(dir)) != NULL) {
fileName = concat_subpath_file("/dev", entry->d_name);
if(fileName == NULL)
const char *name = entry->d_name;
/* Must skip ".." since that is "/", and so we
* would get a false positive on ".." */
if (name[0] == '.' && name[1] == '.' && !name[2])
continue;
fileName = concat_path_file("/dev", name);
/* Some char devices have the same dev_t as block
* devices, so make sure this is a block device */
if (stat(fileName, &statBuf) == 0 &&
@ -66,7 +69,7 @@ extern char *find_real_root_device_name(const char* name)
}
}
if(fileName==NULL)
fileName=bb_xstrdup("/dev/root");
fileName = bb_xstrdup("/dev/root");
return fileName;
}

View File

@ -402,6 +402,7 @@ static void parse_conf(const char *path, int flag)
/* free previous ip setup if present */
free_config_lines(&config->ip_a_d);
config->flg_deny_all = 0;
/* retain previous auth and mime config only for subdir parse */
if(flag != SUBDIR_PARSE) {
#ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH

View File

@ -9,5 +9,6 @@ Other Credits:
--------------
Moreton Bay (http://www.moretonbay.com/)
Lineo (http://opensource.lineo.com)
Vladimir Oleynik <dzo@simtrea.ru>, optimize and more integrate for busybox

View File

@ -1,3 +1,7 @@
0.9.10
Size optimization (over 3k), more busybox integration
(Vladimir Oleynik <dzo@simtreas.ru>
0.9.9 (pending)
+ Fixed a little endian problem in mton (Bastian Blank <waldi@debian.org>)
+ Fixed a arpping alignment problem (Rui He <rhe@3eti.com>)

View File

@ -33,11 +33,22 @@ CONFIG_UDHCP_SHARED=n
endif
endif
ifeq ($(CONFIG_UDHCPD), y)
CONFIG_UDHCP_LEASES_FILE=y
else
ifeq ($(CONFIG_UDHCPD), y)
CONFIG_UDHCP_LEASES_FILE=y
else
CONFIG_UDHCP_LEASES_FILE=n
endif
endif
UDHCP-y:=
UDHCP-$(CONFIG_UDHCP_SHARED) += options.c socket.c packet.c pidfile.c
UDHCP-$(CONFIG_UDHCP_SHARED) += options.c socket.c packet.c common.c
UDHCP-$(CONFIG_UDHCPC) += dhcpc.c clientpacket.c script.c
UDHCP-$(CONFIG_UDHCPD) += dhcpd.c arpping.c files.c leases.c serverpacket.c
UDHCP-$(CONFIG_DUMPLEASES) += dumpleases.c
UDHCP-$(CONFIG_UDHCP_LEASES_FILE) += leases_file.c
UDHCP_OBJS=$(patsubst %.c,$(UDHCP_DIR)%.o, $(UDHCP-y))
libraries-y+=$(UDHCP_DIR)$(UDHCP_AR)
@ -46,5 +57,5 @@ $(UDHCP_DIR)$(UDHCP_AR): $(UDHCP_OBJS)
$(AR) -ro $@ $(UDHCP_OBJS)
$(UDHCP_OBJS): %.o : %.c
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DIN_BUSYBOX -c $< -o $@
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@

View File

@ -5,22 +5,19 @@
* by Yoichi Hariguchi <yoichi@fore.com>
*/
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/if_ether.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "dhcpd.h"
#include "debug.h"
#include "arpping.h"
#include "common.h"
/* args: yiaddr - what IP to ping
* ip - our ip
@ -47,7 +44,7 @@ int arpping(u_int32_t yiaddr, u_int32_t ip, unsigned char *mac, char *interface)
if ((s = socket (PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) == -1) {
LOG(LOG_ERR, "Could not open raw socket");
LOG(LOG_ERR, bb_msg_can_not_create_raw_socket);
return -1;
}
@ -84,7 +81,7 @@ int arpping(u_int32_t yiaddr, u_int32_t ip, unsigned char *mac, char *interface)
FD_SET(s, &fdset);
tm.tv_sec = timeout;
if (select(s + 1, &fdset, (fd_set *) NULL, (fd_set *) NULL, &tm) < 0) {
DEBUG(LOG_ERR, "Error on ARPING request: %s", strerror(errno));
DEBUG(LOG_ERR, "Error on ARPING request: %m");
if (errno != EINTR) rv = 0;
} else if (FD_ISSET(s, &fdset)) {
if (recv(s, &arp, sizeof(arp), 0) < 0 ) rv = 0;

View File

@ -35,17 +35,13 @@
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "dhcpd.h"
#include "packet.h"
#include "options.h"
#include "dhcpc.h"
#include "debug.h"
#include "common.h"
/* Create a random xid */
@ -58,8 +54,7 @@ unsigned long random_xid(void)
fd = open("/dev/urandom", 0);
if (fd < 0 || read(fd, &seed, sizeof(seed)) < 0) {
LOG(LOG_WARNING, "Could not load seed from /dev/urandom: %s",
strerror(errno));
LOG(LOG_WARNING, "Could not load seed from /dev/urandom: %m");
seed = time(0);
}
if (fd >= 0) close(fd);
@ -250,4 +245,3 @@ int get_raw_packet(struct dhcpMessage *payload, int fd)
return bytes - (sizeof(packet.ip) + sizeof(packet.udp));
}

View File

@ -19,9 +19,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/file.h>
#include <unistd.h>
#include <getopt.h>
@ -40,11 +38,9 @@
#include "dhcpc.h"
#include "options.h"
#include "clientpacket.h"
#include "packet.h"
#include "script.h"
#include "socket.h"
#include "debug.h"
#include "pidfile.h"
#include "common.h"
static int state;
static unsigned long requested_ip; /* = 0 */
@ -52,7 +48,6 @@ static unsigned long server_addr;
static unsigned long timeout;
static int packet_num; /* = 0 */
static int fd = -1;
static int signal_pipe[2];
#define LISTEN_NONE 0
#define LISTEN_KERNEL 1
@ -80,34 +75,6 @@ struct client_config_t client_config = {
arp: "\0\0\0\0\0\0", /* appease gcc-3.0 */
};
#ifndef IN_BUSYBOX
static void __attribute__ ((noreturn)) bb_show_usage(void)
{
printf(
"Usage: udhcpc [OPTIONS]\n\n"
" -c, --clientid=CLIENTID Client identifier\n"
" -H, --hostname=HOSTNAME Client hostname\n"
" -h Alias for -H\n"
" -f, --foreground Do not fork after getting lease\n"
" -b, --background Fork to background if lease cannot be\n"
" immediately negotiated.\n"
" -i, --interface=INTERFACE Interface to use (default: eth0)\n"
" -n, --now Exit with failure if lease cannot be\n"
" immediately negotiated.\n"
" -p, --pidfile=file Store process ID of daemon in file\n"
" -q, --quit Quit after obtaining lease\n"
" -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\n"
);
exit(0);
}
#else
extern void bb_show_usage(void) __attribute__ ((noreturn));
#endif
/* just a little helper */
static void change_mode(int new_mode)
{
@ -172,46 +139,15 @@ static void perform_release(void)
}
/* Exit and cleanup */
static void exit_client(int retval)
static void client_background(void)
{
pidfile_delete(client_config.pidfile);
CLOSE_LOG();
exit(retval);
}
/* Signal handler */
static void signal_handler(int sig)
{
if (send(signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) {
LOG(LOG_ERR, "Could not send signal: %s",
strerror(errno));
}
}
static void background(void)
{
int pid_fd;
pid_fd = pidfile_acquire(client_config.pidfile); /* hold lock during fork. */
while (pid_fd >= 0 && pid_fd < 3) pid_fd = dup(pid_fd); /* don't let daemon close it */
if (daemon(0, 0) == -1) {
perror("fork");
exit_client(1);
}
background(client_config.pidfile);
client_config.foreground = 1; /* Do not fork again. */
client_config.background_if_no_lease = 0;
pidfile_write_release(pid_fd);
}
#ifdef COMBINED_BINARY
int udhcpc_main(int argc, char *argv[])
#else
int main(int argc, char *argv[])
#endif
{
unsigned char *temp, *message;
unsigned long t1 = 0, t2 = 0, xid = 0;
@ -222,12 +158,11 @@ int main(int argc, char *argv[])
int c, len;
struct dhcpMessage packet;
struct in_addr temp_addr;
int pid_fd;
time_t now;
int max_fd;
int sig;
static struct option arg_options[] = {
static const struct option arg_options[] = {
{"clientid", required_argument, 0, 'c'},
{"foreground", no_argument, 0, 'f'},
{"background", no_argument, 0, 'b'},
@ -240,7 +175,6 @@ int main(int argc, char *argv[])
{"request", required_argument, 0, 'r'},
{"script", required_argument, 0, 's'},
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, '?'},
{0, 0, 0, 0}
};
@ -294,23 +228,18 @@ int main(int argc, char *argv[])
client_config.script = optarg;
break;
case 'v':
printf("udhcpcd, version %s\n\n", VERSION);
exit_client(0);
bb_error_msg("version %s\n", VERSION);
return(0);
break;
default:
bb_show_usage();
}
}
OPEN_LOG("udhcpc");
LOG(LOG_INFO, "udhcp client (v%s) started", VERSION);
pid_fd = pidfile_acquire(client_config.pidfile);
pidfile_write_release(pid_fd);
start_log("client");
if (read_interface(client_config.interface, &client_config.ifindex,
NULL, client_config.arp) < 0)
exit_client(1);
return(1);
if (!client_config.clientid) {
client_config.clientid = xmalloc(6 + 3);
@ -321,10 +250,7 @@ int main(int argc, char *argv[])
}
/* setup signal handlers */
socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
signal(SIGUSR1, signal_handler);
signal(SIGUSR2, signal_handler);
signal(SIGTERM, signal_handler);
udhcp_set_signal_pipe(SIGUSR2);
state = INIT_SELECTING;
run_script(NULL, "deconfig");
@ -342,16 +268,16 @@ int main(int argc, char *argv[])
else
fd = raw_socket(client_config.ifindex);
if (fd < 0) {
LOG(LOG_ERR, "FATAL: couldn't listen on socket, %s", strerror(errno));
exit_client(0);
LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m");
return(0);
}
}
if (fd >= 0) FD_SET(fd, &rfds);
FD_SET(signal_pipe[0], &rfds);
FD_SET(udhcp_signal_pipe[0], &rfds);
if (tv.tv_sec > 0) {
DEBUG(LOG_INFO, "Waiting on select...\n");
max_fd = signal_pipe[0] > fd ? signal_pipe[0] : fd;
max_fd = udhcp_signal_pipe[0] > fd ? udhcp_signal_pipe[0] : fd;
retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
} else retval = 0; /* If we already timed out, fall through */
@ -372,10 +298,10 @@ int main(int argc, char *argv[])
} else {
if (client_config.background_if_no_lease) {
LOG(LOG_INFO, "No lease, forking to background.");
background();
client_background();
} else if (client_config.abort_if_no_lease) {
LOG(LOG_INFO, "No lease, failing.");
exit_client(1);
return(1);
}
/* wait to try again */
packet_num = 0;
@ -453,7 +379,7 @@ int main(int argc, char *argv[])
else len = get_raw_packet(&packet, fd);
if (len == -1 && errno != EINTR) {
DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
DEBUG(LOG_INFO, "error on read, %m, reopening socket");
change_mode(listen_mode); /* just close and reopen */
}
if (len < 0) continue;
@ -517,9 +443,9 @@ int main(int argc, char *argv[])
state = BOUND;
change_mode(LISTEN_NONE);
if (client_config.quit_after_lease)
exit_client(0);
return(0);
if (!client_config.foreground)
background();
client_background();
} else if (*message == DHCPNAK) {
/* return to init state */
@ -537,10 +463,9 @@ int main(int argc, char *argv[])
break;
/* case BOUND, RELEASED: - ignore all packets */
}
} else if (retval > 0 && FD_ISSET(signal_pipe[0], &rfds)) {
if (read(signal_pipe[0], &sig, sizeof(sig)) < 0) {
DEBUG(LOG_ERR, "Could not read signal: %s",
strerror(errno));
} else if (retval > 0 && FD_ISSET(udhcp_signal_pipe[0], &rfds)) {
if (read(udhcp_signal_pipe[0], &sig, sizeof(sig)) < 0) {
DEBUG(LOG_ERR, "Could not read signal: %m");
continue; /* probably just EINTR */
}
switch (sig) {
@ -552,7 +477,7 @@ int main(int argc, char *argv[])
break;
case SIGTERM:
LOG(LOG_INFO, "Received SIGTERM");
exit_client(0);
return(0);
}
} else if (retval == -1 && errno == EINTR) {
/* a signal was caught */
@ -564,4 +489,3 @@ int main(int argc, char *argv[])
}
return 0;
}

View File

@ -2,8 +2,6 @@
#ifndef _DHCPC_H
#define _DHCPC_H
#include "libbb_udhcp.h"
#define INIT_SELECTING 0
#define REQUESTING 1
#define BOUND 2

View File

@ -25,12 +25,9 @@
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <signal.h>
@ -39,47 +36,21 @@
#include <time.h>
#include <sys/time.h>
#include "debug.h"
#include "dhcpd.h"
#include "arpping.h"
#include "socket.h"
#include "options.h"
#include "files.h"
#include "leases.h"
#include "packet.h"
#include "serverpacket.h"
#include "pidfile.h"
#include "common.h"
/* globals */
struct dhcpOfferedAddr *leases;
struct server_config_t server_config;
static int signal_pipe[2];
/* Exit and cleanup */
static void exit_server(int retval)
{
pidfile_delete(server_config.pidfile);
CLOSE_LOG();
exit(retval);
}
/* Signal handler */
static void signal_handler(int sig)
{
if (send(signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) {
LOG(LOG_ERR, "Could not send signal: %s",
strerror(errno));
}
}
#ifdef COMBINED_BINARY
int udhcpd_main(int argc, char *argv[])
#else
int main(int argc, char *argv[])
#endif
{
fd_set rfds;
struct timeval tv;
@ -92,13 +63,11 @@ int main(int argc, char *argv[])
unsigned long timeout_end;
struct option_set *option;
struct dhcpOfferedAddr *lease;
int pid_fd;
int max_sock;
int sig;
unsigned long num_ips;
OPEN_LOG("udhcpd");
LOG(LOG_INFO, "udhcp server (v%s) started", VERSION);
start_log("server");
memset(&server_config, 0, sizeof(struct server_config_t));
@ -106,9 +75,6 @@ int main(int argc, char *argv[])
read_config(DHCPD_CONF_FILE);
else read_config(argv[1]);
pid_fd = pidfile_acquire(server_config.pidfile);
pidfile_write_release(pid_fd);
if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
memcpy(&server_config.lease, option->data + 2, 4);
server_config.lease = ntohl(server_config.lease);
@ -118,51 +84,43 @@ int main(int argc, char *argv[])
/* Sanity check */
num_ips = ntohl(server_config.end) - ntohl(server_config.start);
if (server_config.max_leases > num_ips) {
LOG(LOG_ERR, "max_leases value (%lu) not sane, setting to %lu instead",
LOG(LOG_ERR, "max_leases value (%lu) not sane, "
"setting to %lu instead",
server_config.max_leases, num_ips);
server_config.max_leases = num_ips;
}
leases = xmalloc(sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
memset(leases, 0, sizeof(struct dhcpOfferedAddr) * server_config.max_leases);
leases = xcalloc(sizeof(struct dhcpOfferedAddr), server_config.max_leases);
read_leases(server_config.lease_file);
if (read_interface(server_config.interface, &server_config.ifindex,
&server_config.server, server_config.arp) < 0)
exit_server(1);
return(1);
#ifndef DEBUGGING
pid_fd = pidfile_acquire(server_config.pidfile); /* hold lock during fork. */
if (daemon(0, 0) == -1) {
perror("fork");
exit_server(1);
}
pidfile_write_release(pid_fd);
#ifndef CONFIG_FEATURE_UDHCP_DEBUG
background(server_config.pidfile);
#endif
socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
signal(SIGUSR1, signal_handler);
signal(SIGTERM, signal_handler);
udhcp_set_signal_pipe(0);
timeout_end = time(0) + server_config.auto_time;
while(1) { /* loop until universe collapses */
if (server_socket < 0)
if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) {
LOG(LOG_ERR, "FATAL: couldn't create server socket, %s", strerror(errno));
exit_server(0);
LOG(LOG_ERR, "FATAL: couldn't create server socket, %m");
return(2);
}
FD_ZERO(&rfds);
FD_SET(server_socket, &rfds);
FD_SET(signal_pipe[0], &rfds);
FD_SET(udhcp_signal_pipe[0], &rfds);
if (server_config.auto_time) {
tv.tv_sec = timeout_end - time(0);
tv.tv_usec = 0;
}
if (!server_config.auto_time || tv.tv_sec > 0) {
max_sock = server_socket > signal_pipe[0] ? server_socket : signal_pipe[0];
max_sock = server_socket > udhcp_signal_pipe[0] ? server_socket : udhcp_signal_pipe[0];
retval = select(max_sock + 1, &rfds, NULL, NULL,
server_config.auto_time ? &tv : NULL);
} else retval = 0; /* If we already timed out, fall through */
@ -176,8 +134,8 @@ int main(int argc, char *argv[])
continue;
}
if (FD_ISSET(signal_pipe[0], &rfds)) {
if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
if (FD_ISSET(udhcp_signal_pipe[0], &rfds)) {
if (read(udhcp_signal_pipe[0], &sig, sizeof(sig)) < 0)
continue; /* probably just EINTR */
switch (sig) {
case SIGUSR1:
@ -188,13 +146,13 @@ int main(int argc, char *argv[])
continue;
case SIGTERM:
LOG(LOG_INFO, "Received a SIGTERM");
exit_server(0);
return(0);
}
}
if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
if (bytes == -1 && errno != EINTR) {
DEBUG(LOG_INFO, "error on read, %s, reopening socket", strerror(errno));
DEBUG(LOG_INFO, "error on read, %m, reopening socket");
close(server_socket);
server_socket = -1;
}
@ -293,4 +251,3 @@ int main(int argc, char *argv[])
return 0;
}

View File

@ -5,9 +5,7 @@
#include <netinet/ip.h>
#include <netinet/udp.h>
#include "libbb_udhcp.h"
#include "leases.h"
#include "version.h"
/************************************/
/* Defaults _you_ may want to tweak */

View File

@ -1,79 +1,55 @@
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <getopt.h>
#include <time.h>
#include "libbb_udhcp.h"
#include "leases.h"
#include "busybox.h"
#define REMAINING 0
#define ABSOLUTE 1
struct lease_t {
unsigned char chaddr[16];
u_int32_t yiaddr;
u_int32_t expires;
};
#ifdef IN_BUSYBOX
int dumpleases_main(int argc, char *argv[])
#else
int main(int argc, char *argv[])
#endif
{
FILE *fp;
int i, c, mode = REMAINING;
long expires;
char file[255] = "/var/lib/misc/udhcpd.leases";
struct lease_t lease;
const char *file = leases_file;
struct dhcpOfferedAddr lease;
struct in_addr addr;
static struct option options[] = {
static const struct option options[] = {
{"absolute", 0, 0, 'a'},
{"remaining", 0, 0, 'r'},
{"file", 1, 0, 'f'},
{"help", 0, 0, 'h'},
{0, 0, 0, 0}
};
while (1) {
int option_index = 0;
c = getopt_long(argc, argv, "arf:h", options, &option_index);
c = getopt_long(argc, argv, "arf:", options, &option_index);
if (c == -1) break;
switch (c) {
case 'a': mode = ABSOLUTE; break;
case 'r': mode = REMAINING; break;
case 'f':
strncpy(file, optarg, 255);
file[254] = '\0';
break;
case 'h':
printf("Usage: dumpleases -f <file> -[r|a]\n\n");
printf(" -f, --file=FILENAME Leases file to load\n");
printf(" -r, --remaining Interepret lease times as time remaing\n");
printf(" -a, --absolute Interepret lease times as expire time\n");
file = optarg;
break;
default:
bb_show_usage();
}
}
if (!(fp = fopen(file, "r"))) {
perror("could not open input file");
return 0;
}
fp = bb_xfopen(file, "r");
printf("Mac Address IP-Address Expires %s\n", mode == REMAINING ? "in" : "at");
/* "00:00:00:00:00:00 255.255.255.255 Wed Jun 30 21:49:08 1993" */

View File

@ -3,23 +3,20 @@
* Rewrite by Russ Dill <Russ.Dill@asu.edu> July 2001
*/
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <netdb.h>
#include "debug.h"
#include "dhcpd.h"
#include "files.h"
#include "options.h"
#include "leases.h"
#include "common.h"
/* on these functions, make sure you datatype matches */
static int read_ip(char *line, void *arg)
static int read_ip(const char *line, void *arg)
{
struct in_addr *addr = arg;
struct hostent *host;
@ -34,7 +31,7 @@ static int read_ip(char *line, void *arg)
}
static int read_str(char *line, void *arg)
static int read_str(const char *line, void *arg)
{
char **dest = arg;
@ -45,7 +42,7 @@ static int read_str(char *line, void *arg)
}
static int read_u32(char *line, void *arg)
static int read_u32(const char *line, void *arg)
{
u_int32_t *dest = arg;
char *endptr;
@ -54,7 +51,7 @@ static int read_u32(char *line, void *arg)
}
static int read_yn(char *line, void *arg)
static int read_yn(const char *line, void *arg)
{
char *dest = arg;
int retval = 1;
@ -68,32 +65,33 @@ static int read_yn(char *line, void *arg)
return retval;
}
#define READ_CONFIG_BUF_SIZE 512 /* domainname may have 254 chars */
/* read a dhcp option and add it to opt_list */
static int read_opt(char *line, void *arg)
static int read_opt(const char *const_line, void *arg)
{
char line[READ_CONFIG_BUF_SIZE];
struct option_set **opt_list = arg;
char *opt, *val, *endptr;
struct dhcp_option *option = NULL;
int retval = 0, length = 0;
char buffer[255];
struct dhcp_option *option;
int retval = 0, length;
char buffer[256]; /* max opt length */
u_int16_t result_u16;
u_int32_t result_u32;
int i;
if (!(opt = strtok(line, " \t="))) return 0;
void *valptr;
for (i = 0; options[i].code; i++)
if (!strcmp(options[i].name, opt))
option = &(options[i]);
if ((opt = strtok(strcpy(line, const_line), " \t="))) {
if (!option) return 0;
for (option = options; option->code; option++)
if (!strcasecmp(option->name, opt))
break;
do {
if (option->code) do {
val = strtok(NULL, ", \t");
if (val) {
if(!val)
break;
length = option_lengths[option->flags & TYPE_MASK];
retval = 0;
valptr = NULL;
switch (option->flags & TYPE_MASK) {
case OPTION_IP:
retval = read_ip(val, buffer);
@ -107,8 +105,9 @@ static int read_opt(char *line, void *arg)
length = strlen(val);
if (length > 0) {
if (length > 254) length = 254;
memcpy(buffer, val, length);
retval = 1;
endptr = buffer + length;
endptr[0] = 0;
valptr = val;
}
break;
case OPTION_BOOLEAN:
@ -116,41 +115,44 @@ static int read_opt(char *line, void *arg)
break;
case OPTION_U8:
buffer[0] = strtoul(val, &endptr, 0);
retval = (endptr[0] == '\0');
valptr = buffer;
break;
case OPTION_U16:
result_u16 = htons(strtoul(val, &endptr, 0));
memcpy(buffer, &result_u16, 2);
retval = (endptr[0] == '\0');
valptr = &result_u16;
break;
case OPTION_S16:
result_u16 = htons(strtol(val, &endptr, 0));
memcpy(buffer, &result_u16, 2);
retval = (endptr[0] == '\0');
valptr = &result_u16;
break;
case OPTION_U32:
result_u32 = htonl(strtoul(val, &endptr, 0));
memcpy(buffer, &result_u32, 4);
retval = (endptr[0] == '\0');
valptr = &result_u32;
break;
case OPTION_S32:
result_u32 = htonl(strtol(val, &endptr, 0));
memcpy(buffer, &result_u32, 4);
retval = (endptr[0] == '\0');
valptr = &result_u32;
break;
default:
retval = 0;
break;
}
if(valptr) {
memcpy(buffer, valptr, length);
retval = (endptr[0] == '\0');
}
if (retval)
attach_option(opt_list, option, buffer, length);
};
} while (val && retval && option->flags & OPTION_LIST);
else
break;
} while (option->flags & OPTION_LIST);
}
return retval;
}
static struct config_keyword keywords[] = {
/* keyword[14] handler variable address default[20] */
static const struct config_keyword keywords[] = {
/* keyword handler variable address default */
{"start", read_ip, &(server_config.start), "192.168.0.20"},
{"end", read_ip, &(server_config.end), "192.168.0.254"},
{"interface", read_str, &(server_config.interface), "eth0"},
@ -163,7 +165,7 @@ static struct config_keyword keywords[] = {
{"conflict_time",read_u32,&(server_config.conflict_time),"3600"},
{"offer_time", read_u32, &(server_config.offer_time), "60"},
{"min_lease", read_u32, &(server_config.min_lease), "60"},
{"lease_file", read_str, &(server_config.lease_file), "/var/lib/misc/udhcpd.leases"},
{"lease_file", read_str, &(server_config.lease_file), leases_file},
{"pidfile", read_str, &(server_config.pidfile), "/var/run/udhcpd.pid"},
{"notify_file", read_str, &(server_config.notify_file), ""},
{"siaddr", read_ip, &(server_config.siaddr), "0.0.0.0"},
@ -174,14 +176,15 @@ static struct config_keyword keywords[] = {
};
int read_config(char *file)
int read_config(const char *file)
{
FILE *in;
char buffer[80], orig[80], *token, *line;
char buffer[READ_CONFIG_BUF_SIZE], orig[READ_CONFIG_BUF_SIZE];
char *token, *line;
int i;
for (i = 0; strlen(keywords[i].keyword); i++)
if (strlen(keywords[i].def))
for (i = 0; keywords[i].keyword[0]; i++)
if (keywords[i].def[0])
keywords[i].handler(keywords[i].def, keywords[i].var);
if (!(in = fopen(file, "r"))) {
@ -189,24 +192,25 @@ int read_config(char *file)
return 0;
}
while (fgets(buffer, 80, in)) {
while (fgets(buffer, READ_CONFIG_BUF_SIZE, in)) {
if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0';
strncpy(orig, buffer, 80);
strcpy(orig, buffer);
if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0';
token = buffer + strspn(buffer, " \t");
if (*token == '\0') continue;
line = token + strcspn(token, " \t=");
if (*line == '\0') continue;
*line = '\0';
token = strtok(buffer, " \t");
if(!token)
continue;
line = strtok(NULL, "");
if(!line)
continue;
while(*line == '=' || isspace(*line))
line++;
/* eat leading whitespace */
line = line + strspn(line, " \t=");
/* eat trailing whitespace */
for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--);
line[i] = '\0';
if (*line == '\0')
continue;
for (i = 0; strlen(keywords[i].keyword); i++)
for (i = 0; keywords[i].keyword[0]; i++)
if (!strcasecmp(token, keywords[i].keyword))
if (!keywords[i].handler(line, keywords[i].var)) {
LOG(LOG_ERR, "unable to parse '%s'", orig);
@ -233,16 +237,17 @@ void write_leases(void)
}
for (i = 0; i < server_config.max_leases; i++) {
struct dhcpOfferedAddr lease;
if (leases[i].yiaddr != 0) {
if (server_config.remaining) {
if (lease_expired(&(leases[i])))
lease_time = 0;
else lease_time = leases[i].expires - curr;
} else lease_time = leases[i].expires;
lease_time = htonl(lease_time);
fwrite(leases[i].chaddr, 16, 1, fp);
fwrite(&(leases[i].yiaddr), 4, 1, fp);
fwrite(&lease_time, 4, 1, fp);
lease.expires = htonl(lease_time);
memcpy(lease.chaddr, leases[i].chaddr, 16);
lease.yiaddr = leases[i].yiaddr;
fwrite(leases, sizeof(lease), 1, fp);
}
}
fclose(fp);
@ -254,7 +259,7 @@ void write_leases(void)
}
void read_leases(char *file)
void read_leases(const char *file)
{
FILE *fp;
unsigned int i = 0;
@ -280,5 +285,3 @@ void read_leases(char *file)
DEBUG(LOG_INFO, "Read %d leases", i);
fclose(fp);
}

View File

@ -3,15 +3,15 @@
#define _FILES_H
struct config_keyword {
char keyword[14];
int (*handler)(char *line, void *var);
const char *keyword;
int (* const handler)(const char *line, void *var);
void *var;
char def[30];
const char *def;
};
int read_config(char *file);
int read_config(const char *file);
void write_leases(void);
void read_leases(char *file);
void read_leases(const char *file);
#endif

View File

@ -9,12 +9,12 @@
#include <netinet/in.h>
#include <arpa/inet.h>
#include "debug.h"
#include "dhcpd.h"
#include "files.h"
#include "options.h"
#include "leases.h"
#include "arpping.h"
#include "common.h"
unsigned char blank_chaddr[] = {[0 ... 15] = 0};
@ -102,6 +102,20 @@ struct dhcpOfferedAddr *find_lease_by_yiaddr(u_int32_t yiaddr)
}
/* check is an IP is taken, if it is, add it to the lease table */
static int check_ip(u_int32_t addr)
{
struct in_addr temp;
if (arpping(addr, server_config.server, server_config.arp, server_config.interface) == 0) {
temp.s_addr = addr;
LOG(LOG_INFO, "%s belongs to someone, reserving it for %ld seconds",
inet_ntoa(temp), server_config.conflict_time);
add_lease(blank_chaddr, addr, server_config.conflict_time);
return 1;
} else return 0;
}
/* find an assignable address, it check_expired is true, we check all the expired leases as well.
* Maybe this should try expired leases by age... */
u_int32_t find_address(int check_expired)
@ -133,19 +147,3 @@ u_int32_t find_address(int check_expired)
}
return 0;
}
/* check is an IP is taken, if it is, add it to the lease table */
int check_ip(u_int32_t addr)
{
struct in_addr temp;
if (arpping(addr, server_config.server, server_config.arp, server_config.interface) == 0) {
temp.s_addr = addr;
LOG(LOG_INFO, "%s belongs to someone, reserving it for %ld seconds",
inet_ntoa(temp), server_config.conflict_time);
add_lease(blank_chaddr, addr, server_config.conflict_time);
return 1;
} else return 0;
}

View File

@ -9,6 +9,8 @@ struct dhcpOfferedAddr {
u_int32_t expires; /* host order */
};
extern const char leases_file[];
extern unsigned char blank_chaddr[];
void clear_lease(u_int8_t *chaddr, u_int32_t yiaddr);
@ -18,7 +20,6 @@ struct dhcpOfferedAddr *oldest_expired_lease(void);
struct dhcpOfferedAddr *find_lease_by_chaddr(u_int8_t *chaddr);
struct dhcpOfferedAddr *find_lease_by_yiaddr(u_int32_t yiaddr);
u_int32_t find_address(int check_expired);
int check_ip(u_int32_t addr);
#endif

View File

@ -3,15 +3,13 @@
* Rewrite by Russ Dill <Russ.Dill@asu.edu> July 2001
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debug.h"
#include "dhcpd.h"
#include "files.h"
#include "options.h"
#include "leases.h"
#include "common.h"
/* supported options are easily added here */

View File

@ -14,10 +14,9 @@
#endif
#include <errno.h>
#include "packet.h"
#include "debug.h"
#include "dhcpd.h"
#include "options.h"
#include "common.h"
void init_header(struct dhcpMessage *packet, char type)
@ -123,7 +122,7 @@ int raw_packet(struct dhcpMessage *payload, u_int32_t source_ip, int source_port
struct udp_dhcp_packet packet;
if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
DEBUG(LOG_ERR, "socket call failed: %s", strerror(errno));
DEBUG(LOG_ERR, "socket call failed: %m");
return -1;
}
@ -136,7 +135,7 @@ int raw_packet(struct dhcpMessage *payload, u_int32_t source_ip, int source_port
dest.sll_halen = 6;
memcpy(dest.sll_addr, dest_arp, 6);
if (bind(fd, (struct sockaddr *)&dest, sizeof(struct sockaddr_ll)) < 0) {
DEBUG(LOG_ERR, "bind call failed: %s", strerror(errno));
DEBUG(LOG_ERR, "bind call failed: %m");
close(fd);
return -1;
}
@ -159,7 +158,7 @@ int raw_packet(struct dhcpMessage *payload, u_int32_t source_ip, int source_port
result = sendto(fd, &packet, sizeof(struct udp_dhcp_packet), 0, (struct sockaddr *) &dest, sizeof(dest));
if (result <= 0) {
DEBUG(LOG_ERR, "write on socket failed: %s", strerror(errno));
DEBUG(LOG_ERR, "write on socket failed: %m");
}
close(fd);
return result;
@ -200,4 +199,3 @@ int kernel_packet(struct dhcpMessage *payload, u_int32_t source_ip, int source_p
close(fd);
return result;
}

View File

@ -28,17 +28,15 @@
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include "options.h"
#include "dhcpd.h"
#include "dhcpc.h"
#include "packet.h"
#include "options.h"
#include "debug.h"
#include "common.h"
/* get a rough idea of how long an option will be (rounding up...) */
static int max_option_length[] = {
static const int max_option_length[] = {
[OPTION_IP] = sizeof("255.255.255.255 "),
[OPTION_IP_PAIR] = sizeof("255.255.255.255 ") * 2,
[OPTION_STRING] = 1,
@ -51,16 +49,21 @@ static int max_option_length[] = {
};
static int upper_length(int length, struct dhcp_option *option)
static inline int upper_length(int length, int opt_index)
{
return max_option_length[option->flags & TYPE_MASK] *
(length / option_lengths[option->flags & TYPE_MASK]);
return max_option_length[opt_index] *
(length / option_lengths[opt_index]);
}
static int sprintip(char *dest, char *pre, unsigned char *ip)
static int sprintip(char *dest, unsigned char *ip)
{
return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]);
return sprintf(dest, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
}
static void asprintip(char **dest, char *pre, unsigned char *ip)
{
asprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]);
}
@ -93,12 +96,12 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option *
for(;;) {
switch (type) {
case OPTION_IP_PAIR:
dest += sprintip(dest, "", option);
dest += sprintip(dest, option);
*(dest++) = '/';
option += 4;
optlen = 4;
case OPTION_IP: /* Works regardless of host byte order. */
dest += sprintip(dest, "", option);
dest += sprintip(dest, option);
break;
case OPTION_BOOLEAN:
dest += sprintf(dest, *option ? "yes" : "no");
@ -137,15 +140,10 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option *
static char *find_env(const char *prefix, char *defaultstr)
{
extern char **environ;
char **ptr;
const int len = strlen(prefix);
char *ptr;
for (ptr = environ; *ptr != NULL; ptr++) {
if (strncmp(prefix, *ptr, len) == 0)
return *ptr;
}
return defaultstr;
ptr = getenv(prefix);
return ptr ? ptr : defaultstr;
}
@ -174,8 +172,7 @@ static char **fill_envp(struct dhcpMessage *packet)
envp = xmalloc((num_options + 5) * sizeof(char *));
j = 0;
envp[j++] = xmalloc(sizeof("interface=") + strlen(client_config.interface));
sprintf(envp[0], "interface=%s", client_config.interface);
asprintf(&envp[j++], "interface=%s", client_config.interface);
envp[j++] = find_env("PATH", "PATH=/bin:/usr/bin:/sbin:/usr/sbin");
envp[j++] = find_env("HOME", "HOME=/");
@ -184,38 +181,33 @@ static char **fill_envp(struct dhcpMessage *packet)
return envp;
}
envp[j] = xmalloc(sizeof("ip=255.255.255.255"));
sprintip(envp[j++], "ip=", (unsigned char *) &packet->yiaddr);
asprintip(&envp[j++], "ip=", (unsigned char *) &packet->yiaddr);
for (i = 0; options[i].code; i++) {
if (!(temp = get_option(packet, options[i].code)))
continue;
envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], &options[i]) + strlen(options[i].name) + 2);
envp[j] = xmalloc(upper_length(temp[OPT_LEN - 2], options[i].flags & TYPE_MASK) + strlen(options[i].name) + 2);
fill_options(envp[j++], temp, &options[i]);
/* Fill in a subnet bits option for things like /24 */
if (options[i].code == DHCP_SUBNET) {
envp[j] = xmalloc(sizeof("mask=32"));
memcpy(&subnet, temp, 4);
sprintf(envp[j++], "mask=%d", mton(&subnet));
asprintf(&envp[j++], "mask=%d", mton(&subnet));
}
}
if (packet->siaddr) {
envp[j] = xmalloc(sizeof("siaddr=255.255.255.255"));
sprintip(envp[j++], "siaddr=", (unsigned char *) &packet->siaddr);
asprintip(&envp[j++], "siaddr=", (unsigned char *) &packet->siaddr);
}
if (!(over & FILE_FIELD) && packet->file[0]) {
/* watch out for invalid packets */
packet->file[sizeof(packet->file) - 1] = '\0';
envp[j] = xmalloc(sizeof("boot_file=") + strlen(packet->file));
sprintf(envp[j++], "boot_file=%s", packet->file);
asprintf(&envp[j++], "boot_file=%s", packet->file);
}
if (!(over & SNAME_FIELD) && packet->sname[0]) {
/* watch out for invalid packets */
packet->sname[sizeof(packet->sname) - 1] = '\0';
envp[j] = xmalloc(sizeof("sname=") + strlen(packet->sname));
sprintf(envp[j++], "sname=%s", packet->sname);
asprintf(&envp[j++], "sname=%s", packet->sname);
}
envp[j] = NULL;
return envp;
@ -245,8 +237,7 @@ void run_script(struct dhcpMessage *packet, const char *name)
DEBUG(LOG_INFO, "execle'ing %s", client_config.script);
execle(client_config.script, client_config.script,
name, NULL, envp);
LOG(LOG_ERR, "script %s failed: %s",
client_config.script, strerror(errno));
LOG(LOG_ERR, "script %s failed: %m", client_config.script);
exit(1);
}
}

View File

@ -25,11 +25,9 @@
#include <string.h>
#include <time.h>
#include "packet.h"
#include "debug.h"
#include "dhcpd.h"
#include "options.h"
#include "leases.h"
#include "common.h"
/* send a packet to giaddr using the kernel ip stack */
static int send_packet_to_relay(struct dhcpMessage *payload)
@ -258,6 +256,3 @@ int send_inform(struct dhcpMessage *oldpacket)
return send_packet(&packet, 0);
}

View File

@ -41,7 +41,7 @@
#include <linux/if_ether.h>
#endif
#include "debug.h"
#include "common.h"
int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp)
{
@ -60,8 +60,7 @@ int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char
*addr = our_ip->sin_addr.s_addr;
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?: %s",
strerror(errno));
LOG(LOG_ERR, "SIOCGIFADDR failed, is the interface up and configured?: %m");
return -1;
}
}
@ -70,7 +69,7 @@ int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char
DEBUG(LOG_INFO, "adapter index %d", ifr.ifr_ifindex);
*ifindex = ifr.ifr_ifindex;
} else {
LOG(LOG_ERR, "SIOCGIFINDEX failed!: %s", strerror(errno));
LOG(LOG_ERR, "SIOCGIFINDEX failed!: %m");
return -1;
}
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0) {
@ -78,11 +77,11 @@ int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char
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", strerror(errno));
LOG(LOG_ERR, "SIOCGIFHWADDR failed!: %m");
return -1;
}
} else {
LOG(LOG_ERR, "socket failed!: %s", strerror(errno));
LOG(LOG_ERR, "socket failed!: %m");
return -1;
}
close(fd);
@ -99,7 +98,7 @@ int listen_socket(unsigned int ip, int port, char *inf)
DEBUG(LOG_INFO, "Opening listen socket on 0x%08x:%d %s\n", ip, port, inf);
if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
DEBUG(LOG_ERR, "socket call failed: %s", strerror(errno));
DEBUG(LOG_ERR, "socket call failed: %m");
return -1;
}
@ -139,7 +138,7 @@ int raw_socket(int ifindex)
DEBUG(LOG_INFO, "Opening raw socket on ifindex %d\n", ifindex);
if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
DEBUG(LOG_ERR, "socket call failed: %s", strerror(errno));
DEBUG(LOG_ERR, "socket call failed: %m");
return -1;
}
@ -147,11 +146,10 @@ int raw_socket(int ifindex)
sock.sll_protocol = htons(ETH_P_IP);
sock.sll_ifindex = ifindex;
if (bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
DEBUG(LOG_ERR, "bind call failed: %s", strerror(errno));
DEBUG(LOG_ERR, "bind call failed: %m");
close(fd);
return -1;
}
return fd;
}