From ecb898db1ed93b9dfdb47d22d34778e35672e860 Mon Sep 17 00:00:00 2001 From: Alexis La Goutte Date: Fri, 1 Feb 2013 09:22:40 +0000 Subject: [PATCH] Fix the dev guide to use the correct indent (Tab => 4 Spaces) and add Modelines info svn path=/trunk/; revision=47415 --- doc/README.developer | 1881 +++++++++++++++++++++--------------------- 1 file changed, 946 insertions(+), 935 deletions(-) diff --git a/doc/README.developer b/doc/README.developer index d2a2dbe726..1b8ca452cd 100644 --- a/doc/README.developer +++ b/doc/README.developer @@ -87,10 +87,10 @@ Wireshark don't support C99 (E.G. Microsoft C). Don't initialize variables in their declaration with non-constant values. Not all compilers support this. E.g. don't use - guint32 i = somearray[2]; + guint32 i = somearray[2]; use - guint32 i; - i = somearray[2]; + guint32 i; + i = somearray[2]; instead. Don't use zero-length arrays; not all compilers support them. If an @@ -103,13 +103,13 @@ function, or at the beginning of a function or compound statement. Don't use anonymous unions; not all compilers support them. Example: - typedef struct foo { - guint32 foo; - union { - guint32 foo_l; - guint16 foo_s; - } u; /* have a name here */ - } foo_t; + typedef struct foo { + guint32 foo; + union { + guint32 foo_l; + guint16 foo_s; + } u; /* have a name here */ + } foo_t; Don't use "uchar", "u_char", "ushort", "u_short", "uint", "u_int", "ulong", "u_long" or "boolean"; they aren't defined on all platforms. @@ -138,37 +138,37 @@ On LLP64 data model systems (notably 64-bit Windows), "int" and "long" are 32 bits while "size_t" and "ptrdiff_t" are 64 bits. This means that the following will generate a compiler warning: - int i; - i = strlen("hello, sailor"); /* Compiler warning */ + int i; + i = strlen("hello, sailor"); /* Compiler warning */ Normally, you'd just make "i" a size_t. However, many GLib and Wireshark functions won't accept a size_t on LLP64: - size_t i; - char greeting[] = "hello, sailor"; - guint byte_after_greet; + size_t i; + char greeting[] = "hello, sailor"; + guint byte_after_greet; - i = strlen(greeting); - byte_after_greet = tvb_get_guint8(tvb, i); /* Compiler warning */ + i = strlen(greeting); + byte_after_greet = tvb_get_guint8(tvb, i); /* Compiler warning */ Try to use the appropriate data type when you can. When you can't, you will have to cast to a compatible data type, e.g. - size_t i; - char greeting[] = "hello, sailor"; - guint byte_after_greet; + size_t i; + char greeting[] = "hello, sailor"; + guint byte_after_greet; - i = strlen(greeting); - byte_after_greet = tvb_get_guint8(tvb, (gint) i); /* OK */ + i = strlen(greeting); + byte_after_greet = tvb_get_guint8(tvb, (gint) i); /* OK */ or - gint i; - char greeting[] = "hello, sailor"; - guint byte_after_greet; + gint i; + char greeting[] = "hello, sailor"; + guint byte_after_greet; - i = (gint) strlen(greeting); - byte_after_greet = tvb_get_guint8(tvb, i); /* OK */ + i = (gint) strlen(greeting); + byte_after_greet = tvb_get_guint8(tvb, i); /* OK */ See http://www.unix.org/version2/whatsnew/lp64_wp.html for more information on the sizes of common types in different data models. @@ -180,18 +180,18 @@ GLib routines, and routines that use them, such as all the routines in Wireshark that take format arguments, use G_GINT64_MODIFIER, for example: proto_tree_add_uint64_format_value(tree, hf_uint64, tvb, offset, len, - val, "%" G_GINT64_MODIFIER "u", val); + val, "%" G_GINT64_MODIFIER "u", val); When specifying an integral constant that doesn't fit in 32 bits, don't use "LL" at the end of the constant - not all compilers use "LL" for that. Instead, put the constant in a call to the "G_GINT64_CONSTANT()" macro, e.g. - G_GINT64_CONSTANT(11644473600U) + G_GINT64_CONSTANT(11644473600U) rather than - 11644473600ULL + 11644473600ULL Don't assume that you can scan through a va_list initialized by va_start more than once without closing it with va_end and re-initializing it with @@ -200,59 +200,59 @@ but are calling a routine that scans through it, such as vfprintf() or one of the routines in Wireshark that takes a format and a va_list as an argument. You must do - va_start(ap, format); - call_routine1(xxx, format, ap); - va_end(ap); - va_start(ap, format); - call_routine2(xxx, format, ap); - va_end(ap); + va_start(ap, format); + call_routine1(xxx, format, ap); + va_end(ap); + va_start(ap, format); + call_routine2(xxx, format, ap); + va_end(ap); rather - va_start(ap, format); - call_routine1(xxx, format, ap); - call_routine2(xxx, format, ap); - va_end(ap); + va_start(ap, format); + call_routine1(xxx, format, ap); + call_routine2(xxx, format, ap); + va_end(ap); Don't use a label without a statement following it. For example, something such as - if (...) { + if (...) { - ... + ... - done: - } + done: + } will not work with all compilers - you have to do - if (...) { + if (...) { - ... + ... - done: - ; - } + done: + ; + } with some statement, even if it's a null statement, after the label. Don't use "bzero()", "bcopy()", or "bcmp()"; instead, use the ANSI C routines - "memset()" (with zero as the second argument, so that it sets - all the bytes to zero); + "memset()" (with zero as the second argument, so that it sets + all the bytes to zero); - "memcpy()" or "memmove()" (note that the first and second - arguments to "memcpy()" are in the reverse order to the - arguments to "bcopy()"; note also that "bcopy()" is typically - guaranteed to work on overlapping memory regions, while - "memcpy()" isn't, so if you may be copying from one region to a - region that overlaps it, use "memmove()", not "memcpy()" - but - "memcpy()" might be faster as a result of not guaranteeing - correct operation on overlapping memory regions); + "memcpy()" or "memmove()" (note that the first and second + arguments to "memcpy()" are in the reverse order to the + arguments to "bcopy()"; note also that "bcopy()" is typically + guaranteed to work on overlapping memory regions, while + "memcpy()" isn't, so if you may be copying from one region to a + region that overlaps it, use "memmove()", not "memcpy()" - but + "memcpy()" might be faster as a result of not guaranteeing + correct operation on overlapping memory regions); - and "memcmp()" (note that "memcmp()" returns 0, 1, or -1, doing - an ordered comparison, rather than just returning 0 for "equal" - and 1 for "not equal", as "bcmp()" does). + and "memcmp()" (note that "memcmp()" returns 0, 1, or -1, doing + an ordered comparison, rather than just returning 0 for "equal" + and 1 for "not equal", as "bcmp()" does). Not all platforms necessarily have "bzero()"/"bcopy()"/"bcmp()", and those that do might not declare them in the header file on which they're @@ -306,18 +306,18 @@ either warn about it (producing extra noise) or refuse to accept it. Don't include without protecting it with - #ifdef HAVE_UNISTD_H + #ifdef HAVE_UNISTD_H - ... + ... - #endif + #endif and, if you're including it to get routines such as "open()", "close()", "read()", and "write()" declared, also include if present: - #ifdef HAVE_IO_H - #include - #endif + #ifdef HAVE_IO_H + #include + #endif in order to declare the Windows C library routines "_open()", "_close()", "_read()", and "_write()". Your file must include @@ -350,25 +350,25 @@ file is to be created if it doesn't exist), and OR in the O_BINARY flag. That flag is not present on most, if not all, UNIX systems, so you must also do - #ifndef O_BINARY - #define O_BINARY 0 - #endif + #ifndef O_BINARY + #define O_BINARY 0 + #endif to properly define it for UNIX (it's not necessary on UNIX). Don't use forward declarations of static arrays without a specified size in a fashion such as this: - static const value_string foo_vals[]; + static const value_string foo_vals[]; - ... + ... - static const value_string foo_vals[] = { - { 0, "Red" }, - { 1, "Green" }, - { 2, "Blue" }, - { 0, NULL } - }; + static const value_string foo_vals[] = { + { 0, "Red" }, + { 1, "Green" }, + { 2, "Blue" }, + { 0, NULL } + }; as some compilers will reject the first of those statements. Instead, initialize the array at the point at which it's first declared, so that @@ -384,35 +384,35 @@ OPTIONAL. Don't use the "numbered argument" feature that many UNIX printf's implement, e.g.: - g_snprintf(add_string, 30, " - (%1$d) (0x%1$04x)", value); + g_snprintf(add_string, 30, " - (%1$d) (0x%1$04x)", value); as not all UNIX printf's implement it, and Windows printf doesn't appear to implement it. Use something like - g_snprintf(add_string, 30, " - (%d) (0x%04x)", value, value); + g_snprintf(add_string, 30, " - (%d) (0x%04x)", value, value); instead. Don't use "variadic macros", such as - #define DBG(format, args...) fprintf(stderr, format, ## args) + #define DBG(format, args...) fprintf(stderr, format, ## args) as not all C compilers support them. Use macros that take a fixed number of arguments, such as - #define DBG0(format) fprintf(stderr, format) - #define DBG1(format, arg1) fprintf(stderr, format, arg1) - #define DBG2(format, arg1, arg2) fprintf(stderr, format, arg1, arg2) + #define DBG0(format) fprintf(stderr, format) + #define DBG1(format, arg1) fprintf(stderr, format, arg1) + #define DBG2(format, arg1, arg2) fprintf(stderr, format, arg1, arg2) - ... + ... or something such as - #define DBG(args) printf args + #define DBG(args) printf args Don't use - case N ... M: + case N ... M: as that's not supported by all compilers. @@ -560,13 +560,13 @@ the chunk of memory is derived from a size field in the packet, make sure all the data is present in the packet before allocating the buffer. Doing so means that: - 1) Wireshark won't leak that chunk of memory if an attempt to - fetch data not present in the packet throws an exception. + 1) Wireshark won't leak that chunk of memory if an attempt to + fetch data not present in the packet throws an exception. and - 2) it won't crash trying to allocate an absurdly-large chunk of - memory if the size field has a bogus large value. + 2) it won't crash trying to allocate an absurdly-large chunk of + memory if the size field has a bogus large value. If you're fetching into such a chunk of memory a string from the buffer, and the string has a specified size, you can use "tvb_get_*_string()", @@ -627,7 +627,7 @@ offset causes an overflow, that overflow is detected. If you have a - for (i = {start}; i < {end}; i++) + for (i = {start}; i < {end}; i++) loop, make sure that the type of the loop index variable is large enough to hold the maximum {end} value plus 1; otherwise, the loop index @@ -801,11 +801,11 @@ SVN repository (committed). #include /* IF PROTO exposes code to other dissectors, then it must be exported - in a header file. If not, a header file is not needed at all. */ + in a header file. If not, a header file is not needed at all. */ #include "packet-PROTOABBREV.h" /* Forward declaration we need below (if using proto_reg_handoff... - as a prefs callback) */ + as a prefs callback) */ void proto_reg_handoff_PROTOABBREV(void); /* Initialize the protocol and registered fields */ @@ -825,9 +825,9 @@ static int dissect_PROTOABBREV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { -/* Set up structures needed to add the protocol subtree and manage it */ - proto_item *ti; - proto_tree *PROTOABBREV_tree; +/* Set up structures needed to add the protocol subtree and manage it */ + proto_item *ti; + proto_tree *PROTOABBREV_tree; /* First, if at all possible, do some heuristics to check if the packet cannot * possibly belong to your protocol. This is especially important for @@ -837,146 +837,146 @@ dissect_PROTOABBREV(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *d * if someone analyzed that web server's traffic in Wireshark, would result * in Wireshark handing an HTTP packet to your dissector). For example: */ - /* Check that there's enough data */ - if (tvb_length(tvb) < /* your protocol's smallest packet size */) - return 0; + /* Check that there's enough data */ + if (tvb_length(tvb) < /* your protocol's smallest packet size */) + return 0; - /* Get some values from the packet header, probably using tvb_get_*() */ - if ( /* these values are not possible in PROTONAME */ ) - /* This packet does not appear to belong to PROTONAME. - * Return 0 to give another dissector a chance to dissect it. - */ - return 0; + /* Get some values from the packet header, probably using tvb_get_*() */ + if ( /* these values are not possible in PROTONAME */ ) + /* This packet does not appear to belong to PROTONAME. + * Return 0 to give another dissector a chance to dissect it. + */ + return 0; -/* Make entries in Protocol column and Info column on summary display */ - col_set_str(pinfo->cinfo, COL_PROTOCOL, "PROTOABBREV"); +/* Make entries in Protocol column and Info column on summary display */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, "PROTOABBREV"); -/* This field shows up as the "Info" column in the display; you should use - it, if possible, to summarize what's in the packet, so that a user looking - at the list of packets can tell what type of packet it is. See section 1.5 - for more information. +/* This field shows up as the "Info" column in the display; you should use + it, if possible, to summarize what's in the packet, so that a user looking + at the list of packets can tell what type of packet it is. See section 1.5 + for more information. - If you are setting the column to a constant string, use "col_set_str()", - as it's more efficient than the other "col_set_XXX()" calls. + If you are setting the column to a constant string, use "col_set_str()", + as it's more efficient than the other "col_set_XXX()" calls. - If you're setting it to a string you've constructed, or will be - appending to the column later, use "col_add_str()". + If you're setting it to a string you've constructed, or will be + appending to the column later, use "col_add_str()". - "col_add_fstr()" can be used instead of "col_add_str()"; it takes - "printf()"-like arguments. Don't use "col_add_fstr()" with a format - string of "%s" - just use "col_add_str()" or "col_set_str()", as it's - more efficient than "col_add_fstr()". + "col_add_fstr()" can be used instead of "col_add_str()"; it takes + "printf()"-like arguments. Don't use "col_add_fstr()" with a format + string of "%s" - just use "col_add_str()" or "col_set_str()", as it's + more efficient than "col_add_fstr()". - If you will be fetching any data from the packet before filling in - the Info column, clear that column first, in case the calls to fetch - data from the packet throw an exception because they're fetching data - past the end of the packet, so that the Info column doesn't have data - left over from the previous dissector; do + If you will be fetching any data from the packet before filling in + the Info column, clear that column first, in case the calls to fetch + data from the packet throw an exception because they're fetching data + past the end of the packet, so that the Info column doesn't have data + left over from the previous dissector; do - col_clear(pinfo->cinfo, COL_INFO); + col_clear(pinfo->cinfo, COL_INFO); - */ + */ - col_set_str(pinfo->cinfo, COL_INFO, "XXX Request"); + col_set_str(pinfo->cinfo, COL_INFO, "XXX Request"); -/* A protocol dissector may be called in 2 different ways - with, or - without a non-null "tree" argument. +/* A protocol dissector may be called in 2 different ways - with, or + without a non-null "tree" argument. - If the proto_tree argument is null, Wireshark does not need to use - the protocol tree information from your dissector, and therefore is - passing the dissector a null "tree" argument so that it doesn't - need to do work necessary to build the protocol tree. + If the proto_tree argument is null, Wireshark does not need to use + the protocol tree information from your dissector, and therefore is + passing the dissector a null "tree" argument so that it doesn't + need to do work necessary to build the protocol tree. - In the interest of speed, if "tree" is NULL, avoid building a - protocol tree and adding stuff to it, or even looking at any packet - data needed only if you're building the protocol tree, if possible. + In the interest of speed, if "tree" is NULL, avoid building a + protocol tree and adding stuff to it, or even looking at any packet + data needed only if you're building the protocol tree, if possible. - Note, however, that you must fill in column information, create - conversations, reassemble packets, do calls to "expert" functions, - build any other persistent state needed for dissection, and call - subdissectors regardless of whether "tree" is NULL or not. + Note, however, that you must fill in column information, create + conversations, reassemble packets, do calls to "expert" functions, + build any other persistent state needed for dissection, and call + subdissectors regardless of whether "tree" is NULL or not. - This might be inconvenient to do without doing most of the - dissection work; the routines for adding items to the protocol tree - can be passed a null protocol tree pointer, in which case they'll - return a null item pointer, and "proto_item_add_subtree()" returns - a null tree pointer if passed a null item pointer, so, if you're - careful not to dereference any null tree or item pointers, you can - accomplish this by doing all the dissection work. This might not - be as efficient as skipping that work if you're not building a - protocol tree, but if the code would have a lot of tests whether - "tree" is null if you skipped that work, you might still be better - off just doing all that work regardless of whether "tree" is null - or not. + This might be inconvenient to do without doing most of the + dissection work; the routines for adding items to the protocol tree + can be passed a null protocol tree pointer, in which case they'll + return a null item pointer, and "proto_item_add_subtree()" returns + a null tree pointer if passed a null item pointer, so, if you're + careful not to dereference any null tree or item pointers, you can + accomplish this by doing all the dissection work. This might not + be as efficient as skipping that work if you're not building a + protocol tree, but if the code would have a lot of tests whether + "tree" is null if you skipped that work, you might still be better + off just doing all that work regardless of whether "tree" is null + or not. - Note also that there is no guarantee, the first time the dissector is - called, whether "tree" will be null or not; your dissector must work - correctly, building or updating whatever state information is - necessary, in either case. */ - if (tree) { + Note also that there is no guarantee, the first time the dissector is + called, whether "tree" will be null or not; your dissector must work + correctly, building or updating whatever state information is + necessary, in either case. */ + if (tree) { -/* NOTE: The offset and length values in the call to - "proto_tree_add_item()" define what data bytes to highlight in the hex - display window when the line in the protocol tree display - corresponding to that item is selected. +/* NOTE: The offset and length values in the call to + "proto_tree_add_item()" define what data bytes to highlight in the hex + display window when the line in the protocol tree display + corresponding to that item is selected. - Supplying a length of -1 is the way to highlight all data from the - offset to the end of the packet. */ + Supplying a length of -1 is the way to highlight all data from the + offset to the end of the packet. */ -/* create display subtree for the protocol */ - ti = proto_tree_add_item(tree, proto_PROTOABBREV, tvb, 0, -1, ENC_NA); +/* create display subtree for the protocol */ + ti = proto_tree_add_item(tree, proto_PROTOABBREV, tvb, 0, -1, ENC_NA); - PROTOABBREV_tree = proto_item_add_subtree(ti, ett_PROTOABBREV); + PROTOABBREV_tree = proto_item_add_subtree(ti, ett_PROTOABBREV); /* add an item to the subtree, see section 1.6 for more information */ - proto_tree_add_item(PROTOABBREV_tree, - hf_PROTOABBREV_FIELDABBREV, tvb, offset, len, ENC_xxx); + proto_tree_add_item(PROTOABBREV_tree, + hf_PROTOABBREV_FIELDABBREV, tvb, offset, len, ENC_xxx); /* Continue adding tree items to process the packet here */ - } + } /* If this protocol has a sub-dissector call it here, see section 1.8 */ /* Return the amount of data this dissector was able to dissect */ - return tvb_length(tvb); + return tvb_length(tvb); } /* Register the protocol with Wireshark */ -/* this format is require because a script is used to build the C function - that calls all the protocol registration. +/* This format is require because a script is used to build the C function + that calls all the protocol registration. */ void proto_register_PROTOABBREV(void) { - module_t *PROTOABBREV_module; + module_t *PROTOABBREV_module; /* Setup list of header fields See Section 1.6.1 for details*/ - static hf_register_info hf[] = { - { &hf_PROTOABBREV_FIELDABBREV, - { "FIELDNAME", "PROTOABBREV.FIELDABBREV", - FIELDTYPE, FIELDDISPLAY, FIELDCONVERT, BITMASK, - "FIELDDESCR", HFILL } - } - }; + static hf_register_info hf[] = { + { &hf_PROTOABBREV_FIELDABBREV, + { "FIELDNAME", "PROTOABBREV.FIELDABBREV", + FIELDTYPE, FIELDDISPLAY, FIELDCONVERT, BITMASK, + "FIELDDESCR", HFILL } + } + }; /* Setup protocol subtree array */ - static gint *ett[] = { - &ett_PROTOABBREV - }; + static gint *ett[] = { + &ett_PROTOABBREV + }; /* Register the protocol name and description */ - proto_PROTOABBREV = proto_register_protocol("PROTONAME", - "PROTOSHORTNAME", "PROTOABBREV"); + proto_PROTOABBREV = proto_register_protocol("PROTONAME", + "PROTOSHORTNAME", "PROTOABBREV"); /* Required function calls to register the header fields and subtrees used */ - proto_register_field_array(proto_PROTOABBREV, hf, array_length(hf)); - proto_register_subtree_array(ett, array_length(ett)); + proto_register_field_array(proto_PROTOABBREV, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); /* Register preferences module (See Section 2.6 for more on preferences) */ /* (Registration of a prefs callback is not required if there are no */ @@ -984,8 +984,8 @@ proto_register_PROTOABBREV(void) /* See proto_reg_handoff below. */ /* If a prefs callback is not needed, use NULL instead of */ /* proto_reg_handoff_PROTOABBREV in the following). */ - PROTOABBREV_module = prefs_register_protocol(proto_PROTOABBREV, - proto_reg_handoff_PROTOABBREV); + PROTOABBREV_module = prefs_register_protocol(proto_PROTOABBREV, + proto_reg_handoff_PROTOABBREV); /* Register preferences module under preferences subtree. Use this function instead of prefs_register_protocol if you want to group @@ -998,15 +998,15 @@ proto_register_PROTOABBREV(void) proto_PROTOABBREV, proto_reg_handoff_PROTOABBREV); /* Register a sample preference */ - prefs_register_bool_preference(PROTOABBREV_module, "show_hex", - "Display numbers in Hex", - "Enable to display numerical values in hexadecimal.", - &gPREF_HEX); + prefs_register_bool_preference(PROTOABBREV_module, "show_hex", + "Display numbers in Hex", + "Enable to display numerical values in hexadecimal.", + &gPREF_HEX); /* Register a sample port preference */ - prefs_register_uint_preference(PROTOABBREV_module, "tcp.port", "PROTOABBREV TCP Port", - " PROTOABBREV TCP port if other than the default", - 10, &gPORT_PREF); + prefs_register_uint_preference(PROTOABBREV_module, "tcp.port", "PROTOABBREV TCP Port", + " PROTOABBREV TCP port if other than the default", + 10, &gPORT_PREF); } @@ -1026,38 +1026,38 @@ proto_register_PROTOABBREV(void) void proto_reg_handoff_PROTOABBREV(void) { - static gboolean initialized = FALSE; - static dissector_handle_t PROTOABBREV_handle; - static int currentPort; + static gboolean initialized = FALSE; + static dissector_handle_t PROTOABBREV_handle; + static int currentPort; - if (!initialized) { + if (!initialized) { /* Use new_create_dissector_handle() to indicate that dissect_PROTOABBREV() * returns the number of bytes it dissected (or 0 if it thinks the packet * does not belong to PROTONAME). */ - PROTOABBREV_handle = new_create_dissector_handle(dissect_PROTOABBREV, - proto_PROTOABBREV); - initialized = TRUE; - } else { + PROTOABBREV_handle = new_create_dissector_handle(dissect_PROTOABBREV, + proto_PROTOABBREV); + initialized = TRUE; + } else { - /* - If you perform registration functions which are dependent upon - prefs the you should de-register everything which was associated - with the previous settings and re-register using the new prefs - settings here. In general this means you need to keep track of - the PROTOABBREV_handle and the value the preference had at the time - you registered. The PROTOABBREV_handle value and the value of the - preference can be saved using local statics in this - function (proto_reg_handoff). - */ + /* + If you perform registration functions which are dependent upon + prefs the you should de-register everything which was associated + with the previous settings and re-register using the new prefs + settings here. In general this means you need to keep track of + the PROTOABBREV_handle and the value the preference had at the time + you registered. The PROTOABBREV_handle value and the value of the + preference can be saved using local statics in this + function (proto_reg_handoff). + */ - dissector_delete_uint("tcp.port", currentPort, PROTOABBREV_handle); - } + dissector_delete_uint("tcp.port", currentPort, PROTOABBREV_handle); + } - currentPort = gPORT_PREF; + currentPort = gPORT_PREF; - dissector_add_uint("tcp.port", currentPort, PROTOABBREV_handle); + dissector_add_uint("tcp.port", currentPort, PROTOABBREV_handle); } @@ -1069,15 +1069,15 @@ proto_reg_handoff_PROTOABBREV(void) void proto_reg_handoff_PROTOABBREV(void) { - dissector_handle_t PROTOABBREV_handle; + dissector_handle_t PROTOABBREV_handle; /* Use new_create_dissector_handle() to indicate that dissect_PROTOABBREV() * returns the number of bytes it dissected (or 0 if it thinks the packet * does not belong to PROTONAME). */ - PROTOABBREV_handle = new_create_dissector_handle(dissect_PROTOABBREV, - proto_PROTOABBREV); - dissector_add_uint("PARENT_SUBFIELD", ID_VALUE, PROTOABBREV_handle); + PROTOABBREV_handle = new_create_dissector_handle(dissect_PROTOABBREV, + proto_PROTOABBREV); + dissector_add_uint("PARENT_SUBFIELD", ID_VALUE, PROTOABBREV_handle); } #endif @@ -1103,58 +1103,57 @@ proto_reg_handoff_PROTOABBREV(void) In the above code block the following strings should be substituted with your information. -YOUR_NAME Your name, of course. You do want credit, don't you? - It's the only payment you will receive.... -YOUR_EMAIL_ADDRESS Keep those cards and letters coming. -WHATEVER_FILE_YOU_USED Add this line if you are using another file as a - starting point. -PROTONAME The name of the protocol; this is displayed in the - top-level protocol tree item for that protocol. -PROTOSHORTNAME An abbreviated name for the protocol; this is displayed - in the "Preferences" dialog box if your dissector has - any preferences, in the dialog box of enabled protocols, - and in the dialog box for filter fields when constructing - a filter expression. -PROTOABBREV A name for the protocol for use in filter expressions; - it shall contain only lower-case letters, digits, and - hyphens. -FIELDNAME The displayed name for the header field. -FIELDABBREV The abbreviated name for the header field. (NO SPACES) -FIELDTYPE FT_NONE, FT_BOOLEAN, FT_UINT8, FT_UINT16, FT_UINT24, - FT_UINT32, FT_UINT64, FT_INT8, FT_INT16, FT_INT24, FT_INT32, - FT_INT64, FT_FLOAT, FT_DOUBLE, FT_ABSOLUTE_TIME, - FT_RELATIVE_TIME, FT_STRING, FT_STRINGZ, FT_EUI64, - FT_UINT_STRING, FT_ETHER, FT_BYTES, FT_UINT_BYTES, FT_IPv4, - FT_IPv6, FT_IPXNET, FT_FRAMENUM, FT_PROTOCOL, FT_GUID, FT_OID -FIELDDISPLAY --For FT_UINT{8,16,24,32,64} and FT_INT{8,16,24,32,64): +YOUR_NAME Your name, of course. You do want credit, don't you? + It's the only payment you will receive.... +YOUR_EMAIL_ADDRESS Keep those cards and letters coming. +WHATEVER_FILE_YOU_USED Add this line if you are using another file as a + starting point. +PROTONAME The name of the protocol; this is displayed in the + top-level protocol tree item for that protocol. +PROTOSHORTNAME An abbreviated name for the protocol; this is displayed + in the "Preferences" dialog box if your dissector has + any preferences, in the dialog box of enabled protocols, + and in the dialog box for filter fields when constructing + a filter expression. +PROTOABBREV A name for the protocol for use in filter expressions; + it shall contain only lower-case letters, digits, and hyphens. +FIELDNAME The displayed name for the header field. +FIELDABBREV The abbreviated name for the header field. (NO SPACES) +FIELDTYPE FT_NONE, FT_BOOLEAN, FT_UINT8, FT_UINT16, FT_UINT24, + FT_UINT32, FT_UINT64, FT_INT8, FT_INT16, FT_INT24, FT_INT32, + FT_INT64, FT_FLOAT, FT_DOUBLE, FT_ABSOLUTE_TIME, + FT_RELATIVE_TIME, FT_STRING, FT_STRINGZ, FT_EUI64, + FT_UINT_STRING, FT_ETHER, FT_BYTES, FT_UINT_BYTES, FT_IPv4, + FT_IPv6, FT_IPXNET, FT_FRAMENUM, FT_PROTOCOL, FT_GUID, FT_OID +FIELDDISPLAY --For FT_UINT{8,16,24,32,64} and FT_INT{8,16,24,32,64): - BASE_DEC, BASE_HEX, BASE_OCT, BASE_DEC_HEX, BASE_HEX_DEC, - or BASE_CUSTOM, possibly ORed with BASE_RANGE_STRING or + BASE_DEC, BASE_HEX, BASE_OCT, BASE_DEC_HEX, BASE_HEX_DEC, + or BASE_CUSTOM, possibly ORed with BASE_RANGE_STRING or BASE_EXT_STRING - --For FT_ABSOLUTE_TIME: + --For FT_ABSOLUTE_TIME: - ABSOLUTE_TIME_LOCAL, ABSOLUTE_TIME_UTC, or - ABSOLUTE_TIME_DOY_UTC + ABSOLUTE_TIME_LOCAL, ABSOLUTE_TIME_UTC, or + ABSOLUTE_TIME_DOY_UTC - --For FT_BOOLEAN: + --For FT_BOOLEAN: if BITMASK is non-zero: - Number of bits in the field containing the FT_BOOLEAN - bitfield. + Number of bits in the field containing the FT_BOOLEAN + bitfield. otherwise: (must be) BASE_NONE - --For all other types: + --For all other types: - BASE_NONE -FIELDCONVERT VALS(x), RVALS(x), TFS(x), NULL -BITMASK Used to mask a field not 8-bit aligned or with a size other + BASE_NONE +FIELDCONVERT VALS(x), RVALS(x), TFS(x), NULL +BITMASK Used to mask a field not 8-bit aligned or with a size other than a multiple of 8 bits -FIELDDESCR A brief description of the field, or NULL. [Please do not use ""]. -PARENT_SUBFIELD Lower level protocol field used for lookup, i.e. "tcp.port" -ID_VALUE Lower level protocol field value that identifies this protocol - For example the TCP or UDP port number +FIELDDESCR A brief description of the field, or NULL. [Please do not use ""]. +PARENT_SUBFIELD Lower level protocol field used for lookup, i.e. "tcp.port" +ID_VALUE Lower level protocol field value that identifies this protocol + For example the TCP or UDP port number If, for example, PROTONAME is "Internet Bogosity Discovery Protocol", PROTOSHORTNAME would be "IBDP", and PROTOABBREV would be "ibdp". Try to @@ -1429,7 +1428,7 @@ that case. For example, to set the "Protocol" column to "PROTOABBREV": - col_set_str(pinfo->cinfo, COL_PROTOCOL, "PROTOABBREV"); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "PROTOABBREV"); 1.5.2 The col_add_str function. @@ -1450,8 +1449,8 @@ the "Info" field to " request, bytes", where "reqtype" is a string containing the type of the request in the packet and "n" is an unsigned integer containing the number of bytes in the request: - col_add_fstr(pinfo->cinfo, COL_INFO, "%s request, %u bytes", - reqtype, n); + col_add_fstr(pinfo->cinfo, COL_INFO, "%s request, %u bytes", + reqtype, n); Don't use 'col_add_fstr' with a format argument of just "%s" - 'col_add_str', or possibly even 'col_set_str' if the string that matches @@ -1556,8 +1555,8 @@ based on the time-value. For example: - nstime_delta(&ts, &pinfo->fd->abs_ts, &tcpd->ts_first); - col_set_time(pinfo->cinfo, COL_REL_CONV_TIME, &ts, "tcp.time_relative"); + nstime_delta(&ts, &pinfo->fd->abs_ts, &tcpd->ts_first); + col_set_time(pinfo->cinfo, COL_REL_CONV_TIME, &ts, "tcp.time_relative"); 1.6 Constructing the protocol tree. @@ -1600,24 +1599,24 @@ called when Wireshark starts. The code to call the register routines is generated automatically; to arrange that a protocol's register routine be called at startup: - the file containing a dissector's "register" routine must be - added to "DISSECTOR_SRC" in "epan/dissectors/Makefile.common" - (and in "epan/CMakeLists.txt"); + the file containing a dissector's "register" routine must be + added to "DISSECTOR_SRC" in "epan/dissectors/Makefile.common" + (and in "epan/CMakeLists.txt"); - the "register" routine must have a name of the form - "proto_register_XXX"; + the "register" routine must have a name of the form + "proto_register_XXX"; - the "register" routine must take no argument, and return no - value; + the "register" routine must take no argument, and return no + value; - the "register" routine's name must appear in the source file - either at the beginning of the line, or preceded only by "void " - at the beginning of the line (that would typically be the - definition) - other white space shouldn't cause a problem, e.g.: + the "register" routine's name must appear in the source file + either at the beginning of the line, or preceded only by "void " + at the beginning of the line (that would typically be the + definition) - other white space shouldn't cause a problem, e.g.: void proto_register_XXX(void) { - ... + ... } @@ -1627,11 +1626,11 @@ void proto_register_XXX( void ) { - ... + ... } - and so on should work. + and so on should work. For every protocol or field that a dissector wants to register, a variable of type int needs to be used to keep track of the protocol. The IDs are @@ -1663,14 +1662,14 @@ information about its data type is needed. It helps to look at the header_field_info struct to see what information is expected: struct header_field_info { - const char *name; - const char *abbrev; - enum ftenum type; - int display; - const void *strings; - guint32 bitmask; - const char *blurb; - ..... + const char *name; + const char *abbrev; + enum ftenum type; + int display; + const void *strings; + guint32 bitmask; + const char *blurb; + ..... }; name @@ -1697,80 +1696,80 @@ type ---- The type of value this field holds. The current field types are: - FT_NONE No field type. Used for fields that - aren't given a value, and that can only - be tested for presence or absence; a - field that represents a data structure, - with a subtree below it containing - fields for the members of the structure, - or that represents an array with a - subtree below it containing fields for - the members of the array, might be an - FT_NONE field. - FT_PROTOCOL Used for protocols which will be placing - themselves as top-level items in the - "Packet Details" pane of the UI. - FT_BOOLEAN 0 means "false", any other value means - "true". - FT_FRAMENUM A frame number; if this is used, the "Go - To Corresponding Frame" menu item can - work on that field. - FT_UINT8 An 8-bit unsigned integer. - FT_UINT16 A 16-bit unsigned integer. - FT_UINT24 A 24-bit unsigned integer. - FT_UINT32 A 32-bit unsigned integer. - FT_UINT64 A 64-bit unsigned integer. - FT_INT8 An 8-bit signed integer. - FT_INT16 A 16-bit signed integer. - FT_INT24 A 24-bit signed integer. - FT_INT32 A 32-bit signed integer. - FT_INT64 A 64-bit signed integer. - FT_FLOAT A single-precision floating point number. - FT_DOUBLE A double-precision floating point number. - FT_ABSOLUTE_TIME An absolute time from some fixed point in time, - displayed as the date, followed by the time, as - hours, minutes, and seconds with 9 digits after - the decimal point. - FT_RELATIVE_TIME Seconds (4 bytes) and nanoseconds (4 bytes) - of time relative to an arbitrary time. - displayed as seconds and 9 digits - after the decimal point. - FT_STRING A string of characters, not necessarily - NULL-terminated, but possibly NULL-padded. - This, and the other string-of-characters - types, are to be used for text strings, - not raw binary data. - FT_STRINGZ A NULL-terminated string of characters. - The string length is normally the length - given in the proto_tree_add_item() call. - However if the length given in the call - is -1, then the length used is that - returned by calling tvb_strsize(). - FT_UINT_STRING A counted string of characters, consisting - of a count (represented as an integral value, - of width given in the proto_tree_add_item() - call) followed immediately by that number of - characters. - FT_ETHER A six octet string displayed in - Ethernet-address format. - FT_BYTES A string of bytes with arbitrary values; - used for raw binary data. - FT_UINT_BYTES A counted string of bytes, consisting - of a count (represented as an integral value, - of width given in the proto_tree_add_item() - call) followed immediately by that number of - arbitrary values; used for raw binary data. - FT_IPv4 A version 4 IP address (4 bytes) displayed - in dotted-quad IP address format (4 - decimal numbers separated by dots). - FT_IPv6 A version 6 IP address (16 bytes) displayed - in standard IPv6 address format. - FT_IPXNET An IPX address displayed in hex as a 6-byte - network number followed by a 6-byte station - address. - FT_GUID A Globally Unique Identifier - FT_OID An ASN.1 Object Identifier - FT_EUI64 A EUI-64 Address + FT_NONE No field type. Used for fields that + aren't given a value, and that can only + be tested for presence or absence; a + field that represents a data structure, + with a subtree below it containing + fields for the members of the structure, + or that represents an array with a + subtree below it containing fields for + the members of the array, might be an + FT_NONE field. + FT_PROTOCOL Used for protocols which will be placing + themselves as top-level items in the + "Packet Details" pane of the UI. + FT_BOOLEAN 0 means "false", any other value means + "true". + FT_FRAMENUM A frame number; if this is used, the "Go + To Corresponding Frame" menu item can + work on that field. + FT_UINT8 An 8-bit unsigned integer. + FT_UINT16 A 16-bit unsigned integer. + FT_UINT24 A 24-bit unsigned integer. + FT_UINT32 A 32-bit unsigned integer. + FT_UINT64 A 64-bit unsigned integer. + FT_INT8 An 8-bit signed integer. + FT_INT16 A 16-bit signed integer. + FT_INT24 A 24-bit signed integer. + FT_INT32 A 32-bit signed integer. + FT_INT64 A 64-bit signed integer. + FT_FLOAT A single-precision floating point number. + FT_DOUBLE A double-precision floating point number. + FT_ABSOLUTE_TIME An absolute time from some fixed point in time, + displayed as the date, followed by the time, as + hours, minutes, and seconds with 9 digits after + the decimal point. + FT_RELATIVE_TIME Seconds (4 bytes) and nanoseconds (4 bytes) + of time relative to an arbitrary time. + displayed as seconds and 9 digits + after the decimal point. + FT_STRING A string of characters, not necessarily + NULL-terminated, but possibly NULL-padded. + This, and the other string-of-characters + types, are to be used for text strings, + not raw binary data. + FT_STRINGZ A NULL-terminated string of characters. + The string length is normally the length + given in the proto_tree_add_item() call. + However if the length given in the call + is -1, then the length used is that + returned by calling tvb_strsize(). + FT_UINT_STRING A counted string of characters, consisting + of a count (represented as an integral value, + of width given in the proto_tree_add_item() + call) followed immediately by that number of + characters. + FT_ETHER A six octet string displayed in + Ethernet-address format. + FT_BYTES A string of bytes with arbitrary values; + used for raw binary data. + FT_UINT_BYTES A counted string of bytes, consisting + of a count (represented as an integral value, + of width given in the proto_tree_add_item() + call) followed immediately by that number of + arbitrary values; used for raw binary data. + FT_IPv4 A version 4 IP address (4 bytes) displayed + in dotted-quad IP address format (4 + decimal numbers separated by dots). + FT_IPv6 A version 6 IP address (16 bytes) displayed + in standard IPv6 address format. + FT_IPXNET An IPX address displayed in hex as a 6-byte + network number followed by a 6-byte station + address. + FT_GUID A Globally Unique Identifier + FT_OID An ASN.1 Object Identifier + FT_EUI64 A EUI-64 Address Some of these field types are still not handled in the display filter routines, but the most common ones are. The FT_UINT* variables all @@ -1798,12 +1797,12 @@ For integer fields (FT_UINT* and FT_INT*), this variable represents the base in which you would like the value displayed. The acceptable bases are: - BASE_DEC, - BASE_HEX, - BASE_OCT, - BASE_DEC_HEX, - BASE_HEX_DEC, - BASE_CUSTOM + BASE_DEC, + BASE_HEX, + BASE_OCT, + BASE_DEC_HEX, + BASE_HEX_DEC, + BASE_CUSTOM BASE_DEC, BASE_HEX, and BASE_OCT are decimal, hexadecimal, and octal, respectively. BASE_DEC_HEX and BASE_HEX_DEC display value in two bases @@ -1813,7 +1812,7 @@ BASE_CUSTOM allows one to specify a callback function pointer that will format the value. The function pointer of the same type as defined by custom_fmt_func_t in epan/proto.h, specifically: - void func(gchar *, guint32); + void func(gchar *, guint32); The first argument is a pointer to a buffer of the ITEM_LABEL_LENGTH size and the second argument is the value to be formatted. @@ -1855,18 +1854,18 @@ enumerated data type, rather than an integral data type. A 'value_string' structure is a way to map values to strings. - typedef struct _value_string { - guint32 value; - gchar *strptr; - } value_string; + typedef struct _value_string { + guint32 value; + gchar *strptr; + } value_string; For fields of that type, you would declare an array of "value_string"s: - static const value_string valstringname[] = { - { INTVAL1, "Descriptive String 1" }, - { INTVAL2, "Descriptive String 2" }, - { 0, NULL } - }; + static const value_string valstringname[] = { + { INTVAL1, "Descriptive String 1" }, + { INTVAL2, "Descriptive String 2" }, + { 0, NULL } + }; (the last entry in the array must have a NULL 'strptr' value, to indicate the end of the array). The 'strings' field would be set to @@ -1927,11 +1926,11 @@ Thus a 'range_string' structure is a way to map ranges to strings. For fields of that type, you would declare an array of "range_string"s: - static const range_string rvalstringname[] = { - { INTVAL_MIN1, INTVALMAX1, "Descriptive String 1" }, - { INTVAL_MIN2, INTVALMAX2, "Descriptive String 2" }, - { 0, 0, NULL } - }; + static const range_string rvalstringname[] = { + { INTVAL_MIN1, INTVALMAX1, "Descriptive String 1" }, + { INTVAL_MIN2, INTVALMAX2, "Descriptive String 2" }, + { 0, 0, NULL } + }; If INTVAL_MIN equals INTVAL_MAX for a given entry the range_string behavior collapses to the one of value_string. @@ -1945,18 +1944,18 @@ Sometimes it is useful to change the labels for boolean values (e.g., to "Yes"/"No", "Fast"/"Slow", etc.). For these mappings, a struct called true_false_string is used. - typedef struct true_false_string { - char *true_string; - char *false_string; - } true_false_string; + typedef struct true_false_string { + char *true_string; + char *false_string; + } true_false_string; For Boolean fields for which "False" and "True" aren't the desired labels, you would declare a "true_false_string"s: - static const true_false_string boolstringname = { - "String for True", - "String for False" - }; + static const true_false_string boolstringname = { + "String for True", + "String for False" + }; Its two fields are pointers to the string representing truth, and the string representing falsehood. For FT_BOOLEAN fields that need a @@ -1998,24 +1997,24 @@ header_field_info struct (or an array of such structs), and calling the registration function along with the registration ID of the protocol that is the parent of the fields. Here is a complete example: - static int proto_eg = -1; - static int hf_field_a = -1; - static int hf_field_b = -1; + static int proto_eg = -1; + static int hf_field_a = -1; + static int hf_field_b = -1; - static hf_register_info hf[] = { + static hf_register_info hf[] = { - { &hf_field_a, - { "Field A", "proto.field_a", FT_UINT8, BASE_HEX, NULL, - 0xf0, "Field A represents Apples", HFILL }}, + { &hf_field_a, + { "Field A", "proto.field_a", FT_UINT8, BASE_HEX, NULL, + 0xf0, "Field A represents Apples", HFILL }}, - { &hf_field_b, - { "Field B", "proto.field_b", FT_UINT16, BASE_DEC, VALS(vs), - 0x0, "Field B represents Bananas", HFILL }} - }; + { &hf_field_b, + { "Field B", "proto.field_b", FT_UINT16, BASE_DEC, VALS(vs), + 0x0, "Field B represents Bananas", HFILL }} + }; - proto_eg = proto_register_protocol("Example Protocol", - "PROTO", "proto"); - proto_register_field_array(proto_eg, hf, array_length(hf)); + proto_eg = proto_register_protocol("Example Protocol", + "PROTO", "proto"); + proto_register_field_array(proto_eg, hf, array_length(hf)); Be sure that your array of hf_register_info structs is declared 'static', since the proto_register_field_array() function does not create a copy @@ -2024,8 +2023,8 @@ information that the compiler created inside your array. Here's the layout of the hf_register_info struct: typedef struct hf_register_info { - int *p_id; /* pointer to parent variable */ - header_field_info hfinfo; + int *p_id; /* pointer to parent variable */ + header_field_info hfinfo; } hf_register_info; Also be sure to use the handy array_length() macro found in packet.h @@ -2039,16 +2038,16 @@ entirely. It is OK to have header fields with a different format be registered with the same abbreviation. For instance, the following is valid: - static hf_register_info hf[] = { + static hf_register_info hf[] = { - { &hf_field_8bit, /* 8-bit version of proto.field */ - { "Field (8 bit)", "proto.field", FT_UINT8, BASE_DEC, NULL, - 0x00, "Field represents FOO", HFILL }}, + { &hf_field_8bit, /* 8-bit version of proto.field */ + { "Field (8 bit)", "proto.field", FT_UINT8, BASE_DEC, NULL, + 0x00, "Field represents FOO", HFILL }}, - { &hf_field_32bit, /* 32-bit version of proto.field */ - { "Field (32 bit)", "proto.field", FT_UINT32, BASE_DEC, NULL, - 0x00, "Field represents FOO", HFILL }} - }; + { &hf_field_32bit, /* 32-bit version of proto.field */ + { "Field (32 bit)", "proto.field", FT_UINT32, BASE_DEC, NULL, + 0x00, "Field represents FOO", HFILL }} + }; This way a filter expression can match a header field, irrespective of the representation of it in the specific protocol context. This is interesting @@ -2069,8 +2068,8 @@ function call can be avoided by checking for the tree pointer. Subtrees can be made with the proto_item_add_subtree() function: - item = proto_tree_add_item(....); - new_tree = proto_item_add_subtree(item, tree_type); + item = proto_tree_add_item(....); + new_tree = proto_item_add_subtree(item, tree_type); This will add a subtree under the item in question; a subtree can be created under an item made by any of the "proto_tree_add_XXX" functions, @@ -2081,15 +2080,15 @@ Subtree types are integers, assigned by array of pointers to "gint" variables to hold the subtree type values to "proto_register_subtree_array()": - static gint ett_eg = -1; - static gint ett_field_a = -1; + static gint ett_eg = -1; + static gint ett_field_a = -1; - static gint *ett[] = { - &ett_eg, - &ett_field_a - }; + static gint *ett[] = { + &ett_eg, + &ett_field_a + }; - proto_register_subtree_array(ett, array_length(ett)); + proto_register_subtree_array(ett, array_length(ett)); in your "register" routine, just as you register the protocol and the fields for that protocol. @@ -2103,232 +2102,232 @@ you move to another packet. There are several functions that the programmer can use to add either protocol or field labels to the proto_tree: - proto_item* - proto_tree_add_item(tree, id, tvb, start, length, encoding); + proto_item* + proto_tree_add_item(tree, id, tvb, start, length, encoding); - proto_item* - proto_tree_add_none_format(tree, id, tvb, start, length, format, ...); + proto_item* + proto_tree_add_none_format(tree, id, tvb, start, length, format, ...); - proto_item* - proto_tree_add_protocol_format(tree, id, tvb, start, length, - format, ...); + proto_item* + proto_tree_add_protocol_format(tree, id, tvb, start, length, + format, ...); - proto_item * - proto_tree_add_bytes(tree, id, tvb, start, length, start_ptr); + proto_item * + proto_tree_add_bytes(tree, id, tvb, start, length, start_ptr); - proto_item * - proto_tree_add_bytes_format(tree, id, tvb, start, length, start_ptr, - format, ...); + proto_item * + proto_tree_add_bytes_format(tree, id, tvb, start, length, start_ptr, + format, ...); - proto_item * - proto_tree_add_bytes_format_value(tree, id, tvb, start, length, - start_ptr, format, ...); + proto_item * + proto_tree_add_bytes_format_value(tree, id, tvb, start, length, + start_ptr, format, ...); - proto_item * - proto_tree_add_time(tree, id, tvb, start, length, value_ptr); + proto_item * + proto_tree_add_time(tree, id, tvb, start, length, value_ptr); - proto_item * - proto_tree_add_time_format(tree, id, tvb, start, length, value_ptr, - format, ...); + proto_item * + proto_tree_add_time_format(tree, id, tvb, start, length, value_ptr, + format, ...); - proto_item * - proto_tree_add_time_format_value(tree, id, tvb, start, length, - value_ptr, format, ...); + proto_item * + proto_tree_add_time_format_value(tree, id, tvb, start, length, + value_ptr, format, ...); - proto_item * - proto_tree_add_ipxnet(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_ipxnet(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_ipxnet_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_ipxnet_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_ipxnet_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_ipxnet_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item * - proto_tree_add_ipv4(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_ipv4(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_ipv4_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_ipv4_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_ipv4_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_ipv4_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item * - proto_tree_add_ipv6(tree, id, tvb, start, length, value_ptr); + proto_item * + proto_tree_add_ipv6(tree, id, tvb, start, length, value_ptr); - proto_item * - proto_tree_add_ipv6_format(tree, id, tvb, start, length, value_ptr, - format, ...); + proto_item * + proto_tree_add_ipv6_format(tree, id, tvb, start, length, value_ptr, + format, ...); - proto_item * - proto_tree_add_ipv6_format_value(tree, id, tvb, start, length, - value_ptr, format, ...); + proto_item * + proto_tree_add_ipv6_format_value(tree, id, tvb, start, length, + value_ptr, format, ...); - proto_item * - proto_tree_add_ether(tree, id, tvb, start, length, value_ptr); + proto_item * + proto_tree_add_ether(tree, id, tvb, start, length, value_ptr); - proto_item * - proto_tree_add_ether_format(tree, id, tvb, start, length, value_ptr, - format, ...); + proto_item * + proto_tree_add_ether_format(tree, id, tvb, start, length, value_ptr, + format, ...); - proto_item * - proto_tree_add_ether_format_value(tree, id, tvb, start, length, - value_ptr, format, ...); + proto_item * + proto_tree_add_ether_format_value(tree, id, tvb, start, length, + value_ptr, format, ...); - proto_item * - proto_tree_add_string(tree, id, tvb, start, length, value_ptr); + proto_item * + proto_tree_add_string(tree, id, tvb, start, length, value_ptr); - proto_item * - proto_tree_add_string_format(tree, id, tvb, start, length, value_ptr, - format, ...); + proto_item * + proto_tree_add_string_format(tree, id, tvb, start, length, value_ptr, + format, ...); - proto_item * - proto_tree_add_string_format_value(tree, id, tvb, start, length, - value_ptr, format, ...); + proto_item * + proto_tree_add_string_format_value(tree, id, tvb, start, length, + value_ptr, format, ...); - proto_item * - proto_tree_add_boolean(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_boolean(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_boolean_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_boolean_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_boolean_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_boolean_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item * - proto_tree_add_float(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_float(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_float_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_float_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_float_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_float_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item * - proto_tree_add_double(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_double(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_double_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_double_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_double_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_double_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item * - proto_tree_add_uint(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_uint(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_uint_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_uint_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_uint_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_uint_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item * - proto_tree_add_uint64(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_uint64(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_uint64_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_uint64_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_uint64_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_uint64_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item * - proto_tree_add_int(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_int(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_int_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_int_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_int_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_int_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item * - proto_tree_add_int64(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_int64(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_int64_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_int64_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_int64_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_int64_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item* - proto_tree_add_text(tree, tvb, start, length, format, ...); + proto_item* + proto_tree_add_text(tree, tvb, start, length, format, ...); - proto_item* - proto_tree_add_text_valist(tree, tvb, start, length, format, ap); + proto_item* + proto_tree_add_text_valist(tree, tvb, start, length, format, ap); - proto_item * - proto_tree_add_guid(tree, id, tvb, start, length, value_ptr); + proto_item * + proto_tree_add_guid(tree, id, tvb, start, length, value_ptr); - proto_item * - proto_tree_add_guid_format(tree, id, tvb, start, length, value_ptr, - format, ...); + proto_item * + proto_tree_add_guid_format(tree, id, tvb, start, length, value_ptr, + format, ...); - proto_item * - proto_tree_add_guid_format_value(tree, id, tvb, start, length, - value_ptr, format, ...); + proto_item * + proto_tree_add_guid_format_value(tree, id, tvb, start, length, + value_ptr, format, ...); - proto_item * - proto_tree_add_oid(tree, id, tvb, start, length, value_ptr); + proto_item * + proto_tree_add_oid(tree, id, tvb, start, length, value_ptr); - proto_item * - proto_tree_add_oid_format(tree, id, tvb, start, length, value_ptr, - format, ...); + proto_item * + proto_tree_add_oid_format(tree, id, tvb, start, length, value_ptr, + format, ...); - proto_item * - proto_tree_add_eui64(tree, id, tvb, start, length, value); + proto_item * + proto_tree_add_eui64(tree, id, tvb, start, length, value); - proto_item * - proto_tree_add_eui64_format(tree, id, tvb, start, length, value, - format, ...); + proto_item * + proto_tree_add_eui64_format(tree, id, tvb, start, length, value, + format, ...); - proto_item * - proto_tree_add_eui64_format_value(tree, id, tvb, start, length, - value, format, ...); + proto_item * + proto_tree_add_eui64_format_value(tree, id, tvb, start, length, + value, format, ...); - proto_item * - proto_tree_add_oid_format_value(tree, id, tvb, start, length, - value_ptr, format, ...); + proto_item * + proto_tree_add_oid_format_value(tree, id, tvb, start, length, + value_ptr, format, ...); - proto_item* - proto_tree_add_bits_item(tree, id, tvb, bit_offset, no_of_bits, - little_endian); + proto_item* + proto_tree_add_bits_item(tree, id, tvb, bit_offset, no_of_bits, + little_endian); - proto_item * - proto_tree_add_bits_ret_val(tree, id, tvb, bit_offset, no_of_bits, - return_value, little_endian); + proto_item * + proto_tree_add_bits_ret_val(tree, id, tvb, bit_offset, no_of_bits, + return_value, little_endian); - proto_item * - proto_tree_add_bitmask(tree, tvb, start, header, ett, fields, - little_endian); + proto_item * + proto_tree_add_bitmask(tree, tvb, start, header, ett, fields, + little_endian); - proto_item * - proto_tree_add_bitmask_text(tree, tvb, offset, len, name, fallback, - ett, fields, little_endian, flags); + proto_item * + proto_tree_add_bitmask_text(tree, tvb, offset, len, name, fallback, + ett, fields, little_endian, flags); - proto_item * - proto_tree_add_split_bits_item_ret_val(tree, hf_index, tvb, bit_offset, - crumb_spec, return_value); + proto_item * + proto_tree_add_split_bits_item_ret_val(tree, hf_index, tvb, bit_offset, + crumb_spec, return_value); - void - proto_tree_add_split_bits_crumb(tree, hf_index, tvb, bit_offset, - crumb_spec, crumb_index); + void + proto_tree_add_split_bits_crumb(tree, hf_index, tvb, bit_offset, + crumb_spec, crumb_index); The 'tree' argument is the tree to which the item is to be added. The 'tvb' argument is the tvbuff from which the item's value is being @@ -2341,8 +2340,8 @@ The length of some items cannot be determined until the item has been dissected; to add such an item, add it with a length of -1, and, when the dissection is complete, set the length with 'proto_item_set_len()': - void - proto_item_set_len(ti, length); + void + proto_item_set_len(ti, length); The "ti" argument is the value returned by the call that added the item to the tree, and the "length" argument is the length of the item. @@ -2379,16 +2378,16 @@ count and the 16-bit values in the string must be the same). In other cases, ENC_NA should be used. The character encodings that are currently supported are: - ENC_ASCII - ASCII (currently treated as UTF-8; in the future, - all bytes with the 8th bit set will be treated as - errors) - ENC_UTF_8 - UTF-8 - ENC_UCS_2 - UCS-2 - ENC_UTF_16 - UTF-16 (currently treated as UCS-2; in the future, - surrogate pairs will be handled, and non-valid 16-bit - code points and surrogate pairs will be treated as - errors) - ENC_EBCDIC - EBCDIC + ENC_ASCII - ASCII (currently treated as UTF-8; in the future, + all bytes with the 8th bit set will be treated as + errors) + ENC_UTF_8 - UTF-8 + ENC_UCS_2 - UCS-2 + ENC_UTF_16 - UTF-16 (currently treated as UCS-2; in the future, + surrogate pairs will be handled, and non-valid 16-bit + code points and surrogate pairs will be treated as + errors) + ENC_EBCDIC - EBCDIC Other encodings will be added in the future. @@ -2396,13 +2395,13 @@ For FT_ABSOLUTE_TIME fields, the encoding specifies the form in which the time stamp is specified, as well as its byte order. The time stamp encodings that are currently supported are: - ENC_TIME_TIMESPEC - seconds (4 bytes) and nanoseconds (4 bytes) - of time since January 1, 1970, midnight UTC. + ENC_TIME_TIMESPEC - seconds (4 bytes) and nanoseconds (4 bytes) + of time since January 1, 1970, midnight UTC. - ENC_TIME_NTP - an NTP timestamp, represented as a 64-bit - unsigned fixed-point number, in seconds relative to 0h - on 1 January 1900. The integer part is in the first 32 - bits and the fraction part in the last 32 bits. + ENC_TIME_NTP - an NTP timestamp, represented as a 64-bit + unsigned fixed-point number, in seconds relative to 0h + on 1 January 1900. The integer part is in the first 32 + bits and the fraction part in the last 32 bits. For other types, there is no support for proto_tree_add_item(). @@ -2413,20 +2412,20 @@ Identifier (FID) field in the Transmission Header (TH) portion of the SNA protocol. The FID is the high nibble of the first byte of the TH. The FID would be registered like this: - name = "Format Identifier" - abbrev = "sna.th.fid" - type = FT_UINT8 - display = BASE_HEX - strings = sna_th_fid_vals - bitmask = 0xf0 + name = "Format Identifier" + abbrev = "sna.th.fid" + type = FT_UINT8 + display = BASE_HEX + strings = sna_th_fid_vals + bitmask = 0xf0 The bitmask contains the value which would leave only the FID if bitwise-ANDed against the parent field, the first byte of the TH. The code to add the FID to the tree would be; - proto_tree_add_item(bf_tree, hf_sna_th_fid, tvb, offset, 1, - ENC_BIG_ENDIAN); + proto_tree_add_item(bf_tree, hf_sna_th_fid, tvb, offset, 1, + ENC_BIG_ENDIAN); The definition of the field already has the information about bitmasking and bitshifting, so it does the work of masking and shifting for us! @@ -2437,14 +2436,14 @@ even though the FID value is actually contained in the high nibble. /* Format Identifier */ static const value_string sna_th_fid_vals[] = { - { 0x0, "SNA device <--> Non-SNA Device" }, - { 0x1, "Subarea Node <--> Subarea Node" }, - { 0x2, "Subarea Node <--> PU2" }, - { 0x3, "Subarea Node or SNA host <--> Subarea Node" }, - { 0x4, "?" }, - { 0x5, "?" }, - { 0xf, "Adjacent Subarea Nodes" }, - { 0, NULL } + { 0x0, "SNA device <--> Non-SNA Device" }, + { 0x1, "Subarea Node <--> Subarea Node" }, + { 0x2, "Subarea Node <--> PU2" }, + { 0x3, "Subarea Node or SNA host <--> Subarea Node" }, + { 0x4, "?" }, + { 0x5, "?" }, + { 0xf, "Adjacent Subarea Nodes" }, + { 0, NULL } }; The final implication of this is that display filters work the way you'd @@ -2489,10 +2488,10 @@ proto_tree_add_eui64() ------------------------ These routines are used to add items to the protocol tree if either: - the value of the item to be added isn't just extracted from the - packet data, but is computed from data in the packet; + the value of the item to be added isn't just extracted from the + packet data, but is computed from data in the packet; - the value was fetched into a variable. + the value was fetched into a variable. The 'value' argument has the value to be added to the tree. @@ -2641,11 +2640,11 @@ in the subtree. This means the label can't be set until at least some of the items in the subtree have been dissected. To do this, use 'proto_item_set_text()' or 'proto_item_append_text()': - void - proto_item_set_text(proto_item *ti, ...); + void + proto_item_set_text(proto_item *ti, ...); - void - proto_item_append_text(proto_item *ti, ...); + void + proto_item_append_text(proto_item *ti, ...); 'proto_item_set_text()' takes as an argument the value returned by 'proto_tree_add_text()', a 'printf'-style format string, and a set of @@ -2658,11 +2657,11 @@ the item the result of applying the arguments to the format string. For example, early in the dissection, one might do: - ti = proto_tree_add_text(tree, tvb, offset, length,