- STATIC struct bpf_insn FilterInstructionTemplate[] =\r
- {\r
- // Load 4 bytes from the destination MAC address.\r
- BPF_STMT( BPF_LD + BPF_W + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 0 ] ) ),\r
-\r
- // Compare to first 4 bytes of fake MAC address.\r
- BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0x12345678, 0, 3 ),\r
-\r
- // Load remaining 2 bytes from the destination MAC address.\r
- BPF_STMT( BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 4 ] ) ),\r
-\r
- // Compare to remaining 2 bytes of fake MAC address.\r
- BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0x9ABC, 5, 0 ),\r
-\r
- // Load 4 bytes from the destination MAC address.\r
- BPF_STMT( BPF_LD + BPF_W + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 0 ] ) ),\r
-\r
- // Compare to first 4 bytes of broadcast MAC address.\r
- BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0xFFFFFFFF, 0, 2 ),\r
-\r
- // Load remaining 2 bytes from the destination MAC address.\r
- BPF_STMT( BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 4 ] ) ),\r
-\r
- // Compare to remaining 2 bytes of broadcast MAC address.\r
- BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0xFFFF, 1, 0 ),\r
-\r
- // Reject packet.\r
- BPF_STMT( BPF_RET + BPF_K, 0 ),\r
-\r
- // Receive entire packet.\r
- BPF_STMT( BPF_RET + BPF_K, -1 )\r
- };\r
- struct ifreq BoundIf;\r
- struct bpf_program BpfProgram;\r
- struct bpf_insn* FilterProgram;\r
- UNIX_SNP_PRIVATE_DATA* Private;\r
- EFI_STATUS Status;\r
- UINT32 Temp32;\r
- INTN Fd;\r
- INTN Result;\r
- INTN Value;\r
- UINT16 Temp16;\r
-\r
- Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
-\r
- switch ( Private->Snp.Mode->State )\r
- {\r
- case EfiSimpleNetworkStopped:\r
- break;\r
-\r
- case EfiSimpleNetworkStarted:\r
- case EfiSimpleNetworkInitialized:\r
- return( EFI_ALREADY_STARTED );\r
- break;\r
-\r
- default:\r
- return( EFI_DEVICE_ERROR );\r
- break;\r
- }\r
-\r
- if ( Private->BpfFd == 0 )\r
- {\r
- Status = OpenBpfFileDescriptor( Private, &Fd );\r
-\r
- if ( EFI_ERROR( Status ) )\r
- {\r
- goto ErrorExit;\r
- }\r
-\r
- Private->BpfFd = Fd;\r
-\r
- //\r
- // Associate our interface with this BPF file descriptor.\r
- //\r
- AsciiStrCpy( BoundIf.ifr_name, Private->InterfaceName );\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSETIF, &BoundIf );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- //\r
- // Enable immediate mode and find out the buffer size.\r
- //\r
- Value = 1;\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCIMMEDIATE, &Value );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- //\r
- // Enable non-blocking I/O.\r
- //\r
-\r
- Value = Private->UnixThunk->Fcntl( Private->BpfFd, F_GETFL, 0 );\r
-\r
- if ( Value == -1 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- Value |= O_NONBLOCK;\r
-\r
- Result = Private->UnixThunk->Fcntl( Private->BpfFd, F_SETFL, (void *) Value );\r
-\r
- if ( Result == -1 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- //\r
- // Disable "header complete" flag. This means the supplied source MAC address is\r
- // what goes on the wire.\r
- //\r
- Value = 1;\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSHDRCMPLT, &Value );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCGBLEN, &Value );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- //\r
- // Allocate read buffer.\r
- //\r
- Private->ReadBufferSize = Value;\r
- Private->ReadBuffer = AllocateZeroPool( Private->ReadBufferSize );\r
- if ( Private->ReadBuffer == NULL )\r
- {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ErrorExit;\r
- }\r
-\r
- Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer;\r
-\r
- //\r
- // Install our packet filter: successful reads should only produce broadcast or unitcast\r
- // packets directed to our fake MAC address.\r
- //\r
- FilterProgram = AllocateCopyPool( sizeof( FilterInstructionTemplate ), &FilterInstructionTemplate );\r
- if ( FilterProgram == NULL )\r
- {\r
- goto ErrorExit;\r
- }\r
-\r
- //\r
- // Insert out fake MAC address into the filter. The data has to be host endian.\r
- //\r
- CopyMem( &Temp32, &Private->Mode.CurrentAddress.Addr[ 0 ], sizeof( UINT32 ) );\r
- FilterProgram[ 1 ].k = NTOHL( Temp32 );\r
- CopyMem( &Temp16, &Private->Mode.CurrentAddress.Addr[ 4 ], sizeof( UINT16 ) );\r
- FilterProgram[ 3 ].k = NTOHS( Temp16 );\r
-\r
- BpfProgram.bf_len = sizeof( FilterInstructionTemplate ) / sizeof( struct bpf_insn );\r
- BpfProgram.bf_insns = FilterProgram;\r
-\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSETF, &BpfProgram );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
-\r
- FreePool( FilterProgram );\r
-\r
- //\r
- // Enable promiscuous mode.\r
- //\r
-\r
- Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCPROMISC, 0 );\r
-\r
- if ( Result < 0 )\r
- {\r
- goto DeviceErrorExit;\r
- }\r
+ STATIC struct bpf_insn FilterInstructionTemplate[] =\r
+ {\r
+ // Load 4 bytes from the destination MAC address.\r
+ BPF_STMT( BPF_LD + BPF_W + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 0 ] ) ),\r
+\r
+ // Compare to first 4 bytes of fake MAC address.\r
+ BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0x12345678, 0, 3 ),\r
+\r
+ // Load remaining 2 bytes from the destination MAC address.\r
+ BPF_STMT( BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 4 ] ) ),\r
+\r
+ // Compare to remaining 2 bytes of fake MAC address.\r
+ BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0x9ABC, 5, 0 ),\r
+\r
+ // Load 4 bytes from the destination MAC address.\r
+ BPF_STMT( BPF_LD + BPF_W + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 0 ] ) ),\r
+\r
+ // Compare to first 4 bytes of broadcast MAC address.\r
+ BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0xFFFFFFFF, 0, 2 ),\r
+\r
+ // Load remaining 2 bytes from the destination MAC address.\r
+ BPF_STMT( BPF_LD + BPF_H + BPF_ABS, OFFSET_OF( EthernetHeader, DstAddr[ 4 ] ) ),\r
+\r
+ // Compare to remaining 2 bytes of broadcast MAC address.\r
+ BPF_JUMP( BPF_JMP + BPF_JEQ + BPF_K, 0xFFFF, 1, 0 ),\r
+\r
+ // Reject packet.\r
+ BPF_STMT( BPF_RET + BPF_K, 0 ),\r
+\r
+ // Receive entire packet.\r
+ BPF_STMT( BPF_RET + BPF_K, -1 )\r
+ };\r
+ struct ifreq BoundIf;\r
+ struct bpf_program BpfProgram;\r
+ struct bpf_insn* FilterProgram;\r
+ UNIX_SNP_PRIVATE_DATA* Private;\r
+ EFI_STATUS Status;\r
+ UINT32 Temp32;\r
+ INTN Fd;\r
+ INTN Result;\r
+ INTN Value;\r
+ UINT16 Temp16;\r
+\r
+ Private = UNIX_SNP_PRIVATE_DATA_FROM_SNP_THIS( This );\r
+\r
+ switch ( Private->Snp.Mode->State )\r
+ {\r
+ case EfiSimpleNetworkStopped:\r
+ break;\r
+\r
+ case EfiSimpleNetworkStarted:\r
+ case EfiSimpleNetworkInitialized:\r
+ return( EFI_ALREADY_STARTED );\r
+ break;\r
+\r
+ default:\r
+ return( EFI_DEVICE_ERROR );\r
+ break;\r
+ }\r
+\r
+ if ( Private->BpfFd == 0 )\r
+ {\r
+ Status = OpenBpfFileDescriptor( Private, &Fd );\r
+\r
+ if ( EFI_ERROR( Status ) )\r
+ {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ Private->BpfFd = Fd;\r
+\r
+ //\r
+ // Associate our interface with this BPF file descriptor.\r
+ //\r
+ AsciiStrCpy( BoundIf.ifr_name, Private->InterfaceName );\r
+ Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSETIF, &BoundIf );\r
+\r
+ if ( Result < 0 )\r
+ {\r
+ goto DeviceErrorExit;\r
+ }\r
+\r
+ //\r
+ // Enable immediate mode and find out the buffer size.\r
+ //\r
+ Value = 1;\r
+ Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCIMMEDIATE, &Value );\r
+\r
+ if ( Result < 0 )\r
+ {\r
+ goto DeviceErrorExit;\r
+ }\r
+\r
+ //\r
+ // Enable non-blocking I/O.\r
+ //\r
+\r
+ Value = Private->UnixThunk->Fcntl( Private->BpfFd, F_GETFL, 0 );\r
+\r
+ if ( Value == -1 )\r
+ {\r
+ goto DeviceErrorExit;\r
+ }\r
+\r
+ Value |= O_NONBLOCK;\r
+\r
+ Result = Private->UnixThunk->Fcntl( Private->BpfFd, F_SETFL, (void *) Value );\r
+\r
+ if ( Result == -1 )\r
+ {\r
+ goto DeviceErrorExit;\r
+ }\r
+\r
+ //\r
+ // Disable "header complete" flag. This means the supplied source MAC address is\r
+ // what goes on the wire.\r
+ //\r
+ Value = 1;\r
+ Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSHDRCMPLT, &Value );\r
+\r
+ if ( Result < 0 )\r
+ {\r
+ goto DeviceErrorExit;\r
+ }\r
+\r
+ Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCGBLEN, &Value );\r
+\r
+ if ( Result < 0 )\r
+ {\r
+ goto DeviceErrorExit;\r
+ }\r
+\r
+ //\r
+ // Allocate read buffer.\r
+ //\r
+ Private->ReadBufferSize = Value;\r
+ Private->ReadBuffer = AllocateZeroPool( Private->ReadBufferSize );\r
+ if ( Private->ReadBuffer == NULL )\r
+ {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ErrorExit;\r
+ }\r
+\r
+ Private->CurrentReadPointer = Private->EndReadPointer = Private->ReadBuffer;\r
+\r
+ //\r
+ // Install our packet filter: successful reads should only produce broadcast or unitcast\r
+ // packets directed to our fake MAC address.\r
+ //\r
+ FilterProgram = AllocateCopyPool( sizeof( FilterInstructionTemplate ), &FilterInstructionTemplate );\r
+ if ( FilterProgram == NULL )\r
+ {\r
+ goto ErrorExit;\r
+ }\r
+\r
+ //\r
+ // Insert out fake MAC address into the filter. The data has to be host endian.\r
+ //\r
+ CopyMem( &Temp32, &Private->Mode.CurrentAddress.Addr[ 0 ], sizeof( UINT32 ) );\r
+ FilterProgram[ 1 ].k = NTOHL( Temp32 );\r
+ CopyMem( &Temp16, &Private->Mode.CurrentAddress.Addr[ 4 ], sizeof( UINT16 ) );\r
+ FilterProgram[ 3 ].k = NTOHS( Temp16 );\r
+\r
+ BpfProgram.bf_len = sizeof( FilterInstructionTemplate ) / sizeof( struct bpf_insn );\r
+ BpfProgram.bf_insns = FilterProgram;\r
+\r
+ Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCSETF, &BpfProgram );\r
+\r
+ if ( Result < 0 )\r
+ {\r
+ goto DeviceErrorExit;\r
+ }\r
+\r
+ FreePool( FilterProgram );\r
+\r
+ //\r
+ // Enable promiscuous mode.\r
+ //\r
+\r
+ Result = Private->UnixThunk->IoCtl( Private->BpfFd, BIOCPROMISC, 0 );\r
+\r
+ if ( Result < 0 )\r
+ {\r
+ goto DeviceErrorExit;\r
+ }\r