diff --git a/include/freerdp/utils/pcap.h b/include/freerdp/utils/pcap.h index 29a743333..a74c82510 100644 --- a/include/freerdp/utils/pcap.h +++ b/include/freerdp/utils/pcap.h @@ -56,18 +56,6 @@ struct s_pcap_record pcap_record* next; }; -struct rdp_pcap -{ - FILE* fp; - char* name; - BOOL write; - INT64 file_size; - int record_count; - pcap_header header; - pcap_record* head; - pcap_record* tail; - pcap_record* record; -}; typedef struct rdp_pcap rdpPcap; #ifdef __cplusplus @@ -78,8 +66,8 @@ extern "C" FREERDP_API rdpPcap* pcap_open(const char* name, BOOL write); FREERDP_API void pcap_close(rdpPcap* pcap); - FREERDP_API BOOL pcap_add_record(rdpPcap* pcap, const void* data, UINT32 length); - FREERDP_API BOOL pcap_has_next_record(rdpPcap* pcap); + FREERDP_API BOOL pcap_add_record(rdpPcap* pcap, const void* data, size_t length); + FREERDP_API BOOL pcap_has_next_record(const rdpPcap* pcap); FREERDP_API BOOL pcap_get_next_record(rdpPcap* pcap, pcap_record* record); FREERDP_API BOOL pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record); FREERDP_API BOOL pcap_get_next_record_content(rdpPcap* pcap, pcap_record* record); diff --git a/libfreerdp/core/freerdp.c b/libfreerdp/core/freerdp.c index 70c2b9ec1..26ffdcdd1 100644 --- a/libfreerdp/core/freerdp.c +++ b/libfreerdp/core/freerdp.c @@ -175,7 +175,7 @@ BOOL freerdp_connect(freerdp* instance) { wStream* s; rdp_update_internal* update = update_cast(instance->context->update); - pcap_record record; + pcap_record record = { 0 }; WINPR_ASSERT(update); update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE); diff --git a/libfreerdp/utils/pcap.c b/libfreerdp/utils/pcap.c index 684e45fa1..a0ea11c2b 100644 --- a/libfreerdp/utils/pcap.c +++ b/libfreerdp/utils/pcap.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -52,28 +53,56 @@ int gettimeofday(struct timeval* tp, void* tz) #define PCAP_MAGIC 0xA1B2C3D4 +struct rdp_pcap +{ + FILE* fp; + char* name; + BOOL write; + INT64 file_size; + size_t record_count; + pcap_header header; + pcap_record* head; + pcap_record* tail; + pcap_record* record; +}; + static BOOL pcap_read_header(rdpPcap* pcap, pcap_header* header) { - return fread((void*)header, sizeof(pcap_header), 1, pcap->fp) == 1; + WINPR_ASSERT(pcap); + WINPR_ASSERT(header); + + return fread(header, sizeof(pcap_header), 1, pcap->fp) == 1; } -static BOOL pcap_write_header(rdpPcap* pcap, pcap_header* header) +static BOOL pcap_write_header(rdpPcap* pcap, const pcap_header* header) { - return fwrite((void*)header, sizeof(pcap_header), 1, pcap->fp) == 1; + WINPR_ASSERT(pcap); + WINPR_ASSERT(header); + + return fwrite(header, sizeof(pcap_header), 1, pcap->fp) == 1; } static BOOL pcap_read_record_header(rdpPcap* pcap, pcap_record_header* record) { - return fread((void*)record, sizeof(pcap_record_header), 1, pcap->fp) == 1; + WINPR_ASSERT(pcap); + WINPR_ASSERT(record); + + return fread(record, sizeof(pcap_record_header), 1, pcap->fp) == 1; } -static BOOL pcap_write_record_header(rdpPcap* pcap, pcap_record_header* record) +static BOOL pcap_write_record_header(rdpPcap* pcap, const pcap_record_header* record) { - return fwrite((void*)record, sizeof(pcap_record_header), 1, pcap->fp) == 1; + WINPR_ASSERT(pcap); + WINPR_ASSERT(record); + + return fwrite(record, sizeof(pcap_record_header), 1, pcap->fp) == 1; } static BOOL pcap_read_record(rdpPcap* pcap, pcap_record* record) { + WINPR_ASSERT(pcap); + WINPR_ASSERT(record); + if (!pcap_read_record_header(pcap, &record->header)) return FALSE; @@ -91,53 +120,61 @@ static BOOL pcap_read_record(rdpPcap* pcap, pcap_record* record) return TRUE; } -static BOOL pcap_write_record(rdpPcap* pcap, pcap_record* record) +static BOOL pcap_write_record(rdpPcap* pcap, const pcap_record* record) { + WINPR_ASSERT(pcap); + WINPR_ASSERT(record); + return pcap_write_record_header(pcap, &record->header) && (fwrite(record->cdata, record->length, 1, pcap->fp) == 1); } -BOOL pcap_add_record(rdpPcap* pcap, const void* data, UINT32 length) +BOOL pcap_add_record(rdpPcap* pcap, const void* data, size_t length) { pcap_record* record; struct timeval tp; + WINPR_ASSERT(pcap); + WINPR_ASSERT(data || (length == 0)); + WINPR_ASSERT(length <= UINT32_MAX); + + record = (pcap_record*)calloc(1, sizeof(pcap_record)); + if (!record) + return FALSE; + + record->cdata = data; + record->length = length; + record->header.incl_len = (UINT32)length; + record->header.orig_len = (UINT32)length; + + gettimeofday(&tp, 0); + record->header.ts_sec = (UINT32)tp.tv_sec; + record->header.ts_usec = (UINT32)tp.tv_usec; + if (pcap->tail == NULL) { - pcap->tail = (pcap_record*)calloc(1, sizeof(pcap_record)); + pcap->tail = record; if (!pcap->tail) return FALSE; pcap->head = pcap->tail; - pcap->record = pcap->head; - record = pcap->tail; } else { - record = (pcap_record*)calloc(1, sizeof(pcap_record)); - if (!record) - return FALSE; - - pcap->tail->next = record; + record->next = pcap->tail; pcap->tail = record; } if (pcap->record == NULL) pcap->record = record; - record->cdata = data; - record->length = length; - record->header.incl_len = length; - record->header.orig_len = length; - - gettimeofday(&tp, 0); - record->header.ts_sec = tp.tv_sec; - record->header.ts_usec = tp.tv_usec; return TRUE; } -BOOL pcap_has_next_record(rdpPcap* pcap) +BOOL pcap_has_next_record(const rdpPcap* pcap) { + WINPR_ASSERT(pcap); + if (pcap->file_size - (_ftelli64(pcap->fp)) <= 16) return FALSE; @@ -146,6 +183,9 @@ BOOL pcap_has_next_record(rdpPcap* pcap) BOOL pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record) { + WINPR_ASSERT(pcap); + WINPR_ASSERT(record); + if (pcap_has_next_record(pcap) != TRUE) return FALSE; @@ -157,11 +197,17 @@ BOOL pcap_get_next_record_header(rdpPcap* pcap, pcap_record* record) BOOL pcap_get_next_record_content(rdpPcap* pcap, pcap_record* record) { + WINPR_ASSERT(pcap); + WINPR_ASSERT(record); + return fread(record->data, record->length, 1, pcap->fp) == 1; } BOOL pcap_get_next_record(rdpPcap* pcap, pcap_record* record) { + WINPR_ASSERT(pcap); + WINPR_ASSERT(record); + return pcap_has_next_record(pcap) && pcap_read_record(pcap, record); } @@ -169,6 +215,8 @@ rdpPcap* pcap_open(const char* name, BOOL write) { rdpPcap* pcap; + WINPR_ASSERT(name); + pcap = (rdpPcap*)calloc(1, sizeof(rdpPcap)); if (!pcap) goto fail; @@ -183,12 +231,12 @@ rdpPcap* pcap_open(const char* name, BOOL write) if (write) { - pcap->header.magic_number = 0xA1B2C3D4; + pcap->header.magic_number = PCAP_MAGIC; pcap->header.version_major = 2; pcap->header.version_minor = 4; pcap->header.thiszone = 0; pcap->header.sigfigs = 0; - pcap->header.snaplen = 0xFFFFFFFF; + pcap->header.snaplen = UINT32_MAX; pcap->header.network = 0; if (!pcap_write_header(pcap, &pcap->header)) goto fail; @@ -211,6 +259,8 @@ fail: void pcap_flush(rdpPcap* pcap) { + WINPR_ASSERT(pcap); + while (pcap->record != NULL) { pcap_write_record(pcap, pcap->record); diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index f1f66e7fa..6f24e38d1 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -508,7 +508,7 @@ static BOOL tf_peer_dump_rfx(freerdp_peer* client) UINT32 prev_useconds; rdpUpdate* update; rdpPcap* pcap_rfx; - pcap_record record; + pcap_record record = { 0 }; struct server_info* info; WINPR_ASSERT(client);