|
@@ -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
|
}
|