From 7724c766bdfba5f3af5cdf5d869bcf03f45149e3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Mar 2010 09:32:09 +0100 Subject: udhcp: pass pointer to whole packet to "add option" functions This is needed for "overflow option" support function old new delta udhcp_find_option - 34 +34 udhcp_add_binary_option 94 106 +12 write_leases 227 223 -4 udhcp_init_header 86 82 -4 send_release 104 99 -5 init_packet 87 81 -6 add_client_options 160 154 -6 add_server_options 100 92 -8 udhcpd_main 1964 1954 -10 udhcpc_main 2859 2837 -22 find_option 34 - -34 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 1/8 up/down: 46/-99) Total: -53 bytes Signed-off-by: Denys Vlasenko --- networking/udhcp/common.c | 16 +++++++++------- networking/udhcp/common.h | 6 +++--- networking/udhcp/dhcpc.c | 26 +++++++++++++------------- networking/udhcp/dhcpd.c | 10 +++++----- networking/udhcp/files.c | 9 +++++---- networking/udhcp/leases.c | 1 + networking/udhcp/packet.c | 2 +- networking/udhcp/socket.c | 1 - 8 files changed, 37 insertions(+), 34 deletions(-) (limited to 'networking/udhcp') diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index bc458ac7a..9316774ff 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c @@ -226,14 +226,16 @@ int FAST_FUNC udhcp_end_option(uint8_t *optionptr) /* Add an option (supplied in binary form) to the options. * Option format: [code][len][data1][data2]..[dataLEN] */ -void FAST_FUNC udhcp_add_binary_option(uint8_t *optionptr, uint8_t *addopt) +void FAST_FUNC udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) { unsigned len; + uint8_t *optionptr = packet->options; unsigned end = udhcp_end_option(optionptr); - /* end position + option code/length + addopt length + end option */ len = OPT_DATA + addopt[OPT_LEN]; + /* end position + (option code/length + addopt length) + end option */ if (end + len + 1 >= DHCP_OPTIONS_BUFSIZE) { +//TODO: learn how to use overflow option if we exhaust packet->options[] bb_error_msg("option 0x%02x did not fit into the packet", addopt[OPT_CODE]); return; @@ -243,8 +245,8 @@ void FAST_FUNC udhcp_add_binary_option(uint8_t *optionptr, uint8_t *addopt) optionptr[end + len] = DHCP_END; } -/* Add a one to four byte option to a packet */ -void FAST_FUNC udhcp_add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data) +/* Add an one to four byte option to a packet */ +void FAST_FUNC udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data) { const struct dhcp_option *dh; @@ -259,7 +261,7 @@ void FAST_FUNC udhcp_add_simple_option(uint8_t *optionptr, uint8_t code, uint32_ data <<= 8 * (4 - len); /* Assignment is unaligned! */ move_to_unaligned32(&option[OPT_DATA], data); - udhcp_add_binary_option(optionptr, option); + udhcp_add_binary_option(packet, option); return; } } @@ -268,7 +270,7 @@ void FAST_FUNC udhcp_add_simple_option(uint8_t *optionptr, uint8_t code, uint32_ } /* Find option 'code' in opt_list */ -struct option_set* FAST_FUNC find_option(struct option_set *opt_list, uint8_t code) +struct option_set* FAST_FUNC udhcp_find_option(struct option_set *opt_list, uint8_t code) { while (opt_list && opt_list->data[OPT_CODE] < code) opt_list = opt_list->next; @@ -307,7 +309,7 @@ static NOINLINE void attach_option( char *allocated = NULL; #endif - existing = find_option(*opt_list, option->code); + existing = udhcp_find_option(*opt_list, option->code); if (!existing) { log2("Attaching option %02x to list", option->code); #if ENABLE_FEATURE_UDHCP_RFC3397 diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index cc0cab6e4..bb7541f6e 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -172,13 +172,13 @@ extern const uint8_t dhcp_option_lengths[]; uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC; int udhcp_end_option(uint8_t *optionptr) FAST_FUNC; -void udhcp_add_binary_option(uint8_t *optionptr, uint8_t *addopt) FAST_FUNC; -void udhcp_add_simple_option(uint8_t *optionptr, uint8_t code, uint32_t data) FAST_FUNC; +void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) FAST_FUNC; +void udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data) FAST_FUNC; #if ENABLE_FEATURE_UDHCP_RFC3397 char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC; uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) FAST_FUNC; #endif -struct option_set *find_option(struct option_set *opt_list, uint8_t code) FAST_FUNC; +struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) FAST_FUNC; // RFC 2131 Table 5: Fields and options used by DHCP clients diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 2c7608048..717c92c6b 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -319,22 +319,22 @@ static void init_packet(struct dhcp_packet *packet, char type) udhcp_init_header(packet, type); memcpy(packet->chaddr, client_config.client_mac, 6); if (client_config.clientid) - udhcp_add_binary_option(packet->options, client_config.clientid); + udhcp_add_binary_option(packet, client_config.clientid); if (client_config.hostname) - udhcp_add_binary_option(packet->options, client_config.hostname); + udhcp_add_binary_option(packet, client_config.hostname); if (client_config.fqdn) - udhcp_add_binary_option(packet->options, client_config.fqdn); + udhcp_add_binary_option(packet, client_config.fqdn); if (type != DHCPDECLINE && type != DHCPRELEASE && client_config.vendorclass ) { - udhcp_add_binary_option(packet->options, client_config.vendorclass); + udhcp_add_binary_option(packet, client_config.vendorclass); } } static void add_client_options(struct dhcp_packet *packet) { - /* Add am "param req" option with the list of options we'd like to have + /* Add a "param req" option with the list of options we'd like to have * from stubborn DHCP servers. Pull the data from the struct in common.c. * No bounds checking because it goes towards the head of the packet. */ uint8_t c; @@ -361,7 +361,7 @@ static void add_client_options(struct dhcp_packet *packet) { struct option_set *curr = client_config.options; while (curr) { - udhcp_add_binary_option(packet->options, curr->data); + udhcp_add_binary_option(packet, curr->data); curr = curr->next; } // if (client_config.sname) @@ -405,10 +405,10 @@ static int send_discover(uint32_t xid, uint32_t requested) init_packet(&packet, DHCPDISCOVER); packet.xid = xid; if (requested) - udhcp_add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); + udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); /* Explicitly saying that we want RFC-compliant packets helps * some buggy DHCP servers to NOT send bigger packets */ - udhcp_add_simple_option(packet.options, DHCP_MAX_SIZE, htons(576)); + udhcp_add_simple_option(&packet, DHCP_MAX_SIZE, htons(576)); add_client_options(&packet); bb_info_msg("Sending discover..."); @@ -426,8 +426,8 @@ static int send_select(uint32_t xid, uint32_t server, uint32_t requested) init_packet(&packet, DHCPREQUEST); packet.xid = xid; - udhcp_add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); - udhcp_add_simple_option(packet.options, DHCP_SERVER_ID, server); + udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); + udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); add_client_options(&packet); addr.s_addr = requested; @@ -461,8 +461,8 @@ static int send_decline(uint32_t xid, uint32_t server, uint32_t requested) init_packet(&packet, DHCPDECLINE); packet.xid = xid; - udhcp_add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); - udhcp_add_simple_option(packet.options, DHCP_SERVER_ID, server); + udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); + udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); bb_info_msg("Sending decline..."); return raw_bcast_from_client_config_ifindex(&packet); @@ -478,7 +478,7 @@ static int send_release(uint32_t server, uint32_t ciaddr) packet.xid = random_xid(); packet.ciaddr = ciaddr; - udhcp_add_simple_option(packet.options, DHCP_SERVER_ID, server); + udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); bb_info_msg("Sending release..."); return udhcp_send_kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 32f351f52..4ab32de90 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -93,7 +93,7 @@ static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacke packet->flags = oldpacket->flags; packet->gateway_nip = oldpacket->gateway_nip; packet->ciaddr = oldpacket->ciaddr; - udhcp_add_simple_option(packet->options, DHCP_SERVER_ID, server_config.server_nip); + udhcp_add_simple_option(packet, DHCP_SERVER_ID, server_config.server_nip); } /* Fill options field, siaddr_nip, and sname and boot_file fields. @@ -105,7 +105,7 @@ static void add_server_options(struct dhcp_packet *packet) while (curr) { if (curr->data[OPT_CODE] != DHCP_LEASE_TIME) - udhcp_add_binary_option(packet->options, curr->data); + udhcp_add_binary_option(packet, curr->data); curr = curr->next; } @@ -194,7 +194,7 @@ static void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, } lease_time_sec = select_lease_time(oldpacket); - udhcp_add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); + udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec)); add_server_options(&packet); addr.s_addr = packet.yiaddr; @@ -224,7 +224,7 @@ static void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) packet.yiaddr = yiaddr; lease_time_sec = select_lease_time(oldpacket); - udhcp_add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); + udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec)); add_server_options(&packet); @@ -324,7 +324,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) bb_info_msg("%s (v"BB_VER") started", applet_name); - option = find_option(server_config.options, DHCP_LEASE_TIME); + option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); server_config.max_lease_sec = DEFAULT_LEASE_TIME; if (option) { move_from_unaligned32(server_config.max_lease_sec, option->data + OPT_DATA); diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 1f25bb105..cf55a6b5c 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c @@ -167,10 +167,11 @@ void FAST_FUNC write_leases(void) close(fd); if (server_config.notify_file) { -// TODO: vfork-based child creation - char *cmd = xasprintf("%s %s", server_config.notify_file, server_config.lease_file); - system(cmd); - free(cmd); + char *argv[3]; + argv[0] = server_config.notify_file; + argv[1] = server_config.lease_file; + argv[2] = NULL; + spawn_and_wait(argv); } } diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index efe67cf5d..81acb9910 100644 --- a/networking/udhcp/leases.c +++ b/networking/udhcp/leases.c @@ -163,6 +163,7 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) lease = find_lease_by_nip(nip); if (!lease) { +//TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! if (nobody_responds_to_arp(nip, safe_mac)) return nip; } else { diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 5b113bc10..ecdbec7f3 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c @@ -33,7 +33,7 @@ void FAST_FUNC udhcp_init_header(struct dhcp_packet *packet, char type) packet->cookie = htonl(DHCP_MAGIC); if (DHCP_END != 0) packet->options[0] = DHCP_END; - udhcp_add_simple_option(packet->options, DHCP_MESSAGE_TYPE, type); + udhcp_add_simple_option(packet, DHCP_MESSAGE_TYPE, type); } #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c index a0ffbf893..469b36202 100644 --- a/networking/udhcp/socket.c +++ b/networking/udhcp/socket.c @@ -24,7 +24,6 @@ */ #include -//#include #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION #include #include -- cgit v1.2.3