示例#1
0
// Verify the ACK message
bool DlipReceiveAck(int fd)
{
	union DL_primitives *dlp;
	struct strbuf ctl;
	int flags = 0;
	char *buf;
	// Validate arguments
	if (fd == -1)
	{
		return false;
	}

	buf = MallocFast(SOLARIS_MAXDLBUF);

	Zero(&ctl, sizeof(ctl));
	ctl.maxlen = SOLARIS_MAXDLBUF;
	ctl.len = 0;
	ctl.buf = buf;

	if (getmsg(fd, &ctl, NULL, &flags) < 0)
	{
		return false;
	}

	dlp = (union DL_primitives *)ctl.buf;
	if (dlp->dl_primitive != (UINT)DL_OK_ACK && dlp->dl_primitive != (UINT)DL_BIND_ACK)
	{
		Free(buf);
		return false;
	}

	Free(buf);

	return true;
}
示例#2
0
// Read the next sent packet from the driver
bool VLanGetNextPacket(VLAN *v, void **buf, UINT *size)
{
	// Validate arguments
	if (v == NULL || buf == NULL || size == NULL)
	{
		return false;
	}
	if (v->Halt)
	{
		return false;
	}

	PROBE_STR("VLanGetNextPacket");

	while (true)
	{
		if (v->CurrentPacketCount < NEO_NUM_PACKET(v->GetBuffer))
		{
			// There are still packets that have been read already
			*size = NEO_SIZE_OF_PACKET(v->GetBuffer, v->CurrentPacketCount);
			*buf = MallocFast(*size);
			Copy(*buf, NEO_ADDR_OF_PACKET(v->GetBuffer, v->CurrentPacketCount), *size);

			// Increment the packet number
			v->CurrentPacketCount++;

			return true;
		}
		else
		{
			// Read the next packet from the driver
			if (VLanGetPacketsFromDriver(v) == false)
			{
				return false;
			}

			if (NEO_NUM_PACKET(v->GetBuffer) == 0)
			{
				// Packet is not received currently
				*buf = NULL;
				*size = 0;
				return true;
			}

			v->CurrentPacketCount = 0;
		}
	}
}
示例#3
0
UINT EthGetPacketSolaris(ETH *e, void **data)
{
	UCHAR tmp[UNIX_ETH_TMP_BUFFER_SIZE];
	struct strbuf buf;
	int s;
	int flags = 0;
	int ret;
	// Validate arguments
	if (e == NULL || data == NULL)
	{
		return INFINITE;
	}

	s = e->Socket;
	if (s == INVALID_SOCKET)
	{
		return INFINITE;
	}

	Zero(&buf, sizeof(buf));
	buf.buf = tmp;
	buf.maxlen = sizeof(tmp);

	ret = getmsg(s, NULL, &buf, &flags);

	if (ret < 0 || ret > sizeof(tmp))
	{
		if (errno == EAGAIN)
		{
			// No packet
			*data = NULL;
			return 0;
		}
		// Error
		*data = NULL;
		return INFINITE;
	}

	ret = buf.len;

	*data = MallocFast(ret);
	Copy(*data, tmp, ret);
	return ret;
}
示例#4
0
UINT EthGetPacketLinux(ETH *e, void **data)
{
	int s, ret;
	UCHAR tmp[UNIX_ETH_TMP_BUFFER_SIZE];
	// Validate arguments
	if (e == NULL || data == NULL)
	{
		return INFINITE;
	}

	if (e->Tap != NULL)
	{
#ifndef	NO_VLAN
		// tap mode
		void *buf;
		UINT size;

		if (VLanGetNextPacket(e->Tap, &buf, &size) == false)
		{
			return INFINITE;
		}

		*data = buf;
		return size;
#else	// NO_VLAN
		return INFINITE;
#endif
	}

	s = e->Socket;

	if (s == INVALID_SOCKET)
	{
		return INFINITE;
	}

	// Read
	ret = read(s, tmp, sizeof(tmp));
	if (ret == 0 || (ret == -1 && errno == EAGAIN))
	{
		// No packet
		*data = NULL;
		return 0;
	}
	else if (ret == -1 || ret > sizeof(tmp))
	{
		// Error
		*data = NULL;
		e->Socket = INVALID_SOCKET;
		return INFINITE;
	}
	else
	{
		// Success to read a packet
		*data = MallocFast(ret);
		Copy(*data, tmp, ret);
		return ret;
	}

	return 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;
}
// 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;
	}
}
示例#7
0
UINT EthGetPacketLinux(ETH *e, void **data)
{
	int s, ret;
	UCHAR tmp[UNIX_ETH_TMP_BUFFER_SIZE];
	// 引数チェック
	if (e == NULL || data == NULL)
	{
		return INFINITE;
	}

	if (e->Tap != NULL)
	{
#ifndef	NO_VLAN
		// tap モード
		void *buf;
		UINT size;

		if (VLanGetNextPacket(e->Tap, &buf, &size) == false)
		{
			return INFINITE;
		}

		*data = buf;
		return size;
#else	// NO_VLAN
		return INFINITE;
#endif
	}

	s = e->Socket;

	if (s == INVALID_SOCKET)
	{
		return INFINITE;
	}

	// 読み込み
	ret = read(s, tmp, sizeof(tmp));
	if (ret == 0 || (ret == -1 && errno == EAGAIN))
	{
		// パケット無し
		*data = NULL;
		return 0;
	}
	else if (ret == -1 || ret > sizeof(tmp))
	{
		// エラー
		*data = NULL;
		e->Socket = INVALID_SOCKET;
		return INFINITE;
	}
	else
	{
		// パケット読み込み成功
		*data = MallocFast(ret);
		Copy(*data, tmp, ret);
		return ret;
	}

	return 0;
}
示例#8
0
UINT EthGetPacketLinux(ETH *e, void **data)
{
	int s, ret;
	UCHAR tmp[UNIX_ETH_TMP_BUFFER_SIZE];
	struct iovec msg_iov;
	struct msghdr msg_header;
	struct cmsghdr *cmsg;
	union
	{
		struct cmsghdr cmsg;
		char buf[CMSG_SPACE(sizeof(struct my_tpacket_auxdata))];
	} cmsg_buf;
	// Validate arguments
	if (e == NULL || data == NULL)
	{
		return INFINITE;
	}

	if (e->Tap != NULL)
	{
#ifndef	NO_VLAN
		// tap mode
		void *buf;
		UINT size;

		if (VLanGetNextPacket(e->Tap, &buf, &size) == false)
		{
			return INFINITE;
		}

		*data = buf;
		return size;
#else	// NO_VLAN
		return INFINITE;
#endif
	}

	s = e->Socket;

	if (s == INVALID_SOCKET)
	{
		return INFINITE;
	}

	// Read
	msg_iov.iov_base = tmp;
	msg_iov.iov_len = sizeof(tmp);

	msg_header.msg_name = NULL;
	msg_header.msg_namelen = 0;
	msg_header.msg_iov = &msg_iov;
	msg_header.msg_iovlen = 1;
	if (e->Linux_IsAuxDataSupported)
	{
		memset(&cmsg_buf, 0, sizeof(cmsg_buf));

		msg_header.msg_control = &cmsg_buf;
		msg_header.msg_controllen = sizeof(cmsg_buf);
	}
	else
	{
		msg_header.msg_control = NULL;
		msg_header.msg_controllen = 0;
	}
	msg_header.msg_flags = 0;

	ret = recvmsg(s, &msg_header, 0);
	if (ret == 0 || (ret == -1 && errno == EAGAIN))
	{
		// No packet
		*data = NULL;
		return 0;
	}
	else if (ret == -1 || ret > sizeof(tmp))
	{
		// Error
		*data = NULL;
		e->Socket = INVALID_SOCKET;
		return INFINITE;
	}
	else
	{
		bool flag = false;
		USHORT api_vlan_id = 0;
		USHORT api_vlan_tpid = 0;

		if (e->Linux_IsAuxDataSupported)
		{
			for (cmsg = CMSG_FIRSTHDR(&msg_header); cmsg; cmsg = CMSG_NXTHDR(&msg_header, cmsg))
			{
				struct my_tpacket_auxdata *aux;
				UINT len;
				USHORT vlan_tpid = 0x8100;
				USHORT vlan_id = 0;

				if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct my_tpacket_auxdata)) ||
					cmsg->cmsg_level != SOL_PACKET ||
					cmsg->cmsg_type != MY_PACKET_AUXDATA)
				{
					continue;
				}

				aux = (struct my_tpacket_auxdata *)CMSG_DATA(cmsg);

				if (aux != NULL)
				{
					if (aux->tp_vlan_tci != 0)
					{
						vlan_id = aux->tp_vlan_tci;
					}
				}

				if (vlan_id != 0)
				{
					api_vlan_id = vlan_id;
					api_vlan_tpid = vlan_tpid;
					break;
				}
			}

			if (api_vlan_id != 0 && api_vlan_tpid != 0)
			{
				// VLAN ID has been received with PACKET_AUXDATA.
				// Insert the tag.
				USHORT vlan_id_ne = Endian16(api_vlan_id);
				USHORT vlan_tpid_ne = Endian16(api_vlan_tpid);

				if (ret >= 14)
				{
					if (*((USHORT *)(tmp + 12)) != vlan_tpid_ne)
					{
						*data = MallocFast(ret + 4);
						Copy(*data, tmp, 12);
						Copy(((UCHAR *)*data) + 12, &vlan_tpid_ne, 2);
						Copy(((UCHAR *)*data) + 14, &vlan_id_ne, 2);
						Copy(((UCHAR *)*data) + 16, tmp + 12, ret - 12);

						flag = true;

						ret += 4;
					}
				}
			}
		}

		// Success to read a packet (No VLAN)
		if (flag == false)
		{
			*data = MallocFast(ret);
			Copy(*data, tmp, ret);
		}
		return ret;
	}

	return 0;
}
示例#9
0
文件: TcpIp.c 项目: falcon8823/utvpn
// パケットヘッダをコピーする
PKT *ClonePacket(PKT *p, bool copy_data)
{
	PKT *ret;
	// 引数チェック
	if (p == NULL)
	{
		return NULL;
	}

	ret = ZeroMallocFast(sizeof(PKT));
	ret->PacketSize = p->PacketSize;

	// MAC ヘッダのコピー
	ret->MacHeader = MallocFast(sizeof(MAC_HEADER));
	Copy(ret->MacHeader, p->MacHeader, sizeof(MAC_HEADER));

	// MAC フラグのコピー
	ret->BroadcastPacket = p->BroadcastPacket;
	ret->InvalidSourcePacket = p->InvalidSourcePacket;

	// IPv6 関係構造体のコピー
	Copy(&ret->IPv6HeaderPacketInfo, &p->IPv6HeaderPacketInfo, sizeof(IPV6_HEADER_PACKET_INFO));
	Copy(&ret->ICMPv6HeaderPacketInfo, &p->ICMPv6HeaderPacketInfo, sizeof(ICMPV6_HEADER_INFO));

	// Layer 3
	ret->TypeL3 = p->TypeL3;
	switch (ret->TypeL3)
	{
	case L3_ARPV4:
		// ARP パケット
		ret->L3.ARPv4Header = MallocFast(sizeof(ARPV4_HEADER));
		Copy(ret->L3.ARPv4Header, p->L3.ARPv4Header, sizeof(ARPV4_HEADER));
		break;

	case L3_IPV4:
		// IPv4 パケット
		ret->L3.IPv4Header = MallocFast(sizeof(IPV4_HEADER));
		Copy(ret->L3.IPv4Header, p->L3.IPv4Header, sizeof(IPV4_HEADER));
		break;

	case L3_IPV6:
		// IPv6 パケット
		ret->L3.IPv6Header = MallocFast(sizeof(IPV6_HEADER));
		Copy(ret->L3.IPv6Header, p->L3.IPv6Header, sizeof(IPV6_HEADER));

		ret->IPv6HeaderPacketInfo.IPv6Header = Clone(p->IPv6HeaderPacketInfo.IPv6Header,
			sizeof(IPV6_HEADER));

		ret->IPv6HeaderPacketInfo.HopHeader = Clone(p->IPv6HeaderPacketInfo.HopHeader,
			sizeof(IPV6_OPTION_HEADER));

		ret->IPv6HeaderPacketInfo.EndPointHeader = Clone(p->IPv6HeaderPacketInfo.EndPointHeader,
			sizeof(IPV6_OPTION_HEADER));

		ret->IPv6HeaderPacketInfo.RoutingHeader = Clone(p->IPv6HeaderPacketInfo.RoutingHeader,
			sizeof(IPV6_OPTION_HEADER));

		ret->IPv6HeaderPacketInfo.FragmentHeader = Clone(p->IPv6HeaderPacketInfo.FragmentHeader,
			sizeof(IPV6_FRAGMENT_HEADER));

		ret->IPv6HeaderPacketInfo.Payload = Clone(p->IPv6HeaderPacketInfo.Payload,
			p->IPv6HeaderPacketInfo.PayloadSize);
		break;
	}

	// Layer 4
	ret->TypeL4 = p->TypeL4;
	switch (ret->TypeL4)
	{
	case L4_ICMPV4:
		// ICMPv4 パケット
		ret->L4.ICMPHeader = MallocFast(sizeof(ICMP_HEADER));
		Copy(ret->L4.ICMPHeader, p->L4.ICMPHeader, sizeof(ICMP_HEADER));
		break;

	case L4_ICMPV6:
		// ICMPv6 パケット
		ret->L4.ICMPHeader = MallocFast(sizeof(ICMP_HEADER));
		Copy(ret->L4.ICMPHeader, p->L4.ICMPHeader, sizeof(ICMP_HEADER));

		ret->ICMPv6HeaderPacketInfo.Data = Clone(p->ICMPv6HeaderPacketInfo.Data,
			p->ICMPv6HeaderPacketInfo.DataSize);

		ret->ICMPv6HeaderPacketInfo.EchoData = Clone(p->ICMPv6HeaderPacketInfo.EchoData,
			p->ICMPv6HeaderPacketInfo.EchoDataSize);

		switch (ret->ICMPv6HeaderPacketInfo.Type)
		{
		case ICMPV6_TYPE_ECHO_REQUEST:
		case ICMPV6_TYPE_ECHO_RESPONSE:
			break;

		case ICMPV6_TYPE_ROUTER_SOLICIATION:
			ret->ICMPv6HeaderPacketInfo.Headers.RouterSoliciationHeader =
				Clone(p->ICMPv6HeaderPacketInfo.Headers.RouterSoliciationHeader,
				sizeof(ICMPV6_ROUTER_SOLICIATION_HEADER));
			break;

		case ICMPV6_TYPE_ROUTER_ADVERTISEMENT:
			ret->ICMPv6HeaderPacketInfo.Headers.RouterAdvertisementHeader =
				Clone(p->ICMPv6HeaderPacketInfo.Headers.RouterAdvertisementHeader,
				sizeof(ICMPV6_ROUTER_ADVERTISEMENT_HEADER));
			break;

		case ICMPV6_TYPE_NEIGHBOR_SOLICIATION:
			ret->ICMPv6HeaderPacketInfo.Headers.NeighborSoliciationHeader =
				Clone(p->ICMPv6HeaderPacketInfo.Headers.NeighborSoliciationHeader,
				sizeof(ICMPV6_NEIGHBOR_SOLICIATION_HEADER));
			break;

		case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
			ret->ICMPv6HeaderPacketInfo.Headers.NeighborAdvertisementHeader =
				Clone(p->ICMPv6HeaderPacketInfo.Headers.NeighborAdvertisementHeader,
				sizeof(ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER));
			break;
		}

		CloneICMPv6Options(&ret->ICMPv6HeaderPacketInfo.OptionList,
			&p->ICMPv6HeaderPacketInfo.OptionList);
		break;

	case L4_TCP:
		// TCP パケット
		ret->L4.TCPHeader = MallocFast(sizeof(TCP_HEADER));
		Copy(ret->L4.TCPHeader, p->L4.TCPHeader, sizeof(TCP_HEADER));
		break;

	case L4_UDP:
		// UDP パケット
		ret->L4.UDPHeader = MallocFast(sizeof(UDP_HEADER));
		Copy(ret->L4.UDPHeader, p->L4.UDPHeader, sizeof(UDP_HEADER));
		break;
	}

	// Layer 7
	ret->TypeL7 = p->TypeL7;
	switch (ret->TypeL7)
	{
	case L7_DHCPV4:
		// DHCP パケット
		ret->L7.DHCPv4Header = MallocFast(sizeof(DHCPV4_HEADER));
		Copy(ret->L7.DHCPv4Header, p->L7.DHCPv4Header, sizeof(DHCPV4_HEADER));
		break;
	}

	// アドレスデータ
	ret->MacAddressSrc = ret->MacHeader->SrcAddress;
	ret->MacAddressDest = ret->MacHeader->DestAddress;

	if (copy_data)
	{
		// パケット本体もコピー
		ret->PacketData = MallocFast(p->PacketSize);
		Copy(ret->PacketData, p->PacketData, p->PacketSize);
	}

	return ret;
}