Commit Graph

66 Commits

Author SHA1 Message Date
John Thacker 4cfae8e378 text_import: pcap_link_type -> wtap_encap_type
The encapsulation type that text_import expects and puts
directly into rec.rec_header.packet_header.pkt_encap is a
wiretap encap type, not a pcap link type. Fix the name and
comment appropriately.
2021-12-22 01:00:19 +00:00
John Thacker db10235d68 text_import: Handle SCTP and minimum packet lengths
Correctly handle when a minimum packet length forces fragmentation of
SCTP and we are generating dummy SCTP DATA chunk headers: mark fragmentation
in the chunk flags and set the transmission sequence number and
stream sequence number appropriately.

Port from text2pcap commit f8d48662c8
Part of #16724.
2021-12-18 22:45:02 -05:00
John Thacker f89d536503 text_import: Fix direction detection in Import from Hexdump
If the first character of the preamble indicates direction, it
needs to be skipped over and not tested as part of the timestamp.
2021-12-18 00:49:42 +00:00
John Thacker b4054d3879 text_import: Time delta between packets without timestamp
The "Import from Hex Dump" time delta for packets without a timestamp
was changed to be a nanosecond, but the time resolution for the file
created by import_text_dialog is the default, microseconds. Until
that is configurable, the time tick used needs to be microseconds like
it was before.

Clean up the code so that it's a little more consistent about when
and how the extra time tick is added, namely:
1. If there is no time format passed in.
2. If time format conversion for the packet fails for any reason.

We don't add an extra delta in other situations, e.g. if packets just
happen to have the same valid time value.

Fix #15562.
2021-12-17 13:37:29 +00:00
John Thacker 5f5f03f0e8 text_import: Fix spelling and grammar 2021-12-17 12:55:52 +00:00
John Thacker a74fabf73f text_import: Parse entire timestamp from hex dumps
_parse_time, which uses g_strlcpy, expects that end_field points
to the position after the end of the field (such as the \0.)
text_import_regex handles this correctly, but when importing from
hex dumps the last character of the timestamp was being cut off,
which makes a big difference when fractional seconds are not used.
2021-12-16 00:07:08 +00:00
João Valverde 59c082c046 Add new global header wireshark.h with guideline
Remove ws_diag_control.h from config.h because that was a workaround
for the lack of a public global header. Fix the resultant build errors.
2021-10-22 06:41:44 +00:00
Guy Harris c6717dc6b3 text_import.c: get EXP_PDU_TAG_PROTO_NAME from the header.
Don't hardcode 12, use EXP_PDU_TAG_PROTO_NAME from
wsutil/exported_pdu_tlvs.h.
2021-08-20 14:58:44 -07:00
Guy Harris e8a8fab18c text_import: create a wtap_block_t before calling wtap_block_add_...option.
Those routines can't add an option if there's no block to add it to;
this meant that neither the direction nor the sequence number would be
set when importing a packet.
2021-07-21 00:03:47 -07:00
Guy Harris ef542759d0 text_import: only add the packet flags if we have them.
If we don't know the packet direction, don't bother adding the packet
flags option.

While we're at it, don't bother casting a guint64 to guint64.
2021-07-20 14:45:52 -07:00
David Perry dc7089e831 Carry drop count/packet ID/queue ID as options on packet block 2021-07-19 21:25:40 +00:00
David Perry 06ed6930dc Carry EPB flags as an option on the packet block
As requested by [this comment][1] on !2859, move `pack_flags` from a
dedicated field in `wtap_rec` to a block option on the packet block in
`wtap_rec.block`.

[1]: https://gitlab.com/wireshark/wireshark/-/merge_requests/2859#note_615984624
2021-07-12 12:41:57 -04:00
Guy Harris 57a1514ac7 Cast away the return value of g_strlcpy() and g_strlcat().
Most of the time, the return value tells us nothing useful, as we've
already decided that we're perfectly willing to live with string
truncation.  Hopefully this keeps Coverity from whining that those
routines could return an error code (NARRATOR: They don't) and thus that
we're ignoring the possibility of failure (as indicated, we've already
decided that we can live with string truncation, so truncation is *NOT*
a failure).
2021-04-30 03:19:19 -07:00
Guy Harris eb4d68033e Don't cast away upper bits when assigning to a nstime_t's secs field.
The secs field is a time_t, which is not necessarily 32 bits.  If it's
not, casting away the upper bits, by casting to guint32, introduces a
Y2.038K bug.

Either cast to time_t or, if you're assigning a time_t to it, don't
bother with the cast.
2021-04-28 21:31:15 +00:00
Gerald Combs 9222bd77cd Remove unneeded modelines in ui.
Remove the editor modeline blocks from the source files in ui that use 4
space indentation by running

perl -i -p0e 's{ \n+ /[ *\n]+ editor \s+ modelines .* shiftwidth= .* \*/ \s+ } {\n}gsix' $( ag -l shiftwidth=4 $( ag -g '\.(c|cpp|h|m|mm)') )

This gives us one source of indentation truth for these files, and it
*shouldn't* affect anyone since

- These files match the default in our top-level .editorconfig.

- The one notable editor that's likely to be used on these files and
*doesn't* support EditorConfig (Qt Creator) defaults to 4 space
indentation.
2021-04-20 07:43:39 +00:00
Guy Harris 2b9a6ee592 text_import: just suppress the two-initializers warning.
Stick with the simpler "init everything to invalid, and then override
that" mechanism, and just turn off the warning for thse structures.
2021-03-27 14:00:44 -07:00
Guy Harris fd39930f40 text_import: don't initialize array elements twice.
Some compilers warn about it with -Winitializer-overrides, and default
to setting that.
2021-03-27 12:35:01 -07:00
Paul Weiß 537c5f2955 Regex text imoprt: MSVC compiling and updated timestamps
replaced [min ... max] = val initiallizers with a macro expansion
removed __attibute__
updated timestamps to march
2021-03-26 06:44:25 +00:00
Paul Weiß 8c1b29a597 Regex based textfile import
Modularized the parser backend slightly to have the needed hooks
Modified the timestamp format slightly to enable arbitrary postion for
second fractions
Added a regex based seeking parser for textfiles as frontend alternative
to text_import_scanner.l
Regex is using the GLib implementation
Supported frame-data formats are bin, hex, oct and base64
Regex based importing UI
Fixed Meory-leak in ImportTextDialog::exec()
A new tab was added to the text_import ui to accomodate the new fields
Hints are available and styled accordingly
2021-03-26 06:44:25 +00:00
Martin Mathieson a5703f22cb More changes arising from PVS-Studio output.
/opt/SourceCode/wireshark/epan/dissectors/packet-ip.c	1556	err	V547 Expression 'opt == (1 | 0x00)' is always true.
/opt/SourceCode/wireshark/epan/dissectors/packet-ipdc.c	739	warn	V547 Expression 'payload_len < 4' is always false.
/opt/SourceCode/wireshark/ui/text_import.c	1049	err	V547 Expression 'info->offset_type == OFFSET_DEC' is always true.

None of these are actual bugfixes.

Bug: 16335
Change-Id: I6d0d3bb92c70ea625fc8b559e7a2bc5ba4e29e25
Reviewed-on: https://code.wireshark.org/review/37136
Petri-Dish: Martin Mathieson <martin.r.mathieson@googlemail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Martin Mathieson <martin.r.mathieson@googlemail.com>
2020-05-06 08:35:11 +00:00
Jaap Keuter c642c1a0a4 text import: make TCP dest port truly direction dependant
During introduction of proper direction support this line was left over,
causing TCP dest port to remain independant of direction. This change
simply drops the line.
See CID 1444115

Change-Id: I4ff362925e422bc57cfa3842127ddaf8695cf303
Reviewed-on: https://code.wireshark.org/review/32902
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2019-04-20 06:59:27 +00:00
Guy Harris 5169abbbe7 Clean up comments and white space.
This is a collection of routines, not a program.

Change-Id: I76296576443602b7ea016c5311e66a52a73ee941
Reviewed-on: https://code.wireshark.org/review/32491
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-03-20 16:45:22 +00:00
Guy Harris 38f348bbb0 Put back EOF rule, but without exporting write_current_packet().
Instead, add a new T_EOF token type, call parse_token() with it when we
get an EOF, and, in parse_token(), write the current packet if we get a
T_EOF token.

That's a bit simpler, and would let us treat EOFs in different places
differently, if, for example, we want to report warnings for
half-finished packets.

Change-Id: Ie41a8a1dedf91c34300468e073f18bf806e01892
Reviewed-on: https://code.wireshark.org/review/32489
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-03-20 16:06:57 +00:00
Guy Harris c01ace71ef Write out the last packet in text_import().
Write out the last packet after text_import_scan() returns, if it
returned successfully, the same way that it's done in text2pcap.  This
means we can get rid of the EOF rule in the lexer - the lexer just
finishes and returns 0 to text_import_scan(), which then returns a
success indication to text_import() - and make write_current_packet()
static.

Change-Id: Ibafdbe01da6bb33a213a32847f1981bc943290a1
Reviewed-on: https://code.wireshark.org/review/32486
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-03-20 07:27:25 +00:00
Guy Harris 6022ea716b Flip MAC and IP addresses, and TCP/UDP/SCTP ports, for outgoing packets.
If we have direction indications, flip the source and destination for
outgoing packets.

Also, generate sequence numbers for TCP.

Code lifted from text2pcap.

Bug: 15561
Change-Id: I869c45e88bf635f3277dbeeb08aff88dbfc8edef
Reviewed-on: https://code.wireshark.org/review/32383
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-03-11 00:58:11 +00:00
Guy Harris b5036134c2 Add macros for the pack_flags field.
Add macros to extract the direction, reception type, and FCS length
fields of the pack_flags field, and add definitions for different
directions and reception types.

Add a macro to construct a pack_flags field value from subfields; this
is for use by non-pcapng file readers (the pack_flags field is just a
copy of the EPB flags option, so that's not needed for pcapng).

Move some #defines for that field from packet-frame.c to wtap.h, and
rename them to match the new macros.

Use the macros rather than rolling our own code.

Fix a variable name in text2pcap.c that apparently had the wrong name,
given the value that was being tested.

Change-Id: Ia788ca4e9f5fabd8d24e6ead5ff1817509f54827
Reviewed-on: https://code.wireshark.org/review/32010
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2019-02-13 18:43:27 +00:00
Jaap Keuter 3c1342291f text import: cleanup type usage
The glib gboolean and integer types are used interchangably,
while a proper use is easily achievable.

Change-Id: I8943bb90c9f23c0e58c296ad3b45153d0364953c
Signed-off-by: Jaap Keuter <jaap.keuter@xs4all.nl>
Reviewed-on: https://code.wireshark.org/review/31708
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2019-01-23 21:17:14 +00:00
Jaap Keuter 020c90fd36 Text Import: update code comments and help texts
From the updates to text2pcap take the updates to the code comments and
apply them here as well. This also applies to the User Guide help texts.

Change-Id: I4e73fb1372ea0c1866c6d0fee7c14bc645fbe1b1
Signed-off-by: Jaap Keuter <jaap.keuter@xs4all.nl>
Reviewed-on: https://code.wireshark.org/review/31636
Tested-by: Petri Dish Buildbot
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2019-01-21 21:03:49 +00:00
Guy Harris 0946518780 Update comments, get rid of IMPORT_MAX_PACKET.
Get rid of the IMPORT_MAX_PACKET #define; just directly use
WTAP_MAX_PACKET_SIZE_STANDARD, to match what text2pcap.c does.

Update comments in text2pcap.c and ui/text_import.c to say the maximum
packet size is WTAP_MAX_PACKET_SIZE_STANDARD.

Change-Id: I34118f76426d1416fccf43b2a356ad8d200de19b
Ping-Bug: 15292
Reviewed-on: https://code.wireshark.org/review/30945
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2018-12-06 16:39:17 +00:00
Dario Lombardo 7396c721bc text_import: fix wrong int type.
Regressed in ge655b9a.

Change-Id: I5aeb9e1935bc1064797db8ac6acaa852d9a07c98
Reviewed-on: https://code.wireshark.org/review/30445
Petri-Dish: Dario Lombardo <lomato@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2018-10-31 15:30:52 +00:00
Dario Lombardo e655b9acf9 import: add export_pdu dummy header feature.
When importing a file from hex dump, this change adds a way to
add a custom dummy header. It's an export_pdu header which uses
one single tag: the protocol name. This allows to call directly
a dissector without more dummy headers.

Example: it can be used to call the DNS dissector without fake
eth/ip/udp headers.

Change-Id: I12fd6d09a131acd9bd1f0d7c4c8aefcd0d718b26
Reviewed-on: https://code.wireshark.org/review/30403
Petri-Dish: Dario Lombardo <lomato@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2018-10-31 13:17:10 +00:00
Jaap Keuter ca7ac05cf0 Fix some source headers, reformat SPDX license lines in comment block.
Change-Id: Ibae6a64a9915003435a3fb17763535a3844143be
Reviewed-on: https://code.wireshark.org/review/25891
Petri-Dish: Jaap Keuter <jaap.keuter@xs4all.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Michael Mann <mmann78@netscape.net>
2018-02-18 22:50:37 +00:00
Guy Harris 4a69d10920 Squelch redundant declaration warnings.
Have the text-to-pcap scanners define a routine that the main code
calls, which both allocates and destroys the scanner.  Don't declare the
Lex-generated routines in a header file we create, declare that routine,
instead.

Change-Id: Icad6a83db1a0dea8ac390315af72383fc99f8513
Reviewed-on: https://code.wireshark.org/review/25822
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2018-02-16 22:40:26 +00:00
Guy Harris 1f5f63f8ef Generalize wtap_pkthdr into a structure for packet and non-packet records.
Separate the stuff that any record could have from the stuff that only
particular record types have; put the latter into a union, and put all
that into a wtap_rec structure.

Add some record-type checks as necessary.

Change-Id: Id6b3486858f826fce4b096c59231f463e44bfaa2
Reviewed-on: https://code.wireshark.org/review/25696
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2018-02-09 00:29:51 +00:00
Dario Lombardo 8cd389e161 replace SPDX identifier GPL-2.0+ with GPL-2.0-or-later.
The first is deprecated, as per https://spdx.org/licenses/.

Change-Id: I8e21e1d32d09b8b94b93a2dc9fbdde5ffeba6bed
Reviewed-on: https://code.wireshark.org/review/25661
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Petri-Dish: Dario Lombardo <lomato@gmail.com>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2018-02-08 14:57:36 +00:00
Dario Lombardo e5f4ef0c42 ui: use SPDX identifiers.
Change-Id: I6b05399395bcc35e59b73b4030ba4a05711a7b1a
Reviewed-on: https://code.wireshark.org/review/25565
Petri-Dish: Michael Mann <mmann78@netscape.net>
Reviewed-by: Michael Mann <mmann78@netscape.net>
2018-02-02 13:39:04 +00:00
Guy Harris f63ad23ef9 Check for localtime() failing.
It "shouldn't happen", but at least this squelches a Coverity complaint,
CID 1398224.

Change-Id: I9555f71a50574e9386a3c96d52143d838f7f121f
Reviewed-on: https://code.wireshark.org/review/21160
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2017-04-17 07:48:56 +00:00
Guy Harris 10ca4c7527 More checks for localtime() and gmtime() returning NULL.
And some comments in the case where we're converting the result of
time() - if your machine's idea of time predates January 1, 1970,
00:00:00 UTC, it'll crash on Windows, but that's not a case where a
*file* can cause the problem due either to a bad file time stamp or bad
time stamps in the file.

Change-Id: I837a438e4b875dd8c4f3ec2137df7a16ee4e9498
Reviewed-on: https://code.wireshark.org/review/18369
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-10-22 02:27:32 +00:00
Stig Bjørlykke 8ec8f6b878 Qt: Multi line import from hex dump without offsets
Fix importing hex dump without offsets with multiple lines.

Change-Id: I7a7339e375b3125688f5b5d29f493704c7b9944a
Reviewed-on: https://code.wireshark.org/review/15868
Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org>
2016-06-13 08:02:04 +00:00
Stig Bjørlykke d72b29c1cb Qt: Add import from hex dump without offsets
Added support for importing from hex dump without offsets.
This will create one packet with all hex values found in the file.

Change-Id: I0414441721078befeb59aa6a87b9412646cfcf5c
Reviewed-on: https://code.wireshark.org/review/15743
Petri-Dish: Stig Bjørlykke <stig@bjorlykke.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2016-06-12 21:31:11 +00:00
Guy Harris 59816ef00c Make the Flex scanners and YACC parser in libraries reentrant.
master-branch libpcap now generates a reentrant Flex scanner and
Bison/Berkeley YACC parser for capture filter expressions, so it
requires versions of Flex and Bison/Berkeley YACC that support that.

We might as well do the same.  For libwiretap, it means we could
actually have multiple K12 text or Ascend/Lucent text files open at the
same time.  For libwireshark, it might not be as useful, as we only read
configuration files at startup (which should only happen once, in one
thread) or on demand (in which case, if we ever support multiple threads
running libwireshark, we'd need a mutex to ensure that only one file
reads it), but it's still the right thing to do.

We also require a version of Flex that can write out a header file, so
we change the runlex script to generate the header file ourselves. This
means we require a version of Flex new enough to support --header-file.

Clean up some other stuff encountered in the process.

Change-Id: Id23078c6acea549a52fc687779bb55d715b55c16
Reviewed-on: https://code.wireshark.org/review/14719
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-04-03 22:21:29 +00:00
Guy Harris dd6a74894f Pull the invocation of the Lex scanner into common code.
Instead of text_import_setup() and text_import_cleanup() routines, and
the actual scanner invocation being done in the dialog box, have a
text_import() routine that does all the work.

Change-Id: Ifd8a999618dbb411d613e6596484e4c2e013431d
Reviewed-on: https://code.wireshark.org/review/14647
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2016-03-27 02:21:19 +00:00
Alexis La Goutte 7762ee33da text_import: Argument with 'nonnull' attribute passed null found by Clang Analyzer
Change-Id: Ie070aa0f58cca156661ddd5689596e29ad56b128
Reviewed-on: https://code.wireshark.org/review/12412
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
2015-12-13 12:50:25 +00:00
Guy Harris 0162e54075 Clean up includes of unistd.h, fcntl.h, and sys/stat.h.
Have wsutil/file_util.h include them on UN*X, just as it includes io.h
on Windows, so we can have a rule of "if you do file operations, include
<wsutil/file_util.h> and use the routines in it".

Remove includes of unistd.h, fcntl.h, and sys/stat.h that aren't
necessary (whether because of the addition of them to wsutil/file_util.h
or because they weren't needed in the first place).

Change-Id: Ie241dd74deff284e39a5f690a297dbb6e1dc485f
Reviewed-on: https://code.wireshark.org/review/11619
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2015-11-07 21:52:23 +00:00
Guy Harris 51522b3372 Handle "I can't map this for that file format" better.
For cases where record (meta)data is something that can't be written out
in a particular file format, return WTAP_ERR_UNWRITABLE_REC_DATA along
with an err_info string.

Report (and free) that err_info string in cases where
WTAP_ERR_UNWRITABLE_REC_DATA is returned.

Clean up some other error reporting cases, and flag with an XXX some
cases where we aren't reporting errors at all, while we're at it.

Change-Id: I91d02093af0d42c24ec4634c2c773b30f3d39ab3
Reviewed-on: https://code.wireshark.org/review/5823
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2014-12-18 00:03:26 +00:00
Bill Meier cb090e81ec [pedantic] Replace usage of 'long' and 'long long'
Change-Id: I78fc82c1a83eb04d78a11fc76710c92dfc916208
Reviewed-on: https://code.wireshark.org/review/5395
Reviewed-by: Bill Meier <wmeier@newsguy.com>
2014-11-19 16:31:42 +00:00
Guy Harris 87545f39da Remove unnecessary includes of <ctype.h>.
Change-Id: I8eacec5fa8d57b10d40a3627197461dae89c6cb2
Reviewed-on: https://code.wireshark.org/review/4768
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2014-10-17 06:57:41 +00:00
Alexis La Goutte cc0f35436f Fix Argument with 'nonnull' attribute passed null found by Clang
Change-Id: I719d8adeb4bc6dbd1e34fe56f7cf68e4c6286dc9
Reviewed-on: https://code.wireshark.org/review/3246
Reviewed-by: Evan Huus <eapache@gmail.com>
2014-07-29 14:41:02 +00:00
Guy Harris 5bfc21cf9e Clean up handling of missing functions.
With autotools, CMake, and nmake, if we have a function, #define
HAVE_{function_name_in_all_caps}, otherwise don't #define it.

If we provide our own version of a function in libwsutil, make sure we
have a header that declares it, and *ONLY* include that header if
HAVE_{function_name_in_all_caps} is *NOT* defined, so that we don't have
the system declaration and our declaration colliding.

Check for inet_aton, strncasecmp, and strptime with CMake, just as we do
with autotools.

Simplify the addition of {function_name_in_all_caps}_LO to libwsutil in
autotools.

Change-Id: Id5be5c73f79f81919a3a865324e400eca7b88889
Reviewed-on: https://code.wireshark.org/review/2903
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2014-07-06 21:03:09 +00:00
Guy Harris 6db77b000f Allow wtap_read() and wtap_seek_read() to return records other than packets.
Add a "record type" field to "struct wtap_pkthdr"; currently, it can be
REC_TYPE_PACKET, for a record containing a packet, or
REC_TYPE_FILE_TYPE_SPECIFIC, for records containing file-type-specific
data.

Modify code that reads packets to be able to handle non-packet records,
even if that just means ignoring them.

Rename some routines to indicate that they handle more than just
packets.

We don't yet have any libwiretap code that supplies records other than
REC_TYPE_PACKET or that supporting writing records other than
REC_TYPE_PACKET, or any code to support plugins for handling
REC_TYPE_FILE_TYPE_SPECIFIC records; this is just the first step for bug
8590.

Change-Id: Idb40b78f17c2c3aea72031bcd252abf9bc11c813
Reviewed-on: https://code.wireshark.org/review/1773
Reviewed-by: Guy Harris <guy@alum.mit.edu>
2014-05-24 18:31:25 +00:00