--- /dev/null
+/** @file\r
+ IKE Packet related operation.\r
+\r
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+\r
+ This program and the accompanying materials\r
+ are licensed and made available under the terms and conditions of the BSD License\r
+ which accompanies this distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php.\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "IpSecDebug.h"\r
+#include "Ikev2/Utility.h"\r
+\r
+/**\r
+ Allocate a buffer for the IKE_PACKET and intitalize its Header and payloadlist.\r
+\r
+ @return The pointer of the IKE_PACKET.\r
+\r
+**/\r
+IKE_PACKET *\r
+IkePacketAlloc (\r
+ VOID\r
+ )\r
+{\r
+ IKE_PACKET *IkePacket;\r
+\r
+ IkePacket = (IKE_PACKET *) AllocateZeroPool (sizeof (IKE_PACKET));\r
+ if (IkePacket == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ IkePacket->RefCount = 1;\r
+ InitializeListHead (&IkePacket->PayloadList);\r
+ \r
+ IkePacket->Header = (IKE_HEADER *) AllocateZeroPool (sizeof (IKE_HEADER));\r
+ if (IkePacket->Header == NULL) {\r
+ FreePool (IkePacket);\r
+ return NULL;\r
+ }\r
+ return IkePacket;\r
+}\r
+\r
+/**\r
+ Free the IkePacket by the specified IKE_PACKET pointer.\r
+\r
+ @param[in] IkePacket The pointer of the IKE_PACKET to be freed.\r
+\r
+**/\r
+VOID\r
+IkePacketFree (\r
+ IN IKE_PACKET *IkePacket\r
+ )\r
+{\r
+ LIST_ENTRY *Entry;\r
+ IKE_PAYLOAD *IkePayload;\r
+\r
+ if (IkePacket == NULL) {\r
+ return;\r
+ }\r
+ //\r
+ // Check if the Packet is referred by others.\r
+ //\r
+ if (--IkePacket->RefCount == 0) {\r
+ //\r
+ // Free IkePacket header\r
+ //\r
+ if (!IkePacket->IsHdrExt && IkePacket->Header != NULL) {\r
+ FreePool (IkePacket->Header);\r
+ }\r
+ //\r
+ // Free the PayloadsBuff\r
+ //\r
+ if (!IkePacket->IsPayloadsBufExt && IkePacket->PayloadsBuf != NULL) {\r
+ FreePool (IkePacket->PayloadsBuf);\r
+ }\r
+ //\r
+ // Iterate payloadlist and free all payloads\r
+ //\r
+ for (Entry = (IkePacket)->PayloadList.ForwardLink; Entry != &(IkePacket)->PayloadList;) {\r
+ IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);\r
+ Entry = Entry->ForwardLink;\r
+\r
+ IkePayloadFree (IkePayload);\r
+ }\r
+\r
+ FreePool (IkePacket);\r
+ }\r
+}\r
+\r
+/**\r
+ Callback funtion of NetbufFromExt()\r
+ \r
+ @param[in] Arg The data passed from the NetBufFromExe(). \r
+\r
+**/\r
+VOID\r
+IkePacketNetbufFree (\r
+ IN VOID *Arg\r
+ )\r
+{\r
+ //\r
+ // TODO: add something if need.\r
+ //\r
+}\r
+\r
+/**\r
+ Copy the NetBuf into a IKE_PACKET sturcture.\r
+ \r
+ Create a IKE_PACKET and fill the received IKE header into the header of IKE_PACKET \r
+ and copy the recieved packet without IKE HEADER to the PayloadBuf of IKE_PACKET.\r
+\r
+ @param[in] Netbuf The pointer of the Netbuf which contains the whole received \r
+ IKE packet.\r
+\r
+ @return The pointer of the IKE_PACKET which contains the received packet.\r
+\r
+**/\r
+IKE_PACKET *\r
+IkePacketFromNetbuf (\r
+ IN NET_BUF *Netbuf\r
+ )\r
+{\r
+ IKE_PACKET *IkePacket;\r
+\r
+ IkePacket = NULL;\r
+ if (Netbuf->TotalSize < sizeof (IKE_HEADER)) {\r
+ goto Error;\r
+ }\r
+\r
+ IkePacket = IkePacketAlloc ();\r
+ if (IkePacket == NULL) {\r
+ return NULL;\r
+ }\r
+ //\r
+ // Copy the IKE header from Netbuf to IkePacket->Hdr\r
+ //\r
+ NetbufCopy (Netbuf, 0, sizeof (IKE_HEADER), (UINT8 *) IkePacket->Header);\r
+ //\r
+ // Net order to host order\r
+ //\r
+ IkeHdrNetToHost (IkePacket->Header);\r
+ if (IkePacket->Header->Length < Netbuf->TotalSize) {\r
+ goto Error;\r
+ }\r
+\r
+ IkePacket->PayloadTotalSize = IkePacket->Header->Length - sizeof (IKE_HEADER);\r
+ IkePacket->PayloadsBuf = (UINT8 *) AllocateZeroPool (IkePacket->PayloadTotalSize);\r
+\r
+ if (IkePacket->PayloadsBuf == NULL) {\r
+ goto Error;\r
+ }\r
+ //\r
+ // Copy the IKE packet without the header into the IkePacket->PayloadsBuf.\r
+ //\r
+ NetbufCopy (Netbuf, sizeof (IKE_HEADER), (UINT32) IkePacket->PayloadTotalSize, IkePacket->PayloadsBuf);\r
+ return IkePacket;\r
+\r
+Error:\r
+ if (IkePacket != NULL) {\r
+ IkePacketFree (IkePacket);\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Convert the format from IKE_PACKET to NetBuf.\r
+\r
+ @param[in] SessionCommon Pointer of related IKE_COMMON_SESSION\r
+ @param[in] IkePacket Pointer of IKE_PACKET to be copy to NetBuf\r
+ @param[in] IkeType The IKE type to pointer the packet is for which IKE \r
+ phase. Now it supports IKE_SA_TYPE, IKE_CHILDSA_TYPE, \r
+ IKE_INFO_TYPE.\r
+\r
+ @return a pointer of Netbuff which contains the IKE_PACKE in network order.\r
+ \r
+**/\r
+NET_BUF *\r
+IkeNetbufFromPacket (\r
+ IN UINT8 *SessionCommon,\r
+ IN IKE_PACKET *IkePacket,\r
+ IN UINTN IkeType\r
+ )\r
+{\r
+ NET_BUF *Netbuf;\r
+ NET_FRAGMENT *Fragments;\r
+ UINTN Index;\r
+ UINTN NumPayloads;\r
+ LIST_ENTRY *PacketEntry;\r
+ LIST_ENTRY *Entry;\r
+ IKE_PAYLOAD *IkePayload;\r
+\r
+ if (!IkePacket->IsEncoded) {\r
+ IkePacket->IsEncoded = TRUE;\r
+ //\r
+ // Convert Host order to Network order for IKE_PACKET header and payloads\r
+ // Encryption payloads if needed\r
+ //\r
+ if (((IKEV2_SESSION_COMMON *) SessionCommon)->IkeVer == 2) {\r
+ Ikev2EncodePacket ((IKEV2_SESSION_COMMON *) SessionCommon, IkePacket, IkeType);\r
+ } else {\r
+ //\r
+ //If IKEv1 support, check it here.\r
+ //\r
+ return NULL;\r
+ }\r
+ }\r
+\r
+ NumPayloads = 0;\r
+ //\r
+ // Get the number of the payloads\r
+ //\r
+ NET_LIST_FOR_EACH (PacketEntry, &(IkePacket)->PayloadList) {\r
+ \r
+ NumPayloads++;\r
+ }\r
+ //\r
+ // Allocate the Framgents according to the numbers of the IkePayload\r
+ //\r
+ Fragments = (NET_FRAGMENT *) AllocateZeroPool ((1 + NumPayloads) * sizeof (NET_FRAGMENT));\r
+ if (Fragments == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ Fragments[0].Bulk = (UINT8 *) IkePacket->Header;\r
+ Fragments[0].Len = sizeof (IKE_HEADER);\r
+ Index = 0;\r
+\r
+ //\r
+ // Set payloads to the Framgments.\r
+ //\r
+ NET_LIST_FOR_EACH (Entry, &(IkePacket)->PayloadList) {\r
+ IkePayload = IKE_PAYLOAD_BY_PACKET (Entry);\r
+\r
+ Fragments[Index + 1].Bulk = IkePayload->PayloadBuf;\r
+ Fragments[Index + 1].Len = (UINT32) IkePayload->PayloadSize;\r
+ Index++;\r
+ }\r
+\r
+ Netbuf = NetbufFromExt (\r
+ Fragments,\r
+ (UINT32) (NumPayloads + 1),\r
+ 0,\r
+ 0,\r
+ IkePacketNetbufFree,\r
+ NULL\r
+ );\r
+ \r
+ FreePool (Fragments);\r
+ return Netbuf;\r
+}\r
+\r