#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
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)
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)
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)
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 &&
}
}
if(fileName==NULL)
- fileName=bb_xstrdup("/dev/root");
+ fileName = bb_xstrdup("/dev/root");
return fileName;
}
/* 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
--------------
Moreton Bay (http://www.moretonbay.com/)
Lineo (http://opensource.lineo.com)
+Vladimir Oleynik <dzo@simtrea.ru>, optimize and more integrate for busybox
+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>)
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)
$(AR) -ro $@ $(UDHCP_OBJS)
$(UDHCP_OBJS): %.o : %.c
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DIN_BUSYBOX -c $< -o $@
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
* 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
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;
}
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;
#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 */
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);
return bytes - (sizeof(packet.ip) + sizeof(packet.udp));
}
-
* 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>
#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 */
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
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)
{
}
-/* Exit and cleanup */
-static void exit_client(int retval)
-{
- 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)
+static void client_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;
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'},
{"request", required_argument, 0, 'r'},
{"script", required_argument, 0, 's'},
{"version", no_argument, 0, 'v'},
- {"help", no_argument, 0, '?'},
{0, 0, 0, 0}
};
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);
}
/* 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");
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 */
} 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;
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;
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 */
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) {
break;
case SIGTERM:
LOG(LOG_INFO, "Received SIGTERM");
- exit_client(0);
+ return(0);
}
} else if (retval == -1 && errno == EINTR) {
/* a signal was caught */
}
return 0;
}
-
#ifndef _DHCPC_H
#define _DHCPC_H
-#include "libbb_udhcp.h"
-
#define INIT_SELECTING 0
#define REQUESTING 1
#define BOUND 2
#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>
#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;
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));
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);
/* 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 */
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:
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;
}
return 0;
}
-
#include <netinet/ip.h>
#include <netinet/udp.h>
-#include "libbb_udhcp.h"
#include "leases.h"
-#include "version.h"
/************************************/
/* Defaults _you_ may want to tweak */
#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" */
* 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;
}
-static int read_str(char *line, void *arg)
+static int read_str(const char *line, void *arg)
{
char **dest = 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;
}
-static int read_yn(char *line, void *arg)
+static int read_yn(const char *line, void *arg)
{
char *dest = arg;
int retval = 1;
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);
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:
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"},
{"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"},
};
-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"))) {
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);
}
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);
}
-void read_leases(char *file)
+void read_leases(const char *file)
{
FILE *fp;
unsigned int i = 0;
DEBUG(LOG_INFO, "Read %d leases", i);
fclose(fp);
}
-
-
#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
#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};
}
+/* 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)
}
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;
-}
-
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);
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
* 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 */
#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)
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;
}
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;
}
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;
close(fd);
return result;
}
-
#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,
};
-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]);
}
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");
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;
}
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=/");
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;
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);
}
}
#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)
return send_packet(&packet, 0);
}
-
-
-
#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)
{
*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;
}
}
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) {
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);
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;
}
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;
}
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;
}
-