Kaynağa Gözat

[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 yıl önce
ebeveyn
işleme
8aab959bed
2 değiştirilmiş dosya ile 28 ekleme ve 28 silme
  1. 7
    8
      src/include/ipxe/dhcpv6.h
  2. 21
    20
      src/net/udp/dhcpv6.c

+ 7
- 8
src/include/ipxe/dhcpv6.h Dosyayı Görüntüle

@@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
11 11
 
12 12
 #include <stdint.h>
13 13
 #include <ipxe/in.h>
14
+#include <ipxe/uuid.h>
14 15
 
15 16
 /** DHCPv6 server port */
16 17
 #define DHCPV6_SERVER_PORT 547
@@ -31,18 +32,16 @@ struct dhcpv6_option {
31 32
 	uint8_t data[0];
32 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 37
 	/** Type */
37 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 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 46
 /** DHCPv6 client or server identifier option */
48 47
 struct dhcpv6_duid_option {

+ 21
- 20
src/net/udp/dhcpv6.c Dosyayı Görüntüle

@@ -457,9 +457,7 @@ struct dhcpv6_session {
457 457
 	/** Start time (in ticks) */
458 458
 	unsigned long start;
459 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 461
 	/** Server DUID, if known */
464 462
 	void *server_duid;
465 463
 	/** Server DUID length */
@@ -578,7 +576,8 @@ static int dhcpv6_tx ( struct dhcpv6_session *dhcpv6 ) {
578 576
 	int rc;
579 577
 
580 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 581
 	server_id_len = ( dhcpv6->server_duid ? ( sizeof ( *server_id ) +
583 582
 						  dhcpv6->server_duid_len ) :0);
584 583
 	if ( dhcpv6->state->flags & DHCPV6_TX_IA_NA ) {
@@ -614,8 +613,8 @@ static int dhcpv6_tx ( struct dhcpv6_session *dhcpv6 ) {
614 613
 	client_id->header.code = htons ( DHCPV6_CLIENT_ID );
615 614
 	client_id->header.len = htons ( client_id_len -
616 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 619
 	/* Construct server identifier, if applicable */
621 620
 	if ( server_id_len ) {
@@ -748,8 +747,8 @@ static int dhcpv6_rx ( struct dhcpv6_session *dhcpv6,
748 747
 
749 748
 	/* Verify client identifier */
750 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 752
 		DBGC ( dhcpv6, "DHCPv6 %s received %s without correct client "
754 753
 		       "ID: %s\n", dhcpv6->netdev->name,
755 754
 		       dhcpv6_type_name ( dhcphdr->type ), strerror ( rc ) );
@@ -904,14 +903,12 @@ int start_dhcpv6 ( struct interface *job, struct net_device *netdev,
904 903
 			struct sockaddr sa;
905 904
 		} server;
906 905
 	} addresses;
907
-	struct dhcpv6_duid_ll *client_duid;
908
-	size_t client_duid_len;
909 906
 	uint32_t xid;
907
+	int len;
910 908
 	int rc;
911 909
 
912 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 912
 	if ( ! dhcpv6 )
916 913
 		return -ENOMEM;
917 914
 	ref_init ( &dhcpv6->refcnt, dhcpv6_free );
@@ -921,8 +918,6 @@ int start_dhcpv6 ( struct interface *job, struct net_device *netdev,
921 918
 	xid = random();
922 919
 	memcpy ( dhcpv6->xid, &xid, sizeof ( dhcpv6->xid ) );
923 920
 	dhcpv6->start = currticks();
924
-	dhcpv6->client_duid = ( ( ( void * ) dhcpv6 ) + sizeof ( *dhcpv6 ) );
925
-	dhcpv6->client_duid_len = client_duid_len;
926 921
 	timer_init ( &dhcpv6->timer, dhcpv6_timer_expired, &dhcpv6->refcnt );
927 922
 
928 923
 	/* Construct client and server addresses */
@@ -935,12 +930,17 @@ int start_dhcpv6 ( struct interface *job, struct net_device *netdev,
935 930
 	addresses.server.sin6.sin6_scope_id = netdev->index;
936 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 944
 	dhcpv6->iaid = crc32_le ( 0, netdev->ll_addr, ll_protocol->ll_addr_len);
945 945
 	DBGC ( dhcpv6, "DHCPv6 %s has XID %02x%02x%02x\n", dhcpv6->netdev->name,
946 946
 	       dhcpv6->xid[0], dhcpv6->xid[1], dhcpv6->xid[2] );
@@ -965,6 +965,7 @@ int start_dhcpv6 ( struct interface *job, struct net_device *netdev,
965 965
 
966 966
  err_open_socket:
967 967
 	dhcpv6_finished ( dhcpv6, rc );
968
+ err_client_duid:
968 969
 	ref_put ( &dhcpv6->refcnt );
969 970
 	return rc;
970 971
 }

Loading…
İptal
Kaydet