/** Check whether the DestinationAddress is an anycast address. @param[in] IpSb The IP service that received the packet. @param[in] DestinationAddress Points to the Destination Address of the packet. @retval TRUE The DestinationAddress is anycast address. @retval FALSE The DestinationAddress is not anycast address. **/ BOOLEAN Ip6IsAnycast ( IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *DestinationAddress ) { IP6_PREFIX_LIST_ENTRY *PrefixEntry; EFI_IPv6_ADDRESS Prefix; BOOLEAN Flag; ZeroMem (&Prefix, sizeof (EFI_IPv6_ADDRESS)); Flag = FALSE; // // If the address is known as on-link or autonomous prefix, record it as // anycast address. // do { PrefixEntry = Ip6FindPrefixListEntry (IpSb, Flag, 255, DestinationAddress); if (PrefixEntry != NULL) { IP6_COPY_ADDRESS (&Prefix, &PrefixEntry->Prefix); Ip6GetPrefix (PrefixEntry->PrefixLength, &Prefix); if (EFI_IP6_EQUAL (&Prefix, DestinationAddress)) { return TRUE; } } Flag = (BOOLEAN) !Flag; } while (Flag); return FALSE; }
/** The set process of the IfConfig6 application. @param[in] IfList The pointer of IfList(interface list). @param[in] VarArg The pointer of ARG_LIST(Args with "-s" option). @retval EFI_SUCCESS The IfConfig6 set processed successfully. @retval others The IfConfig6 set process failed. **/ EFI_STATUS IfConfig6SetInterfaceInfo ( IN LIST_ENTRY *IfList, IN ARG_LIST *VarArg ) { EFI_STATUS Status; IFCONFIG6_INTERFACE_CB *IfCb; EFI_IP6_CONFIG_MANUAL_ADDRESS *CfgManAddr; EFI_IPv6_ADDRESS *CfgAddr; UINTN AddrSize; EFI_IP6_CONFIG_INTERFACE_ID *InterfaceId; UINT32 DadXmits; UINT32 CurDadXmits; UINTN CurDadXmitsLen; EFI_IP6_CONFIG_POLICY Policy; VAR_CHECK_CODE CheckCode; EFI_EVENT TimeOutEvt; EFI_EVENT MappedEvt; BOOLEAN IsAddressOk; UINTN DataSize; UINT32 Index; UINT32 Index2; BOOLEAN IsAddressSet; EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo; CfgManAddr = NULL; CfgAddr = NULL; TimeOutEvt = NULL; MappedEvt = NULL; IfInfo = NULL; InterfaceId = NULL; CurDadXmits = 0; if (IsListEmpty (IfList)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_INVALID_INTERFACE), mHiiHandle); return EFI_INVALID_PARAMETER; } // // Make sure to set only one interface each time. // IfCb = BASE_CR (IfList->ForwardLink, IFCONFIG6_INTERFACE_CB, Link); Status = EFI_SUCCESS; // // Initialize check list mechanism. // CheckCode = IfConfig6RetriveCheckListByName( NULL, NULL, TRUE ); // // Create events & timers for asynchronous settings. // Status = gBS->CreateEvent ( EVT_TIMER, TPL_CALLBACK, NULL, NULL, &TimeOutEvt ); if (EFI_ERROR (Status)) { goto ON_EXIT; } Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, IfConfig6ManualAddressNotify, &IsAddressOk, &MappedEvt ); if (EFI_ERROR (Status)) { goto ON_EXIT; } // // Parse the setting variables. // while (VarArg != NULL) { // // Check invalid parameters (duplication & unknown & conflict). // CheckCode = IfConfig6RetriveCheckListByName( mSetCheckList, VarArg->Arg, FALSE ); if (VarCheckOk != CheckCode) { switch (CheckCode) { case VarCheckDuplicate: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_DUPLICATE_COMMAND), mHiiHandle, VarArg->Arg); break; case VarCheckConflict: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_CONFLICT_COMMAND), mHiiHandle, VarArg->Arg); break; case VarCheckUnknown: ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_UNKNOWN_COMMAND), mHiiHandle, VarArg->Arg); break; default: break; } VarArg = VarArg->Next; continue; } // // Process valid variables. // if (StrCmp(VarArg->Arg, L"auto") == 0) { // // Set automaic config policy // Policy = Ip6ConfigPolicyAutomatic; Status = IfCb->IfCfg->SetData ( IfCb->IfCfg, Ip6ConfigDataTypePolicy, sizeof (EFI_IP6_CONFIG_POLICY), &Policy ); if (EFI_ERROR(Status)) { goto ON_EXIT; } VarArg= VarArg->Next; } else if (StrCmp (VarArg->Arg, L"man") == 0) { // // Set manual config policy. // Policy = Ip6ConfigPolicyManual; Status = IfCb->IfCfg->SetData ( IfCb->IfCfg, Ip6ConfigDataTypePolicy, sizeof (EFI_IP6_CONFIG_POLICY), &Policy ); if (EFI_ERROR(Status)) { goto ON_EXIT; } VarArg= VarArg->Next; } else if (StrCmp (VarArg->Arg, L"host") == 0) { // // Parse till the next tag or the end of command line. // VarArg = VarArg->Next; Status = IfConfig6ParseManualAddressList ( &VarArg, &CfgManAddr, &AddrSize ); if (EFI_ERROR (Status)) { if (Status == EFI_INVALID_PARAMETER) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"host"); continue; } else { goto ON_EXIT; } } // // Set static host ip6 address list. // This is a asynchronous process. // IsAddressOk = FALSE; Status = IfCb->IfCfg->RegisterDataNotify ( IfCb->IfCfg, Ip6ConfigDataTypeManualAddress, MappedEvt ); if (EFI_ERROR (Status)) { goto ON_EXIT; } Status = IfCb->IfCfg->SetData ( IfCb->IfCfg, Ip6ConfigDataTypeManualAddress, AddrSize, CfgManAddr ); if (Status == EFI_NOT_READY) { // // Get current dad transmits count. // CurDadXmitsLen = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS); IfCb->IfCfg->GetData ( IfCb->IfCfg, Ip6ConfigDataTypeDupAddrDetectTransmits, &CurDadXmitsLen, &CurDadXmits ); gBS->SetTimer (TimeOutEvt, TimerRelative, 50000000 + 10000000 * CurDadXmits); while (EFI_ERROR (gBS->CheckEvent (TimeOutEvt))) { if (IsAddressOk) { Status = EFI_SUCCESS; break; } } } IfCb->IfCfg->UnregisterDataNotify ( IfCb->IfCfg, Ip6ConfigDataTypeManualAddress, MappedEvt ); if (EFI_ERROR (Status)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_MAN_HOST), mHiiHandle, Status); goto ON_EXIT; } // // Check whether the address is set successfully. // DataSize = 0; Status = IfCb->IfCfg->GetData ( IfCb->IfCfg, Ip6ConfigDataTypeInterfaceInfo, &DataSize, NULL ); if (Status != EFI_BUFFER_TOO_SMALL) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status); goto ON_EXIT; } IfInfo = AllocateZeroPool (DataSize); if (IfInfo == NULL) { Status = EFI_OUT_OF_RESOURCES; goto ON_EXIT; } Status = IfCb->IfCfg->GetData ( IfCb->IfCfg, Ip6ConfigDataTypeInterfaceInfo, &DataSize, IfInfo ); if (EFI_ERROR (Status)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_IP6CFG_GETDATA), mHiiHandle, Status); goto ON_EXIT; } for ( Index = 0; Index < (UINTN) (AddrSize / sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS)); Index++) { IsAddressSet = FALSE; // // By default, the prefix length 0 is regarded as 64. // if (CfgManAddr[Index].PrefixLength == 0) { CfgManAddr[Index].PrefixLength = 64; } for (Index2 = 0; Index2 < IfInfo->AddressInfoCount; Index2++) { if (EFI_IP6_EQUAL (&IfInfo->AddressInfo[Index2].Address, &CfgManAddr[Index].Address) && (IfInfo->AddressInfo[Index2].PrefixLength == CfgManAddr[Index].PrefixLength)) { IsAddressSet = TRUE; break; } } if (!IsAddressSet) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_ADDRESS_FAILED), mHiiHandle); IfConfig6PrintIpAddr ( &CfgManAddr[Index].Address, &CfgManAddr[Index].PrefixLength ); } } } else if (StrCmp (VarArg->Arg, L"gw") == 0) { // // Parse till the next tag or the end of command line. // VarArg = VarArg->Next; Status = IfConfig6ParseGwDnsAddressList ( &VarArg, &CfgAddr, &AddrSize ); if (EFI_ERROR (Status)) { if (Status == EFI_INVALID_PARAMETER) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"gw"); continue; } else { goto ON_EXIT; } } // // Set static gateway ip6 address list. // Status = IfCb->IfCfg->SetData ( IfCb->IfCfg, Ip6ConfigDataTypeGateway, AddrSize, CfgAddr ); if (EFI_ERROR (Status)) { goto ON_EXIT; } } else if (StrCmp (VarArg->Arg, L"dns") == 0) { // // Parse till the next tag or the end of command line. // VarArg = VarArg->Next; Status = IfConfig6ParseGwDnsAddressList ( &VarArg, &CfgAddr, &AddrSize ); if (EFI_ERROR (Status)) { if (Status == EFI_INVALID_PARAMETER) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_IFCONFIG6_ERR_LACK_ARGUMENTS), mHiiHandle, L"dns"); continue; } else { goto ON_EXIT; } } // // Set static dhs server ip6 address list. // Status = IfCb->IfCfg->SetData ( IfCb->IfCfg, Ip6ConfigDataTypeDnsServer, AddrSize, CfgAddr ); if (EFI_ERROR (Status)) { goto ON_EXIT; } } else if (StrCmp (VarArg->Arg, L"id") == 0) { // // Parse till the next tag or the end of command line. // VarArg = VarArg->Next; Status = IfConfig6ParseInterfaceId (&VarArg, &InterfaceId); if (EFI_ERROR (Status)) { goto ON_EXIT; } // // Set alternative interface id. // Status = IfCb->IfCfg->SetData ( IfCb->IfCfg, Ip6ConfigDataTypeAltInterfaceId, sizeof (EFI_IP6_CONFIG_INTERFACE_ID), InterfaceId ); if (EFI_ERROR (Status)) { goto ON_EXIT; } } else if (StrCmp (VarArg->Arg, L"dad") == 0) { // // Parse till the next tag or the end of command line. // VarArg = VarArg->Next; Status = IfConfig6ParseDadXmits (&VarArg, &DadXmits); if (EFI_ERROR (Status)) { goto ON_EXIT; } // // Set dad transmits count. // Status = IfCb->IfCfg->SetData ( IfCb->IfCfg, Ip6ConfigDataTypeDupAddrDetectTransmits, sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS), &DadXmits ); if (EFI_ERROR(Status)) { goto ON_EXIT; } } } ON_EXIT: if (CfgManAddr != NULL) { FreePool (CfgManAddr); } if (CfgAddr != NULL) { FreePool (CfgAddr); } if (MappedEvt != NULL) { gBS->CloseEvent (MappedEvt); } if (TimeOutEvt != NULL) { gBS->CloseEvent (TimeOutEvt); } if (IfInfo != NULL) { FreePool (IfInfo); } return Status; }