1 /** @file 2 The implementation of dump policy entry function in IpSecConfig application. 3 4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR> 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php. 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include "IpSecConfig.h" 17 #include "Dump.h" 18 #include "ForEach.h" 19 #include "Helper.h" 20 21 /** 22 Private function called to get the version infomation from an EFI_IP_ADDRESS_INFO structure. 23 24 @param[in] AddressInfo The pointer to the EFI_IP_ADDRESS_INFO structure. 25 26 @return the value of version. 27 **/ 28 UINTN 29 GetVerFromAddrInfo ( 30 IN EFI_IP_ADDRESS_INFO *AddressInfo 31 ) 32 { 33 if((AddressInfo->PrefixLength <= 32) && (AddressInfo->Address.Addr[1] == 0) && 34 (AddressInfo->Address.Addr[2] == 0) && (AddressInfo->Address.Addr[3] == 0)) { 35 return IP_VERSION_4; 36 } else { 37 return IP_VERSION_6; 38 } 39 } 40 41 /** 42 Private function called to get the version information from a EFI_IP_ADDRESS structure. 43 44 @param[in] Address The pointer to the EFI_IP_ADDRESS structure. 45 46 @return The value of the version. 47 **/ 48 UINTN 49 GetVerFromIpAddr ( 50 IN EFI_IP_ADDRESS *Address 51 ) 52 { 53 if ((Address->Addr[1] == 0) && (Address->Addr[2] == 0) && (Address->Addr[3] == 0)) { 54 return IP_VERSION_4; 55 } else { 56 return IP_VERSION_6; 57 } 58 } 59 60 /** 61 Private function called to print an ASCII string in unicode char format. 62 63 @param[in] Str The pointer to the ASCII string. 64 @param[in] Length The value of the ASCII string length. 65 **/ 66 VOID 67 DumpAsciiString ( 68 IN CHAR8 *Str, 69 IN UINTN Length 70 ) 71 { 72 UINTN Index; 73 Print (L"\""); 74 for (Index = 0; Index < Length; Index++) { 75 Print (L"%c", (CHAR16) Str[Index]); 76 } 77 Print (L"\""); 78 } 79 80 /** 81 Private function called to print a buffer in Hex format. 82 83 @param[in] Data The pointer to the buffer. 84 @param[in] Length The size of the buffer. 85 86 **/ 87 VOID 88 DumpBuf ( 89 IN UINT8 *Data, 90 IN UINTN Length 91 ) 92 { 93 UINTN Index; 94 for (Index = 0; Index < Length; Index++) { 95 Print (L"%02x ", Data[Index]); 96 } 97 } 98 99 /** 100 Private function called to print EFI_IP_ADDRESS_INFO content. 101 102 @param[in] AddressInfo The pointer to the EFI_IP_ADDRESS_INFO structure. 103 **/ 104 VOID 105 DumpAddressInfo ( 106 IN EFI_IP_ADDRESS_INFO *AddressInfo 107 ) 108 { 109 if (IP_VERSION_4 == GetVerFromAddrInfo (AddressInfo)) { 110 Print ( 111 L"%d.%d.%d.%d", 112 (UINTN) AddressInfo->Address.v4.Addr[0], 113 (UINTN) AddressInfo->Address.v4.Addr[1], 114 (UINTN) AddressInfo->Address.v4.Addr[2], 115 (UINTN) AddressInfo->Address.v4.Addr[3] 116 ); 117 if (AddressInfo->PrefixLength != 32) { 118 Print (L"/%d", (UINTN) AddressInfo->PrefixLength); 119 } 120 } 121 122 if (IP_VERSION_6 == GetVerFromAddrInfo (AddressInfo)) { 123 Print ( 124 L"%x:%x:%x:%x:%x:%x:%x:%x", 125 (((UINT16) AddressInfo->Address.v6.Addr[0]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[1]), 126 (((UINT16) AddressInfo->Address.v6.Addr[2]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[3]), 127 (((UINT16) AddressInfo->Address.v6.Addr[4]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[5]), 128 (((UINT16) AddressInfo->Address.v6.Addr[6]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[7]), 129 (((UINT16) AddressInfo->Address.v6.Addr[8]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[9]), 130 (((UINT16) AddressInfo->Address.v6.Addr[10]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[11]), 131 (((UINT16) AddressInfo->Address.v6.Addr[12]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[13]), 132 (((UINT16) AddressInfo->Address.v6.Addr[14]) << 8) | ((UINT16) AddressInfo->Address.v6.Addr[15]) 133 ); 134 if (AddressInfo->PrefixLength != 128) { 135 Print (L"/%d", AddressInfo->PrefixLength); 136 } 137 } 138 } 139 140 /** 141 Private function called to print EFI_IP_ADDRESS content. 142 143 @param[in] IpAddress The pointer to the EFI_IP_ADDRESS structure. 144 **/ 145 VOID 146 DumpIpAddress ( 147 IN EFI_IP_ADDRESS *IpAddress 148 ) 149 { 150 if (IP_VERSION_4 == GetVerFromIpAddr (IpAddress)) { 151 Print ( 152 L"%d.%d.%d.%d", 153 (UINTN) IpAddress->v4.Addr[0], 154 (UINTN) IpAddress->v4.Addr[1], 155 (UINTN) IpAddress->v4.Addr[2], 156 (UINTN) IpAddress->v4.Addr[3] 157 ); 158 } 159 160 if (IP_VERSION_6 == GetVerFromIpAddr (IpAddress)) { 161 Print ( 162 L"%x:%x:%x:%x:%x:%x:%x:%x", 163 (((UINT16) IpAddress->v6.Addr[0]) << 8) | ((UINT16) IpAddress->v6.Addr[1]), 164 (((UINT16) IpAddress->v6.Addr[2]) << 8) | ((UINT16) IpAddress->v6.Addr[3]), 165 (((UINT16) IpAddress->v6.Addr[4]) << 8) | ((UINT16) IpAddress->v6.Addr[5]), 166 (((UINT16) IpAddress->v6.Addr[6]) << 8) | ((UINT16) IpAddress->v6.Addr[7]), 167 (((UINT16) IpAddress->v6.Addr[8]) << 8) | ((UINT16) IpAddress->v6.Addr[9]), 168 (((UINT16) IpAddress->v6.Addr[10]) << 8) | ((UINT16) IpAddress->v6.Addr[11]), 169 (((UINT16) IpAddress->v6.Addr[12]) << 8) | ((UINT16) IpAddress->v6.Addr[13]), 170 (((UINT16) IpAddress->v6.Addr[14]) << 8) | ((UINT16) IpAddress->v6.Addr[15]) 171 ); 172 } 173 174 } 175 176 /** 177 Private function called to print EFI_IPSEC_SPD_SELECTOR content. 178 179 @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. 180 **/ 181 VOID 182 DumpSpdSelector ( 183 IN EFI_IPSEC_SPD_SELECTOR *Selector 184 ) 185 { 186 UINT32 Index; 187 CHAR16 *Str; 188 189 for (Index = 0; Index < Selector->LocalAddressCount; Index++) { 190 if (Index > 0) { 191 Print (L","); 192 } 193 194 DumpAddressInfo (&Selector->LocalAddress[Index]); 195 } 196 197 if (Index == 0) { 198 Print (L"localhost"); 199 } 200 201 Print (L" -> "); 202 203 for (Index = 0; Index < Selector->RemoteAddressCount; Index++) { 204 if (Index > 0) { 205 Print (L","); 206 } 207 208 DumpAddressInfo (&Selector->RemoteAddress[Index]); 209 } 210 211 Str = MapIntegerToString (Selector->NextLayerProtocol, mMapIpProtocol); 212 if (Str != NULL) { 213 Print (L" %s", Str); 214 } else { 215 Print (L" proto:%d", (UINTN) Selector->NextLayerProtocol); 216 } 217 218 if ((Selector->NextLayerProtocol == EFI_IP4_PROTO_TCP) || (Selector->NextLayerProtocol == EFI_IP4_PROTO_UDP)) { 219 Print (L" port:"); 220 if (Selector->LocalPort != EFI_IPSEC_ANY_PORT) { 221 Print (L"%d", Selector->LocalPort); 222 if (Selector->LocalPortRange != 0) { 223 Print (L"~%d", (UINTN) Selector->LocalPort + Selector->LocalPortRange); 224 } 225 } else { 226 Print (L"any"); 227 } 228 229 Print (L" -> "); 230 if (Selector->RemotePort != EFI_IPSEC_ANY_PORT) { 231 Print (L"%d", Selector->RemotePort); 232 if (Selector->RemotePortRange != 0) { 233 Print (L"~%d", (UINTN) Selector->RemotePort + Selector->RemotePortRange); 234 } 235 } else { 236 Print (L"any"); 237 } 238 } else if (Selector->NextLayerProtocol == EFI_IP4_PROTO_ICMP) { 239 Print (L" class/code:"); 240 if (Selector->LocalPort != 0) { 241 Print (L"%d", (UINTN) (UINT8) Selector->LocalPort); 242 } else { 243 Print (L"any"); 244 } 245 246 Print (L"/"); 247 if (Selector->RemotePort != 0) { 248 Print (L"%d", (UINTN) (UINT8) Selector->RemotePort); 249 } else { 250 Print (L"any"); 251 } 252 } 253 } 254 255 /** 256 Print EFI_IPSEC_SPD_SELECTOR and EFI_IPSEC_SPD_DATA content. 257 258 @param[in] Selector The pointer to the EFI_IPSEC_SPD_SELECTOR structure. 259 @param[in] Data The pointer to the EFI_IPSEC_SPD_DATA structure. 260 @param[in] EntryIndex The pointer to the Index in SPD Database. 261 262 @retval EFI_SUCCESS Dump SPD information successfully. 263 **/ 264 EFI_STATUS 265 DumpSpdEntry ( 266 IN EFI_IPSEC_SPD_SELECTOR *Selector, 267 IN EFI_IPSEC_SPD_DATA *Data, 268 IN UINTN *EntryIndex 269 ) 270 { 271 BOOLEAN HasPre; 272 CHAR16 DataName[128]; 273 CHAR16 *String1; 274 CHAR16 *String2; 275 CHAR16 *String3; 276 UINT8 Index; 277 278 Print (L"%d.", (*EntryIndex)++); 279 280 // 281 // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400 282 // Protect PF:0x34323423 Name:First Entry 283 // ext-sequence sequence-overflow fragcheck life:[B0,S1024,H3600] 284 // ESP algo1 algo2 Tunnel [xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx set] 285 // 286 287 DumpSpdSelector (Selector); 288 Print (L"\n "); 289 290 Print (L"%s ", MapIntegerToString (Data->Action, mMapIpSecAction)); 291 Print (L"PF:%08x ", Data->PackageFlag); 292 293 Index = 0; 294 while (Data->Name[Index] != 0) { 295 DataName[Index] = (CHAR16) Data->Name[Index]; 296 Index++; 297 ASSERT (Index < 128); 298 } 299 DataName[Index] = L'\0'; 300 301 Print (L"Name:%s", DataName); 302 303 if (Data->Action == EfiIPsecActionProtect) { 304 Print (L"\n "); 305 if (Data->ProcessingPolicy->ExtSeqNum) { 306 Print (L"ext-sequence "); 307 } 308 309 if (Data->ProcessingPolicy->SeqOverflow) { 310 Print (L"sequence-overflow "); 311 } 312 313 if (Data->ProcessingPolicy->FragCheck) { 314 Print (L"fragment-check "); 315 } 316 317 HasPre = FALSE; 318 if (Data->ProcessingPolicy->SaLifetime.ByteCount != 0) { 319 Print (HasPre ? L"," : L"life:["); 320 Print (L"%lxB", Data->ProcessingPolicy->SaLifetime.ByteCount); 321 HasPre = TRUE; 322 } 323 324 if (Data->ProcessingPolicy->SaLifetime.SoftLifetime != 0) { 325 Print (HasPre ? L"," : L"life:["); 326 Print (L"%lxs", Data->ProcessingPolicy->SaLifetime.SoftLifetime); 327 HasPre = TRUE; 328 } 329 330 if (Data->ProcessingPolicy->SaLifetime.HardLifetime != 0) { 331 Print (HasPre ? L"," : L"life:["); 332 Print (L"%lxS", Data->ProcessingPolicy->SaLifetime.HardLifetime); 333 HasPre = TRUE; 334 } 335 336 if (HasPre) { 337 Print (L"]"); 338 } 339 340 if (HasPre || Data->ProcessingPolicy->ExtSeqNum || 341 Data->ProcessingPolicy->SeqOverflow || Data->ProcessingPolicy->FragCheck) { 342 Print (L"\n "); 343 } 344 345 String1 = MapIntegerToString (Data->ProcessingPolicy->Proto, mMapIpSecProtocol); 346 String2 = MapIntegerToString (Data->ProcessingPolicy->AuthAlgoId, mMapAuthAlgo); 347 String3 = MapIntegerToString (Data->ProcessingPolicy->EncAlgoId, mMapEncAlgo); 348 Print ( 349 L"%s Auth:%s Encrypt:%s ", 350 String1, 351 String2, 352 String3 353 ); 354 355 Print (L"%s ", MapIntegerToString (Data->ProcessingPolicy->Mode, mMapIpSecMode)); 356 if (Data->ProcessingPolicy->Mode == EfiIPsecTunnel) { 357 Print (L"["); 358 DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->LocalTunnelAddress); 359 Print (L" -> "); 360 DumpIpAddress (&Data->ProcessingPolicy->TunnelOption->RemoteTunnelAddress); 361 Print (L" %s]", MapIntegerToString (Data->ProcessingPolicy->TunnelOption->DF, mMapDfOption)); 362 } 363 } 364 365 Print (L"\n"); 366 367 return EFI_SUCCESS; 368 } 369 370 /** 371 Print EFI_IPSEC_SA_ID and EFI_IPSEC_SA_DATA2 content. 372 373 @param[in] SaId The pointer to the EFI_IPSEC_SA_ID structure. 374 @param[in] Data The pointer to the EFI_IPSEC_SA_DATA2 structure. 375 @param[in] EntryIndex The pointer to the Index in the SAD Database. 376 377 @retval EFI_SUCCESS Dump SAD information successfully. 378 **/ 379 EFI_STATUS 380 DumpSadEntry ( 381 IN EFI_IPSEC_SA_ID *SaId, 382 IN EFI_IPSEC_SA_DATA2 *Data, 383 IN UINTN *EntryIndex 384 ) 385 { 386 BOOLEAN HasPre; 387 CHAR16 *AuthAlgoStr; 388 CHAR16 *EncAlgoStr; 389 390 AuthAlgoStr = NULL; 391 EncAlgoStr = NULL; 392 393 // 394 // SPI:1234 ESP Destination:xxx.xxx.xxx.xxx 395 // Mode:Transport SeqNum:134 AntiReplayWin:64 life:[0B,1023s,3400S] PathMTU:34 396 // Auth:xxxx/password Encrypt:yyyy/password 397 // xxx.xxx.xxx.xxx/yy -> xxx.xxx.xxx.xx/yy proto:23 port:100~300 -> 300~400 398 // 399 400 Print (L"%d.", (*EntryIndex)++); 401 Print (L"0x%x %s ", (UINTN) SaId->Spi, MapIntegerToString (SaId->Proto, mMapIpSecProtocol)); 402 if (Data->Mode == EfiIPsecTunnel) { 403 Print (L"TunnelSourceAddress:"); 404 DumpIpAddress (&Data->TunnelSourceAddress); 405 Print (L"\n"); 406 Print (L" TunnelDestination:"); 407 DumpIpAddress (&Data->TunnelDestinationAddress); 408 Print (L"\n"); 409 } 410 411 Print ( 412 L" Mode:%s SeqNum:%lx AntiReplayWin:%d ", 413 MapIntegerToString (Data->Mode, mMapIpSecMode), 414 Data->SNCount, 415 (UINTN) Data->AntiReplayWindows 416 ); 417 418 HasPre = FALSE; 419 if (Data->SaLifetime.ByteCount != 0) { 420 Print (HasPre ? L"," : L"life:["); 421 Print (L"%lxB", Data->SaLifetime.ByteCount); 422 HasPre = TRUE; 423 } 424 425 if (Data->SaLifetime.SoftLifetime != 0) { 426 Print (HasPre ? L"," : L"life:["); 427 Print (L"%lxs", Data->SaLifetime.SoftLifetime); 428 HasPre = TRUE; 429 } 430 431 if (Data->SaLifetime.HardLifetime != 0) { 432 Print (HasPre ? L"," : L"life:["); 433 Print (L"%lxS", Data->SaLifetime.HardLifetime); 434 HasPre = TRUE; 435 } 436 437 if (HasPre) { 438 Print (L"] "); 439 } 440 441 Print (L"PathMTU:%d\n", (UINTN) Data->PathMTU); 442 443 if (SaId->Proto == EfiIPsecAH) { 444 Print ( 445 L" Auth:%s/%s\n", 446 MapIntegerToString (Data->AlgoInfo.AhAlgoInfo.AuthAlgoId, mMapAuthAlgo), 447 Data->AlgoInfo.AhAlgoInfo.AuthKey 448 ); 449 } else { 450 AuthAlgoStr = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.AuthAlgoId, mMapAuthAlgo); 451 EncAlgoStr = MapIntegerToString (Data->AlgoInfo.EspAlgoInfo.EncAlgoId, mMapEncAlgo); 452 453 if (Data->ManualSet) { 454 // 455 // if the SAD is set manually the key is a Ascii string in most of time. 456 // Print the Key in Ascii string format. 457 // 458 Print (L" Auth:%s/",AuthAlgoStr); 459 DumpAsciiString ( 460 Data->AlgoInfo.EspAlgoInfo.AuthKey, 461 Data->AlgoInfo.EspAlgoInfo.AuthKeyLength 462 ); 463 Print (L"\n Encrypt:%s/",EncAlgoStr); 464 DumpAsciiString ( 465 Data->AlgoInfo.EspAlgoInfo.EncKey, 466 Data->AlgoInfo.EspAlgoInfo.EncKeyLength 467 ); 468 } else { 469 // 470 // if the SAD is created by IKE, the key is a set of hex value in buffer. 471 // Print the Key in Hex format. 472 // 473 Print (L" Auth:%s/",AuthAlgoStr); 474 DumpBuf ((UINT8 *)(Data->AlgoInfo.EspAlgoInfo.AuthKey), Data->AlgoInfo.EspAlgoInfo.AuthKeyLength); 475 476 Print (L"\n Encrypt:%s/",EncAlgoStr); 477 DumpBuf ((UINT8 *)(Data->AlgoInfo.EspAlgoInfo.EncKey), Data->AlgoInfo.EspAlgoInfo.EncKeyLength); 478 } 479 } 480 Print (L"\n"); 481 if (Data->SpdSelector != NULL) { 482 Print (L" "); 483 DumpSpdSelector (Data->SpdSelector); 484 Print (L"\n"); 485 } 486 487 return EFI_SUCCESS; 488 } 489 490 /** 491 Print EFI_IPSEC_PAD_ID and EFI_IPSEC_PAD_DATA content. 492 493 @param[in] PadId The pointer to the EFI_IPSEC_PAD_ID structure. 494 @param[in] Data The pointer to the EFI_IPSEC_PAD_DATA structure. 495 @param[in] EntryIndex The pointer to the Index in the PAD Database. 496 497 @retval EFI_SUCCESS Dump PAD information successfully. 498 **/ 499 EFI_STATUS 500 DumpPadEntry ( 501 IN EFI_IPSEC_PAD_ID *PadId, 502 IN EFI_IPSEC_PAD_DATA *Data, 503 IN UINTN *EntryIndex 504 ) 505 { 506 CHAR16 *String1; 507 CHAR16 *String2; 508 509 // 510 // ADDR:10.23.17.34/15 511 // IDEv1 PreSharedSecret IKE-ID 512 // password 513 // 514 515 Print (L"%d.", (*EntryIndex)++); 516 517 if (PadId->PeerIdValid) { 518 Print (L"ID:%s", PadId->Id.PeerId); 519 } else { 520 Print (L"ADDR:"); 521 DumpAddressInfo (&PadId->Id.IpAddress); 522 } 523 524 Print (L"\n"); 525 526 String1 = MapIntegerToString (Data->AuthProtocol, mMapAuthProto); 527 String2 = MapIntegerToString (Data->AuthMethod, mMapAuthMethod); 528 Print ( 529 L" %s %s", 530 String1, 531 String2 532 ); 533 534 if (Data->IkeIdFlag) { 535 Print (L"IKE-ID"); 536 } 537 538 Print (L"\n"); 539 540 if (Data->AuthData != NULL) { 541 DumpAsciiString (Data->AuthData, Data->AuthDataSize); 542 Print (L"\n"); 543 } 544 545 if (Data->RevocationData != NULL) { 546 Print (L" %s\n", Data->RevocationData); 547 } 548 549 return EFI_SUCCESS; 550 551 } 552 553 VISIT_POLICY_ENTRY mDumpPolicyEntry[] = { 554 (VISIT_POLICY_ENTRY) DumpSpdEntry, 555 (VISIT_POLICY_ENTRY) DumpSadEntry, 556 (VISIT_POLICY_ENTRY) DumpPadEntry 557 }; 558 559 /** 560 Print all entry information in the database according to datatype. 561 562 @param[in] DataType The value of EFI_IPSEC_CONFIG_DATA_TYPE. 563 @param[in] ParamPackage The pointer to the ParamPackage list. 564 565 @retval EFI_SUCCESS Dump all information successfully. 566 @retval Others Some mistaken case. 567 **/ 568 EFI_STATUS 569 ListPolicyEntry ( 570 IN EFI_IPSEC_CONFIG_DATA_TYPE DataType, 571 IN LIST_ENTRY *ParamPackage 572 ) 573 { 574 UINTN EntryIndex; 575 576 EntryIndex = 0; 577 return ForeachPolicyEntry (DataType, mDumpPolicyEntry[DataType], &EntryIndex); 578 } 579 580