Browse Source

[dhcpv6] Use DUID-UUID form of client DUID

Use the system UUID to generate the client DUID-UUID as per RFC 6355.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
8aab959bed
2 changed files with 28 additions and 28 deletions
  1. 7
    8
      src/include/ipxe/dhcpv6.h
  2. 21
    20
      src/net/udp/dhcpv6.c

+ 7
- 8
src/include/ipxe/dhcpv6.h View File

11
 
11
 
12
 #include <stdint.h>
12
 #include <stdint.h>
13
 #include <ipxe/in.h>
13
 #include <ipxe/in.h>
14
+#include <ipxe/uuid.h>
14
 
15
 
15
 /** DHCPv6 server port */
16
 /** DHCPv6 server port */
16
 #define DHCPV6_SERVER_PORT 547
17
 #define DHCPV6_SERVER_PORT 547
31
 	uint8_t data[0];
32
 	uint8_t data[0];
32
 } __attribute__ (( packed ));
33
 } __attribute__ (( packed ));
33
 
34
 
34
-/** DHCP unique identifier based on link-layer address (DUID-LL) */
35
-struct dhcpv6_duid_ll {
35
+/** DHCP unique identifier based on UUID (DUID-UUID) */
36
+struct dhcpv6_duid_uuid {
36
 	/** Type */
37
 	/** Type */
37
 	uint16_t type;
38
 	uint16_t type;
38
-	/** Hardware type */
39
-	uint16_t htype;
40
-	/** Link-layer address */
41
-	uint8_t ll_addr[0];
39
+	/** UUID */
40
+	union uuid uuid;
42
 } __attribute__ (( packed ));
41
 } __attribute__ (( packed ));
43
 
42
 
44
-/** DHCP unique identifier based on link-layer address (DUID-LL) */
45
-#define DHCPV6_DUID_LL 3
43
+/** DHCP unique identifier based on UUID (DUID-UUID) */
44
+#define DHCPV6_DUID_UUID 4
46
 
45
 
47
 /** DHCPv6 client or server identifier option */
46
 /** DHCPv6 client or server identifier option */
48
 struct dhcpv6_duid_option {
47
 struct dhcpv6_duid_option {

+ 21
- 20
src/net/udp/dhcpv6.c View File

457
 	/** Start time (in ticks) */
457
 	/** Start time (in ticks) */
458
 	unsigned long start;
458
 	unsigned long start;
459
 	/** Client DUID */
459
 	/** Client DUID */
460
-	void *client_duid;
461
-	/** Client DUID length */
462
-	size_t client_duid_len;
460
+	struct dhcpv6_duid_uuid client_duid;
463
 	/** Server DUID, if known */
461
 	/** Server DUID, if known */
464
 	void *server_duid;
462
 	void *server_duid;
465
 	/** Server DUID length */
463
 	/** Server DUID length */
578
 	int rc;
576
 	int rc;
579
 
577
 
580
 	/* Calculate lengths */
578
 	/* Calculate lengths */
581
-	client_id_len = ( sizeof ( *client_id ) + dhcpv6->client_duid_len );
579
+	client_id_len = ( sizeof ( *client_id ) +
580
+			  sizeof ( dhcpv6->client_duid ) );
582
 	server_id_len = ( dhcpv6->server_duid ? ( sizeof ( *server_id ) +
581
 	server_id_len = ( dhcpv6->server_duid ? ( sizeof ( *server_id ) +
583
 						  dhcpv6->server_duid_len ) :0);
582
 						  dhcpv6->server_duid_len ) :0);
584
 	if ( dhcpv6->state->flags & DHCPV6_TX_IA_NA ) {
583
 	if ( dhcpv6->state->flags & DHCPV6_TX_IA_NA ) {
614
 	client_id->header.code = htons ( DHCPV6_CLIENT_ID );
613
 	client_id->header.code = htons ( DHCPV6_CLIENT_ID );
615
 	client_id->header.len = htons ( client_id_len -
614
 	client_id->header.len = htons ( client_id_len -
616
 					sizeof ( client_id->header ) );
615
 					sizeof ( client_id->header ) );
617
-	memcpy ( client_id->duid, dhcpv6->client_duid,
618
-		 dhcpv6->client_duid_len );
616
+	memcpy ( client_id->duid, &dhcpv6->client_duid,
617
+		 sizeof ( dhcpv6->client_duid ) );
619
 
618
 
620
 	/* Construct server identifier, if applicable */
619
 	/* Construct server identifier, if applicable */
621
 	if ( server_id_len ) {
620
 	if ( server_id_len ) {
748
 
747
 
749
 	/* Verify client identifier */
748
 	/* Verify client identifier */
750
 	if ( ( rc = dhcpv6_check_duid ( &options, DHCPV6_CLIENT_ID,
749
 	if ( ( rc = dhcpv6_check_duid ( &options, DHCPV6_CLIENT_ID,
751
-					dhcpv6->client_duid,
752
-					dhcpv6->client_duid_len ) ) != 0 ) {
750
+					&dhcpv6->client_duid,
751
+					sizeof ( dhcpv6->client_duid ) ) ) !=0){
753
 		DBGC ( dhcpv6, "DHCPv6 %s received %s without correct client "
752
 		DBGC ( dhcpv6, "DHCPv6 %s received %s without correct client "
754
 		       "ID: %s\n", dhcpv6->netdev->name,
753
 		       "ID: %s\n", dhcpv6->netdev->name,
755
 		       dhcpv6_type_name ( dhcphdr->type ), strerror ( rc ) );
754
 		       dhcpv6_type_name ( dhcphdr->type ), strerror ( rc ) );
904
 			struct sockaddr sa;
903
 			struct sockaddr sa;
905
 		} server;
904
 		} server;
906
 	} addresses;
905
 	} addresses;
907
-	struct dhcpv6_duid_ll *client_duid;
908
-	size_t client_duid_len;
909
 	uint32_t xid;
906
 	uint32_t xid;
907
+	int len;
910
 	int rc;
908
 	int rc;
911
 
909
 
912
 	/* Allocate and initialise structure */
910
 	/* Allocate and initialise structure */
913
-	client_duid_len = ( sizeof ( *client_duid ) + ll_protocol->ll_addr_len);
914
-	dhcpv6 = zalloc ( sizeof ( *dhcpv6 ) + client_duid_len );
911
+	dhcpv6 = zalloc ( sizeof ( *dhcpv6 ) );
915
 	if ( ! dhcpv6 )
912
 	if ( ! dhcpv6 )
916
 		return -ENOMEM;
913
 		return -ENOMEM;
917
 	ref_init ( &dhcpv6->refcnt, dhcpv6_free );
914
 	ref_init ( &dhcpv6->refcnt, dhcpv6_free );
921
 	xid = random();
918
 	xid = random();
922
 	memcpy ( dhcpv6->xid, &xid, sizeof ( dhcpv6->xid ) );
919
 	memcpy ( dhcpv6->xid, &xid, sizeof ( dhcpv6->xid ) );
923
 	dhcpv6->start = currticks();
920
 	dhcpv6->start = currticks();
924
-	dhcpv6->client_duid = ( ( ( void * ) dhcpv6 ) + sizeof ( *dhcpv6 ) );
925
-	dhcpv6->client_duid_len = client_duid_len;
926
 	timer_init ( &dhcpv6->timer, dhcpv6_timer_expired, &dhcpv6->refcnt );
921
 	timer_init ( &dhcpv6->timer, dhcpv6_timer_expired, &dhcpv6->refcnt );
927
 
922
 
928
 	/* Construct client and server addresses */
923
 	/* Construct client and server addresses */
935
 	addresses.server.sin6.sin6_scope_id = netdev->index;
930
 	addresses.server.sin6.sin6_scope_id = netdev->index;
936
 	addresses.server.sin6.sin6_port = htons ( DHCPV6_SERVER_PORT );
931
 	addresses.server.sin6.sin6_port = htons ( DHCPV6_SERVER_PORT );
937
 
932
 
938
-	/* Construct client DUID and IAID from link-layer address */
939
-	client_duid = dhcpv6->client_duid;
940
-	client_duid->type = htons ( DHCPV6_DUID_LL );
941
-	client_duid->htype = ll_protocol->ll_proto;
942
-	memcpy ( client_duid->ll_addr, netdev->ll_addr,
943
-		 ll_protocol->ll_addr_len );
933
+	/* Construct client DUID from system UUID */
934
+	dhcpv6->client_duid.type = htons ( DHCPV6_DUID_UUID );
935
+	if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting,
936
+					  &dhcpv6->client_duid.uuid ) ) < 0 ) {
937
+		rc = len;
938
+		DBGC ( dhcpv6, "DHCPv6 %s could not create DUID-UUID: %s\n",
939
+		       dhcpv6->netdev->name, strerror ( rc ) );
940
+		goto err_client_duid;
941
+	}
942
+
943
+	/* Construct IAID from link-layer address */
944
 	dhcpv6->iaid = crc32_le ( 0, netdev->ll_addr, ll_protocol->ll_addr_len);
944
 	dhcpv6->iaid = crc32_le ( 0, netdev->ll_addr, ll_protocol->ll_addr_len);
945
 	DBGC ( dhcpv6, "DHCPv6 %s has XID %02x%02x%02x\n", dhcpv6->netdev->name,
945
 	DBGC ( dhcpv6, "DHCPv6 %s has XID %02x%02x%02x\n", dhcpv6->netdev->name,
946
 	       dhcpv6->xid[0], dhcpv6->xid[1], dhcpv6->xid[2] );
946
 	       dhcpv6->xid[0], dhcpv6->xid[1], dhcpv6->xid[2] );
965
 
965
 
966
  err_open_socket:
966
  err_open_socket:
967
 	dhcpv6_finished ( dhcpv6, rc );
967
 	dhcpv6_finished ( dhcpv6, rc );
968
+ err_client_duid:
968
 	ref_put ( &dhcpv6->refcnt );
969
 	ref_put ( &dhcpv6->refcnt );
969
 	return rc;
970
 	return rc;
970
 }
971
 }

Loading…
Cancel
Save