Change mstpcap to either write to pipe or file, not both. (#492)

* Change mstpcap to either write to pipe or file, not both.

Fixed bug#83 of mstpcap.exe Permission Denied in Wireshark

---------

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2023-09-11 09:41:54 -05:00
committed by GitHub
parent e4dd30ed89
commit 94dd465e7b
2 changed files with 217 additions and 206 deletions
+27 -26
View File
@@ -1,6 +1,6 @@
# BACnet Stack ChangeLog
BACnet open source protocol stack C library for embedded systems,
BACnet open source protocol stack C library for embedded systems,
Linux, MacOS, BSD, and Windows
All notable changes to this project will be documented in this file.
@@ -16,16 +16,16 @@ The git repositories are hosted at the following sites:
### Security
- Added or updated secure the BACnet primitive value decoders
named bacnet_x_decode(), bacnet_x_application_decode() and
bacnet_x_context_decode where x is one of the 13 BACnet primitive value names.
The updated API includes an APDU size to prevent over-reading of an APDU buffer.
- Added or updated secure the BACnet primitive value decoders
named bacnet_x_decode(), bacnet_x_application_decode() and
bacnet_x_context_decode where x is one of the 13 BACnet primitive value names.
The updated API includes an APDU size to prevent over-reading of an APDU buffer.
Improved or added unit test code coverage for the primitive value decoders (#481)
- marked the insecure decoding API as 'deprecated' which is defined in
- marked the insecure decoding API as 'deprecated' which is defined in
src/bacnet/basic/sys/platform.h and can be disabled during a build. (#481)
- secured decoders for BACnetTimeValue, BACnetHostNPort, BACnetTimeStamp,
- secured decoders for BACnetTimeValue, BACnetHostNPort, BACnetTimeStamp,
BACnetAddress, and Weekly_Schedule and improved unit test code coverage. (#481)
- secured AtomicReadFile and AtomicWriteFile service decoders and
- secured AtomicReadFile and AtomicWriteFile service decoders and
improved unit test code coverage. (#481)
- secured BACnet Error service decoder and improved unit test code coverage. (#481)
- improved test code coverage for BACnet objects and properties. (#481)
@@ -42,6 +42,7 @@ improved unit test code coverage. (#481)
Link_Speed property is writable (#488)
- Fixed Microchip xmega xplained example project to build under GCC in pipeline.
- Fixed BACnet/IP on OS to bind broadcast to specific port (#489)
- Fixed (bug#83) mstpcap.exe permission denied in Wireshark (#492)
## [1.1.2] - 2023-08-18
@@ -87,7 +88,7 @@ Link_Speed property is writable (#488)
- Added minimim support for BACnet protocol-revision 0 through 24. See 
BACNET_PROTOCOL_REVISION define in bacdef.h
- Added example objects for color and color temperature, new for protocol-revision 24.
- Added example objects for color and color temperature, new for protocol-revision 24.
- Added current-command-priority to output objects revision 17 or later.
- Added demo apps ack-alarm, add-list-element, and event (#418)
- Added UTC option to BACnet TimeSync app (#396)
@@ -95,7 +96,7 @@ BACNET_PROTOCOL_REVISION define in bacdef.h
- Added --retry option for repeating Who-Is or I-Am C number of times (#199)
- Added write BDT application (#170)
- Added repeat option to Who-Is and I-Am app (#117)
- Added UTF8 multibyte to wide char printing in ReadProperty and ReadPropertyMultiple
- Added UTF8 multibyte to wide char printing in ReadProperty and ReadPropertyMultiple
apps if supported by the compiler and C library (#106).
- Added IPv6 Foreign Device Registration and IPv6 support for BSD and macOS for apps
- Added example of spawning 100 servers using a BBMD connection.
@@ -106,23 +107,23 @@ apps if supported by the compiler and C library (#106).
### Changed
- Modified example objects to support CreateObject and DeleteObject API for
these objects: file, analog output, binary output, multi-state output, color,
color temperature).
- Unit tests and functional tests have been moved from the source C files
into their own test files under the test folder in a src/ mirrored folder
structure under test/. 
- The testing framework was moved from ctest to ztest, using CMake, CTest, and LCOV. 
It's now possible to visually view code coverage from the testing of each file
in the library. The tests are run in continuous integration.  Adding new tests
can be done by as copying an existing folder under test/ as a starting point, and
adding the new test folder name into the CMakeLists.txt under test/ folder, or
- Modified example objects to support CreateObject and DeleteObject API for
these objects: file, analog output, binary output, multi-state output, color,
color temperature).
- Unit tests and functional tests have been moved from the source C files
into their own test files under the test folder in a src/ mirrored folder
structure under test/. 
- The testing framework was moved from ctest to ztest, using CMake, CTest, and LCOV. 
It's now possible to visually view code coverage from the testing of each file
in the library. The tests are run in continuous integration.  Adding new tests
can be done by as copying an existing folder under test/ as a starting point, and
adding the new test folder name into the CMakeLists.txt under test/ folder, or
editing the existing test C file and extending or fixing the existing test. 
- Most (all?) of the primitive value encoders are now using a snprintf()
style API pattern, where passing NULL in the buffer parameter will
return the length that the buffer would use (i.e. returns the length that the
buffer needs to be).  This makes simple to write the parent encoders to check
the length versus their buffer before attempting the encoding at the expense of
- Most (all?) of the primitive value encoders are now using a snprintf()
style API pattern, where passing NULL in the buffer parameter will
return the length that the buffer would use (i.e. returns the length that the
buffer needs to be).  This makes simple to write the parent encoders to check
the length versus their buffer before attempting the encoding at the expense of
an extra function call to get the length.
- BACnetARRAY property types now have a helper function to use for encoding (see bacnet_array_encode) 
+190 -180
View File
@@ -386,6 +386,7 @@ static void packet_statistics_print(void)
fprintf(stdout, "Node Count: %u\n", node_count);
fprintf(stdout, "Invalid Frame Count: %lu\n",
(long unsigned int)Invalid_Frame_Count);
fflush(stdout);
}
static void packet_statistics_clear(void)
@@ -438,20 +439,20 @@ uint16_t MSTP_Get_Reply(
}
static char Capture_Filename[64] = "mstp_20090123091200.cap";
static FILE *pFile = NULL; /* stream pointer */
static FILE *File_Handle = NULL; /* stream pointer */
#if defined(_WIN32)
static HANDLE hPipe = INVALID_HANDLE_VALUE; /* pipe handle */
static HANDLE Pipe_Handle = INVALID_HANDLE_VALUE; /* pipe handle */
static void named_pipe_create(char *pipe_name)
{
if (!Wireshark_Capture) {
fprintf(stdout, "mstpcap: Creating Named Pipe \"%s\"\n", pipe_name);
}
/* create the pipe */
while (hPipe == INVALID_HANDLE_VALUE) {
while (Pipe_Handle == INVALID_HANDLE_VALUE) {
/* use CreateFile rather than CreateNamedPipe */
hPipe = CreateFile(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
Pipe_Handle = CreateFile(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
if (hPipe != INVALID_HANDLE_VALUE) {
if (Pipe_Handle != INVALID_HANDLE_VALUE) {
break;
}
/* if an error occured at handle creation */
@@ -463,36 +464,48 @@ static void named_pipe_create(char *pipe_name)
return;
}
}
ConnectNamedPipe(hPipe, NULL);
ConnectNamedPipe(Pipe_Handle, NULL);
}
static size_t data_write(const void *ptr, size_t size, size_t nitems)
{
size_t written = 0;
DWORD cbWritten = 0;
if (hPipe != INVALID_HANDLE_VALUE) {
(void)WriteFile(hPipe, /* handle to pipe */
if (Pipe_Handle != INVALID_HANDLE_VALUE) {
(void)WriteFile(Pipe_Handle, /* handle to pipe */
ptr, /* buffer to write from */
size * nitems, /* number of bytes to write */
&cbWritten, /* number of bytes written */
NULL); /* not overlapped I/O */
written = cbWritten;
}
return fwrite(ptr, size, nitems, pFile);
if (File_Handle) {
written = fwrite(ptr, size, nitems, File_Handle);
}
return written;
}
static size_t data_write_header(
const void *ptr, size_t size, size_t nitems, bool pipe_enable)
const void *ptr, size_t size, size_t nitems)
{
size_t written = 0;
DWORD cbWritten = 0;
if (pipe_enable && (hPipe != INVALID_HANDLE_VALUE)) {
(void)WriteFile(hPipe, /* handle to pipe */
if (Pipe_Handle != INVALID_HANDLE_VALUE) {
(void)WriteFile(Pipe_Handle, /* handle to pipe */
ptr, /* buffer to write from */
size * nitems, /* number of bytes to write */
&cbWritten, /* number of bytes written */
NULL); /* not overlapped I/O */
written = cbWritten;
}
if (File_Handle) {
written = fwrite(ptr, size, nitems, File_Handle);
}
return fwrite(ptr, size, nitems, pFile);
return written;
}
#else
static int FD_Pipe = -1;
@@ -513,43 +526,64 @@ static void named_pipe_create(char *name)
static size_t data_write(const void *ptr, size_t size, size_t nitems)
{
ssize_t bytes = 0;
ssize_t written = 0;
if (FD_Pipe != -1) {
bytes = write(FD_Pipe, ptr, size * nitems);
(void)bytes;
written = write(FD_Pipe, ptr, size * nitems);
}
return fwrite(ptr, size, nitems, pFile);
if (File_Handle) {
written = fwrite(ptr, size, nitems, File_Handle);
}
return written;
}
static size_t data_write_header(
const void *ptr, size_t size, size_t nitems, bool pipe_enable)
const void *ptr, size_t size, size_t nitems)
{
ssize_t bytes = 0;
if (pipe_enable && (FD_Pipe != -1)) {
bytes = write(FD_Pipe, ptr, size * nitems);
(void)bytes;
ssize_t written = 0;
if (FD_Pipe != -1) {
written = write(FD_Pipe, ptr, size * nitems);
}
return fwrite(ptr, size, nitems, pFile);
if (File_Handle) {
written = fwrite(ptr, size, nitems, File_Handle);
}
return written;
}
#endif
static void filename_create(char *filename)
static void filename_create_new(void)
{
BACNET_DATE bdate;
BACNET_TIME btime;
char *filename = &Capture_Filename[0];
size_t filename_size = sizeof(Capture_Filename);
if (filename) {
datetime_local(&bdate, &btime, NULL, NULL);
sprintf(filename, "mstp_%04d%02d%02d%02d%02d%02d.cap", (int)bdate.year,
(int)bdate.month, (int)bdate.day, (int)btime.hour, (int)btime.min,
(int)btime.sec);
if (Wireshark_Capture) {
return;
}
if (File_Handle) {
fclose(File_Handle);
}
File_Handle = NULL;
datetime_local(&bdate, &btime, NULL, NULL);
snprintf(filename, filename_size, "mstp_%04d%02d%02d%02d%02d%02d.cap",
(int)bdate.year, (int)bdate.month, (int)bdate.day, (int)btime.hour,
(int)btime.min, (int)btime.sec);
File_Handle = fopen(filename, "wb");
if (File_Handle) {
fprintf(stdout, "mstpcap: saving capture to %s\n", filename);
} else {
fprintf(stderr, "mstpcap: failed to open %s: %s\n", filename,
strerror(errno));
}
}
/* write packet to file in libpcap format */
static void write_global_header(const char *filename)
static void write_global_header(void)
{
static bool pipe_enable = true; /* don't write more than one header */
uint32_t magic_number = 0xa1b2c3d4; /* magic number */
uint16_t version_major = 2; /* major version number */
uint16_t version_minor = 4; /* minor version number */
@@ -559,29 +593,17 @@ static void write_global_header(const char *filename)
uint32_t network = DLT_BACNET_MS_TP; /* data link type - BACNET_MS_TP */
/* create a new file. */
pFile = fopen(filename, "wb");
if (pFile) {
(void)data_write_header(
&magic_number, sizeof(magic_number), 1, pipe_enable);
(void)data_write_header(
&version_major, sizeof(version_major), 1, pipe_enable);
(void)data_write_header(
&version_minor, sizeof(version_minor), 1, pipe_enable);
(void)data_write_header(&thiszone, sizeof(thiszone), 1, pipe_enable);
(void)data_write_header(&sigfigs, sizeof(sigfigs), 1, pipe_enable);
(void)data_write_header(&snaplen, sizeof(snaplen), 1, pipe_enable);
(void)data_write_header(&network, sizeof(network), 1, pipe_enable);
fflush(pFile);
if (!Wireshark_Capture) {
fprintf(stdout, "mstpcap: saving capture to %s\n", filename);
}
} else {
fprintf(stderr, "mstpcap[header]: failed to open %s: %s\n", filename,
strerror(errno));
}
if (pipe_enable) {
pipe_enable = false;
}
(void)data_write_header(
&magic_number, sizeof(magic_number), 1);
(void)data_write_header(
&version_major, sizeof(version_major), 1);
(void)data_write_header(
&version_minor, sizeof(version_minor), 1);
(void)data_write_header(&thiszone, sizeof(thiszone), 1);
(void)data_write_header(&sigfigs, sizeof(sigfigs), 1);
(void)data_write_header(&snaplen, sizeof(snaplen), 1);
(void)data_write_header(&network, sizeof(network), 1);
fflush(File_Handle);
}
static void write_received_packet(
@@ -596,66 +618,61 @@ static void write_received_packet(
struct timeval tv;
size_t max_data = 0;
if (pFile) {
gettimeofday(&tv, NULL);
ts_sec = tv.tv_sec;
ts_usec = tv.tv_usec;
if ((mstp_port->ReceivedValidFrame) ||
(mstp_port->ReceivedValidFrameNotForUs)) {
packet_statistics(&tv, mstp_port);
}
(void)data_write(&ts_sec, sizeof(ts_sec), 1);
(void)data_write(&ts_usec, sizeof(ts_usec), 1);
if (mstp_port->ReceivedInvalidFrame) {
if (mstp_port->Index) {
max_data = min(mstp_port->InputBufferSize, mstp_port->Index);
if ((mstp_port->DataLength > 0) &&
(mstp_port->Index == (mstp_port->DataLength + 1))) {
/* case where index is not incremented for CRC2,
so only 1 for checksum */
data_crc_len = 1;
}
incl_len = orig_len = header_len + max_data + data_crc_len;
} else {
/* header only */
incl_len = orig_len = header_len;
gettimeofday(&tv, NULL);
ts_sec = tv.tv_sec;
ts_usec = tv.tv_usec;
if ((mstp_port->ReceivedValidFrame) ||
(mstp_port->ReceivedValidFrameNotForUs)) {
packet_statistics(&tv, mstp_port);
}
(void)data_write(&ts_sec, sizeof(ts_sec), 1);
(void)data_write(&ts_usec, sizeof(ts_usec), 1);
if (mstp_port->ReceivedInvalidFrame) {
if (mstp_port->Index) {
max_data = min(mstp_port->InputBufferSize, mstp_port->Index);
if ((mstp_port->DataLength > 0) &&
(mstp_port->Index == (mstp_port->DataLength + 1))) {
/* case where index is not incremented for CRC2,
so only 1 for checksum */
data_crc_len = 1;
}
incl_len = orig_len = header_len + max_data + data_crc_len;
} else {
if (mstp_port->DataLength) {
max_data =
min(mstp_port->InputBufferSize, mstp_port->DataLength);
incl_len = orig_len = header_len + max_data + data_crc_len;
} else {
/* header only - or at least some bytes of the header */
incl_len = orig_len = header_len;
}
}
(void)data_write(&incl_len, sizeof(incl_len), 1);
(void)data_write(&orig_len, sizeof(orig_len), 1);
if (header_len == 1) {
header[0] = mstp_port->DataRegister;
} else if (header_len == 2) {
header[0] = 0x55;
header[1] = mstp_port->DataRegister;
} else {
header[0] = 0x55;
header[1] = 0xFF;
header[2] = mstp_port->FrameType;
header[3] = mstp_port->DestinationAddress;
header[4] = mstp_port->SourceAddress;
header[5] = HI_BYTE(mstp_port->DataLength);
header[6] = LO_BYTE(mstp_port->DataLength);
header[7] = mstp_port->HeaderCRCActual;
}
(void)data_write(header, header_len, 1);
if (max_data) {
(void)data_write(mstp_port->InputBuffer, max_data, 1);
(void)data_write((char *)&mstp_port->DataCRCActualMSB, 1, 1);
(void)data_write((char *)&mstp_port->DataCRCActualLSB, 1, 1);
/* header only */
incl_len = orig_len = header_len;
}
} else {
fprintf(stderr, "mstpcap[packet]: failed to open %s: %s\n",
Capture_Filename, strerror(errno));
if (mstp_port->DataLength) {
max_data =
min(mstp_port->InputBufferSize, mstp_port->DataLength);
incl_len = orig_len = header_len + max_data + data_crc_len;
} else {
/* header only - or at least some bytes of the header */
incl_len = orig_len = header_len;
}
}
(void)data_write(&incl_len, sizeof(incl_len), 1);
(void)data_write(&orig_len, sizeof(orig_len), 1);
if (header_len == 1) {
header[0] = mstp_port->DataRegister;
} else if (header_len == 2) {
header[0] = 0x55;
header[1] = mstp_port->DataRegister;
} else {
header[0] = 0x55;
header[1] = 0xFF;
header[2] = mstp_port->FrameType;
header[3] = mstp_port->DestinationAddress;
header[4] = mstp_port->SourceAddress;
header[5] = HI_BYTE(mstp_port->DataLength);
header[6] = LO_BYTE(mstp_port->DataLength);
header[7] = mstp_port->HeaderCRCActual;
}
(void)data_write(header, header_len, 1);
if (max_data) {
(void)data_write(mstp_port->InputBuffer, max_data, 1);
(void)data_write((char *)&mstp_port->DataCRCActualMSB, 1, 1);
(void)data_write((char *)&mstp_port->DataCRCActualLSB, 1, 1);
}
}
@@ -672,55 +689,55 @@ static bool test_global_header(const char *filename)
size_t count = 0;
/* open existing file. */
pFile = fopen(filename, "rb");
if (pFile) {
count = fread(&magic_number, sizeof(magic_number), 1, pFile);
File_Handle = fopen(filename, "rb");
if (File_Handle) {
count = fread(&magic_number, sizeof(magic_number), 1, File_Handle);
if ((count != 1) || (magic_number != 0xa1b2c3d4)) {
fprintf(stderr, "mstpcap: invalid magic number\n");
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread(&version_major, sizeof(version_major), 1, pFile);
count = fread(&version_major, sizeof(version_major), 1, File_Handle);
if ((count != 1) || (version_major != 2)) {
fprintf(stderr, "mstpcap: invalid major version\n");
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread(&version_minor, sizeof(version_minor), 1, pFile);
count = fread(&version_minor, sizeof(version_minor), 1, File_Handle);
if ((count != 1) || (version_minor != 4)) {
fprintf(stderr, "mstpcap: invalid minor version\n");
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread(&thiszone, sizeof(thiszone), 1, pFile);
count = fread(&thiszone, sizeof(thiszone), 1, File_Handle);
if ((count != 1) || (thiszone != 0)) {
fprintf(stderr, "mstpcap: invalid time zone\n");
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread(&sigfigs, sizeof(sigfigs), 1, pFile);
count = fread(&sigfigs, sizeof(sigfigs), 1, File_Handle);
if ((count != 1) || (sigfigs != 0)) {
fprintf(stderr, "mstpcap: invalid time stamp accuracy\n");
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread(&snaplen, sizeof(snaplen), 1, pFile);
count = fread(&snaplen, sizeof(snaplen), 1, File_Handle);
if (count != 1) {
fprintf(stderr, "mstpcap: unable to read SNAP length\n");
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread(&network, sizeof(network), 1, pFile);
count = fread(&network, sizeof(network), 1, File_Handle);
if ((count != 1) || (network != DLT_BACNET_MS_TP)) {
fprintf(stderr, "mstpcap: invalid data link type (DLT)\n");
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
} else {
@@ -743,37 +760,37 @@ static bool read_received_packet(volatile struct mstp_port_struct_t *mstp_port)
size_t count = 0;
unsigned i = 0;
if (pFile) {
count = fread(&ts_sec, sizeof(ts_sec), 1, pFile);
if (File_Handle) {
count = fread(&ts_sec, sizeof(ts_sec), 1, File_Handle);
if (count != 1) {
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread(&ts_usec, sizeof(ts_usec), 1, pFile);
count = fread(&ts_usec, sizeof(ts_usec), 1, File_Handle);
if (count != 1) {
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
tv.tv_sec = ts_sec;
tv.tv_usec = ts_usec;
count = fread(&incl_len, sizeof(incl_len), 1, pFile);
count = fread(&incl_len, sizeof(incl_len), 1, File_Handle);
if (count != 1) {
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread(&orig_len, sizeof(orig_len), 1, pFile);
count = fread(&orig_len, sizeof(orig_len), 1, File_Handle);
if (count != 1) {
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread(&header, sizeof(header), 1, pFile);
count = fread(&header, sizeof(header), 1, File_Handle);
if (count != 1) {
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
mstp_port->FrameType = header[2];
@@ -801,22 +818,22 @@ static bool read_received_packet(volatile struct mstp_port_struct_t *mstp_port)
/* packet includes data */
mstp_port->DataLength = orig_len - 8 - 2;
count =
fread(mstp_port->InputBuffer, mstp_port->DataLength, 1, pFile);
fread(mstp_port->InputBuffer, mstp_port->DataLength, 1, File_Handle);
if (count != 1) {
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread((char *)&mstp_port->DataCRCActualMSB, 1, 1, pFile);
count = fread((char *)&mstp_port->DataCRCActualMSB, 1, 1, File_Handle);
if (count != 1) {
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
count = fread((char *)&mstp_port->DataCRCActualLSB, 1, 1, pFile);
count = fread((char *)&mstp_port->DataCRCActualLSB, 1, 1, File_Handle);
if (count != 1) {
fclose(pFile);
pFile = NULL;
fclose(File_Handle);
File_Handle = NULL;
return false;
}
mstp_port->DataCRC = 0xFFFF;
@@ -858,11 +875,11 @@ static void cleanup(void)
if (!Wireshark_Capture) {
packet_statistics_print();
}
if (pFile) {
fflush(pFile); /* stream pointer */
fclose(pFile); /* stream pointer */
if (File_Handle) {
fflush(File_Handle); /* stream pointer */
fclose(File_Handle); /* stream pointer */
}
pFile = NULL;
File_Handle = NULL;
}
#if defined(_WIN32)
@@ -870,11 +887,11 @@ static BOOL WINAPI CtrlCHandler(DWORD dwCtrlType)
{
dwCtrlType = dwCtrlType;
if (hPipe != INVALID_HANDLE_VALUE) {
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
hPipe = INVALID_HANDLE_VALUE;
if (Pipe_Handle != INVALID_HANDLE_VALUE) {
FlushFileBuffers(Pipe_Handle);
DisconnectNamedPipe(Pipe_Handle);
CloseHandle(Pipe_Handle);
Pipe_Handle = INVALID_HANDLE_VALUE;
}
/* signal to main loop to exit */
Exit_Requested = true;
@@ -904,16 +921,6 @@ static void signal_init(void)
}
#endif
static void filename_create_new(void)
{
if (pFile) {
fclose(pFile);
}
pFile = NULL;
filename_create(&Capture_Filename[0]);
write_global_header(&Capture_Filename[0]);
}
static void print_usage(char *filename)
{
printf("Usage: %s", filename);
@@ -931,9 +938,9 @@ static void print_help(char *filename)
filename);
printf("\n");
printf("Captures MS/TP packets from a serial interface\n"
"and saves them to a file. Saves packets in a\n"
"filename mstp_20090123091200.cap that has data and time.\n"
"After receiving 65535 packets, a new file is created.\n");
"and writes them to a file or a pipe, or scans a file for stats."
"Filename is of the form mstp_20090123091200.cap (timestamp).\n"
"New files are created after receiving 65535 packets.\n");
printf("\n");
printf("Command line options:\n"
"[--extcap-interface port] - serial interface.\n"
@@ -1144,6 +1151,7 @@ int main(int argc, char *argv[])
signal_init();
#endif
filename_create_new();
write_global_header();
/* run forever */
for (;;) {
RS485_Check_UART_Data(mstp_port);
@@ -1196,11 +1204,13 @@ int main(int argc, char *argv[])
if (!(packet_count % 100)) {
fprintf(stdout, "\r%u packets, %u invalid frames",
(unsigned)packet_count, (unsigned)Invalid_Frame_Count);
fflush(stdout);
}
if (packet_count >= 65535) {
packet_statistics_print();
packet_statistics_clear();
filename_create_new();
write_global_header();
packet_count = 0;
}
}