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

📄 vpnmac.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	NDIS_STATUS status;
	PBINDING_CONTEXT	binding;
	PVPN_ADAPTER		adapter;

	DBG_ENTER();

	binding = (PBINDING_CONTEXT) Context;
	adapter = binding->adapter;

	if (!adapter->open)
	{
		status = NDIS_STATUS_CLOSING;
		DBG_LEAVE(status);

		return status;

	}

    switch (NdisRequest->RequestType) {

    case NdisRequestSetInformation:
#if DBG_MESSAGE
		DBG_PRINT(("NdisRequestSetInformation: %s\n", GetOidString(NdisRequest->DATA.SET_INFORMATION.Oid)););
#endif
        status = PgpMacSetInformation(
                    binding,
                    NdisRequest,
                    NdisRequest->DATA.SET_INFORMATION.Oid,
                    NdisRequest->DATA.SET_INFORMATION.InformationBuffer);
        break;

    case NdisRequestQueryInformation:
#if DBG_MESSAGE
		DBG_PRINT(("NdisRequestQueryInformation: %s\n", GetOidString(NdisRequest->DATA.QUERY_INFORMATION.Oid)););
#endif
        status = PgpMacQueryInformation(
                    binding,
                    NdisRequest,
                    NdisRequest->DATA.QUERY_INFORMATION.Oid,
                    NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
                    NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
                    &(NdisRequest->DATA.QUERY_INFORMATION.BytesWritten),
                    &(NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded));

        break;

    default:
        status = NDIS_STATUS_NOT_SUPPORTED;
        break;
    }

	DBG_LEAVE(status);

	return status;
}

NDIS_STATUS MacSend(
    IN NDIS_HANDLE Context,
    IN PNDIS_PACKET Packet
    )
{
	DBG_FUNC("MacSend")

	NDIS_STATUS		status;
	PBINDING_CONTEXT binding;
	PVPN_ADAPTER	adapter;
	PNDIS_BUFFER	src_buffer;
	UINT			src_len;
	PNDIS_BUFFER	working_buffer;
	PVOID			working_block;
	UINT			working_block_len;

	PETHERNET_HEADER	eth_header;
	USHORT				eth_protocol;

	USHORT				eth_header_len;

	PIP_HEADER			ip_header;

	PUDP_HEADER			udp_header = 0; /* EML 05/04/99 */

	PPGPNDIS_PACKET		pgpPacket;
	PPGPNDIS_PACKET_HEAD	packetHead;
	BOOLEAN					newHead = FALSE;

	PGPnetPMStatus		pmstatus;

	BOOLEAN				assembleComplete = FALSE;

	DBG_ENTER();

	binding = (PBINDING_CONTEXT)Context;
	adapter = binding->adapter;

	/*
	 *	Check the Packet with the policy manager. Need some design work to be
	 *	done.
	 */

	NdisQueryPacket(Packet, NULL, NULL, &src_buffer, &src_len);
	NdisQueryBuffer(src_buffer, &working_block, &working_block_len);

	/*
	 *	An outgoing src packet would go through up to 4 stages in this stage before it is eventually 
	 *	sent out.
	 */

	/*
	 *	Stage 1. Get the ethernet header. Determines if this is an ip packet. If not bail out early,
	 *	otherwise go to stage 2.
	 */
	eth_header   = (PETHERNET_HEADER) working_block;
	eth_protocol = *((PUSHORT)(&eth_header->eth_protocolType[0]));
	eth_header_len = sizeof(ETHERNET_HEADER);
	if (eth_protocol != IPPROT_NET)
	{
		if (eth_protocol == ARPPROT_NET && adapter->media != NdisMediumWan)
		{
			GetIPAddressFromARP(adapter, (PVOID)((UCHAR*)eth_header + eth_header_len));
		}
		goto bailout;
	}

	if (BroadcastEthernetAddress(eth_header->eth_dstAddress))
		goto bailout;

	if (adapter->media != NdisMedium802_3 && adapter->media != NdisMediumWan)
	{
		status = NDIS_STATUS_NOT_ACCEPTED;
		goto failout;
	}

	/*
	 *	Stage 2 Get the ip header.
	 */
	
	if (working_block_len >= eth_header_len + sizeof(IP_HEADER))
	{
		ip_header = (PIP_HEADER) ( (PCHAR)working_block + eth_header_len);
		working_block = (PCHAR)working_block + eth_header_len;
		working_block_len -= eth_header_len;
	}
	else if (working_block_len == eth_header_len)
	{

		NdisGetNextBuffer(src_buffer, &working_buffer);
		if (working_buffer == NULL)
		{
			status = NDIS_STATUS_NOT_ACCEPTED;
			goto failout;
		}
		NdisQueryBuffer(working_buffer, &working_block, &working_block_len);

		ip_header = (PIP_HEADER)working_block;
	}
	else
	{
		status = NDIS_STATUS_NOT_ACCEPTED;
		goto failout;
	}

	/*
	 *	For Win98 WAN only
	 */
#ifdef CHICAGO
	if (!adapter->WanIPAddressDetected)
	{
		adapter->ip_address = ip_header->ip_src;
		adapter->WanIPAddressDetected = TRUE;
		PGPnetRASconnect(adapter, adapter->ip_address);
	}
#endif

	/*
	 *	Stage 3 Policy on IGMP, ICMP to be determined.
	 */

	if (ip_header->ip_prot == PROTOCOL_IGMP)
		goto bailout;


	/*
	 *	Stage 4. If it's UDP, Get the UDP header.
	 *	Determine if this is a UDP 500 packet. If it is, bail out.
	 */

	if (ip_header->ip_prot == PROTOCOL_UDP)
	{
		if( working_block_len <= sizeof(struct tag_IP_HEADER) )		// FIX!!! ONLY work for ordinary ipv4 header.
		{
			NdisGetNextBuffer(working_buffer, &working_buffer);
			if (working_buffer == NULL)
			{
				status = NDIS_STATUS_NOT_ACCEPTED;
				goto failout;
			}
			NdisQueryBuffer(working_buffer, &working_block, &working_block_len);
			udp_header = (PUDP_HEADER)working_block;
		}
		else
			udp_header = (PUDP_HEADER)( (UCHAR*)working_block + sizeof(IP_HEADER));
	}

#if 0

		if (PGPnetPMIKEPassthrough(PGPnetDriver.PolicyManagerHandle,
			ip_header->ip_dest,
			udp_header->dest_port))

//		if (udp_header->dest_port == UDP_PORT_IKE_NET)
		{
			goto bailout;
		}
		else if (ip_header->ip_foff != 0)
		{
			goto bailout;

		}

	}
#endif

	/*
	 *	Now we have an normal ip packet, ask the policy manager for more directions.
	 */

	if (ip_header->ip_foff)
		pmstatus = PGPnetPMNeedTransformLight(PGPnetDriver.PolicyManagerHandle,
			ip_header->ip_dest,
			FALSE,
			adapter);
	else
		pmstatus = PGPnetPMNeedTransform(PGPnetDriver.PolicyManagerHandle,
			ip_header->ip_dest,
			(PGPUInt16)(udp_header ? udp_header->dest_port : 0), /* EML 05/04/99 */
			FALSE,
			0,
			0,
			adapter);

	if ( kPGPNetPMPacketSent == pmstatus)
		goto dropout;
	if ( kPGPNetPMPacketWaiting == pmstatus)
		goto dropout;
	if ( kPGPNetPMPacketDrop == pmstatus)
		goto dropout;
	if ( kPGPNetPMPacketClear == pmstatus)
		goto bailout;
	if ( kPGPNetPMPacketEncrypt != pmstatus)
	{
		status = NDIS_STATUS_FAILURE;
		goto failout;
	}

	// Now we have a packet to be secured.

	// Allocate the pgpPakcet

	pgpPacket = PGPNdisPacketAllocWithXformPacket(&status, adapter);

	if (status != NDIS_STATUS_SUCCESS)
		goto failout;

	pgpPacket->Binding = binding;
	pgpPacket->srcPacket = Packet;

	PGPCopyPacketToBlock(pgpPacket->srcPacket, pgpPacket->srcBlock, &pgpPacket->srcBlockLen);

	pgpPacket->ipAddress = ntohl(ip_header->ip_dest);

	/* Start EML 05/04/99 */
	pgpPacket->port = udp_header ? udp_header->dest_port : 0;
	/* End ELM */

	pgpPacket->offset = ntohs(ip_header->ip_foff & IP_OFFSET) << 3;
	if (pgpPacket->offset == 0)
		pgpPacket->firstSrcBlock = TRUE;
	// Check to see if it's in the outgoing fragment list.
	packetHead = PacketHeadListQuery(adapter,
				&adapter->outgoing_packet_head_list,
				ip_header->ip_id,
				pgpPacket->ipAddress);
	// If there is no outgoing fragment list. Create one.
	if (packetHead == NULL)
	{
		packetHead = PGPNdisPacketHeadAlloc(&status, adapter);
		newHead = TRUE;
	}

	if (status != NDIS_STATUS_SUCCESS)
		goto failout;

	// Add timestamp, update head information.
	if (packetHead->id == 0)
	{
		// Initialize packetHead
		packetHead->ipAddress = pgpPacket->ipAddress;
		packetHead->id = ip_header->ip_id;
		packetHead->timeStamp = PgpKernelGetSystemTime();
	}

	if (packetHead->numFragments ==0)
		packetHead->accumulatedLength = htons(ip_header->ip_len);
	else
		packetHead->accumulatedLength += htons(ip_header->ip_len) - IP_HEADER_SIZE;
	packetHead->numFragments++;
	
	if (IP_LAST_FRAGMENT(ip_header->ip_foff))
	{
		ASSERT(packetHead->totalLength == 0);
		pgpPacket->lastSrcBlock = TRUE;
		packetHead->totalLength = htons(ip_header->ip_len) + pgpPacket->offset;
	}

	// Insert this pgpPacket to the packet list 
	InsertPGPNdisPacket(adapter, packetHead, pgpPacket);
	
	// Check status, if finished fire up the send sequence.

	if ((packetHead->totalLength) && (packetHead->totalLength == packetHead->accumulatedLength))
	{
		// Have them all, send them all.
		PGPnetPMStatus pm_status;
		PPGPNDIS_PACKET extraPacket;

		// Put an extra buffer there.
		extraPacket = PGPNdisPacketAllocWithXformPacket(&status, adapter);

		AppendPGPNdisPacket(adapter, packetHead, extraPacket);

		if ( !(packetHead->link)->lastSrcBlock )
		{
			// More fragment. Adjust packet length.
			PIP_HEADER first_ip_hdr;
			PUCHAR		first_srcBlock;


			first_srcBlock = (packetHead->link)->srcBlock;
			first_ip_hdr = (PIP_HEADER)(first_srcBlock + ETHER_HEADER_SIZE);

			first_ip_hdr->ip_len = htons(packetHead->totalLength);

		}

		pm_status = PGPnetPMDoTransform(PGPnetDriver.PolicyManagerHandle,
							packetHead->link,
							FALSE,
							adapter);

		if (pm_status != kPGPNetPMPacketSent)
		{
			DBG_PRINT(("!!!!! Yellow Alert! PGPnetPMDoTransform Error!\n"););
			//PGPNdisPacketFree(adapter, pgpPacket);
			PGPNdisPacketHeadFreeList(adapter, packetHead, TRUE);
			PacketHeadListRemove(adapter, &adapter->outgoing_packet_head_list, packetHead);
			PGPNdisPacketHeadFree(adapter, packetHead);

			goto dropout;
		}

		status = MacSendPackets(adapter, packetHead);		

		assembleComplete = TRUE;

	}
	else
	{
		// Not finished, add to the outgoing list
		if (newHead)
			PacketHeadEnqueue(adapter, &adapter->outgoing_packet_head_list, packetHead);

	}
	
	goto dropout;
	// Either way, return successful.
	DBG_LEAVE(status);
	return status;

	


bailout:

	pgpPacket = PGPNdisPacketAllocWithBindingContext(&status, adapter);

	if (status != NDIS_STATUS_SUCCESS)
		goto failout;

	pgpPacket->srcPacket = Packet;
	pgpPacket->Binding = binding;

	PacketEnqueue(adapter, &adapter->sent_plainpacket_list, pgpPacket);

	NdisSend(&status,
				adapter->NdisBindingHandleToRealMac,
				Packet);

	if (status != NDIS_STATUS_PENDING)
	{
		pgpPacket = PacketRemoveBySrcPacket(adapter, &adapter->sent_plainpacket_list, Packet);
		PGPNdisPacketFreeWithBindingContext(adapter, pgpPacket);
	}

	adapter->SendPackets++;

failout:

	DBG_LEAVE(status);
	return status;

dropout:
	if (assembleComplete == FALSE)
		status = NDIS_STATUS_SUCCESS;
	DBG_LEAVE(status);
	return status;
}

NDIS_STATUS MacTransferData(
    IN NDIS_HANDLE MacBindingHandle,
    IN NDIS_HANDLE MacReceiveContext,
    IN UINT ByteOffset,              
    IN UINT BytesToTransfer,         
    OUT PNDIS_PACKET Packet,         

⌨️ 快捷键说明

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