]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/Application/IpsecConfig/Dump.c
Add check before using it to avoid access violation.
[mirror_edk2.git] / NetworkPkg / Application / IpsecConfig / Dump.c
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