Wireshark is the world's foremost network protocol analyzer, and is the de facto (and often de jure) standard across many industries and educational institutions:
for this reasons, implementing a new protocol on any kind of transport, it is worth considering implementing a pcap logger and a Wireshark dissector:
To download the required libraries in c:\wireshark-win32-libs
nmake -f Makefile.nmake setup
To configure the windows build:
nmake -f Makefile.nmake distclean
To build it (especially the libaries required by the plugins):
nmake -f Makefile.nmake
A basic pcap logger for a user defined protocol:
Logger.h
#ifndef LOGGER_H_ #define LOGGER_H_ #include <stdio.h> #include <stdexcept> using namespace std; class Logger { public: Logger(const char* filename) throw(runtime_error); void log_packet(const unsigned char* data, const int len) throw(runtime_error); virtual ~Logger(); private: void write(const void* buffer, const size_t len) throw(runtime_error); FILE* file; }; #endif /*LOGGER_H_*/
Logger.cpp
#include <stdlib.h> #ifdef WIN32 #include <sys/types.h> #include <sys/timeb.h> #else #include <time.h> #include <sys/time.h> #endif #include "Logger.h" /* Global Header Data */ #define MAGIC_NUMBER 0xa1b2c3d4 #define CURRENT_PCAP_MAJOR 2 #define CURRENT_PCAP_MINOR 4 #define ZONE_GMT 0 #define WTAP_ENCAP_USER0 147 typedef struct pcap_hdr_s { unsigned int magic_number; /* magic number */ unsigned short version_major; /* major version number */ unsigned short version_minor; /* minor version number */ int thiszone; /* GMT to local correction */ unsigned int sigfigs; /* accuracy of timestamps */ unsigned int snaplen; /* max length of captured packets, in octets */ unsigned int network; /* data link type */ } pcap_hdr_t; /* Record Header Data */ typedef struct pcaprec_hdr_s { unsigned int ts_sec; /* timestamp seconds */ unsigned int ts_usec; /* timestamp microseconds */ unsigned int incl_len; /* number of octets of packet saved in file */ unsigned int orig_len; /* actual length of packet */ } pcaprec_hdr_t; Logger::Logger(const char* filename) throw(runtime_error){ file = fopen(filename, "w"); if (file == NULL) throw runtime_error("[ERROR] opening file"); /* Write Global Header */ pcap_hdr_t header; header.magic_number = MAGIC_NUMBER; header.version_major = CURRENT_PCAP_MAJOR; header.version_minor = CURRENT_PCAP_MINOR; header.thiszone = ZONE_GMT; header.sigfigs = 0; header.snaplen = 0xFFFF; header.network = WTAP_ENCAP_USER0; /*See: http://anonsvn.wireshark.org/wireshark/trunk/wiretap/libpcap.c */ write(&header, sizeof(pcap_hdr_t)); } void Logger::write(const void* buffer, const size_t len) throw(runtime_error) { if (fwrite(buffer, len, 1, file) != 1) throw runtime_error("[ERROR] writing to file"); } void Logger::log_packet(const unsigned char* data, const int len) throw(runtime_error) { unsigned int sec, sec; #ifdef WIN32 struct _timeb timebuffer; _ftime(&timebuffer); sec = (unsigned int)timebuffer.time; usec = ((unsigned int)timebuffer.millitm) * 1000; #else struct timeval time; gettimeofday(&time, NULL); sec = time.tv_sec; usec = time.tv_usec; #endif pcaprec_hdr_t recHeader; recHeader.ts_sec = sec; recHeader.ts_usec = usec; recHeader.incl_len = len; recHeader.orig_len = len; write(&recHeader, sizeof(pcaprec_hdr_t)); write(data, len); } Logger::~Logger() { if (file != NULL) fclose(file); }