Blame winpr/libwinpr/utils/wlog/PacketMessage.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 * WinPR Logger
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 * Copyright 2015 Thincast Technologies GmbH
Packit 1fb8d4
 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include "wlog.h"
Packit 1fb8d4
Packit 1fb8d4
#include "wlog/PacketMessage.h"
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/wtypes.h>
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
#include <winpr/stream.h>
Packit 1fb8d4
Packit 1fb8d4
#include "../../log.h"
Packit 1fb8d4
#define TAG WINPR_TAG("utils.wlog")
Packit 1fb8d4
Packit 1fb8d4
#ifndef _WIN32
Packit 1fb8d4
#include <sys/time.h>
Packit 1fb8d4
#else
Packit 1fb8d4
#include <time.h>
Packit 1fb8d4
#include <sys/timeb.h>
Packit 1fb8d4
#include <winpr/windows.h>
Packit 1fb8d4
Packit 1fb8d4
static int gettimeofday(struct timeval* tp, void* tz)
Packit 1fb8d4
{
Packit 1fb8d4
	struct _timeb timebuffer;
Packit 1fb8d4
	_ftime(&timebuffer);
Packit Service 5a9772
	tp->tv_sec = (long)timebuffer.time;
Packit 1fb8d4
	tp->tv_usec = timebuffer.millitm * 1000;
Packit 1fb8d4
	return 0;
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_Read_Header(wPcap* pcap, wPcapHeader* header)
Packit 1fb8d4
{
Packit Service 5a9772
	if (pcap && pcap->fp && fread((void*)header, sizeof(wPcapHeader), 1, pcap->fp) == 1)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/* currently unused code */
Packit Service 5a9772
#if 0
Packit 1fb8d4
static BOOL Pcap_Read_RecordHeader(wPcap* pcap, wPcapRecordHeader* record)
Packit 1fb8d4
{
Packit 1fb8d4
	if (pcap && pcap->fp && (fread((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp) == 1))
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_Read_Record(wPcap* pcap, wPcapRecord* record)
Packit 1fb8d4
{
Packit 1fb8d4
	if (pcap && pcap->fp)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (!Pcap_Read_RecordHeader(pcap, &record->header))
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		record->length = record->header.incl_len;
Packit 1fb8d4
		record->data = malloc(record->length);
Packit 1fb8d4
		if (!record->data)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		if (fread(record->data, record->length, 1, pcap->fp) != 1)
Packit 1fb8d4
		{
Packit 1fb8d4
			free(record->data);
Packit 1fb8d4
			record->length = 0;
Packit 1fb8d4
			record->data = NULL;
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_Add_Record(wPcap* pcap, void* data, UINT32 length)
Packit 1fb8d4
{
Packit 1fb8d4
	wPcapRecord* record;
Packit 1fb8d4
	struct timeval tp;
Packit 1fb8d4
Packit 1fb8d4
	if (!pcap->tail)
Packit 1fb8d4
	{
Packit 1fb8d4
		pcap->tail = (wPcapRecord*) calloc(1, sizeof(wPcapRecord));
Packit 1fb8d4
		if (!pcap->tail)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		pcap->head = pcap->tail;
Packit 1fb8d4
		pcap->record = pcap->head;
Packit 1fb8d4
		record = pcap->tail;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		record = (wPcapRecord*) calloc(1, sizeof(wPcapRecord));
Packit 1fb8d4
		if (!record)
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
		pcap->tail->next = record;
Packit 1fb8d4
		pcap->tail = record;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (!pcap->record)
Packit 1fb8d4
		pcap->record = record;
Packit 1fb8d4
Packit 1fb8d4
	record->data = data;
Packit 1fb8d4
	record->length = length;
Packit 1fb8d4
	record->header.incl_len = length;
Packit 1fb8d4
	record->header.orig_len = length;
Packit 1fb8d4
	gettimeofday(&tp, 0);
Packit 1fb8d4
	record->header.ts_sec = tp.tv_sec;
Packit 1fb8d4
	record->header.ts_usec = tp.tv_usec;
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_HasNext_Record(wPcap* pcap)
Packit 1fb8d4
{
Packit 1fb8d4
	if (pcap->file_size - (_ftelli64(pcap->fp)) <= 16)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_GetNext_RecordHeader(wPcap* pcap, wPcapRecord* record)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!Pcap_HasNext_Record(pcap) || !Pcap_Read_RecordHeader(pcap, &record->header))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	record->length = record->header.incl_len;
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_GetNext_RecordContent(wPcap* pcap, wPcapRecord* record)
Packit 1fb8d4
{
Packit 1fb8d4
	if (pcap && pcap->fp && fread(record->data, record->length, 1, pcap->fp) == 1)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_GetNext_Record(wPcap* pcap, wPcapRecord* record)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!Pcap_HasNext_Record(pcap))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	return Pcap_Read_Record(pcap, record);
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_Write_Header(wPcap* pcap, wPcapHeader* header)
Packit 1fb8d4
{
Packit Service 5a9772
	if (pcap && pcap->fp && fwrite((void*)header, sizeof(wPcapHeader), 1, pcap->fp) == 1)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_Write_RecordHeader(wPcap* pcap, wPcapRecordHeader* record)
Packit 1fb8d4
{
Packit Service 5a9772
	if (pcap && pcap->fp && fwrite((void*)record, sizeof(wPcapRecordHeader), 1, pcap->fp) == 1)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_Write_RecordContent(wPcap* pcap, wPcapRecord* record)
Packit 1fb8d4
{
Packit 1fb8d4
	if (pcap && pcap->fp && fwrite(record->data, record->length, 1, pcap->fp) == 1)
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL Pcap_Write_Record(wPcap* pcap, wPcapRecord* record)
Packit 1fb8d4
{
Packit Service 5a9772
	return Pcap_Write_RecordHeader(pcap, &record->header) && Pcap_Write_RecordContent(pcap, record);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
wPcap* Pcap_Open(char* name, BOOL write)
Packit 1fb8d4
{
Packit 1fb8d4
	wPcap* pcap = NULL;
Packit 1fb8d4
	FILE* pcap_fp = fopen(name, write ? "w+b" : "rb");
Packit 1fb8d4
Packit 1fb8d4
	if (!pcap_fp)
Packit 1fb8d4
	{
Packit Service 5a9772
		WLog_ERR(TAG, "opening pcap file");
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit Service 5a9772
	pcap = (wPcap*)calloc(1, sizeof(wPcap));
Packit 1fb8d4
Packit 1fb8d4
	if (!pcap)
Packit 1fb8d4
		goto out_fail;
Packit 1fb8d4
Packit 1fb8d4
	pcap->name = name;
Packit 1fb8d4
	pcap->write = write;
Packit 1fb8d4
	pcap->record_count = 0;
Packit 1fb8d4
	pcap->fp = pcap_fp;
Packit 1fb8d4
Packit 1fb8d4
	if (write)
Packit 1fb8d4
	{
Packit 1fb8d4
		pcap->header.magic_number = PCAP_MAGIC_NUMBER;
Packit 1fb8d4
		pcap->header.version_major = 2;
Packit 1fb8d4
		pcap->header.version_minor = 4;
Packit 1fb8d4
		pcap->header.thiszone = 0;
Packit 1fb8d4
		pcap->header.sigfigs = 0;
Packit 1fb8d4
		pcap->header.snaplen = 0xFFFFFFFF;
Packit 1fb8d4
		pcap->header.network = 1; /* ethernet */
Packit 1fb8d4
		if (!Pcap_Write_Header(pcap, &pcap->header))
Packit 1fb8d4
			goto out_fail;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		if (_fseeki64(pcap->fp, 0, SEEK_END) < 0)
Packit 1fb8d4
			goto out_fail;
Packit 1fb8d4
		pcap->file_size = _ftelli64(pcap->fp);
Packit 1fb8d4
		if (pcap->file_size < 0)
Packit 1fb8d4
			goto out_fail;
Packit 1fb8d4
		if (_fseeki64(pcap->fp, 0, SEEK_SET) < 0)
Packit 1fb8d4
			goto out_fail;
Packit 1fb8d4
		if (!Pcap_Read_Header(pcap, &pcap->header))
Packit 1fb8d4
			goto out_fail;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return pcap;
Packit 1fb8d4
Packit 1fb8d4
out_fail:
Packit 1fb8d4
	fclose(pcap_fp);
Packit 1fb8d4
	free(pcap);
Packit 1fb8d4
	return NULL;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void Pcap_Flush(wPcap* pcap)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!pcap || !pcap->fp)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	while (pcap->record)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (!Pcap_Write_Record(pcap, pcap->record))
Packit 1fb8d4
			return;
Packit 1fb8d4
		pcap->record = pcap->record->next;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	fflush(pcap->fp);
Packit 1fb8d4
	return;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void Pcap_Close(wPcap* pcap)
Packit 1fb8d4
{
Packit 1fb8d4
	if (!pcap || !pcap->fp)
Packit 1fb8d4
		return;
Packit 1fb8d4
Packit 1fb8d4
	Pcap_Flush(pcap);
Packit 1fb8d4
	fclose(pcap->fp);
Packit 1fb8d4
	free(pcap);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL WLog_PacketMessage_Write_EthernetHeader(wPcap* pcap, wEthernetHeader* ethernet)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	BYTE buffer[14];
Packit 1fb8d4
	BOOL ret = TRUE;
Packit 1fb8d4
Packit 1fb8d4
	if (!pcap || !pcap->fp || !ethernet)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	s = Stream_New(buffer, 14);
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	Stream_Write(s, ethernet->Destination, 6);
Packit 1fb8d4
	Stream_Write(s, ethernet->Source, 6);
Packit 1fb8d4
	Stream_Write_UINT16_BE(s, ethernet->Type);
Packit 1fb8d4
	if (fwrite(buffer, 14, 1, pcap->fp) != 1)
Packit 1fb8d4
		ret = FALSE;
Packit 1fb8d4
	Stream_Free(s, FALSE);
Packit 1fb8d4
	return ret;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT16 IPv4Checksum(BYTE* ipv4, int length)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT16 tmp16;
Packit 1fb8d4
	long checksum = 0;
Packit 1fb8d4
Packit 1fb8d4
	while (length > 1)
Packit 1fb8d4
	{
Packit Service 5a9772
		tmp16 = *((UINT16*)ipv4);
Packit 1fb8d4
		checksum += tmp16;
Packit 1fb8d4
		length -= 2;
Packit 1fb8d4
		ipv4 += 2;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (length > 0)
Packit 1fb8d4
		checksum += *ipv4;
Packit 1fb8d4
Packit 1fb8d4
	while (checksum >> 16)
Packit 1fb8d4
		checksum = (checksum & 0xFFFF) + (checksum >> 16);
Packit 1fb8d4
Packit 1fb8d4
	return (UINT16)(~checksum);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL WLog_PacketMessage_Write_IPv4Header(wPcap* pcap, wIPv4Header* ipv4)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	BYTE buffer[20];
Packit 1fb8d4
	int ret = TRUE;
Packit 1fb8d4
Packit 1fb8d4
	if (!pcap || !pcap->fp || !ipv4)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	s = Stream_New(buffer, 20);
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	Stream_Write_UINT8(s, (ipv4->Version << 4) | ipv4->InternetHeaderLength);
Packit 1fb8d4
	Stream_Write_UINT8(s, ipv4->TypeOfService);
Packit 1fb8d4
	Stream_Write_UINT16_BE(s, ipv4->TotalLength);
Packit 1fb8d4
	Stream_Write_UINT16_BE(s, ipv4->Identification);
Packit 1fb8d4
	Stream_Write_UINT16_BE(s, (ipv4->InternetProtocolFlags << 13) | ipv4->FragmentOffset);
Packit 1fb8d4
	Stream_Write_UINT8(s, ipv4->TimeToLive);
Packit 1fb8d4
	Stream_Write_UINT8(s, ipv4->Protocol);
Packit 1fb8d4
	Stream_Write_UINT16(s, ipv4->HeaderChecksum);
Packit 1fb8d4
	Stream_Write_UINT32_BE(s, ipv4->SourceAddress);
Packit 1fb8d4
	Stream_Write_UINT32_BE(s, ipv4->DestinationAddress);
Packit Service 5a9772
	ipv4->HeaderChecksum = IPv4Checksum((BYTE*)buffer, 20);
Packit 1fb8d4
	Stream_Rewind(s, 10);
Packit 1fb8d4
	Stream_Write_UINT16(s, ipv4->HeaderChecksum);
Packit 1fb8d4
	Stream_Seek(s, 8);
Packit 1fb8d4
	if (fwrite(buffer, 20, 1, pcap->fp) != 1)
Packit 1fb8d4
		ret = FALSE;
Packit 1fb8d4
	Stream_Free(s, FALSE);
Packit 1fb8d4
	return ret;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static BOOL WLog_PacketMessage_Write_TcpHeader(wPcap* pcap, wTcpHeader* tcp)
Packit 1fb8d4
{
Packit 1fb8d4
	wStream* s;
Packit 1fb8d4
	BYTE buffer[20];
Packit 1fb8d4
	BOOL ret = TRUE;
Packit 1fb8d4
Packit 1fb8d4
	if (!pcap || !pcap->fp || !tcp)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	s = Stream_New(buffer, 20);
Packit 1fb8d4
	if (!s)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	Stream_Write_UINT16_BE(s, tcp->SourcePort);
Packit 1fb8d4
	Stream_Write_UINT16_BE(s, tcp->DestinationPort);
Packit 1fb8d4
	Stream_Write_UINT32_BE(s, tcp->SequenceNumber);
Packit 1fb8d4
	Stream_Write_UINT32_BE(s, tcp->AcknowledgementNumber);
Packit 1fb8d4
	Stream_Write_UINT8(s, (tcp->Offset << 4) | tcp->Reserved);
Packit 1fb8d4
	Stream_Write_UINT8(s, tcp->TcpFlags);
Packit 1fb8d4
	Stream_Write_UINT16_BE(s, tcp->Window);
Packit 1fb8d4
	Stream_Write_UINT16_BE(s, tcp->Checksum);
Packit 1fb8d4
	Stream_Write_UINT16_BE(s, tcp->UrgentPointer);
Packit 1fb8d4
Packit 1fb8d4
	if (pcap->fp)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (fwrite(buffer, 20, 1, pcap->fp) != 1)
Packit 1fb8d4
			ret = FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	Stream_Free(s, FALSE);
Packit 1fb8d4
	return ret;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static UINT32 g_InboundSequenceNumber = 0;
Packit 1fb8d4
static UINT32 g_OutboundSequenceNumber = 0;
Packit 1fb8d4
Packit 1fb8d4
BOOL WLog_PacketMessage_Write(wPcap* pcap, void* data, DWORD length, DWORD flags)
Packit 1fb8d4
{
Packit 1fb8d4
	wTcpHeader tcp;
Packit 1fb8d4
	wIPv4Header ipv4;
Packit 1fb8d4
	struct timeval tp;
Packit 1fb8d4
	wPcapRecord record;
Packit 1fb8d4
	wEthernetHeader ethernet;
Packit 1fb8d4
	ethernet.Type = 0x0800;
Packit 1fb8d4
Packit 1fb8d4
	if (!pcap || !pcap->fp)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (flags & WLOG_PACKET_OUTBOUND)
Packit 1fb8d4
	{
Packit 1fb8d4
		/* 00:15:5D:01:64:04 */
Packit 1fb8d4
		ethernet.Source[0] = 0x00;
Packit 1fb8d4
		ethernet.Source[1] = 0x15;
Packit 1fb8d4
		ethernet.Source[2] = 0x5D;
Packit 1fb8d4
		ethernet.Source[3] = 0x01;
Packit 1fb8d4
		ethernet.Source[4] = 0x64;
Packit 1fb8d4
		ethernet.Source[5] = 0x04;
Packit 1fb8d4
		/* 00:15:5D:01:64:01 */
Packit 1fb8d4
		ethernet.Destination[0] = 0x00;
Packit 1fb8d4
		ethernet.Destination[1] = 0x15;
Packit 1fb8d4
		ethernet.Destination[2] = 0x5D;
Packit 1fb8d4
		ethernet.Destination[3] = 0x01;
Packit 1fb8d4
		ethernet.Destination[4] = 0x64;
Packit 1fb8d4
		ethernet.Destination[5] = 0x01;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		/* 00:15:5D:01:64:01 */
Packit 1fb8d4
		ethernet.Source[0] = 0x00;
Packit 1fb8d4
		ethernet.Source[1] = 0x15;
Packit 1fb8d4
		ethernet.Source[2] = 0x5D;
Packit 1fb8d4
		ethernet.Source[3] = 0x01;
Packit 1fb8d4
		ethernet.Source[4] = 0x64;
Packit 1fb8d4
		ethernet.Source[5] = 0x01;
Packit 1fb8d4
		/* 00:15:5D:01:64:04 */
Packit 1fb8d4
		ethernet.Destination[0] = 0x00;
Packit 1fb8d4
		ethernet.Destination[1] = 0x15;
Packit 1fb8d4
		ethernet.Destination[2] = 0x5D;
Packit 1fb8d4
		ethernet.Destination[3] = 0x01;
Packit 1fb8d4
		ethernet.Destination[4] = 0x64;
Packit 1fb8d4
		ethernet.Destination[5] = 0x04;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	ipv4.Version = 4;
Packit 1fb8d4
	ipv4.InternetHeaderLength = 5;
Packit 1fb8d4
	ipv4.TypeOfService = 0;
Packit 1fb8d4
	ipv4.TotalLength = (UINT16)(length + 20 + 20);
Packit 1fb8d4
	ipv4.Identification = 0;
Packit 1fb8d4
	ipv4.InternetProtocolFlags = 0x02;
Packit 1fb8d4
	ipv4.FragmentOffset = 0;
Packit 1fb8d4
	ipv4.TimeToLive = 128;
Packit 1fb8d4
	ipv4.Protocol = 6; /* TCP */
Packit 1fb8d4
	ipv4.HeaderChecksum = 0;
Packit 1fb8d4
Packit 1fb8d4
	if (flags & WLOG_PACKET_OUTBOUND)
Packit 1fb8d4
	{
Packit Service 5a9772
		ipv4.SourceAddress = 0xC0A80196;      /* 192.168.1.150 */
Packit 1fb8d4
		ipv4.DestinationAddress = 0x4A7D64C8; /* 74.125.100.200 */
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit Service 5a9772
		ipv4.SourceAddress = 0x4A7D64C8;      /* 74.125.100.200 */
Packit 1fb8d4
		ipv4.DestinationAddress = 0xC0A80196; /* 192.168.1.150 */
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	tcp.SourcePort = 3389;
Packit 1fb8d4
	tcp.DestinationPort = 3389;
Packit 1fb8d4
Packit 1fb8d4
	if (flags & WLOG_PACKET_OUTBOUND)
Packit 1fb8d4
	{
Packit 1fb8d4
		tcp.SequenceNumber = g_OutboundSequenceNumber;
Packit 1fb8d4
		tcp.AcknowledgementNumber = g_InboundSequenceNumber;
Packit 1fb8d4
		g_OutboundSequenceNumber += length;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		tcp.SequenceNumber = g_InboundSequenceNumber;
Packit 1fb8d4
		tcp.AcknowledgementNumber = g_OutboundSequenceNumber;
Packit 1fb8d4
		g_InboundSequenceNumber += length;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	tcp.Offset = 5;
Packit 1fb8d4
	tcp.Reserved = 0;
Packit 1fb8d4
	tcp.TcpFlags = 0x0018;
Packit 1fb8d4
	tcp.Window = 0x7FFF;
Packit 1fb8d4
	tcp.Checksum = 0;
Packit 1fb8d4
	tcp.UrgentPointer = 0;
Packit 1fb8d4
	record.data = data;
Packit 1fb8d4
	record.length = length;
Packit 1fb8d4
	record.header.incl_len = record.length + 14 + 20 + 20;
Packit 1fb8d4
	record.header.orig_len = record.length + 14 + 20 + 20;
Packit 1fb8d4
	record.next = NULL;
Packit 1fb8d4
	gettimeofday(&tp, 0);
Packit 1fb8d4
	record.header.ts_sec = tp.tv_sec;
Packit 1fb8d4
	record.header.ts_usec = tp.tv_usec;
Packit 1fb8d4
	if (!Pcap_Write_RecordHeader(pcap, &record.header) ||
Packit Service 5a9772
	    !WLog_PacketMessage_Write_EthernetHeader(pcap, &ethernet) ||
Packit Service 5a9772
	    !WLog_PacketMessage_Write_IPv4Header(pcap, &ipv4) ||
Packit Service 5a9772
	    !WLog_PacketMessage_Write_TcpHeader(pcap, &tcp) || !Pcap_Write_RecordContent(pcap, &record))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
	fflush(pcap->fp);
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}