Have separate packet_provider_data structures and packet_provider_funcs
structures; the latter holds a table of functions that libwireshark can
call for information about packets, the latter holds the data that those
functions use.
This means we no longer need to expose the structure of an epan_t
outside epan/epan.c; get rid of epan/epan-int.h.
Change-Id: I381b88993aa19e55720ce02c42ad33738e3f51f4
Reviewed-on: https://code.wireshark.org/review/24732
Reviewed-by: Guy Harris <guy@alum.mit.edu>
libwireshark now expects an epan_t to be created with a pointer to a
"packet provider" structure; that structure is opaque within
libwireshark, and a pointer to it is passed to the callbacks that
provide interface names, interface, descriptions, user comments, and
packet time stamps, and that set user comments. The code that calls
epan_new() is expected to provide those callbacks, and to define the
structure, which can be used by the providers. If none of the callbacks
need that extra information, the "packet provider" structure can be
null.
Have a "file" packet provider for all the programs that provide packets
from a file.
Change-Id: I4b5709a3dd7b098ebd7d2a7d95bcdd7b5903c1a0
Reviewed-on: https://code.wireshark.org/review/24731
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Embed one of those structures in a capture_file, and have a struct
epan_session point to that structure rather than to a capture_file.
Pass that structure to the routines that fetch data that libwireshark
uses when dissecting.
That separates the stuff that libwireshark expects from the stuff that
it doesn't look at.
Change-Id: Ia3cd28efb9622476437a2ce32204597fae720877
Reviewed-on: https://code.wireshark.org/review/24692
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Those fields weren't being used in TShark/TFShark/rawshark/sharkd, so we
can use them, instead of defining our own static variables.
This makes the non-Wireshark code paths a bit more like the Wireshark
code paths.
Change-Id: I55da4cf525e37598f314efca22f20d3e80cb547c
Reviewed-on: https://code.wireshark.org/review/24691
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Have cfile-int.h declare the structure, and use it in files that
directly access the structure.
Have cfile.h just incompletely declare the structure and include it
rather than explicitly declaring it in source files or other header
files.
Never directly refer to struct _capture_file except when typedeffing
capture_file.
Add #includes as necessary, now that cfile.h doesn't drag in a ton of
Change-Id: I7931c8039d75ff7c980b0f2a6e221f20e602a556
Reviewed-on: https://code.wireshark.org/review/24686
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Follow-up to b695b3e2f7.
Change-Id: I7e36519f2c3806c1205d05437671325080974257
Reviewed-on: https://code.wireshark.org/review/24524
Petri-Dish: João Valverde <j@v6e.pt>
Tested-by: Petri Dish Buildbot
Reviewed-by: João Valverde <j@v6e.pt>
A while back Graham pointed out the SPDX project (spdx.org), which is
working on standardizing license specifications:
https://www.wireshark.org/lists/wireshark-dev/201509/msg00119.html
Appendix V of the specification describes a short identifier
(SPDX-License-Identifier) that you can use in place of boilerplate in
your source files:
https://spdx.org/spdx-specification-21-web-version#h.twlc0ztnng3b
Start the conversion process with our top-level C and C++ files.
Change-Id: Iba1d835776714deb6285e2181e8ca17f95221878
Reviewed-on: https://code.wireshark.org/review/24302
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Reviewed-by: Balint Reczey <balint@balintreczey.hu>
Tested-by: Petri Dish Buildbot
Reviewed-by: Michael Mann <mmann78@netscape.net>
This partially reverts dc0e6ccc9f in favor
of a cleaner solution.
Change-Id: Ie57329020b5a7d15eb7d99aad3103843a14f07a6
Reviewed-on: https://code.wireshark.org/review/24278
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Dario Lombardo <lomato@gmail.com>
The user has no way to apply this setting while loading dissectors in order
to enable g_debug messages during init for example.
Change the behavior to be as documented in the comment.
Change-Id: I9317f12b207d4621508212b02ca1ebd46b55aadc
Reviewed-on: https://code.wireshark.org/review/24184
Petri-Dish: Roland Knall <rknall@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Richard Sharpe <realrichardsharpe@gmail.com>
Not all platforms handle ? or -? *predictably* at the command line.
As long as "?" isn't replaced with a file name, it works, but if it
gets replaced by a file name...
Bug: 13984
Change-Id: I4496bb27fdef121967e7baf7b7f4a1bb0a44b00a
Reviewed-on: https://code.wireshark.org/review/24125
Reviewed-by: Michael Mann <mmann78@netscape.net>
If we're building on Windows we're going to have windows.h and
winsock2.h. Don't bother checking for them.
Change-Id: I0004c44d7364ab3f41682f34b8c84cd8617c9603
Reviewed-on: https://code.wireshark.org/review/24068
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
In preparation for possibly using AUTOUIC in CMake which treats "ui_*.h"
files specially, rename ui_util.h. No other changes.
Change-Id: Id026572c000b713ff0e9388dc7fff8d81d4df73e
Reviewed-on: https://code.wireshark.org/review/23916
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Currently, the Elasticsearch output exports the packet details and,
if -x is specified, the raw hex data.
This change adds the option of exporting the packet summary as well.
The default stays the same (packet details only), but now the existing
-P switch turns on printing of the packet summary. It also turns off
printing packet details, which can be turned back on with -V to print
both, and combined with -x to print all three: summary, details and
raw hex.
The packet summary is especially useful when exploring and visualizing
the data in Kibana, e.g. by displaying the summary "Info" field/column
in a table, as in the Wireshark GUI.
Change-Id: I2030490cfdd905572397bc3d5457ba49d805a5c4
Reviewed-on: https://code.wireshark.org/review/22716
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
tcpdump just got a --print option, which causes packet information to be
printed even if the raw packets are being saved to a file with -w. We
have -P for the same purpose; make --print another name for it.
While we're at it:
document --help and --version;
just speak of -P/--print as causing printing even of the packet
details, even though -V forces printing with -w, for consistency
with how --print is documented for tcpdump;
fix the description of -h/--help.
Change-Id: Idf650a202a09a2d1682edbd9d76123f1b1412b55
Reviewed-on: https://code.wireshark.org/review/23888
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Add links to the online man page for each tool. Make sure tshark
generates pre-commit-compatible output on Linux.
Change-Id: I00d2973475f27460065bc8a65471abef152ded33
Reviewed-on: https://code.wireshark.org/review/23754
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
It's not installed so like most other files it doesn't need or benefit
from the prefix.
Change-Id: I01517e06f12b3101fee21b68cba3bc6842bbef5c
Reviewed-on: https://code.wireshark.org/review/23751
Petri-Dish: João Valverde <j@v6e.pt>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: João Valverde <j@v6e.pt>
Display separate entries for binary plugins and lua scripts.
This is explained in the user guide, that the binary folder is
a subfolder of the lua folder, but it's probably a good idea to be more
explicit about it, at the risk of cluttering the interface a bit.
Move GeoIP information down because it seems the least important.
Add helper functions to provide plugin version subdir.
Change some #ifdefs while at it for legibility.
Change-Id: Ieb8665df029b3c14de19e2c973bd9b1cc4ec4621
Reviewed-on: https://code.wireshark.org/review/23609
Petri-Dish: João Valverde <j@v6e.pt>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: João Valverde <j@v6e.pt>
WS_DLL_PUBLIC const char *get_plugin_dir(void);
WS_DLL_PUBLIC const char *get_plugins_pers_dir(void);
Opt for the plural form consistently (for public functions at least).
Change-Id: I8a5861ad7f90f9c87168bd3275bd9dbc5c83b749
Reviewed-on: https://code.wireshark.org/review/23608
Petri-Dish: João Valverde <j@v6e.pt>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Obviate allocation on every call to get_plugins_pers_dir().
Change-Id: I089ae499f93739d490d4552f59b5db5996f7d26f
Reviewed-on: https://code.wireshark.org/review/23495
Petri-Dish: João Valverde <j@v6e.pt>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Reviewed-by: João Valverde <j@v6e.pt>
Depending on how packetlist columns are arranged certain columns may have a
Unicode arrow character inserted between it and the subsequent column to
indicate source vs destination column directionality when displayed in
tshark. Currently any inserted Unicode arrow characters are
unconditionally prefaced with an ASCII SPACE character.
Tshark's `-T tabs` option causes the various packetlist columns to be
delimited with ASCII TAB characters. The unconditional use of the SPACE
character before any inserted Unicode arrows makes it difficult to directly
compare a -T tabs report of column N values to column N+1 values without
dealing with the SPACE/Unicode Arrow suffix appended to all of the column
N values.
The inserted Unicode directionality arrows are effectively another
packetlist column of data that should be delimited like all other columns.
This patch ensures that any Unicode directionality arrows inserted between
packet list columns are delimited on both sides of the arrows with the
selected delimiter character.
Change-Id: I4eb7c6015a538afdc2c41be746eca4eec1ace36f
Reviewed-on: https://code.wireshark.org/review/23222
Petri-Dish: Jim Young <jim.young.ws@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Change access of ifaces elements from by val to by reference.
With this change unnecessary copying of the whole struct is avoided
but even more important is that elements no longer have to be
removed and inserted whenever data is updated.
This change aims to make it more clear that ifaces elements shall
never directly be removed from the array. Instead use function
capture_opts_del_iface
NOTE: Code for GTK UI not updated
Ping-Bug: 13864
Change-Id: I04b65d5ee36526b30d959b8e5a2a48a3c7c4f15b
Reviewed-on: https://code.wireshark.org/review/23204
Reviewed-by: Anders Broman <a.broman58@gmail.com>
pcap provides a pcap_set_tstamp_type function, which can be used to request
hardware timestamps from a supporting kernel.
This patch adds support for aforementioned function as well as two new
command line options to dumpcap, wireshark and tshark:
--list-time-stamp-types
List time stamp types supported for the interface
--time-stamp-type <type>
Change the interface's timestamp method
Name choice mimics those used by tcpdump(1), which already supports this
feature. However, unlike tcpdump, we provide both options unconditionally.
If Wireshark was configured without pcap_set_tstamp_type being available,
--list-time-stamp-types reports an empty list.
Change-Id: I418a4b2b84cb01949cd262aad0ad8427f5ac0652
Signed-off-by: Ahmad Fatoum <ahmad.fatoum@siemens.com>
Reviewed-on: https://code.wireshark.org/review/23113
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Add the "interval" option to "-b". Each new capture starts at the
exact start of a time interval. For instance, using -b interval:3600
will start a new capture file at each whole hour.
Changed the duration option in the GUI interfaces to use the new
interval option.
Change-Id: I0180c43843f5d2f0c2f50153c9ce42ac7fa5aeae
Reviewed-on: https://code.wireshark.org/review/22428
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Sake Blok <sake.blok@SYN-bit.nl>
Adds the --no-duplicate-keys option to tshark. If -T json is specified,
this option can be specified in order to transform the duplicate keys
produced by -T json into single keys with as value a json array of all
separate values.
Specifying --no-duplicate-keys changes the function which groups node
children that is passed to write_json_proto_tree. Instead of a function
that puts each node in a separate group (proto_node_group_children_by_unique)
a function is passed that groups children that have the same json key
together (proto_node_group_children_by_json_key). This will lead to
some groups having multiple values. Groups with multiple values are
written to the output as a json array. This includes normal json keys
but also keys with the "_raw" and "_tree" suffix.
If --no-duplicate-keys is specified with an option other than "-T json"
or "-T jsonraw" or without -T an error is shown and tshark will exit.
"Export Packet Dissections -> As JSON" in the GUI is hardcoded to use
the duplicated keys format.
Fixes one regression in the output where a filtered json key (-j) with
both a value and children would not have the "_tree" suffix added to the
json key containing the children.
Includes a little code cleanup (removes one instance of code
duplication and simplifies a while loop).
Fixes a memory leak (I thought this fix was already included in the
previous refactor patch but something must have gone wrong when updating
the patch so I'm including it again in this patch).
Bug: 12958
Change-Id: I401f8fc877b5c590686567c3c44cdb832e9e7dfe
Reviewed-on: https://code.wireshark.org/review/22166
Petri-Dish: Jaap Keuter <jaap.keuter@xs4all.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Refactors the print.c json output functions to be more intuitive and
to allow easy switching to single json keys with a json array of values
instead of duplicate json keys. With this commit the json output does
not change at all.
These changes have been tested on multiple decrypted http2 traces with
the following testing method:
- Save the pcap file as json with a build of the current master branch.
- Save the pcap file as json with a build of the master branch + this
commit.
- Compare the files for changes with the "cmp" utility.
No differences were found between files for multiple different decrypted
http2 traces. Printing with the "-x" or "-j" options also does not
produce any changes either.
Bug: 12958
Change-Id: Ibd3d39119c3a08906389aa8bbf4e2a2b21dd824e
Reviewed-on: https://code.wireshark.org/review/22064
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Bug: 6682
Change-Id: I19330d06aa3d5692503c61369c3c650d595971f5
Reviewed-on: https://code.wireshark.org/review/22077
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Stephen Donnelly <stephen.donnelly@endace.com>
Reviewed-by: Anders Broman <a.broman58@gmail.com>
There's no guarantee that there's a color filter that matches, so the
color filter pointer might be null.
Change-Id: Ia11845824a4ca9c0cc153a89aa2fba876084a796
Reviewed-on: https://code.wireshark.org/review/22079
Reviewed-by: Guy Harris <guy@alum.mit.edu>
With this commit, tshark will mimic the packet coloring present in the
Wireshark GUI whenever "--color" is passed. This initial commit only
adds such support for the standard text output format. A future commit
could potentially broaden this support to other output modes (such as
"-V" mode).
Bug: 5158
Change-Id: I59329e32475b0c67e28802e79610544d4868ea2d
Reviewed-on: https://code.wireshark.org/review/21325
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Use WTAP_MAX_PACKET_SIZE_STANDARD, set to 256KB, for everything except
for D-Bus captures. Use WTAP_MAX_PACKET_SIZE_DBUS, set to 128MB, for
them, because that's the largest possible D-Bus message size. See
https://bugs.freedesktop.org/show_bug.cgi?id=100220
for an example of the problems caused by limiting the snapshot length to
256KB for D-Bus.
Have a snapshot length of 0 in a capture_file structure mean "there is
no snapshot length for the file"; we don't need the has_snap field in
that case, a value of 0 mean "no, we don't have a snapshot length".
In dumpcap, start out with a pipe buffer size of 2KB, and grow it as
necessary. When checking for a too-big packet from a pipe, check
against the appropriate maximum - 128MB for DLT_DBUS, 256KB for
everything else.
Change-Id: Ib2ce7a0cf37b971fbc0318024fd011e18add8b20
Reviewed-on: https://code.wireshark.org/review/21952
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Add the cause for a syntax error while parsing UATs. Example output:
$ tshark -ouat:ssl_keys:,
tshark: Invalid -o flag "uat:ssl_keys:,": ssl_keys:1: No IP address given.
$ tshark -ouat:unknown:,
tshark: Invalid -o flag "uat:unknown:,": Unknown preference
Change-Id: I549406c4e31a81d29f487ef47bdb3c22da084947
Reviewed-on: https://code.wireshark.org/review/21748
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Jakub Zawadzki <darkjames-ws@darkjames.pl>
Reviewed-by: Michael Mann <mmann78@netscape.net>
Automatically resets intarnal epan session after reaching to
specified number of packets, for example
-M 1000
will reset the session every 1000 packets.
this is more like a proposal since the usage is very specific
it is useful for 24/7 live capture with dissection and sending
data directly to another application.
example:
tshark -Y "gtp" -M 100000 -T fields -e gtp.message -e gtp.teid
Change-Id: I8ee8b0380017c684120a93cb3fb43f41615a9c04
Reviewed-on: https://code.wireshark.org/review/21312
Reviewed-by: Evan Huus <eapache@gmail.com>
Petri-Dish: Evan Huus <eapache@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
The cfile_ error-reporting routines free err_info; the caller doesn't
have to and, in fact, mustn't do so themselves.
While we're at it, make sure wtap_seek_read() always zeroes out *err and
nulls out *err_info, so the latter either points to a freshly-allocated
string or is null.
Change-Id: Idfe05a3ba2fbf2647ba14e483187617ee53e3c69
Reviewed-on: https://code.wireshark.org/review/21407
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Packet ranges are used only in the UI; move the packet range stuff into
libui.
Don't pass a print_args_t structure to libwireshark packet-printing
routines, just pass the few parameters they need. Move the declaration
of print_args_t into file.h.
Change-Id: Icff5991eea7d7d56f33b4716105895263d275bcf
Reviewed-on: https://code.wireshark.org/review/21308
Petri-Dish: Guy Harris <guy@alum.mit.edu>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
That way, they don't, for example, get lost as a result of being
scrolled off the screen by output from the second pass.
Also, do the post-processing of output regardless of whether we got read
errors or not, and fix a code error hidden by a call to tshark_debug().
Change-Id: I389c7c794f4dd5fda6e4c50ce480802c92701866
Reviewed-on: https://code.wireshark.org/review/21305
Reviewed-by: Guy Harris <guy@alum.mit.edu>
/home/wireshark/builders/ubuntu-x86-64-petri-dish/ubuntu-x86-64-petri-dish/build/tshark.c: In function ‘main’:
/home/wireshark/builders/ubuntu-x86-64-petri-dish/ubuntu-x86-64-petri-dish/build/tshark.c:653:12:
error: variable ‘success’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered]
Change-Id: I793962c71b0ebfafc7c09b1d865cfa774456bb3a
Reviewed-on: https://code.wireshark.org/review/21303
Petri-Dish: Jakub Zawadzki <darkjames-ws@darkjames.pl>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
They might read the file once or twice, but the key is that they (and
what they call) are doing the work of processing the file's contents.
Change-Id: I2df6257c55ff5ace944f1a1db5e2aec456ed2038
Reviewed-on: https://code.wireshark.org/review/21293
Reviewed-by: Guy Harris <guy@alum.mit.edu>
No need to report the precise error code - it's already reported the
error.
Change-Id: Ib52daf094253deac2a10d16793ebf0f42581afd6
Reviewed-on: https://code.wireshark.org/review/21292
Reviewed-by: Guy Harris <guy@alum.mit.edu>
In TShark, rename load_cap_file() to read_cap_file(); this is TShark,
not Wireshark, so you're not "loading" a file to be manipulated through
the GUI.
In TFShark, rename it to "read_file()"; not only are we not loading it,
it's not even necessarily a capture file.
Change-Id: I122b46ecd8cb7de9c1e1c249ba6c08fdeb93f7e2
Reviewed-on: https://code.wireshark.org/review/21291
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Expand comments while we're at it.
Change-Id: I6dcc791eab1c9e323a9572f3d54720d223bdd64b
Reviewed-on: https://code.wireshark.org/review/21252
Reviewed-by: Guy Harris <guy@alum.mit.edu>
(Clang FTW! Is this not an issue on x86-64 macOS, so that it doesn't
warn about it, or does it, unlike GCC, require a particular -W flag to
warn about non-volatile variables being stomped by setjmp/longjmp?)
Change-Id: I253c1ea324feac1372aa4077aaba03c787a47d9f
Reviewed-on: https://code.wireshark.org/review/21248
Reviewed-by: Guy Harris <guy@alum.mit.edu>
These are similar to the routines added to ui/alert_box.c for dialog-box
libwiretap error reporting.
This centralizes the knowledge about what to say for various libwiretap
errors, removing some duplicate code, and giving more details in some
programs.
Change-Id: I737405c4edaa0e6c27840f78a8c587a8b3ee120b
Reviewed-on: https://code.wireshark.org/review/21234
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Use that for both "open for input" and "open for output" errors.
Change-Id: Id17b732a2ca91bd080957b9fa010f781a1c65471
Reviewed-on: https://code.wireshark.org/review/21175
Reviewed-by: Guy Harris <guy@alum.mit.edu>
List all of --enable-protocol, --disable-protocol, --enable-heuristic,
and --disable-heuristic in the SYNOPSIS section of the man pages.
Undent after the list of taps for the -z option, so the following
options are at the same indentation as other options.
List --enable-protocol in the DESCRIPTION, above --disable-protocol.
Include --enable-protocol in the help message.
Change-Id: I680a54430789f3543b2d539fbded22b0b57f7f76
Reviewed-on: https://code.wireshark.org/review/21159
Reviewed-by: Guy Harris <guy@alum.mit.edu>
They deal with sets of hfids, which can belong to protocols as well as
fields (I guess you could argue that a protocol is a field, but...).
Change-Id: Ibd103cfa26427ead4ef54be89f1251908004cfae
Reviewed-on: https://code.wireshark.org/review/21154
Reviewed-by: Guy Harris <guy@alum.mit.edu>