📄 rndismin.c
字号:
return NDIS_STATUS_SUCCESS;
break;
case OID_GEN_CURRENT_PACKET_FILTER:
*pulBytesRead = ulInformationBufferLength;
*pulBytesNeeded = 0;
if (ulInformationBufferLength != 4 )
return NDIS_STATUS_INVALID_LENGTH;
memcpy (&dwFilter, pvInformationBuffer, 4);
// Reject types we don't support..
if (dwFilter &
(NDIS_PACKET_TYPE_SOURCE_ROUTING |
NDIS_PACKET_TYPE_SMT |
NDIS_PACKET_TYPE_MAC_FRAME |
NDIS_PACKET_TYPE_FUNCTIONAL |
NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
NDIS_PACKET_TYPE_GROUP))
{
return NDIS_STATUS_NOT_SUPPORTED;
}
USBDBGMSG(USBDBG_ZONE_INFO, (
L"RNdis:: New filter set: [0x%x] --> [0x%x]\r\n",
m_rndisDev.dwCurrentPacketFilter, dwFilter
));
// Hence we support:
// DIRECTED, MULTICAST, ALL_MULTICAST, BROADCAST,
// Set the new value on the adapter..
m_rndisDev.dwCurrentPacketFilter = dwFilter;
if (dwFilter)
m_rndisDev.state = RNDIS_INITIALIZED;
else
m_rndisDev.state = RNDIS_DATA_INITIALIZED;
return NDIS_STATUS_SUCCESS;
break;
case OID_GEN_CURRENT_LOOKAHEAD:
// No need to record requested lookahead length since we
// always indicate the whole packet.
*pulBytesRead = 4;
return NDIS_STATUS_SUCCESS;
break;
default:
*pulBytesRead = 0;
*pulBytesNeeded = 0;
return NDIS_STATUS_INVALID_OID;
}
}
//------------------------------------------------------------------------------
// Prepare a rndis packet for transmission
//
static
BOOL
PrepareRndisPacket(
PBYTE pbData,
UINT32 cbData
)
{
UINT32 outPktLen;
UINT32 tmp;
PRNDIS_PACKET pRndisPacket;
outPktLen = RNDIS_MESSAGE_SIZE (RNDIS_PACKET) + cbData;
if (outPktLen < cbData) //overflow
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"RNdis:: ERROR! Outgoing pkt is too big, bailing out!\r\n"
));
return FALSE;
}
tmp = outPktLen;
// Pad it to multiple of 8 bytes (required by RNDIS host).
outPktLen += (8 - (outPktLen % 8));
if ((outPktLen > sizeof(m_outgoingPkt)) || (outPktLen < tmp))
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"RNdis:: Outgoing pkt is bigger than buffer size, bailing out!\r\n"
));
return FALSE;
}
// Fill up the RNDIS_PACKET header
//
m_outgoingPkt.rndisMsg.NdisMessageType = REMOTE_NDIS_PACKET_MSG;
m_outgoingPkt.rndisMsg.MessageLength = outPktLen;
pRndisPacket = &(m_outgoingPkt.rndisMsg.Message.Packet);
pRndisPacket->DataOffset = sizeof(RNDIS_PACKET);
pRndisPacket->DataLength = cbData;
pRndisPacket->OOBDataOffset = 0x00;
pRndisPacket->OOBDataLength = 0x00;
pRndisPacket->NumOOBDataElements = 0x00;
pRndisPacket->PerPacketInfoOffset = 0x00;
pRndisPacket->PerPacketInfoLength = 0x00;
pRndisPacket->VcHandle = 0x00;
pRndisPacket->Reserved = 0x00;
//copy the data to outgoing packet buffer
memcpy(pRndisPacket+1,pbData,cbData);
return TRUE;
}
//------------------------------------------------------------------------------
// Send the Rndis message to host (as opposed to a data packet)
//
static
void
SendRndisMessage(
DWORD dwRndisMessageType,
DWORD dwRequestId,
NDIS_STATUS NdisStatus,
PUCHAR pucInBuffer,
DWORD dwBufferLength,
DWORD dwUnspecified1
)
{
UINT32 uiMessageSize;
switch (dwRndisMessageType)
{
case REMOTE_NDIS_INITIALIZE_CMPLT:
{
PRNDIS_INITIALIZE_COMPLETE pInitComplete;
uiMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_INITIALIZE_COMPLETE);
m_outgoingMsg.rndisMsg.NdisMessageType = REMOTE_NDIS_INITIALIZE_CMPLT;
m_outgoingMsg.rndisMsg.MessageLength = uiMessageSize;
pInitComplete = &(m_outgoingMsg.rndisMsg.Message.InitializeComplete);
pInitComplete->RequestId = dwRequestId;
pInitComplete->Status = NdisStatus;
pInitComplete->MajorVersion = SUPPORTED_RNDIS_MAJOR_VER;
pInitComplete->MinorVersion = SUPPORTED_RNDIS_MINOR_VER;
pInitComplete->DeviceFlags = RNDIS_DF_CONNECTIONLESS;
pInitComplete->Medium = 0x00;
pInitComplete->MaxPacketsPerMessage = RNDIS_MAX_PACKETS_PER_MESSAGE;
pInitComplete->AFListOffset = 0x00;
pInitComplete->AFListSize = 0x00;
pInitComplete->MaxTransferSize = RNDIS_MAX_TRANSFER_SIZE;
// 8 byte alignment, to cater for non x86 devices..
pInitComplete->PacketAlignmentFactor = 0x03;
break;
}
case REMOTE_NDIS_QUERY_CMPLT:
{
PRNDIS_QUERY_COMPLETE pQueryComplete;
PUCHAR pucBuffer;
UINT uiRndisQuerySize;
uiRndisQuerySize = RNDIS_MESSAGE_SIZE(RNDIS_QUERY_COMPLETE);
uiMessageSize = uiRndisQuerySize + dwBufferLength;
if (uiMessageSize > sizeof(m_outgoingMsg))
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"RNdis:: SendRndisMessage: REMOTE_NDIS_QUERY_CMPLT: "
L"Message too big for statically allocated space.\r\n"
));
break;
}
pucBuffer = (PUCHAR)(&m_outgoingMsg.rndisMsg) + uiRndisQuerySize;
// Have the buffer will fill now..
//
m_outgoingMsg.rndisMsg.NdisMessageType = dwRndisMessageType;
m_outgoingMsg.rndisMsg.MessageLength = uiMessageSize;
pQueryComplete = &(m_outgoingMsg.rndisMsg.Message.QueryComplete);
pQueryComplete->RequestId = dwRequestId;
pQueryComplete->Status = NdisStatus;
pQueryComplete->InformationBufferLength = dwUnspecified1;
pQueryComplete->InformationBufferOffset = (dwBufferLength == 0) ?
(0) :
(pucBuffer - (PUCHAR)pQueryComplete);
if (dwBufferLength)
memcpy(pucBuffer, pucInBuffer, dwUnspecified1);
break;
}
// Both messages have same entries..
// They are only interested in NdisStatus..
//
case REMOTE_NDIS_KEEPALIVE_CMPLT:
case REMOTE_NDIS_SET_CMPLT:
{
PRNDIS_KEEPALIVE_COMPLETE pKeepAliveOrSetComplete;
uiMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_KEEPALIVE_COMPLETE);
if (uiMessageSize > sizeof(m_outgoingMsg))
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"RNdis:: SendRndisMessage: REMOTE_NDIS_SET_CMPLT: Message "
L"too big for statically allocated space.\r\n"
));
break;
}
m_outgoingMsg.rndisMsg.NdisMessageType = dwRndisMessageType;
m_outgoingMsg.rndisMsg.MessageLength = uiMessageSize;
pKeepAliveOrSetComplete = &(m_outgoingMsg.rndisMsg.Message.KeepaliveComplete);
pKeepAliveOrSetComplete->RequestId = dwRequestId;
pKeepAliveOrSetComplete->Status = NdisStatus;
break;
}
case REMOTE_NDIS_RESET_CMPLT:
{
PRNDIS_RESET_COMPLETE pResetComplete;
uiMessageSize = RNDIS_MESSAGE_SIZE(RNDIS_RESET_COMPLETE);
if (uiMessageSize > sizeof(m_outgoingMsg))
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"RNdis:: SendRndisMessage: REMOTE_NDIS_RESET_CMPLT: "
L"Message too big for statically allocated space.\r\n"
));
break;
}
m_outgoingMsg.rndisMsg.NdisMessageType = dwRndisMessageType;
m_outgoingMsg.rndisMsg.MessageLength = uiMessageSize;
pResetComplete = &(m_outgoingMsg.rndisMsg.Message.ResetComplete);
// Reset is always successful..
// We always require host to return the multicast list etc..
pResetComplete->Status = NDIS_STATUS_SUCCESS;
pResetComplete->AddressingReset = 0x00;
break;
}
default:
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"ERROR: SendRndisMessage:: Incorrect message send "
L"request\r\n"));
return;
}
// Send it out..
// Buffer will return back to us and freed in
// RndisPdd_SendMessageComplete()
USBDBGMSG (USBDBG_ZONE_VERBOSE,
(L"RNdis:: Sending Msg [%s]\r\n",
dwRndisMessageType == REMOTE_NDIS_INITIALIZE_CMPLT ?
L"INIT-CMPLT" :
dwRndisMessageType == REMOTE_NDIS_QUERY_CMPLT ?
L"QUERY-CMPLT":
dwRndisMessageType == REMOTE_NDIS_SET_CMPLT ?
L"SET-CMPLT" :
dwRndisMessageType == REMOTE_NDIS_RESET_CMPLT ?
L"RESET-CMPLT":
dwRndisMessageType == REMOTE_NDIS_KEEPALIVE_CMPLT ?
L"KEEPALIVE-CMPLT" :
L"UNKNOWN!"
));
UsbRndis_SendMessage((PBYTE)&m_outgoingMsg,
m_outgoingMsg.rndisMsg.MessageLength);
}
//------------------------------------------------------------------------------
// Wait for Rndis to Init.
//
static
BOOL
IsRndisInit(
)
{
DWORD retryCnt = 0;
if (m_rndisDev.dwCurrentPacketFilter != 0)
return TRUE;
#define INIT_RETRY_COUNT 5
// call event handler to give an opportunity to initialize
do
{
UsbRndis_EventHandler();
}
while ((m_rndisDev.dwCurrentPacketFilter == 0) &&
(retryCnt++ < INIT_RETRY_COUNT));
// if not initialized return FALSE
if (m_rndisDev.dwCurrentPacketFilter == 0)
{
USBDBGMSG(USBDBG_ZONE_VERBOSE, (
L"INFO: RNdis:: Not initialized. Aborting send/recv frame\r\n"
));
return FALSE;
}
return TRUE;
}
/// Public Functions (interface implementation)
///
///
//---------------------------------------------------------------------------//
/// incoming OAL_KITL_ETH_DRIVER interface
//------------------------------------------------------------------------------
// Description: Signature matches OAL_KITLETH_INIT defined in oal_kitl.h
// Called by KITL or DLE to initialize USB DBG RNDIS.
//
// Returns: TRUE if initialized
// else returns FALSE
//
BOOL
Rndis_Init(
UINT8 *pAddress,
UINT32 offset,
UINT16 mac[3]
)
{
#define INITIALTIME_SEC 300
DWORD dwStartSec;
m_rndisDev.state = RNDIS_UNINITIALIZED;
// copy mac address
//
if ((mac[0] == 0) && (mac[1] == 0) && (mac[2] == 0))
{
USBDBGMSG(USBDBG_ZONE_ERROR, (
L"ERROR: RNdis:: Empty MAC address passed to Rndis_Init\r\n"
));
return FALSE;
}
memcpy(&m_rndisDev.MacAddr, &mac[0], 6);
USBDBGMSG(USBDBG_ZONE_INFO, (
L"RNdis:: Init: MAC address:%x-%x-%x-%x-%x-%x\r\n",
m_rndisDev.MacAddr[0], m_rndisDev.MacAddr[1],
m_rndisDev.MacAddr[2], m_rndisDev.MacAddr[3],
m_rndisDev.MacAddr[4], m_rndisDev.MacAddr[5]
));
// init lower layer - usbrndis
//
UsbRndis_Init(mac);
// For RNDIS packets to flow from host to device, MAC address of the
// the virtual ethernet adapter and device MAC address should be different.
// Change OUI to locally administered address.
m_rndisDev.MacAddr[0] |= 0x02;
USBDBGMSG(USBDBG_ZONE_INFO, (L"UsbDbgRndis:: Waiting to connect ...\r\n"));
// wait for RNDIS init msg from host and filters for INITIALTIME_SEC
//
dwStartSec=OEMKitlGetSecs();
while (OEMKitlGetSecs()-dwStartSec<=INITIALTIME_SEC) {
UsbRndis_EventHandler(); // call message handler
if (m_rndisDev.dwCurrentPacketFilter != 0)
break;
}
// print success/failure message
//
if (m_rndisDev.dwCurrentPacketFilter != 0) {
USBDBGMSG(USBDBG_ZONE_INFO, (L"RNdis:: initialization: Success\r\n"));
return TRUE;
}
else {
USBDBGMSG(USBDBG_ZONE_ERROR, (L"RNdis:: initialization: Fail!\r\n"));
return FALSE;
}
}
void
Rndis_EnableInts(
)
{
//empty
}
void
Rndis_DisableInts(
)
{
//empty
}
void
Rndis_CurrentPktFilter(
UINT32 filter
)
{
//empty
}
//------------------------------------------------------------------------------
// Description: Signature matches OAL_KITLETH_SEND_FRAME defined in oal_kitl.h
// Called by KITL or DLE to send a packet over USB DBG RNDIS.
//
// Returns: ERROR_SUCCESS if no error
// else return error code
//
UINT16
Rndis_SendFrame(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -