[SLOF] [PATCH 6/7] net-snk: Use transaction IDs in DHCPv4, too

Thomas Huth thuth at redhat.com
Fri Dec 18 07:18:55 AEDT 2015


Generate a proper transaction ID before sending DHCPv4 packets
and check whether the DHCPv4 replies contain that correct XID, too.

Signed-off-by: Thomas Huth <thuth at redhat.com>
---
 clients/net-snk/app/netapps/netboot.c |  2 ++
 clients/net-snk/app/netlib/dhcp.c     | 17 +++++++++++++++--
 clients/net-snk/app/netlib/dhcp.h     |  1 +
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/clients/net-snk/app/netapps/netboot.c b/clients/net-snk/app/netapps/netboot.c
index d51d5a8..9f5ff8d 100644
--- a/clients/net-snk/app/netapps/netboot.c
+++ b/clients/net-snk/app/netapps/netboot.c
@@ -332,6 +332,8 @@ int dhcp(char *ret_buffer, filename_ip_t * fn_ip, unsigned int retries, int flag
 	int i = (int) retries+1;
 	int rc = -1;
 
+	if (flags != F_IPV6)
+		dhcpv4_generate_transaction_id();
 	if (flags != F_IPV4)
 		dhcpv6_generate_transaction_id();
 
diff --git a/clients/net-snk/app/netlib/dhcp.c b/clients/net-snk/app/netlib/dhcp.c
index 5f26f3a..bd9c104 100644
--- a/clients/net-snk/app/netlib/dhcp.c
+++ b/clients/net-snk/app/netlib/dhcp.c
@@ -178,11 +178,18 @@ static uint32_t dhcp_server_ip     = 0;
 static uint32_t dhcp_siaddr_ip     = 0;
 static int8_t   dhcp_filename[256];
 static int8_t   dhcp_tftp_name[256];
+static uint32_t dhcp_xid;
 
 static char   * response_buffer;
 
 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<<*/
 
+void
+dhcpv4_generate_transaction_id(void)
+{
+	dhcp_xid = (rand() << 16) ^ rand();
+}
+
 int32_t
 dhcpv4(char *ret_buffer, filename_ip_t * fn_ip) {
 
@@ -627,6 +634,7 @@ dhcp_send_discover(int fd) {
 	btph -> op = 1;
 	btph -> htype = 1;
 	btph -> hlen = 6;
+	btph -> xid = dhcp_xid;
 	memcpy(btph -> chaddr, get_mac_address(), 6);
 
 	memset(&opt, 0, sizeof(dhcp_options_t));
@@ -670,6 +678,7 @@ dhcp_send_request(int fd) {
 	btph -> op = 1;
 	btph -> htype = 1;
 	btph -> hlen = 6;
+	btph -> xid = dhcp_xid;
 	memcpy(btph -> chaddr, get_mac_address(), 6);
 
 	memset(&opt, 0, sizeof(dhcp_options_t));
@@ -718,6 +727,7 @@ void dhcp_send_release(int fd) {
 	btph -> op = 1;
 	btph -> htype = 1;
 	btph -> hlen = 6;
+	btph -> xid = dhcp_xid;
 	strcpy((char *) btph -> file, "");
 	memcpy(btph -> chaddr, get_mac_address(), 6);
 	btph -> ciaddr = htonl(dhcp_own_ip);
@@ -763,8 +773,11 @@ handle_dhcp(int fd, uint8_t * packet, int32_t packetsize) {
 	btph = (struct btphdr *) packet;
 	iph = (struct iphdr *) packet - sizeof(struct udphdr) -
 	      sizeof(struct iphdr);
-	if (btph -> op != 2)
-		return -1; // it is not Boot Reply
+
+	if (btph->op != 2)
+		return -1;		/* It is not a Bootp/DHCP reply */
+	if (btph->xid != dhcp_xid)
+		return -1;		/* The transaction ID does not match */
 
 	if (memcmp(btph -> vend, dhcp_magic, 4)) {
 		// It is BootP - RFC 951
diff --git a/clients/net-snk/app/netlib/dhcp.h b/clients/net-snk/app/netlib/dhcp.h
index 69dd49d..54fb1ee 100644
--- a/clients/net-snk/app/netlib/dhcp.h
+++ b/clients/net-snk/app/netlib/dhcp.h
@@ -43,6 +43,7 @@ struct btphdr {
 	uint8_t vend[64];    /**< Optional parameters field (DHCP-options)     */
 };
 
+void dhcpv4_generate_transaction_id(void);
 int bootp(char *ret_buffer, filename_ip_t *, unsigned int);
 int dhcpv4(char *ret_buffer, filename_ip_t *);
 void dhcp_send_release(int fd);
-- 
1.8.3.1



More information about the SLOF mailing list