libwinpr-utils: start implement wlog packet appender
This commit is contained in:
parent
07afc88878
commit
684db03578
@ -56,6 +56,7 @@ typedef struct _wLogAppender wLogAppender;
|
||||
#define WLOG_MESSAGE_TEXT 0
|
||||
#define WLOG_MESSAGE_DATA 1
|
||||
#define WLOG_MESSAGE_IMAGE 2
|
||||
#define WLOG_MESSAGE_PACKET 3
|
||||
|
||||
struct _wLogMessage
|
||||
{
|
||||
@ -109,17 +110,23 @@ typedef int (*WLOG_APPENDER_CLOSE_FN)(wLog* log, wLogAppender* appender);
|
||||
typedef int (*WLOG_APPENDER_WRITE_MESSAGE_FN)(wLog* log, wLogAppender* appender, wLogMessage* message);
|
||||
typedef int (*WLOG_APPENDER_WRITE_DATA_MESSAGE_FN)(wLog* log, wLogAppender* appender, wLogMessage* message);
|
||||
typedef int (*WLOG_APPENDER_WRITE_IMAGE_MESSAGE_FN)(wLog* log, wLogAppender* appender, wLogMessage* message);
|
||||
typedef int (*WLOG_APPENDER_WRITE_PACKET_MESSAGE_FN)(wLog* log, wLogAppender* appender, wLogMessage* message);
|
||||
|
||||
#define WLOG_APPENDER_COMMON() \
|
||||
DWORD Type; \
|
||||
DWORD State; \
|
||||
wLogLayout* Layout; \
|
||||
CRITICAL_SECTION lock; \
|
||||
void* TextMessageContext; \
|
||||
void* DataMessageContext; \
|
||||
void* ImageMessageContext; \
|
||||
void* PacketMessageContext; \
|
||||
WLOG_APPENDER_OPEN_FN Open; \
|
||||
WLOG_APPENDER_CLOSE_FN Close; \
|
||||
WLOG_APPENDER_WRITE_MESSAGE_FN WriteMessage; \
|
||||
WLOG_APPENDER_WRITE_DATA_MESSAGE_FN WriteDataMessage; \
|
||||
WLOG_APPENDER_WRITE_IMAGE_MESSAGE_FN WriteImageMessage
|
||||
WLOG_APPENDER_WRITE_IMAGE_MESSAGE_FN WriteImageMessage; \
|
||||
WLOG_APPENDER_WRITE_PACKET_MESSAGE_FN WritePacketMessage
|
||||
|
||||
struct _wLogAppender
|
||||
{
|
||||
@ -193,6 +200,18 @@ WINPR_API void WLog_PrintMessage(wLog* log, wLogMessage* message, ...);
|
||||
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
|
||||
}
|
||||
|
||||
#define WLog_Data(_log, _log_level, ...) \
|
||||
if (_log_level >= _log->Level) { \
|
||||
wLogMessage _log_message; \
|
||||
_log_message.Type = WLOG_MESSAGE_DATA; \
|
||||
_log_message.Level = _log_level; \
|
||||
_log_message.FormatString = NULL; \
|
||||
_log_message.LineNumber = __LINE__; \
|
||||
_log_message.FileName = __FILE__; \
|
||||
_log_message.FunctionName = __FUNCTION__; \
|
||||
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
|
||||
}
|
||||
|
||||
#define WLog_Image(_log, _log_level, ...) \
|
||||
if (_log_level >= _log->Level) { \
|
||||
wLogMessage _log_message; \
|
||||
@ -205,10 +224,10 @@ WINPR_API void WLog_PrintMessage(wLog* log, wLogMessage* message, ...);
|
||||
WLog_PrintMessage(_log, &(_log_message), ## __VA_ARGS__ ); \
|
||||
}
|
||||
|
||||
#define WLog_Data(_log, _log_level, ...) \
|
||||
#define WLog_Packet(_log, _log_level, ...) \
|
||||
if (_log_level >= _log->Level) { \
|
||||
wLogMessage _log_message; \
|
||||
_log_message.Type = WLOG_MESSAGE_DATA; \
|
||||
_log_message.Type = WLOG_MESSAGE_PACKET; \
|
||||
_log_message.Level = _log_level; \
|
||||
_log_message.FormatString = NULL; \
|
||||
_log_message.LineNumber = __LINE__; \
|
||||
|
@ -61,6 +61,8 @@ set(${MODULE_PREFIX}_WLOG_SRCS
|
||||
wlog/DataMessage.h
|
||||
wlog/ImageMessage.c
|
||||
wlog/ImageMessage.h
|
||||
wlog/PacketMessage.c
|
||||
wlog/PacketMessage.h
|
||||
wlog/Appender.c
|
||||
wlog/Appender.h
|
||||
wlog/FileAppender.c
|
||||
|
@ -116,6 +116,27 @@ int WLog_ConsoleAppender_WriteImageMessage(wLog* log, wLogConsoleAppender* appen
|
||||
return ImageId;
|
||||
}
|
||||
|
||||
static int g_PacketId = 0;
|
||||
|
||||
int WLog_ConsoleAppender_WritePacketMessage(wLog* log, wLogConsoleAppender* appender, wLogMessage* message)
|
||||
{
|
||||
int PacketId;
|
||||
char* FullFileName;
|
||||
|
||||
PacketId = g_PacketId++;
|
||||
|
||||
if (!appender->PacketMessageContext)
|
||||
{
|
||||
FullFileName = WLog_Message_GetOutputFileName(PacketId, "pcap");
|
||||
appender->PacketMessageContext = (void*) Pcap_Open(FullFileName, TRUE);
|
||||
free(FullFileName);
|
||||
}
|
||||
|
||||
WLog_PacketMessage_Write((wPcap*) appender->PacketMessageContext, message->Data, message->Length, 0);
|
||||
|
||||
return PacketId;
|
||||
}
|
||||
|
||||
wLogConsoleAppender* WLog_ConsoleAppender_New(wLog* log)
|
||||
{
|
||||
wLogConsoleAppender* ConsoleAppender;
|
||||
@ -137,6 +158,8 @@ wLogConsoleAppender* WLog_ConsoleAppender_New(wLog* log)
|
||||
(WLOG_APPENDER_WRITE_DATA_MESSAGE_FN) WLog_ConsoleAppender_WriteDataMessage;
|
||||
ConsoleAppender->WriteImageMessage =
|
||||
(WLOG_APPENDER_WRITE_IMAGE_MESSAGE_FN) WLog_ConsoleAppender_WriteImageMessage;
|
||||
ConsoleAppender->WritePacketMessage =
|
||||
(WLOG_APPENDER_WRITE_PACKET_MESSAGE_FN) WLog_ConsoleAppender_WritePacketMessage;
|
||||
|
||||
ConsoleAppender->outputStream = WLOG_CONSOLE_STDOUT;
|
||||
}
|
||||
@ -148,6 +171,11 @@ void WLog_ConsoleAppender_Free(wLog* log, wLogConsoleAppender* appender)
|
||||
{
|
||||
if (appender)
|
||||
{
|
||||
if (appender->PacketMessageContext)
|
||||
{
|
||||
Pcap_Close((wPcap*) appender->PacketMessageContext);
|
||||
}
|
||||
|
||||
free(appender);
|
||||
}
|
||||
}
|
||||
|
@ -24,8 +24,10 @@
|
||||
|
||||
#include "wlog/wlog.h"
|
||||
|
||||
#include "wlog/TextMessage.h"
|
||||
#include "wlog/DataMessage.h"
|
||||
#include "wlog/ImageMessage.h"
|
||||
#include "wlog/PacketMessage.h"
|
||||
|
||||
char* WLog_Message_GetOutputFileName(int id, const char* ext);
|
||||
|
||||
|
238
winpr/libwinpr/utils/wlog/PacketMessage.c
Normal file
238
winpr/libwinpr/utils/wlog/PacketMessage.c
Normal file
@ -0,0 +1,238 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* WinPR Logger
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/wlog.h>
|
||||
|
||||
#include "wlog/PacketMessage.h"
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
static int gettimeofday(struct timeval* tp, void* tz)
|
||||
{
|
||||
struct _timeb timebuffer;
|
||||
_ftime(&timebuffer);
|
||||
tp->tv_sec = (long) timebuffer.time;
|
||||
tp->tv_usec = timebuffer.millitm * 1000;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Pcap_Read_Header(wPcap* pcap, wPcapHeader* header)
|
||||
{
|
||||
fread((void*) header, sizeof(wPcapHeader), 1, pcap->fp);
|
||||
}
|
||||
|
||||
void Pcap_Write_Header(wPcap* pcap, wPcapHeader* header)
|
||||
{
|
||||
fwrite((void*) header, sizeof(wPcapHeader), 1, pcap->fp);
|
||||
}
|
||||
|
||||
void Pcap_Read_RecordHeader(wPcap* pcap, wPcapRecordHeader* record)
|
||||
{
|
||||
fread((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp);
|
||||
}
|
||||
|
||||
void Pcap_Write_RecordHeader(wPcap* pcap, wPcapRecordHeader* record)
|
||||
{
|
||||
fwrite((void*) record, sizeof(wPcapRecordHeader), 1, pcap->fp);
|
||||
}
|
||||
|
||||
void Pcap_Read_Record(wPcap* pcap, wPcapRecord* record)
|
||||
{
|
||||
Pcap_Read_RecordHeader(pcap, &record->header);
|
||||
record->length = record->header.incl_len;
|
||||
record->data = malloc(record->length);
|
||||
fread(record->data, record->length, 1, pcap->fp);
|
||||
}
|
||||
|
||||
void Pcap_Write_Record(wPcap* pcap, wPcapRecord* record)
|
||||
{
|
||||
Pcap_Write_RecordHeader(pcap, &record->header);
|
||||
fwrite(record->data, record->length, 1, pcap->fp);
|
||||
}
|
||||
|
||||
void Pcap_Add_Record(wPcap* pcap, void* data, UINT32 length)
|
||||
{
|
||||
wPcapRecord* record;
|
||||
struct timeval tp;
|
||||
|
||||
if (!pcap->tail)
|
||||
{
|
||||
pcap->tail = (wPcapRecord*) malloc(sizeof(wPcapRecord));
|
||||
ZeroMemory(pcap->tail, sizeof(wPcapRecord));
|
||||
|
||||
pcap->head = pcap->tail;
|
||||
pcap->record = pcap->head;
|
||||
record = pcap->tail;
|
||||
}
|
||||
else
|
||||
{
|
||||
record = (wPcapRecord*) malloc(sizeof(wPcapRecord));
|
||||
ZeroMemory(record, sizeof(wPcapRecord));
|
||||
|
||||
pcap->tail->next = record;
|
||||
pcap->tail = record;
|
||||
}
|
||||
|
||||
if (!pcap->record)
|
||||
pcap->record = record;
|
||||
|
||||
record->data = 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;
|
||||
}
|
||||
|
||||
BOOL Pcap_HasNext_Record(wPcap* pcap)
|
||||
{
|
||||
if (pcap->file_size - (ftell(pcap->fp)) <= 16)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Pcap_GetNext_RecordHeader(wPcap* pcap, wPcapRecord* record)
|
||||
{
|
||||
if (Pcap_HasNext_Record(pcap) != TRUE)
|
||||
return FALSE;
|
||||
|
||||
Pcap_Read_RecordHeader(pcap, &record->header);
|
||||
record->length = record->header.incl_len;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Pcap_GetNext_RecordContent(wPcap* pcap, wPcapRecord* record)
|
||||
{
|
||||
fread(record->data, record->length, 1, pcap->fp);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Pcap_GetNext_Record(wPcap* pcap, wPcapRecord* record)
|
||||
{
|
||||
if (Pcap_HasNext_Record(pcap) != TRUE)
|
||||
return FALSE;
|
||||
|
||||
Pcap_Read_Record(pcap, record);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
wPcap* Pcap_Open(char* name, BOOL write)
|
||||
{
|
||||
wPcap* pcap;
|
||||
|
||||
FILE* pcap_fp = fopen(name, write ? "w+b" : "rb");
|
||||
|
||||
if (!pcap_fp)
|
||||
{
|
||||
perror("opening pcap file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pcap = (wPcap*) malloc(sizeof(wPcap));
|
||||
|
||||
if (pcap)
|
||||
{
|
||||
ZeroMemory(pcap, sizeof(wPcap));
|
||||
|
||||
pcap->name = name;
|
||||
pcap->write = write;
|
||||
pcap->record_count = 0;
|
||||
pcap->fp = pcap_fp;
|
||||
|
||||
if (write)
|
||||
{
|
||||
pcap->header.magic_number = PCAP_MAGIC_NUMBER;
|
||||
pcap->header.version_major = 2;
|
||||
pcap->header.version_minor = 4;
|
||||
pcap->header.thiszone = 0;
|
||||
pcap->header.sigfigs = 0;
|
||||
pcap->header.snaplen = 0xFFFFFFFF;
|
||||
pcap->header.network = 0;
|
||||
Pcap_Write_Header(pcap, &pcap->header);
|
||||
}
|
||||
else
|
||||
{
|
||||
fseek(pcap->fp, 0, SEEK_END);
|
||||
pcap->file_size = (int) ftell(pcap->fp);
|
||||
fseek(pcap->fp, 0, SEEK_SET);
|
||||
Pcap_Read_Header(pcap, &pcap->header);
|
||||
}
|
||||
}
|
||||
|
||||
return pcap;
|
||||
}
|
||||
|
||||
void Pcap_Flush(wPcap* pcap)
|
||||
{
|
||||
while (pcap->record)
|
||||
{
|
||||
Pcap_Write_Record(pcap, pcap->record);
|
||||
pcap->record = pcap->record->next;
|
||||
}
|
||||
|
||||
if (pcap->fp)
|
||||
fflush(pcap->fp);
|
||||
}
|
||||
|
||||
void Pcap_Close(wPcap* pcap)
|
||||
{
|
||||
Pcap_Flush(pcap);
|
||||
|
||||
if (pcap->fp)
|
||||
fclose(pcap->fp);
|
||||
|
||||
free(pcap);
|
||||
}
|
||||
|
||||
int WLog_PacketMessage_Write(wPcap* pcap, void* data, DWORD length, DWORD flags)
|
||||
{
|
||||
struct timeval tp;
|
||||
wPcapRecord record;
|
||||
|
||||
record.data = data;
|
||||
record.length = length;
|
||||
record.next = NULL;
|
||||
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;
|
||||
|
||||
Pcap_Write_Record(pcap, &record);
|
||||
|
||||
return 0;
|
||||
}
|
82
winpr/libwinpr/utils/wlog/PacketMessage.h
Normal file
82
winpr/libwinpr/utils/wlog/PacketMessage.h
Normal file
@ -0,0 +1,82 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* WinPR Logger
|
||||
*
|
||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef WINPR_WLOG_PACKET_MESSAGE_PRIVATE_H
|
||||
#define WINPR_WLOG_PACKET_MESSAGE_PRIVATE_H
|
||||
|
||||
#include <winpr/wlog.h>
|
||||
|
||||
#include "wlog/wlog.h"
|
||||
|
||||
#define PCAP_MAGIC_NUMBER 0xA1B2C3D4
|
||||
|
||||
struct _wPcapHeader
|
||||
{
|
||||
UINT32 magic_number; /* magic number */
|
||||
UINT16 version_major; /* major version number */
|
||||
UINT16 version_minor; /* minor version number */
|
||||
INT32 thiszone; /* GMT to local correction */
|
||||
UINT32 sigfigs; /* accuracy of timestamps */
|
||||
UINT32 snaplen; /* max length of captured packets, in octets */
|
||||
UINT32 network; /* data link type */
|
||||
};
|
||||
typedef struct _wPcapHeader wPcapHeader;
|
||||
|
||||
struct _wPcapRecordHeader
|
||||
{
|
||||
UINT32 ts_sec; /* timestamp seconds */
|
||||
UINT32 ts_usec; /* timestamp microseconds */
|
||||
UINT32 incl_len; /* number of octets of packet saved in file */
|
||||
UINT32 orig_len; /* actual length of packet */
|
||||
};
|
||||
typedef struct _wPcapRecordHeader wPcapRecordHeader;
|
||||
|
||||
typedef struct _wPcapRecord wPcapRecord;
|
||||
|
||||
struct _wPcapRecord
|
||||
{
|
||||
wPcapRecordHeader header;
|
||||
void* data;
|
||||
UINT32 length;
|
||||
wPcapRecord* next;
|
||||
};
|
||||
|
||||
struct _wPcap
|
||||
{
|
||||
FILE* fp;
|
||||
char* name;
|
||||
BOOL write;
|
||||
int file_size;
|
||||
int record_count;
|
||||
wPcapHeader header;
|
||||
wPcapRecord* head;
|
||||
wPcapRecord* tail;
|
||||
wPcapRecord* record;
|
||||
};
|
||||
typedef struct _wPcap wPcap;
|
||||
|
||||
wPcap* Pcap_Open(char* name, BOOL write);
|
||||
void Pcap_Close(wPcap* pcap);
|
||||
|
||||
void Pcap_Flush(wPcap* pcap);
|
||||
|
||||
int WLog_PacketMessage_Write(wPcap* pcap, void* data, DWORD length, DWORD flags);
|
||||
|
||||
#endif /* WINPR_WLOG_PACKET_MESSAGE_PRIVATE_H */
|
||||
|
@ -79,6 +79,31 @@ int WLog_Write(wLog* log, wLogMessage* message)
|
||||
return status;
|
||||
}
|
||||
|
||||
int WLog_WriteData(wLog* log, wLogMessage* message)
|
||||
{
|
||||
int status;
|
||||
wLogAppender* appender;
|
||||
|
||||
appender = WLog_GetLogAppender(log);
|
||||
|
||||
if (!appender)
|
||||
return -1;
|
||||
|
||||
if (!appender->State)
|
||||
WLog_OpenAppender(log);
|
||||
|
||||
if (!appender->WriteDataMessage)
|
||||
return -1;
|
||||
|
||||
EnterCriticalSection(&appender->lock);
|
||||
|
||||
status = appender->WriteDataMessage(log, appender, message);
|
||||
|
||||
LeaveCriticalSection(&appender->lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int WLog_WriteImage(wLog* log, wLogMessage* message)
|
||||
{
|
||||
int status;
|
||||
@ -104,7 +129,7 @@ int WLog_WriteImage(wLog* log, wLogMessage* message)
|
||||
return status;
|
||||
}
|
||||
|
||||
int WLog_WriteData(wLog* log, wLogMessage* message)
|
||||
int WLog_WritePacket(wLog* log, wLogMessage* message)
|
||||
{
|
||||
int status;
|
||||
wLogAppender* appender;
|
||||
@ -117,12 +142,12 @@ int WLog_WriteData(wLog* log, wLogMessage* message)
|
||||
if (!appender->State)
|
||||
WLog_OpenAppender(log);
|
||||
|
||||
if (!appender->WriteDataMessage)
|
||||
if (!appender->WritePacketMessage)
|
||||
return -1;
|
||||
|
||||
EnterCriticalSection(&appender->lock);
|
||||
|
||||
status = appender->WriteDataMessage(log, appender, message);
|
||||
status = appender->WritePacketMessage(log, appender, message);
|
||||
|
||||
LeaveCriticalSection(&appender->lock);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user