1 This file is a HOWTO for Wireshark developers. It describes general development
2 and coding practices for contributing to Wireshark no matter which part of
3 Wireshark you want to work on.
5 To learn how to write a dissector, read this first, then read the file
8 This file is compiled to give in depth information on Wireshark.
9 It is by no means all inclusive and complete. Please feel free to discuss on
10 the developer mailing list or upload merge requests to gitlab.
14 Before starting to develop a new dissector, a "running" Wireshark build
15 environment is required - there's no such thing as a standalone "dissector
18 How to setup such an environment is platform dependent; detailed
19 information about these steps can be found in the "Developer's Guide"
20 (available from: https://www.wireshark.org) and in the INSTALL and
21 README.md files of the sources root dir.
23 0.1. General README files.
25 You'll find additional information in the following README files:
27 - doc/README.capture - the capture engine internals
28 - doc/README.design - Wireshark software design - incomplete
29 - doc/README.developer - this file
30 - doc/README.dissector - How to dissect a packet
31 - doc/README.display_filter - Display Filter Engine
32 - doc/README.idl2wrs - CORBA IDL converter
33 - doc/README.regression - regression testing of WS and TS
34 - doc/README.stats_tree - a tree statistics counting specific packets
35 - doc/README.tapping - "tap" a dissector to get protocol specific events
36 - doc/README.vagrant - how to create a development VM using vagrant
37 - doc/README.wslua - working with LUA
38 - doc/README.xml-output - how to work with the PDML exported output
39 - wiretap/README.developer - how to add additional capture file types to
42 0.2. Dissector related README files.
44 You'll find additional dissector related information in the file
45 README.dissector as well as the following README files:
47 - doc/README.heuristic - what are heuristic dissectors and how to write
49 - doc/README.plugins - how to "pluginize" a dissector
50 - doc/README.request_response_tracking - how to track req./resp. times and such
51 - doc/README.wmem - how to obtain "memory leak free" memory
55 James Coe <jammer[AT]cin.net>
56 Gilbert Ramirez <gram[AT]alumni.rice.edu>
57 Jeff Foster <jfoste[AT]woodward.com>
58 Olivier Abad <oabad[AT]cybercable.fr>
59 Laurent Deniel <laurent.deniel[AT]free.fr>
60 Gerald Combs <gerald[AT]wireshark.org>
61 Guy Harris <guy[AT]alum.mit.edu>
62 Ulf Lamping <ulf.lamping[AT]web.de>
66 Wireshark runs on many platforms, and can be compiled with a number of
67 different compilers; here are some rules for writing code that will work
68 on multiple platforms.
70 Building Wireshark requires a compiler that supports C11. This includes
71 reasonably recent versions of GCC and clang. Microsoft Visual Studio supports
72 C11 from Visual Studio 2019 version 16.8 and later. Support requires an updated
73 Universal C Runtime (UCRT) and Windows SDK version to work properly with the
74 conforming preprocessor. The minimum SDK version is 10.0.20348.0 (version 2104).
76 The C11 has some optional parts that are not a requirement to build Wireshark.
77 In particular the following optional C11 features must NOT be used:
78 - Variable length arrays
79 - Bounds-checking interfaces (Annex K)
81 We don't allow them because their value is questionable and requiring them
82 would exclude a lot of compilers and runtimes that we wish to support.
84 Don't initialize global or static variables (variables with static
85 storage duration) in their declaration with non-constant values. This is not
86 permitted in C. E.g., if "i" is a static or global
87 variable, don't declare "i" as
89 uint32_t i = somearray[2];
91 outside a function, or as
93 static uint32_t i = somearray[2];
95 inside or outside a function, declare it as just
103 and later, in code, initialize it with
107 instead. Initializations of variables with automatic storage duration -
108 i.e., local variables - with non-constant values is permitted, so,
111 uint32_t i = somearray[2];
115 Don't use zero-length arrays as structure members, use flexible array members
118 Don't use "uchar", "u_char", "ushort", "u_short", "uint", "u_int",
119 "ulong", "u_long" or "boolean"; they aren't defined on all platforms.
121 GLib typedefs have historically been used extensively throughout the
122 codebase (gchar, guint8, gint16, etc). We are moving towards the fixed
123 width integers provided in C since C99. These are defined in <stdint.h>,
124 which is included in <wireshark.h>. You should choose stdint types when
125 possible, but realise that until we can fully migrate our APIs, in many
126 situations the GLib types still make sense.
128 If you want an 8-bit unsigned quantity, use "uint8_t"; if you want an
129 8-bit character value with the 8th bit not interpreted as a sign bit,
130 use "unsigned char"; if you want a 16-bit unsigned quantity, use "uint16_t";
131 if you want a 32-bit unsigned quantity, use "uint32_t"; and if you want
132 an "int-sized" unsigned quantity, use "unsigned"; if you want a boolean,
133 use "bool" (defined in <stdbool.h>). You don't need to explicitly include
134 these headers; they are included in <wireshark.h>. Use that instead.
136 To print fixed width integers you must use the macros provided in <inttypes.h>.
139 printf("var = " PRIu32 "\n", var);
141 Don't use "long" to mean "signed 32-bit integer", and don't use
142 "unsigned long" to mean "unsigned 32-bit integer"; "long"s are 64 bits
143 long on many platforms. Use "int32_t" for signed 32-bit integers and use
144 "uint32_t" for unsigned 32-bit integers.
146 Don't use "long" to mean "signed 64-bit integer" and don't use "unsigned
147 long" to mean "unsigned 64-bit integer"; "long"s are 32 bits long on
148 many other platforms. Don't use "long long" or "unsigned long long",
149 either, as not all platforms support them; use "int64_t" or "uint64_t",
150 which will be defined as the appropriate types for 64-bit signed and
153 On LLP64 data model systems (notably 64-bit Windows), "int" and "long"
154 are 32 bits while "size_t" and "ptrdiff_t" are 64 bits. This means that
155 the following will generate a compiler warning:
158 i = strlen("hello, sailor"); /* Compiler warning */
160 Normally, you'd just make "i" a size_t. However, many GLib and Wireshark
161 functions won't accept a size_t on LLP64:
164 char greeting[] = "hello, sailor";
165 unsigned byte_after_greet;
167 i = strlen(greeting);
168 byte_after_greet = tvb_get_uint8(tvb, i); /* Compiler warning */
170 Try to use the appropriate data type when you can. When you can't, you
171 will have to cast to a compatible data type, e.g.
174 char greeting[] = "hello, sailor";
175 uint8_t byte_after_greet;
177 i = strlen(greeting);
178 byte_after_greet = tvb_get_uint8(tvb, (int) i); /* OK */
183 char greeting[] = "hello, sailor";
184 uint8_t byte_after_greet;
186 i = (int) strlen(greeting);
187 byte_after_greet = tvb_get_uint8(tvb, i); /* OK */
189 See https://unix.org/version2/whatsnew/lp64_wp.html for more
190 information on the sizes of common types in different data models.
192 A lot of legacy code still uses GLib types and I/O replacement API. These
193 should be gradually transitioned to use the standard interfaces provided in
194 C11. Sometimes it may be necessary to use an unsavory cast or two or abuse
195 a macro to bridge the two codebases during the transition. Such is life,
196 use your judgement and do the best possible under the circumstances.
198 Avoid GLib synonyms like gchar and gint and especially don't
199 use gpointer and gconstpointer, unless you are writing GLib callbacks
200 and trying to match their signature exactly. These just obscure the
201 code and gconstpointer in particular is just semantically weird and poor style.
203 When printing or displaying the values of 64-bit integral data types,
204 don't use "%lld", "%llu", "%llx", or "%llo" - not all platforms
205 support "%ll" for printing 64-bit integral data types. Instead use
206 the macros in <inttypes.h>, for example:
208 proto_tree_add_uint64_format_value(tree, hf_uint64, tvb, offset, len,
209 val, "%" PRIu64, val);
211 GLib provides the G_GUINT64_FORMAT and G_GINT64_FORMAT specifiers for
212 64-bit integral types. You should use PRIu64 and PRId64 instead.
214 When specifying an integral constant that doesn't fit in 32 bits, don't
215 use "LL" at the end of the constant - not all compilers use "LL" for
216 that. Instead, put the constant in a call to the "INT64_C()" or "UINT64_C()"
219 INT64_C(-11644473600), UINT64_C(11644473600)
223 -11644473600LL, 11644473600ULL
225 Don't assume that you can scan through a va_list initialized by va_start
226 more than once without closing it with va_end and re-initializing it with
227 va_start. This applies even if you're not scanning through it yourself,
228 but are calling a routine that scans through it, such as vfprintf() or
229 one of the routines in Wireshark that takes a format and a va_list as an
230 argument. You must do
232 va_start(ap, format);
233 call_routine1(xxx, format, ap);
235 va_start(ap, format);
236 call_routine2(xxx, format, ap);
241 va_start(ap, format);
242 call_routine1(xxx, format, ap);
243 call_routine2(xxx, format, ap);
246 Don't use a label without a statement following it. For example,
256 will not work with all compilers - you have to do
266 with some statement, even if it's a null statement, after the label.
267 Preferably don't do it at all.
269 Don't use "bzero()", "bcopy()", or "bcmp()"; instead, use the ANSI C
272 "memset()" (with zero as the second argument, so that it sets
273 all the bytes to zero);
275 "memcpy()" or "memmove()" (note that the first and second
276 arguments to "memcpy()" are in the reverse order to the
277 arguments to "bcopy()"; note also that "bcopy()" is typically
278 guaranteed to work on overlapping memory regions, while
279 "memcpy()" isn't, so if you may be copying from one region to a
280 region that overlaps it, use "memmove()", not "memcpy()" - but
281 "memcpy()" might be faster as a result of not guaranteeing
282 correct operation on overlapping memory regions);
284 and "memcmp()" (note that "memcmp()" returns 0, 1, or -1, doing
285 an ordered comparison, rather than just returning 0 for "equal"
286 and 1 for "not equal", as "bcmp()" does).
288 Not all platforms necessarily have "bzero()"/"bcopy()"/"bcmp()", and
289 those that do might not declare them in the header file on which they're
290 declared on your platform.
292 Don't use "index()" or "rindex()"; instead, use the ANSI C equivalents,
293 "strchr()" and "strrchr()". Not all platforms necessarily have
294 "index()" or "rindex()", and those that do might not declare them in the
295 header file on which they're declared on your platform.
297 Don't use "tvb_get_ptr()". If you must use it, keep in mind that the pointer
298 returned by a call to "tvb_get_ptr()" is not guaranteed to be aligned on any
299 particular byte boundary; this means that you cannot safely cast it to any
300 data type other than a pointer to "char", "unsigned char", "guint8", or other
301 one-byte data types. Casting a pointer returned by tvb_get_ptr() into any
302 multi-byte data type or structure may cause crashes on some platforms (even
303 if it does not crash on x86-based PCs). Even if such mis-aligned accesses
304 don't crash on your platform they will be slower than properly aligned
305 accesses would be. Furthermore, the data in a packet is not necessarily in
306 the byte order of the machine on which Wireshark is running. Use the tvbuff
307 routines to extract individual items from the packet, or, better yet, use
308 "proto_tree_add_item()" and let it extract the items for you.
310 Don't use structures that overlay packet data, or into which you copy
311 packet data; the C programming language does not guarantee any
312 particular alignment of fields within a structure, and even the
313 extensions that try to guarantee that are compiler-specific and not
314 necessarily supported by all compilers used to build Wireshark. Using
315 bitfields in those structures is even worse; the order of bitfields
318 Don't use "ntohs()", "ntohl()", "htons()", or "htonl()"; the header
319 files required to define or declare them differ between platforms, and
320 you might be able to get away with not including the appropriate header
321 file on your platform but that might not work on other platforms.
322 Instead, use "g_ntohs()", "g_ntohl()", "g_htons()", and "g_htonl()";
323 those are declared by <glib.h>, and you'll need to include that anyway,
324 as Wireshark header files that all dissectors must include use stuff from
327 Don't fetch a little-endian value using "tvb_get_ntohs() or
328 "tvb_get_ntohl()" and then using "g_ntohs()", "g_htons()", "g_ntohl()",
329 or "g_htonl()" on the resulting value - the g_ routines in question
330 convert between network byte order (big-endian) and *host* byte order,
331 not *little-endian* byte order; not all machines on which Wireshark runs
332 are little-endian, even though PCs are. Fetch those values using
333 "tvb_get_letohs()" and "tvb_get_letohl()".
335 Do not use "open()", "rename()", "mkdir()", "stat()", "unlink()", "remove()",
336 "fopen()", "freopen()" directly. Instead use "ws_open()", "ws_rename()",
337 "ws_mkdir()", "ws_stat()", "ws_unlink()", "ws_remove()", "ws_fopen()",
338 "ws_freopen()": these wrapper functions change the path and file name from
339 UTF-8 to UTF-16 on Windows allowing the functions to work correctly when the
340 path or file name contain non-ASCII characters.
342 Also, use ws_read(), ws_write(), ws_lseek(), ws_dup(), ws_fstat(), and
343 ws_fdopen(), rather than read(), write(), lseek(), dup(), fstat(), and
344 fdopen() on descriptors returned by ws_open().
346 Those functions are declared in <wsutil/file_util.h>; include that
347 header in any code that uses any of those routines.
349 When opening a file with "ws_fopen()", "ws_freopen()", or "ws_fdopen()", if
350 the file contains ASCII text, use "r", "w", "a", and so on as the open mode
351 - but if it contains binary data, use "rb", "wb", and so on. On
352 Windows, if a file is opened in a text mode, writing a byte with the
353 value of octal 12 (newline) to the file causes two bytes, one with the
354 value octal 15 (carriage return) and one with the value octal 12, to be
355 written to the file, and causes bytes with the value octal 15 to be
356 discarded when reading the file (to translate between C's UNIX-style
357 lines that end with newline and Windows' DEC-style lines that end with
358 carriage return/line feed).
360 In addition, that also means that when opening or creating a binary
361 file, you must use "ws_open()" (with O_CREAT and possibly O_TRUNC if the
362 file is to be created if it doesn't exist), and OR in the O_BINARY flag,
363 even on UN*X - O_BINARY is defined by <wsutil/file_util.h> as 0 on UN*X.
365 Do not include <unistd.h>, <fcntl.h>, or <io.h> to declare any of the
366 routines listed as replaced by routines in <wsutil/file_util.h>;
367 instead, just include <wsutil/file_util.h>.
369 If you need the declarations of other functions defined by <unistd.h>,
370 don't include it without protecting it with
378 Don't use forward declarations of static arrays without a specified size
379 in a fashion such as this:
381 static const value_string foo_vals[];
385 static const value_string foo_vals[] = {
392 as some compilers will reject the first of those statements. Instead,
393 initialize the array at the point at which it's first declared, so that
396 For #define names and enum member names, prefix the names with a tag so
397 as to avoid collisions with other names - this might be more of an issue
398 on Windows, as it appears to #define names such as DELETE and
401 Don't use the "positional parameters" extension that many UNIX printf's
404 snprintf(add_string, 30, " - (%1$d) (0x%1$04x)", value);
406 as not all UNIX printf's implement it, and Windows printf doesn't appear
407 to implement it. Use something like
409 snprintf(add_string, 30, " - (%d) (0x%04x)", value, value);
417 as that's not supported by all compilers.
419 Prefer the C99 output functions from <stdio.h> instead of their GLib
420 replacements (note that positional format parameters are not part of C99).
421 In the past we used to recommend using g_snprintf() and g_vsnprintf()
422 instead but since Visual Studio 2015 native C99 implementations are
423 available on all platforms we support. These are optimized better than
424 the gnulib (GLib) implementation and on hot codepaths that can be a
425 noticeable difference in execution speed.
427 tmpnam() -> mkstemp()
428 tmpnam is insecure and should not be used any more. Wireshark brings its
429 own mkstemp implementation for use on platforms that lack mkstemp.
430 Note: mkstemp does not accept NULL as a parameter.
432 Wireshark requires minimum versions of each of the libraries it uses, in
433 particular GLib 2.54.0 and Qt 5.15.0 or newer. If you require a mechanism
434 that is available only in a newer version of a library then use its
435 version detection macros, e.g. "#if GLIB_CHECK_VERSION(...)" and "#if
436 QT_VERSION_CHECK(...)" to conditionally compile code using that
439 When different code must be used on UN*X and Win32, use a #if or #ifdef
440 that tests _WIN32, not WIN32. Try to write code portably whenever
441 possible, however; note that there are some routines in Wireshark with
442 platform-dependent implementations and platform-independent APIs, such
443 as the routines in epan/filesystem.c, allowing the code that calls it to
444 be written portably without #ifdefs.
446 We support building on Windows using MinGW-w64 (experimental) so be mindful
447 of the difference between an #ifdef on _WIN32 and _MSC_VER. The first tests
448 if the platform is some version of Windows and also applies to MinGW. The
449 latter tests if the toolchain is Microsoft Visual Studio. Sometimes you need
450 one or the other, depending on whether the condition applies to all Windows
451 compilers or only Microsoft's compiler. Use #ifdef __MINGW32__ to test for
452 a MinGW toolchain, including MinGW-w64. The same concern applies to CMake
453 code. Depending on the particular situation you may need to use if(WIN32) or
454 if(MSVC) or if(MINGW).
456 Wireshark uses Libgcrypt as general-purpose crypto library. Some Wireshark
457 specific extensions are defined in wsutil/wsgcrypt.h. You might want to
458 include that file instead.
462 Do not use functions such as strcat() or strcpy().
463 A lot of work has been done to remove the existing calls to these functions and
464 we do not want any new callers of these functions.
466 Instead use snprintf() since that function will if used correctly prevent
467 buffer overflows for large strings.
469 Be sure that all pointers passed to %s specifiers in format strings are non-
470 NULL. Some implementations will automatically replace NULL pointers with the
471 string "(NULL)", but most will not.
473 When using a buffer to create a string, do not use a buffer stored on the stack.
474 I.e. do not use a buffer declared as
478 instead allocate a buffer dynamically using the string-specific or plain wmem
479 routines (see README.wmem) such as
481 wmem_strbuf_t *strbuf;
482 strbuf = wmem_strbuf_new(pinfo->pool, "");
483 wmem_strbuf_append_printf(strbuf, ...
489 #define MAX_BUFFER 1024
490 buffer=wmem_alloc(pinfo->pool, MAX_BUFFER);
493 snprintf(buffer, MAX_BUFFER, ...
495 This avoids the stack from being corrupted in case there is a bug in your code
496 that accidentally writes beyond the end of the buffer.
499 If you write a routine that will create and return a pointer to a filled in
500 string and if that buffer will not be further processed or appended to after
501 the routine returns (except being added to the proto tree),
502 do not preallocate the buffer to fill in and pass as a parameter instead
503 pass a pointer to a pointer to the function and return a pointer to a
504 wmem-allocated buffer that will be automatically freed. (see README.wmem)
506 I.e. do not write code such as
508 foo_to_str(char *string, ... ){
514 foo_to_str(buffer, ...
515 proto_tree_add_string(... buffer ...
517 instead write the code as
519 foo_to_str(char **buffer, ...
521 *buffer=wmem_alloc(pinfo->pool, MAX_BUFFER);
527 foo_to_str(&buffer, ...
528 proto_tree_add_string(... *buffer ...
530 Use wmem_ allocated buffers. They are very fast and nice. These buffers are all
531 automatically free()d when the dissection of the current packet ends so you
532 don't have to worry about free()ing them explicitly in order to not leak memory.
533 Please read README.wmem.
535 Source files can use UTF-8 encoding, but characters outside the ASCII
536 range should be used sparingly. It should be safe to use non-ASCII
537 characters in comments and strings, but some compilers (such as GCC
538 versions prior to 10) may not support extended identifiers very well.
539 There is also no guarantee that a developer's text editor will interpret
540 the characters the way you intend them to be interpreted.
542 The majority of Wireshark encodes strings as UTF-8. The main exception
543 is the code that uses the Qt API, which uses UTF-16. Console output is
544 UTF-8, but as with the source code extended characters should be used
545 sparingly since some consoles (most notably Windows' cmd.exe) have
546 limited support for UTF-8.
550 Wireshark is not guaranteed to read only network traces that contain correctly-
551 formed packets. Wireshark is commonly used to track down networking
552 problems, and the problems might be due to a buggy protocol implementation
553 sending out bad packets.
555 Therefore, code does not only have to be able to handle
556 correctly-formed packets without, for example, crashing or looping
557 infinitely, they also have to be able to handle *incorrectly*-formed
558 packets without crashing or looping infinitely.
560 Here are some suggestions for making code more robust in the face
561 of incorrectly-formed packets:
563 Do *NOT* use "ws_assert()" or "ws_assert_not_reached()" with input data in dissectors.
564 *NO* value in a packet's data should be considered "wrong" in the sense
565 that it's a problem with the dissector if found; if it cannot do
566 anything else with a particular value from a packet's data, the
567 dissector should put into the protocol tree an indication that the
568 value is invalid, and should return. The "expert" mechanism should be
569 used for that purpose.
571 Use assertions to catch logic errors in your program. A failed assertion
572 indicates a bug in the code. Use ws_assert() instead of g_assert() to
573 test a logic condition. Note that ws_assert() can be removed at compile
574 time. Therefore assertions should not have any side-effects,
575 otherwise the program may behave inconsistently.
577 Use ws_assert_not_reached() instead of g_assert_not_reached() for
578 unreachable error conditions. For example if (and only if) you know
579 'myvar' can only have the values 1 and 2 do:
588 ws_assert_not_reached();
592 For dissectors use DISSECTOR_ASSERT() and DISSECTOR_ASSERT_NOT_REACHED()
593 instead, with the same caveats as above.
595 You should continue to use g_assert_true(), g_assert_cmpstr(), etc for
596 "test code", such as unit testing. These assertions are always active.
597 See the GLib Testing API documentation for the details on each of those
600 If there is a case where you are checking not for an invalid data item
601 in the packet, but for a bug in the dissector (for example, an
602 assumption being made at a particular point in the code about the
603 internal state of the dissector), use the DISSECTOR_ASSERT macro for
604 that purpose; this will put into the protocol tree an indication that
605 the dissector has a bug in it, and will not crash the application.
607 If you are allocating a chunk of memory to contain data from a packet,
608 or to contain information derived from data in a packet, and the size of
609 the chunk of memory is derived from a size field in the packet, make
610 sure all the data is present in the packet before allocating the buffer.
613 1) Wireshark won't leak that chunk of memory if an attempt to
614 fetch data not present in the packet throws an exception.
618 2) it won't crash trying to allocate an absurdly-large chunk of
619 memory if the size field has a bogus large value.
621 If you're fetching into such a chunk of memory a sequence of bytes from
622 the buffer, and the sequence has a specified size, you can use
623 "tvb_memdup()", which will check whether the entire sequence is present
624 before allocating a buffer for it.
626 Otherwise, you can check whether the data is present by using
627 "tvb_ensure_bytes_exist()" although this frequently is not needed: the
628 TVB-accessor routines can handle requests to read data beyond the end of
629 the TVB (by throwing an exception which will either mark the frame as
630 truncated--not all the data was captured--or as malformed).
632 If you're fetching a string only to add it to the tree, you should
633 generally be using "proto_tree_add_item()" instead. If you also need
634 the string, you can use the variant "proto_tree_add_item_ret_string()"
635 or "proto_tree_add_item_ret_string_and_length()" forms.
637 If you must fetch it from the tvbuff, and the string has a specified
638 size and known encoding, you can use "tvb_get_string_enc()" for most
639 encodings, which will check whether the entire string is present before
640 allocating a buffer for the string, will put a trailing '\0' at the end
641 of the buffer, and will also check for invalid characters in the supplied
642 encoding and convert the string to UTF-8. The "tvb_get_*_string()" set of
643 functions is available as well, and must be used for some encodings,
644 primarily non byte aligned ones. If the string has a known encoding and
645 is null terminated, the "stringz" variants can be used. (Note that these
646 functions are called with memory allocators, and if called with a NULL
647 allocator you are required to free the string when finished with it.)
649 If the string has a known encoding but requires token parsing or other
650 text manipulation to determine the offset and size, do so by calling
651 tvb_*() functions on the tvbuff that perform bounds checking if possible.
652 Only extract the bytes into a newly allocated buffer to extract a string
653 if absolutely necessary. If you do so, then you *must* ensure that the
654 string is valid UTF-8 when passing it to a libwireshark API function
655 such as proto_tree_add_string(). (Cf. 7.5: Unicode and string encoding
658 Conversion to UTF-8 can produce a string with a length longer than
659 that of the string in the original packet data; this includes strings
660 encoded in ASCII or UTF-8 itself if they have invalid character sequences
661 that are replaced with the 3 byte UTF-8 REPLACEMENT CHARACTER. Truncating
662 a valid UTF-8 string to an arbitrary number of bytes does not guarantee
663 that the result is a valid UTF-8 string, because a multibyte character
664 might span the boundary.
666 Note also that you should only fetch string data into a fixed-length
667 buffer if the code ensures that no more bytes than will fit into the
668 buffer are fetched ("the protocol ensures" isn't good enough, as
669 protocol specifications can't ensure only packets that conform to the
670 specification will be transmitted or that only packets for the protocol
671 in question will be interpreted as packets for that protocol by
674 If you have gotten a pointer using "tvb_get_ptr()" (which you should not
675 have: you should seriously consider a better alternative to this function),
676 you must make sure that you do not refer to any data past the length passed
677 as the last argument to "tvb_get_ptr()"; while the various "tvb_get"
678 routines perform bounds checking and throw an exception if you refer to data
679 not available in the tvbuff, direct references through a pointer gotten from
680 "tvb_get_ptr()" do not do any bounds checking.
682 If you have a loop that dissects a sequence of items, each of which has
683 a length field, with the offset in the tvbuff advanced by the length of
684 the item, then, if the length field is the total length of the item, and
685 thus can be zero, you *MUST* check for a zero-length item and abort the
686 loop if you see one. Otherwise, a zero-length item could cause the
687 dissector to loop infinitely. You should also check that the offset,
688 after having the length added to it, is greater than the offset before
689 the length was added to it, if the length field is greater than 24 bits
690 long, so that, if the length value is *very* large and adding it to the
691 offset causes an overflow, that overflow is detected.
695 for (i = {start}; i < {end}; i++)
697 loop, make sure that the type of the loop index variable is large enough
698 to hold the maximum {end} value plus 1; otherwise, the loop index
699 variable can overflow before it ever reaches its maximum value. In
700 particular, be very careful when using int8_t, uint8_t, int16_t, or uint16_t
701 (or the deprecated Glib synonyms gint8, guint8, gint16, or guint16)
702 variables as loop indices; you almost always want to use an "int"/"gint"
703 or "unsigned"/"guint" as the loop index rather than a shorter type.
705 If you are fetching a length field from the buffer, corresponding to the
706 length of a portion of the packet, and subtracting from that length a
707 value corresponding to the length of, for example, a header in the
708 packet portion in question, *ALWAYS* check that the value of the length
709 field is greater than or equal to the length you're subtracting from it,
710 and report an error in the packet and stop dissecting the packet if it's
711 less than the length you're subtracting from it. Otherwise, the
712 resulting length value will be negative, which will either cause errors
713 in the dissector or routines called by the dissector, or, if the value
714 is interpreted as an unsigned integer, will cause the value to be
715 interpreted as a very large positive value.
717 Any tvbuff offset that is added to as processing is done on a packet
718 should be stored in a 32-bit variable, such as an "int"; if you store it
719 in an 8-bit or 16-bit variable, you run the risk of the variable
722 If your dissector uses recursion, you must ensure that your code does
723 not do so excessively. If there isn't an inherent limit on recursion in
724 your dissector, you can can add one using increment_dissection_depth and
725 decrement_dissection_depth. Wireshark's CI system uses Clang-tidy to
726 check for recursion; you might also need to add suppressions described at
727 https://clang.llvm.org/extra/clang-tidy/#suppressing-undesired-diagnostics
728 in order to pass CI checks.
730 sprintf() -> snprintf()
731 Prevent yourself from using the sprintf() function, as it does not test the
732 length of the given output buffer and might be writing into unintended memory
733 areas. This function is one of the main causes of security problems like buffer
734 exploits and many other bugs that are very hard to find. It's much better to
735 use the snprintf() function declared by <stdio.h> instead.
737 You should test your dissector against incorrectly-formed packets. This
738 can be done using the randpkt and editcap utilities that come with the
739 Wireshark distribution. Testing using randpkt can be done by generating
740 output at the same layer as your protocol, and forcing Wireshark/TShark
741 to decode it as your protocol, e.g. if your protocol sits on top of UDP:
743 randpkt -c 50000 -t dns randpkt.pcap
744 tshark -nVr randpkt.pcap -d udp.port==53,<myproto>
746 Testing using editcap can be done using preexisting capture files and the
747 "-E" flag, which introduces errors in a capture file. E.g.:
749 editcap -E 0.03 infile.pcap outfile.pcap
750 tshark -nVr outfile.pcap
752 tools/fuzz-test.sh is available to help automate these tests.
756 Wireshark uses the underscore_convention rather than the InterCapConvention for
757 function names, so new code should probably use underscores rather than
758 intercaps for functions and variable names. This is especially important if you
759 are writing code that will be called from outside your code. We are just
760 trying to keep things consistent for other developers.
762 C symbols exported from libraries shipped with Wireshark should start with a
763 prefix that helps avoiding name collision with public symbols from other shared
764 libraries. The current suggested prefixes for newly added symbols are
765 ws_, wslua_, wmem_ and wtap_.
767 5. White space convention.
769 Most of the C and C++ files in Wireshark use 4-space or 2-space indentation.
770 When creating new files you are you are strongly encouraged to use 4-space
771 indentation for source code in order to ensure consistency between files.
773 Please avoid using tab expansions different from 8 column widths, as not all
774 text editors in use by the developers support this. For a detailed discussion
775 of tabs, spaces, and indentation, see
777 https://www.jwz.org/doc/tabs-vs-spaces.html
779 We use EditorConfig (http://editorconfig.org) files to provide formatting
780 hints. Most editors and IDEs support EditorConfig, either directly or via
781 a plugin. If yours requires a plugin we encourage you to install it. Our
782 default EditorConfig indentation style for C and C++ files is 4 spaces.
784 Many files also have a short comment (modelines) on the indentation logic at
785 the end of the file. This was required in the past but has been superseded by
788 https://www.wireshark.org/tools/modelines.html
790 for more information.
792 Please do not leave trailing whitespace (spaces/tabs) on lines.
794 Quite a bit of our source code has varying indentation styles. When editing an
795 existing file, try following the existing indentation logic. If you wish to
796 convert a file to 4 space indentation, please do so in its own commit and be
797 sure to remove its .editorconfig entry so that the default setting takes
802 You should write code that is free of compiler warnings. Such warnings will
803 often indicate questionable code and sometimes even real bugs, so it's best
804 to avoid warnings at all.
806 The compiler flags in the Makefiles are set to "treat warnings as errors",
807 so your code won't even compile when warnings occur.
809 7. General observations about architecture
811 7.1 The global header "wireshark.h"
813 You should include the global header <wireshark.h> in your code. However
814 there are some things to keep in mind when using it and especially
815 if you are considering modifying it.
817 ** wireshark.h needs to be minimal: for efficiency reasons, to reduce the
818 error surface and because every time this header changes everything must be
819 rebuilt. Consider carefully if another header/module should be included
820 globally with every project file and exported as public header.
822 ** No configuration: configuration is specific to the build environment
823 and target machine. wireshark.h must not depend on that.
825 ** Only wireshark system headers allowed: plugins use this header and
826 cannot depend on any header (even indirectly) that is not installed on the
829 ** Only global definitions allowed: for example it is acceptable to include
830 'wsutil' headers in wireshark.h because every component of Wireshark is allowed
831 to depend on wsutil. wiretap is not acceptable because we cannot introduce
832 dependencies on wiretap globally (and wireshark.h must be usable everywhere).
834 7.2 Best practices using headers
836 C files can be categorized in three types: source files, private headers and
839 A module "foobar" can have only a private header, only a public header, or
840 both. If it's only one it is named "foobar.h" in both cases. If it is both they
841 are named "foobar-int.h" and "foobar.h" respectively.
843 In general the order of #include's for a C module source files (foobar.c),
844 assuming foobar implements any kind of interface should be:
847 #define WS_LOG_DOMAIN "mydomain"
848 #include "foobar-int.h"
850 followed by <system headers>
851 followed by <wireshark public headers>
852 followed by <wireshark private headers>
854 For header files (private and public) config.h must NOT be included. A public
855 header file (foobar.h) looks like this:
859 #include <wireshark.h>
860 followed by <system headers>
861 followed by <wireshark public headers>
870 #endif /* FOOBAR_H */
872 A private header (foobar-int.h) is the public header plus the declarations
875 #ifndef __FOOBAR_INT_H__
876 #define __FOOBAR_INT_H__
878 followed by <system headers>
879 followed by <wireshark public headers>
880 followed by <wireshark private headers>
883 Again if there are only public or private declarations the name foobar-int.h
884 is not used. The macro symbol WS_LOG_DOMAIN can be defined in source files or
885 private headers as long as it comes before wireshark.h.
887 7.3 Wireshark internal and external API policy
889 Wireshark has several APIs. We need to distinguish between internal
890 Wireshark library APIs and external Wireshark APIs. Wireshark the project is
891 composed of many different programs and these executable binaries use a number
892 of internal libraries to share code efficiently. These internal shared
893 libraries need to be installed on the system to run the programs (wireshark,
896 A library's public API includes the symbols exported by the DSO (wsutil,
897 libwireshark, etc). The internal API is made available in the shared libraries
898 and exists to support the goals of the project. It is public from the point
899 of view of Wireshark programs (client users of the internal API). The
900 external API exists to support plugins (client users of the external API)
901 and is a loosely defined subset of the internal API plus any infrastructure
902 required to support a plugin system. Note that these two uses of shared
903 libraries coexist with a lot of overlap, but are nevertheless distinct.
905 The internal (public) API is not considered to be stable and will regularly
906 change as a normal part of development to support new features, remove cruft,
907 and whatever else is necessary to make the project sustainable and ease the
908 burden on developers. There is less freedom to change something that could
909 break a lot of plugins but this is also acceptable (with cause).
911 The plugin ABI policy is to be compatible only between micro releases (also
912 called patch releases). That means we try to make it unnecessary to recompile
913 plugins with each micro release (on a best-effort basis). For major.minor
914 releases it is explicitly required to recompile plugins. There is no stable
915 ABI contract of any kind in that case.
917 Keep in mind that APIs can exist in different scopes and levels of abstraction.
918 Don't get stuck thinking the words public/private have a very specific
919 meaning, like being decorated or not with WS_DLL_PUBLIC, although that is a
920 big part of it usually.
922 Also the Wireshark developers have historically tried to keep the Lua API
923 very stable and provide strong backward-compatibility guarantees. Under this
924 policy moving from Lua 5.2 is unlikely to happen in the foreseeable future.
926 7.4 libwireshark is not a single monolithic entity
928 One day we might conceivably wish to load dissectors on demand and do other
929 more sophisticated kinds of unit test. Plus other scenarios not immediately
930 obvious. For this to be possible it is important that the code in epan/ does
931 not depend on code in epan/dissectors, i.e it is possible to compile epan
932 without linking with dissector code. It helps to view dissectors as clients
933 of an API provided by epan (libwireshark being constituted by two distinct
934 components "epan" and "dissectors" bundled together, plus other bits and
935 pieces). The reverse is not* true; epan should not be the client of an API
936 provided by dissectors.
938 The main way this separation of concerns is achieved is by using runtime
939 registration interfaces in epan for dissectors, preferences, etc. that are
940 dynamic and do not have any dissector routines hard coded. Naturally this
941 is also an essential component of a plugin system (libwireshark has plugins
942 for taps, dissectors and an experimental interface to augment dissection with
943 new extension languages).
945 7.5 Unicode and string encoding best practices
947 Wireshark strings are always encoded in UTF-8 internally, regardless of the
948 platform where it is running. The C datatype used is "pointer to char" and this
949 is assumed to point to a valid UTF-8 string. Sometimes older code uses char to
950 point to opaque byte strings but this archaic usage should be avoided. A better
951 data type for that is uint8_t.
953 Every untrusted string needs to be validated for correct and error-free UTF-8
954 encoding, or converted from the source encoding to UTF-8. This should be done
955 at the periphery of the code. This means converting input during dissection or
956 when reading input generally. To reiterate: all the Wireshark APIs expect to
957 receive valid UTF-8 strings. These include proto_tree_add_string(),
958 proto_item_append_text() and col_append_fstr() just to name a few.
960 If a dissector uses standard API functions to handle strings, such as
961 proto_tree_add_item() with an FT_STRING header field type, the API will
962 transparently handle the conversion from the source encoding to UTF-8 and
963 nothing else needs to be done to ensure valid string input.
965 If your dissector does text manipulation, token parsing and such and generally
966 extracts text strings from the TVBuff or tries to do line oriented input from
967 TVBuffs it *must* make sure it passes only valid UTF-8 to libwireshark APIs.
968 This should be done using tvb_get_string_enc() to extract a string from a TVbuff
969 or get_utf_8_string() to validate a string after it has been constructed.
971 The Qt API uses UTF-16 for its QString class; when converting between a
972 QString and a pointer to char, functions that convert to or from UTF-8
973 encoded pointers to char (or QByteArrays) such as toUtf8() should be used,
974 not toLocal8Bit() or toLatin1().
976 8. Miscellaneous notes
978 Each commit in your branch corresponds to a different VCS_VERSION string
979 automatically defined in the header 'vcs_version.h' during the build. If you happen
980 to find it convenient to disable this feature it can be done using:
982 touch .git/wireshark-disable-versioning
984 i.e., the file 'wireshark-disable-versioning' must exist in the git repo dir.
987 * Editor modelines - https://www.wireshark.org/tools/modelines.html
992 * indent-tabs-mode: nil
995 * vi: set shiftwidth=4 tabstop=8 expandtab:
996 * :indentSize=4:tabSize=8:noTabs=true: