]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/IpSecDxe/IkePacket.c
Before decrypting the packet, Ipsec will check if the inbound protected packet is...
[mirror_edk2.git] / NetworkPkg / IpSecDxe / IkePacket.c
CommitLineData
9166f840 1/** @file\r
2 IKE Packet related operation.\r
3\r
4 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
5\r
6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php.\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "IpSecDebug.h"\r
17#include "Ikev2/Utility.h"\r
18\r
19/**\r
20 Allocate a buffer for the IKE_PACKET and intitalize its Header and payloadlist.\r
21\r
22 @return The pointer of the IKE_PACKET.\r
23\r
24**/\r
25IKE_PACKET *\r
26IkePacketAlloc (\r
27 VOID\r
28 )\r
29{\r
30 IKE_PACKET *IkePacket;\r
31\r
32 IkePacket = (IKE_PACKET *) AllocateZeroPool (sizeof (IKE_PACKET));\r
33 if (IkePacket == NULL) {\r
34 return NULL;\r
35 }\r
36\r
37 IkePacket->RefCount = 1;\r
38 InitializeListHead (&IkePacket->PayloadList);\r
39 \r
40 IkePacket->Header = (IKE_HEADER *) AllocateZeroPool (sizeof (IKE_HEADER));\r
41 if (IkePacket->Header == NULL) {\r
42 FreePool (IkePacket);\r
43 return NULL;\r
44 }\r
45 return IkePacket;\r
46}\r
47\r
48/**\r
49 Free the IkePacket by the specified IKE_PACKET pointer.\r
50\r
51 @param[in] IkePacket The pointer of the IKE_PACKET to be freed.\r
52\r
53**/\r
54VOID\r
55IkePacketFree (\r
56 IN IKE_PACKET *IkePacket\r
57 )\r
58{\r
59 LIST_ENTRY *Entry;\r
60 IKE_PAYLOAD *IkePayload;\r
61\r
62 if (IkePacket == NULL) {\r
63 return;\r
64 }\r
65 //\r
66 // Check if the Packet is referred by others.\r
67 //\r
68 if (--IkePacket->RefCount == 0) {\r
69 //\r
70 // Free IkePacket header\r
71 //\r
72 if (!IkePacket->IsHdrExt && IkePacket->Header != NULL) {\r
73 FreePool (IkePacket->Header);\r
74 }\r
75 //\r
76 // Free the PayloadsBuff\r
77 //\r
78 if (!IkePacket->IsPayloadsBufExt && IkePacket->PayloadsBuf != NULL) {\r
79 FreePool (IkePacket->PayloadsBuf);\r
80 }\r
81 //\r
82 // Iterate payloadlist and free all payloads\r
83 //\r
84 for (Entry = (IkePacket)->PayloadList.ForwardLink; Entry != &(IkePacket)->PayloadList;) {\r
85 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);\r
86 Entry = Entry->ForwardLink;\r
87\r
88 IkePayloadFree (IkePayload);\r
89 }\r
90\r
91 FreePool (IkePacket);\r
92 }\r
93}\r
94\r
95/**\r
96 Callback funtion of NetbufFromExt()\r
97 \r
98 @param[in] Arg The data passed from the NetBufFromExe(). \r
99\r
100**/\r
101VOID\r
1d8fa5e9 102EFIAPI\r
9166f840 103IkePacketNetbufFree (\r
104 IN VOID *Arg\r
105 )\r
106{\r
107 //\r
108 // TODO: add something if need.\r
109 //\r
110}\r
111\r
112/**\r
113 Copy the NetBuf into a IKE_PACKET sturcture.\r
114 \r
115 Create a IKE_PACKET and fill the received IKE header into the header of IKE_PACKET \r
116 and copy the recieved packet without IKE HEADER to the PayloadBuf of IKE_PACKET.\r
117\r
118 @param[in] Netbuf The pointer of the Netbuf which contains the whole received \r
119 IKE packet.\r
120\r
121 @return The pointer of the IKE_PACKET which contains the received packet.\r
122\r
123**/\r
124IKE_PACKET *\r
125IkePacketFromNetbuf (\r
126 IN NET_BUF *Netbuf\r
127 )\r
128{\r
129 IKE_PACKET *IkePacket;\r
130\r
131 IkePacket = NULL;\r
132 if (Netbuf->TotalSize < sizeof (IKE_HEADER)) {\r
133 goto Error;\r
134 }\r
135\r
136 IkePacket = IkePacketAlloc ();\r
137 if (IkePacket == NULL) {\r
138 return NULL;\r
139 }\r
140 //\r
141 // Copy the IKE header from Netbuf to IkePacket->Hdr\r
142 //\r
143 NetbufCopy (Netbuf, 0, sizeof (IKE_HEADER), (UINT8 *) IkePacket->Header);\r
144 //\r
145 // Net order to host order\r
146 //\r
147 IkeHdrNetToHost (IkePacket->Header);\r
148 if (IkePacket->Header->Length < Netbuf->TotalSize) {\r
149 goto Error;\r
150 }\r
151\r
152 IkePacket->PayloadTotalSize = IkePacket->Header->Length - sizeof (IKE_HEADER);\r
153 IkePacket->PayloadsBuf = (UINT8 *) AllocateZeroPool (IkePacket->PayloadTotalSize);\r
154\r
155 if (IkePacket->PayloadsBuf == NULL) {\r
156 goto Error;\r
157 }\r
158 //\r
159 // Copy the IKE packet without the header into the IkePacket->PayloadsBuf.\r
160 //\r
161 NetbufCopy (Netbuf, sizeof (IKE_HEADER), (UINT32) IkePacket->PayloadTotalSize, IkePacket->PayloadsBuf);\r
162 return IkePacket;\r
163\r
164Error:\r
165 if (IkePacket != NULL) {\r
166 IkePacketFree (IkePacket);\r
167 }\r
168\r
169 return NULL;\r
170}\r
171\r
172/**\r
173 Convert the format from IKE_PACKET to NetBuf.\r
174\r
175 @param[in] SessionCommon Pointer of related IKE_COMMON_SESSION\r
176 @param[in] IkePacket Pointer of IKE_PACKET to be copy to NetBuf\r
177 @param[in] IkeType The IKE type to pointer the packet is for which IKE \r
178 phase. Now it supports IKE_SA_TYPE, IKE_CHILDSA_TYPE, \r
179 IKE_INFO_TYPE.\r
180\r
181 @return a pointer of Netbuff which contains the IKE_PACKE in network order.\r
182 \r
183**/\r
184NET_BUF *\r
185IkeNetbufFromPacket (\r
186 IN UINT8 *SessionCommon,\r
187 IN IKE_PACKET *IkePacket,\r
188 IN UINTN IkeType\r
189 )\r
190{\r
191 NET_BUF *Netbuf;\r
192 NET_FRAGMENT *Fragments;\r
193 UINTN Index;\r
194 UINTN NumPayloads;\r
195 LIST_ENTRY *PacketEntry;\r
196 LIST_ENTRY *Entry;\r
197 IKE_PAYLOAD *IkePayload;\r
198\r
199 if (!IkePacket->IsEncoded) {\r
200 IkePacket->IsEncoded = TRUE;\r
201 //\r
202 // Convert Host order to Network order for IKE_PACKET header and payloads\r
203 // Encryption payloads if needed\r
204 //\r
205 if (((IKEV2_SESSION_COMMON *) SessionCommon)->IkeVer == 2) {\r
206 Ikev2EncodePacket ((IKEV2_SESSION_COMMON *) SessionCommon, IkePacket, IkeType);\r
207 } else {\r
208 //\r
209 //If IKEv1 support, check it here.\r
210 //\r
211 return NULL;\r
212 }\r
213 }\r
214\r
215 NumPayloads = 0;\r
216 //\r
217 // Get the number of the payloads\r
218 //\r
219 NET_LIST_FOR_EACH (PacketEntry, &(IkePacket)->PayloadList) {\r
220 \r
221 NumPayloads++;\r
222 }\r
223 //\r
224 // Allocate the Framgents according to the numbers of the IkePayload\r
225 //\r
226 Fragments = (NET_FRAGMENT *) AllocateZeroPool ((1 + NumPayloads) * sizeof (NET_FRAGMENT));\r
227 if (Fragments == NULL) {\r
228 return NULL;\r
229 }\r
230\r
231 Fragments[0].Bulk = (UINT8 *) IkePacket->Header;\r
232 Fragments[0].Len = sizeof (IKE_HEADER);\r
233 Index = 0;\r
234\r
235 //\r
236 // Set payloads to the Framgments.\r
237 //\r
238 NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {\r
239 IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);\r
240\r
241 Fragments[Index + 1].Bulk = IkePayload->PayloadBuf;\r
242 Fragments[Index + 1].Len = (UINT32) IkePayload->PayloadSize;\r
243 Index++;\r
244 }\r
245\r
246 Netbuf = NetbufFromExt (\r
247 Fragments,\r
248 (UINT32) (NumPayloads + 1),\r
249 0,\r
250 0,\r
251 IkePacketNetbufFree,\r
252 NULL\r
253 );\r
254 \r
255 FreePool (Fragments);\r
256 return Netbuf;\r
257}\r
258\r