mirror of
https://github.com/topjohnwu/ndk-busybox.git
synced 2024-12-11 21:44:38 +00:00
Finish remerging busybox udhcp and udhcp. Some cleanups as well.
This commit is contained in:
parent
e30495654d
commit
4e864a36b6
@ -9,6 +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
|
||||
Vladimir Oleynik <dzo@simtrea.ru> Size optimizations
|
||||
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
0.9.10
|
||||
Size optimization (over 3k), more busybox integration
|
||||
(Vladimir Oleynik <dzo@simtreas.ru>
|
||||
|
||||
0.9.9 (pending)
|
||||
+ Various other size optimizations (Vladimir)
|
||||
+ Change strerror(errno) to %m (Vladimir N. Oleynik <dzo@simtreas.ru>)
|
||||
+ Fixed a little endian problem in mton (Bastian Blank <waldi@debian.org>)
|
||||
+ Fixed a arpping alignment problem (Rui He <rhe@3eti.com>)
|
||||
+ Added sanity check for max_leases (udhcp bug #1285) (me)
|
||||
@ -36,7 +34,7 @@
|
||||
udhcp bug#1256
|
||||
+ Fixed reading of client id (David Poole <davep@portsmith.com>)
|
||||
+ change sys_errlist[] to strerror() as it aparently doesn't exist
|
||||
(Erik Andersen <andersen@codepoet.org>)
|
||||
(Erik Andersen <andersee@codepoet.org>)
|
||||
+ fixed get_raw_packet so it returns -2 on non fatal errors
|
||||
(Ted Lemon <Ted.Lemon@nominum.com>)
|
||||
+ Improved (hopefully) NAKing behavior (me)
|
||||
|
@ -33,22 +33,14 @@ 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 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_UDHCP_SHARED) += common.c options.c packet.c pidfile.c \
|
||||
signalpipe.c socket.c
|
||||
UDHCP-$(CONFIG_UDHCPC) += dhcpc.c clientpacket.c clientsocket.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)
|
||||
|
@ -11,19 +11,22 @@ compile time options
|
||||
|
||||
The Makefile contains three of the compile time options:
|
||||
|
||||
DEBUG: If DEBUG is defined, udhcpd will output extra debugging
|
||||
output, compile with -g, and not fork to the background when run.
|
||||
SYSLOG: If SYSLOG is defined, udhcpd will log all its messages
|
||||
syslog, otherwise, it will attempt to log them to stdout.
|
||||
UDHCP_DEBUG: If UDHCP_DEBUG is defined, udhcpd will output extra
|
||||
debugging output, compile with -g, and not fork to the background when
|
||||
run.
|
||||
UDHCP_SYSLOG: If UDHCP_SYSLOG is defined, udhcpd will log all its
|
||||
messages syslog, otherwise, it will attempt to log them to stdout.
|
||||
|
||||
COMBINED_BINARY: If COMBINED_BINARY is define, one binary, udhcpd,
|
||||
is created. If called as udhcpd, the dhcp server will be started.
|
||||
If called as udhcpc, the dhcp client will be started.
|
||||
|
||||
dhcpd.h contains the other two compile time options:
|
||||
dhcpd.h contains the other three compile time options:
|
||||
|
||||
LEASE_TIME: The default lease time if not specified in the config
|
||||
file.
|
||||
|
||||
LEASES_FILE: The default file for storing leases.
|
||||
|
||||
DHCPD_CONFIG_FILE: The defualt config file to use.
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
TODO
|
||||
----
|
||||
+ Check for valid IP, netmask, hostname, paths, strings, etc
|
||||
+ Integrade README.*'s with manpages
|
||||
+ using time(0) breaks if the system clock changes, find a portable solution
|
||||
+ make failure of reading functions revert to previous value, not the default
|
||||
@ -9,6 +10,7 @@ TODO
|
||||
+ make sure packet generation works on a wide varitey of arches
|
||||
+ Interoperability testing
|
||||
+ Hooks within the DHCP server
|
||||
* Server notification when a lease is added/removed
|
||||
+ Additional bootp support in client/server
|
||||
+ Make serverid option in server configurable
|
||||
+ Possibly add failure message to DHCP NAK
|
||||
|
@ -44,7 +44,11 @@ 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) {
|
||||
#ifdef IN_BUSYBOX
|
||||
LOG(LOG_ERR, bb_msg_can_not_create_raw_socket);
|
||||
#else
|
||||
LOG(LOG_ERR, "Could not open raw socket");
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
62
networking/udhcp/clientsocket.c
Normal file
62
networking/udhcp/clientsocket.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* clientsocket.c -- DHCP client socket creation
|
||||
*
|
||||
* udhcp client
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <features.h>
|
||||
#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
|
||||
#include <netpacket/packet.h>
|
||||
#include <net/ethernet.h>
|
||||
#else
|
||||
#include <asm/types.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <linux/if_ether.h>
|
||||
#endif
|
||||
|
||||
#include "clientsocket.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
int raw_socket(int ifindex)
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_ll sock;
|
||||
|
||||
DEBUG(LOG_INFO, "Opening raw socket on ifindex %d", ifindex);
|
||||
if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
|
||||
DEBUG(LOG_ERR, "socket call failed: %m");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sock.sll_family = AF_PACKET;
|
||||
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: %m");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
7
networking/udhcp/clientsocket.h
Normal file
7
networking/udhcp/clientsocket.h
Normal file
@ -0,0 +1,7 @@
|
||||
/* clientsocket.h */
|
||||
#ifndef _CLIENTSOCKET_H
|
||||
#define _CLIENTSOCKET_H
|
||||
|
||||
int raw_socket(int ifindex);
|
||||
|
||||
#endif
|
@ -1,8 +1,9 @@
|
||||
/* common.c
|
||||
*
|
||||
* Functions to assist in the writing and removing of pidfiles.
|
||||
* Functions for debugging and logging as well as some other
|
||||
* simple helper functions.
|
||||
*
|
||||
* Russ Dill <Russ.Dill@asu.edu> Soptember 2001
|
||||
* Russ Dill <Russ.Dill@asu.edu> 2001-2003
|
||||
* Rewrited by Vladimir Oleynik <dzo@simtreas.ru> (C) 2003
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -26,18 +27,54 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <paths.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "pidfile.h"
|
||||
|
||||
|
||||
static int daemonized;
|
||||
|
||||
#ifdef CONFIG_FEATURE_UDHCP_SYSLOG
|
||||
|
||||
/*
|
||||
* This function makes sure our first socket calls
|
||||
* aren't going to fd 1 (printf badness...) and are
|
||||
* not later closed by daemon()
|
||||
*/
|
||||
static inline void sanitize_fds(void)
|
||||
{
|
||||
int zero;
|
||||
if ((zero = open(_PATH_DEVNULL, O_RDWR, 0)) < 0) return;
|
||||
while (zero < 3) zero = dup(zero);
|
||||
close(zero);
|
||||
}
|
||||
|
||||
|
||||
void background(const char *pidfile)
|
||||
{
|
||||
#ifdef __uClinux__
|
||||
LOG(LOG_ERR, "Cannot background in uclinux (yet)");
|
||||
#else /* __uClinux__ */
|
||||
int pid_fd;
|
||||
|
||||
if (!pidfile) return;
|
||||
|
||||
pid_fd = pidfile_acquire(pidfile); /* hold lock during fork. */
|
||||
if (daemon(0, 0) == -1) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
daemonized++;
|
||||
pidfile_write_release(pid_fd);
|
||||
#endif /* __uClinux__ */
|
||||
}
|
||||
|
||||
|
||||
#ifdef UDHCP_SYSLOG
|
||||
void udhcp_logging(int level, const char *fmt, ...)
|
||||
{
|
||||
int e = errno;
|
||||
va_list p;
|
||||
va_list p2;
|
||||
|
||||
@ -46,21 +83,34 @@ void udhcp_logging(int level, const char *fmt, ...)
|
||||
if(!daemonized) {
|
||||
vprintf(fmt, p);
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
errno = e;
|
||||
}
|
||||
vsyslog(level, fmt, p2);
|
||||
va_end(p);
|
||||
}
|
||||
|
||||
void start_log(const char *client_server)
|
||||
|
||||
void start_log_and_pid(const char *client_server, const char *pidfile)
|
||||
{
|
||||
openlog(bb_applet_name, LOG_PID | LOG_CONS, LOG_LOCAL0);
|
||||
int pid_fd;
|
||||
|
||||
/* Make sure our syslog fd isn't overwritten */
|
||||
sanitize_fds();
|
||||
|
||||
/* do some other misc startup stuff while we are here to save bytes */
|
||||
pid_fd = pidfile_acquire(pidfile);
|
||||
pidfile_write_release(pid_fd);
|
||||
|
||||
/* equivelent of doing a fflush after every \n */
|
||||
setlinebuf(stdout);
|
||||
|
||||
openlog(client_server, LOG_PID | LOG_CONS, LOG_LOCAL0);
|
||||
udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
static char *syslog_level_msg[] = {
|
||||
[LOG_EMERG] = "EMERGENCY!",
|
||||
[LOG_ALERT] = "ALERT!",
|
||||
@ -71,86 +121,36 @@ static char *syslog_level_msg[] = {
|
||||
[LOG_DEBUG] = "debug"
|
||||
};
|
||||
|
||||
|
||||
void udhcp_logging(int level, const char *fmt, ...)
|
||||
{
|
||||
int e = errno;
|
||||
va_list p;
|
||||
|
||||
va_start(p, fmt);
|
||||
if(!daemonized) {
|
||||
printf("%s, ", syslog_level_msg[level]);
|
||||
errno = e;
|
||||
vprintf(fmt, p);
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
}
|
||||
va_end(p);
|
||||
}
|
||||
|
||||
void start_log(const char *client_server)
|
||||
|
||||
void start_log_and_pid(const char *client_server, const char *pidfile)
|
||||
{
|
||||
int pid_fd;
|
||||
|
||||
/* Make sure our syslog fd isn't overwritten */
|
||||
sanitize_fds();
|
||||
|
||||
/* do some other misc startup stuff while we are here to save bytes */
|
||||
pid_fd = pidfile_acquire(pidfile);
|
||||
pidfile_write_release(pid_fd);
|
||||
|
||||
/* equivelent of doing a fflush after every \n */
|
||||
setlinebuf(stdout);
|
||||
|
||||
udhcp_logging(LOG_INFO, "%s (v%s) started", client_server, VERSION);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *saved_pidfile;
|
||||
|
||||
static void exit_fun(void)
|
||||
{
|
||||
if (saved_pidfile) unlink(saved_pidfile);
|
||||
}
|
||||
|
||||
void background(const char *pidfile)
|
||||
{
|
||||
#ifdef __uClinux__
|
||||
LOG(LOG_ERR, "Cannot background in uclinux (yet)");
|
||||
#else /* __uClinux__ */
|
||||
int pid_fd = -1;
|
||||
|
||||
if (pidfile) {
|
||||
pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
|
||||
if (pid_fd < 0) {
|
||||
LOG(LOG_ERR, "Unable to open pidfile %s: %m", pidfile);
|
||||
} else {
|
||||
lockf(pid_fd, F_LOCK, 0);
|
||||
if(!saved_pidfile)
|
||||
atexit(exit_fun); /* set atexit one only */
|
||||
saved_pidfile = pidfile; /* but may be rewrite */
|
||||
}
|
||||
}
|
||||
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(1);
|
||||
}
|
||||
daemonized++;
|
||||
if (pid_fd >= 0) {
|
||||
FILE *out;
|
||||
|
||||
if ((out = fdopen(pid_fd, "w")) != NULL) {
|
||||
fprintf(out, "%d\n", getpid());
|
||||
fclose(out);
|
||||
}
|
||||
lockf(pid_fd, F_UNLCK, 0);
|
||||
close(pid_fd);
|
||||
}
|
||||
#endif /* __uClinux__ */
|
||||
}
|
||||
|
||||
/* Signal handler */
|
||||
int udhcp_signal_pipe[2];
|
||||
static void signal_handler(int sig)
|
||||
{
|
||||
if (send(udhcp_signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0) {
|
||||
LOG(LOG_ERR, "Could not send signal: %m");
|
||||
}
|
||||
}
|
||||
|
||||
void udhcp_set_signal_pipe(int sig_add)
|
||||
{
|
||||
socketpair(AF_UNIX, SOCK_STREAM, 0, udhcp_signal_pipe);
|
||||
signal(SIGUSR1, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
if(sig_add)
|
||||
signal(sig_add, signal_handler);
|
||||
}
|
||||
|
@ -18,10 +18,14 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "version.h"
|
||||
#include "busybox.h"
|
||||
#ifndef _COMMON_H
|
||||
#define _COMMON_H
|
||||
|
||||
#ifndef CONFIG_FEATURE_UDHCP_SYSLOG
|
||||
#include "version.h"
|
||||
#include "libbb_udhcp.h"
|
||||
|
||||
|
||||
#ifndef UDHCP_SYSLOG
|
||||
enum syslog_levels {
|
||||
LOG_EMERG = 0,
|
||||
LOG_ALERT,
|
||||
@ -35,18 +39,17 @@ enum syslog_levels {
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
void start_log(const char *client_server);
|
||||
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, ...);
|
||||
|
||||
extern int udhcp_signal_pipe[2];
|
||||
void udhcp_set_signal_pipe(int sig_add);
|
||||
|
||||
|
||||
|
||||
#define LOG(level, str, args...) udhcp_logging(level, str, ## args)
|
||||
|
||||
#ifdef CONFIG_FEATURE_UDHCP_DEBUG
|
||||
# define DEBUG(level, str, args...) udhcp_logging(level, str, ## args)
|
||||
#ifdef UDHCP_DEBUG
|
||||
# define DEBUG(level, str, args...) LOG(level, str, ## args)
|
||||
#else
|
||||
# define DEBUG(level, str, args...) do {;} while(0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -38,9 +38,11 @@
|
||||
#include "dhcpc.h"
|
||||
#include "options.h"
|
||||
#include "clientpacket.h"
|
||||
#include "clientsocket.h"
|
||||
#include "script.h"
|
||||
#include "socket.h"
|
||||
#include "common.h"
|
||||
#include "signalpipe.h"
|
||||
|
||||
static int state;
|
||||
static unsigned long requested_ip; /* = 0 */
|
||||
@ -54,12 +56,6 @@ static int fd = -1;
|
||||
#define LISTEN_RAW 2
|
||||
static int listen_mode;
|
||||
|
||||
#ifdef CONFIG_INSTALL_NO_USR
|
||||
#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
|
||||
#else
|
||||
#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
|
||||
#endif
|
||||
|
||||
struct client_config_t client_config = {
|
||||
/* Default options. */
|
||||
abort_if_no_lease: 0,
|
||||
@ -78,7 +74,7 @@ struct client_config_t client_config = {
|
||||
#ifndef IN_BUSYBOX
|
||||
static void __attribute__ ((noreturn)) show_usage(void)
|
||||
{
|
||||
printf(
|
||||
printf(
|
||||
"Usage: udhcpc [OPTIONS]\n\n"
|
||||
" -c, --clientid=CLIENTID Client identifier\n"
|
||||
" -H, --hostname=HOSTNAME Client hostname\n"
|
||||
@ -95,8 +91,8 @@ static void __attribute__ ((noreturn)) show_usage(void)
|
||||
" -s, --script=file Run file at dhcp events (default:\n"
|
||||
" " DEFAULT_SCRIPT ")\n"
|
||||
" -v, --version Display version\n"
|
||||
);
|
||||
exit(0);
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
#else
|
||||
#define show_usage bb_show_usage
|
||||
@ -177,7 +173,11 @@ static void client_background(void)
|
||||
}
|
||||
|
||||
|
||||
#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;
|
||||
@ -258,18 +258,20 @@ int udhcpc_main(int argc, char *argv[])
|
||||
client_config.script = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
bb_error_msg("version %s\n", VERSION);
|
||||
return(0);
|
||||
printf("udhcpcd, version %s\n\n", VERSION);
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
show_usage();
|
||||
}
|
||||
}
|
||||
|
||||
start_log("client");
|
||||
/* Start the log, sanitize fd's, and write a pid file */
|
||||
start_log_and_pid("udhcpc", client_config.pidfile);
|
||||
|
||||
if (read_interface(client_config.interface, &client_config.ifindex,
|
||||
NULL, client_config.arp) < 0)
|
||||
return(1);
|
||||
return 1;
|
||||
|
||||
if (!client_config.clientid) {
|
||||
client_config.clientid = xmalloc(6 + 3);
|
||||
@ -279,8 +281,8 @@ int udhcpc_main(int argc, char *argv[])
|
||||
memcpy(client_config.clientid + 3, client_config.arp, 6);
|
||||
}
|
||||
|
||||
/* setup signal handlers */
|
||||
udhcp_set_signal_pipe(SIGUSR2);
|
||||
/* setup the signal pipe */
|
||||
udhcp_sp_setup();
|
||||
|
||||
state = INIT_SELECTING;
|
||||
run_script(NULL, "deconfig");
|
||||
@ -290,7 +292,6 @@ int udhcpc_main(int argc, char *argv[])
|
||||
|
||||
tv.tv_sec = timeout - time(0);
|
||||
tv.tv_usec = 0;
|
||||
FD_ZERO(&rfds);
|
||||
|
||||
if (listen_mode != LISTEN_NONE && fd < 0) {
|
||||
if (listen_mode == LISTEN_KERNEL)
|
||||
@ -299,15 +300,13 @@ int udhcpc_main(int argc, char *argv[])
|
||||
fd = raw_socket(client_config.ifindex);
|
||||
if (fd < 0) {
|
||||
LOG(LOG_ERR, "FATAL: couldn't listen on socket, %m");
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (fd >= 0) FD_SET(fd, &rfds);
|
||||
FD_SET(udhcp_signal_pipe[0], &rfds);
|
||||
max_fd = udhcp_sp_fd_set(&rfds, fd);
|
||||
|
||||
if (tv.tv_sec > 0) {
|
||||
DEBUG(LOG_INFO, "Waiting on select...");
|
||||
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 */
|
||||
|
||||
@ -332,7 +331,7 @@ int udhcpc_main(int argc, char *argv[])
|
||||
client_background();
|
||||
} else if (client_config.abort_if_no_lease) {
|
||||
LOG(LOG_INFO, "No lease, failing.");
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
/* wait to try again */
|
||||
packet_num = 0;
|
||||
@ -474,7 +473,7 @@ int udhcpc_main(int argc, char *argv[])
|
||||
state = BOUND;
|
||||
change_mode(LISTEN_NONE);
|
||||
if (client_config.quit_after_lease)
|
||||
return(0);
|
||||
return 0;
|
||||
if (!client_config.foreground)
|
||||
client_background();
|
||||
|
||||
@ -494,11 +493,7 @@ int udhcpc_main(int argc, char *argv[])
|
||||
break;
|
||||
/* case BOUND, RELEASED: - ignore all packets */
|
||||
}
|
||||
} 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 */
|
||||
}
|
||||
} else if (retval > 0 && (sig = udhcp_sp_read(&rfds))) {
|
||||
switch (sig) {
|
||||
case SIGUSR1:
|
||||
perform_renew();
|
||||
@ -508,7 +503,7 @@ int udhcpc_main(int argc, char *argv[])
|
||||
break;
|
||||
case SIGTERM:
|
||||
LOG(LOG_INFO, "Received SIGTERM");
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
} else if (retval == -1 && errno == EINTR) {
|
||||
/* a signal was caught */
|
||||
|
@ -2,6 +2,11 @@
|
||||
#ifndef _DHCPC_H
|
||||
#define _DHCPC_H
|
||||
|
||||
#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
|
||||
|
||||
/* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */
|
||||
#include "libbb_udhcp.h"
|
||||
|
||||
#define INIT_SELECTING 0
|
||||
#define REQUESTING 1
|
||||
#define BOUND 2
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "files.h"
|
||||
#include "serverpacket.h"
|
||||
#include "common.h"
|
||||
#include "signalpipe.h"
|
||||
|
||||
|
||||
/* globals */
|
||||
@ -50,7 +51,11 @@ struct dhcpOfferedAddr *leases;
|
||||
struct server_config_t server_config;
|
||||
|
||||
|
||||
#ifdef COMBINED_BINARY
|
||||
int udhcpd_main(int argc, char *argv[])
|
||||
#else
|
||||
int main(int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
fd_set rfds;
|
||||
struct timeval tv;
|
||||
@ -64,16 +69,13 @@ int udhcpd_main(int argc, char *argv[])
|
||||
struct option_set *option;
|
||||
struct dhcpOfferedAddr *lease;
|
||||
int max_sock;
|
||||
int sig;
|
||||
unsigned long num_ips;
|
||||
|
||||
start_log("server");
|
||||
|
||||
memset(&server_config, 0, sizeof(struct server_config_t));
|
||||
|
||||
if (argc < 2)
|
||||
read_config(DHCPD_CONF_FILE);
|
||||
else read_config(argv[1]);
|
||||
read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);
|
||||
|
||||
/* Start the log, sanitize fd's, and write a pid file */
|
||||
start_log_and_pid("udhcpd", server_config.pidfile);
|
||||
|
||||
if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) {
|
||||
memcpy(&server_config.lease, option->data + 2, 4);
|
||||
@ -90,18 +92,19 @@ int udhcpd_main(int argc, char *argv[])
|
||||
server_config.max_leases = num_ips;
|
||||
}
|
||||
|
||||
leases = xcalloc(sizeof(struct dhcpOfferedAddr), server_config.max_leases);
|
||||
leases = xcalloc(server_config.max_leases, sizeof(struct dhcpOfferedAddr));
|
||||
read_leases(server_config.lease_file);
|
||||
|
||||
if (read_interface(server_config.interface, &server_config.ifindex,
|
||||
&server_config.server, server_config.arp) < 0)
|
||||
return(1);
|
||||
return 1;
|
||||
|
||||
#ifndef CONFIG_FEATURE_UDHCP_DEBUG
|
||||
background(server_config.pidfile);
|
||||
#ifndef UDHCP_DEBUG
|
||||
background(server_config.pidfile); /* hold lock during fork. */
|
||||
#endif
|
||||
|
||||
udhcp_set_signal_pipe(0);
|
||||
/* Setup the signal pipe */
|
||||
udhcp_sp_setup();
|
||||
|
||||
timeout_end = time(0) + server_config.auto_time;
|
||||
while(1) { /* loop until universe collapses */
|
||||
@ -109,18 +112,15 @@ int udhcpd_main(int argc, char *argv[])
|
||||
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, %m");
|
||||
return(2);
|
||||
return 2;
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(server_socket, &rfds);
|
||||
FD_SET(udhcp_signal_pipe[0], &rfds);
|
||||
max_sock = udhcp_sp_fd_set(&rfds, server_socket);
|
||||
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 > 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 */
|
||||
@ -134,20 +134,18 @@ int udhcpd_main(int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
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:
|
||||
LOG(LOG_INFO, "Received a SIGUSR1");
|
||||
write_leases();
|
||||
/* why not just reset the timeout, eh */
|
||||
timeout_end = time(0) + server_config.auto_time;
|
||||
continue;
|
||||
case SIGTERM:
|
||||
LOG(LOG_INFO, "Received a SIGTERM");
|
||||
return(0);
|
||||
}
|
||||
switch (udhcp_sp_read(&rfds)) {
|
||||
case SIGUSR1:
|
||||
LOG(LOG_INFO, "Received a SIGUSR1");
|
||||
write_leases();
|
||||
/* why not just reset the timeout, eh */
|
||||
timeout_end = time(0) + server_config.auto_time;
|
||||
continue;
|
||||
case SIGTERM:
|
||||
LOG(LOG_INFO, "Received a SIGTERM");
|
||||
return 0;
|
||||
case 0: break; /* no signal */
|
||||
default: continue; /* signal or error (probably EINTR) */
|
||||
}
|
||||
|
||||
if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */
|
||||
@ -251,3 +249,4 @@ int udhcpd_main(int argc, char *argv[])
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,13 @@
|
||||
#include "options.h"
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* Domain names may have 254 chars, and string options can be 254
|
||||
* chars long. However, 80 bytes will be enough for most, and won't
|
||||
* hog up memory. If you have a special application, change it
|
||||
*/
|
||||
#define READ_CONFIG_BUF_SIZE 80
|
||||
|
||||
/* on these functions, make sure you datatype matches */
|
||||
static int read_ip(const char *line, void *arg)
|
||||
{
|
||||
@ -66,23 +73,23 @@ static int read_yn(const 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(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;
|
||||
int retval = 0, length;
|
||||
char buffer[256]; /* max opt length */
|
||||
u_int16_t result_u16;
|
||||
u_int32_t result_u32;
|
||||
void *valptr;
|
||||
char buffer[8];
|
||||
char *line;
|
||||
u_int16_t *result_u16 = (u_int16_t *) buffer;
|
||||
u_int32_t *result_u32 = (u_int32_t *) buffer;
|
||||
|
||||
/* Cheat, the only const line we'll actually get is "" */
|
||||
line = (char *) const_line;
|
||||
if (!(opt = strtok(line, " \t="))) return 0;
|
||||
|
||||
if (!(opt = strtok(strcpy(line, const_line), " \t="))) return 0;
|
||||
|
||||
for (option = dhcp_options; option->code; option++)
|
||||
if (!strcasecmp(option->name, opt))
|
||||
break;
|
||||
@ -90,11 +97,10 @@ static int read_opt(const char *const_line, void *arg)
|
||||
if (!option->code) return 0;
|
||||
|
||||
do {
|
||||
val = strtok(NULL, ", \t");
|
||||
if(!val)
|
||||
break;
|
||||
if (!(val = strtok(NULL, ", \t"))) break;
|
||||
length = option_lengths[option->flags & TYPE_MASK];
|
||||
valptr = NULL;
|
||||
retval = 0;
|
||||
opt = buffer; /* new meaning for variable opt */
|
||||
switch (option->flags & TYPE_MASK) {
|
||||
case OPTION_IP:
|
||||
retval = read_ip(val, buffer);
|
||||
@ -108,9 +114,8 @@ static int read_opt(const char *const_line, void *arg)
|
||||
length = strlen(val);
|
||||
if (length > 0) {
|
||||
if (length > 254) length = 254;
|
||||
endptr = buffer + length;
|
||||
endptr[0] = 0;
|
||||
valptr = val;
|
||||
opt = val;
|
||||
retval = 1;
|
||||
}
|
||||
break;
|
||||
case OPTION_BOOLEAN:
|
||||
@ -118,43 +123,36 @@ static int read_opt(const char *const_line, void *arg)
|
||||
break;
|
||||
case OPTION_U8:
|
||||
buffer[0] = strtoul(val, &endptr, 0);
|
||||
valptr = buffer;
|
||||
retval = (endptr[0] == '\0');
|
||||
break;
|
||||
case OPTION_U16:
|
||||
result_u16 = htons(strtoul(val, &endptr, 0));
|
||||
valptr = &result_u16;
|
||||
*result_u16 = htons(strtoul(val, &endptr, 0));
|
||||
retval = (endptr[0] == '\0');
|
||||
break;
|
||||
case OPTION_S16:
|
||||
result_u16 = htons(strtol(val, &endptr, 0));
|
||||
valptr = &result_u16;
|
||||
*result_u16 = htons(strtol(val, &endptr, 0));
|
||||
retval = (endptr[0] == '\0');
|
||||
break;
|
||||
case OPTION_U32:
|
||||
result_u32 = htonl(strtoul(val, &endptr, 0));
|
||||
valptr = &result_u32;
|
||||
*result_u32 = htonl(strtoul(val, &endptr, 0));
|
||||
retval = (endptr[0] == '\0');
|
||||
break;
|
||||
case OPTION_S32:
|
||||
result_u32 = htonl(strtol(val, &endptr, 0));
|
||||
valptr = &result_u32;
|
||||
*result_u32 = htonl(strtol(val, &endptr, 0));
|
||||
retval = (endptr[0] == '\0');
|
||||
break;
|
||||
default:
|
||||
retval = 0;
|
||||
break;
|
||||
}
|
||||
if (valptr) {
|
||||
memcpy(buffer, valptr, length);
|
||||
retval = (endptr[0] == '\0');
|
||||
}
|
||||
if (retval)
|
||||
attach_option(opt_list, option, buffer, length);
|
||||
else
|
||||
break;
|
||||
} while (option->flags & OPTION_LIST);
|
||||
attach_option(opt_list, option, opt, length);
|
||||
} while (retval && option->flags & OPTION_LIST);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static const struct config_keyword keywords[] = {
|
||||
/* keyword handler variable address default */
|
||||
/* 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"},
|
||||
@ -167,7 +165,7 @@ static const 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), LEASES_FILE},
|
||||
{"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"},
|
||||
@ -181,9 +179,11 @@ static const struct config_keyword keywords[] = {
|
||||
int read_config(const char *file)
|
||||
{
|
||||
FILE *in;
|
||||
char buffer[READ_CONFIG_BUF_SIZE], orig[READ_CONFIG_BUF_SIZE];
|
||||
char *token, *line;
|
||||
int i;
|
||||
char buffer[READ_CONFIG_BUF_SIZE], *token, *line;
|
||||
#ifdef UDHCP_DEBUG
|
||||
char orig[READ_CONFIG_BUF_SIZE];
|
||||
#endif
|
||||
int i, lm = 0;
|
||||
|
||||
for (i = 0; keywords[i].keyword[0]; i++)
|
||||
if (keywords[i].def[0])
|
||||
@ -195,27 +195,27 @@ int read_config(const char *file)
|
||||
}
|
||||
|
||||
while (fgets(buffer, READ_CONFIG_BUF_SIZE, in)) {
|
||||
lm++;
|
||||
if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0';
|
||||
#ifdef UDHCP_DEBUG
|
||||
strcpy(orig, buffer);
|
||||
#endif
|
||||
if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0';
|
||||
token = strtok(buffer, " \t");
|
||||
if(!token)
|
||||
continue;
|
||||
line = strtok(NULL, "");
|
||||
if(!line)
|
||||
continue;
|
||||
while(*line == '=' || isspace(*line))
|
||||
line++;
|
||||
|
||||
if (!(token = strtok(buffer, " \t"))) continue;
|
||||
if (!(line = strtok(NULL, ""))) continue;
|
||||
|
||||
/* 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; 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);
|
||||
LOG(LOG_ERR, "Failure parsing line %d of %s", lm, file);
|
||||
DEBUG(LOG_ERR, "unable to parse '%s'", orig);
|
||||
/* reset back to the default value */
|
||||
keywords[i].handler(keywords[i].def, keywords[i].var);
|
||||
}
|
||||
|
@ -117,6 +117,7 @@ static int check_ip(u_int32_t addr)
|
||||
} 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)
|
||||
|
@ -9,8 +9,6 @@ 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);
|
||||
|
@ -1 +0,0 @@
|
||||
const char leases_file[] = "/var/lib/misc/udhcpd.leases";
|
@ -1,5 +1,13 @@
|
||||
/* libbb_udhcp.h - busybox compatability wrapper */
|
||||
|
||||
/* bit of a hack, do this no matter what the order of the includes.
|
||||
* (for busybox) */
|
||||
|
||||
#ifdef CONFIG_INSTALL_NO_USR
|
||||
#undef DEFUALT_SCRIPT
|
||||
#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
|
||||
#endif
|
||||
|
||||
#ifndef _LIBBB_UDHCP_H
|
||||
#define _LIBBB_UDHCP_H
|
||||
|
||||
@ -7,22 +15,16 @@
|
||||
#include "busybox.h"
|
||||
|
||||
#ifdef CONFIG_FEATURE_UDHCP_SYSLOG
|
||||
#define SYSLOG
|
||||
#define UDHCP_SYSLOG
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FEATURE_UDHCP_DEBUG
|
||||
#define DEBUG
|
||||
#define UDHCP_DEBUG
|
||||
#endif
|
||||
|
||||
#define COMBINED_BINARY
|
||||
#include "version.h"
|
||||
|
||||
#ifdef CONFIG_INSTALL_NO_USR
|
||||
#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
|
||||
#else
|
||||
#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
|
||||
#endif
|
||||
|
||||
#define xfopen bb_xfopen
|
||||
|
||||
#else /* ! BB_VER */
|
||||
@ -36,8 +38,6 @@
|
||||
#define xmalloc malloc
|
||||
#define xcalloc calloc
|
||||
|
||||
#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
|
||||
|
||||
static inline FILE *xfopen(const char *file, const char *mode)
|
||||
{
|
||||
FILE *fp;
|
||||
|
75
networking/udhcp/pidfile.c
Normal file
75
networking/udhcp/pidfile.c
Normal file
@ -0,0 +1,75 @@
|
||||
/* pidfile.c
|
||||
*
|
||||
* Functions to assist in the writing and removing of pidfiles.
|
||||
*
|
||||
* Russ Dill <Russ.Dill@asu.edu> Soptember 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "pidfile.h"
|
||||
#include "common.h"
|
||||
|
||||
static char *saved_pidfile;
|
||||
|
||||
static void pidfile_delete(void)
|
||||
{
|
||||
if (saved_pidfile) unlink(saved_pidfile);
|
||||
}
|
||||
|
||||
|
||||
int pidfile_acquire(const char *pidfile)
|
||||
{
|
||||
int pid_fd;
|
||||
if (!pidfile) return -1;
|
||||
|
||||
pid_fd = open(pidfile, O_CREAT | O_WRONLY, 0644);
|
||||
if (pid_fd < 0) {
|
||||
LOG(LOG_ERR, "Unable to open pidfile %s: %m\n", pidfile);
|
||||
} else {
|
||||
lockf(pid_fd, F_LOCK, 0);
|
||||
if (!saved_pidfile)
|
||||
atexit(pidfile_delete);
|
||||
saved_pidfile = (char *) pidfile;
|
||||
}
|
||||
|
||||
return pid_fd;
|
||||
}
|
||||
|
||||
|
||||
void pidfile_write_release(int pid_fd)
|
||||
{
|
||||
FILE *out;
|
||||
|
||||
if (pid_fd < 0) return;
|
||||
|
||||
if ((out = fdopen(pid_fd, "w")) != NULL) {
|
||||
fprintf(out, "%d\n", getpid());
|
||||
fclose(out);
|
||||
}
|
||||
lockf(pid_fd, F_UNLCK, 0);
|
||||
close(pid_fd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
25
networking/udhcp/pidfile.h
Normal file
25
networking/udhcp/pidfile.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* pidfile.h
|
||||
*
|
||||
* Functions to assist in the writing and removing of pidfiles.
|
||||
*
|
||||
* Russ Dill <Russ.Dill@asu.edu> Soptember 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.
|
||||
*/
|
||||
|
||||
|
||||
int pidfile_acquire(const char *pidfile);
|
||||
void pidfile_write_release(int pid_fd);
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "options.h"
|
||||
#include "dhcpd.h"
|
||||
#include "dhcpc.h"
|
||||
#include "script.h"
|
||||
#include "common.h"
|
||||
|
||||
/* get a rough idea of how long an option will be (rounding up...) */
|
||||
@ -56,14 +55,9 @@ static inline int upper_length(int length, int opt_index)
|
||||
}
|
||||
|
||||
|
||||
static int sprintip(char *dest, unsigned char *ip)
|
||||
static int sprintip(char *dest, char *pre, unsigned char *ip)
|
||||
{
|
||||
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]);
|
||||
return sprintf(dest, "%s%d.%d.%d.%d", pre, ip[0], ip[1], ip[2], ip[3]);
|
||||
}
|
||||
|
||||
|
||||
@ -96,12 +90,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");
|
||||
@ -138,15 +132,6 @@ static void fill_options(char *dest, unsigned char *option, struct dhcp_option *
|
||||
}
|
||||
|
||||
|
||||
static char *find_env(const char *prefix, char *defaultstr)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = getenv(prefix);
|
||||
return ptr ? ptr : defaultstr;
|
||||
}
|
||||
|
||||
|
||||
/* put all the paramaters into an environment */
|
||||
static char **fill_envp(struct dhcpMessage *packet)
|
||||
{
|
||||
@ -167,21 +152,20 @@ static char **fill_envp(struct dhcpMessage *packet)
|
||||
if ((temp = get_option(packet, DHCP_OPTION_OVER)))
|
||||
over = *temp;
|
||||
if (!(over & FILE_FIELD) && packet->file[0]) num_options++;
|
||||
if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++;
|
||||
if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++;
|
||||
}
|
||||
|
||||
envp = xmalloc((num_options + 5) * sizeof(char *));
|
||||
envp = xcalloc(sizeof(char *), num_options + 5);
|
||||
j = 0;
|
||||
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=/");
|
||||
asprintf(&envp[j++], "%s=%s", "PATH",
|
||||
getenv("PATH") ? : "/bin:/usr/bin:/sbin:/usr/sbin");
|
||||
asprintf(&envp[j++], "%s=%s", "HOME", getenv("HOME") ? : "/");
|
||||
|
||||
if (packet == NULL) {
|
||||
envp[j++] = NULL;
|
||||
return envp;
|
||||
}
|
||||
if (packet == NULL) return envp;
|
||||
|
||||
asprintip(&envp[j++], "ip=", (unsigned char *) &packet->yiaddr);
|
||||
envp[j] = xmalloc(sizeof("ip=255.255.255.255"));
|
||||
sprintip(envp[j++], "ip=", (unsigned char *) &packet->yiaddr);
|
||||
|
||||
|
||||
for (i = 0; dhcp_options[i].code; i++) {
|
||||
@ -198,7 +182,8 @@ static char **fill_envp(struct dhcpMessage *packet)
|
||||
}
|
||||
}
|
||||
if (packet->siaddr) {
|
||||
asprintip(&envp[j++], "siaddr=", (unsigned char *) &packet->siaddr);
|
||||
envp[j] = xmalloc(sizeof("siaddr=255.255.255.255"));
|
||||
sprintip(envp[j++], "siaddr=", (unsigned char *) &packet->siaddr);
|
||||
}
|
||||
if (!(over & FILE_FIELD) && packet->file[0]) {
|
||||
/* watch out for invalid packets */
|
||||
@ -210,7 +195,6 @@ static char **fill_envp(struct dhcpMessage *packet)
|
||||
packet->sname[sizeof(packet->sname) - 1] = '\0';
|
||||
asprintf(&envp[j++], "sname=%s", packet->sname);
|
||||
}
|
||||
envp[j] = NULL;
|
||||
return envp;
|
||||
}
|
||||
|
||||
|
78
networking/udhcp/signalpipe.c
Normal file
78
networking/udhcp/signalpipe.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* signalpipe.c
|
||||
*
|
||||
* Signal pipe infastructure. A reliable way of delivering signals.
|
||||
*
|
||||
* Russ Dill <Russ.Dill@asu.edu> Decemeber 2003
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
|
||||
#include "signalpipe.h"
|
||||
#include "common.h"
|
||||
|
||||
static int signal_pipe[2];
|
||||
|
||||
static void signal_handler(int sig)
|
||||
{
|
||||
if (send(signal_pipe[1], &sig, sizeof(sig), MSG_DONTWAIT) < 0)
|
||||
DEBUG(LOG_ERR, "Could not send signal: %m");
|
||||
}
|
||||
|
||||
|
||||
/* Call this before doing anything else. Sets up the socket pair
|
||||
* and installs the signal handler */
|
||||
void udhcp_sp_setup(void)
|
||||
{
|
||||
socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe);
|
||||
signal(SIGUSR1, signal_handler);
|
||||
signal(SIGUSR2, signal_handler);
|
||||
signal(SIGTERM, signal_handler);
|
||||
}
|
||||
|
||||
|
||||
/* Quick little function to setup the rfds. Will return the
|
||||
* max_fd for use with select. Limited in that you can only pass
|
||||
* one extra fd */
|
||||
int udhcp_sp_fd_set(fd_set *rfds, int extra_fd)
|
||||
{
|
||||
FD_ZERO(rfds);
|
||||
FD_SET(signal_pipe[0], rfds);
|
||||
if (extra_fd >= 0) FD_SET(extra_fd, rfds);
|
||||
return signal_pipe[0] > extra_fd ? signal_pipe[0] : extra_fd;
|
||||
}
|
||||
|
||||
|
||||
/* Read a signal from the signal pipe. Returns 0 if there is
|
||||
* no signal, -1 on error (and sets errno appropriately), and
|
||||
* your signal on success */
|
||||
int udhcp_sp_read(fd_set *rfds)
|
||||
{
|
||||
int sig;
|
||||
|
||||
if (!FD_ISSET(signal_pipe[0], rfds))
|
||||
return 0;
|
||||
|
||||
if (read(signal_pipe[0], &sig, sizeof(sig)) < 0)
|
||||
return -1;
|
||||
|
||||
return sig;
|
||||
}
|
22
networking/udhcp/signalpipe.h
Normal file
22
networking/udhcp/signalpipe.h
Normal file
@ -0,0 +1,22 @@
|
||||
/* signalpipe.h
|
||||
*
|
||||
* Russ Dill <Russ.Dill@asu.edu> December 2003
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
void udhcp_sp_setup(void);
|
||||
int udhcp_sp_fd_set(fd_set *rfds, int extra_fd);
|
||||
int udhcp_sp_read(fd_set *rfds);
|
@ -130,29 +130,3 @@ int listen_socket(unsigned int ip, int port, char *inf)
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
int raw_socket(int ifindex)
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_ll sock;
|
||||
|
||||
DEBUG(LOG_INFO, "Opening raw socket on ifindex %d", ifindex);
|
||||
if ((fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) {
|
||||
DEBUG(LOG_ERR, "socket call failed: %m");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fd >= 0 && fd < 3) fd = dup(fd); /* don't let daemon close fds on us */
|
||||
|
||||
sock.sll_family = AF_PACKET;
|
||||
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: %m");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
@ -4,6 +4,5 @@
|
||||
|
||||
int read_interface(char *interface, int *ifindex, u_int32_t *addr, unsigned char *arp);
|
||||
int listen_socket(unsigned int ip, int port, char *inf);
|
||||
int raw_socket(int ifindex);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user