mirror of
https://git.busybox.net/udhcp
synced 2025-05-08 22:09:45 +08:00
sync busybox and udhcp trees
This commit is contained in:
parent
8df074e69a
commit
b37705b24e
@ -23,7 +23,7 @@
|
||||
* ip - our ip
|
||||
* mac - our arp address
|
||||
* interface - interface to use
|
||||
* retn: 1 addr free
|
||||
* retn: 1 addr free
|
||||
* 0 addr used
|
||||
* -1 error
|
||||
*/
|
||||
@ -33,7 +33,7 @@ int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *mac, char *interface)
|
||||
{
|
||||
|
||||
int timeout = 2;
|
||||
int optval = 1;
|
||||
int optval = 1;
|
||||
int s; /* socket */
|
||||
int rv = 1; /* return value */
|
||||
struct sockaddr addr; /* for interface name */
|
||||
@ -101,6 +101,6 @@ int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *mac, char *interface)
|
||||
prevTime = uptime();
|
||||
}
|
||||
close(s);
|
||||
DEBUG(LOG_INFO, "%salid arp replies for this address", rv ? "No v" : "V");
|
||||
DEBUG(LOG_INFO, "%salid arp replies for this address", rv ? "No v" : "V");
|
||||
return rv;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ struct arpMsg {
|
||||
uint8_t tHaddr[6]; /* target's hardware address */
|
||||
uint8_t tInaddr[4]; /* target's IP address */
|
||||
uint8_t pad[18]; /* pad for min. Ethernet payload (60 bytes) */
|
||||
} __attribute__ ((packed));
|
||||
} ATTRIBUTE_PACKED;
|
||||
|
||||
/* function prototypes */
|
||||
int arpping(uint32_t yiaddr, uint32_t ip, uint8_t *arp, char *interface);
|
||||
|
@ -205,8 +205,8 @@ int get_raw_packet(struct dhcpMessage *payload, int fd)
|
||||
packet.ip.ihl != sizeof(packet.ip) >> 2 || packet.udp.dest != htons(CLIENT_PORT) ||
|
||||
bytes > (int) sizeof(struct udp_dhcp_packet) ||
|
||||
ntohs(packet.udp.len) != (uint16_t) (bytes - sizeof(packet.ip))) {
|
||||
DEBUG(LOG_INFO, "unrelated/bogus packet");
|
||||
return -2;
|
||||
DEBUG(LOG_INFO, "unrelated/bogus packet");
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* check IP checksum */
|
||||
|
3
common.h
3
common.h
@ -42,9 +42,8 @@ enum syslog_levels {
|
||||
long uptime(void);
|
||||
void background(const char *pidfile);
|
||||
void start_log_and_pid(const char *client_server, const char *pidfile);
|
||||
void background(const char *pidfile);
|
||||
void udhcp_logging(int level, const char *fmt, ...);
|
||||
|
||||
|
||||
#define LOG(level, str, args...) udhcp_logging(level, str, ## args)
|
||||
|
||||
#ifdef UDHCP_DEBUG
|
||||
|
67
dhcpc.c
67
dhcpc.c
@ -4,19 +4,7 @@
|
||||
*
|
||||
* Russ Dill <Russ.Dill@asu.edu> July 2001
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
* Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
@ -34,6 +22,7 @@
|
||||
#include <net/if.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "dhcpd.h"
|
||||
#include "dhcpc.h"
|
||||
#include "options.h"
|
||||
@ -41,7 +30,6 @@
|
||||
#include "clientsocket.h"
|
||||
#include "script.h"
|
||||
#include "socket.h"
|
||||
#include "common.h"
|
||||
#include "signalpipe.h"
|
||||
|
||||
static int state;
|
||||
@ -70,11 +58,13 @@ struct client_config_t client_config = {
|
||||
.hostname = NULL,
|
||||
.fqdn = NULL,
|
||||
.ifindex = 0,
|
||||
.retries = 3,
|
||||
.timeout = 3,
|
||||
.arp = "\0\0\0\0\0\0", /* appease gcc-3.0 */
|
||||
};
|
||||
|
||||
#ifndef IN_BUSYBOX
|
||||
static void __attribute__ ((noreturn)) show_usage(void)
|
||||
static void ATTRIBUTE_NORETURN show_usage(void)
|
||||
{
|
||||
printf(
|
||||
"Usage: udhcpc [OPTIONS]\n\n"
|
||||
@ -95,13 +85,15 @@ static void __attribute__ ((noreturn)) show_usage(void)
|
||||
" -r, --request=IP IP address to request (default: none)\n"
|
||||
" -s, --script=file Run file at dhcp events (default:\n"
|
||||
" " DEFAULT_SCRIPT ")\n"
|
||||
" -T, --timeout=seconds Try to get the lease for the amount of\n"
|
||||
" seconds (default: 3)\n"
|
||||
" -v, --version Display version\n"
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
#else
|
||||
#define show_usage bb_show_usage
|
||||
extern void show_usage(void) __attribute__ ((noreturn));
|
||||
extern void show_usage(void) ATTRIBUTE_NORETURN;
|
||||
#endif
|
||||
|
||||
|
||||
@ -208,31 +200,33 @@ int main(int argc, char *argv[])
|
||||
{"hostname", required_argument, 0, 'h'},
|
||||
{"fqdn", required_argument, 0, 'F'},
|
||||
{"interface", required_argument, 0, 'i'},
|
||||
{"now", no_argument, 0, 'n'},
|
||||
{"now", no_argument, 0, 'n'},
|
||||
{"pidfile", required_argument, 0, 'p'},
|
||||
{"quit", no_argument, 0, 'q'},
|
||||
{"request", required_argument, 0, 'r'},
|
||||
{"script", required_argument, 0, 's'},
|
||||
{"timeout", required_argument, 0, 'T'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{"retries", required_argument, 0, 't'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* get options */
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qr:s:v", arg_options, &option_index);
|
||||
c = getopt_long(argc, argv, "c:CV:fbH:h:F:i:np:qr:s:T:t:v", arg_options, &option_index);
|
||||
if (c == -1) break;
|
||||
|
||||
switch (c) {
|
||||
case 'c':
|
||||
if (no_clientid) show_usage();
|
||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
||||
if (client_config.clientid) free(client_config.clientid);
|
||||
free(client_config.clientid);
|
||||
client_config.clientid = xmalloc(len + 2);
|
||||
client_config.clientid[OPT_CODE] = DHCP_CLIENT_ID;
|
||||
client_config.clientid[OPT_LEN] = len;
|
||||
client_config.clientid[OPT_DATA] = '\0';
|
||||
strncpy(client_config.clientid + OPT_DATA, optarg, len);
|
||||
strncpy((char*)client_config.clientid + OPT_DATA, optarg, len);
|
||||
break;
|
||||
case 'C':
|
||||
if (client_config.clientid) show_usage();
|
||||
@ -240,11 +234,11 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
case 'V':
|
||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
||||
if (client_config.vendorclass) free(client_config.vendorclass);
|
||||
free(client_config.vendorclass);
|
||||
client_config.vendorclass = xmalloc(len + 2);
|
||||
client_config.vendorclass[OPT_CODE] = DHCP_VENDOR;
|
||||
client_config.vendorclass[OPT_LEN] = len;
|
||||
strncpy(client_config.vendorclass + OPT_DATA, optarg, len);
|
||||
strncpy((char*)client_config.vendorclass + OPT_DATA, optarg, len);
|
||||
break;
|
||||
case 'f':
|
||||
client_config.foreground = 1;
|
||||
@ -255,15 +249,15 @@ int main(int argc, char *argv[])
|
||||
case 'h':
|
||||
case 'H':
|
||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
||||
if (client_config.hostname) free(client_config.hostname);
|
||||
free(client_config.hostname);
|
||||
client_config.hostname = xmalloc(len + 2);
|
||||
client_config.hostname[OPT_CODE] = DHCP_HOST_NAME;
|
||||
client_config.hostname[OPT_LEN] = len;
|
||||
strncpy(client_config.hostname + 2, optarg, len);
|
||||
strncpy((char*)client_config.hostname + 2, optarg, len);
|
||||
break;
|
||||
case 'F':
|
||||
len = strlen(optarg) > 255 ? 255 : strlen(optarg);
|
||||
if (client_config.fqdn) free(client_config.fqdn);
|
||||
free(client_config.fqdn);
|
||||
client_config.fqdn = xmalloc(len + 5);
|
||||
client_config.fqdn[OPT_CODE] = DHCP_FQDN;
|
||||
client_config.fqdn[OPT_LEN] = len + 3;
|
||||
@ -276,7 +270,7 @@ int main(int argc, char *argv[])
|
||||
client_config.fqdn[OPT_LEN + 1] = 0x1;
|
||||
client_config.fqdn[OPT_LEN + 2] = 0;
|
||||
client_config.fqdn[OPT_LEN + 3] = 0;
|
||||
strncpy(client_config.fqdn + 5, optarg, len);
|
||||
strncpy((char*)client_config.fqdn + 5, optarg, len);
|
||||
break;
|
||||
case 'i':
|
||||
client_config.interface = optarg;
|
||||
@ -296,6 +290,12 @@ int main(int argc, char *argv[])
|
||||
case 's':
|
||||
client_config.script = optarg;
|
||||
break;
|
||||
case 'T':
|
||||
client_config.timeout = atoi(optarg);
|
||||
break;
|
||||
case 't':
|
||||
client_config.retries = atoi(optarg);
|
||||
break;
|
||||
case 'v':
|
||||
printf("udhcpcd, version %s\n\n", VERSION);
|
||||
return 0;
|
||||
@ -326,7 +326,7 @@ int main(int argc, char *argv[])
|
||||
client_config.vendorclass[OPT_CODE] = DHCP_VENDOR;
|
||||
client_config.vendorclass[OPT_LEN] = sizeof("udhcp "VERSION) - 1;
|
||||
client_config.vendorclass[OPT_DATA] = 1;
|
||||
memcpy(&client_config.vendorclass[OPT_DATA],
|
||||
memcpy(&client_config.vendorclass[OPT_DATA],
|
||||
"udhcp "VERSION, sizeof("udhcp "VERSION) - 1);
|
||||
}
|
||||
|
||||
@ -365,14 +365,14 @@ int main(int argc, char *argv[])
|
||||
/* timeout dropped to zero */
|
||||
switch (state) {
|
||||
case INIT_SELECTING:
|
||||
if (packet_num < 3) {
|
||||
if (packet_num < client_config.retries) {
|
||||
if (packet_num == 0)
|
||||
xid = random_xid();
|
||||
|
||||
/* send discover packet */
|
||||
send_discover(xid, requested_ip); /* broadcast */
|
||||
|
||||
timeout = now + ((packet_num == 2) ? 4 : 2);
|
||||
timeout = now + client_config.timeout;
|
||||
packet_num++;
|
||||
} else {
|
||||
run_script(NULL, "leasefail");
|
||||
@ -382,7 +382,7 @@ int main(int argc, char *argv[])
|
||||
} else if (client_config.abort_if_no_lease) {
|
||||
LOG(LOG_INFO, "No lease, failing.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* wait to try again */
|
||||
packet_num = 0;
|
||||
timeout = now + 60;
|
||||
@ -390,7 +390,7 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
case RENEW_REQUESTED:
|
||||
case REQUESTING:
|
||||
if (packet_num < 3) {
|
||||
if (packet_num < client_config.retries) {
|
||||
/* send request packet */
|
||||
if (state == RENEW_REQUESTED)
|
||||
send_renew(xid, server_addr, requested_ip); /* unicast */
|
||||
@ -469,9 +469,12 @@ int main(int argc, char *argv[])
|
||||
(unsigned long) packet.xid, xid);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ignore packets that aren't for us */
|
||||
if (memcmp(client_config.arp,packet.chaddr,6))
|
||||
if (memcmp(packet.chaddr, client_config.arp, 6)) {
|
||||
DEBUG(LOG_INFO, "packet does not have our chaddr -- ignoring");
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
|
||||
DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring");
|
||||
|
6
dhcpc.h
6
dhcpc.h
@ -2,9 +2,7 @@
|
||||
#ifndef _DHCPC_H
|
||||
#define _DHCPC_H
|
||||
|
||||
#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
|
||||
|
||||
/* allow libbb_udhcp.h to redefine DEFAULT_SCRIPT */
|
||||
/* grab define DEFAULT_SCRIPT */
|
||||
#include "libbb_udhcp.h"
|
||||
|
||||
#define INIT_SELECTING 0
|
||||
@ -30,6 +28,8 @@ struct client_config_t {
|
||||
uint8_t *hostname; /* Optional hostname to use */
|
||||
uint8_t *fqdn; /* Optional fully qualified domain name to use */
|
||||
int ifindex; /* Index number of the interface to use */
|
||||
int retries; /* Max number of request packets */
|
||||
int timeout; /* Number of seconds to try to get a lease */
|
||||
uint8_t arp[6]; /* Our arp address */
|
||||
};
|
||||
|
||||
|
4
dhcpd.c
4
dhcpd.c
@ -88,7 +88,7 @@ int main(int argc, char *argv[])
|
||||
else server_config.lease = LEASE_TIME;
|
||||
|
||||
/* Sanity check */
|
||||
num_ips = ntohl(server_config.end) - ntohl(server_config.start);
|
||||
num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1;
|
||||
if (server_config.max_leases > num_ips) {
|
||||
LOG(LOG_ERR, "max_leases value (%lu) not sane, "
|
||||
"setting to %lu instead",
|
||||
@ -193,7 +193,7 @@ int main(int argc, char *argv[])
|
||||
LOG(LOG_ERR, "send OFFER failed");
|
||||
}
|
||||
break;
|
||||
case DHCPREQUEST:
|
||||
case DHCPREQUEST:
|
||||
DEBUG(LOG_INFO, "received REQUEST");
|
||||
|
||||
requested = get_option(&packet, DHCP_REQUESTED_IP);
|
||||
|
22
dhcpd.h
22
dhcpd.h
@ -108,23 +108,23 @@ struct static_lease {
|
||||
|
||||
struct server_config_t {
|
||||
uint32_t server; /* Our IP, in network order */
|
||||
uint32_t start; /* Start address of leases, network order */
|
||||
uint32_t start; /* Start address of leases, network order */
|
||||
uint32_t end; /* End of leases, network order */
|
||||
struct option_set *options; /* List of DHCP options loaded from the config file */
|
||||
char *interface; /* The name of the interface to use */
|
||||
int ifindex; /* Index number of the interface to use */
|
||||
uint8_t arp[6]; /* Our arp address */
|
||||
uint8_t arp[6]; /* Our arp address */
|
||||
unsigned long lease; /* lease time in seconds (host order) */
|
||||
unsigned long max_leases; /* maximum number of leases (including reserved address) */
|
||||
char remaining; /* should the lease file be interpreted as lease time remaining, or
|
||||
* as the time the lease expires */
|
||||
unsigned long auto_time; /* how long should udhcpd wait before writing a config file.
|
||||
unsigned long max_leases; /* maximum number of leases (including reserved address) */
|
||||
char remaining; /* should the lease file be interpreted as lease time remaining, or
|
||||
* as the time the lease expires */
|
||||
unsigned long auto_time; /* how long should udhcpd wait before writing a config file.
|
||||
* if this is zero, it will only write one on SIGUSR1 */
|
||||
unsigned long decline_time; /* how long an address is reserved if a client returns a
|
||||
* decline message */
|
||||
unsigned long conflict_time; /* how long an arp conflict offender is leased for */
|
||||
unsigned long offer_time; /* how long an offered address is reserved */
|
||||
unsigned long min_lease; /* minimum lease a client can request*/
|
||||
unsigned long decline_time; /* how long an address is reserved if a client returns a
|
||||
* decline message */
|
||||
unsigned long conflict_time; /* how long an arp conflict offender is leased for */
|
||||
unsigned long offer_time; /* how long an offered address is reserved */
|
||||
unsigned long min_lease; /* minimum lease a client can request*/
|
||||
char *lease_file;
|
||||
char *pidfile;
|
||||
char *notify_file; /* What to run whenever leases are written */
|
||||
|
@ -1,3 +1,7 @@
|
||||
/* vi: set sw=4 ts=4: */
|
||||
/*
|
||||
* Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
|
||||
*/
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@ -21,7 +25,7 @@
|
||||
|
||||
|
||||
#ifndef IN_BUSYBOX
|
||||
static void __attribute__ ((noreturn)) show_usage(void)
|
||||
static void ATTRIBUTE_NORETURN show_usage(void)
|
||||
{
|
||||
printf(
|
||||
"Usage: dumpleases -f <file> -[r|a]\n\n"
|
||||
|
53
files.c
53
files.c
@ -15,8 +15,8 @@
|
||||
#include "static_leases.h"
|
||||
|
||||
#include "dhcpd.h"
|
||||
#include "files.h"
|
||||
#include "options.h"
|
||||
#include "files.h"
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
@ -62,7 +62,7 @@ static int read_str(const char *line, void *arg)
|
||||
{
|
||||
char **dest = arg;
|
||||
|
||||
if (*dest) free(*dest);
|
||||
free(*dest);
|
||||
*dest = strdup(line);
|
||||
|
||||
return 1;
|
||||
@ -93,6 +93,53 @@ static int read_yn(const char *line, void *arg)
|
||||
}
|
||||
|
||||
|
||||
/* find option 'code' in opt_list */
|
||||
struct option_set *find_option(struct option_set *opt_list, char code)
|
||||
{
|
||||
while (opt_list && opt_list->data[OPT_CODE] < code)
|
||||
opt_list = opt_list->next;
|
||||
|
||||
if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* add an option to the opt_list */
|
||||
static void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length)
|
||||
{
|
||||
struct option_set *existing, *new, **curr;
|
||||
|
||||
/* add it to an existing option */
|
||||
if ((existing = find_option(*opt_list, option->code))) {
|
||||
DEBUG(LOG_INFO, "Attaching option %s to existing member of list", option->name);
|
||||
if (option->flags & OPTION_LIST) {
|
||||
if (existing->data[OPT_LEN] + length <= 255) {
|
||||
existing->data = realloc(existing->data,
|
||||
existing->data[OPT_LEN] + length + 2);
|
||||
memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
|
||||
existing->data[OPT_LEN] += length;
|
||||
} /* else, ignore the data, we could put this in a second option in the future */
|
||||
} /* else, ignore the new data */
|
||||
} else {
|
||||
DEBUG(LOG_INFO, "Attaching option %s to list", option->name);
|
||||
|
||||
/* make a new option */
|
||||
new = xmalloc(sizeof(struct option_set));
|
||||
new->data = xmalloc(length + 2);
|
||||
new->data[OPT_CODE] = option->code;
|
||||
new->data[OPT_LEN] = length;
|
||||
memcpy(new->data + 2, buffer, length);
|
||||
|
||||
curr = opt_list;
|
||||
while (*curr && (*curr)->data[OPT_CODE] < option->code)
|
||||
curr = &(*curr)->next;
|
||||
|
||||
new->next = *curr;
|
||||
*curr = new;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* read a dhcp option and add it to opt_list */
|
||||
static int read_opt(const char *const_line, void *arg)
|
||||
{
|
||||
@ -225,7 +272,7 @@ static const struct config_keyword keywords[] = {
|
||||
{"boot_file", read_str, &(server_config.boot_file), ""},
|
||||
{"static_lease",read_staticlease, &(server_config.static_leases), ""},
|
||||
/*ADDME: static lease */
|
||||
{"", NULL, NULL, ""}
|
||||
{"", NULL, NULL, ""}
|
||||
};
|
||||
|
||||
|
||||
|
2
files.h
2
files.h
@ -14,4 +14,6 @@ int read_config(const char *file);
|
||||
void write_leases(void);
|
||||
void read_leases(const char *file);
|
||||
|
||||
struct option_set *find_option(struct option_set *opt_list, char code);
|
||||
|
||||
#endif
|
||||
|
2
leases.c
2
leases.c
@ -148,7 +148,7 @@ uint32_t find_address(int check_expired)
|
||||
(check_expired && lease_expired(lease))) &&
|
||||
|
||||
/* and it isn't on the network */
|
||||
!check_ip(ret)) {
|
||||
!check_ip(ret)) {
|
||||
return ret;
|
||||
break;
|
||||
}
|
||||
|
@ -3,14 +3,15 @@
|
||||
/* bit of a hack, do this no matter what the order of the includes.
|
||||
* (for busybox) */
|
||||
|
||||
#ifdef CONFIG_INSTALL_NO_USR
|
||||
#undef DEFAULT_SCRIPT
|
||||
#define DEFAULT_SCRIPT "/share/udhcpc/default.script"
|
||||
#endif
|
||||
|
||||
#ifndef _LIBBB_UDHCP_H
|
||||
#define _LIBBB_UDHCP_H
|
||||
|
||||
#ifdef CONFIG_INSTALL_NO_USR
|
||||
# define DEFAULT_SCRIPT "/share/udhcpc/default.script"
|
||||
#else
|
||||
# define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
|
||||
#endif
|
||||
|
||||
#ifdef IN_BUSYBOX
|
||||
#include "busybox.h"
|
||||
|
||||
@ -27,12 +28,49 @@
|
||||
|
||||
#define xfopen bb_xfopen
|
||||
|
||||
#else /* ! BB_VER */
|
||||
/* make safe the exported namespace */
|
||||
/* from common.h */
|
||||
#define background udhcp_background
|
||||
#define start_log_and_pid udhcp_start_log_and_pid
|
||||
/* from script.h */
|
||||
#define run_script udhcp_run_script
|
||||
/* from packet.h */
|
||||
#define init_header udhcp_init_header
|
||||
#define get_packet udhcp_get_packet
|
||||
#define checksum udhcp_checksum
|
||||
#define raw_packet udhcp_raw_packet
|
||||
#define kernel_packet udhcp_kernel_packet
|
||||
/* from pidfile.h */
|
||||
#define pidfile_acquire udhcp_pidfile_acquire
|
||||
#define pidfile_write_release udhcp_pidfile_write_release
|
||||
/* from options.h */
|
||||
#define get_option udhcp_get_option
|
||||
#define end_option udhcp_end_option
|
||||
#define add_option_string udhcp_add_option_string
|
||||
#define add_simple_option udhcp_add_simple_option
|
||||
#define option_lengths udhcp_option_lengths
|
||||
/* from socket.h */
|
||||
#define listen_socket udhcp_listen_socket
|
||||
#define read_interface udhcp_read_interface
|
||||
/* from dhcpc.h */
|
||||
#define client_config udhcp_client_config
|
||||
/* from dhcpd.h */
|
||||
#define server_config udhcp_server_config
|
||||
|
||||
#else /* ! IN_BUSYBOX */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
#ifndef ATTRIBUTE_NORETURN
|
||||
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||
#endif /* ATTRIBUTE_NORETURN */
|
||||
|
||||
#ifndef ATTRIBUTE_PACKED
|
||||
#define ATTRIBUTE_PACKED __attribute__ ((__packed__))
|
||||
#endif /* ATTRIBUTE_PACKED */
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
@ -49,6 +87,6 @@ static inline FILE *xfopen(const char *file, const char *mode)
|
||||
return fp;
|
||||
}
|
||||
|
||||
#endif /* BB_VER */
|
||||
#endif /* IN_BUSYBOX */
|
||||
|
||||
#endif /* _LIBBB_UDHCP_H */
|
||||
|
96
options.c
96
options.c
@ -6,10 +6,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "dhcpd.h"
|
||||
#include "files.h"
|
||||
#include "options.h"
|
||||
#include "common.h"
|
||||
#include "dhcpd.h"
|
||||
#include "options.h"
|
||||
#include "files.h"
|
||||
|
||||
|
||||
/* supported options are easily added here */
|
||||
@ -149,82 +149,24 @@ int add_option_string(uint8_t *optionptr, uint8_t *string)
|
||||
/* add a one to four byte option to a packet */
|
||||
int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data)
|
||||
{
|
||||
char length = 0;
|
||||
int i;
|
||||
uint8_t option[2 + 4];
|
||||
uint8_t *u8;
|
||||
uint16_t *u16;
|
||||
uint32_t *u32;
|
||||
uint32_t aligned;
|
||||
u8 = (uint8_t *) &aligned;
|
||||
u16 = (uint16_t *) &aligned;
|
||||
u32 = &aligned;
|
||||
struct dhcp_option *dh;
|
||||
|
||||
for (i = 0; dhcp_options[i].code; i++)
|
||||
if (dhcp_options[i].code == code) {
|
||||
length = option_lengths[dhcp_options[i].flags & TYPE_MASK];
|
||||
for (dh=dhcp_options; dh->code; dh++) {
|
||||
if (dh->code == code) {
|
||||
uint8_t option[6], len;
|
||||
|
||||
option[OPT_CODE] = code;
|
||||
len = option_lengths[dh->flags & TYPE_MASK];
|
||||
option[OPT_LEN] = len;
|
||||
if (__BYTE_ORDER == __BIG_ENDIAN)
|
||||
data <<= 8 * (4 - len);
|
||||
/* This memcpy is for broken processors which can't
|
||||
* handle a simple unaligned 32-bit assignment */
|
||||
memcpy(&option[OPT_DATA], &data, 4);
|
||||
return add_option_string(optionptr, option);
|
||||
}
|
||||
|
||||
if (!length) {
|
||||
DEBUG(LOG_ERR, "Could not add option 0x%02x", code);
|
||||
return 0;
|
||||
}
|
||||
|
||||
option[OPT_CODE] = code;
|
||||
option[OPT_LEN] = length;
|
||||
|
||||
switch (length) {
|
||||
case 1: *u8 = data; break;
|
||||
case 2: *u16 = data; break;
|
||||
case 4: *u32 = data; break;
|
||||
}
|
||||
memcpy(option + 2, &aligned, length);
|
||||
return add_option_string(optionptr, option);
|
||||
}
|
||||
|
||||
|
||||
/* find option 'code' in opt_list */
|
||||
struct option_set *find_option(struct option_set *opt_list, char code)
|
||||
{
|
||||
while (opt_list && opt_list->data[OPT_CODE] < code)
|
||||
opt_list = opt_list->next;
|
||||
|
||||
if (opt_list && opt_list->data[OPT_CODE] == code) return opt_list;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* add an option to the opt_list */
|
||||
void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length)
|
||||
{
|
||||
struct option_set *existing, *new, **curr;
|
||||
|
||||
/* add it to an existing option */
|
||||
if ((existing = find_option(*opt_list, option->code))) {
|
||||
DEBUG(LOG_INFO, "Attaching option %s to existing member of list", option->name);
|
||||
if (option->flags & OPTION_LIST) {
|
||||
if (existing->data[OPT_LEN] + length <= 255) {
|
||||
existing->data = realloc(existing->data,
|
||||
existing->data[OPT_LEN] + length + 2);
|
||||
memcpy(existing->data + existing->data[OPT_LEN] + 2, buffer, length);
|
||||
existing->data[OPT_LEN] += length;
|
||||
} /* else, ignore the data, we could put this in a second option in the future */
|
||||
} /* else, ignore the new data */
|
||||
} else {
|
||||
DEBUG(LOG_INFO, "Attaching option %s to list", option->name);
|
||||
|
||||
/* make a new option */
|
||||
new = xmalloc(sizeof(struct option_set));
|
||||
new->data = xmalloc(length + 2);
|
||||
new->data[OPT_CODE] = option->code;
|
||||
new->data[OPT_LEN] = length;
|
||||
memcpy(new->data + 2, buffer, length);
|
||||
|
||||
curr = opt_list;
|
||||
while (*curr && (*curr)->data[OPT_CODE] < option->code)
|
||||
curr = &(*curr)->next;
|
||||
|
||||
new->next = *curr;
|
||||
*curr = new;
|
||||
}
|
||||
DEBUG(LOG_ERR, "Could not add option 0x%02x", code);
|
||||
return 0;
|
||||
}
|
||||
|
@ -34,7 +34,5 @@ uint8_t *get_option(struct dhcpMessage *packet, int code);
|
||||
int end_option(uint8_t *optionptr);
|
||||
int add_option_string(uint8_t *optionptr, uint8_t *string);
|
||||
int add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data);
|
||||
struct option_set *find_option(struct option_set *opt_list, char code);
|
||||
void attach_option(struct option_set **opt_list, struct dhcp_option *option, char *buffer, int length);
|
||||
|
||||
#endif
|
||||
|
27
packet.c
27
packet.c
@ -46,12 +46,12 @@ void init_header(struct dhcpMessage *packet, char type)
|
||||
/* read a packet from socket fd, return -1 on read error, -2 on packet error */
|
||||
int get_packet(struct dhcpMessage *packet, int fd)
|
||||
{
|
||||
int bytes;
|
||||
int i;
|
||||
const char broken_vendors[][8] = {
|
||||
static const char broken_vendors[][8] = {
|
||||
"MSFT 98",
|
||||
""
|
||||
};
|
||||
int bytes;
|
||||
int i;
|
||||
char unsigned *vendor;
|
||||
|
||||
memset(packet, 0, sizeof(struct dhcpMessage));
|
||||
@ -70,14 +70,13 @@ int get_packet(struct dhcpMessage *packet, int fd)
|
||||
if (packet->op == BOOTREQUEST && (vendor = get_option(packet, DHCP_VENDOR))) {
|
||||
for (i = 0; broken_vendors[i][0]; i++) {
|
||||
if (vendor[OPT_LEN - 2] == (uint8_t) strlen(broken_vendors[i]) &&
|
||||
!strncmp(vendor, broken_vendors[i], vendor[OPT_LEN - 2])) {
|
||||
DEBUG(LOG_INFO, "broken client (%s), forcing broadcast",
|
||||
broken_vendors[i]);
|
||||
packet->flags |= htons(BROADCAST_FLAG);
|
||||
!strncmp((char*)vendor, broken_vendors[i], vendor[OPT_LEN - 2])) {
|
||||
DEBUG(LOG_INFO, "broken client (%s), forcing broadcast",
|
||||
broken_vendors[i]);
|
||||
packet->flags |= htons(BROADCAST_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return bytes;
|
||||
}
|
||||
@ -177,24 +176,30 @@ int kernel_packet(struct dhcpMessage *payload, uint32_t source_ip, int source_po
|
||||
if ((fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
|
||||
return -1;
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1)
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &n, sizeof(n)) == -1) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&client, 0, sizeof(client));
|
||||
client.sin_family = AF_INET;
|
||||
client.sin_port = htons(source_port);
|
||||
client.sin_addr.s_addr = source_ip;
|
||||
|
||||
if (bind(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
|
||||
if (bind(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&client, 0, sizeof(client));
|
||||
client.sin_family = AF_INET;
|
||||
client.sin_port = htons(dest_port);
|
||||
client.sin_addr.s_addr = dest_ip;
|
||||
|
||||
if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1)
|
||||
if (connect(fd, (struct sockaddr *)&client, sizeof(struct sockaddr)) == -1) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = write(fd, payload, sizeof(struct dhcpMessage));
|
||||
close(fd);
|
||||
|
5
script.c
5
script.c
@ -29,10 +29,11 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "options.h"
|
||||
#include "dhcpd.h"
|
||||
#include "dhcpc.h"
|
||||
#include "common.h"
|
||||
#include "script.h"
|
||||
|
||||
/* get a rough idea of how long an option will be (rounding up...) */
|
||||
static const int max_option_length[] = {
|
||||
@ -96,7 +97,7 @@ static void fill_options(char *dest, uint8_t *option, struct dhcp_option *type_p
|
||||
optlen = 4;
|
||||
case OPTION_IP: /* Works regardless of host byte order. */
|
||||
dest += sprintip(dest, "", option);
|
||||
break;
|
||||
break;
|
||||
case OPTION_BOOLEAN:
|
||||
dest += sprintf(dest, *option ? "yes" : "no");
|
||||
break;
|
||||
|
2
script.h
2
script.h
@ -1,6 +1,6 @@
|
||||
#ifndef _SCRIPT_H
|
||||
#define _SCRIPT_H
|
||||
|
||||
void run_script(struct dhcpMessage *packet, const char *name);
|
||||
extern void run_script(struct dhcpMessage *packet, const char *name);
|
||||
|
||||
#endif
|
||||
|
@ -25,10 +25,10 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "serverpacket.h"
|
||||
#include "dhcpd.h"
|
||||
#include "options.h"
|
||||
#include "common.h"
|
||||
#include "static_leases.h"
|
||||
|
||||
/* send a packet to giaddr using the kernel ip stack */
|
||||
@ -98,9 +98,9 @@ static void add_bootp_options(struct dhcpMessage *packet)
|
||||
{
|
||||
packet->siaddr = server_config.siaddr;
|
||||
if (server_config.sname)
|
||||
strncpy(packet->sname, server_config.sname, sizeof(packet->sname) - 1);
|
||||
strncpy((char*)packet->sname, server_config.sname, sizeof(packet->sname) - 1);
|
||||
if (server_config.boot_file)
|
||||
strncpy(packet->file, server_config.boot_file, sizeof(packet->file) - 1);
|
||||
strncpy((char*)packet->file, server_config.boot_file, sizeof(packet->file) - 1);
|
||||
}
|
||||
|
||||
|
||||
@ -138,11 +138,11 @@ int sendOffer(struct dhcpMessage *oldpacket)
|
||||
/* and the ip is in the lease range */
|
||||
ntohl(req_align) >= ntohl(server_config.start) &&
|
||||
ntohl(req_align) <= ntohl(server_config.end) &&
|
||||
|
||||
|
||||
!static_lease_ip && /* Check that its not a static lease */
|
||||
/* and is not already taken/offered */
|
||||
((!(lease = find_lease_by_yiaddr(req_align)) ||
|
||||
|
||||
|
||||
/* or its taken, but expired */ /* ADDME: or maybe in here */
|
||||
lease_expired(lease)))) {
|
||||
packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */
|
||||
|
3
socket.c
3
socket.c
@ -62,6 +62,7 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp)
|
||||
DEBUG(LOG_INFO, "%s (our ip) = %s", ifr.ifr_name, inet_ntoa(our_ip->sin_addr));
|
||||
} else {
|
||||
LOG(LOG_ERR, "SIOCGIFADDR failed, is the interface up and configured?: %m");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -71,6 +72,7 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp)
|
||||
*ifindex = ifr.ifr_ifindex;
|
||||
} else {
|
||||
LOG(LOG_ERR, "SIOCGIFINDEX failed!: %m");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == 0) {
|
||||
@ -79,6 +81,7 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp)
|
||||
arp[0], arp[1], arp[2], arp[3], arp[4], arp[5]);
|
||||
} else {
|
||||
LOG(LOG_ERR, "SIOCGIFHWADDR failed!: %m");
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user