forked from osmocom/wireshark
text2pcap: Support parsing of iso-8601 dates
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
|
||||
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
|
||||
converted into a packet capture with multiple packets. Packets may be
|
||||
preceded by a timestamp. These are interpreted according to the format
|
||||
given on the command line (see *-t*). If not, the first packet
|
||||
is timestamped with the current time the conversion takes place. Multiple
|
||||
packets are written with timestamps differing by one microsecond each.
|
||||
converted into a packet capture with multiple packets.
|
||||
|
||||
Packets may be preceded by a direction indicator and a timestamp if
|
||||
indicated by the command line (see *-D* and *-t*). The format of the
|
||||
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
|
||||
about reading in hexdumps and has been tested with a variety of
|
||||
mangled outputs (including being forwarded through email multiple
|
||||
|
@ -122,7 +126,7 @@ multiple times to generate more debugging information.
|
|||
-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 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
|
||||
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."
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
|
114
text2pcap.c
114
text2pcap.c
|
@ -104,6 +104,7 @@
|
|||
#include <ui/version_info.h>
|
||||
#include <wsutil/inet_addr.h>
|
||||
#include <wsutil/wslog.h>
|
||||
#include <wsutil/nstime.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#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 */
|
||||
#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;
|
||||
|
||||
/* Number of packets read and written */
|
||||
|
@ -217,6 +218,7 @@ static guint64 bytes_written = 0;
|
|||
static time_t ts_sec = 0;
|
||||
static guint32 ts_nsec = 0;
|
||||
static char *ts_fmt = NULL;
|
||||
static int ts_fmt_iso = 0;
|
||||
static struct tm timecode_default;
|
||||
|
||||
static guint8* pkt_lnstart;
|
||||
|
@ -953,9 +955,6 @@ static void
|
|||
parse_preamble (void)
|
||||
{
|
||||
struct tm timecode;
|
||||
char *subsecs;
|
||||
char *p;
|
||||
int subseclen;
|
||||
int i;
|
||||
|
||||
/*
|
||||
|
@ -1015,56 +1014,71 @@ parse_preamble (void)
|
|||
* This should cover line breaks etc that get counted.
|
||||
*/
|
||||
if (strlen(packet_preamble) > 2) {
|
||||
/* 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);
|
||||
if (ts_fmt_iso) {
|
||||
nstime_t ts_iso;
|
||||
if (0 < iso8601_to_nstime(&ts_iso, packet_preamble, ISO8601_DATETIME_AUTO)) {
|
||||
ts_sec = ts_iso.secs;
|
||||
ts_nsec = ts_iso.nsecs;
|
||||
} else {
|
||||
ts_sec = 0; /* Jan 1,1970: 00:00 GMT; tshark/wireshark will display date/time as adjusted by timezone */
|
||||
ts_nsec = 0;
|
||||
}
|
||||
ts_sec = 0; /* Jan 1,1970: 00:00 GMT; tshark/wireshark will display date/time as adjusted by timezone */
|
||||
ts_nsec = 0;
|
||||
} else {
|
||||
/* Parse subseconds */
|
||||
ts_nsec = (guint32)strtol(subsecs, &p, 10);
|
||||
if (subsecs == p) {
|
||||
/* Error */
|
||||
char *subsecs;
|
||||
char *p;
|
||||
int subseclen;
|
||||
|
||||
/* 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;
|
||||
} else {
|
||||
/*
|
||||
* Convert that number to a number
|
||||
* of nanoseconds; if it's N digits
|
||||
* 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).
|
||||
*/
|
||||
subseclen = (int) (p - subsecs);
|
||||
if (subseclen > 9) {
|
||||
/* Parse subseconds */
|
||||
ts_nsec = (guint32)strtol(subsecs, &p, 10);
|
||||
if (subsecs == p) {
|
||||
/* Error */
|
||||
ts_nsec = 0;
|
||||
} else {
|
||||
/*
|
||||
* *More* than 9 digits; 9-N is
|
||||
* negative, so we divide by
|
||||
* 10^(N-9).
|
||||
* Convert that number to a number
|
||||
* of nanoseconds; if it's N digits
|
||||
* 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--)
|
||||
ts_nsec /= 10;
|
||||
} else if (subseclen < 9) {
|
||||
for (i = 9 - subseclen; i != 0; i--)
|
||||
ts_nsec *= 10;
|
||||
subseclen = (int) (p - subsecs);
|
||||
if (subseclen > 9) {
|
||||
/*
|
||||
* *More* than 9 digits; 9-N is
|
||||
* 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':
|
||||
ts_fmt = ws_optarg;
|
||||
if (!strcmp(ws_optarg, "ISO"))
|
||||
ts_fmt_iso = 1;
|
||||
break;
|
||||
|
||||
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,
|
||||
* but it's long after 1970, so....
|
||||
*/
|
||||
fprintf(stderr, "localtime(right now) failed\n");
|
||||
fprintf(stderr, "localtime (right now) failed\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
timecode_default = *now_tm;
|
||||
|
|
Loading…
Reference in New Issue