⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmini.c

📁 三星2410的BSP开发包
💻 C
📖 第 1 页 / 共 4 页
字号:
                    

NextLoop:
            //
            //  Return the buffer to kernel.
            //			

			if (bConvert)
				BufferAddress |= 0x20000000;

            KernelIoControl(
                IOCTL_VBRIDGE_GET_RX_PACKET_COMPLETE,
                (LPVOID)BufferAddress,
                sizeof(DWORD),
                NULL,
                0x00,
                &dwReturnedBytes);

        }	//	while()


		//
		//	Time to quit..
		//

		if (VMini.vm_bHalt)
		{
			DEBUGMSG (ZONE_WARNING,
				(TEXT("VMini:: RX Thread quiting..\r\n")));

			return;
		}
    
	}	//	while (1)

}   //  VirtMiniISR()



////////////////////////////////////////////////////////////////////////////////
//	GetXBytesOffsetYBytes()
//
//	Routine description:
//
//		Given an NDIS packet, get the first X bytes after offset Y bytes.
//		If the X Bytes are all in one NdisBuffer then that's fine.
//		otherwise copy that into the given buffer.
//
//	Arguments:
//
//		ppbData			::	[i/o] If all X Bytes are in one buffer, ppbData will 
//							point to this buffer on return or otherwise it will
//							point to the pTransitBuffer..
//
//		pTransitBuffer	::	If X bytes spans across NdisBuffer, then copy them
//							to this given buffer.	
//							** Caller ** must allocate the buffer.
//
//		uiXBytes		::	X number of bytes required.
//
//		uiYBytes		::	Y number of bytes offset from the very beginning..
//
//		pPacket			::	The NDIS_PACKET
//
//	return values:
//
//		FALSE			::	Unable to get the required bytes.
//
//		TRUE			::	The required info is either pointed to by ppbData or 
//							copied to pTransitBuffer.
//

BOOL
GetXBytesOffsetYBytes(
	BYTE			**ppbData,
	BYTE			*pTransitBuffer,
	UINT			uiXBytes,
	UINT			uiYBytes,
	PNDIS_PACKET	pPacket)
{
	UINT			NdisBufferCount;
	PNDIS_BUFFER	CurrentNdisBuffer;
	UINT			TotalPacketLength;
	UINT			CurrentBufferLength = 0x00;
	PVOID			VirtualAddress		= 0x00;
	UINT			TotalCopiedLength	= 0x00;
	UINT			TotalParsedLength	= 0x00;
	BOOL			bStarted			= FALSE;

	
	NdisRecalculatePacketCounts(pPacket);

	NdisQueryPacket(
		pPacket,
		NULL,
		&NdisBufferCount,
		&CurrentNdisBuffer,
		&TotalPacketLength
		);

	DEBUGMSG (0, (TEXT("GetFirstXBytes: Packet Length = %d\r\n"), 
		TotalPacketLength));
	

	if (TotalPacketLength < uiXBytes)
	{
		//
		//	Impossible to get, total length is less than X bytes.
		//

		*ppbData = NULL;
		return FALSE;
	}


	//
	//	Now, loop through the Total buffer count, and break out once our goal
	//	has been achieved.
	//

	while (NdisBufferCount--)
	{
		NdisQueryBuffer(
			CurrentNdisBuffer,
			&VirtualAddress,
			&CurrentBufferLength
			);

		NdisGetNextBuffer(
			CurrentNdisBuffer,
			&CurrentNdisBuffer);
		
		if (!bStarted)
		{
			if ((TotalParsedLength + CurrentBufferLength) >=  uiYBytes)
			{
				bStarted = TRUE;

				if ((TotalParsedLength + CurrentBufferLength) >= (uiYBytes + uiXBytes))
				{
					//
					//	All data available in one buffer, simply point the 
					//	ppbData to this VA, and our job is done!
					//

					*ppbData = ((PBYTE) VirtualAddress) + 
							   (uiYBytes - TotalParsedLength);

					return TRUE;
				}
				else
				{
					//
					//	Now, the X bytes we want span across different 
					//	NDIS_BUFFER, start copying from this buffer onwards.
					//

					if (pTransitBuffer == NULL)
						return FALSE;

					*ppbData = pTransitBuffer;

					memcpy(
						pTransitBuffer + TotalCopiedLength,
						(PBYTE)VirtualAddress + (uiYBytes - TotalParsedLength),
						CurrentBufferLength - (uiYBytes - TotalParsedLength));

					TotalCopiedLength += 
						(CurrentBufferLength - (uiYBytes - TotalParsedLength));
				}
			}

			TotalParsedLength += CurrentBufferLength;
		}
		else
		{	
			//
			//	By the time we get here, it will always be a straight copy.
			//	
			
			if ((CurrentBufferLength + TotalCopiedLength) > uiXBytes)
			{
				memcpy(
					pTransitBuffer + TotalCopiedLength,
					VirtualAddress,
					uiXBytes - TotalCopiedLength);

				return TRUE;
			}

			//
			//	If we get here, it means we need more buffer!!
			//

			memcpy(
				pTransitBuffer + TotalCopiedLength,
				VirtualAddress,
				CurrentBufferLength);

			TotalCopiedLength += CurrentBufferLength;
		}

	}	//	while()	


	//
	//	We should never get here.
	//	If we do it means that total number of bytes in the packet is less
	//	than what we expect.
	//

	DEBUGMSG (1, 
		(TEXT("VMini:: GetX... Not enough! Need:[%d] - Copied So Far:[%d]\r\n"),
		uiXBytes,
		TotalCopiedLength));

	return FALSE;


}	//	GetXBytesOffsetYBytes()



////////////////////////////////////////////////////////////////////////////////
//	IsDhcpRelease()
//
//	Routine description:
//
//		This function determines whether a given NDIS_PACKET is dhcp release
//		packet. 
//
//	Arguments:
//
//		pPacket		::	The NDIS_PACKET
//
//	return values:
//
//		FALSE		::	Not DHCP release packet.
//
//		TRUE		::	Oh ya...
//

BOOL
IsDhcpRelease(PNDIS_PACKET	pPacket)
{	
	#define MIN_ETYPE				0x0600		//	Minimum valid Ethertype
	#define	IP_TYPE					0x0800		//	IP frame.
	#define	PROTOCOL_UDP			0x11
	#define DHCP_SERVER_PORT		0x0043
	#define DHCP_CLIENT_PORT		0x0044
	#define DHCP_MSG_TYPE_OP		53
	#define DHCPDISCOVER			1
	#define DHCPOFFER				2	
	#define DHCPREQUEST				3
	#define DHCPDECLINE				4
	#define DHCPACK					5
	#define DHCPNACK				6
	#define DHCPRELEASE				7
	#define DHCPINFORM				8

	#define	DHCP_MINUS_OPTION_SIZE	(sizeof(DHCP_PACKET) - OPTIONS_LEN)

	#define	MIN_LENGTH				sizeof(ENetHeaderFormat)	+	\
									sizeof(IPHeaderFormat)		+	\
									sizeof(UDPHeaderFormat)		+	\
									DHCP_MINUS_OPTION_SIZE
									


	UCHAR				ucScrapBuffer[512];
	DWORD				dwOffset;
	DWORD				dwPacketLength;
	USHORT				usEType;
	ENetHeaderFormat	UNALIGNED	*pEnetHeader;
	IPHeaderFormat		UNALIGNED	*pIPHeader;	
	UDPHeaderFormat		UNALIGNED	*pUDPHeader;	
	PUCHAR				pucType, pucTargetEnd;
	DWORD				dwOptionLength;


	//
	//	Quick check that it is DHCP packet..
	//

	NdisQueryPacket(
        pPacket,
        NULL,
        NULL,
        NULL,
        &dwPacketLength);  

	if (dwPacketLength < MIN_LENGTH)
		return FALSE;


	//
	//	Get the ethernet header..
	//

	if (!GetXBytesOffsetYBytes(
			(BYTE **)&pEnetHeader,
			&ucScrapBuffer[0],
			sizeof(ENetHeaderFormat),
			0,			
			pPacket))
	{
		//
		//	Can't even get ethernet header... Should never happen..
		//	Well, just pass it..
		//

		return FALSE;
	}
	
	usEType = net_short(pEnetHeader->eh_type);


	//
	//	Bail if not IP packet..
	//

	if (usEType != IP_TYPE)
		return FALSE;

	
	//
	//	Get the IP header..
	//

	if (usEType < MIN_ETYPE)
		dwOffset = sizeof(SNAPHeaderFormat);
	else
		dwOffset = sizeof(ENetHeaderFormat);


	if (!GetXBytesOffsetYBytes(
			(BYTE **)&pIPHeader,
			&ucScrapBuffer[0],
			sizeof(IPHeaderFormat),
			dwOffset,			
			pPacket))
	{
		//
		//	Should never happen..   Well, just pass it..
		//

		return FALSE;
	}


	//
	//	Bail if not UDP
	//

	if (pIPHeader->bProtocol != PROTOCOL_UDP)
		return FALSE;


	//
	//	Get the UDP header..
	//

	dwOffset += (pIPHeader->bVersionLength & 0x0f) * 4;

	if (!GetXBytesOffsetYBytes(
			(BYTE **)&pUDPHeader,
			&ucScrapBuffer[0],
			sizeof(UDPHeaderFormat),
			dwOffset,			
			pPacket))
	{
		//
		//	Should never happen..   Well, just pass it..
		//

		return FALSE;
	}

	
	//
	//	If destination is DHCP server port then it can potentially
	//	be DHCP Release..
	//

	if (net_short(pUDPHeader->wDestPort) != DHCP_SERVER_PORT)	
		return FALSE;

	
	//
	//	Definitely DHCP packet, bypass all of it and get the option
	//	field..
	//
	
	dwOffset		+= sizeof(UDPHeaderFormat) + DHCP_MINUS_OPTION_SIZE;		

	dwOptionLength  =  dwPacketLength - dwOffset;	

	if (!GetXBytesOffsetYBytes(
			(BYTE **)&pucType,
			&ucScrapBuffer[0],
			dwOptionLength,
			dwOffset,			
			pPacket))
	{
		//
		//	Should not happen..  
		//
		
		ASSERT(0);

		return FALSE;
	}

	pucTargetEnd = pucType + dwOptionLength;

	//
	//	Skip the magic cookie..
	//

	pucType += 4;	

	//
	//	Okay, parse the option field looking for DHCPRELEASE
	//	in DHCP_MSG_TYPE_OP type.
	//	
	

	while (pucType < pucTargetEnd)
	{
		if (*pucType == DHCP_MSG_TYPE_OP)
		{		
			DEBUGMSG (1, (TEXT("VMini:: Detected DHCP [%s]\r\n"),
				(pucType[2] == DHCPDISCOVER) ? TEXT("DISCOVER") :
				(pucType[2] == DHCPOFFER)	 ? TEXT("OFFER") :
				(pucType[2] == DHCPREQUEST)	 ? TEXT("REQUEST") :
				(pucType[2] == DHCPDECLINE)  ? TEXT("DECLINE") :
				(pucType[2] == DHCPACK)		 ? TEXT("ACK") :
				(pucType[2] == DHCPNACK)	 ? TEXT("NACK") :
				(pucType[2] == DHCPRELEASE)	 ? TEXT("RELEASE") :
				(pucType[2] == DHCPINFORM)	 ? TEXT("INFORM") :
				TEXT("UNKNOWN!")));

			if (pucType[2] == DHCPRELEASE)
			{
				RETAILMSG (1, 
					(TEXT("VMini:: is doing the right thing, block DHCP_RELEASE..\r\n")));
				return TRUE;
			}
			else
				return FALSE;
		}


		//
		//	Next type please...
		//	Type is followed by length (1 byte), add two
		//	for the type and the length fields..
		//

		pucType += pucType[1] + 2;		
	}

	return FALSE;

}	//	IsDhcpRelease()



////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//  Start of all the normal MiniportXXX functions. 
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////
//	VMiniInitialize()
//
//	Routine description:
//
//		Called by NDIS after we call: NdisMRegisterMiniport().	
//
//	Arguments:
//
//		Look at MSDN MiniportInitialize() description.
//
//	return values:
//	
//		NDIS_STATUS_XXX
//

NDIS_STATUS
VMiniMInitialize(
    OUT PNDIS_STATUS    OpenErrorStatus,
    OUT PUINT           SelectedMediumIndex,
    IN  PNDIS_MEDIUM    MediumArray,
    IN  UINT            MediumArraySize,
    IN  NDIS_HANDLE     VMiniportHandle,
    IN  NDIS_HANDLE     ConfigurationHandle
    )
{   
    DWORD			dwReturnedBytes;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -