xref: /freebsd/contrib/tcpdump/CONTRIBUTING.md (revision 0a7e5f1f02aad2ff5fff1c60f44c6975fd07e1d9)
1ee67461eSJoseph Mingrone# Some Information for Contributors
2ee67461eSJoseph MingroneThank you for considering to make a contribution to tcpdump! Please use the
3ee67461eSJoseph Mingroneguidelines below to achieve the best results and experience for everyone.
4ee67461eSJoseph Mingrone
5ee67461eSJoseph Mingrone## How to report bugs and other problems
6ee67461eSJoseph Mingrone**To report a security issue (segfault, buffer overflow, infinite loop, arbitrary
7ee67461eSJoseph Mingronecode execution etc) please send an e-mail to security@tcpdump.org, do not use
8ee67461eSJoseph Mingronethe bug tracker!**
9ee67461eSJoseph Mingrone
10ee67461eSJoseph MingroneTo report a non-security problem (failure to compile, incorrect output in the
11ee67461eSJoseph Mingroneprotocol printout, missing support for a particular protocol etc) please check
12ee67461eSJoseph Mingronefirst that it reproduces with the latest stable release of tcpdump and the latest
13ee67461eSJoseph Mingronestable release of libpcap. If it does, please check that the problem reproduces
14ee67461eSJoseph Mingronewith the current git master branch of tcpdump and the current git master branch of
15ee67461eSJoseph Mingronelibpcap. If it does (and it is not a security-related problem, otherwise see
16ee67461eSJoseph Mingroneabove), please navigate to the
17ee67461eSJoseph Mingrone[bug tracker](https://github.com/the-tcpdump-group/tcpdump/issues)
18ee67461eSJoseph Mingroneand check if the problem has already been reported. If it has not, please open
19ee67461eSJoseph Mingronea new issue and provide the following details:
20ee67461eSJoseph Mingrone
21ee67461eSJoseph Mingrone* tcpdump and libpcap version (`tcpdump --version`)
22ee67461eSJoseph Mingrone* operating system name and version and any other details that may be relevant
23ee67461eSJoseph Mingrone  (`uname -a`, compiler name and version, CPU type etc.)
24ee67461eSJoseph Mingrone* custom `configure`/`cmake` flags, if any
25ee67461eSJoseph Mingrone* statement of the problem
26ee67461eSJoseph Mingrone* steps to reproduce
27ee67461eSJoseph Mingrone
28ee67461eSJoseph MingronePlease note that if you know exactly how to solve the problem and the solution
29ee67461eSJoseph Mingronewould not be too intrusive, it would be best to contribute some development time
30ee67461eSJoseph Mingroneand to open a pull request instead as discussed below.
31ee67461eSJoseph Mingrone
32ee67461eSJoseph MingroneStill not sure how to do? Feel free to
33ee67461eSJoseph Mingrone[subscribe to the mailing list](https://www.tcpdump.org/#mailing-lists)
34ee67461eSJoseph Mingroneand ask!
35ee67461eSJoseph Mingrone
36ee67461eSJoseph Mingrone
37ee67461eSJoseph Mingrone## How to add new code and to update existing code
38ee67461eSJoseph Mingrone
39*0a7e5f1fSJoseph Mingrone1) Check that there isn't a pull request already opened for the changes you
40ee67461eSJoseph Mingrone   intend to make.
41ee67461eSJoseph Mingrone
42*0a7e5f1fSJoseph Mingrone2) [Fork](https://help.github.com/articles/fork-a-repo/) the Tcpdump
43ee67461eSJoseph Mingrone   [repository](https://github.com/the-tcpdump-group/tcpdump).
44ee67461eSJoseph Mingrone
45*0a7e5f1fSJoseph Mingrone3) The easiest way to test your changes on multiple operating systems and
46ee67461eSJoseph Mingrone   architectures is to let the upstream CI test your pull request (more on
47ee67461eSJoseph Mingrone   this below).
48ee67461eSJoseph Mingrone
49*0a7e5f1fSJoseph Mingrone4) Setup your git working copy
50ee67461eSJoseph Mingrone   ```
51ee67461eSJoseph Mingrone   git clone https://github.com/<username>/tcpdump.git
52ee67461eSJoseph Mingrone   cd tcpdump
53ee67461eSJoseph Mingrone   git remote add upstream https://github.com/the-tcpdump-group/tcpdump
54ee67461eSJoseph Mingrone   git fetch upstream
55ee67461eSJoseph Mingrone   ```
56ee67461eSJoseph Mingrone
57*0a7e5f1fSJoseph Mingrone5) Do a `touch .devel` in your working directory.
58ee67461eSJoseph Mingrone   Currently, the effect is
59ee67461eSJoseph Mingrone   * add (via `configure`, in `Makefile`) some warnings options (`-Wall`,
60ee67461eSJoseph Mingrone     `-Wmissing-prototypes`, `-Wstrict-prototypes`, ...) to the compiler if it
61ee67461eSJoseph Mingrone     supports these options,
62ee67461eSJoseph Mingrone   * have the `Makefile` support `make depend` and the `configure` script run it.
63ee67461eSJoseph Mingrone
64*0a7e5f1fSJoseph Mingrone6) Configure and build
65ee67461eSJoseph Mingrone   ```
66ee67461eSJoseph Mingrone   ./configure && make -s && make check
67ee67461eSJoseph Mingrone   ```
68ee67461eSJoseph Mingrone
69*0a7e5f1fSJoseph Mingrone7) Add/update tests
70ee67461eSJoseph Mingrone   The `tests` directory contains regression tests of the dissection of captured
71ee67461eSJoseph Mingrone   packets.  Those captured packets were saved running tcpdump with option
72ee67461eSJoseph Mingrone   `-w sample.pcap`.  Additional options, such as `-n`, are used to create relevant
73ee67461eSJoseph Mingrone   and reproducible output; `-#` is used to indicate which particular packets
74ee67461eSJoseph Mingrone   have output that differs.  The tests are run with the `TZ` environment
75ee67461eSJoseph Mingrone   variable set to `GMT0`, so that UTC, rather than the local time where the
76ee67461eSJoseph Mingrone   tests are being run, is used when "local time" values are printed.  The
77ee67461eSJoseph Mingrone   actual test compares the current text output with the expected result
78ee67461eSJoseph Mingrone   (`sample.out`) saved from a previous version.
79ee67461eSJoseph Mingrone
80ee67461eSJoseph Mingrone   Any new/updated fields in a dissector must be present in a `sample.pcap` file
81ee67461eSJoseph Mingrone   and the corresponding output file.
82ee67461eSJoseph Mingrone
83ee67461eSJoseph Mingrone   Configuration is set in `tests/TESTLIST`.
84ee67461eSJoseph Mingrone   Each line in this file has the following format:
85ee67461eSJoseph Mingrone   ```
86ee67461eSJoseph Mingrone   test-name   sample.pcap   sample.out   tcpdump-options
87ee67461eSJoseph Mingrone   ```
88ee67461eSJoseph Mingrone
89ee67461eSJoseph Mingrone   The `sample.out` file can be produced as follows:
90ee67461eSJoseph Mingrone   ```
91ee67461eSJoseph Mingrone   (cd tests && TZ=GMT0 ../tcpdump -# -n -r sample.pcap tcpdump-options > sample.out)
92ee67461eSJoseph Mingrone   ```
93ee67461eSJoseph Mingrone
94ee67461eSJoseph Mingrone   Or, for convenience, use `./update-test.sh test-name`
95ee67461eSJoseph Mingrone
96ee67461eSJoseph Mingrone   It is often useful to have test outputs with different verbosity levels
97ee67461eSJoseph Mingrone   (none, `-v`, `-vv`, `-vvv`, etc.) depending on the code.
98ee67461eSJoseph Mingrone
99*0a7e5f1fSJoseph Mingrone8) Test using `make check` (current build options) and `./build_matrix.sh`
100ee67461eSJoseph Mingrone   (a multitude of build options, build systems and compilers). If you can,
101ee67461eSJoseph Mingrone   test on more than one operating system. Don't send a pull request until
102ee67461eSJoseph Mingrone   all tests pass.
103ee67461eSJoseph Mingrone
104*0a7e5f1fSJoseph Mingrone9) Try to rebase your commits to keep the history simple.
105ee67461eSJoseph Mingrone   ```
106ee67461eSJoseph Mingrone   git fetch upstream
107ee67461eSJoseph Mingrone   git rebase upstream/master
108ee67461eSJoseph Mingrone   ```
109ee67461eSJoseph Mingrone   (If the rebase fails and you cannot resolve, issue `git rebase --abort`
110ee67461eSJoseph Mingrone   and ask for help in the pull request comment.)
111ee67461eSJoseph Mingrone
112*0a7e5f1fSJoseph Mingrone10) Once 100% happy, put your work into your forked repository using `git push`.
113ee67461eSJoseph Mingrone
114*0a7e5f1fSJoseph Mingrone11) [Initiate and send](https://help.github.com/articles/using-pull-requests/)
115ee67461eSJoseph Mingrone    a pull request.
116ee67461eSJoseph Mingrone    This will trigger the upstream repository CI tests.
117ee67461eSJoseph Mingrone
118ee67461eSJoseph Mingrone
119ee67461eSJoseph Mingrone## Code style and generic remarks
120*0a7e5f1fSJoseph Mingrone1) A thorough reading of some other printers code is useful.
121ee67461eSJoseph Mingrone
122*0a7e5f1fSJoseph Mingrone2) To help learn how tcpdump works or to help debugging:
123*0a7e5f1fSJoseph Mingrone   You can configure and build tcpdump with the instrumentation of functions:
124*0a7e5f1fSJoseph Mingrone   ```
125*0a7e5f1fSJoseph Mingrone   $ ./configure --enable-instrument-functions
126*0a7e5f1fSJoseph Mingrone   $ make -s clean all
127*0a7e5f1fSJoseph Mingrone   ```
128ee67461eSJoseph Mingrone
129*0a7e5f1fSJoseph Mingrone   This generates instrumentation calls for entry and exit to functions.
130*0a7e5f1fSJoseph Mingrone   Just after function entry and just before function exit, these
131*0a7e5f1fSJoseph Mingrone   profiling functions are called and print the function names with
132*0a7e5f1fSJoseph Mingrone   indentation and call level.
133*0a7e5f1fSJoseph Mingrone
134*0a7e5f1fSJoseph Mingrone   If entering in a function, it prints also the calling function name with
135*0a7e5f1fSJoseph Mingrone   file name and line number. There may be a small shift in the line number.
136*0a7e5f1fSJoseph Mingrone
137*0a7e5f1fSJoseph Mingrone   In some cases, with Clang 11, the file number is unknown (printed '??')
138*0a7e5f1fSJoseph Mingrone   or the line number is unknown (printed '?'). In this case, use GCC.
139*0a7e5f1fSJoseph Mingrone
140*0a7e5f1fSJoseph Mingrone   If the environment variable INSTRUMENT is
141*0a7e5f1fSJoseph Mingrone   - unset or set to an empty string, print nothing, like with no
142*0a7e5f1fSJoseph Mingrone     instrumentation
143*0a7e5f1fSJoseph Mingrone   - set to "all" or "a", print all the functions names
144*0a7e5f1fSJoseph Mingrone   - set to "global" or "g", print only the global functions names
145*0a7e5f1fSJoseph Mingrone
146*0a7e5f1fSJoseph Mingrone   This allows to run:
147*0a7e5f1fSJoseph Mingrone   ```
148*0a7e5f1fSJoseph Mingrone   $ INSTRUMENT=a ./tcpdump ...
149*0a7e5f1fSJoseph Mingrone   $ INSTRUMENT=g ./tcpdump ...
150*0a7e5f1fSJoseph Mingrone   $ INSTRUMENT= ./tcpdump ...
151*0a7e5f1fSJoseph Mingrone   ```
152*0a7e5f1fSJoseph Mingrone   or
153*0a7e5f1fSJoseph Mingrone   ```
154*0a7e5f1fSJoseph Mingrone   $ export INSTRUMENT=global
155*0a7e5f1fSJoseph Mingrone   $ ./tcpdump ...
156*0a7e5f1fSJoseph Mingrone   ```
157*0a7e5f1fSJoseph Mingrone
158*0a7e5f1fSJoseph Mingrone   The library libbfd is used, therefore the binutils-dev package is required.
159*0a7e5f1fSJoseph Mingrone
160*0a7e5f1fSJoseph Mingrone3) Put the normative reference if any as comments (RFC, etc.).
161*0a7e5f1fSJoseph Mingrone
162*0a7e5f1fSJoseph Mingrone4) Put the format of packets/headers/options as comments if there is no
163ee67461eSJoseph Mingrone   published normative reference.
164ee67461eSJoseph Mingrone
165*0a7e5f1fSJoseph Mingrone5) The printer may receive incomplete packet in the buffer, truncated at any
166ee67461eSJoseph Mingrone   random position, for example by capturing with `-s size` option.
167*0a7e5f1fSJoseph Mingrone   This means that an attempt to fetch packet data based on the expected
168*0a7e5f1fSJoseph Mingrone   format of the packet may run the risk of overrunning the buffer.
169*0a7e5f1fSJoseph Mingrone
170*0a7e5f1fSJoseph Mingrone   Furthermore, if the packet is complete, but is not correctly formed,
171*0a7e5f1fSJoseph Mingrone   that can also cause a printer to overrun the buffer, as it will be
172*0a7e5f1fSJoseph Mingrone   fetching packet data based on the expected format of the packet.
173*0a7e5f1fSJoseph Mingrone
174*0a7e5f1fSJoseph Mingrone   Therefore, integral, IPv4 address, and octet sequence values should
175*0a7e5f1fSJoseph Mingrone   be fetched using the `GET_*()` macros, which are defined in
176*0a7e5f1fSJoseph Mingrone   `extract.h`.
177*0a7e5f1fSJoseph Mingrone
178ee67461eSJoseph Mingrone   If your code reads and decodes every byte of the protocol packet, then to
179ee67461eSJoseph Mingrone   ensure proper and complete bounds checks it would be sufficient to read all
180*0a7e5f1fSJoseph Mingrone   packet data using the `GET_*()` macros.
181*0a7e5f1fSJoseph Mingrone
182ee67461eSJoseph Mingrone   If your code uses the macros above only on some packet data, then the gaps
183ee67461eSJoseph Mingrone   would have to be bounds-checked using the `ND_TCHECK_*()` macros:
184ee67461eSJoseph Mingrone   ```
185ee67461eSJoseph Mingrone   ND_TCHECK_n(p), n in { 1, 2, 3, 4, 5, 6, 7, 8, 16 }
186ee67461eSJoseph Mingrone   ND_TCHECK_SIZE(p)
187ee67461eSJoseph Mingrone   ND_TCHECK_LEN(p, l)
188ee67461eSJoseph Mingrone   ```
189*0a7e5f1fSJoseph Mingrone
190*0a7e5f1fSJoseph Mingrone   where *p* points to the data not being decoded.  For `ND_CHECK_n()`,
191*0a7e5f1fSJoseph Mingrone   *n* is the length of the gap, in bytes.  For `ND_CHECK_SIZE()`, the
192*0a7e5f1fSJoseph Mingrone   length of the gap, in bytes, is the size of an item of the data type
193*0a7e5f1fSJoseph Mingrone   to which *p* points.  For `ND_CHECK_LEN()`, *l* is the length of the
194*0a7e5f1fSJoseph Mingrone   gap, in bytes.
195*0a7e5f1fSJoseph Mingrone
196*0a7e5f1fSJoseph Mingrone   For the `GET_*()` and `ND_TCHECK_*` macros (if not already done):
197ee67461eSJoseph Mingrone   * Assign: `ndo->ndo_protocol = "protocol";`
198ee67461eSJoseph Mingrone   * Define: `ND_LONGJMP_FROM_TCHECK` before including `netdissect.h`
199ee67461eSJoseph Mingrone   * Make sure that the intersection of `GET_*()` and `ND_TCHECK_*()` is minimal,
200ee67461eSJoseph Mingrone     but at the same time their union covers all packet data in all cases.
201ee67461eSJoseph Mingrone
202ee67461eSJoseph Mingrone   You can test the code via:
203ee67461eSJoseph Mingrone   ```
204ee67461eSJoseph Mingrone   sudo ./tcpdump -s snaplen [-v][v][...] -i lo # in a terminal
205ee67461eSJoseph Mingrone   sudo tcpreplay -i lo sample.pcap             # in another terminal
206ee67461eSJoseph Mingrone   ```
207ee67461eSJoseph Mingrone   You should try several values for snaplen to do various truncation.
208ee67461eSJoseph Mingrone
209*0a7e5f1fSJoseph Mingrone*  The `GET_*()` macros that fetch integral values are:
210*0a7e5f1fSJoseph Mingrone   ```
211*0a7e5f1fSJoseph Mingrone   GET_U_1(p)
212*0a7e5f1fSJoseph Mingrone   GET_S_1(p)
213*0a7e5f1fSJoseph Mingrone   GET_BE_U_n(p), n in { 2, 3, 4, 5, 6, 7, 8 }
214*0a7e5f1fSJoseph Mingrone   GET_BE_S_n(p), n in { 2, 3, 4, 5, 6, 7, 8 }
215*0a7e5f1fSJoseph Mingrone   GET_LE_U_n(p), n in { 2, 3, 4, 5, 6, 7, 8 }
216*0a7e5f1fSJoseph Mingrone   GET_LE_S_n(p), n in { 2, 3, 4, 5, 6, 7, 8 }
217*0a7e5f1fSJoseph Mingrone   ```
218*0a7e5f1fSJoseph Mingrone
219*0a7e5f1fSJoseph Mingrone   where *p* points to the integral value in the packet buffer. The
220*0a7e5f1fSJoseph Mingrone   macro returns the integral value at that location.
221*0a7e5f1fSJoseph Mingrone
222*0a7e5f1fSJoseph Mingrone   `U` indicates that an unsigned value is fetched; `S` indicates that a
223*0a7e5f1fSJoseph Mingrone   signed value is fetched.  For multi-byte values, `BE` indicates that
224*0a7e5f1fSJoseph Mingrone   a big-endian value ("network byte order") is fetched, and `LE`
225*0a7e5f1fSJoseph Mingrone   indicates that a little-endian value is fetched. *n* is the length,
226*0a7e5f1fSJoseph Mingrone   in bytes, of the multi-byte integral value to be fetched.
227*0a7e5f1fSJoseph Mingrone
228*0a7e5f1fSJoseph Mingrone   In addition to the bounds checking the `GET_*()` macros perform,
229*0a7e5f1fSJoseph Mingrone   using those macros has other advantages:
230*0a7e5f1fSJoseph Mingrone
231*0a7e5f1fSJoseph Mingrone   * tcpdump runs on both big-endian and little-endian systems, so
232*0a7e5f1fSJoseph Mingrone     fetches of multi-byte integral values must be done in a fashion
233*0a7e5f1fSJoseph Mingrone     that works regardless of the byte order of the machine running
234*0a7e5f1fSJoseph Mingrone     tcpdump.  The `GET_BE_*()` macros will fetch a big-endian value and
235*0a7e5f1fSJoseph Mingrone     return a host-byte-order value on both big-endian and little-endian
236*0a7e5f1fSJoseph Mingrone     machines, and the `GET_LE_*()` macros will fetch a little-endian
237*0a7e5f1fSJoseph Mingrone     value and return a host-byte-order value on both big-endian and
238*0a7e5f1fSJoseph Mingrone     little-endian machines.
239*0a7e5f1fSJoseph Mingrone
240*0a7e5f1fSJoseph Mingrone   * tcpdump runs on machines that do not support unaligned access to
241*0a7e5f1fSJoseph Mingrone     multi-byte values, and packet values are not guaranteed to be
242*0a7e5f1fSJoseph Mingrone     aligned on the proper boundary.  The `GET_BE_*()` and `GET_LE_*()`
243*0a7e5f1fSJoseph Mingrone     macros will fetch values even if they are not aligned on the proper
244*0a7e5f1fSJoseph Mingrone     boundary.
245*0a7e5f1fSJoseph Mingrone
246*0a7e5f1fSJoseph Mingrone*  The `GET_*()` macros that fetch IPv4 address values are:
247*0a7e5f1fSJoseph Mingrone   ```
248*0a7e5f1fSJoseph Mingrone   GET_IPV4_TO_HOST_ORDER(p)
249*0a7e5f1fSJoseph Mingrone   GET_IPV4_TO_NETWORK_ORDER(p)
250*0a7e5f1fSJoseph Mingrone   ```
251*0a7e5f1fSJoseph Mingrone
252*0a7e5f1fSJoseph Mingrone   where *p* points to the address in the packet buffer.
253*0a7e5f1fSJoseph Mingrone  `GET_IPV4_TO_HOST_ORDER()` returns the address in the byte order of
254*0a7e5f1fSJoseph Mingrone   the host that is running tcpdump; `GET_IPV4_TO_NETWORK_ORDER()`
255*0a7e5f1fSJoseph Mingrone   returns it in network byte order.
256*0a7e5f1fSJoseph Mingrone
257*0a7e5f1fSJoseph Mingrone   Like the integral `GET_*()` macros, these macros work correctly on
258*0a7e5f1fSJoseph Mingrone   both big-endian and little-endian machines and will fetch values even
259*0a7e5f1fSJoseph Mingrone   if they are not aligned on the proper boundary.
260*0a7e5f1fSJoseph Mingrone
261*0a7e5f1fSJoseph Mingrone*  The `GET_*()` macro that fetches an arbitrary sequences of bytes is:
262*0a7e5f1fSJoseph Mingrone   ```
263*0a7e5f1fSJoseph Mingrone   GET_CPY_BYTES(dst, p, len)
264*0a7e5f1fSJoseph Mingrone   ```
265*0a7e5f1fSJoseph Mingrone
266*0a7e5f1fSJoseph Mingrone   where *dst* is the destination to which the sequence of bytes should
267*0a7e5f1fSJoseph Mingrone   be copied, *p* points to the first byte of the sequence of bytes, and
268*0a7e5f1fSJoseph Mingrone   *len* is the number of bytes to be copied.  The bytes are copied in
269*0a7e5f1fSJoseph Mingrone   the order in which they appear in the packet.
270*0a7e5f1fSJoseph Mingrone
271*0a7e5f1fSJoseph Mingrone*  To fetch a network address and convert it to a printable string, use
272*0a7e5f1fSJoseph Mingrone   the following `GET_*()` macros, defined in `addrtoname.h`, to
273*0a7e5f1fSJoseph Mingrone   perform bounds checks to make sure the entire address is within the
274*0a7e5f1fSJoseph Mingrone   buffer and to translate the address to a string to print:
275*0a7e5f1fSJoseph Mingrone   ```
276*0a7e5f1fSJoseph Mingrone   GET_IPADDR_STRING(p)
277*0a7e5f1fSJoseph Mingrone   GET_IP6ADDR_STRING(p)
278*0a7e5f1fSJoseph Mingrone   GET_MAC48_STRING(p)
279*0a7e5f1fSJoseph Mingrone   GET_EUI64_STRING(p)
280*0a7e5f1fSJoseph Mingrone   GET_EUI64LE_STRING(p)
281*0a7e5f1fSJoseph Mingrone   GET_LINKADDR_STRING(p, type, len)
282*0a7e5f1fSJoseph Mingrone   GET_ISONSAP_STRING(nsap, nsap_length)
283*0a7e5f1fSJoseph Mingrone   ```
284*0a7e5f1fSJoseph Mingrone
285*0a7e5f1fSJoseph Mingrone   `GET_IPADDR_STRING()` fetches an IPv4 address pointed to by *p* and
286*0a7e5f1fSJoseph Mingrone   returns a string that is either a host name, if the `-n` flag wasn't
287*0a7e5f1fSJoseph Mingrone   specified and a host name could be found for the address, or the
288*0a7e5f1fSJoseph Mingrone   standard XXX.XXX.XXX.XXX-style representation of the address.
289*0a7e5f1fSJoseph Mingrone
290*0a7e5f1fSJoseph Mingrone   `GET_IP6ADDR_STRING()` fetches an IPv6 address pointed to by *p* and
291*0a7e5f1fSJoseph Mingrone   returns a string that is either a host name, if the `-n` flag wasn't
292*0a7e5f1fSJoseph Mingrone   specified and a host name could be found for the address, or the
293*0a7e5f1fSJoseph Mingrone   standard XXXX::XXXX-style representation of the address.
294*0a7e5f1fSJoseph Mingrone
295*0a7e5f1fSJoseph Mingrone   `GET_MAC48_STRING()` fetches a 48-bit MAC address (Ethernet, 802.11,
296*0a7e5f1fSJoseph Mingrone   etc.) pointed to by *p* and returns a string that is either a host
297*0a7e5f1fSJoseph Mingrone   name, if the `-n` flag wasn't specified and a host name could be
298*0a7e5f1fSJoseph Mingrone   found in the ethers file for the address, or the standard
299*0a7e5f1fSJoseph Mingrone   XX:XX:XX:XX:XX:XX-style representation of the address.
300*0a7e5f1fSJoseph Mingrone
301*0a7e5f1fSJoseph Mingrone   `GET_EUI64_STRING()` fetches a 64-bit EUI pointed to by *p* and
302*0a7e5f1fSJoseph Mingrone   returns a string that is the standard XX:XX:XX:XX:XX:XX:XX:XX-style
303*0a7e5f1fSJoseph Mingrone   representation of the address.
304*0a7e5f1fSJoseph Mingrone
305*0a7e5f1fSJoseph Mingrone   `GET_EUI64LE_STRING()` fetches a 64-bit EUI, in reverse byte order,
306*0a7e5f1fSJoseph Mingrone   pointed to by *p* and returns a string that is the standard
307*0a7e5f1fSJoseph Mingrone   XX:XX:XX:XX:XX:XX:XX:XX-style representation of the address.
308*0a7e5f1fSJoseph Mingrone
309*0a7e5f1fSJoseph Mingrone   `GET_LINKADDR_STRING()` fetches an octet string, of length *length*
310*0a7e5f1fSJoseph Mingrone   and type *type*,  pointed to by *p* and returns a string whose format
311*0a7e5f1fSJoseph Mingrone   depends on the value of *type*:
312*0a7e5f1fSJoseph Mingrone
313*0a7e5f1fSJoseph Mingrone   * `LINKADDR_MAC48` - if the length is 6, the string has the same
314*0a7e5f1fSJoseph Mingrone   value as `GET_MAC48_STRING()` would return for that address,
315*0a7e5f1fSJoseph Mingrone   otherwise, the string is a sequence of XX:XX:... values for the bytes
316*0a7e5f1fSJoseph Mingrone   of the address;
317*0a7e5f1fSJoseph Mingrone
318*0a7e5f1fSJoseph Mingrone   * `LINKADDR_FRELAY` - the string is "DLCI XXX", where XXX is the
319*0a7e5f1fSJoseph Mingrone   DLCI, if the address is a valid Q.922 header, and an error indication
320*0a7e5f1fSJoseph Mingrone   otherwise;
321*0a7e5f1fSJoseph Mingrone
322*0a7e5f1fSJoseph Mingrone   * `LINKADDR_EUI64`, `LINKADDR_ATM`, `LINKADDR_OTHER` -
323*0a7e5f1fSJoseph Mingrone   the string is a sequence of XX:XX:... values for the bytes
324*0a7e5f1fSJoseph Mingrone   of the address.
325*0a7e5f1fSJoseph Mingrone
326*0a7e5f1fSJoseph Mingrone6) When defining a structure corresponding to a packet or part of a
327*0a7e5f1fSJoseph Mingrone   packet, so that a pointer to packet data can be cast to a pointer to
328*0a7e5f1fSJoseph Mingrone   that structure and that structure pointer used to refer to fields in
329*0a7e5f1fSJoseph Mingrone   the packet, use the `nd_*` types for the structure members.
330*0a7e5f1fSJoseph Mingrone
331*0a7e5f1fSJoseph Mingrone   Those types all are aligned only on a 1-byte boundary, so a
332*0a7e5f1fSJoseph Mingrone   compiler will not assume that the structure is aligned on a boundary
333*0a7e5f1fSJoseph Mingrone   stricter than one byte; there is no guarantee that fields in packets
334*0a7e5f1fSJoseph Mingrone   are aligned on any particular boundary.
335*0a7e5f1fSJoseph Mingrone
336*0a7e5f1fSJoseph Mingrone   This means that all padding in the structure must be explicitly
337*0a7e5f1fSJoseph Mingrone   declared as fields in the structure.
338*0a7e5f1fSJoseph Mingrone
339*0a7e5f1fSJoseph Mingrone   The `nd_*` types for integral values are:
340*0a7e5f1fSJoseph Mingrone
341*0a7e5f1fSJoseph Mingrone   * `nd_uintN_t`, for unsigned integral values, where *N* is the number
342*0a7e5f1fSJoseph Mingrone      of bytes in the value.
343*0a7e5f1fSJoseph Mingrone   * `nd_intN_t`, for signed integral values, where *N* is the number
344*0a7e5f1fSJoseph Mingrone      of bytes in the value.
345*0a7e5f1fSJoseph Mingrone
346*0a7e5f1fSJoseph Mingrone   The `nd_*` types for IP addresses are:
347*0a7e5f1fSJoseph Mingrone
348*0a7e5f1fSJoseph Mingrone   * `nd_ipv4`, for IPv4 addresses;
349*0a7e5f1fSJoseph Mingrone   * `nd_ipv6`, for IPv6 addresses.
350*0a7e5f1fSJoseph Mingrone
351*0a7e5f1fSJoseph Mingrone   The `nd_*` types for link-layer addresses are:
352*0a7e5f1fSJoseph Mingrone
353*0a7e5f1fSJoseph Mingrone   * `nd_mac48`, for MAC-48 (Ethernet, 802.11, etc.) addresses;
354*0a7e5f1fSJoseph Mingrone   * `nd_eui64`, for EUI-64 values.
355*0a7e5f1fSJoseph Mingrone
356*0a7e5f1fSJoseph Mingrone   The `nd_*` type for a byte in a sequence of bytes is `nd_byte`; an
357*0a7e5f1fSJoseph Mingrone   *N*-byte sequence should be declared as `nd_byte[N]`.
358*0a7e5f1fSJoseph Mingrone
359*0a7e5f1fSJoseph Mingrone7) Do invalid packet checks in code: Think that your code can receive in input
360ee67461eSJoseph Mingrone   not only a valid packet but any arbitrary random sequence of octets (packet
361ee67461eSJoseph Mingrone   * built malformed originally by the sender or by a fuzz tester,
362ee67461eSJoseph Mingrone   * became corrupted in transit or for some other reason).
363ee67461eSJoseph Mingrone
364ee67461eSJoseph Mingrone   Print with: `nd_print_invalid(ndo);	/* to print " (invalid)" */`
365ee67461eSJoseph Mingrone
366*0a7e5f1fSJoseph Mingrone8) Use `struct tok` for indexed strings and print them with
367ee67461eSJoseph Mingrone   `tok2str()` or `bittok2str()` (for flags).
368*0a7e5f1fSJoseph Mingrone   All `struct tok` must end with `{ 0, NULL }`.
369ee67461eSJoseph Mingrone
370*0a7e5f1fSJoseph Mingrone9) Avoid empty lines in output of printers.
371ee67461eSJoseph Mingrone
372*0a7e5f1fSJoseph Mingrone10) A commit message must have:
373ee67461eSJoseph Mingrone   ```
374ee67461eSJoseph Mingrone   First line: Capitalized short summary in the imperative (50 chars or less)
375ee67461eSJoseph Mingrone
376ee67461eSJoseph Mingrone   If the commit concerns a protocol, the summary line must start with
377ee67461eSJoseph Mingrone   "protocol: ".
378ee67461eSJoseph Mingrone
379ee67461eSJoseph Mingrone   Body: Detailed explanatory text, if necessary. Fold it to approximately
380ee67461eSJoseph Mingrone   72 characters. There must be an empty line separating the summary from
381ee67461eSJoseph Mingrone   the body.
382ee67461eSJoseph Mingrone   ```
383ee67461eSJoseph Mingrone
384*0a7e5f1fSJoseph Mingrone11) Avoid non-ASCII characters in code and commit messages.
385ee67461eSJoseph Mingrone
386*0a7e5f1fSJoseph Mingrone12) Use the style of the modified sources.
387ee67461eSJoseph Mingrone
388*0a7e5f1fSJoseph Mingrone13) Don't mix declarations and code.
389ee67461eSJoseph Mingrone
390*0a7e5f1fSJoseph Mingrone14) tcpdump requires a compiler that supports C99 or later, so C99
391*0a7e5f1fSJoseph Mingrone   features may be used in code, but C11 or later features should not be
392*0a7e5f1fSJoseph Mingrone   used.
393ee67461eSJoseph Mingrone
394*0a7e5f1fSJoseph Mingrone15) Avoid trailing tabs/spaces
395