3 Copyright (c) 2004 - 2005, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 Miscellaneous support routines for PxeDhcp4 protocol.
26 // #define DebugPrint(x) Aprint x
29 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
35 return (UINT16
) ((n
>> 8) | (n
<< 8));
38 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
44 return (UINT32
) ((n
>> 24) | ((n
>> 8) & 0xFF00) | ((n
& 0xFF00) << 8) | (n
<< 24));
47 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
57 if (Context
!= NULL
) {
58 ((PXE_DHCP4_PRIVATE_DATA
*) Context
)->TimeoutOccurred
= TRUE
;
62 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
72 if (Context
!= NULL
) {
73 ((PXE_DHCP4_PRIVATE_DATA
*) Context
)->PeriodicOccurred
= TRUE
;
77 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
81 @return EFI_SUCCESS := Option was found
82 @return EFI_INVALID_PARAMETER := Packet == NULL || OpPtr == NULL
83 @return EFI_INVALID_PARAMETER := OpCode == DHCP4_PAD
84 @return EFI_INVALID_PARAMETER := OpCode == DHCP4_END && Skip != 0
85 @return EFI_INVALID_PARAMETER := DHCP magik number in Packet is not valid
86 @return EFI_NOT_FOUND := op-code was not found in packet
87 @return EFI_INVALID_PARAMETER := If present, DHCP_MAX_MESSAGE_SIZE option
88 @return does not have a valid value.
93 IN DHCP4_PACKET
*Packet
,
107 // Verify parameters.
109 if (Packet
== NULL
|| OpPtr
== NULL
|| OpCode
== DHCP4_PAD
|| (OpCode
== DHCP4_END
&& Skip
!= 0)) {
110 return EFI_INVALID_PARAMETER
;
113 if (Packet
->dhcp4
.magik
!= htonl (DHCP4_MAGIK_NUMBER
)) {
114 return EFI_INVALID_PARAMETER
;
117 // Initialize search variables.
121 msg_size
= DHCP4_MAX_PACKET_SIZE
- (DHCP4_UDP_HEADER_SIZE
+ DHCP4_IP_HEADER_SIZE
);
126 buf
= Packet
->dhcp4
.options
;
127 buf_len
= msg_size
- (Packet
->dhcp4
.options
- Packet
->raw
);
130 // Start searching for requested option.
134 // If match is found, decrement skip count and return
135 // when desired match is found.
137 if (buf
[n
] == OpCode
) {
138 *OpPtr
= (DHCP4_OP
*) &buf
[n
];
145 // Skip past current option. Check for option overload
146 // and message size options since these will affect the
147 // amount of data to be searched.
152 // Remember the first pad byte of a group. This
153 // could be the end of a badly formed packet.
155 if (end_ptr
== NULL
) {
164 // If we reach the end we are done.
167 return EFI_NOT_FOUND
;
169 case DHCP4_OPTION_OVERLOAD
:
171 // Remember the option overload value since it
172 // could cause the search to continue into
173 // the fname and sname fields.
177 if (buf
[n
+ 1] == 1) {
178 overload
= buf
[n
+ 2];
184 case DHCP4_MAX_MESSAGE_SIZE
:
186 // Remember the message size value since it could
187 // change the amount of option buffer to search.
191 if (buf
[n
+ 1] == 2 && buf
== Packet
->dhcp4
.options
) {
192 msg_size
= ((buf
[n
+ 2] << 8) | buf
[n
+ 3]) - (DHCP4_UDP_HEADER_SIZE
+ DHCP4_IP_HEADER_SIZE
);
194 if (msg_size
< 328) {
195 return EFI_INVALID_PARAMETER
;
198 buf_len
= msg_size
- (Packet
->dhcp4
.options
- Packet
->raw
);
200 if (n
+ 2 + buf
[n
+ 1] > buf_len
) {
201 return EFI_INVALID_PARAMETER
;
212 // Keep searching until the end of the buffer is reached.
218 // Reached end of current buffer. Check if we are supposed
219 // to search the fname and sname buffers.
221 if (buf
== Packet
->dhcp4
.options
&&
222 (overload
== DHCP4_OVERLOAD_FNAME
|| overload
== DHCP4_OVERLOAD_FNAME_AND_SNAME
)
224 buf
= Packet
->dhcp4
.fname
;
230 if (buf
!= Packet
->dhcp4
.sname
&& (overload
== DHCP4_OVERLOAD_SNAME
|| overload
== DHCP4_OVERLOAD_FNAME_AND_SNAME
)) {
231 buf
= Packet
->dhcp4
.sname
;
237 // End of last buffer reached. If this was a search
238 // for the end of the options, go back to the start
239 // of the current pad block.
241 if (OpCode
== DHCP4_END
&& end_ptr
!= NULL
) {
242 *OpPtr
= (DHCP4_OP
*) end_ptr
;
246 return EFI_NOT_FOUND
;
250 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
254 @return EFI_INVALID_PARAMETER := Packet == NULL || OpPtr == NULL
255 @return EFI_INVALID_PARAMETER := OpPtr->op == DHCP4_PAD || OpPtr->op == DHCP4_END
256 @return EFI_INVALID_PARAMETER := DHCP magik number in DHCP packet is not valid
257 @return EFI_INVALID_PARAMETER := If DHCP_MAX_MESSAGE_SIZE option is present and
259 @return EFI_INVALID_PARAMETER := If DHCP_OPTION_OVERLOAD option is present and
261 @return EFI_DEVICE_ERROR := Cannot determine end of packet
262 @return EFI_BUFFER_TOO_SMALL := Not enough room in packet to add option
263 @return EFI_SUCCESS := Option added to DHCP packet
268 IN DHCP4_PACKET
*Packet
,
272 EFI_STATUS efi_status
;
273 DHCP4_OP
*msg_size_op
;
274 DHCP4_OP
*overload_op
;
282 // Verify parameters.
287 if (Packet
== NULL
|| OpPtr
== NULL
) {
288 return EFI_INVALID_PARAMETER
;
295 // No adding PAD or END.
297 return EFI_INVALID_PARAMETER
;
300 // Check the DHCP magik number.
302 CopyMem (&magik
, &Packet
->dhcp4
.magik
, 4);
304 if (magik
!= htonl (DHCP4_MAGIK_NUMBER
)) {
305 return EFI_INVALID_PARAMETER
;
308 // Find the DHCP message size option.
310 msg_size
= DHCP4_DEFAULT_MAX_MESSAGE_SIZE
;
312 efi_status
= find_opt (
314 DHCP4_MAX_MESSAGE_SIZE
,
319 if (EFI_ERROR (efi_status
)) {
320 if (efi_status
!= EFI_NOT_FOUND
) {
332 CopyMem (&msg_size
, msg_size_op
->data
, 2);
333 msg_size
= htons (msg_size
);
335 if (msg_size
< DHCP4_DEFAULT_MAX_MESSAGE_SIZE
) {
336 return EFI_INVALID_PARAMETER
;
340 // Find the DHCP option overload option.
342 efi_status
= find_opt (
344 DHCP4_OPTION_OVERLOAD
,
349 if (EFI_ERROR (efi_status
)) {
350 if (efi_status
!= EFI_NOT_FOUND
) {
362 if (overload_op
->len
!= 1) {
363 return EFI_INVALID_PARAMETER
;
366 switch (overload_op
->data
[0]) {
373 return EFI_INVALID_PARAMETER
;
377 // Find the end of the packet.
379 efi_status
= find_opt (Packet
, DHCP4_END
, 0, &op
);
381 if (EFI_ERROR (efi_status
)) {
382 return EFI_INVALID_PARAMETER
;
385 // Find which buffer the end is in.
387 if ((UINTN
) op
>= (UINTN
) (buf
= Packet
->dhcp4
.options
)) {
388 buf_len
= (msg_size
- ((UINT8
*) &Packet
->dhcp4
.options
- (UINT8
*) &Packet
->raw
)) - (DHCP4_UDP_HEADER_SIZE
+ DHCP4_IP_HEADER_SIZE
);
389 } else if ((UINTN
) op
>= (UINTN
) (buf
= Packet
->dhcp4
.fname
)) {
391 } else if ((UINTN
) op
>= (UINTN
) (buf
= Packet
->dhcp4
.sname
)) {
394 return EFI_DEVICE_ERROR
;
397 // Add option to current buffer if there is no overlow.
399 if ((UINTN
) ((&op
->op
- buf
) + 3 + op
->len
) < buf_len
) {
400 CopyMem (op
, OpPtr
, OpPtr
->len
+ 2);
402 op
->data
[op
->len
] = DHCP4_END
;
407 // Error if there is no space for option.
409 return EFI_BUFFER_TOO_SMALL
;
412 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
416 @return EFI_INVALID_PARAMETER := Private == NULL || Private->PxeBc == NULL
417 @return EFI_INVALID_PARAMETER := Only one of StationIp and SubnetMask is given
418 @return EFI_SUCCESS := UDP stack is ready
419 @return other := Error from PxeBc->SetIpFilter() or PxeBc->SetStationIp()
424 IN PXE_DHCP4_PRIVATE_DATA
*Private
,
425 IN OPTIONAL EFI_IP_ADDRESS
*StationIp
,
426 IN OPTIONAL EFI_IP_ADDRESS
*SubnetMask
429 EFI_PXE_BASE_CODE_IP_FILTER bcast_filter
;
430 EFI_STATUS efi_status
;
436 ASSERT (Private
->PxeBc
);
438 if (Private
== NULL
) {
439 return EFI_INVALID_PARAMETER
;
442 if (Private
->PxeBc
== NULL
) {
443 return EFI_INVALID_PARAMETER
;
446 if (StationIp
!= NULL
&& SubnetMask
== NULL
) {
447 return EFI_INVALID_PARAMETER
;
450 if (StationIp
== NULL
&& SubnetMask
!= NULL
) {
451 return EFI_INVALID_PARAMETER
;
454 // Setup broadcast receive filter...
456 ZeroMem (&bcast_filter
, sizeof (EFI_PXE_BASE_CODE_IP_FILTER
));
458 bcast_filter
.Filters
= EFI_PXE_BASE_CODE_IP_FILTER_BROADCAST
;
459 bcast_filter
.IpCnt
= 0;
461 efi_status
= Private
->PxeBc
->SetIpFilter (
466 if (EFI_ERROR (efi_status
)) {
467 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
471 // Configure station IP address and subnet mask...
473 efi_status
= Private
->PxeBc
->SetStationIp (
479 if (EFI_ERROR (efi_status
)) {
480 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
486 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
489 IN PXE_DHCP4_PRIVATE_DATA
*Private
496 ASSERT (Private
->PxeBc
);
499 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
506 start_receive_events (
507 IN PXE_DHCP4_PRIVATE_DATA
*Private
,
508 IN UINTN SecondsTimeout
511 EFI_STATUS efi_status
;
518 ASSERT (SecondsTimeout
);
520 if (Private
== NULL
|| SecondsTimeout
== 0) {
521 return EFI_INVALID_PARAMETER
;
524 // Need a bettern randomizer...
525 // For now adjust the timeout value by the least significant
526 // digit in the MAC address.
530 if (Private
->PxeDhcp4
.Data
!= NULL
) {
531 if (Private
->PxeDhcp4
.Data
->Discover
.dhcp4
.hlen
!= 0 && Private
->PxeDhcp4
.Data
->Discover
.dhcp4
.hlen
<= 16) {
532 random
= 0xFFF & Private
->PxeDhcp4
.Data
->Discover
.dhcp4
.chaddr
[Private
->PxeDhcp4
.Data
->Discover
.dhcp4
.hlen
- 1];
536 // Setup timeout event and start timer.
538 efi_status
= gBS
->CreateEvent (
539 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
543 &Private
->TimeoutEvent
546 if (EFI_ERROR (efi_status
)) {
547 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
551 efi_status
= gBS
->SetTimer (
552 Private
->TimeoutEvent
,
554 SecondsTimeout
* 10000000 + random
557 if (EFI_ERROR (efi_status
)) {
558 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
559 gBS
->CloseEvent (Private
->TimeoutEvent
);
563 Private
->TimeoutOccurred
= FALSE
;
566 // Setup periodic event for callbacks
568 efi_status
= gBS
->CreateEvent (
569 EVT_TIMER
| EVT_NOTIFY_SIGNAL
,
573 &Private
->PeriodicEvent
576 if (EFI_ERROR (efi_status
)) {
577 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
578 gBS
->CloseEvent (Private
->TimeoutEvent
);
582 efi_status
= gBS
->SetTimer (
583 Private
->PeriodicEvent
,
586 ); /* 1/10th second */
588 if (EFI_ERROR (efi_status
)) {
589 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
590 gBS
->CloseEvent (Private
->TimeoutEvent
);
591 gBS
->CloseEvent (Private
->PeriodicEvent
);
595 Private
->PeriodicOccurred
= FALSE
;
600 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
602 stop_receive_events (
603 IN PXE_DHCP4_PRIVATE_DATA
*Private
611 if (Private
== NULL
) {
617 gBS
->CloseEvent (Private
->TimeoutEvent
);
618 Private
->TimeoutOccurred
= FALSE
;
623 gBS
->CloseEvent (Private
->PeriodicEvent
);
624 Private
->PeriodicOccurred
= FALSE
;
627 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
631 @return EFI_INVALID_PARAMETER := Private == NULL || dest_ip == NULL ||
632 @return buffer == NULL || BufferSize < 300 || Private->PxeBc == NULL
633 @return EFI_SUCCESS := Buffer was transmitted
634 @return other := Return from PxeBc->UdpWrite()
639 IN PXE_DHCP4_PRIVATE_DATA
*Private
,
640 IN EFI_IP_ADDRESS
*dest_ip
,
641 IN OPTIONAL EFI_IP_ADDRESS
*gateway_ip
,
642 IN EFI_IP_ADDRESS
*src_ip
,
647 EFI_PXE_BASE_CODE_UDP_PORT dest_port
;
648 EFI_PXE_BASE_CODE_UDP_PORT src_port
;
649 EFI_IP_ADDRESS zero_ip
;
657 ASSERT (BufferSize
>= 300);
659 if (Private
== NULL
|| dest_ip
== NULL
|| buffer
== NULL
|| BufferSize
< 300) {
660 return EFI_INVALID_PARAMETER
;
663 ASSERT (Private
->PxeBc
);
665 if (Private
->PxeBc
== NULL
) {
666 return EFI_INVALID_PARAMETER
;
669 // Transmit DHCP discover packet...
671 ZeroMem (&zero_ip
, sizeof (EFI_IP_ADDRESS
));
673 if (src_ip
== NULL
) {
677 dest_port
= DHCP4_SERVER_PORT
;
678 src_port
= DHCP4_CLIENT_PORT
;
680 return Private
->PxeBc
->UdpWrite (
682 EFI_PXE_BASE_CODE_UDP_OPFLAGS_MAY_FRAGMENT
,
695 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
699 @return EFI_INVALID_PARAMETER :=
700 @return EFI_SUCCESS := Packet received
701 @return other := Return from PxeBc->UdpRead()
706 IN PXE_DHCP4_PRIVATE_DATA
*Private
,
708 IN OUT UINTN
*BufferSize
,
709 IN OUT EFI_IP_ADDRESS
*dest_ip
,
710 IN OUT EFI_IP_ADDRESS
*src_ip
,
714 EFI_PXE_BASE_CODE_UDP_PORT dest_port
;
715 EFI_PXE_BASE_CODE_UDP_PORT src_port
;
725 if (Private
== NULL
|| buffer
== NULL
|| dest_ip
== NULL
|| src_ip
== NULL
|| BufferSize
== NULL
) {
726 return EFI_INVALID_PARAMETER
;
729 ASSERT (Private
->PxeBc
);
731 if (Private
->PxeBc
== NULL
) {
732 return EFI_INVALID_PARAMETER
;
737 *BufferSize
= sizeof (DHCP4_PACKET
);
739 dest_port
= DHCP4_CLIENT_PORT
;
740 src_port
= DHCP4_SERVER_PORT
;
742 return Private
->PxeBc
->UdpRead (
756 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
759 IN PXE_DHCP4_PRIVATE_DATA
*Private
,
760 IN OUT EFI_IP_ADDRESS
*ServerIp
,
761 IN OPTIONAL EFI_IP_ADDRESS
*gateway_ip
,
762 IN OPTIONAL EFI_IP_ADDRESS
*client_ip
,
763 IN OPTIONAL EFI_IP_ADDRESS
*SubnetMask
,
764 IN DHCP4_PACKET
*tx_pkt
,
765 OUT DHCP4_PACKET
*rx_pkt
,
767 IN PXE_DHCP4_PRIVATE_DATA
*Private
,
768 IN DHCP4_PACKET
*tx_pkt
,
769 IN DHCP4_PACKET
*rx_pkt
,
772 IN UINTN SecondsTimeout
776 Transmit DHCP packet and wait for replies.
779 Private := Pointer to PxeDhcp4 private data
780 ServerIp := Pointer to server IP address
781 gateway_ip := Pointer to gateway IP address or NULL
782 client_ip := Pointer to client IP address or NULL
783 SubnetMask := Pointer to subnet mask or NULL
784 tx_pkt := Pointer to DHCP packet to transmit
785 rx_pkt := Pointer to DHCP packet receive buffer
786 rx_vfy := Pointer to DHCP packet receive verification routine
787 SecondsTimeout := Number of seconds until timeout
790 EFI_INVALID_PARAMETER := Private == NULL || ServerIp == NULL ||
791 tx_pkt == NULL || rx_pkt == NULL || rx_vfy == NULL || Private->PxeBc == NULL
792 EFI_ABORTED := Receive aborted
793 EFI_TIMEOUT := No packets received
794 EFI_SUCCESS := Packet(s) received
795 other := Returns from other PxeDhcp4 support routines
798 EFI_PXE_DHCP4_CALLBACK_STATUS CallbackStatus
;
799 EFI_IP_ADDRESS dest_ip
;
800 EFI_IP_ADDRESS src_ip
;
801 EFI_STATUS efi_status
;
802 DHCP4_OP
*msg_size_op
;
811 // Bad programmer check...
819 if (Private
== NULL
|| ServerIp
== NULL
|| tx_pkt
== NULL
|| rx_pkt
== NULL
|| rx_vfy
== NULL
) {
820 return EFI_INVALID_PARAMETER
;
823 ASSERT (Private
->PxeBc
);
825 if (Private
->PxeBc
== NULL
) {
826 return EFI_INVALID_PARAMETER
;
831 efi_status
= start_udp (Private
, client_ip
, SubnetMask
);
833 if (EFI_ERROR (efi_status
)) {
834 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
838 // Get length of transmit packet...
840 msg_size
= DHCP4_DEFAULT_MAX_MESSAGE_SIZE
;
842 efi_status
= find_opt (
844 DHCP4_MAX_MESSAGE_SIZE
,
849 if (!EFI_ERROR (efi_status
)) {
850 CopyMem (&msg_size
, msg_size_op
->data
, 2);
852 if ((msg_size
= htons (msg_size
)) < 328) {
857 // Transmit packet...
859 efi_status
= tx_udp (
865 msg_size
- (DHCP4_UDP_HEADER_SIZE
+ DHCP4_IP_HEADER_SIZE
)
868 if (EFI_ERROR (efi_status
)) {
869 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
874 // Enable periodic and timeout events...
876 efi_status
= start_receive_events (Private
, SecondsTimeout
);
878 if (EFI_ERROR (efi_status
)) {
879 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
884 // Wait for packet(s)...
888 Aprint ("client_ip == NULL ");
891 "client_ip == %d.%d.%d.%d ",
892 client_ip
->v4
.Addr
[0],
893 client_ip
->v4
.Addr
[1],
894 client_ip
->v4
.Addr
[2],
895 client_ip
->v4
.Addr
[3]
900 Aprint ("ServerIp == NULL\n");
903 "ServerIp == %d.%d.%d.%d\n",
904 ServerIp
->v4
.Addr
[0],
905 ServerIp
->v4
.Addr
[1],
906 ServerIp
->v4
.Addr
[2],
917 // Check for timeout event...
919 if (Private
->TimeoutOccurred
) {
920 efi_status
= EFI_SUCCESS
;
924 // Check for periodic event...
926 if (Private
->PeriodicOccurred
&& Private
->callback
!= NULL
) {
927 CallbackStatus
= EFI_PXE_DHCP4_CALLBACK_STATUS_CONTINUE
;
929 if (Private
->callback
->Callback
!= NULL
) {
930 CallbackStatus
= (Private
->callback
->Callback
) (&Private
->PxeDhcp4
, Private
->function
, 0, NULL
);
933 switch (CallbackStatus
) {
934 case EFI_PXE_DHCP4_CALLBACK_STATUS_CONTINUE
:
937 case EFI_PXE_DHCP4_CALLBACK_STATUS_ABORT
:
939 stop_receive_events (Private
);
944 Private
->PeriodicOccurred
= FALSE
;
947 // Check for packet...
949 if (client_ip
== NULL
) {
950 SetMem (&dest_ip
, sizeof (EFI_IP_ADDRESS
), 0xFF);
952 CopyMem (&dest_ip
, client_ip
, sizeof (EFI_IP_ADDRESS
));
955 SetMem (&src_ip
, sizeof (EFI_IP_ADDRESS
), 0xFF);
957 if (CompareMem (&src_ip
, &ServerIp
, sizeof (EFI_IP_ADDRESS
))) {
958 ZeroMem (&src_ip
, sizeof (EFI_IP_ADDRESS
));
959 op_flags
= EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP
;
964 efi_status
= rx_udp (
973 if (efi_status
== EFI_TIMEOUT
) {
974 efi_status
= EFI_SUCCESS
;
978 if (EFI_ERROR (efi_status
)) {
982 // Some basic packet sanity checks..
984 if (pkt_size
< 300) {
988 if (rx_pkt
->dhcp4
.op
!= BOOTP_REPLY
) {
992 if (tx_pkt
->dhcp4
.htype
!= rx_pkt
->dhcp4
.htype
) {
996 if ((n
= tx_pkt
->dhcp4
.hlen
) != rx_pkt
->dhcp4
.hlen
) {
1000 if (CompareMem (&tx_pkt
->dhcp4
.xid
, &rx_pkt
->dhcp4
.xid
, 4)) {
1009 if (CompareMem (tx_pkt
->dhcp4
.chaddr
, rx_pkt
->dhcp4
.chaddr
, n
)) {
1014 // Internal callback packet verification...
1016 switch ((*rx_vfy
) (Private
, tx_pkt
, rx_pkt
, pkt_size
)) {
1017 case -2: /* ignore and stop */
1018 stop_receive_events (Private
);
1022 case -1: /* ignore and wait */
1025 case 0: /* accept and wait */
1028 case 1: /* accept and stop */
1036 // External callback packet verification...
1038 CallbackStatus
= EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_CONTINUE
;
1040 if (Private
->callback
!= NULL
) {
1041 if (Private
->callback
->Callback
!= NULL
) {
1042 CallbackStatus
= (Private
->callback
->Callback
) (&Private
->PxeDhcp4
, Private
->function
, (UINT32
) pkt_size
, rx_pkt
);
1046 switch (CallbackStatus
) {
1047 case EFI_PXE_DHCP4_CALLBACK_STATUS_IGNORE_CONTINUE
:
1050 case EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_ABORT
:
1054 case EFI_PXE_DHCP4_CALLBACK_STATUS_IGNORE_ABORT
:
1055 stop_receive_events (Private
);
1059 case EFI_PXE_DHCP4_CALLBACK_STATUS_KEEP_CONTINUE
:
1064 // We did! We did get a packet!
1071 stop_receive_events (Private
);
1074 if (EFI_ERROR (efi_status
)) {
1075 DebugPrint (("%s:%d:%r\n", __FILE__
, __LINE__
, efi_status
));
1086 /* eof - support.c */