📄 vbridge.c
字号:
*pbTaken = TRUE;
return pBuffer;
}
if (ETH_IS_BROADCAST(pBuffer))
bBroadcast = TRUE;
pEnetHeader = (ENetHeaderFormat UNALIGNED *)pBuffer;
if ((usEType = net_short(pEnetHeader->eh_type)) < MIN_ETYPE)
pIPHeader = (IPHeaderFormat UNALIGNED *) (pBuffer + sizeof(SNAPHeaderFormat));
else
pIPHeader = (IPHeaderFormat UNALIGNED *) (pBuffer + sizeof(ENetHeaderFormat));
////////////////////////////////////////////////////////////////////////////
// See if it's EDBG or DHCP packet (Dest port = DHCP_CLIENT_PORT)
//
if (usEType == IP_TYPE && pIPHeader->bProtocol == PROTOCOL_UDP)
{
pUDPHeader = (UDPHeaderFormat UNALIGNED *)
(((PBYTE)pIPHeader) + (pIPHeader->bVersionLength & 0x0f) * 4);
pKitlHdr = (KITL_HDR UNALIGNED *)
(((PBYTE)pUDPHeader) + sizeof(UDPHeaderFormat));
if ((((PUCHAR)pKitlHdr + sizeof(KITL_HDR)) <= (pBuffer + uiLength)) &&
(pKitlHdr->Id == KITL_ID))
{
BOOL bIsOurMac;
//
// We want to make sure only the EDBG packet directed to to device
// get passed up..
//
ETH_COMPARE_NETWORK_ADDRESSES_EQ(
pEnetHeader->eh_daddr,
EDBGMacAddress,
&bIsOurMac);
//
// Block EDBG packet that's not ours, allow broadcast edbg pkt..
//
if (!bBroadcast && !bIsOurMac)
{
PRINTMSG (1,
("WARNING! Not our EDBG pkt... Possible filter err!\r\n"));
PRINTMSG (1, ("Rx: [%x%x%x%x%x%x] --> [%x%x%x%x%x%x] [%x%x]\r\n",
pBuffer[6],
pBuffer[7],
pBuffer[8],
pBuffer[9],
pBuffer[10],
pBuffer[11],
pBuffer[0],
pBuffer[1],
pBuffer[2],
pBuffer[3],
pBuffer[4],
pBuffer[5],
pBuffer[12],
pBuffer[13]));
*pbTaken = TRUE;
return pBuffer;
}
else
{
*pbTaken = FALSE;
return pBuffer;
}
}
////////////////////////////////////////////////////////////////////////
// Not EDBG, see if it is packet for DHCP client.
//
if (net_short(pUDPHeader->wDestPort) == DHCP_CLIENT_PORT)
{
PRINTMSG (0, ("DHCP MESSAGE DETECTED..\r\n"));
bDhcp = TRUE;
}
}
//
// We should now have enough information to decide whether or not
// EDBG should have this packet..
//
if (bBroadcast | bDhcp)
*pbTaken = FALSE;
else
*pbTaken = TRUE;
//
// Since we are sharing with edbg, we will always get at least
// broadcast packets. So now make sure that VMINI has set its filter.
//
if (dwCurrentPacketFilter == 0x00)
return pBuffer;
//
// By now, the packet has to be passed up to VMINI.
// There is no further filtering needed here since the h/w should have
// been set to filter correctly.
// First, pop a buffer from kernel's free buffer.
// If none is free, then we simply toss away this packet.
//
pucKernelBuffer = ProduceBuffer (FALSE, uiLength);
if (pucKernelBuffer == NULL)
{
PRINTMSG (0,
("VBridgeKIndicateOneRxBuffer():: no mem!\r\n"));
PRINTMSG (0,
("!"));
return pBuffer;
}
memcpy (pucKernelBuffer, pBuffer, uiLength);
ProduceBufferDone (FALSE, pucKernelBuffer);
PRINTMSG (0,
("Rx [0x%x] [%d] bytes\r\n",
pucKernelBuffer,
uiLength));
//
// Trigger the RX event VMini is waiting for..
//
SetInterruptEvent(SYSINTR_VMINI);
return pBuffer;
} // VBridgeKIndicateOneRxBuffer()
#pragma optimize("",on)
////////////////////////////////////////////////////////////////////////////////
// VBridgeKSetLocalMacAddress()
//
// Routine Description:
//
// Kernel only, used to indicate the MAC address currently used by the EDBG.
//
// Arguments:
//
// pucMacAddress :: The MAC address passed in here.
//
// Return Values:
//
// None.
//
// Mode:
//
// Kernel Mode only.
//
void
VBridgeKSetLocalMacAddress(PUCHAR pucMacAddress)
{
if (pucMacAddress == NULL)
{
PRINTMSG (1,
("VBridgeKSetLocalMacAddress() Err!! Null pucMacAddress.\r\n"));
return;
}
PRINTMSG (1, ("VBridge:: NK add MAC: [%x-%x-%x-%x-%x-%x]\r\n",
pucMacAddress[0],
pucMacAddress[1],
pucMacAddress[2],
pucMacAddress[3],
pucMacAddress[4],
pucMacAddress[5]));
memcpy(
EDBGMacAddress,
pucMacAddress,
0x06);
bValidAddress = TRUE;
} // VBridgeKSetLocalMacAddress()
////////////////////////////////////////////////////////////////////////////////
// VBridgeUGetOneTxBuffer()
//
// Routine Description:
//
// Called by user mode code to obtain a buffer for TX.
//
// Arguments:
//
// ppucBuffer :: If successful, points to the free buffer that VMini
// can use to fill up its TX packet.
// uiSize :: Size of the buffer requested..
//
// Return Values:
//
// TRUE :: If there is free buffer available.
// FALSE :: Otherwise.
//
// Mode:
//
// User Mode only.
//
BOOL
VBridgeUGetOneTxPacket(PUCHAR *ppucBuffer, UINT uiSize)
{
if (ppucBuffer == NULL || uiSize > MAX_8023_PDU)
{
PRINTMSG (1,
("VBridgeUGetOneTxPacket() Err!! [0x%x] [0x%x].\r\n",
ppucBuffer,
uiSize));
return FALSE;
}
*ppucBuffer = ProduceBuffer(TRUE, (DWORD)uiSize);
if (*ppucBuffer == NULL)
{
PRINTMSG (0 , ("@ "));
return FALSE;
}
else
return TRUE;
} // VBridgeUGetOneTxBuffer()
////////////////////////////////////////////////////////////////////////////////
// VBridgeUGetOneTxBufferComplete()
//
// Routine Description:
// This function will complete the user's call to send a packet.
// The user should have called VBridgeUGetOneTxBuffer() and then return
// the filled buffer here, ready to be sent.
// VBridge will then insert the buffer to TX queue for kernel to look at.
//
// Arguments:
// pucBuffer :: Pointer to buffer returned previously by
// VBridgeGetOneTxBuffer().
// uiLength :: Length of the user packet to be sent.
//
// Return Values:
// None.
//
// Mode:
// User Mode only.
//
// Notes:
// It is important that caller makes sure that the
// VBridgeUGetOneTxBufferComplete() is called after each
// VBridgeUGetOneTxBuffer(). And the total number called has to
// match.
//
void
VBridgeUGetOneTxPacketComplete(PUCHAR pucBuffer, UINT uiLength)
{
if (pucBuffer == NULL || uiLength > MAX_8023_PDU)
{
PRINTMSG (1,
("VBridgeUGetOneTxPacketComplete() Err!! [0x%x] [0x%x].\r\n",
pucBuffer,
uiLength));
return;
}
PRINTMSG (0, ("Tx: %x%x%x%x%x%x %x%x%x%x%x%x[%d]\r\n",
pucBuffer[6],
pucBuffer[7],
pucBuffer[8],
pucBuffer[9],
pucBuffer[10],
pucBuffer[11],
pucBuffer[0],
pucBuffer[1],
pucBuffer[2],
pucBuffer[3],
pucBuffer[4],
pucBuffer[5],
uiLength));
RETAILMSG (0, (TEXT("VBridgeUGetOneTxPacketComplete():: Sending to: %x-%x-%x-%x-%x-%x\r\n"),
pucBuffer[0],
pucBuffer[1],
pucBuffer[2],
pucBuffer[3],
pucBuffer[4],
pucBuffer[5]));
#if 0
PRINTMSG (1, ("Tx: Sending: \r\n"));
VBridgeDumpMemory(pucBuffer, uiLength);
#endif
ProduceBufferDone(TRUE, pucBuffer);
} // VBridgeUGetOneTxBufferComplete()
////////////////////////////////////////////////////////////////////////////////
// VBridgeUGetOneRxPacket()
//
// Routine Description:
//
// Called by user mode code to retrieve an RX packet.
//
// Arguments:
//
// pucBuffer :: Pointer to buffer
// uiLength :: Length of the user packet to be sent.
//
// Return Values:
//
// TRUE :: If there is a pending RX packet.
// FALSE :: Otherwise.
//
// Mode:
//
// User Mode only.
//
BOOL
VBridgeUGetOneRxPacket(PUCHAR *ppucBuffer, UINT *puiLength)
{
if (ppucBuffer == NULL || puiLength == NULL)
{
PRINTMSG (1,
("VBridgeUGetOneRxPacket() Err!! [0x%x] [0x%x].\r\n",
ppucBuffer,
puiLength));
return FALSE;
}
*ppucBuffer = ConsumeBuffer(FALSE, puiLength);
if (*ppucBuffer)
{
PRINTMSG (0,
("Rx consuming [0x%x][%d]\r\n",
*ppucBuffer,
*puiLength));
return TRUE;
}
else
{
PRINTMSG (0, ("-"));
return FALSE;
}
} // VBridgeUGetOneRxPacket()
////////////////////////////////////////////////////////////////////////////////
// VBridgeUGetOneRxPacketComplete()
//
// Routine Descriptions:
//
// Called by user mode code to return the buffer retrieved via
// VBridgeUGetOneRxPacket()
//
// Arguments:
//
// pucBuffer :: Pointer to buffer
// uiLength :: Length of the user packet to be sent.
//
// Return Values:
//
// Always TRUE..
//
// Mode:
// User Mode only.
//
// Note:
// It is important that the caller match this call to the
// VBridgeUGetOneRxPacket()
//
BOOL
VBridgeUGetOneRxPacketComplete(PUCHAR pucBuffer)
{
if (pucBuffer == NULL)
{
PRINTMSG (1,
("VBridgeUGetOneRxPacketComplete() NULL pucBuffer"));
return FALSE;
}
ConsumeBufferDone(FALSE, pucBuffer);
PRINTMSG (0,
("Rx consumed [0x%x]r\n",
pucBuffer));
return TRUE;
} // VBridgeUGetOneRxPacketComplete()
////////////////////////////////////////////////////////////////////////////////
// VBridgeUWildCard()
//
// Routine Descriptions:
//
// *** Not Used *** For future expansion..
//
// Arguments:
//
//
// Return Values:
//
// Always TRUE..
//
// Mode:
// User Mode only.
//
//
BOOL
VBridgeUWildCard(
LPVOID lpInBuf,
DWORD nInBufSize,
LPVOID lpOutBuf,
DWORD nOutBufSize,
LPDWORD lpBytesReturned)
{
switch ((DWORD)lpInBuf)
{
case IOCTL_VBRIDGE_WILD_CARD_RESET_BUFFER:
g_bResetBuffer = TRUE;
break;
case IOCTL_VBRIDGE_WILD_CARD_VB_INITIALIZED:
if (nOutBufSize == sizeof(DWORD))
{
PRINTMSG (1, ("VBridge:: VB_INITIALIZED returns [%d]\r\n",
bValidAddress));
*(DWORD *)lpOutBuf = bValidAddress;
if (lpBytesReturned)
*lpBytesReturned = sizeof(DWORD);
}
break;
default:
break;
}
return TRUE;
} // VBridgeUWildCard()
////////////////////////////////////////////////////////////////////////////////
// VBridgeUGetEdbgMac()
//
// Routine Descriptions:
//
// Called by the user mode to get the EDBG mac address (this should be the
// normal case, EDBG and VMini sharing same MAC).
//
// Arguments:
//
// pucMacAddress :: [out] the mac address we have learnt from
// kernel mode code.
//
// Mode:
//
// User Mode only.
//
void
VBridgeUGetEDBGMac(PUCHAR pucMacAddress)
{
if (pucMacAddress == NULL)
{
PRINTMSG (1,
("VBridgeUGetEDBGMac(), ERR! NULL pucMacAddress.\r\n"));
return;
}
memcpy(
pucMacAddress,
EDBGMacAddress,
6);
} // VBridgeUGetEDBGMac()
////////////////////////////////////////////////////////////////////////////////
// VBridgeUCurrentPacketFilter()
//
// Routine Descriptions:
//
// Called by user mode code informing us the current filtering mode
// the hardware is being set to.
//
// Arguments:
//
// pdwFilter :: point to the new filtering mode.
//
// Return Value:
//
// None.
//
//
void
VBridgeUCurrentPacketFilter(PDWORD pdwFilter)
{
if (pdwFilter == NULL)
{
PRINTMSG (1,
("VBridgeUCurrentPacketFilter(), ERR! NULL pdwFilter.\r\n"));
return;
}
PRINTMSG (1, ("VBridge:: Current VMini packet filter = [0x%x]\r\n",
*pdwFilter));
dwCurrentPacketFilter = *pdwFilter;
} // VBridgeUCurrentPacketFilter()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -