svn commit: [25916] trunk/busybox/networking/udhcp

vda at busybox.net vda at busybox.net
Wed Apr 1 12:36:09 UTC 2009


Author: vda
Date: 2009-04-01 12:36:09 +0000 (Wed, 01 Apr 2009)
New Revision: 25916

Log:
dhcpd: remember and record hostnames; optimize get_option
dumpleases: show hostnames

function                                             old     new   delta
add_lease                                            230     292     +62
send_offer                                           403     421     +18
send_ACK                                             232     249     +17
read_leases                                          249     258      +9
dumpleases_main                                      604     609      +5
nobody_responds_to_arp                                84      86      +2
udhcp_end_option                                      32      30      -2
udhcp_get_option                                     222     171     -51
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 6/2 up/down: 113/-53)            Total: 60 bytes



Modified:
   trunk/busybox/networking/udhcp/dhcpd.h
   trunk/busybox/networking/udhcp/dumpleases.c
   trunk/busybox/networking/udhcp/files.c
   trunk/busybox/networking/udhcp/leases.c
   trunk/busybox/networking/udhcp/options.c
   trunk/busybox/networking/udhcp/options.h
   trunk/busybox/networking/udhcp/script.c
   trunk/busybox/networking/udhcp/serverpacket.c


Changeset:
Modified: trunk/busybox/networking/udhcp/dhcpd.h
===================================================================
--- trunk/busybox/networking/udhcp/dhcpd.h	2009-04-01 11:24:04 UTC (rev 25915)
+++ trunk/busybox/networking/udhcp/dhcpd.h	2009-04-01 12:36:09 UTC (rev 25916)
@@ -74,9 +74,7 @@
 #define SERVER_PORT 67
 #endif
 
-extern struct dhcpOfferedAddr *leases;
 
-
 /*** leases.h ***/
 
 typedef uint32_t leasetime_t;
@@ -92,9 +90,15 @@
 	 * and optionally adjusted (current time subtracted)
 	 * if server_config.remaining = 1 */
 	leasetime_t expires;
+	uint8_t hostname[20]; /* (size is a multiply of 4) */
 };
 
-struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, leasetime_t leasetime) FAST_FUNC;
+extern struct dhcpOfferedAddr *leases;
+
+struct dhcpOfferedAddr *add_lease(
+		const uint8_t *chaddr, uint32_t yiaddr,
+		leasetime_t leasetime, uint8_t *hostname
+		) FAST_FUNC;
 int lease_expired(struct dhcpOfferedAddr *lease) FAST_FUNC;
 struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr) FAST_FUNC;
 struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) FAST_FUNC;

Modified: trunk/busybox/networking/udhcp/dumpleases.c
===================================================================
--- trunk/busybox/networking/udhcp/dumpleases.c	2009-04-01 11:24:04 UTC (rev 25915)
+++ trunk/busybox/networking/udhcp/dumpleases.c	2009-04-01 12:36:09 UTC (rev 25916)
@@ -47,8 +47,9 @@
 
 	fd = xopen(file, O_RDONLY);
 
-	printf("Mac Address       IP-Address      Expires %s\n", (opt & OPT_a) ? "at" : "in");
-	/*     "00:00:00:00:00:00 255.255.255.255 Wed Jun 30 21:49:08 1993" */
+	printf("Mac Address       IP Address      Host Name           Expires %s\n", (opt & OPT_a) ? "at" : "in");
+	/*     "00:00:00:00:00:00 255.255.255.255 ABCDEFGHIJKLMNOPQRS Wed Jun 30 21:49:08 1993" */
+	/*     "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */
 
 	if (full_read(fd, &written_at, sizeof(written_at)) != sizeof(written_at))
 		return 0;
@@ -64,7 +65,9 @@
 			fmt = ":%02x";
 		}
 		addr.s_addr = lease.yiaddr;
-		printf(" %-15s ", inet_ntoa(addr));
+		/* actually, 15+1 and 19+1, +1 is a space between columns */
+		/* lease.hostname is char[20] and is always NUL terminated */
+		printf(" %-16s%-20s", inet_ntoa(addr), lease.hostname);
 		expires_abs = ntohl(lease.expires) + written_at;
 		if (expires_abs <= curr) {
 			puts("expired");

Modified: trunk/busybox/networking/udhcp/files.c
===================================================================
--- trunk/busybox/networking/udhcp/files.c	2009-04-01 11:24:04 UTC (rev 25915)
+++ trunk/busybox/networking/udhcp/files.c	2009-04-01 12:36:09 UTC (rev 25916)
@@ -420,7 +420,7 @@
 				continue;
 			/* NB: add_lease takes "relative time", IOW,
 			 * lease duration, not lease deadline. */
-			if (!(add_lease(lease.chaddr, lease.yiaddr, expires))) {
+			if (!(add_lease(lease.chaddr, lease.yiaddr, expires, lease.hostname))) {
 				bb_error_msg("too many leases while loading %s", file);
 				break;
 			}

Modified: trunk/busybox/networking/udhcp/leases.c
===================================================================
--- trunk/busybox/networking/udhcp/leases.c	2009-04-01 11:24:04 UTC (rev 25915)
+++ trunk/busybox/networking/udhcp/leases.c	2009-04-01 12:36:09 UTC (rev 25916)
@@ -48,9 +48,12 @@
 
 
 /* Add a lease into the table, clearing out any old ones */
-struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiaddr, leasetime_t leasetime)
+struct dhcpOfferedAddr* FAST_FUNC add_lease(
+		const uint8_t *chaddr, uint32_t yiaddr,
+		leasetime_t leasetime, uint8_t *hostname)
 {
 	struct dhcpOfferedAddr *oldest;
+	uint8_t hostname_length;
 
 	/* clean out any old ones */
 	clear_lease(chaddr, yiaddr);
@@ -58,6 +61,19 @@
 	oldest = oldest_expired_lease();
 
 	if (oldest) {
+		oldest->hostname[0] = '\0';
+		if (hostname) {
+        		hostname_length = hostname[-1]; /* look at option size byte */
+			if (hostname_length > sizeof(oldest->hostname))
+				hostname_length = sizeof(oldest->hostname);
+            		hostname = (uint8_t*) safe_strncpy((char*)oldest->hostname, (char*)hostname, hostname_length);
+			/* sanitization (s/non-ACSII/^/g) */
+			while (*hostname) {
+				if (*hostname < ' ' || *hostname > 126)
+					*hostname = '^';
+				hostname++;
+			}
+		}
 		memcpy(oldest->chaddr, chaddr, 16);
 		oldest->yiaddr = yiaddr;
 		oldest->expires = time(NULL) + leasetime;
@@ -117,7 +133,7 @@
 	temp.s_addr = addr;
 	bb_info_msg("%s belongs to someone, reserving it for %u seconds",
 		inet_ntoa(temp), (unsigned)server_config.conflict_time);
-	add_lease(blank_chaddr, addr, server_config.conflict_time);
+	add_lease(blank_chaddr, addr, server_config.conflict_time, NULL);
 	return 0;
 }
 

Modified: trunk/busybox/networking/udhcp/options.c
===================================================================
--- trunk/busybox/networking/udhcp/options.c	2009-04-01 11:24:04 UTC (rev 25915)
+++ trunk/busybox/networking/udhcp/options.c	2009-04-01 12:36:09 UTC (rev 25916)
@@ -119,58 +119,61 @@
 };
 
 
-/* get an option with bounds checking (warning, not aligned). */
+/* get an option with bounds checking (warning, result is not aligned). */
 uint8_t* FAST_FUNC get_option(struct dhcpMessage *packet, int code)
 {
-	int i, length;
 	uint8_t *optionptr;
-	int over = 0;
-	int curr = OPTION_FIELD;
+	int len;
+	int rem;
+	int overload = 0;
+	enum {
+		FILE_FIELD101  = FILE_FIELD  * 0x101,
+		SNAME_FIELD101 = SNAME_FIELD * 0x101,
+	};
 
+	/* option bytes: [code][len][data1][data2]..[dataLEN] */
 	optionptr = packet->options;
-	i = 0;
-	length = sizeof(packet->options);
+	rem = sizeof(packet->options);
 	while (1) {
-		if (i >= length) {
-			bb_error_msg("bogus packet, option fields too long");
+		if (rem <= 0) {
+			bb_error_msg("bogus packet, malformed option field");
 			return NULL;
 		}
-		if (optionptr[i + OPT_CODE] == code) {
-			if (i + 1 + optionptr[i + OPT_LEN] >= length) {
-				bb_error_msg("bogus packet, option fields too long");
-				return NULL;
-			}
-			return optionptr + i + 2;
+		if (optionptr[OPT_CODE] == DHCP_PADDING) {
+			rem--;
+			optionptr++;
+			continue;
 		}
-		switch (optionptr[i + OPT_CODE]) {
-		case DHCP_PADDING:
-			i++;
-			break;
-		case DHCP_OPTION_OVER:
-			if (i + 1 + optionptr[i + OPT_LEN] >= length) {
-				bb_error_msg("bogus packet, option fields too long");
-				return NULL;
+		if (optionptr[OPT_CODE] == DHCP_END) {
+			if ((overload & FILE_FIELD101) == FILE_FIELD) {
+				/* can use packet->file, and didn't look at it yet */
+				overload |= FILE_FIELD101; /* "we looked at it" */
+				optionptr = packet->file;
+				rem = sizeof(packet->file);
+				continue;
 			}
-			over = optionptr[i + 3];
-			i += optionptr[OPT_LEN] + 2;
-			break;
-		case DHCP_END:
-			if (curr == OPTION_FIELD && (over & FILE_FIELD)) {
-				optionptr = packet->file;
-				i = 0;
-				length = sizeof(packet->file);
-				curr = FILE_FIELD;
-			} else if (curr == FILE_FIELD && (over & SNAME_FIELD)) {
+			if ((overload & SNAME_FIELD101) == SNAME_FIELD) {
+				/* can use packet->sname, and didn't look at it yet */
+				overload |= SNAME_FIELD101; /* "we looked at it" */
 				optionptr = packet->sname;
-				i = 0;
-				length = sizeof(packet->sname);
-				curr = SNAME_FIELD;
-			} else
-				return NULL;
-			break;
-		default:
-			i += optionptr[OPT_LEN + i] + 2;
+				rem = sizeof(packet->sname);
+				continue;
+			}
+			return NULL;
 		}
+		len = 2 + optionptr[OPT_LEN];
+		rem -= len;
+		if (rem < 0)
+			continue; /* complain and return NULL */
+
+		if (optionptr[OPT_CODE] == code)
+			return optionptr + OPT_DATA;
+
+		if (optionptr[OPT_CODE] == DHCP_OPTION_OVERLOAD) {
+			overload |= optionptr[OPT_DATA];
+			/* fall through */
+		}
+		optionptr += len;
 	}
 	return NULL;
 }
@@ -182,17 +185,16 @@
 	int i = 0;
 
 	while (optionptr[i] != DHCP_END) {
-		if (optionptr[i] == DHCP_PADDING)
-			i++;
-		else
-			i += optionptr[i + OPT_LEN] + 2;
+		if (optionptr[i] != DHCP_PADDING)
+			i += optionptr[i + OPT_LEN] + 1;
+		i++;
 	}
 	return i;
 }
 
 
-/* add an option string to the options (an option string contains an option code,
- * length, then data) */
+/* add an option string to the options */
+/* option bytes: [code][len][data1][data2]..[dataLEN] */
 int FAST_FUNC add_option_string(uint8_t *optionptr, uint8_t *string)
 {
 	int end = end_option(optionptr);

Modified: trunk/busybox/networking/udhcp/options.h
===================================================================
--- trunk/busybox/networking/udhcp/options.h	2009-04-01 11:24:04 UTC (rev 25915)
+++ trunk/busybox/networking/udhcp/options.h	2009-04-01 12:36:09 UTC (rev 25916)
@@ -7,7 +7,7 @@
 # pragma GCC visibility push(hidden)
 #endif
 
-#define TYPE_MASK	0x0F
+#define TYPE_MASK       0x0F
 
 enum {
 	OPTION_IP = 1,
@@ -24,8 +24,8 @@
 	OPTION_S32
 };
 
-#define OPTION_REQ	0x10 /* have the client request this option */
-#define OPTION_LIST	0x20 /* There can be a list of 1 or more of these */
+#define OPTION_REQ      0x10 /* have the client request this option */
+#define OPTION_LIST     0x20 /* There can be a list of 1 or more of these */
 
 /*****************************************************************/
 /* Do not modify below here unless you know what you are doing!! */
@@ -34,68 +34,65 @@
 /* DHCP protocol -- see RFC 2131 */
 #define DHCP_MAGIC		0x63825363
 
-
 /* DHCP option codes (partial list) */
-#define DHCP_PADDING		0x00
-#define DHCP_SUBNET		0x01
-#define DHCP_TIME_OFFSET	0x02
-#define DHCP_ROUTER		0x03
-#define DHCP_TIME_SERVER	0x04
-#define DHCP_NAME_SERVER	0x05
-#define DHCP_DNS_SERVER		0x06
-#define DHCP_LOG_SERVER		0x07
-#define DHCP_COOKIE_SERVER	0x08
-#define DHCP_LPR_SERVER		0x09
-#define DHCP_HOST_NAME		0x0c
-#define DHCP_BOOT_SIZE		0x0d
-#define DHCP_DOMAIN_NAME	0x0f
-#define DHCP_SWAP_SERVER	0x10
-#define DHCP_ROOT_PATH		0x11
-#define DHCP_IP_TTL		0x17
-#define DHCP_MTU		0x1a
-#define DHCP_BROADCAST		0x1c
-#define DHCP_NTP_SERVER		0x2a
-#define DHCP_WINS_SERVER	0x2c
-#define DHCP_REQUESTED_IP	0x32
-#define DHCP_LEASE_TIME		0x33
-#define DHCP_OPTION_OVER	0x34
-#define DHCP_MESSAGE_TYPE	0x35
-#define DHCP_SERVER_ID		0x36
-#define DHCP_PARAM_REQ		0x37
-#define DHCP_MESSAGE		0x38
-#define DHCP_MAX_SIZE		0x39
-#define DHCP_T1			0x3a
-#define DHCP_T2			0x3b
-#define DHCP_VENDOR		0x3c
-#define DHCP_CLIENT_ID		0x3d
-#define DHCP_FQDN		0x51
-#define DHCP_END		0xFF
+#define DHCP_PADDING            0x00
+#define DHCP_SUBNET             0x01
+#define DHCP_TIME_OFFSET        0x02
+#define DHCP_ROUTER             0x03
+#define DHCP_TIME_SERVER        0x04
+#define DHCP_NAME_SERVER        0x05
+#define DHCP_DNS_SERVER         0x06
+#define DHCP_LOG_SERVER         0x07
+#define DHCP_COOKIE_SERVER      0x08
+#define DHCP_LPR_SERVER         0x09
+#define DHCP_HOST_NAME          0x0c
+#define DHCP_BOOT_SIZE          0x0d
+#define DHCP_DOMAIN_NAME        0x0f
+#define DHCP_SWAP_SERVER        0x10
+#define DHCP_ROOT_PATH          0x11
+#define DHCP_IP_TTL             0x17
+#define DHCP_MTU                0x1a
+#define DHCP_BROADCAST          0x1c
+#define DHCP_NTP_SERVER         0x2a
+#define DHCP_WINS_SERVER        0x2c
+#define DHCP_REQUESTED_IP       0x32
+#define DHCP_LEASE_TIME         0x33
+#define DHCP_OPTION_OVERLOAD    0x34
+#define DHCP_MESSAGE_TYPE       0x35
+#define DHCP_SERVER_ID          0x36
+#define DHCP_PARAM_REQ          0x37
+#define DHCP_MESSAGE            0x38
+#define DHCP_MAX_SIZE           0x39
+#define DHCP_T1                 0x3a
+#define DHCP_T2                 0x3b
+#define DHCP_VENDOR             0x3c
+#define DHCP_CLIENT_ID          0x3d
+#define DHCP_FQDN               0x51
+#define DHCP_END                0xFF
+/* Offsets in option byte sequence */
+#define OPT_CODE                0
+#define OPT_LEN                 1
+#define OPT_DATA                2
+/* Bits in "overload" option */
+#define OPTION_FIELD            0
+#define FILE_FIELD              1
+#define SNAME_FIELD             2
 
+#define BOOTREQUEST             1
+#define BOOTREPLY               2
 
-#define BOOTREQUEST		1
-#define BOOTREPLY		2
+#define ETH_10MB                1
+#define ETH_10MB_LEN            6
 
-#define ETH_10MB		1
-#define ETH_10MB_LEN		6
+#define DHCPDISCOVER            1 /* client -> server */
+#define DHCPOFFER               2 /* client <- server */
+#define DHCPREQUEST             3 /* client -> server */
+#define DHCPDECLINE             4 /* client -> server */
+#define DHCPACK                 5 /* client <- server */
+#define DHCPNAK                 6 /* client <- server */
+#define DHCPRELEASE             7 /* client -> server */
+#define DHCPINFORM              8 /* client -> server */
 
-#define DHCPDISCOVER		1 /* client -> server */
-#define DHCPOFFER		2 /* client <- server */
-#define DHCPREQUEST		3 /* client -> server */
-#define DHCPDECLINE		4 /* client -> server */
-#define DHCPACK			5 /* client <- server */
-#define DHCPNAK			6 /* client <- server */
-#define DHCPRELEASE		7 /* client -> server */
-#define DHCPINFORM		8 /* client -> server */
-
-#define OPTION_FIELD		0
-#define FILE_FIELD		1
-#define SNAME_FIELD		2
-
-/* miscellaneous defines */
-#define OPT_CODE 0
-#define OPT_LEN 1
-#define OPT_DATA 2
-
 struct dhcp_option {
 	uint8_t flags;
 	uint8_t code;

Modified: trunk/busybox/networking/udhcp/script.c
===================================================================
--- trunk/busybox/networking/udhcp/script.c	2009-04-01 11:24:04 UTC (rev 25915)
+++ trunk/busybox/networking/udhcp/script.c	2009-04-01 12:36:09 UTC (rev 25916)
@@ -135,7 +135,7 @@
 	char **envp, **curr;
 	const char *opt_name;
 	uint8_t *temp;
-	char over = 0;
+	uint8_t over = 0;
 
 	if (packet) {
 		for (i = 0; dhcp_options[i].code; i++) {
@@ -147,7 +147,7 @@
 		}
 		if (packet->siaddr)
 			num_options++;
-		temp = get_option(packet, DHCP_OPTION_OVER);
+		temp = get_option(packet, DHCP_OPTION_OVERLOAD);
 		if (temp)
 			over = *temp;
 		if (!(over & FILE_FIELD) && packet->file[0])

Modified: trunk/busybox/networking/udhcp/serverpacket.c
===================================================================
--- trunk/busybox/networking/udhcp/serverpacket.c	2009-04-01 11:24:04 UTC (rev 25915)
+++ trunk/busybox/networking/udhcp/serverpacket.c	2009-04-01 12:36:09 UTC (rev 25916)
@@ -105,7 +105,7 @@
 	uint32_t req_align;
 	uint32_t lease_time_aligned = server_config.lease;
 	uint32_t static_lease_ip;
-	uint8_t *req, *lease_time;
+	uint8_t *req, *lease_time, *p_host_name;
 	struct option_set *curr;
 	struct in_addr addr;
 
@@ -146,7 +146,8 @@
 			bb_error_msg("no IP addresses to give - OFFER abandoned");
 			return -1;
 		}
-		if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) {
+		p_host_name = get_option(oldpacket, DHCP_HOST_NAME);
+		if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time, p_host_name)) {
 			bb_error_msg("lease pool is full - OFFER abandoned");
 			return -1;
 		}
@@ -201,6 +202,7 @@
 	uint8_t *lease_time;
 	uint32_t lease_time_aligned = server_config.lease;
 	struct in_addr addr;
+	uint8_t *p_host_name;
 
 	init_packet(&packet, oldpacket, DHCPACK);
 	packet.yiaddr = yiaddr;
@@ -232,7 +234,8 @@
 	if (send_packet(&packet, 0) < 0)
 		return -1;
 
-	add_lease(packet.chaddr, packet.yiaddr, lease_time_aligned);
+	p_host_name = get_option(oldpacket, DHCP_HOST_NAME);
+	add_lease(packet.chaddr, packet.yiaddr, lease_time_aligned, p_host_name);
 	if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) {
 		/* rewrite the file with leases at every new acceptance */
 		write_leases();



More information about the busybox-cvs mailing list