2 Windows Packet Filter implementation of the EMU_SNP_PROTOCOL that allows the
3 emulator to get on real networks.
5 Copyright (c) 2004 - 2009, Intel Corporation. All rights reserved.<BR>
6 Portions copyright (c) 2011, Apple Inc. All rights reserved.
7 (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
9 SPDX-License-Identifier: BSD-2-Clause-Patent
14 #define NETWORK_LIBRARY_NAME_U L"SnpNt32Io.dll"
15 #define NETWORK_LIBRARY_INITIALIZE "SnpInitialize"
16 #define NETWORK_LIBRARY_FINALIZE "SnpFinalize"
17 #define NETWORK_LIBRARY_SET_RCV_FILTER "SnpSetReceiveFilter"
18 #define NETWORK_LIBRARY_RECEIVE "SnpReceive"
19 #define NETWORK_LIBRARY_TRANSMIT "SnpTransmit"
22 typedef struct _NT_NET_INTERFACE_INFO
{
23 UINT32 InterfaceIndex
;
24 EFI_MAC_ADDRESS MacAddr
;
25 } NT_NET_INTERFACE_INFO
;
28 #define NET_ETHER_HEADER_SIZE 14
29 #define MAX_INTERFACE_INFO_NUMBER 16
30 #define SNP_MAX_TX_BUFFER_NUM 65536
31 #define SNP_TX_BUFFER_INCREASEMENT 32
32 #define DEFAULT_SELECTED_NIC_INDEX 0
35 // Functions in Net Library
39 (*NT_NET_INITIALIZE
) (
40 IN OUT UINT32
*InterfaceCount
,
41 IN OUT NT_NET_INTERFACE_INFO
* InterfaceInfoBuffer
52 (*NT_NET_SET_RECEIVE_FILTER
) (
54 IN UINT32 EnableFilter
,
55 IN UINT32 MCastFilterCnt
,
56 IN EFI_MAC_ADDRESS
* MCastFilter
63 IN OUT UINT32
*BufferSize
,
74 IN EFI_MAC_ADDRESS
* SrcAddr
,
75 IN EFI_MAC_ADDRESS
* DestAddr
,
79 typedef struct _NT_NET_UTILITY_TABLE
{
80 NT_NET_INITIALIZE Initialize
;
81 NT_NET_FINALIZE Finalize
;
82 NT_NET_SET_RECEIVE_FILTER SetReceiveFilter
;
83 NT_NET_RECEIVE Receive
;
84 NT_NET_TRANSMIT Transmit
;
85 } NT_NET_UTILITY_TABLE
;
88 // Instance data for each fake SNP instance
90 #define WIN_NT_INSTANCE_SIGNATURE SIGNATURE_32 ('N', 'T', 'I', 'S')
96 // Array of the recycled transmit buffer address.
98 UINT64
*RecycledTxBuf
;
101 // Current number of recycled buffer pointers in RecycledTxBuf.
103 UINT32 RecycledTxBufCount
;
106 // The maximum number of recycled buffer pointers in RecycledTxBuf.
108 UINT32 MaxRecycledTxBuf
;
109 EFI_SIMPLE_NETWORK_MODE Mode
;
110 NT_NET_INTERFACE_INFO InterfaceInfo
;
111 } WIN_NT_INSTANCE_DATA
;
114 // Instance data for each SNP private instance
116 #define WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE SIGNATURE_32 ('N', 'T', 's', 'n')
120 EMU_IO_THUNK_PROTOCOL
*Thunk
;
121 EMU_SNP_PROTOCOL EmuSnp
;
122 EFI_SIMPLE_NETWORK_MODE
*Mode
;
123 HMODULE NetworkLibraryHandle
;
124 NT_NET_UTILITY_TABLE NtNetUtilityTable
;
125 WIN_NT_INSTANCE_DATA Instance
;
126 } WIN_NT_SNP_PRIVATE
;
128 #define WIN_NT_SNP_PRIVATE_DATA_FROM_THIS(a) \
129 CR(a, WIN_NT_SNP_PRIVATE, EmuSnp, WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE)
133 Register storage for SNP Mode.
135 @param This Protocol instance pointer.
136 @param Mode SimpleNetworkProtocol Mode structure passed into driver.
138 @retval EFI_SUCCESS The network interface was started.
139 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
143 WinNtSnpCreateMapping (
144 IN EMU_SNP_PROTOCOL
*This
,
145 IN EFI_SIMPLE_NETWORK_MODE
*Mode
148 WIN_NT_SNP_PRIVATE
*Private
;
150 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
152 Private
->Mode
= Mode
;
155 // Set the broadcast address.
157 CopyMem (&Mode
->BroadcastAddress
, &Private
->Instance
.Mode
.BroadcastAddress
, sizeof (EFI_MAC_ADDRESS
));
159 // Set the MAC address.
161 CopyMem (&Mode
->CurrentAddress
, &Private
->Instance
.Mode
.CurrentAddress
, sizeof (EFI_MAC_ADDRESS
));
162 CopyMem (&Mode
->PermanentAddress
, &Private
->Instance
.Mode
.PermanentAddress
, sizeof (EFI_MAC_ADDRESS
));
168 Changes the state of a network interface from "stopped" to "started".
170 @param This Protocol instance pointer.
172 @retval EFI_SUCCESS The network interface was started.
173 @retval EFI_ALREADY_STARTED The network interface is already in the started state.
174 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
175 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
176 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
181 IN EMU_SNP_PROTOCOL
*This
184 WIN_NT_SNP_PRIVATE
*Private
;
186 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
188 switch (Private
->Mode
->State
) {
189 case EfiSimpleNetworkStopped
:
192 case EfiSimpleNetworkStarted
:
193 case EfiSimpleNetworkInitialized
:
194 return EFI_ALREADY_STARTED
;
198 return EFI_DEVICE_ERROR
;
202 Private
->Mode
->State
= EfiSimpleNetworkStarted
;
208 Changes the state of a network interface from "started" to "stopped".
210 @param This Protocol instance pointer.
212 @retval EFI_SUCCESS The network interface was stopped.
213 @retval EFI_ALREADY_STARTED The network interface is already in the stopped state.
214 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
215 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
216 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
221 IN EMU_SNP_PROTOCOL
*This
224 WIN_NT_SNP_PRIVATE
*Private
;
226 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
228 switch ( Private
->Mode
->State
) {
229 case EfiSimpleNetworkStarted
:
232 case EfiSimpleNetworkStopped
:
233 return EFI_NOT_STARTED
;
237 return EFI_DEVICE_ERROR
;
241 Private
->Mode
->State
= EfiSimpleNetworkStopped
;
247 Resets a network adapter and allocates the transmit and receive buffers
248 required by the network interface; optionally, also requests allocation
249 of additional transmit and receive buffers.
251 @param This The protocol instance pointer.
252 @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
253 that the driver should allocate for the network interface.
254 Some network interfaces will not be able to use the extra
255 buffer, and the caller will not know if it is actually
257 @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
258 that the driver should allocate for the network interface.
259 Some network interfaces will not be able to use the extra
260 buffer, and the caller will not know if it is actually
263 @retval EFI_SUCCESS The network interface was initialized.
264 @retval EFI_NOT_STARTED The network interface has not been started.
265 @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and
267 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
268 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
269 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
274 IN EMU_SNP_PROTOCOL
*This
,
275 IN UINTN ExtraRxBufferSize OPTIONAL
,
276 IN UINTN ExtraTxBufferSize OPTIONAL
279 WIN_NT_SNP_PRIVATE
*Private
;
281 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
283 switch ( Private
->Mode
->State
) {
284 case EfiSimpleNetworkStarted
:
287 case EfiSimpleNetworkStopped
:
288 return EFI_NOT_STARTED
;
292 return EFI_DEVICE_ERROR
;
296 Private
->Mode
->MCastFilterCount
= 0;
297 Private
->Mode
->ReceiveFilterSetting
= 0;
298 ZeroMem (Private
->Mode
->MCastFilter
, sizeof (Private
->Mode
->MCastFilter
));
300 Private
->Mode
->State
= EfiSimpleNetworkInitialized
;
306 Resets a network adapter and re-initializes it with the parameters that were
307 provided in the previous call to Initialize().
309 @param This The protocol instance pointer.
310 @param ExtendedVerification Indicates that the driver may perform a more
311 exhaustive verification operation of the device
314 @retval EFI_SUCCESS The network interface was reset.
315 @retval EFI_NOT_STARTED The network interface has not been started.
316 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
317 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
318 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
323 IN EMU_SNP_PROTOCOL
*This
,
324 IN BOOLEAN ExtendedVerification
327 WIN_NT_SNP_PRIVATE
*Private
;
329 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
331 switch ( Private
->Mode
->State
) {
332 case EfiSimpleNetworkInitialized
:
335 case EfiSimpleNetworkStopped
:
336 return EFI_NOT_STARTED
;
340 return EFI_DEVICE_ERROR
;
348 Resets a network adapter and leaves it in a state that is safe for
349 another driver to initialize.
351 @param This Protocol instance pointer.
353 @retval EFI_SUCCESS The network interface was shutdown.
354 @retval EFI_NOT_STARTED The network interface has not been started.
355 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
356 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
357 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
362 IN EMU_SNP_PROTOCOL
*This
365 WIN_NT_SNP_PRIVATE
*Private
;
367 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
369 switch ( Private
->Mode
->State
) {
370 case EfiSimpleNetworkInitialized
:
373 case EfiSimpleNetworkStopped
:
374 return EFI_NOT_STARTED
;
378 return EFI_DEVICE_ERROR
;
382 Private
->Mode
->State
= EfiSimpleNetworkStarted
;
384 Private
->Mode
->ReceiveFilterSetting
= 0;
385 Private
->Mode
->MCastFilterCount
= 0;
386 ZeroMem (Private
->Mode
->MCastFilter
, sizeof (Private
->Mode
->MCastFilter
));
392 Manages the multicast receive filters of a network interface.
394 @param This The protocol instance pointer.
395 @param Enable A bit mask of receive filters to enable on the network interface.
396 @param Disable A bit mask of receive filters to disable on the network interface.
397 @param ResetMCastFilter Set to TRUE to reset the contents of the multicast receive
398 filters on the network interface to their default values.
399 @param McastFilterCnt Number of multicast HW MAC addresses in the new
400 MCastFilter list. This value must be less than or equal to
401 the MCastFilterCnt field of EMU_SNP_MODE. This
402 field is optional if ResetMCastFilter is TRUE.
403 @param MCastFilter A pointer to a list of new multicast receive filter HW MAC
404 addresses. This list will replace any existing multicast
405 HW MAC address list. This field is optional if
406 ResetMCastFilter is TRUE.
408 @retval EFI_SUCCESS The multicast receive filter list was updated.
409 @retval EFI_NOT_STARTED The network interface has not been started.
410 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
411 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
412 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
416 WinNtSnpReceiveFilters (
417 IN EMU_SNP_PROTOCOL
*This
,
420 IN BOOLEAN ResetMCastFilter
,
421 IN UINTN MCastFilterCnt OPTIONAL
,
422 IN EFI_MAC_ADDRESS
*MCastFilter OPTIONAL
425 WIN_NT_SNP_PRIVATE
*Private
;
428 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
430 ReturnValue
= Private
->NtNetUtilityTable
.SetReceiveFilter (
431 Private
->Instance
.InterfaceInfo
.InterfaceIndex
,
433 (UINT32
)MCastFilterCnt
,
437 if (ReturnValue
<= 0) {
438 return EFI_DEVICE_ERROR
;
445 Modifies or resets the current station address, if supported.
447 @param This The protocol instance pointer.
448 @param Reset Flag used to reset the station address to the network interfaces
450 @param New The new station address to be used for the network interface.
452 @retval EFI_SUCCESS The network interfaces station address was updated.
453 @retval EFI_NOT_STARTED The network interface has not been started.
454 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
455 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
456 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
460 WinNtSnpStationAddress (
461 IN EMU_SNP_PROTOCOL
*This
,
463 IN EFI_MAC_ADDRESS
*New OPTIONAL
466 WIN_NT_SNP_PRIVATE
*Private
;
468 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
470 return EFI_UNSUPPORTED
;
474 Resets or collects the statistics on a network interface.
476 @param This Protocol instance pointer.
477 @param Reset Set to TRUE to reset the statistics for the network interface.
478 @param StatisticsSize On input the size, in bytes, of StatisticsTable. On
479 output the size, in bytes, of the resulting table of
481 @param StatisticsTable A pointer to the EFI_NETWORK_STATISTICS structure that
482 contains the statistics.
484 @retval EFI_SUCCESS The statistics were collected from the network interface.
485 @retval EFI_NOT_STARTED The network interface has not been started.
486 @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
487 size needed to hold the statistics is returned in
489 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
490 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
491 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
496 IN EMU_SNP_PROTOCOL
*This
,
498 IN OUT UINTN
*StatisticsSize OPTIONAL
,
499 OUT EFI_NETWORK_STATISTICS
*StatisticsTable OPTIONAL
502 WIN_NT_SNP_PRIVATE
*Private
;
504 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
506 return EFI_UNSUPPORTED
;
510 Converts a multicast IP address to a multicast HW MAC address.
512 @param This The protocol instance pointer.
513 @param IPv6 Set to TRUE if the multicast IP address is IPv6 [RFC 2460]. Set
514 to FALSE if the multicast IP address is IPv4 [RFC 791].
515 @param IP The multicast IP address that is to be converted to a multicast
517 @param MAC The multicast HW MAC address that is to be generated from IP.
519 @retval EFI_SUCCESS The multicast IP address was mapped to the multicast
521 @retval EFI_NOT_STARTED The network interface has not been started.
522 @retval EFI_BUFFER_TOO_SMALL The Statistics buffer was too small. The current buffer
523 size needed to hold the statistics is returned in
525 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
526 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
527 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
531 WinNtSnpMCastIpToMac (
532 IN EMU_SNP_PROTOCOL
*This
,
534 IN EFI_IP_ADDRESS
*IP
,
535 OUT EFI_MAC_ADDRESS
*MAC
538 WIN_NT_SNP_PRIVATE
*Private
;
540 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
542 return EFI_UNSUPPORTED
;
546 Performs read and write operations on the NVRAM device attached to a
549 @param This The protocol instance pointer.
550 @param ReadWrite TRUE for read operations, FALSE for write operations.
551 @param Offset Byte offset in the NVRAM device at which to start the read or
552 write operation. This must be a multiple of NvRamAccessSize and
554 @param BufferSize The number of bytes to read or write from the NVRAM device.
555 This must also be a multiple of NvramAccessSize.
556 @param Buffer A pointer to the data buffer.
558 @retval EFI_SUCCESS The NVRAM access was performed.
559 @retval EFI_NOT_STARTED The network interface has not been started.
560 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
561 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
562 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
567 IN EMU_SNP_PROTOCOL
*This
,
568 IN BOOLEAN ReadWrite
,
574 WIN_NT_SNP_PRIVATE
*Private
;
576 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
578 return EFI_UNSUPPORTED
;
582 Reads the current interrupt status and recycled transmit buffer status from
585 @param This The protocol instance pointer.
586 @param InterruptStatus A pointer to the bit mask of the currently active interrupts
587 If this is NULL, the interrupt status will not be read from
588 the device. If this is not NULL, the interrupt status will
589 be read from the device. When the interrupt status is read,
590 it will also be cleared. Clearing the transmit interrupt
591 does not empty the recycled transmit buffer array.
592 @param TxBuf Recycled transmit buffer address. The network interface will
593 not transmit if its internal recycled transmit buffer array
594 is full. Reading the transmit buffer does not clear the
595 transmit interrupt. If this is NULL, then the transmit buffer
596 status will not be read. If there are no transmit buffers to
597 recycle and TxBuf is not NULL, * TxBuf will be set to NULL.
599 @retval EFI_SUCCESS The status of the network interface was retrieved.
600 @retval EFI_NOT_STARTED The network interface has not been started.
601 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
602 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
603 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
608 IN EMU_SNP_PROTOCOL
*This
,
609 OUT UINT32
*InterruptStatus OPTIONAL
,
610 OUT VOID
**TxBuf OPTIONAL
613 WIN_NT_SNP_PRIVATE
*Private
;
615 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
618 if (Private
->Instance
.RecycledTxBufCount
!= 0) {
619 Private
->Instance
.RecycledTxBufCount
--;
620 *((UINT8
**) TxBuf
) = (UINT8
*) (UINTN
)Private
->Instance
.RecycledTxBuf
[Private
->Instance
.RecycledTxBufCount
];
622 *((UINT8
**) TxBuf
) = NULL
;
626 if (InterruptStatus
!= NULL
) {
627 *InterruptStatus
= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT
;
634 Places a packet in the transmit queue of a network interface.
636 @param This The protocol instance pointer.
637 @param HeaderSize The size, in bytes, of the media header to be filled in by
638 the Transmit() function. If HeaderSize is non-zero, then it
639 must be equal to This->Mode->MediaHeaderSize and the DestAddr
640 and Protocol parameters must not be NULL.
641 @param BufferSize The size, in bytes, of the entire packet (media header and
642 data) to be transmitted through the network interface.
643 @param Buffer A pointer to the packet (media header followed by data) to be
644 transmitted. This parameter cannot be NULL. If HeaderSize is zero,
645 then the media header in Buffer must already be filled in by the
646 caller. If HeaderSize is non-zero, then the media header will be
647 filled in by the Transmit() function.
648 @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this parameter
649 is ignored. If HeaderSize is non-zero and SrcAddr is NULL, then
650 This->Mode->CurrentAddress is used for the source HW MAC address.
651 @param DestAddr The destination HW MAC address. If HeaderSize is zero, then this
652 parameter is ignored.
653 @param Protocol The type of header to build. If HeaderSize is zero, then this
654 parameter is ignored. See RFC 1700, section "Ether Types", for
657 @retval EFI_SUCCESS The packet was placed on the transmit queue.
658 @retval EFI_NOT_STARTED The network interface has not been started.
659 @retval EFI_NOT_READY The network interface is too busy to accept this transmit request.
660 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
661 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
662 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
663 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
668 IN EMU_SNP_PROTOCOL
*This
,
672 IN EFI_MAC_ADDRESS
*SrcAddr OPTIONAL
,
673 IN EFI_MAC_ADDRESS
*DestAddr OPTIONAL
,
674 IN UINT16
*Protocol OPTIONAL
677 WIN_NT_SNP_PRIVATE
*Private
;
681 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
683 if ((HeaderSize
!= 0) && (SrcAddr
== NULL
)) {
684 SrcAddr
= &Private
->Instance
.Mode
.CurrentAddress
;
687 ReturnValue
= Private
->NtNetUtilityTable
.Transmit (
688 Private
->Instance
.InterfaceInfo
.InterfaceIndex
,
697 if (ReturnValue
< 0) {
698 return EFI_DEVICE_ERROR
;
700 if ((Private
->Instance
.MaxRecycledTxBuf
+ SNP_TX_BUFFER_INCREASEMENT
) >= SNP_MAX_TX_BUFFER_NUM
) {
701 return EFI_NOT_READY
;
704 if (Private
->Instance
.RecycledTxBufCount
< Private
->Instance
.MaxRecycledTxBuf
) {
705 Private
->Instance
.RecycledTxBuf
[Private
->Instance
.RecycledTxBufCount
] = (UINT64
) Buffer
;
706 Private
->Instance
.RecycledTxBufCount
++;
708 Tmp
= malloc (sizeof (UINT64
) * (Private
->Instance
.MaxRecycledTxBuf
+ SNP_TX_BUFFER_INCREASEMENT
));
710 return EFI_DEVICE_ERROR
;
712 CopyMem (Tmp
, Private
->Instance
.RecycledTxBuf
, sizeof (UINT64
) * Private
->Instance
.RecycledTxBufCount
);
713 free (Private
->Instance
.RecycledTxBuf
);
714 Private
->Instance
.RecycledTxBuf
= Tmp
;
715 Private
->Instance
.MaxRecycledTxBuf
+= SNP_TX_BUFFER_INCREASEMENT
;
723 Receives a packet from a network interface.
725 @param This The protocol instance pointer.
726 @param HeaderSize The size, in bytes, of the media header received on the network
727 interface. If this parameter is NULL, then the media header size
728 will not be returned.
729 @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in
730 bytes, of the packet that was received on the network interface.
731 @param Buffer A pointer to the data buffer to receive both the media header and
733 @param SrcAddr The source HW MAC address. If this parameter is NULL, the
734 HW MAC source address will not be extracted from the media
736 @param DestAddr The destination HW MAC address. If this parameter is NULL,
737 the HW MAC destination address will not be extracted from the
739 @param Protocol The media header type. If this parameter is NULL, then the
740 protocol will not be extracted from the media header. See
741 RFC 1700 section "Ether Types" for examples.
743 @retval EFI_SUCCESS The received data was stored in Buffer, and BufferSize has
744 been updated to the number of bytes received.
745 @retval EFI_NOT_STARTED The network interface has not been started.
746 @retval EFI_NOT_READY The network interface is too busy to accept this transmit
748 @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.
749 @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported value.
750 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
751 @retval EFI_UNSUPPORTED This function is not supported by the network interface.
756 IN EMU_SNP_PROTOCOL
*This
,
757 OUT UINTN
*HeaderSize OPTIONAL
,
758 IN OUT UINTN
*BufferSize
,
760 OUT EFI_MAC_ADDRESS
*SrcAddr OPTIONAL
,
761 OUT EFI_MAC_ADDRESS
*DestAddr OPTIONAL
,
762 OUT UINT16
*Protocol OPTIONAL
765 WIN_NT_SNP_PRIVATE
*Private
;
769 Private
= WIN_NT_SNP_PRIVATE_DATA_FROM_THIS (This
);
771 BufSize
= *BufferSize
;
773 ASSERT (Private
->NtNetUtilityTable
.Receive
!= NULL
);
775 ReturnValue
= Private
->NtNetUtilityTable
.Receive (
776 Private
->Instance
.InterfaceInfo
.InterfaceIndex
,
781 if (ReturnValue
< 0) {
782 if (ReturnValue
== -100) {
783 return EFI_BUFFER_TOO_SMALL
;
786 return EFI_DEVICE_ERROR
;
787 } else if (ReturnValue
== 0) {
788 return EFI_NOT_READY
;
791 if (HeaderSize
!= NULL
) {
795 if (SrcAddr
!= NULL
) {
796 ZeroMem (SrcAddr
, sizeof (EFI_MAC_ADDRESS
));
797 CopyMem (SrcAddr
, ((UINT8
*) Buffer
) + 6, 6);
800 if (DestAddr
!= NULL
) {
801 ZeroMem (DestAddr
, sizeof (EFI_MAC_ADDRESS
));
802 CopyMem (DestAddr
, ((UINT8
*) Buffer
), 6);
805 if (Protocol
!= NULL
) {
806 *Protocol
= NTOHS (*((UINT16
*) (((UINT8
*) Buffer
) + 12)));
809 return (*BufferSize
<= BufSize
) ? EFI_SUCCESS
: EFI_BUFFER_TOO_SMALL
;
813 Initialize the snpnt32 driver instance.
815 @param Instance Pointer to the instance context data.
816 @param NetInfo Pointer to the interface info.
818 @retval EFI_SUCCESS The driver instance is initialized.
819 @retval other Initialization errors.
823 WinNtInitializeInstanceData (
824 IN OUT WIN_NT_INSTANCE_DATA
*Instance
,
825 IN NT_NET_INTERFACE_INFO
*NetInfo
828 if (Instance
== NULL
|| NetInfo
== NULL
) {
829 return EFI_INVALID_PARAMETER
;
832 ZeroMem (Instance
, sizeof (WIN_NT_INSTANCE_DATA
));
834 Instance
->Signature
= WIN_NT_INSTANCE_SIGNATURE
;
835 Instance
->RecycledTxBufCount
= 0;
836 Instance
->MaxRecycledTxBuf
= 32;
837 Instance
->Mode
.State
= EfiSimpleNetworkInitialized
;
838 Instance
->Mode
.HwAddressSize
= NET_ETHER_ADDR_LEN
;
839 Instance
->Mode
.MediaHeaderSize
= NET_ETHER_HEADER_SIZE
;
840 Instance
->Mode
.MaxPacketSize
= 1500;
841 Instance
->Mode
.MaxMCastFilterCount
= MAX_MCAST_FILTER_CNT
;
842 Instance
->Mode
.IfType
= NET_IFTYPE_ETHERNET
;
843 Instance
->Mode
.MediaPresentSupported
= TRUE
;
844 Instance
->Mode
.MediaPresent
= TRUE
;
847 // Allocate the RecycledTxBuf.
849 Instance
->RecycledTxBuf
= malloc (sizeof (UINT64
) * Instance
->MaxRecycledTxBuf
);
850 if (Instance
->RecycledTxBuf
== NULL
) {
851 return EFI_OUT_OF_RESOURCES
;
855 // Set the interface information.
857 CopyMem (&Instance
->InterfaceInfo
, NetInfo
, sizeof (Instance
->InterfaceInfo
));
861 // Set broadcast address
863 SetMem (&Instance
->Mode
.BroadcastAddress
, sizeof (EFI_MAC_ADDRESS
), 0xFF);
866 // Copy Current/PermanentAddress MAC address
868 CopyMem (&Instance
->Mode
.CurrentAddress
, &Instance
->InterfaceInfo
.MacAddr
, sizeof(Instance
->Mode
.CurrentAddress
));
869 CopyMem (&Instance
->Mode
.PermanentAddress
, &Instance
->InterfaceInfo
.MacAddr
, sizeof(Instance
->Mode
.PermanentAddress
));
872 // Since the fake SNP is based on a real NIC, to avoid conflict with the host
873 // NIC network stack, we use a different MAC address.
874 // So just change the last byte of the MAC address for the real NIC.
876 Instance
->Mode
.CurrentAddress
.Addr
[NET_ETHER_ADDR_LEN
- 1]++;
882 Initialize the net utility data.
884 @param This Pointer to the private data.
885 @param ActiveInstance The active network interface.
887 @retval EFI_SUCCESS The global data is initialized.
888 @retval EFI_NOT_FOUND The required DLL is not found.
889 @retval EFI_DEVICE_ERROR Error initialize network utility library.
890 @retval other Other errors.
894 WintNtInitializeNetUtilityData (
895 IN OUT WIN_NT_SNP_PRIVATE
*Private
,
896 IN UINT8 ActiveInstance
900 CHAR16
*DllFileNameU
;
902 BOOLEAN NetUtilityLibInitDone
;
903 NT_NET_INTERFACE_INFO NetInterfaceInfoBuffer
[MAX_INTERFACE_INFO_NUMBER
];
904 UINT32 InterfaceCount
;
905 UINT8 ActiveInterfaceIndex
;
907 if (Private
== NULL
) {
908 return EFI_INVALID_PARAMETER
;
911 NetUtilityLibInitDone
= FALSE
;
912 InterfaceCount
= MAX_INTERFACE_INFO_NUMBER
;
913 DllFileNameU
= NETWORK_LIBRARY_NAME_U
;
916 // Load network utility library
918 Private
->NetworkLibraryHandle
= LoadLibraryEx (DllFileNameU
, NULL
, 0);
919 if (NULL
== Private
->NetworkLibraryHandle
) {
920 return EFI_NOT_FOUND
;
923 Private
->NtNetUtilityTable
.Initialize
= (NT_NET_INITIALIZE
) GetProcAddress (Private
->NetworkLibraryHandle
, NETWORK_LIBRARY_INITIALIZE
);
924 if (NULL
== Private
->NtNetUtilityTable
.Initialize
) {
925 Status
= EFI_NOT_FOUND
;
929 Private
->NtNetUtilityTable
.Finalize
= (NT_NET_FINALIZE
) GetProcAddress (Private
->NetworkLibraryHandle
, NETWORK_LIBRARY_FINALIZE
);
930 if (NULL
== Private
->NtNetUtilityTable
.Finalize
) {
931 Status
= EFI_NOT_FOUND
;
935 Private
->NtNetUtilityTable
.SetReceiveFilter
= (NT_NET_SET_RECEIVE_FILTER
) GetProcAddress (Private
->NetworkLibraryHandle
, NETWORK_LIBRARY_SET_RCV_FILTER
);
936 if (NULL
== Private
->NtNetUtilityTable
.SetReceiveFilter
) {
937 Status
= EFI_NOT_FOUND
;
941 Private
->NtNetUtilityTable
.Receive
= (NT_NET_RECEIVE
) GetProcAddress (Private
->NetworkLibraryHandle
, NETWORK_LIBRARY_RECEIVE
);
942 if (NULL
== Private
->NtNetUtilityTable
.Receive
) {
943 Status
= EFI_NOT_FOUND
;
947 Private
->NtNetUtilityTable
.Transmit
= (NT_NET_TRANSMIT
) GetProcAddress (Private
->NetworkLibraryHandle
, NETWORK_LIBRARY_TRANSMIT
);
948 if (NULL
== Private
->NtNetUtilityTable
.Transmit
) {
949 Status
= EFI_NOT_FOUND
;
954 // Initialize the network utility library
955 // And enumerate the interfaces in emulator host
957 ReturnValue
= Private
->NtNetUtilityTable
.Initialize (&InterfaceCount
, &NetInterfaceInfoBuffer
[0]);
958 if (ReturnValue
<= 0) {
959 Status
= EFI_DEVICE_ERROR
;
963 NetUtilityLibInitDone
= TRUE
;
965 if (InterfaceCount
== 0) {
966 Status
= EFI_NOT_FOUND
;
970 DEBUG ((DEBUG_INFO
, "%a, total %d interface(s) found\n", __FUNCTION__
, InterfaceCount
));
972 // Active interface index is set to first interface if given instance does
975 ActiveInterfaceIndex
= (ActiveInstance
>= InterfaceCount
? DEFAULT_SELECTED_NIC_INDEX
: ActiveInstance
);
978 // Initialize instance
980 Status
= WinNtInitializeInstanceData (&Private
->Instance
, &NetInterfaceInfoBuffer
[ActiveInterfaceIndex
]);
981 if (EFI_ERROR (Status
)) {
989 if (Private
->Instance
.RecycledTxBuf
!= NULL
) {
990 free (Private
->Instance
.RecycledTxBuf
);
993 if (NetUtilityLibInitDone
) {
994 if (Private
->NtNetUtilityTable
.Finalize
!= NULL
) {
995 Private
->NtNetUtilityTable
.Finalize ();
996 Private
->NtNetUtilityTable
.Finalize
= NULL
;
1004 Release the net utility data.
1006 @param This Pointer to the private data.
1008 @retval EFI_SUCCESS The global data is released.
1009 @retval other Other errors.
1013 WintNtReleaseNetUtilityData (
1014 IN OUT WIN_NT_SNP_PRIVATE
*Private
1017 if (Private
== NULL
) {
1018 return EFI_INVALID_PARAMETER
;
1021 if (Private
->Instance
.RecycledTxBuf
!= NULL
) {
1022 free (Private
->Instance
.RecycledTxBuf
);
1025 if (Private
->NtNetUtilityTable
.Finalize
!= NULL
) {
1026 Private
->NtNetUtilityTable
.Finalize ();
1029 FreeLibrary (Private
->NetworkLibraryHandle
);
1034 EMU_SNP_PROTOCOL mWinNtSnpProtocol
= {
1035 WinNtSnpCreateMapping
,
1041 WinNtSnpReceiveFilters
,
1042 WinNtSnpStationAddress
,
1044 WinNtSnpMCastIpToMac
,
1052 Open SNP thunk protocol.
1054 @param This Pointer to the thunk protocol instance.
1056 @retval EFI_SUCCESS SNP thunk protocol is opened successfully.
1057 @retval EFI_UNSUPPORTED This is not SNP thunk protocol.
1058 @retval EFI_OUT_OF_RESOURCES Not enough memory.
1059 @retval other Other errors.
1064 IN EMU_IO_THUNK_PROTOCOL
*This
1067 WIN_NT_SNP_PRIVATE
*Private
;
1068 UINT8 HostInterfaceIndex
;
1070 HostInterfaceIndex
= 0;
1072 if (This
->Private
!= NULL
) {
1073 return EFI_ALREADY_STARTED
;
1076 if (!CompareGuid (This
->Protocol
, &gEmuSnpProtocolGuid
)) {
1077 return EFI_UNSUPPORTED
;
1080 Private
= malloc (sizeof (WIN_NT_SNP_PRIVATE
));
1081 if (Private
== NULL
) {
1082 return EFI_OUT_OF_RESOURCES
;
1085 Private
->Signature
= WIN_NT_SIMPLE_NETWORK_PRIVATE_SIGNATURE
;
1086 Private
->Thunk
= This
;
1087 CopyMem (&Private
->EmuSnp
, &mWinNtSnpProtocol
, sizeof (mWinNtSnpProtocol
));
1089 This
->Interface
= &Private
->EmuSnp
;
1090 This
->Private
= Private
;
1092 if (This
->ConfigString
!= NULL
&& This
->ConfigString
[0] != '\0') {
1093 HostInterfaceIndex
= (UINT8
)StrDecimalToUintn (This
->ConfigString
);
1096 return WintNtInitializeNetUtilityData (Private
, HostInterfaceIndex
);
1100 Close SNP thunk protocol.
1102 @param This Pointer to the thunk protocol instance.
1104 @retval EFI_SUCCESS SNP thunk protocol is closed successfully.
1105 @retval EFI_UNSUPPORTED This is not SNP thunk protocol.
1106 @retval other Other errors.
1110 WinNtSnpThunkClose (
1111 IN EMU_IO_THUNK_PROTOCOL
*This
1114 WIN_NT_SNP_PRIVATE
*Private
;
1116 if (!CompareGuid (This
->Protocol
, &gEmuSnpProtocolGuid
)) {
1117 return EFI_UNSUPPORTED
;
1120 Private
= This
->Private
;
1121 WintNtReleaseNetUtilityData (Private
);
1127 EMU_IO_THUNK_PROTOCOL mWinNtSnpThunkIo
= {
1128 &gEmuSnpProtocolGuid
,