audk/NetworkPkg/Application/IpsecConfig/Dump.c

580 lines
16 KiB
C

/** @file
The implementation of dump policy entry function in IpSecConfig application.
Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#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);
}