forked from osmocom/wireshark
text2pcap: Support parsing of iso-8601 dates
This commit is contained in:
parent
76ff47152b
commit
a0173cd7cf
|
@ -75,11 +75,15 @@ a hex number longer than two characters. Any text after the bytes is
|
||||||
ignored (e.g. the character dump). Any hex numbers in this text are
|
ignored (e.g. the character dump). Any hex numbers in this text are
|
||||||
also ignored. An offset of zero is indicative of starting a new
|
also ignored. An offset of zero is indicative of starting a new
|
||||||
packet, so a single text file with a series of hexdumps can be
|
packet, so a single text file with a series of hexdumps can be
|
||||||
converted into a packet capture with multiple packets. Packets may be
|
converted into a packet capture with multiple packets.
|
||||||
preceded by a timestamp. These are interpreted according to the format
|
|
||||||
given on the command line (see *-t*). If not, the first packet
|
Packets may be preceded by a direction indicator and a timestamp if
|
||||||
is timestamped with the current time the conversion takes place. Multiple
|
indicated by the command line (see *-D* and *-t*). The format of the
|
||||||
packets are written with timestamps differing by one microsecond each.
|
timestamps is specified as a mandatory parameter to *-t*. If timestamp
|
||||||
|
parsing is not enabled or failed, the first packet is timestamped
|
||||||
|
with the current time the conversion takes place. Multiple packets
|
||||||
|
are written with timestamps differing by one microsecond each.
|
||||||
|
|
||||||
In general, short of these restrictions, *text2pcap* is pretty liberal
|
In general, short of these restrictions, *text2pcap* is pretty liberal
|
||||||
about reading in hexdumps and has been tested with a variety of
|
about reading in hexdumps and has been tested with a variety of
|
||||||
mangled outputs (including being forwarded through email multiple
|
mangled outputs (including being forwarded through email multiple
|
||||||
|
@ -122,7 +126,7 @@ multiple times to generate more debugging information.
|
||||||
-D::
|
-D::
|
||||||
+
|
+
|
||||||
--
|
--
|
||||||
The text before the packet starts either with an I or O indicating that
|
The text before the packet may start either with an I or O indicating that
|
||||||
the packet is inbound or outbound. This is used when generating dummy headers.
|
the packet is inbound or outbound. This is used when generating dummy headers.
|
||||||
The indication is only stored if the output format is pcapng.
|
The indication is only stored if the output format is pcapng.
|
||||||
--
|
--
|
||||||
|
@ -239,8 +243,10 @@ into the SCTP header.
|
||||||
+
|
+
|
||||||
--
|
--
|
||||||
Treats the text before the packet as a date/time code; __timefmt__ is a
|
Treats the text before the packet as a date/time code; __timefmt__ is a
|
||||||
format string of the sort supported by strptime(3).
|
format string of the sort supported by strftime(3).
|
||||||
Example: The time "10:15:14.5476" has the format code "%H:%M:%S."
|
Example: The time "10:15:14.5476" has the format code "%H:%M:%S."
|
||||||
|
The special format string __ISO__ indicates that the string should be
|
||||||
|
parsed according to the ISO-8601 specification.
|
||||||
|
|
||||||
*NOTE:* The subsecond component delimiter must be specified (.) but no
|
*NOTE:* The subsecond component delimiter must be specified (.) but no
|
||||||
pattern is required; the remaining number is assumed to be fractions of
|
pattern is required; the remaining number is assumed to be fractions of
|
||||||
|
@ -300,7 +306,7 @@ use fe80::202:b3ff:fe1e:8329 and 2001:0db8:85a3::8a2e:0370:7334 for all IP packe
|
||||||
== SEE ALSO
|
== SEE ALSO
|
||||||
|
|
||||||
od(1), xref:https://www.tcpdump.org/manpages/pcap.3pcap.html[pcap](3), xref:wireshark.html[wireshark](1), xref:tshark.html[tshark](1), xref:dumpcap.html[dumpcap](1), xref:mergecap.html[mergecap](1),
|
od(1), xref:https://www.tcpdump.org/manpages/pcap.3pcap.html[pcap](3), xref:wireshark.html[wireshark](1), xref:tshark.html[tshark](1), xref:dumpcap.html[dumpcap](1), xref:mergecap.html[mergecap](1),
|
||||||
xref:editcap.html[editcap](1), strptime(3), xref:https://www.tcpdump.org/manpages/pcap-filter.7.html[pcap-filter](7) or xref:https://www.tcpdump.org/manpages/tcpdump.1.html[tcpdump](8)
|
xref:editcap.html[editcap](1), strftime(3), xref:https://www.tcpdump.org/manpages/pcap-filter.7.html[pcap-filter](7) or xref:https://www.tcpdump.org/manpages/tcpdump.1.html[tcpdump](8)
|
||||||
|
|
||||||
== NOTES
|
== NOTES
|
||||||
|
|
||||||
|
|
114
text2pcap.c
114
text2pcap.c
|
@ -104,6 +104,7 @@
|
||||||
#include <ui/version_info.h>
|
#include <ui/version_info.h>
|
||||||
#include <wsutil/inet_addr.h>
|
#include <wsutil/inet_addr.h>
|
||||||
#include <wsutil/wslog.h>
|
#include <wsutil/wslog.h>
|
||||||
|
#include <wsutil/nstime.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <io.h> /* for _setmode */
|
#include <io.h> /* for _setmode */
|
||||||
|
@ -205,7 +206,7 @@ static int start_new_packet(gboolean);
|
||||||
|
|
||||||
/* This buffer contains strings present before the packet offset 0 */
|
/* This buffer contains strings present before the packet offset 0 */
|
||||||
#define PACKET_PREAMBLE_MAX_LEN 2048
|
#define PACKET_PREAMBLE_MAX_LEN 2048
|
||||||
static guint8 packet_preamble[PACKET_PREAMBLE_MAX_LEN+1];
|
static char packet_preamble[PACKET_PREAMBLE_MAX_LEN+1];
|
||||||
static int packet_preamble_len = 0;
|
static int packet_preamble_len = 0;
|
||||||
|
|
||||||
/* Number of packets read and written */
|
/* Number of packets read and written */
|
||||||
|
@ -217,6 +218,7 @@ static guint64 bytes_written = 0;
|
||||||
static time_t ts_sec = 0;
|
static time_t ts_sec = 0;
|
||||||
static guint32 ts_nsec = 0;
|
static guint32 ts_nsec = 0;
|
||||||
static char *ts_fmt = NULL;
|
static char *ts_fmt = NULL;
|
||||||
|
static int ts_fmt_iso = 0;
|
||||||
static struct tm timecode_default;
|
static struct tm timecode_default;
|
||||||
|
|
||||||
static guint8* pkt_lnstart;
|
static guint8* pkt_lnstart;
|
||||||
|
@ -953,9 +955,6 @@ static void
|
||||||
parse_preamble (void)
|
parse_preamble (void)
|
||||||
{
|
{
|
||||||
struct tm timecode;
|
struct tm timecode;
|
||||||
char *subsecs;
|
|
||||||
char *p;
|
|
||||||
int subseclen;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1015,56 +1014,71 @@ parse_preamble (void)
|
||||||
* This should cover line breaks etc that get counted.
|
* This should cover line breaks etc that get counted.
|
||||||
*/
|
*/
|
||||||
if (strlen(packet_preamble) > 2) {
|
if (strlen(packet_preamble) > 2) {
|
||||||
/* Get Time leaving subseconds */
|
if (ts_fmt_iso) {
|
||||||
subsecs = strptime( packet_preamble, ts_fmt, &timecode );
|
nstime_t ts_iso;
|
||||||
if (subsecs != NULL) {
|
if (0 < iso8601_to_nstime(&ts_iso, packet_preamble, ISO8601_DATETIME_AUTO)) {
|
||||||
/* Get the long time from the tm structure */
|
ts_sec = ts_iso.secs;
|
||||||
/* (will return -1 if failure) */
|
ts_nsec = ts_iso.nsecs;
|
||||||
ts_sec = mktime( &timecode );
|
} else {
|
||||||
} else
|
ts_sec = 0; /* Jan 1,1970: 00:00 GMT; tshark/wireshark will display date/time as adjusted by timezone */
|
||||||
ts_sec = -1; /* we failed to parse it */
|
ts_nsec = 0;
|
||||||
|
|
||||||
/* This will ensure incorrectly parsed dates get set to zero */
|
|
||||||
if (-1 == ts_sec) {
|
|
||||||
/* Sanitize - remove all '\r' */
|
|
||||||
char *c;
|
|
||||||
while ((c = strchr(packet_preamble, '\r')) != NULL) *c=' ';
|
|
||||||
fprintf (stderr, "Failure processing time \"%s\" using time format \"%s\"\n (defaulting to Jan 1,1970 00:00:00 GMT)\n",
|
|
||||||
packet_preamble, ts_fmt);
|
|
||||||
if (debug >= 2) {
|
|
||||||
fprintf(stderr, "timecode: %02d/%02d/%d %02d:%02d:%02d %d\n",
|
|
||||||
timecode.tm_mday, timecode.tm_mon, timecode.tm_year,
|
|
||||||
timecode.tm_hour, timecode.tm_min, timecode.tm_sec, timecode.tm_isdst);
|
|
||||||
}
|
}
|
||||||
ts_sec = 0; /* Jan 1,1970: 00:00 GMT; tshark/wireshark will display date/time as adjusted by timezone */
|
|
||||||
ts_nsec = 0;
|
|
||||||
} else {
|
} else {
|
||||||
/* Parse subseconds */
|
char *subsecs;
|
||||||
ts_nsec = (guint32)strtol(subsecs, &p, 10);
|
char *p;
|
||||||
if (subsecs == p) {
|
int subseclen;
|
||||||
/* Error */
|
|
||||||
|
/* Get Time leaving subseconds */
|
||||||
|
subsecs = strptime( packet_preamble, ts_fmt, &timecode );
|
||||||
|
if (subsecs != NULL) {
|
||||||
|
/* Get the long time from the tm structure */
|
||||||
|
/* (will return -1 if failure) */
|
||||||
|
ts_sec = mktime( &timecode );
|
||||||
|
} else
|
||||||
|
ts_sec = -1; /* we failed to parse it */
|
||||||
|
|
||||||
|
/* This will ensure incorrectly parsed dates get set to zero */
|
||||||
|
if (-1 == ts_sec) {
|
||||||
|
/* Sanitize - remove all '\r' */
|
||||||
|
char *c;
|
||||||
|
while ((c = strchr(packet_preamble, '\r')) != NULL) *c=' ';
|
||||||
|
fprintf (stderr, "Failure processing time \"%s\" using time format \"%s\"\n (defaulting to Jan 1,1970 00:00:00 GMT)\n",
|
||||||
|
packet_preamble, ts_fmt);
|
||||||
|
if (debug >= 2) {
|
||||||
|
fprintf(stderr, "timecode: %02d/%02d/%d %02d:%02d:%02d %d\n",
|
||||||
|
timecode.tm_mday, timecode.tm_mon, timecode.tm_year,
|
||||||
|
timecode.tm_hour, timecode.tm_min, timecode.tm_sec, timecode.tm_isdst);
|
||||||
|
}
|
||||||
|
ts_sec = 0; /* Jan 1,1970: 00:00 GMT; tshark/wireshark will display date/time as adjusted by timezone */
|
||||||
ts_nsec = 0;
|
ts_nsec = 0;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/* Parse subseconds */
|
||||||
* Convert that number to a number
|
ts_nsec = (guint32)strtol(subsecs, &p, 10);
|
||||||
* of nanoseconds; if it's N digits
|
if (subsecs == p) {
|
||||||
* long, it's in units of 10^(-N) seconds,
|
/* Error */
|
||||||
* so, to convert it to units of
|
ts_nsec = 0;
|
||||||
* 10^-9 seconds, we multiply by
|
} else {
|
||||||
* 10^(9-N).
|
|
||||||
*/
|
|
||||||
subseclen = (int) (p - subsecs);
|
|
||||||
if (subseclen > 9) {
|
|
||||||
/*
|
/*
|
||||||
* *More* than 9 digits; 9-N is
|
* Convert that number to a number
|
||||||
* negative, so we divide by
|
* of nanoseconds; if it's N digits
|
||||||
* 10^(N-9).
|
* long, it's in units of 10^(-N) seconds,
|
||||||
|
* so, to convert it to units of
|
||||||
|
* 10^-9 seconds, we multiply by
|
||||||
|
* 10^(9-N).
|
||||||
*/
|
*/
|
||||||
for (i = subseclen - 9; i != 0; i--)
|
subseclen = (int) (p - subsecs);
|
||||||
ts_nsec /= 10;
|
if (subseclen > 9) {
|
||||||
} else if (subseclen < 9) {
|
/*
|
||||||
for (i = 9 - subseclen; i != 0; i--)
|
* *More* than 9 digits; 9-N is
|
||||||
ts_nsec *= 10;
|
* negative, so we divide by
|
||||||
|
* 10^(N-9).
|
||||||
|
*/
|
||||||
|
for (i = subseclen - 9; i != 0; i--)
|
||||||
|
ts_nsec /= 10;
|
||||||
|
} else if (subseclen < 9) {
|
||||||
|
for (i = 9 - subseclen; i != 0; i--)
|
||||||
|
ts_nsec *= 10;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1587,6 +1601,8 @@ parse_options (int argc, char *argv[])
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
ts_fmt = ws_optarg;
|
ts_fmt = ws_optarg;
|
||||||
|
if (!strcmp(ws_optarg, "ISO"))
|
||||||
|
ts_fmt_iso = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'u':
|
case 'u':
|
||||||
|
@ -1794,7 +1810,7 @@ parse_options (int argc, char *argv[])
|
||||||
* on Windows, it won't work if ts_sec is before the Epoch,
|
* on Windows, it won't work if ts_sec is before the Epoch,
|
||||||
* but it's long after 1970, so....
|
* but it's long after 1970, so....
|
||||||
*/
|
*/
|
||||||
fprintf(stderr, "localtime(right now) failed\n");
|
fprintf(stderr, "localtime (right now) failed\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
timecode_default = *now_tm;
|
timecode_default = *now_tm;
|
||||||
|
|
Loading…
Reference in New Issue