コード例 #1
0
ファイル: VLanWin32.c プロジェクト: RexSi/SoftEtherVPN
// Write the next received packet to the driver
bool VLanPutPacket(VLAN *v, void *buf, UINT size)
{
	// Validate arguments
	if (v == NULL)
	{
		return false;
	}
	if (v->Halt)
	{
		return false;
	}
	if (size > MAX_PACKET_SIZE)
	{
		return false;
	}

	// First, examine whether the current buffer is full
	if ((NEO_NUM_PACKET(v->PutBuffer) >= NEO_MAX_PACKET_EXCHANGE) ||
		(buf == NULL && NEO_NUM_PACKET(v->PutBuffer) != 0))
	{
#ifdef	USE_PROBE
		{
			char tmp[MAX_SIZE];
			snprintf(tmp, sizeof(tmp), "VLanPutPacket: NEO_NUM_PACKET(v->PutBuffer) = %u", NEO_NUM_PACKET(v->PutBuffer));
			PROBE_DATA2(tmp, NULL, 0);
		}
#endif	// USE_PROBE
		// Write a packet to the driver
		if (VLanPutPacketsToDriver(v) == false)
		{
			return false;
		}
		NEO_NUM_PACKET(v->PutBuffer) = 0;
	}

	// Add the next packet to the buffer
	if (buf != NULL)
	{
		UINT i = NEO_NUM_PACKET(v->PutBuffer);
		NEO_NUM_PACKET(v->PutBuffer)++;

		NEO_SIZE_OF_PACKET(v->PutBuffer, i) = size;
		Copy(NEO_ADDR_OF_PACKET(v->PutBuffer, i), buf, size);
		Free(buf);
	}

	return true;
}
コード例 #2
0
// Read next packet
UINT EthGetPacket(ETH *e, void **data)
{
	BLOCK *b;
	bool flag = false;
	// Validate arguments
	if (e == NULL || data == NULL)
	{
		return INFINITE;
	}
	if (e->HasFatalError)
	{
		return INFINITE;
	}

	if (e->SuAdapter != NULL)
	{
		// Read packet with SeLow
		UINT size;
		if (SuGetNextPacket(e->SuAdapter, data, &size) == false)
		{
			// Error occurred
			e->HasFatalError = true;
			return INFINITE;
		}

		return size;
	}

RETRY:
	// Check the presence of the packet in queue
	b = GetNext(e->PacketQueue);
	if (b != NULL)
	{
		UINT size;
		size = b->Size;
		*data = b->Buf;
		Free(b);

		if (e->PacketQueue->num_item == 0)
		{
			e->Empty = true;
		}

		return size;
	}

	if (e->Empty)
	{
		e->Empty = false;
		return 0;
	}

	if (flag == false)
	{
		// Try to get next packet
		PROBE_STR("EthGetPacket: PacketInitPacket");
		wp->PacketInitPacket(e->Packet, e->Buffer, e->BufferSize);
		PROBE_STR("EthGetPacket: PacketReceivePacket");
		if (wp->PacketReceivePacket(e->Adapter, e->Packet, false) == false)
		{
			// Failed
			return INFINITE;
		}
		else
		{
			UCHAR *buf;
			UINT total;
			UINT offset;

			buf = (UCHAR *)e->Packet->Buffer;
			total = e->Packet->ulBytesReceived;
			offset = 0;

			while (offset < total)
			{
				struct bpf_hdr *header;
				UINT packet_size;
				UCHAR *packet_data;

				header = (struct bpf_hdr *)(buf + offset);
				packet_size = header->bh_caplen;
				offset += header->bh_hdrlen;
				packet_data = buf + offset;
				offset = Packet_WORDALIGN(offset + packet_size);

				if (packet_size >= 14)
				{
					UCHAR *tmp;
					BLOCK *b;

					PROBE_DATA2("EthGetPacket: NewBlock", packet_data, packet_size);
					
					tmp = MallocFast(packet_size);

					Copy(tmp, packet_data, packet_size);
					b = NewBlock(tmp, packet_size, 0);
					InsertQueue(e->PacketQueue, b);
				}
			}

			flag = true;
			goto RETRY;
		}
	}

	// No more packet
	return 0;
}
コード例 #3
0
// Send multiple packets
void EthPutPackets(ETH *e, UINT num, void **datas, UINT *sizes)
{
	UINT i, total_size;
	UCHAR *buf;
	UINT write_pointer;
	UINT err = 0;
	// Validate arguments
	if (e == NULL || num == 0 || datas == NULL || sizes == NULL)
	{
		return;
	}
	if (e->HasFatalError)
	{
		return;
	}

	if (e->SuAdapter != NULL)
	{
		bool ok = true;

		// Send packets with SeLow
		for (i = 0;i < num;i++)
		{
			UCHAR *data = datas[i];
			UINT size = sizes[i];

			if (ok)
			{
				// Actually, only enqueuing
				ok = SuPutPacket(e->SuAdapter, data, size);
			}

			if (ok == false)
			{
				// Free memory on write error
				Free(data);
			}
		}

		if (ok)
		{
			// Send all data in queue at once
			ok = SuPutPacket(e->SuAdapter, NULL, 0);
		}

		if (ok == false)
		{
			// Error occurred
			e->HasFatalError = true;
		}

		return;
	}

	if (IsWin32BridgeWithSee() == false)
	{
		if (e->LastSetSingleCpu == 0 || (e->LastSetSingleCpu + 10000) <= Tick64())
		{
			e->LastSetSingleCpu = Tick64();
			MsSetThreadSingleCpu();
		}
	}

	// Calculate buffer size
	total_size = 0;
	for (i = 0;i < num;i++)
	{
		void *data = datas[i];
		UINT size = sizes[i];
		if (data != NULL && size >= 14 && size <= MAX_PACKET_SIZE)
		{
			total_size += size + sizeof(struct dump_bpf_hdr);
		}
	}

	buf = MallocFast(total_size * 100 / 75 + 1600);

	write_pointer = 0;
	// Enqueue
	for (i = 0;i < num;i++)
	{
		void *data = datas[i];
		UINT size = sizes[i];
		if (data != NULL && size >= 14 && size <= MAX_PACKET_SIZE)
		{
			struct dump_bpf_hdr *h;

			h = (struct dump_bpf_hdr *)(buf + write_pointer);
			Zero(h, sizeof(struct dump_bpf_hdr));
			h->caplen = h->len = size;
			write_pointer += sizeof(struct dump_bpf_hdr);
			Copy(buf + write_pointer, data, size);
			write_pointer += size;

			PROBE_DATA2("EthPutPackets", data, size);
		}
		// Free original buffer
		Free(data);
	}

	// Send
	if (total_size != 0)
	{
		err = wp->PacketSendPackets(e->Adapter, buf, total_size, true);
	}

	Free(buf);

	if (err == 0x7FFFFFFF)
	{
		// Critical error (infinite loop) occurred on sending
		e->HasFatalError = true;
	}
}