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 mdnsInit(NetInterface *interface) { error_t error; #if (IPV4_SUPPORT == ENABLED) //Join the mDNS IPv4 multicast group error = ipv4JoinMulticastGroup(interface, MDNS_IPV4_MULTICAST_ADDR); //Any error to report? if(error) return error; #endif #if (IPV6_SUPPORT == ENABLED) //Join the mDNS IPv6 multicast group error = ipv6JoinMulticastGroup(interface, &MDNS_IPV6_MULTICAST_ADDR); //Any error to report? if(error) return error; #endif //Callback function to be called when a mDNS message is received error = udpAttachRxCallback(interface, MDNS_PORT, mdnsProcessMessage, NULL); //Any error to report? if(error) return error; //Successful initialization return NO_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 tcpIpStackConfigInterface(NetInterface *interface) { error_t error; //IPv6 specific variables #if (IPV6_SUPPORT == ENABLED) Ipv6Addr solicitedNodeAddr; #endif //Disable Ethernet controller interrupts interface->nicDriver->disableIrq(interface); //Start of exception handling block do { //Receive notifications when the transmitter is ready to send interface->nicTxEvent = osEventCreate(FALSE, FALSE); //Out of resources? if(interface->nicTxEvent == OS_INVALID_HANDLE) { //Report an error error = ERROR_OUT_OF_RESOURCES; //Stop immediately break; } //Receive notifications when a Ethernet frame has been received, //or the link status has changed interface->nicRxEvent = osEventCreate(FALSE, FALSE); //Out of resources? if(interface->nicRxEvent == OS_INVALID_HANDLE) { //Report an error error = ERROR_OUT_OF_RESOURCES; //Stop immediately break; } //Create a mutex to prevent simultaneous access to the NIC driver interface->nicDriverMutex = osMutexCreate(FALSE); //Out of resources? if(interface->nicDriverMutex == OS_INVALID_HANDLE) { //Report an error error = ERROR_OUT_OF_RESOURCES; //Stop immediately break; } //Ethernet controller configuration error = interface->nicDriver->init(interface); //Any error to report? if(error) break; //Ethernet related initialization error = ethInit(interface); //Any error to report? if(error) break; //IPv4 specific initialization #if (IPV4_SUPPORT == ENABLED) //Network layer initialization error = ipv4Init(interface); //Any error to report? if(error) break; //ARP cache initialization error = arpInit(interface); //Any error to report? if(error) break; #if (IGMP_SUPPORT == ENABLED) //IGMP related initialization error = igmpInit(interface); //Any error to report? if(error) break; //Join the all-systems group error = ipv4JoinMulticastGroup(interface, IGMP_ALL_SYSTEMS_ADDR); //Any error to report? if(error) break; #endif #endif //IPv6 specific initialization #if (IPV6_SUPPORT == ENABLED) //Network layer initialization error = ipv6Init(interface); //Any error to report? if(error) break; //Neighbor cache initialization error = ndpInit(interface); //Any error to report? if(error) break; #if (MLD_SUPPORT == ENABLED) ///MLD related initialization error = mldInit(interface); //Any error to report? if(error) break; #endif //Join the All-Nodes multicast address error = ipv6JoinMulticastGroup(interface, &IPV6_LINK_LOCAL_ALL_NODES_ADDR); //Any error to report? if(error) break; //Form the Solicited-Node address for the link-local address error = ipv6ComputeSolicitedNodeAddr(&interface->ipv6Config.linkLocalAddr, &solicitedNodeAddr); //Any error to report? if(error) break; //Join the Solicited-Node multicast group for each assigned address error = ipv6JoinMulticastGroup(interface, &solicitedNodeAddr); //Any error to report? if(error) break; #endif //Create a task to process incoming frames interface->rxTask = osTaskCreate("TCP/IP Stack (RX)", tcpIpStackRxTask, interface, TCP_IP_RX_STACK_SIZE, TCP_IP_RX_PRIORITY); //Unable to create the task? if(interface->rxTask == OS_INVALID_HANDLE) error = ERROR_OUT_OF_RESOURCES; //End of exception handling block } while(0); //Check whether the interface is fully configured if(!error) { //Successful interface configuration interface->configured = TRUE; //Interrupts can be safely enabled interface->nicDriver->enableIrq(interface); } else { //Clean up side effects before returning osEventClose(interface->nicTxEvent); osEventClose(interface->nicRxEvent); osMutexClose(interface->nicDriverMutex); } //Return status code return error; }