]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/support.c
Retiring the ANT/JAVA build and removing the older EDK II packages that required...
[mirror_edk2.git] / EdkModulePkg / Universal / Network / PxeDhcp4 / Dxe / support.c
diff --git a/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/support.c b/EdkModulePkg/Universal/Network/PxeDhcp4/Dxe/support.c
deleted file mode 100644 (file)
index b6667ca..0000000
+++ /dev/null
@@ -1,1101 +0,0 @@
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. 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
-Module Name:\r
-  support.c\r
-\r
-Abstract:\r
-  Miscellaneous support routines for PxeDhcp4 protocol.\r
-\r
---*/\r
-\r
-\r
-#include "PxeDhcp4.h"\r
-\r
-#define DebugPrint(x)\r
-//\r
-// #define DebugPrint(x) Aprint x\r
-//\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-UINT16\r
-htons (\r
-  UINTN n\r
-  )\r
-{\r
-  return (UINT16) ((n >> 8) | (n << 8));\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-UINT32\r
-htonl (\r
-  UINTN n\r
-  )\r
-{\r
-  return (UINT32) ((n >> 24) | ((n >> 8) & 0xFF00) | ((n & 0xFF00) << 8) | (n << 24));\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-VOID\r
-EFIAPI\r
-timeout_notify (\r
-  IN EFI_EVENT Event,\r
-  IN VOID      *Context\r
-  )\r
-{\r
-  ASSERT (Context);\r
-\r
-  if (Context != NULL) {\r
-    ((PXE_DHCP4_PRIVATE_DATA *) Context)->TimeoutOccurred = TRUE;\r
-  }\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-VOID\r
-EFIAPI\r
-periodic_notify (\r
-  IN EFI_EVENT Event,\r
-  IN VOID      *Context\r
-  )\r
-{\r
-  ASSERT (Context);\r
-\r
-  if (Context != NULL) {\r
-    ((PXE_DHCP4_PRIVATE_DATA *) Context)->PeriodicOccurred = TRUE;\r
-  }\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-EFI_STATUS\r
-find_opt (\r
-  IN DHCP4_PACKET *Packet,\r
-  IN UINT8        OpCode,\r
-  IN UINTN        Skip,\r
-  OUT DHCP4_OP    **OpPtr\r
-  )\r
-/*++\r
-Routine description:\r
-  Locate option inside DHCP packet.\r
-\r
-Parameters:\r
-  Packet := Pointer to DHCP packet structure.\r
-  OpCode := Option op-code to find.\r
-  Skip := Number of found op-codes to skip.\r
-  OpPtr := Pointer to found op-code pointer.\r
-\r
-Returns:\r
-  EFI_SUCCESS := Option was found\r
-  EFI_INVALID_PARAMETER := Packet == NULL || OpPtr == NULL\r
-  EFI_INVALID_PARAMETER := OpCode == DHCP4_PAD\r
-  EFI_INVALID_PARAMETER := OpCode == DHCP4_END && Skip != 0\r
-  EFI_INVALID_PARAMETER := DHCP magik number in Packet is not valid\r
-  EFI_NOT_FOUND := op-code was not found in packet\r
-  EFI_INVALID_PARAMETER := If present, DHCP_MAX_MESSAGE_SIZE option\r
-    does not have a valid value.\r
---*/\r
-{\r
-  UINTN msg_size;\r
-  UINTN buf_len;\r
-  UINTN n;\r
-  UINT8 *buf;\r
-  UINT8 *end_ptr;\r
-  UINT8 overload;\r
-\r
-  //\r
-  // Verify parameters.\r
-  //\r
-  if (Packet == NULL || OpPtr == NULL || OpCode == DHCP4_PAD || (OpCode == DHCP4_END && Skip != 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Packet->dhcp4.magik != htonl (DHCP4_MAGIK_NUMBER)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Initialize search variables.\r
-  //\r
-  *OpPtr    = NULL;\r
-\r
-  msg_size  = DHCP4_MAX_PACKET_SIZE - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE);\r
-\r
-  overload  = 0;\r
-  end_ptr   = NULL;\r
-\r
-  buf       = Packet->dhcp4.options;\r
-  buf_len   = msg_size - (Packet->dhcp4.options - Packet->raw);\r
-\r
-  //\r
-  // Start searching for requested option.\r
-  //\r
-  for (n = 0;;) {\r
-    //\r
-    // If match is found, decrement skip count and return\r
-    // when desired match is found.\r
-    //\r
-    if (buf[n] == OpCode) {\r
-      *OpPtr = (DHCP4_OP *) &buf[n];\r
-\r
-      if (Skip-- == 0) {\r
-        return EFI_SUCCESS;\r
-      }\r
-    }\r
-    //\r
-    // Skip past current option.  Check for option overload\r
-    // and message size options since these will affect the\r
-    // amount of data to be searched.\r
-    //\r
-    switch (buf[n]) {\r
-    case DHCP4_PAD:\r
-      //\r
-      // Remember the first pad byte of a group.  This\r
-      // could be the end of a badly formed packet.\r
-      //\r
-      if (end_ptr == NULL) {\r
-        end_ptr = &buf[n];\r
-      }\r
-\r
-      ++n;\r
-      break;\r
-\r
-    case DHCP4_END:\r
-      //\r
-      // If we reach the end we are done.\r
-      //\r
-      end_ptr = NULL;\r
-      return EFI_NOT_FOUND;\r
-\r
-    case DHCP4_OPTION_OVERLOAD:\r
-      //\r
-      // Remember the option overload value since it\r
-      // could cause the search to continue into\r
-      // the fname and sname fields.\r
-      //\r
-      end_ptr = NULL;\r
-\r
-      if (buf[n + 1] == 1) {\r
-        overload = buf[n + 2];\r
-      }\r
-\r
-      n += 2 + buf[n + 1];\r
-      break;\r
-\r
-    case DHCP4_MAX_MESSAGE_SIZE:\r
-      //\r
-      // Remember the message size value since it could\r
-      // change the amount of option buffer to search.\r
-      //\r
-      end_ptr = NULL;\r
-\r
-      if (buf[n + 1] == 2 && buf == Packet->dhcp4.options) {\r
-        msg_size = ((buf[n + 2] << 8) | buf[n + 3]) - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE);\r
-\r
-        if (msg_size < 328) {\r
-          return EFI_INVALID_PARAMETER;\r
-        }\r
-\r
-        buf_len = msg_size - (Packet->dhcp4.options - Packet->raw);\r
-\r
-        if (n + 2 + buf[n + 1] > buf_len) {\r
-          return EFI_INVALID_PARAMETER;\r
-        }\r
-      }\r
-\r
-    /* fall thru */\r
-    default:\r
-      end_ptr = NULL;\r
-\r
-      n += 2 + buf[n + 1];\r
-    }\r
-    //\r
-    // Keep searching until the end of the buffer is reached.\r
-    //\r
-    if (n < buf_len) {\r
-      continue;\r
-    }\r
-    //\r
-    // Reached end of current buffer.  Check if we are supposed\r
-    // to search the fname and sname buffers.\r
-    //\r
-    if (buf == Packet->dhcp4.options &&\r
-        (overload == DHCP4_OVERLOAD_FNAME || overload == DHCP4_OVERLOAD_FNAME_AND_SNAME)\r
-        ) {\r
-      buf     = Packet->dhcp4.fname;\r
-      buf_len = 128;\r
-      n       = 0;\r
-      continue;\r
-    }\r
-\r
-    if (buf != Packet->dhcp4.sname && (overload == DHCP4_OVERLOAD_SNAME || overload == DHCP4_OVERLOAD_FNAME_AND_SNAME)) {\r
-      buf     = Packet->dhcp4.sname;\r
-      buf_len = 64;\r
-      n       = 0;\r
-      continue;\r
-    }\r
-    //\r
-    // End of last buffer reached.  If this was a search\r
-    // for the end of the options, go back to the start\r
-    // of the current pad block.\r
-    //\r
-    if (OpCode == DHCP4_END && end_ptr != NULL) {\r
-      *OpPtr = (DHCP4_OP *) end_ptr;\r
-      return EFI_SUCCESS;\r
-    }\r
-\r
-    return EFI_NOT_FOUND;\r
-  }\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-EFI_STATUS\r
-add_opt (\r
-  IN DHCP4_PACKET *Packet,\r
-  IN DHCP4_OP     *OpPtr\r
-  )\r
-/*++\r
-Routine description:\r
-  Add option to DHCP packet.\r
-\r
-Parameters:\r
-  Packet := Pointer to DHCP packet structure.\r
-  OpPtr := Pointer to DHCP option.\r
-\r
-Returns:\r
-  EFI_INVALID_PARAMETER := Packet == NULL || OpPtr == NULL\r
-  EFI_INVALID_PARAMETER := OpPtr->op == DHCP4_PAD || OpPtr->op == DHCP4_END\r
-  EFI_INVALID_PARAMETER := DHCP magik number in DHCP packet is not valid\r
-  EFI_INVALID_PARAMETER := If DHCP_MAX_MESSAGE_SIZE option is present and\r
-    is not valid\r
-  EFI_INVALID_PARAMETER := If DHCP_OPTION_OVERLOAD option is present and\r
-    is not valid\r
-  EFI_DEVICE_ERROR := Cannot determine end of packet\r
-  EFI_BUFFER_TOO_SMALL := Not enough room in packet to add option\r
-  EFI_SUCCESS := Option added to DHCP packet\r
---*/\r
-{\r
-  EFI_STATUS  efi_status;\r
-  DHCP4_OP    *msg_size_op;\r
-  DHCP4_OP    *overload_op;\r
-  DHCP4_OP    *op;\r
-  UINTN       msg_size;\r
-  UINTN       buf_len;\r
-  UINT32      magik;\r
-  UINT8       *buf;\r
-\r
-  //\r
-  // Verify parameters.\r
-  //\r
-  ASSERT (Packet);\r
-  ASSERT (OpPtr);\r
-\r
-  if (Packet == NULL || OpPtr == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  switch (OpPtr->op) {\r
-  case DHCP4_PAD:\r
-  case DHCP4_END:\r
-    //\r
-    // No adding PAD or END.\r
-    //\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Check the DHCP magik number.\r
-  //\r
-  CopyMem (&magik, &Packet->dhcp4.magik, 4);\r
-\r
-  if (magik != htonl (DHCP4_MAGIK_NUMBER)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Find the DHCP message size option.\r
-  //\r
-  msg_size = DHCP4_DEFAULT_MAX_MESSAGE_SIZE;\r
-\r
-  efi_status = find_opt (\r
-                Packet,\r
-                DHCP4_MAX_MESSAGE_SIZE,\r
-                0,\r
-                &msg_size_op\r
-                );\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    if (efi_status != EFI_NOT_FOUND) {\r
-      DebugPrint (\r
-        ("%s:%d:%r\n",\r
-        __FILE__,\r
-        __LINE__,\r
-        efi_status)\r
-        );\r
-      return efi_status;\r
-    }\r
-\r
-    msg_size_op = NULL;\r
-  } else {\r
-    CopyMem (&msg_size, msg_size_op->data, 2);\r
-    msg_size = htons (msg_size);\r
-\r
-    if (msg_size < DHCP4_DEFAULT_MAX_MESSAGE_SIZE) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-  }\r
-  //\r
-  // Find the DHCP option overload option.\r
-  //\r
-  efi_status = find_opt (\r
-                Packet,\r
-                DHCP4_OPTION_OVERLOAD,\r
-                0,\r
-                &overload_op\r
-                );\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    if (efi_status != EFI_NOT_FOUND) {\r
-      DebugPrint (\r
-        ("%s:%d:%r\n",\r
-        __FILE__,\r
-        __LINE__,\r
-        efi_status)\r
-        );\r
-      return efi_status;\r
-    }\r
-\r
-    overload_op = NULL;\r
-  } else {\r
-    if (overload_op->len != 1) {\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-\r
-    switch (overload_op->data[0]) {\r
-    case 1:\r
-    case 2:\r
-    case 3:\r
-      break;\r
-\r
-    default:\r
-      return EFI_INVALID_PARAMETER;\r
-    }\r
-  }\r
-  //\r
-  // Find the end of the packet.\r
-  //\r
-  efi_status = find_opt (Packet, DHCP4_END, 0, &op);\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Find which buffer the end is in.\r
-  //\r
-  if ((UINTN) op >= (UINTN) (buf = Packet->dhcp4.options)) {\r
-    buf_len = (msg_size - ((UINT8 *) &Packet->dhcp4.options - (UINT8 *) &Packet->raw)) - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE);\r
-  } else if ((UINTN) op >= (UINTN) (buf = Packet->dhcp4.fname)) {\r
-    buf_len = 128;\r
-  } else if ((UINTN) op >= (UINTN) (buf = Packet->dhcp4.sname)) {\r
-    buf_len = 64;\r
-  } else {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  //\r
-  // Add option to current buffer if there is no overlow.\r
-  //\r
-  if ((UINTN) ((&op->op - buf) + 3 + op->len) < buf_len) {\r
-    CopyMem (op, OpPtr, OpPtr->len + 2);\r
-\r
-    op->data[op->len] = DHCP4_END;\r
-\r
-    return EFI_SUCCESS;\r
-  }\r
-  //\r
-  // Error if there is no space for option.\r
-  //\r
-  return EFI_BUFFER_TOO_SMALL;\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-EFI_STATUS\r
-start_udp (\r
-  IN PXE_DHCP4_PRIVATE_DATA *Private,\r
-  IN OPTIONAL EFI_IP_ADDRESS         *StationIp,\r
-  IN OPTIONAL EFI_IP_ADDRESS         *SubnetMask\r
-  )\r
-/*++\r
-Routine description:\r
-  Setup PXE BaseCode UDP stack.\r
-\r
-Parameters:\r
-  Private := Pointer to PxeDhcp4 private data.\r
-  StationIp := Pointer to IP address or NULL if not known.\r
-  SubnetMask := Pointer to subnet mask or NULL if not known.\r
-\r
-Returns:\r
-  EFI_INVALID_PARAMETER := Private == NULL || Private->PxeBc == NULL\r
-  EFI_INVALID_PARAMETER := Only one of StationIp and SubnetMask is given\r
-  EFI_SUCCESS := UDP stack is ready\r
-  other := Error from PxeBc->SetIpFilter() or PxeBc->SetStationIp()\r
---*/\r
-{\r
-  EFI_PXE_BASE_CODE_IP_FILTER bcast_filter;\r
-  EFI_STATUS                  efi_status;\r
-\r
-  //\r
-  //\r
-  //\r
-  ASSERT (Private);\r
-  ASSERT (Private->PxeBc);\r
-\r
-  if (Private == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Private->PxeBc == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (StationIp != NULL && SubnetMask == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (StationIp == NULL && SubnetMask != NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Setup broadcast receive filter...\r
-  //\r
-  ZeroMem (&bcast_filter, sizeof (EFI_PXE_BASE_CODE_IP_FILTER));\r
-\r
-  bcast_filter.Filters  = EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST;\r
-  bcast_filter.IpCnt    = 0;\r
-\r
-  efi_status = Private->PxeBc->SetIpFilter (\r
-                                Private->PxeBc,\r
-                                &bcast_filter\r
-                                );\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-    return efi_status;\r
-  }\r
-  //\r
-  // Configure station IP address and subnet mask...\r
-  //\r
-  efi_status = Private->PxeBc->SetStationIp (\r
-                                Private->PxeBc,\r
-                                StationIp,\r
-                                SubnetMask\r
-                                );\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-  }\r
-\r
-  return efi_status;\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-VOID\r
-stop_udp (\r
-  IN PXE_DHCP4_PRIVATE_DATA *Private\r
-  )\r
-{\r
-  //\r
-  //\r
-  //\r
-  ASSERT (Private);\r
-  ASSERT (Private->PxeBc);\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-EFI_STATUS\r
-start_receive_events (\r
-  IN PXE_DHCP4_PRIVATE_DATA *Private,\r
-  IN UINTN                  SecondsTimeout\r
-  )\r
-/*++\r
-Routine description:\r
-  Create periodic and timeout receive events.\r
-\r
-Parameters:\r
-  Private := Pointer to PxeDhcp4 private data.\r
-  SecondsTimeout := Number of seconds to wait before timeout.\r
-\r
-Returns:\r
---*/\r
-{\r
-  EFI_STATUS  efi_status;\r
-  UINTN       random;\r
-\r
-  //\r
-  //\r
-  //\r
-  ASSERT (Private);\r
-  ASSERT (SecondsTimeout);\r
-\r
-  if (Private == NULL || SecondsTimeout == 0) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Need a bettern randomizer...\r
-  // For now adjust the timeout value by the least significant\r
-  // digit in the MAC address.\r
-  //\r
-  random = 0;\r
-\r
-  if (Private->PxeDhcp4.Data != NULL) {\r
-    if (Private->PxeDhcp4.Data->Discover.dhcp4.hlen != 0 && Private->PxeDhcp4.Data->Discover.dhcp4.hlen <= 16) {\r
-      random = 0xFFF & Private->PxeDhcp4.Data->Discover.dhcp4.chaddr[Private->PxeDhcp4.Data->Discover.dhcp4.hlen - 1];\r
-    }\r
-  }\r
-  //\r
-  // Setup timeout event and start timer.\r
-  //\r
-  efi_status = gBS->CreateEvent (\r
-                      EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                      TPL_NOTIFY,\r
-                      &timeout_notify,\r
-                      Private,\r
-                      &Private->TimeoutEvent\r
-                      );\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-    return efi_status;\r
-  }\r
-\r
-  efi_status = gBS->SetTimer (\r
-                      Private->TimeoutEvent,\r
-                      TimerRelative,\r
-                      SecondsTimeout * 10000000 + random\r
-                      );\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-    gBS->CloseEvent (Private->TimeoutEvent);\r
-    return efi_status;\r
-  }\r
-\r
-  Private->TimeoutOccurred = FALSE;\r
-\r
-  //\r
-  // Setup periodic event for callbacks\r
-  //\r
-  efi_status = gBS->CreateEvent (\r
-                      EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                      TPL_NOTIFY,\r
-                      &periodic_notify,\r
-                      Private,\r
-                      &Private->PeriodicEvent\r
-                      );\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-    gBS->CloseEvent (Private->TimeoutEvent);\r
-    return efi_status;\r
-  }\r
-\r
-  efi_status = gBS->SetTimer (\r
-                      Private->PeriodicEvent,\r
-                      TimerPeriodic,\r
-                      1000000\r
-                      );  /* 1/10th second */\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-    gBS->CloseEvent (Private->TimeoutEvent);\r
-    gBS->CloseEvent (Private->PeriodicEvent);\r
-    return efi_status;\r
-  }\r
-\r
-  Private->PeriodicOccurred = FALSE;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-VOID\r
-stop_receive_events (\r
-  IN PXE_DHCP4_PRIVATE_DATA *Private\r
-  )\r
-{\r
-  //\r
-  //\r
-  //\r
-  ASSERT (Private);\r
-\r
-  if (Private == NULL) {\r
-    return ;\r
-  }\r
-  //\r
-  //\r
-  //\r
-  gBS->CloseEvent (Private->TimeoutEvent);\r
-  Private->TimeoutOccurred = FALSE;\r
-\r
-  //\r
-  //\r
-  //\r
-  gBS->CloseEvent (Private->PeriodicEvent);\r
-  Private->PeriodicOccurred = FALSE;\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-EFI_STATUS\r
-tx_udp (\r
-  IN PXE_DHCP4_PRIVATE_DATA *Private,\r
-  IN EFI_IP_ADDRESS         *dest_ip,\r
-  IN OPTIONAL EFI_IP_ADDRESS         *gateway_ip,\r
-  IN EFI_IP_ADDRESS         *src_ip,\r
-  IN VOID                   *buffer,\r
-  IN UINTN                  BufferSize\r
-  )\r
-/*++\r
-Routine description:\r
-  Transmit DHCP packet.\r
-\r
-Parameters:\r
-  Private := Pointer to PxeDhcp4 private data\r
-  dest_ip := Pointer to destination IP address\r
-  gateway_ip := Pointer to gateway IP address or NULL\r
-  src_ip := Pointer to source IP address or NULL\r
-  buffer := Pointer to buffer to transmit\r
-  BufferSize := Size of buffer in bytes\r
-\r
-Returns:\r
-  EFI_INVALID_PARAMETER := Private == NULL || dest_ip == NULL ||\r
-    buffer == NULL || BufferSize < 300 || Private->PxeBc == NULL\r
-  EFI_SUCCESS := Buffer was transmitted\r
-  other := Return from PxeBc->UdpWrite()\r
---*/\r
-{\r
-  EFI_PXE_BASE_CODE_UDP_PORT  dest_port;\r
-  EFI_PXE_BASE_CODE_UDP_PORT  src_port;\r
-  EFI_IP_ADDRESS              zero_ip;\r
-\r
-  //\r
-  //\r
-  //\r
-  ASSERT (Private);\r
-  ASSERT (dest_ip);\r
-  ASSERT (buffer);\r
-  ASSERT (BufferSize >= 300);\r
-\r
-  if (Private == NULL || dest_ip == NULL || buffer == NULL || BufferSize < 300) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  ASSERT (Private->PxeBc);\r
-\r
-  if (Private->PxeBc == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Transmit DHCP discover packet...\r
-  //\r
-  ZeroMem (&zero_ip, sizeof (EFI_IP_ADDRESS));\r
-\r
-  if (src_ip == NULL) {\r
-    src_ip = &zero_ip;\r
-  }\r
-\r
-  dest_port = DHCP4_SERVER_PORT;\r
-  src_port  = DHCP4_CLIENT_PORT;\r
-\r
-  return Private->PxeBc->UdpWrite (\r
-                          Private->PxeBc,\r
-                          EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT,\r
-                          dest_ip,\r
-                          &dest_port,\r
-                          gateway_ip,\r
-                          src_ip,\r
-                          &src_port,\r
-                          NULL,\r
-                          NULL,\r
-                          &BufferSize,\r
-                          buffer\r
-                          );\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-EFI_STATUS\r
-rx_udp (\r
-  IN PXE_DHCP4_PRIVATE_DATA *Private,\r
-  OUT VOID                  *buffer,\r
-  IN OUT UINTN              *BufferSize,\r
-  IN OUT EFI_IP_ADDRESS     *dest_ip,\r
-  IN OUT EFI_IP_ADDRESS     *src_ip,\r
-  IN UINT16                 op_flags\r
-  )\r
-/*++\r
-Routine description:\r
-  Receive DHCP packet.\r
-\r
-Parameters:\r
-  Private := Pointer to PxeDhcp4 private data\r
-  buffer := Pointer to buffer to receive DHCP packet\r
-  BufferSize := Pointer to buffer size in bytes\r
-  dest_ip := Pointer to destination IP address\r
-  src_ip := Pointer to source IP address\r
-  op_flags := UDP receive operation flags\r
-\r
-Returns:\r
-  EFI_INVALID_PARAMETER :=\r
-  EFI_SUCCESS := Packet received\r
-  other := Return from PxeBc->UdpRead()\r
---*/\r
-{\r
-  EFI_PXE_BASE_CODE_UDP_PORT  dest_port;\r
-  EFI_PXE_BASE_CODE_UDP_PORT  src_port;\r
-\r
-  //\r
-  //\r
-  //\r
-  ASSERT (Private);\r
-  ASSERT (buffer);\r
-  ASSERT (dest_ip);\r
-  ASSERT (src_ip);\r
-\r
-  if (Private == NULL || buffer == NULL || dest_ip == NULL || src_ip == NULL || BufferSize == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  ASSERT (Private->PxeBc);\r
-\r
-  if (Private->PxeBc == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Check for packet\r
-  //\r
-  *BufferSize = sizeof (DHCP4_PACKET);\r
-\r
-  dest_port   = DHCP4_CLIENT_PORT;\r
-  src_port    = DHCP4_SERVER_PORT;\r
-\r
-  return Private->PxeBc->UdpRead (\r
-                          Private->PxeBc,\r
-                          op_flags,\r
-                          dest_ip,\r
-                          &dest_port,\r
-                          src_ip,\r
-                          &src_port,\r
-                          NULL,\r
-                          NULL,\r
-                          BufferSize,\r
-                          buffer\r
-                          );\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-EFI_STATUS\r
-tx_rx_udp (\r
-  IN PXE_DHCP4_PRIVATE_DATA *Private,\r
-  IN OUT EFI_IP_ADDRESS     *ServerIp,\r
-  IN OPTIONAL EFI_IP_ADDRESS         *gateway_ip,\r
-  IN OPTIONAL EFI_IP_ADDRESS         *client_ip,\r
-  IN OPTIONAL EFI_IP_ADDRESS         *SubnetMask,\r
-  IN DHCP4_PACKET           *tx_pkt,\r
-  OUT DHCP4_PACKET          *rx_pkt,\r
-  IN INTN (*rx_vfy)(\r
-      IN PXE_DHCP4_PRIVATE_DATA *Private,\r
-      IN DHCP4_PACKET *tx_pkt,\r
-      IN DHCP4_PACKET *rx_pkt,\r
-      IN UINTN rx_pkt_size\r
-    ),\r
-  IN UINTN SecondsTimeout\r
-  )\r
-/*++\r
-Routine description:\r
-  Transmit DHCP packet and wait for replies.\r
-\r
-Parameters:\r
-  Private := Pointer to PxeDhcp4 private data\r
-  ServerIp := Pointer to server IP address\r
-  gateway_ip := Pointer to gateway IP address or NULL\r
-  client_ip := Pointer to client IP address or NULL\r
-  SubnetMask := Pointer to subnet mask or NULL\r
-  tx_pkt := Pointer to DHCP packet to transmit\r
-  rx_pkt := Pointer to DHCP packet receive buffer\r
-  rx_vfy := Pointer to DHCP packet receive verification routine\r
-  SecondsTimeout := Number of seconds until timeout\r
-\r
-Returns:\r
-  EFI_INVALID_PARAMETER := Private == NULL || ServerIp == NULL ||\r
-    tx_pkt == NULL || rx_pkt == NULL || rx_vfy == NULL || Private->PxeBc == NULL\r
-  EFI_ABORTED := Receive aborted\r
-  EFI_TIMEOUT := No packets received\r
-  EFI_SUCCESS := Packet(s) received\r
-  other := Returns from other PxeDhcp4 support routines\r
---*/\r
-{\r
-  EFI_PXE_DHCP4_CALLBACK_STATUS CallbackStatus;\r
-  EFI_IP_ADDRESS                dest_ip;\r
-  EFI_IP_ADDRESS                src_ip;\r
-  EFI_STATUS                    efi_status;\r
-  DHCP4_OP                      *msg_size_op;\r
-  UINTN                         pkt_size;\r
-  UINTN                         n;\r
-  UINT16                        msg_size;\r
-  UINT16                        op_flags;\r
-  BOOLEAN                       done_flag;\r
-  BOOLEAN                       got_packet;\r
-\r
-  //\r
-  // Bad programmer check...\r
-  //\r
-  ASSERT (Private);\r
-  ASSERT (ServerIp);\r
-  ASSERT (tx_pkt);\r
-  ASSERT (rx_pkt);\r
-  ASSERT (rx_vfy);\r
-\r
-  if (Private == NULL || ServerIp == NULL || tx_pkt == NULL || rx_pkt == NULL || rx_vfy == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  ASSERT (Private->PxeBc);\r
-\r
-  if (Private->PxeBc == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Enable UDP...\r
-  //\r
-  efi_status = start_udp (Private, client_ip, SubnetMask);\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-    return efi_status;\r
-  }\r
-  //\r
-  // Get length of transmit packet...\r
-  //\r
-  msg_size = DHCP4_DEFAULT_MAX_MESSAGE_SIZE;\r
-\r
-  efi_status = find_opt (\r
-                tx_pkt,\r
-                DHCP4_MAX_MESSAGE_SIZE,\r
-                0,\r
-                &msg_size_op\r
-                );\r
-\r
-  if (!EFI_ERROR (efi_status)) {\r
-    CopyMem (&msg_size, msg_size_op->data, 2);\r
-\r
-    if ((msg_size = htons (msg_size)) < 328) {\r
-      msg_size = 328;\r
-    }\r
-  }\r
-  //\r
-  // Transmit packet...\r
-  //\r
-  efi_status = tx_udp (\r
-                Private,\r
-                ServerIp,\r
-                gateway_ip,\r
-                client_ip,\r
-                tx_pkt,\r
-                msg_size - (DHCP4_UDP_HEADER_SIZE + DHCP4_IP_HEADER_SIZE)\r
-                );\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-    stop_udp (Private);\r
-    return efi_status;\r
-  }\r
-  //\r
-  // Enable periodic and timeout events...\r
-  //\r
-  efi_status = start_receive_events (Private, SecondsTimeout);\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-    stop_udp (Private);\r
-    return efi_status;\r
-  }\r
-  //\r
-  // Wait for packet(s)...\r
-  //\r
-\r
-  done_flag   = FALSE;\r
-  got_packet  = FALSE;\r
-\r
-  while (!done_flag) {\r
-    //\r
-    // Check for timeout event...\r
-    //\r
-    if (Private->TimeoutOccurred) {\r
-      efi_status = EFI_SUCCESS;\r
-      break;\r
-    }\r
-    //\r
-    // Check for periodic event...\r
-    //\r
-    if (Private->PeriodicOccurred && Private->callback != NULL) {\r
-      CallbackStatus = EFI_PXE_DHCP4_CALLBACK_STATUS_CONTINUE;\r
-\r
-      if (Private->callback->Callback != NULL) {\r
-        CallbackStatus = (Private->callback->Callback) (&Private->PxeDhcp4, Private->function, 0, NULL);\r
-      }\r
-\r
-      switch (CallbackStatus) {\r
-      case EFI_PXE_DHCP4_CALLBACK_STATUS_CONTINUE:\r
-        break;\r
-\r
-      case EFI_PXE_DHCP4_CALLBACK_STATUS_ABORT:\r
-      default:\r
-        stop_receive_events (Private);\r
-        stop_udp (Private);\r
-        return EFI_ABORTED;\r
-      }\r
-\r
-      Private->PeriodicOccurred = FALSE;\r
-    }\r
-    //\r
-    // Check for packet...\r
-    //\r
-    if (client_ip == NULL) {\r
-      SetMem (&dest_ip, sizeof (EFI_IP_ADDRESS), 0xFF);\r
-    } else {\r
-      CopyMem (&dest_ip, client_ip, sizeof (EFI_IP_ADDRESS));\r
-    }\r
-\r
-    SetMem (&src_ip, sizeof (EFI_IP_ADDRESS), 0xFF);\r
-\r
-    if (CompareMem (&src_ip, &ServerIp, sizeof (EFI_IP_ADDRESS))) {\r
-      ZeroMem (&src_ip, sizeof (EFI_IP_ADDRESS));\r
-      op_flags = EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP;\r
-    } else {\r
-      op_flags = 0;\r
-    }\r
-\r
-    efi_status = rx_udp (\r
-                  Private,\r
-                  rx_pkt,\r
-                  &pkt_size,\r
-                  &dest_ip,\r
-                  &src_ip,\r
-                  op_flags\r
-                  );\r
-\r
-    if (efi_status == EFI_TIMEOUT) {\r
-      efi_status = EFI_SUCCESS;\r
-      continue;\r
-    }\r
-\r
-    if (EFI_ERROR (efi_status)) {\r
-      break;\r
-    }\r
-    //\r
-    // Some basic packet sanity checks..\r
-    //\r
-    if (pkt_size < 300) {\r
-      continue;\r
-    }\r
-\r
-    if (rx_pkt->dhcp4.op != BOOTP_REPLY) {\r
-      continue;\r
-    }\r
-\r
-    if (tx_pkt->dhcp4.htype != rx_pkt->dhcp4.htype) {\r
-      continue;\r
-    }\r
-\r
-    if ((n = tx_pkt->dhcp4.hlen) != rx_pkt->dhcp4.hlen) {\r
-      continue;\r
-    }\r
-\r
-    if (CompareMem (&tx_pkt->dhcp4.xid, &rx_pkt->dhcp4.xid, 4)) {\r
-      continue;\r
-    }\r
-\r
-    if (n != 0) {\r
-      if (n >= 16) {\r
-        n = 16;\r
-      }\r
-\r
-      if (CompareMem (tx_pkt->dhcp4.chaddr, rx_pkt->dhcp4.chaddr, n)) {\r
-        continue;\r
-      }\r
-    }\r
-    //\r
-    // Internal callback packet verification...\r
-    //\r
-    switch ((*rx_vfy) (Private, tx_pkt, rx_pkt, pkt_size)) {\r
-    case -2:  /* ignore and stop */\r
-      stop_receive_events (Private);\r
-      stop_udp (Private);\r
-      return EFI_ABORTED;\r
-\r
-    case -1:  /* ignore and wait */\r
-      continue;\r
-\r
-    case 0:   /* accept and wait */\r
-      break;\r
-\r
-    case 1:   /* accept and stop */\r
-      done_flag = TRUE;\r
-      break;\r
-\r
-    default:\r
-      ASSERT (0);\r
-    }\r
-    //\r
-    // External callback packet verification...\r
-    //\r
-    CallbackStatus = EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_CONTINUE;\r
-\r
-    if (Private->callback != NULL) {\r
-      if (Private->callback->Callback != NULL) {\r
-        CallbackStatus = (Private->callback->Callback) (&Private->PxeDhcp4, Private->function, (UINT32) pkt_size, rx_pkt);\r
-      }\r
-    }\r
-\r
-    switch (CallbackStatus) {\r
-    case EFI_PXE_DHCP4_CALLBACK_STATUS_IGNORE_CONTINUE:\r
-      continue;\r
-\r
-    case EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_ABORT:\r
-      done_flag = TRUE;\r
-      break;\r
-\r
-    case EFI_PXE_DHCP4_CALLBACK_STATUS_IGNORE_ABORT:\r
-      stop_receive_events (Private);\r
-      stop_udp (Private);\r
-      return EFI_ABORTED;\r
-\r
-    case EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_CONTINUE:\r
-    default:\r
-      break;\r
-    }\r
-    //\r
-    // We did!  We did get a packet!\r
-    //\r
-    got_packet = TRUE;\r
-  }\r
-  //\r
-  //\r
-  //\r
-  stop_receive_events (Private);\r
-  stop_udp (Private);\r
-\r
-  if (EFI_ERROR (efi_status)) {\r
-    DebugPrint (("%s:%d:%r\n", __FILE__, __LINE__, efi_status));\r
-    return efi_status;\r
-  }\r
-\r
-  if (got_packet) {\r
-    return EFI_SUCCESS;\r
-  } else {\r
-    return EFI_TIMEOUT;\r
-  }\r
-}\r
-\r
-/* eof - support.c */\r