Wireshark-dev: Re: [Wireshark-dev] 4 questions

From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Fri, 11 Jan 2008 17:00:24 -0800

On Jan 11, 2008, at 4:33 PM, warlord wrote:

a) I want to add my own protocol, on the same level as ethernet. So
instead of "Ethernet" or "FDDI" or something similar, I want f.ex.
"PROTO_WRL".
In a pcap the protocol information of the packet is specified in an int.
0x1 is Ethernet, 0x6 is Token_Ring and so on. If I use a hexeditor and
claim my packet in the pcap is of type 115(0x73), Wireshark tells me the protocol is unknown/unspecified. Great, so I found myself a free number
I can (ab)use.

No, you haven't. You've found a DLT_ value that Wireshark doesn't dissect. Just because it doesn't dissect Acorn Econet - the protocol to which 115 is assigned - now doesn't mean it never will. (Unlikely, perhaps, but not impossible - and, given that there are better ways of finding a DLT_ value to use, "unlikely" isn't enough.)

The way you find a free number you can use *privately* is to look in / usr/include/pcap-bpf.h (or, on older systems, /usr/include/net/bpf.h, or, with the not-yet-released libpcap 1.0, /usr/include/pcap/bpf.h - / usr/include/pcap-bpf.h includes the latter in 1.0), where, at least with reasonably modern versions of libpcap, you'll find:

/*
 * Reserved for private use.  If you have some link-layer header type
* that you want to use within your organization, with the capture files
 * using that link-layer header type not ever be sent outside your
 * organization, you can use these values.
 *
 * No libpcap release will use these for any purpose, nor will any
 * tcpdump release use them, either.
 *
* Do *NOT* use these in capture files that you expect anybody not using
 * your private versions of capture-file-reading tools to read; in
* particular, do *NOT* use them in products, otherwise you may find that
 * people won't be able to use tcpdump, or snort, or Ethereal, or... to
 * read capture files from your firewall/intrusion detection/traffic
 * monitoring/etc. appliance, or whatever product uses that DLT_ value,
 * and you may also find that the developers of those applications will
 * not accept patches to let them read those files.
 *
* Also, do not use them if somebody might send you a capture using them * for *their* private type and tools using them for *your* private type
 * would have to read them.
 *
 * Instead, ask "tcpdump-workers@xxxxxxxxxxx" for a new DLT_ value,
 * as per the comment above, and use the type you're given.
 */
#define DLT_USER0               147
#define DLT_USER1               148
#define DLT_USER2               149
#define DLT_USER3               150
#define DLT_USER4               151
#define DLT_USER5               152
#define DLT_USER6               153
#define DLT_USER7               154
#define DLT_USER8               155
#define DLT_USER9               156
#define DLT_USER10              157
#define DLT_USER11              158
#define DLT_USER12              159
#define DLT_USER13              160
#define DLT_USER14              161
#define DLT_USER15              162

Use one of those values.

If you want a type you can use *publicly* - i.e., if you want libpcap and some application such as Wireshark to officially include support for it - you need to ask tcpdump-workers@xxxxxxxxxxx for a DLT_ value.

It seems wiretap/libpcap.c is responsible for number->protocol decoding. So I edit the file and add number 115 with a value of "WTAP_ENCAP_WRL".
When trying to recompile wireshark I'm consequently told that this
hasn't been assigned, so I edit wiretap/wtap.h and add WTAP_ENCAP_WRL
with a value of 115.

Note that, in reasonably modern versions of Wireshark, wiretap/wtap.h has:

#define WTAP_ENCAP_USER0                        45
#define WTAP_ENCAP_USER1                        46
#define WTAP_ENCAP_USER2                        47
#define WTAP_ENCAP_USER3                        48
#define WTAP_ENCAP_USER4                        49
#define WTAP_ENCAP_USER5                        50
#define WTAP_ENCAP_USER6                        51
#define WTAP_ENCAP_USER7                        52
#define WTAP_ENCAP_USER8                        53
#define WTAP_ENCAP_USER9                        54
#define WTAP_ENCAP_USER10                       55
#define WTAP_ENCAP_USER11                       56
#define WTAP_ENCAP_USER12                       57
#define WTAP_ENCAP_USER13                       58
#define WTAP_ENCAP_USER14                       59
#define WTAP_ENCAP_USER15                       60

The fact that they're named USER0 through USER15 is not a coincidence. :-)

However, they're not mapped to DLT_USER0 through DLT_USER15, as somebody might want them for some other purpose, e.g. to handle a particular link layer header type in another capture file format. Both sets are intended for that sort of private use.

I recompile wshark and what do I get? Protocol 115 is not unknown
anymore. But now it's "WTAP_ENCAP = 115". How do I get that right? All I
want is my own protocol, instead of ethernet.

You have to have a dissector for your own protocol, *and* you have to have it tell the core of Wireshark that it should be used with a particular WTAP_ENCAP value. You do the latter by having your dissector's "reg_handoff" routine call

dissector_add("wtap_encap", WTAP_ENCAP_{yours}, {your dissector}_handle);

See, for example, epan/dissectors/packet-eth.c, which contains the dissector for Ethernet.

b) I don't need all those dissectors in epan/dissectors. I tried
removing some from epan/dissectors/Makefile.common from the
CLEAN_DISSECTOR_SRC section. Wireshark failed to compile, complaining
about missing dependencies. Can I not easily remove unused
dissectors(basically all of them)?

No.

d) I'm on a Gentoo and have Wireshark installed from the packet manager. I created a new dir for my experimental dev wireshark, checked wireshark out into there and built it. The build worked fine, but I can't run it.
It segfaults when I try to execute it.

stat64("/home/warlord/some_dirs_here/wireshark2/gtkrc", 0xbf93c8fc) = -1
ENOENT (No such file or directory)
access("/home/warlord/some_dirs_here/wireshark2/gtkrc.en_EN", F_OK) = -1
ENOENT (No such file or directory)
access("/home/warlord/some_dirs_here/wireshark2/gtkrc.en", F_OK) = -1
ENOENT (No such file or directory)
lstat64("/home/warlord/.wireshark/gtkrc", 0xbf93c8fc) = -1 ENOENT (No
such file or directory)
access("/home/warlord/.wireshark/gtkrc.en_EN", F_OK) = -1 ENOENT (No
such file or directory)
access("/home/warlord/.wireshark/gtkrc.en", F_OK) = -1 ENOENT (No such
file or directory)
- --- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

Run it under GDB, and see *where* it gets the segmentation fault.