/** @file The implementation of dump policy entry function in IpSecConfig application. Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "IpSecConfig.h" #include "Dump.h" #include "ForEach.h" #include "Helper.h" /** Private function called to get the version infomation from an EFI_IP_ADDRESS_INFO structure. @param[in] AddressInfo The pointer to the EFI_IP_ADDRESS_INFO structure. @return the value of version. **/ UINTN GetVerFromAddrInfo ( IN EFI_IP_ADDRESS_INFO *AddressInfo ) { if((AddressInfo->PrefixLength <= 32) && (AddressInfo->Address.Addr[1] == 0) && (AddressInfo->Address.Addr[2] == 0) && (AddressInfo->Address.Addr[3] == 0)) { return IP_VERSION_4; } else { return IP_VERSION_6; } } /** Private function called to get the version information from a EFI_IP_ADDRESS structure. @param[in] Address The pointer to the EFI_IP_ADDRESS structure. @return The value of the version. **/ UINTN GetVerFromIpAddr ( IN EFI_IP_ADDRESS *Address ) { if ((Address->Addr[1] == 0) && (Address->Addr[2] == 0) && (Address->Addr[3] == 0)) { return IP_VERSION_4; } else { return IP_VERSION_6; } } /** Private function called to print an ASCII string in unicode char format. @param[in] Str The pointer to the ASCII string. @param[in] Length The value of the ASCII string length. **/ VOID DumpAsciiString ( IN CHAR8 *Str, IN UINTN Length ) { UINTN Index; Print (L"\""); for (Index = 0; Index < Length; Index++) { Print (L"%c", (CHAR16) Str[Index]); } Print (L"\""); } /** Private function called to print a buffer in Hex format. @param[in] Data The pointer to the buffer. @param[in] Length The size of the buffer. **/ VOID DumpBuf ( IN UINT8 *Data, IN UINTN Length ) { UINTN Index; for (Index = 0; Index < Length; Index++) { Print (L"%02x ", Data[Index]); } } /** Private function called to print EFI_IP_ADDRESS_INFO content. @param[in] AddressInfo The pointer to the EFI_IP_ADDRESS_INFO structure. **/ VOID DumpAddressInfo ( IN EFI_IP_ADDRESS_INFO *AddressInfo ) { if (IP_VERSION_4 == GetVerFromAddrInfo (AddressInfo)) { Print ( L"%d.%d.%d.%d", (UINTN) AddressInfo->Address.v4.Addr[0], (UINTN) AddressInfo->Address.v4.Addr[1], (UINTN) AddressInfo->Address.v4.Addr[2], (UINTN) AddressInfo->Address.v4.Addr[3] ); if (AddressInfo->PrefixLength != 32) { Print (L"/%d", (UINTN) AddressInfo->PrefixLength); } } if (IP_VERSION_6 == GetVerFromAddrInfo (AddressInfo)) { Print ( L"%x:%x:%x:%x:%x:%x:%x:%x", (((UINT16) AddressInfo->Address.v6.Addr[0]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[1]), (((UINT16) AddressInfo->Address.v6.Addr[2]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[3]), (((UINT16) AddressInfo->Address.v6.Addr[4]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[5]), (((UINT16) AddressInfo->Address.v6.Addr[6]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[7]), (((UINT16) AddressInfo->Address.v6.Addr[8]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[9]), (((UINT16) AddressInfo->Address.v6.Addr[10]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[11]), (((UINT16) AddressInfo->Address.v6.Addr[12]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[13]), (((UINT16) AddressInfo->Address.v6.Addr[14]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[15]) ); if (AddressInfo->PrefixLength != 128) { Print (L"/%d", AddressInfo->PrefixLength); } } } /** Private function called to print EFI_IP_ADDRESS content. @param[in] IpAddress The pointer to the EFI_IP_ADDRESS structure. **/ VOID DumpIpAddress ( IN EFI_IP_ADDRESS *IpAddress ) { if (IP_VERSION_4 == GetVerFromIpAddr (IpAddress)) { Print ( L"%d.%d.%d.%d", (UINTN) IpAddress->v4.Addr[0], (UINTN) IpAddress->v4.Addr[1], (UINTN) IpAddress->v4.Addr[2], (UINTN) IpAddress->v4.Addr[3] ); } if (IP_VERSION_6 == GetVerFromIpAddr (IpAddress)) { Print ( L"%x:%x:%x:%x:%x:%x:%x:%x", (((UINT16) IpAddress->v6.Addr[0]) << 8) | ((UINT16) IpAddress->v6.Addr[1]), (((UINT16) IpAddress->v6.Addr[2]) << 8) | ((UINT16) IpAddress->v6.Addr[3]), (((UINT16) IpAddress->v6.Addr[4]) << 8) | ((UINT16) IpAddress->v6.Addr[5]), (((UINT16) IpAddress->v6.Addr[6]) << 8) | ((UINT16) IpAddress->v6.Addr[7]), (((UINT16) IpAddress->v6.Addr[8]) << 8) | ((UINT16) IpAddress->v6.Addr[9]), (((UINT16) IpAddress->v6.Addr[10]) << 8) | ((UINT16) IpAddress->v6.Addr[11]), (((UINT16) IpAddress->v6.Addr[12]) << 8) | ((UINT16) IpAddress->v6.Addr[13]), (((UINT16) IpAddress->v6.Addr[14]) << 8) | ((UINT16) IpAddress->v6.Addr[15]) ); } } /** Private function called to print EFI_IPSEC_SPD_SELECTOR content. @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. **/ VOID DumpSpdSelector ( IN EFI_IPSEC_SPD_SELECTOR *Selector ) { UINT32 Index; CHAR16 *Str; for (Index = 0; Index < Selector->LocalAddressCount; Index++) { if (Index > 0) { Print (L","); } DumpAddressInfo (&Selector->LocalAddress[Index]); } if (Index == 0) { Print (L"localhost"); } Print (L" -> "); for (Index = 0; Index < Selector->RemoteAddressCount; Index++) { if (Index > 0) { Print (L","); } DumpAddressInfo (&Selector->RemoteAddress[Index]); } Str = MapIntegerToString (Selector->NextLayerProtocol, mMapIpProtocol); if (Str != NULL) { Print (L" %s", Str); } else { Print (L" proto:%d", (UINTN) Selector->NextLayerProtocol); } if ((Selector->NextLayerProtocol == EFI_IP4_PROTO_TCP) || (Selector->NextLayerProtocol == EFI_IP4_PROTO_UDP)) { Print (L" port:"); if (Selector->LocalPort != EFI_IPSEC_ANY_PORT) { Print (L"%d", Selector->LocalPort); if (Selector->LocalPortRange != 0) { Print (L"~%d", (UINTN) Selector->LocalPort + Selector->LocalPortRange); } } else { Print (L"any"); } Print (L" -> "); if (Selector->RemotePort != EFI_IPSEC_ANY_PORT) { Print (L"%d", Selector->RemotePort); if (Selector->RemotePortRange != 0) { Print (L"~%d", (UINTN) Selector->RemotePort + Selector->RemotePortRange); } } else { Print (L"any"); } } else if (Selector->NextLayerProtocol == EFI_IP4_PROTO_ICMP) { Print (L" class/code:"); if (Selector->LocalPort != 0) { Print (L"%d", (UINTN) (UINT8) Selector->LocalPort); } else { Print (L"any"); } Print (L"/"); if (Selector->RemotePort != 0) { Print (L"%d", (UINTN) (UINT8) Selector->RemotePort); } else { Print (L"any"); } } } /** Print EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA content. @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. @param[in] Data The pointer to the EFI_IPSEC_SPD_DATA structure. @param[in] EntryIndex The pointer to the Index in SPD Database. @retval EFI_SUCCESS Dump SPD information successfully. **/ EFI_STATUS DumpSpdEntry ( IN EFI_IPSEC_SPD_SELECTOR *Selector, IN EFI_IPSEC_SPD_DATA *Data, IN UINTN *EntryIndex ) { BOOLEAN HasPre; CHAR16 DataName[128]; CHAR16 *String1; CHAR16 *String2; CHAR16 *String3; UINT8 Index; Print (L"%d.", (*EntryIndex)++); // // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400 // Protect PF:0x34323423 Name:First Entry // ext-sequence sequence-overflow fragcheck life:[B0,S1024,H3600] // ESP algo1 algo2 Tunnel [xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx set] // DumpSpdSelector (Selector); Print (L"\n "); Print (L"%s ", MapIntegerToString (Data->Action, mMapIpSecAction)); Print (L"PF:%08x ", Data->PackageFlag); Index = 0; while (Data->Name[Index] != 0) { DataName[Index] = (CHAR16) Data->Name[Index]; Index++; ASSERT (Index < 128); } DataName[Index] = L'\0'; Print (L"Name:%s", DataName); if (Data->Action == EfiIPsecActionProtect) { Print (L"\n "); if (Data->ProcessingPolicy->ExtSeqNum) { Print (L"ext-sequence "); } if (Data->ProcessingPolicy->SeqOverflow) { Print (L"sequence-overflow "); } if (Data->ProcessingPolicy->FragCheck) { Print (L"fragment-check "); } HasPre = FALSE; if (Data->ProcessingPolicy->SaLifetime.ByteCount != 0) { Print (HasPre ? L"," : L"life:["); Print (L"%lxB", Data->ProcessingPolicy->SaLifetime.ByteCount); HasPre = TRUE; } if (Data->ProcessingPolicy->SaLifetime.SoftLifetime != 0) { Print (HasPre ? L"," : L"life:["); Print (L"%lxs", Data->ProcessingPolicy->SaLifetime.SoftLifetime); HasPre = TRUE; } if (Data->ProcessingPolicy->SaLifetime.HardLifetime != 0) { Print (HasPre ? L"," : L"life:["); Print (L"%lxS", Data->ProcessingPolicy->SaLifetime.HardLifetime); HasPre = TRUE; } if (HasPre) { Print (L"]"); } if (HasPre || Data->ProcessingPolicy->ExtSeqNum || Data->ProcessingPolicy->SeqOverflow || Data->ProcessingPolicy->FragCheck) { Print (L"\n "); } String1 = MapIntegerToString (Data->ProcessingPolicy->Proto, mMapIpSecProtocol); String2 = MapIntegerToString (Data->ProcessingPolicy->AuthAlgoId, mMapAuthAlgo); String3 = MapIntegerToString (Data->ProcessingPolicy->EncAlgoId, mMapEncAlgo); Print ( L"%s Auth:%s Encrypt:%s ", String1, String2, String3 ); Print (L"%s ", MapIntegerToString (Data->ProcessingPolicy->Mode, mMapIpSecMode)); if (Data->ProcessingPolicy->Mode == EfiIPsecTunnel) { Print (L"["); DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->LocalTunnelAddress); Print (L" -> "); DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->RemoteTunnelAddress); Print (L" %s]", MapIntegerToString (Data->ProcessingPolicy->TunnelOption->DF, mMapDfOption)); } } Print (L"\n"); return EFI_SUCCESS; } /** Print EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 content. @param[in] SaId The pointer to the EFI_IPSEC_SA_ID structure. @param[in] Data The pointer to the EFI_IPSEC_SA_DATA2 structure. @param[in] EntryIndex The pointer to the Index in the SAD Database. @retval EFI_SUCCESS Dump SAD information successfully. **/ EFI_STATUS DumpSadEntry ( IN EFI_IPSEC_SA_ID *SaId, IN EFI_IPSEC_SA_DATA2 *Data, IN UINTN *EntryIndex ) { BOOLEAN HasPre; CHAR16 *AuthAlgoStr; CHAR16 *EncAlgoStr; AuthAlgoStr = NULL; EncAlgoStr = NULL; // // SPI:1234 ESP Destination:xxx.xxx.xxx.xxx // Mode:Transport SeqNum:134 AntiReplayWin:64 life:[0B,1023s,3400S] PathMTU:34 // Auth:xxxx/password Encrypt:yyyy/password // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400 // Print (L"%d.", (*EntryIndex)++); Print (L"0x%x %s ", (UINTN) SaId->Spi, MapIntegerToString (SaId->Proto, mMapIpSecProtocol)); if (Data->Mode == EfiIPsecTunnel) { Print (L"TunnelSourceAddress:"); DumpIpAddress (&Data->TunnelSourceAddress); Print (L"\n"); Print (L" TunnelDestination:"); DumpIpAddress (&Data->TunnelDestinationAddress); Print (L"\n"); } Print ( L" Mode:%s SeqNum:%lx AntiReplayWin:%d ", MapIntegerToString (Data->Mode, mMapIpSecMode), Data->SNCount, (UINTN) Data->AntiReplayWindows ); HasPre = FALSE; if (Data->SaLifetime.ByteCount != 0) { Print (HasPre ? L"," : L"life:["); Print (L"%lxB", Data->SaLifetime.ByteCount); HasPre = TRUE; } if (Data->SaLifetime.SoftLifetime != 0) { Print (HasPre ? L"," : L"life:["); Print (L"%lxs", Data->SaLifetime.SoftLifetime); HasPre = TRUE; } if (Data->SaLifetime.HardLifetime != 0) { Print (HasPre ? L"," : L"life:["); Print (L"%lxS", Data->SaLifetime.HardLifetime); HasPre = TRUE; } if (HasPre) { Print (L"] "); } Print (L"PathMTU:%d\n", (UINTN) Data->PathMTU); if (SaId->Proto == EfiIPsecAH) { Print ( L" Auth:%s/%s\n", MapIntegerToString (Data->AlgoInfo.AhAlgoInfo.AuthAlgoId, mMapAuthAlgo), Data->AlgoInfo.AhAlgoInfo.AuthKey ); } else { AuthAlgoStr = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.AuthAlgoId, mMapAuthAlgo); EncAlgoStr = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.EncAlgoId, mMapEncAlgo); if (Data->ManualSet) { // // if the SAD is set manually the key is a Ascii string in most of time. // Print the Key in Ascii string format. // Print (L" Auth:%s/",AuthAlgoStr); DumpAsciiString ( Data->AlgoInfo.EspAlgoInfo.AuthKey, Data->AlgoInfo.EspAlgoInfo.AuthKeyLength ); Print (L"\n Encrypt:%s/",EncAlgoStr); DumpAsciiString ( Data->AlgoInfo.EspAlgoInfo.EncKey, Data->AlgoInfo.EspAlgoInfo.EncKeyLength ); } else { // // if the SAD is created by IKE, the key is a set of hex value in buffer. // Print the Key in Hex format. // Print (L" Auth:%s/",AuthAlgoStr); DumpBuf ((UINT8 *)(Data->AlgoInfo.EspAlgoInfo.AuthKey), Data->AlgoInfo.EspAlgoInfo.AuthKeyLength); Print (L"\n Encrypt:%s/",EncAlgoStr); DumpBuf ((UINT8 *)(Data->AlgoInfo.EspAlgoInfo.EncKey), Data->AlgoInfo.EspAlgoInfo.EncKeyLength); } } Print (L"\n"); if (Data->SpdSelector != NULL) { Print (L" "); DumpSpdSelector (Data->SpdSelector); Print (L"\n"); } return EFI_SUCCESS; } /** Print EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA content. @param[in] PadId The pointer to the EFI_IPSEC_PAD_ID structure. @param[in] Data The pointer to the EFI_IPSEC_PAD_DATA structure. @param[in] EntryIndex The pointer to the Index in the PAD Database. @retval EFI_SUCCESS Dump PAD information successfully. **/ EFI_STATUS DumpPadEntry ( IN EFI_IPSEC_PAD_ID *PadId, IN EFI_IPSEC_PAD_DATA *Data, IN UINTN *EntryIndex ) { CHAR16 *String1; CHAR16 *String2; // // ADDR:10.23.17.34/15 // IDEv1 PreSharedSecret IKE-ID // password // Print (L"%d.", (*EntryIndex)++); if (PadId->PeerIdValid) { Print (L"ID:%s", PadId->Id.PeerId); } else { Print (L"ADDR:"); DumpAddressInfo (&PadId->Id.IpAddress); } Print (L"\n"); String1 = MapIntegerToString (Data->AuthProtocol, mMapAuthProto); String2 = MapIntegerToString (Data->AuthMethod, mMapAuthMethod); Print ( L" %s %s", String1, String2 ); if (Data->IkeIdFlag) { Print (L"IKE-ID"); } Print (L"\n"); if (Data->AuthData != NULL) { DumpAsciiString (Data->AuthData, Data->AuthDataSize); Print (L"\n"); } if (Data->RevocationData != NULL) { Print (L" %s\n", Data->RevocationData); } return EFI_SUCCESS; } VISIT_POLICY_ENTRY mDumpPolicyEntry[] = { (VISIT_POLICY_ENTRY) DumpSpdEntry, (VISIT_POLICY_ENTRY) DumpSadEntry, (VISIT_POLICY_ENTRY) DumpPadEntry }; /** Print all entry information in the database according to datatype. @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. @param[in] ParamPackage The pointer to the ParamPackage list. @retval EFI_SUCCESS Dump all information successfully. @retval Others Some mistaken case. **/ EFI_STATUS ListPolicyEntry ( IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, IN LIST_ENTRY *ParamPackage ) { UINTN EntryIndex; EntryIndex = 0; return ForeachPolicyEntry (DataType, mDumpPolicyEntry[DataType], &EntryIndex); }