22#include <winpr/config.h> 
   26#include "PacketMessage.h" 
   28#include <winpr/wtypes.h> 
   30#include <winpr/file.h> 
   31#include <winpr/stream.h> 
   32#include <winpr/sysinfo.h> 
   35#define TAG WINPR_TAG("utils.wlog") 
   39  if (pcap && pcap->fp && fread((
void*)header, 
sizeof(
wPcapHeader), 1, pcap->fp) == 1)
 
   46  if (pcap && pcap->fp && fwrite((
void*)header, 
sizeof(
wPcapHeader), 1, pcap->fp) == 1)
 
   53  if (pcap && pcap->fp && fwrite((
void*)record, 
sizeof(
wPcapRecordHeader), 1, pcap->fp) == 1)
 
   60  if (pcap && pcap->fp && fwrite(record->data, record->length, 1, pcap->fp) == 1)
 
   67  return Pcap_Write_RecordHeader(pcap, &record->header) && Pcap_Write_RecordContent(pcap, record);
 
   70wPcap* Pcap_Open(
char* name, BOOL write)
 
   73  FILE* pcap_fp = winpr_fopen(name, write ? 
"w+b" : 
"rb");
 
   77    WLog_ERR(TAG, 
"opening pcap file");
 
   88  pcap->record_count = 0;
 
   93    pcap->header.magic_number = PCAP_MAGIC_NUMBER;
 
   94    pcap->header.version_major = 2;
 
   95    pcap->header.version_minor = 4;
 
   96    pcap->header.thiszone = 0;
 
   97    pcap->header.sigfigs = 0;
 
   98    pcap->header.snaplen = 0xFFFFFFFF;
 
   99    pcap->header.network = 1; 
 
  100    if (!Pcap_Write_Header(pcap, &pcap->header))
 
  105    if (_fseeki64(pcap->fp, 0, SEEK_END) < 0)
 
  107    pcap->file_size = (SSIZE_T)_ftelli64(pcap->fp);
 
  108    if (pcap->file_size < 0)
 
  110    if (_fseeki64(pcap->fp, 0, SEEK_SET) < 0)
 
  112    if (!Pcap_Read_Header(pcap, &pcap->header))
 
  120    (void)fclose(pcap_fp);
 
  125void Pcap_Flush(
wPcap* pcap)
 
  127  if (!pcap || !pcap->fp)
 
  132    if (!Pcap_Write_Record(pcap, pcap->record))
 
  134    pcap->record = pcap->record->next;
 
  137  (void)fflush(pcap->fp);
 
  140void Pcap_Close(
wPcap* pcap)
 
  142  if (!pcap || !pcap->fp)
 
  146  (void)fclose(pcap->fp);
 
  154  BYTE buffer[14] = { 0 };
 
  157  if (!pcap || !pcap->fp || !ethernet)
 
  160  s = Stream_StaticInit(&sbuffer, buffer, 
sizeof(buffer));
 
  163  Stream_Write(s, ethernet->Destination, 6);
 
  164  Stream_Write(s, ethernet->Source, 6);
 
  165  Stream_Write_UINT16_BE(s, ethernet->Type);
 
  166  if (fwrite(buffer, 
sizeof(buffer), 1, pcap->fp) != 1)
 
  172static UINT16 IPv4Checksum(
const BYTE* ipv4, 
int length)
 
  178    const UINT16 tmp16 = *((
const UINT16*)ipv4);
 
  187  while (checksum >> 16)
 
  188    checksum = (checksum & 0xFFFF) + (checksum >> 16);
 
  190  return (UINT16)(~checksum);
 
  193static BOOL WLog_PacketMessage_Write_IPv4Header(
wPcap* pcap, 
wIPv4Header* ipv4)
 
  197  BYTE buffer[20] = { 0 };
 
  200  if (!pcap || !pcap->fp || !ipv4)
 
  203  s = Stream_StaticInit(&sbuffer, buffer, 
sizeof(buffer));
 
  206  Stream_Write_UINT8(s, (BYTE)((ipv4->Version << 4) | ipv4->InternetHeaderLength));
 
  207  Stream_Write_UINT8(s, ipv4->TypeOfService);
 
  208  Stream_Write_UINT16_BE(s, ipv4->TotalLength);
 
  209  Stream_Write_UINT16_BE(s, ipv4->Identification);
 
  210  Stream_Write_UINT16_BE(s, (UINT16)((ipv4->InternetProtocolFlags << 13) | ipv4->FragmentOffset));
 
  211  Stream_Write_UINT8(s, ipv4->TimeToLive);
 
  212  Stream_Write_UINT8(s, ipv4->Protocol);
 
  213  Stream_Write_UINT16(s, ipv4->HeaderChecksum);
 
  214  Stream_Write_UINT32_BE(s, ipv4->SourceAddress);
 
  215  Stream_Write_UINT32_BE(s, ipv4->DestinationAddress);
 
  216  ipv4->HeaderChecksum = IPv4Checksum((BYTE*)buffer, 20);
 
  217  Stream_Rewind(s, 10);
 
  218  Stream_Write_UINT16(s, ipv4->HeaderChecksum);
 
  220  if (fwrite(buffer, 
sizeof(buffer), 1, pcap->fp) != 1)
 
  226static BOOL WLog_PacketMessage_Write_TcpHeader(
wPcap* pcap, 
wTcpHeader* tcp)
 
  230  BYTE buffer[20] = { 0 };
 
  233  if (!pcap || !pcap->fp || !tcp)
 
  236  s = Stream_StaticInit(&sbuffer, buffer, 
sizeof(buffer));
 
  239  Stream_Write_UINT16_BE(s, tcp->SourcePort);
 
  240  Stream_Write_UINT16_BE(s, tcp->DestinationPort);
 
  241  Stream_Write_UINT32_BE(s, tcp->SequenceNumber);
 
  242  Stream_Write_UINT32_BE(s, tcp->AcknowledgementNumber);
 
  243  Stream_Write_UINT8(s, (UINT8)((tcp->Offset << 4) | (tcp->Reserved & 0xF)));
 
  244  Stream_Write_UINT8(s, tcp->TcpFlags);
 
  245  Stream_Write_UINT16_BE(s, tcp->Window);
 
  246  Stream_Write_UINT16_BE(s, tcp->Checksum);
 
  247  Stream_Write_UINT16_BE(s, tcp->UrgentPointer);
 
  251    if (fwrite(buffer, 
sizeof(buffer), 1, pcap->fp) != 1)
 
  258static UINT32 g_InboundSequenceNumber = 0;
 
  259static UINT32 g_OutboundSequenceNumber = 0;
 
  261BOOL WLog_PacketMessage_Write(
wPcap* pcap, 
void* data, 
size_t length, DWORD flags)
 
  267  ethernet.Type = 0x0800;
 
  269  if (!pcap || !pcap->fp)
 
  272  if (flags & WLOG_PACKET_OUTBOUND)
 
  275    ethernet.Source[0] = 0x00;
 
  276    ethernet.Source[1] = 0x15;
 
  277    ethernet.Source[2] = 0x5D;
 
  278    ethernet.Source[3] = 0x01;
 
  279    ethernet.Source[4] = 0x64;
 
  280    ethernet.Source[5] = 0x04;
 
  282    ethernet.Destination[0] = 0x00;
 
  283    ethernet.Destination[1] = 0x15;
 
  284    ethernet.Destination[2] = 0x5D;
 
  285    ethernet.Destination[3] = 0x01;
 
  286    ethernet.Destination[4] = 0x64;
 
  287    ethernet.Destination[5] = 0x01;
 
  292    ethernet.Source[0] = 0x00;
 
  293    ethernet.Source[1] = 0x15;
 
  294    ethernet.Source[2] = 0x5D;
 
  295    ethernet.Source[3] = 0x01;
 
  296    ethernet.Source[4] = 0x64;
 
  297    ethernet.Source[5] = 0x01;
 
  299    ethernet.Destination[0] = 0x00;
 
  300    ethernet.Destination[1] = 0x15;
 
  301    ethernet.Destination[2] = 0x5D;
 
  302    ethernet.Destination[3] = 0x01;
 
  303    ethernet.Destination[4] = 0x64;
 
  304    ethernet.Destination[5] = 0x04;
 
  308  ipv4.InternetHeaderLength = 5;
 
  309  ipv4.TypeOfService = 0;
 
  310  ipv4.TotalLength = (UINT16)(length + 20 + 20);
 
  311  ipv4.Identification = 0;
 
  312  ipv4.InternetProtocolFlags = 0x02;
 
  313  ipv4.FragmentOffset = 0;
 
  314  ipv4.TimeToLive = 128;
 
  316  ipv4.HeaderChecksum = 0;
 
  318  if (flags & WLOG_PACKET_OUTBOUND)
 
  320    ipv4.SourceAddress = 0xC0A80196;      
 
  321    ipv4.DestinationAddress = 0x4A7D64C8; 
 
  325    ipv4.SourceAddress = 0x4A7D64C8;      
 
  326    ipv4.DestinationAddress = 0xC0A80196; 
 
  329  tcp.SourcePort = 3389;
 
  330  tcp.DestinationPort = 3389;
 
  332  if (flags & WLOG_PACKET_OUTBOUND)
 
  334    tcp.SequenceNumber = g_OutboundSequenceNumber;
 
  335    tcp.AcknowledgementNumber = g_InboundSequenceNumber;
 
  336    WINPR_ASSERT(length + g_OutboundSequenceNumber <= UINT32_MAX);
 
  337    g_OutboundSequenceNumber += WINPR_ASSERTING_INT_CAST(uint32_t, length);
 
  341    tcp.SequenceNumber = g_InboundSequenceNumber;
 
  342    tcp.AcknowledgementNumber = g_OutboundSequenceNumber;
 
  344    WINPR_ASSERT(length + g_InboundSequenceNumber <= UINT32_MAX);
 
  345    g_InboundSequenceNumber += WINPR_ASSERTING_INT_CAST(uint32_t, length);
 
  350  tcp.TcpFlags = 0x0018;
 
  353  tcp.UrgentPointer = 0;
 
  355  record.length = length;
 
  356  const size_t offset = 14 + 20 + 20;
 
  357  WINPR_ASSERT(record.length <= UINT32_MAX - offset);
 
  358  const uint32_t rloff = WINPR_ASSERTING_INT_CAST(uint32_t, record.length + offset);
 
  359  record.header.incl_len = rloff;
 
  360  record.header.orig_len = rloff;
 
  363  UINT64 ns = winpr_GetUnixTimeNS();
 
  364  record.header.ts_sec = (UINT32)WINPR_TIME_NS_TO_S(ns);
 
  365  record.header.ts_usec = WINPR_TIME_NS_REM_US(ns);
 
  367  if (!Pcap_Write_RecordHeader(pcap, &record.header) ||
 
  368      !WLog_PacketMessage_Write_EthernetHeader(pcap, ðernet) ||
 
  369      !WLog_PacketMessage_Write_IPv4Header(pcap, &ipv4) ||
 
  370      !WLog_PacketMessage_Write_TcpHeader(pcap, &tcp) || !Pcap_Write_RecordContent(pcap, &record))
 
  372  (void)fflush(pcap->fp);