BOOTP Support in BusyBox udhcp Client
Grant Erickson
gerickson at nuovations.com
Tue Apr 8 01:17:23 UTC 2008
On 4/3/08 9:10 AM, Grant Erickson wrote:
> Sometime ago, in December 2002 to be exact, there was discussion of a patch
> submitted by Magnus Damm integrating BOOTP support into the udhcp client:
>
> http://www.busybox.net/lists/udhcp/2002-December/000002.html
>
> However, it looks like as of BusyBox-1.9.1, this patch never made it into the
> mainline code base. Do you have any additional insight or background on what
> happened with the patch in the intervening five years?
For those interested, I've adapted the aforementioned patch to
BusyBox-1.9.1:
----
diff -aruN busybox-1.9.1/include/usage.h busybox-1.9.1.N/include/usage.h
--- busybox-1.9.1/include/usage.h 2008-02-12 08:03:10.000000000 -0800
+++ busybox-1.9.1.N/include/usage.h 2008-04-07 10:33:25.000000000 -0700
@@ -3839,13 +3839,14 @@
"Adjust filesystem options on ext[23] filesystems"
#define udhcpc_trivial_usage \
- "[-Cfbnqtv] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \
+ "[-BCfbnqtv] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \
" [-p pidfile] [-r IP] [-s script] [-O dhcp-option]..."
#define udhcpc_full_usage \
USE_GETOPT_LONG( \
" -V,--vendorclass=CLASSID Vendor class identifier" \
"\n -i,--interface=INTERFACE Interface to use (default eth0)"
\
"\n -H,-h,--hostname=HOSTNAME Client hostname" \
+ "\n -B,--bootp Operate as bootp-only client" \
"\n -c,--clientid=CLIENTID Client identifier" \
"\n -C,--clientid-none Suppress default client identifier" \
"\n -p,--pidfile=file Create pidfile" \
diff -aruN busybox-1.9.1/networking/udhcp/clientpacket.c
busybox-1.9.1.N/networking/udhcp/clientpacket.c
--- busybox-1.9.1/networking/udhcp/clientpacket.c 2008-02-12
08:03:00.000000000 -0800
+++ busybox-1.9.1.N/networking/udhcp/clientpacket.c 2008-04-07
10:33:25.000000000 -0700
@@ -38,11 +38,11 @@
/* initialize a packet with the proper defaults */
-static void init_packet(struct dhcpMessage *packet, char type)
+static void init_packet(struct dhcpMessage *packet, char op, char type)
{
- udhcp_init_header(packet, type);
+ udhcp_init_header(packet, op, type);
memcpy(packet->chaddr, client_config.arp, 6);
- if (client_config.clientid)
+ if (client_config.clientid && type)
add_option_string(packet->options, client_config.clientid);
if (client_config.hostname)
add_option_string(packet->options, client_config.hostname);
@@ -80,7 +80,7 @@
{
struct dhcpMessage packet;
- init_packet(&packet, DHCPDECLINE);
+ init_packet(&packet, 0, DHCPDECLINE);
packet.xid = xid;
add_requests(&packet);
@@ -96,10 +96,19 @@
{
struct dhcpMessage packet;
- init_packet(&packet, DHCPDISCOVER);
+ if (client_config.bootp) {
+ init_packet(&packet, BOOTREQUEST, 0);
+ if (requested) {
+ packet.ciaddr = requested; /* already in network order */
+ }
+
+ } else {
+ init_packet(&packet, 0, DHCPDISCOVER);
+ if (requested)
+ add_simple_option(packet.options, DHCP_REQUESTED_IP,
requested);
+
+ }
packet.xid = xid;
- if (requested)
- add_simple_option(packet.options, DHCP_REQUESTED_IP, requested);
/* Explicitly saying that we want RFC-compliant packets helps
* some buggy DHCP servers to NOT send bigger packets */
@@ -117,7 +126,7 @@
struct dhcpMessage packet;
struct in_addr addr;
- init_packet(&packet, DHCPREQUEST);
+ init_packet(&packet, 0, DHCPREQUEST);
packet.xid = xid;
add_simple_option(packet.options, DHCP_REQUESTED_IP, requested);
@@ -136,7 +145,7 @@
{
struct dhcpMessage packet;
- init_packet(&packet, DHCPREQUEST);
+ init_packet(&packet, 0, DHCPREQUEST);
packet.xid = xid;
packet.ciaddr = ciaddr;
@@ -155,7 +164,7 @@
{
struct dhcpMessage packet;
- init_packet(&packet, DHCPRELEASE);
+ init_packet(&packet, 0, DHCPRELEASE);
packet.xid = random_xid();
packet.ciaddr = ciaddr;
@@ -227,10 +236,6 @@
memcpy(payload, &packet.data, bytes - (sizeof(packet.ip) +
sizeof(packet.udp)));
- if (payload->cookie != htonl(DHCP_MAGIC)) {
- bb_error_msg("received bogus message (bad magic) - ignoring");
- return -2;
- }
DEBUG("Got valid DHCP packet");
return bytes - (sizeof(packet.ip) + sizeof(packet.udp));
}
diff -aruN busybox-1.9.1/networking/udhcp/common.h
busybox-1.9.1.N/networking/udhcp/common.h
--- busybox-1.9.1/networking/udhcp/common.h 2008-02-12 08:03:01.000000000
-0800
+++ busybox-1.9.1.N/networking/udhcp/common.h 2008-04-07
10:33:25.000000000 -0700
@@ -56,7 +56,7 @@
uint16_t udhcp_checksum(void *addr, int count);
-void udhcp_init_header(struct dhcpMessage *packet, char type);
+void udhcp_init_header(struct dhcpMessage *packet, char op, char type);
int udhcp_recv_packet(struct dhcpMessage *packet, int fd);
int udhcp_send_raw_packet(struct dhcpMessage *payload,
diff -aruN busybox-1.9.1/networking/udhcp/dhcpc.c
busybox-1.9.1.N/networking/udhcp/dhcpc.c
--- busybox-1.9.1/networking/udhcp/dhcpc.c 2008-02-12 08:03:01.000000000
-0800
+++ busybox-1.9.1.N/networking/udhcp/dhcpc.c 2008-04-07
11:06:25.000000000 -0700
@@ -181,6 +181,7 @@
OPT_a = 1 << 20,
OPT_W = 1 << 21,
#endif
+ OPT_B = 1 << 22,
};
#if ENABLE_GETOPT_LONG
static const char udhcpc_longopts[] ALIGN1 =
@@ -206,6 +207,7 @@
#if ENABLE_FEATURE_UDHCPC_ARPING
"arping\0" No_argument "a"
#endif
+ "bootp\0" No_argument "B"
"request-option\0" Required_argument "O"
;
#endif
@@ -220,7 +222,7 @@
#endif
opt = getopt32(argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:vSA:"
USE_FEATURE_UDHCPC_ARPING("aW:")
- "O:"
+ "BO:"
, &str_c, &str_V, &str_h, &str_h, &str_F
, &client_config.interface, &client_config.pidfile, &str_r
, &client_config.script, &str_T, &str_t, &str_A
@@ -276,6 +278,9 @@
openlog(applet_name, LOG_PID, LOG_LOCAL0);
logmode |= LOGMODE_SYSLOG;
}
+ if (opt & OPT_B) {
+ client_config.bootp = 1;
+ }
while (list_O) {
int n = index_in_strings(dhcp_option_strings, list_O->data);
if (n < 0)
@@ -301,6 +306,10 @@
/* Goes to stdout and possibly syslog */
bb_info_msg("%s (v"BB_VER") started", applet_name);
+ if (client_config.bootp == 1) {
+ DEBUG("Running in bootp-only mode.");
+ }
+
/* if not set, and not suppressed, setup the default client ID */
if (!client_config.clientid && !(opt & OPT_C)) {
client_config.clientid = alloc_dhcp_option(DHCP_CLIENT_ID, "", 7);
@@ -450,9 +459,11 @@
if (listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) {
/* A packet is ready, read it */
- if (listen_mode == LISTEN_KERNEL)
+ if (listen_mode == LISTEN_KERNEL) {
len = udhcp_recv_packet(&packet, sockfd);
- else len = get_raw_packet(&packet, sockfd);
+ } else {
+ len = get_raw_packet(&packet, sockfd);
+ }
if (len == -1 && errno != EINTR) {
DEBUG("error on read, %s, reopening socket",
strerror(errno));
@@ -466,6 +477,22 @@
continue;
}
+ if (packet.op != BOOTREPLY) {
+ DEBUG("Ignoring non BOOTREPLY packet");
+ continue;
+ }
+
+ if (client_config.bootp) {
+ udhcp_run_script(&packet, "bound"); /* bound? */
+ change_listen_mode(LISTEN_NONE);
+ goto ret0;
+ }
+
+ if (packet.cookie != htonl(DHCP_MAGIC)) {
+ bb_error_msg("received bogus message (bad magic) --
ignoring");
+ continue;
+ }
+
/* Ignore packets that aren't for us */
if (memcmp(packet.chaddr, client_config.arp, 6)) {
DEBUG("Packet does not have our chaddr - ignoring");
diff -aruN busybox-1.9.1/networking/udhcp/dhcpc.h
busybox-1.9.1.N/networking/udhcp/dhcpc.h
--- busybox-1.9.1/networking/udhcp/dhcpc.h 2008-02-12 08:03:01.000000000
-0800
+++ busybox-1.9.1.N/networking/udhcp/dhcpc.h 2008-04-07
10:33:25.000000000 -0700
@@ -30,6 +30,7 @@
uint8_t *fqdn; /* Optional fully qualified domain name
to use */
int ifindex; /* Index number of the interface to use
*/
uint8_t arp[6]; /* Our arp address */
+ char bootp; /* Act like a BOOTP client. */
uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O
option) */
};
diff -aruN busybox-1.9.1/networking/udhcp/dhcpd.c
busybox-1.9.1.N/networking/udhcp/dhcpd.c
--- busybox-1.9.1/networking/udhcp/dhcpd.c 2008-02-12 08:03:01.000000000
-0800
+++ busybox-1.9.1.N/networking/udhcp/dhcpd.c 2008-04-07
10:33:25.000000000 -0700
@@ -143,6 +143,11 @@
continue;
}
+ if (packet.cookie != htonl(DHCP_MAGIC)) {
+ bb_error_msg("received bogus message, ignoring");
+ continue;
+ }
+
state = get_option(&packet, DHCP_MESSAGE_TYPE);
if (state == NULL) {
bb_error_msg("cannot get option from packet, ignoring");
diff -aruN busybox-1.9.1/networking/udhcp/packet.c
busybox-1.9.1.N/networking/udhcp/packet.c
--- busybox-1.9.1/networking/udhcp/packet.c 2008-02-12 08:03:01.000000000
-0800
+++ busybox-1.9.1.N/networking/udhcp/packet.c 2008-04-07
10:33:25.000000000 -0700
@@ -15,26 +15,38 @@
#include "options.h"
-void udhcp_init_header(struct dhcpMessage *packet, char type)
+void udhcp_init_header(struct dhcpMessage *packet, char op, char type)
{
memset(packet, 0, sizeof(struct dhcpMessage));
- switch (type) {
- case DHCPDISCOVER:
- case DHCPREQUEST:
- case DHCPRELEASE:
- case DHCPINFORM:
- packet->op = BOOTREQUEST;
- break;
- case DHCPOFFER:
- case DHCPACK:
- case DHCPNAK:
- packet->op = BOOTREPLY;
+
+ /* DHCP-only */
+ if (!op && type) {
+ switch (type) {
+ case DHCPDISCOVER:
+ case DHCPREQUEST:
+ case DHCPRELEASE:
+ case DHCPINFORM:
+ op = BOOTREQUEST;
+ break;
+ case DHCPOFFER:
+ case DHCPACK:
+ case DHCPNAK:
+ op = BOOTREPLY;
+ break;
+ }
}
+
+ /* Fill in packet with data present in both BOOTP and DHCP */
+ packet->op = op;
packet->htype = ETH_10MB;
packet->hlen = ETH_10MB_LEN;
packet->cookie = htonl(DHCP_MAGIC);
packet->options[0] = DHCP_END;
- add_simple_option(packet->options, DHCP_MESSAGE_TYPE, type);
+
+ /* DHCP-only */
+ if (!op && type) {
+ add_simple_option(packet->options, DHCP_MESSAGE_TYPE, type);
+ }
}
@@ -57,13 +69,9 @@
return -1;
}
- if (packet->cookie != htonl(DHCP_MAGIC)) {
- bb_error_msg("received bogus message, ignoring");
- return -2;
- }
DEBUG("Received a packet");
- if (packet->op == BOOTREQUEST) {
+ if (packet->cookie == htonl(DHCP_MAGIC) && packet->op == BOOTREQUEST) {
vendor = get_option(packet, DHCP_VENDOR);
if (vendor) {
#if 0
diff -aruN busybox-1.9.1/networking/udhcp/serverpacket.c
busybox-1.9.1.N/networking/udhcp/serverpacket.c
--- busybox-1.9.1/networking/udhcp/serverpacket.c 2008-02-12
08:03:00.000000000 -0800
+++ busybox-1.9.1.N/networking/udhcp/serverpacket.c 2008-04-07
10:33:25.000000000 -0700
@@ -77,7 +77,7 @@
static void init_packet(struct dhcpMessage *packet, struct dhcpMessage
*oldpacket, char type)
{
- udhcp_init_header(packet, type);
+ udhcp_init_header(packet, 0, type);
packet->xid = oldpacket->xid;
memcpy(packet->chaddr, oldpacket->chaddr, 16);
packet->flags = oldpacket->flags;
More information about the busybox
mailing list