PATCH: udhcpc -- don't request set of options by default
L. Gabriel Somlo
somlo at cmu.edu
Tue Apr 1 21:09:18 UTC 2008
Denys & All,
I noticed that udhcpc sends a default list of options in its request
(i.e., all options listed with flag OPTION_REQ in options.c)
That's bad, at least when used with some versions of isc dhcpd, which
will only include the requested options in a reply.
I know about the -O flag that can get udhcpc to request extra options,
but what if I want to see options I didn't think about asking for ?
Including a default option list in the request will always preclude me
from seeing options I didn't know to ask for.
I've added the '-o' command line flag to udhcpc, which inhibits
inclusion of default options in the request. Options can still be
explicitly requested with -O.
I have also added a mechanism to request '-o' (actually, its long form
--no-default-options) from ifupdown's /etc/network/interfaces:
auto eth0
iface eth0 inet dhcp
nodefaultopts --no-default-options
Last, but not least, a slightly more complex sample udhcpc.script,
which attempts to react to changes in parameters returned by the dhcp
server in a minimal-effort sort of way (i.e. don't reconfigure the
interface if the only change was in the list of ntp servers, etc.)
Please note that I did not change anything in the default behavior,
although I'd like to propose that udhcpc should not ask for a default
list of options unless we explicitly tell it to do so...
Please let me know what you think, and apply if you agree.
Regards,
--Gabriel
-------------- next part --------------
diff -NarU5 busybox-svn-21617.orig/examples/udhcp/udhcpc.script busybox-svn-21617/examples/udhcp/udhcpc.script
--- busybox-svn-21617.orig/examples/udhcp/udhcpc.script 1969-12-31 19:00:00.000000000 -0500
+++ busybox-svn-21617/examples/udhcp/udhcpc.script 2008-04-01 16:25:24.000000000 -0400
@@ -0,0 +1,88 @@
+#!/bin/busybox sh
+
+# a more "complex" udhcpc script that attempts to handle option changes with minimal work
+# Gabriel Somlo <somlo at cmu.edu>, 04/01/2008
+
+[ -z "$1" ] && echo 'Error: should be called from udhcpc' && exit 1
+
+CFG="/var/run/udhcpc.${interface}.cfg"
+RESOLV_CONF='/etc/resolv.conf'
+NTP_CONF='/etc/ntp.conf'
+# which interface configures DNS and NTP ? Comment out if none:
+PEERDNS_IF=eth0
+PEERNTP_IF=eth0
+
+case "$1" in
+ deconfig)
+ ip addr flush dev $interface
+ ip link set up dev $interface
+ rm -f $CFG
+ if [ "$PEERDNS_IF" == "$interface" ] ; then
+ [ -f ${RESOLV_CONF}.dhcsave ] && mv -f ${RESOLV_CONF}.dhcsave $RESOLV_CONF
+ fi
+ if [ "$PEERNTP_IF" == "$interface" ] ; then
+ [ -f ${NTP_CONF}.dhcsave ] && mv -f ${NTP_CONF}.dhcsave $NTP_CONF
+ fi
+ ;;
+ bound)
+ set > $CFG
+ ip addr flush dev $interface
+ [ -n "$mtu" ] && ip link set mtu $mtu dev $interface
+ ip addr add ${ip}/${mask} dev $interface
+ [ -n "$router" ] && ip route add default via ${router%% *} dev $interface
+ if [ "$PEERDNS_IF" == "$interface" ] ; then
+ [ -f $RESOLV_CONF ] && mv -f $RESOLV_CONF ${RESOLV_CONF}.dhcsave
+ [ -n "$domain" ] && echo search $domain > $RESOLV_CONF
+ for i in $dns ; do
+ echo nameserver $i >> $RESOLV_CONF
+ done
+ fi
+ if [ "$PEERNTP_IF" == "$interface" ] ; then
+ [ -f $NTP_CONF ] && mv -f $NTP_CONF ${NTP_CONF}.dhcsave
+ > $NTP_CONF
+ for i in $ntpsrv ; do
+ echo server $i >> $NTP_CONF
+ done
+ fi
+ ;;
+ renew)
+ set > ${CFG}.new
+ for i in $(diff -U1 $CFG ${CFG}.new | grep -E ^[+-] \
+ | tail +3 \
+ | awk -F[+-=] '{print $2}') ; do
+ case "$i" in
+ ip|mask|router|mtu)
+ REDO_NET='yes'
+ ;;
+ domain|dns)
+ REDO_DNS='yes'
+ ;;
+ ntpsrv)
+ REDO_NTP='yes'
+ ;;
+ esac
+ done
+ mv -f ${CFG}.new $CFG
+ if [ -n "$REDO_NET" ] ; then
+ ip addr flush dev $interface
+ [ -n "$mtu" ] && ip link set mtu $mtu dev $interface
+ ip addr add ${ip}/${mask} dev $interface
+ [ -n "$router" ] && ip route add default via ${router%% *} dev $interface
+ fi
+ if [ -n "$REDO_DNS" -a "$PEERDNS_IF" == "$interface" ] ; then
+ [ -n "$domain" ] && echo search $domain > $RESOLV_CONF
+ for i in $dns ; do
+ echo nameserver $i >> $RESOLV_CONF
+ done
+ fi
+ if [ -n "$REDO_NTP" -a "$PEERNTP_IF" == "$interface" ] ; then
+ > $NTP_CONF
+ for i in $ntpsrv ; do
+ echo server $i >> $NTP_CONF
+ done
+ # FIXME: RELOAD NTP DAEMON HERE
+ fi
+ ;;
+esac
+
+exit 0
diff -NarU5 busybox-svn-21617.orig/include/usage.h busybox-svn-21617/include/usage.h
--- busybox-svn-21617.orig/include/usage.h 2008-04-01 14:47:29.000000000 -0400
+++ busybox-svn-21617/include/usage.h 2008-04-01 15:20:40.000000000 -0400
@@ -4114,11 +4114,11 @@
"[-T last-check-time] [-U UUID] device"
#define tune2fs_full_usage \
"Adjust filesystem options on ext[23] filesystems"
#define udhcpc_trivial_usage \
- "[-Cfbnqtv] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \
+ "[-Cfbnqtvo] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \
" [-p pidfile] [-r IP] [-s script] [-O dhcp-option]..." USE_FEATURE_UDHCP_PORT(" [-P N]")
#define udhcpc_full_usage \
USE_GETOPT_LONG( \
" -V,--vendorclass=CLASSID Vendor class identifier" \
"\n -i,--interface=INTERFACE Interface to use (default eth0)" \
@@ -4142,10 +4142,11 @@
"\n -P,--client-port N Use port N instead of default 68" \
) \
USE_FEATURE_UDHCPC_ARPING( \
"\n -a,--arping Use arping to validate offered address" \
) \
+ "\n -o,--no-default-options Do not request options by default" \
) \
SKIP_GETOPT_LONG( \
" -V CLASSID Vendor class identifier" \
"\n -i INTERFACE Interface to use (default: eth0)" \
"\n -H,-h HOSTNAME Client hostname" \
diff -NarU5 busybox-svn-21617.orig/networking/ifupdown.c busybox-svn-21617/networking/ifupdown.c
--- busybox-svn-21617.orig/networking/ifupdown.c 2008-04-01 14:47:25.000000000 -0400
+++ busybox-svn-21617/networking/ifupdown.c 2008-04-01 16:09:02.000000000 -0400
@@ -474,11 +474,11 @@
{ "pump",
"pump -i %iface%[[ -h %hostname%]][[ -l %leasehours%]]",
"pump -i %iface% -k",
},
{ "udhcpc",
- "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ -t %retries%]]",
+ "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ -t %retries%]][[ %nodefaultopts%]]",
"kill `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null",
},
};
#endif /* ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCPC */
@@ -505,11 +505,11 @@
/* ip doesn't up iface when it configures it (unlike ifconfig) */
if (!execute("ip link set %iface% up", ifd, exec))
return 0;
#endif
return execute("udhcpc -R -n -p /var/run/udhcpc.%iface%.pid "
- "-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ -t %retries%]]",
+ "-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ -t %retries%]][[ %nodefaultopts%]]",
ifd, exec);
}
#else
static int dhcp_up(struct interface_defn_t *ifd ATTRIBUTE_UNUSED,
execfn *exec ATTRIBUTE_UNUSED)
diff -NarU5 busybox-svn-21617.orig/networking/udhcp/clientpacket.c busybox-svn-21617/networking/udhcp/clientpacket.c
--- busybox-svn-21617.orig/networking/udhcp/clientpacket.c 2008-04-01 14:47:25.000000000 -0400
+++ busybox-svn-21617/networking/udhcp/clientpacket.c 2008-04-01 15:04:18.000000000 -0400
@@ -62,11 +62,11 @@
int end = end_option(packet->options);
int i, len = 0;
packet->options[end + OPT_CODE] = DHCP_PARAM_REQ;
for (i = 0; (c = dhcp_options[i].code) != 0; i++) {
- if ((dhcp_options[i].flags & OPTION_REQ)
+ if (((dhcp_options[i].flags & OPTION_REQ) && !client_config.no_default_options)
|| (client_config.opt_mask[c >> 3] & (1 << (c & 7)))
) {
packet->options[end + OPT_DATA + len] = c;
len++;
}
diff -NarU5 busybox-svn-21617.orig/networking/udhcp/dhcpc.c busybox-svn-21617/networking/udhcp/dhcpc.c
--- busybox-svn-21617.orig/networking/udhcp/dhcpc.c 2008-04-01 14:47:25.000000000 -0400
+++ busybox-svn-21617/networking/udhcp/dhcpc.c 2008-04-01 15:01:01.000000000 -0400
@@ -180,10 +180,11 @@
#if ENABLE_FEATURE_UDHCPC_ARPING
OPT_a = 1 << 20,
OPT_W = 1 << 21,
#endif
OPT_P = 1 << 22,
+ OPT_o = 1 << 23,
};
#if ENABLE_GETOPT_LONG
static const char udhcpc_longopts[] ALIGN1 =
"clientid\0" Required_argument "c"
"clientid-none\0" No_argument "C"
@@ -209,10 +210,11 @@
#endif
"request-option\0" Required_argument "O"
#if ENABLE_FEATURE_UDHCP_PORT
"client-port\0" Required_argument "P"
#endif
+ "no-default-options\0" No_argument "o"
;
#endif
/* Default options. */
#if ENABLE_FEATURE_UDHCP_PORT
SERVER_PORT = 67;
@@ -228,11 +230,11 @@
applet_long_options = udhcpc_longopts;
#endif
opt = getopt32(argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:vSA:"
USE_FEATURE_UDHCPC_ARPING("aW:")
USE_FEATURE_UDHCP_PORT("P:")
- "O:"
+ "O:o:"
, &str_c, &str_V, &str_h, &str_h, &str_F
, &client_config.interface, &client_config.pidfile, &str_r
, &client_config.script
, &discover_timeout, &discover_retries, &tryagain_timeout
USE_FEATURE_UDHCPC_ARPING(, &str_W)
@@ -289,10 +291,12 @@
if (opt & OPT_P) {
CLIENT_PORT = xatou16(str_P);
SERVER_PORT = CLIENT_PORT - 1;
}
#endif
+ if (opt & OPT_o)
+ client_config.no_default_options = 1;
while (list_O) {
int n = index_in_strings(dhcp_option_strings, list_O->data);
if (n < 0)
bb_error_msg_and_die("unknown option '%s'", list_O->data);
n = dhcp_options[n].code;
diff -NarU5 busybox-svn-21617.orig/networking/udhcp/dhcpc.h busybox-svn-21617/networking/udhcp/dhcpc.h
--- busybox-svn-21617.orig/networking/udhcp/dhcpc.h 2008-04-01 14:47:25.000000000 -0400
+++ busybox-svn-21617/networking/udhcp/dhcpc.h 2008-04-01 14:56:12.000000000 -0400
@@ -19,10 +19,11 @@
char foreground; /* Do not fork */
char quit_after_lease; /* Quit after obtaining lease */
char release_on_quit; /* Perform release on quit */
char abort_if_no_lease; /* Abort if no lease */
char background_if_no_lease; /* Fork to background if no lease */
+ char no_default_options; /* Do not include default optins in request */
const char *interface; /* The name of the interface to use */
char *pidfile; /* Optionally store the process ID */
const char *script; /* User script to run at dhcp events */
uint8_t *clientid; /* Optional client id to use */
uint8_t *vendorclass; /* Optional vendor class-id to use */
More information about the busybox
mailing list