From d55fe3e595eb0aad60484d273e251cfee4ef8aa5 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 4 Feb 2008 13:12:16 +0000 Subject: [PATCH] udhcp: optional support for non-standard DHCP ports (+300 bytes when selected) --- include/usage.h | 15 ++++++++++++--- networking/udhcp/Config.in | 7 +++++++ networking/udhcp/clientsocket.c | 14 +++++++++----- networking/udhcp/common.h | 3 --- networking/udhcp/dhcpc.c | 17 +++++++++++++++++ networking/udhcp/dhcpc.h | 10 +++++++++- networking/udhcp/dhcpd.c | 16 ++++++++++++++-- networking/udhcp/dhcpd.h | 9 +++++++++ networking/udhcp/dhcprelay.c | 1 + networking/udhcp/serverpacket.c | 1 + 10 files changed, 79 insertions(+), 14 deletions(-) diff --git a/include/usage.h b/include/usage.h index 989ed9134..fb88e9bcd 100644 --- a/include/usage.h +++ b/include/usage.h @@ -3892,7 +3892,7 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when #define udhcpc_trivial_usage \ "[-Cfbnqtv] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \ - " [-p pidfile] [-r IP] [-s script] [-O dhcp-option]..." + " [-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" \ @@ -3913,6 +3913,9 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when "\n -q,--quit Quit after obtaining lease" \ "\n -R,--release Release IP on quit" \ "\n -O,--request-option=OPT Request DHCP option OPT from server" \ + USE_FEATURE_UDHCP_PORT( \ + "\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" \ ) \ @@ -3936,18 +3939,24 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when "\n -q Quit after obtaining lease" \ "\n -R Release IP on quit" \ "\n -O OPT Request DHCP option OPT from server" \ + USE_FEATURE_UDHCP_PORT( \ + "\n -P N Use port N instead of default 68" \ + ) \ USE_FEATURE_UDHCPC_ARPING( \ "\n -a Use arping to validate offered address" \ ) \ ) #define udhcpd_trivial_usage \ - "[-fS] [configfile]" \ + "[-fS]" USE_FEATURE_UDHCP_PORT(" [-P N]") " [configfile]" \ #define udhcpd_full_usage \ "DHCP server" \ "\n -f Run in foreground" \ - "\n -S Log to syslog too" + "\n -S Log to syslog too" \ + USE_FEATURE_UDHCP_PORT( \ + "\n -P N Use port N instead of default 67" \ + ) #define umount_trivial_usage \ "[flags] FILESYSTEM|DIRECTORY" diff --git a/networking/udhcp/Config.in b/networking/udhcp/Config.in index 26cc8f501..ff0e4e2ae 100644 --- a/networking/udhcp/Config.in +++ b/networking/udhcp/Config.in @@ -63,6 +63,13 @@ config FEATURE_UDHCPC_ARPING is really available. The client will DHCPDECLINE the offer if the address is in use, and restart the discover process. +config FEATURE_UDHCP_PORT + bool "Enable '-P port' option for udhcpd and udhcpc" + default n + depends on APP_UDHCPD || APP_UDHCPC + help + At the cost of ~300 bytes, enables -P port option. + This feature is typically not needed. config FEATURE_UDHCP_DEBUG bool "Compile udhcp with noisy debugging messages" diff --git a/networking/udhcp/clientsocket.c b/networking/udhcp/clientsocket.c index 954db5319..b5534f83e 100644 --- a/networking/udhcp/clientsocket.c +++ b/networking/udhcp/clientsocket.c @@ -33,8 +33,8 @@ #include #include "common.h" - -#define SERVER_AND_CLIENT_PORTS ((SERVER_PORT << 16) + CLIENT_PORT) +#include "dhcpd.h" +#include "dhcpc.h" int raw_socket(int ifindex) { @@ -62,6 +62,7 @@ int raw_socket(int ifindex) * * TODO: make conditional? */ +#define SERVER_AND_CLIENT_PORTS ((67 << 16) + 68) static const struct sock_filter filter_instr[] = { /* check for udp */ BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9), @@ -89,10 +90,13 @@ int raw_socket(int ifindex) fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); DEBUG("got raw socket fd %d", fd); - /* Ignoring error (kernel may lack support for this) */ - if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, + if (SERVER_PORT == 67 && CLIENT_PORT == 68) { + /* Use only if standard ports are in use */ + /* Ignoring error (kernel may lack support for this) */ + if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, sizeof(filter_prog)) >= 0) - DEBUG("attached filter to raw socket fd %d", fd); + DEBUG("attached filter to raw socket fd %d", fd); + } sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_IP); diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index b1d629b18..9b26678c1 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -14,9 +14,6 @@ #define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script" -#define SERVER_PORT 67 -#define CLIENT_PORT 68 - extern const uint8_t MAC_BCAST_ADDR[6]; /* six all-ones */ /*** packet.h ***/ diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index f54bc08f1..7fca184ab 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -133,6 +133,7 @@ int udhcpc_main(int argc, char **argv) { uint8_t *temp, *message; char *str_c, *str_V, *str_h, *str_F, *str_r, *str_T, *str_A, *str_t; + USE_FEATURE_UDHCP_PORT(char *str_P;) llist_t *list_O = NULL; #if ENABLE_FEATURE_UDHCPC_ARPING char *str_W; @@ -181,6 +182,7 @@ int udhcpc_main(int argc, char **argv) OPT_a = 1 << 20, OPT_W = 1 << 21, #endif + OPT_P = 1 << 22, }; #if ENABLE_GETOPT_LONG static const char udhcpc_longopts[] ALIGN1 = @@ -207,9 +209,16 @@ int udhcpc_main(int argc, char **argv) "arping\0" No_argument "a" #endif "request-option\0" Required_argument "O" +#if ENABLE_FEATURE_UDHCP_PORT + "client-port\0" Required_argument "P" +#endif ; #endif /* Default options. */ +#if ENABLE_FEATURE_UDHCP_PORT + SERVER_PORT = 67; + CLIENT_PORT = 68; +#endif client_config.interface = "eth0"; client_config.script = DEFAULT_SCRIPT; @@ -220,11 +229,13 @@ int udhcpc_main(int argc, char **argv) #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:" , &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 USE_FEATURE_UDHCPC_ARPING(, &str_W) + USE_FEATURE_UDHCP_PORT(, &str_P) , &list_O ); @@ -276,6 +287,12 @@ int udhcpc_main(int argc, char **argv) openlog(applet_name, LOG_PID, LOG_LOCAL0); logmode |= LOGMODE_SYSLOG; } +#if ENABLE_FEATURE_UDHCP_PORT + if (opt & OPT_P) { + CLIENT_PORT = xatou16(str_P); + SERVER_PORT = CLIENT_PORT - 1; + } +#endif while (list_O) { int n = index_in_strings(dhcp_option_strings, list_O->data); if (n < 0) diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index bc05754ac..4b8f3ec98 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h @@ -29,11 +29,19 @@ 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 */ + uint16_t port; uint8_t arp[6]; /* Our arp address */ uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */ }; -#define client_config (*(struct client_config_t*)&bb_common_bufsiz1) +/* server_config sits in 1st half of bb_common_bufsiz1 */ +#define client_config (*(struct client_config_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE/2])) + +#if ENABLE_FEATURE_UDHCP_PORT +#define CLIENT_PORT (client_config.port) +#else +#define CLIENT_PORT 68 +#endif /*** clientpacket.h ***/ diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 45f445b48..eb7323da7 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -12,6 +12,7 @@ #include #include "common.h" +#include "dhcpc.h" #include "dhcpd.h" #include "options.h" @@ -35,8 +36,14 @@ int udhcpd_main(int argc, char **argv) unsigned opt; struct option_set *option; struct dhcpOfferedAddr *lease, static_lease; + USE_FEATURE_UDHCP_PORT(char *str_P;) - opt = getopt32(argv, "fS"); +#if ENABLE_FEATURE_UDHCP_PORT + SERVER_PORT = 67; + CLIENT_PORT = 68; +#endif + + opt = getopt32(argv, "fS" USE_FEATURE_UDHCP_PORT("P:", &str_P)); argv += optind; if (!(opt & 1)) { /* no -f */ @@ -48,7 +55,12 @@ int udhcpd_main(int argc, char **argv) openlog(applet_name, LOG_PID, LOG_LOCAL0); logmode |= LOGMODE_SYSLOG; } - +#if ENABLE_FEATURE_UDHCP_PORT + if (opt & 4) { /* -P */ + SERVER_PORT = xatou16(str_P); + CLIENT_PORT = SERVER_PORT + 1; + } +#endif /* Would rather not do read_config before daemonization - * otherwise NOMMU machines will parse config twice */ read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE); diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h index 216b7ab64..fe45ca312 100644 --- a/networking/udhcp/dhcpd.h +++ b/networking/udhcp/dhcpd.h @@ -1,5 +1,6 @@ /* vi: set sw=4 ts=4: */ /* dhcpd.h */ + #ifndef _DHCPD_H #define _DHCPD_H @@ -27,6 +28,7 @@ struct static_lease { struct server_config_t { uint32_t server; /* Our IP, in network order */ + uint16_t port; /* start,end are in host order: we need to compare start <= ip <= end */ uint32_t start_ip; /* Start address of leases, in host order */ uint32_t end_ip; /* End of leases, in host order */ @@ -55,6 +57,13 @@ struct server_config_t { }; #define server_config (*(struct server_config_t*)&bb_common_bufsiz1) +/* client_config sits in 2nd half of bb_common_bufsiz1 */ + +#if ENABLE_FEATURE_UDHCP_PORT +#define SERVER_PORT (server_config.port) +#else +#define SERVER_PORT 67 +#endif extern struct dhcpOfferedAddr *leases; diff --git a/networking/udhcp/dhcprelay.c b/networking/udhcp/dhcprelay.c index c243cc16c..def1bc297 100644 --- a/networking/udhcp/dhcprelay.c +++ b/networking/udhcp/dhcprelay.c @@ -14,6 +14,7 @@ #include "options.h" /* constants */ +#define SERVER_PORT 67 #define SELECT_TIMEOUT 5 /* select timeout in sec. */ #define MAX_LIFETIME 2*60 /* lifetime of an xid entry in sec. */ diff --git a/networking/udhcp/serverpacket.c b/networking/udhcp/serverpacket.c index 764b9a8f6..1dc7233f2 100644 --- a/networking/udhcp/serverpacket.c +++ b/networking/udhcp/serverpacket.c @@ -21,6 +21,7 @@ */ #include "common.h" +#include "dhcpc.h" #include "dhcpd.h" #include "options.h"