error_t dhcpv6RelayJoinMulticastGroup(Dhcpv6RelayCtx *context) { uint_t i; uint_t j; //Initialize status code error_t error = NO_ERROR; //Loop through the client-facing interfaces for(i = 0; i < context->clientInterfaceCount; i++) { //Join the All_DHCP_Relay_Agents_and_Servers multicast //group for each interface error = ipv6JoinMulticastGroup(context->clientInterface[i], &DHCPV6_ALL_RELAY_AGENTS_AND_SERVERS_ADDR); //Unable to join the specified multicast group? if(error) break; } //Did we encounter an error? if(error) { //Clean up side effects before returning... for(j = 0; j < i; j++) { //Leave the multicast group for each interface ipv6LeaveMulticastGroup(context->clientInterface[j], &DHCPV6_ALL_RELAY_AGENTS_AND_SERVERS_ADDR); } } //Return status code return error; }
error_t statelessAddrConfig(NetInterface *interface) { error_t error; Eui64 interfaceId; Ipv6Addr linkLocalAddr; Ipv6Addr solicitedNodeAddr; //Generate the 64-bit interface identifier macAddrToEui64(&interface->macAddr, &interfaceId); //A link-local address is formed by combining the well-known //link-local prefix fe80::0 with the interface identifier linkLocalAddr.w[0] = htons(0xFE80); linkLocalAddr.w[1] = htons(0x0000); linkLocalAddr.w[2] = htons(0x0000); linkLocalAddr.w[3] = htons(0x0000); linkLocalAddr.w[4] = interfaceId.w[0]; linkLocalAddr.w[5] = interfaceId.w[1]; linkLocalAddr.w[6] = interfaceId.w[2]; linkLocalAddr.w[7] = interfaceId.w[3]; //Form the Solicited-Node address ipv6ComputeSolicitedNodeAddr(&linkLocalAddr, &solicitedNodeAddr); //Join the Solicited-Node multicast group for the tentative address ipv6JoinMulticastGroup(interface, &solicitedNodeAddr); //Ensure that the address is not already in use on the local network error = slaacDetectDuplicateAddr(&linkLocalAddr); //If a duplicate address is discovered during the procedure, //the address cannot be assigned to the interface if(error) { ipv6LeaveMulticastGroup(interface, &solicitedNodeAddr); return error; } //Assign the link-local address to the local IPv6 address interface->ipv6Config.linkLocalAddr = linkLocalAddr; //The node next attempts to contact a local router for more //information on continuing the configuration //The global address is formed by appending the interface //identifier to a prefix of appropriate length //Successful configuration return NO_ERROR; }
error_t dhcpv6RelayLeaveMulticastGroup(Dhcpv6RelayCtx *context) { uint_t i; //Loop through the client-facing interfaces for(i = 0; i < context->clientInterfaceCount; i++) { //Leave the All_DHCP_Relay_Agents_and_Servers multicast //group for each interface ipv6LeaveMulticastGroup(context->clientInterface[i], &DHCPV6_ALL_RELAY_AGENTS_AND_SERVERS_ADDR); } //Successsful processing return NO_ERROR; }