b8f716a3d250c3a5f03cf8cb68f62c2840933e29
[metze/wireshark/wip.git] / doc / README.plugins
1 0. Plugins
2
3 There are a multitude of plugin options available in Wireshark that allow to
4 extend its functionality without changing the source code itself.  Using the
5 available APIs gives you the means to do this.
6
7 Currently plugin APIs are available for dissectors (epan), capture file types
8 (wiretap) and media decoders (codecs).  This README focuses primarily on
9 dissector plugins; most of the descriptions are applicable to the other plugin
10 types as well.
11
12 1. Dissector plugins
13
14 Writing a "plugin" dissector is not very different from writing a standard
15 one.  In fact all of the functions described in README.dissector can be
16 used in the plugins exactly as they are used in standard dissectors.
17
18 (Note, however, that not all OSes on which Wireshark runs can support
19 plugins.)
20
21 If you've chosen "foo" as the name of your plugin (typically, that would
22 be a short name for your protocol, in all lower case), the following
23 instructions tell you how to implement it as a plugin.  All occurrences
24 of "foo" below should be replaced by the name of your plugin.
25
26 2. The directory for the plugin, and its files
27
28 The plugin should be placed in a new plugins/epan/foo directory which should
29 contain at least the following files:
30
31 CMakeLists.txt
32 Makefile.am
33 README
34
35 The README can be brief but it should provide essential information relevant
36 to developers and users. Optionally AUTHORS and ChangeLog files can be added.
37 Optionally you can add your own plugin.rc.in.
38
39 And of course the source and header files for your dissector.
40
41 Examples of these files can be found in plugins/epan/gryphon.
42
43 2.1 CMakeLists.txt
44
45 For your plugins/epan/foo/CMakeLists.txt file, see the corresponding file in
46 plugins/epan/gryphon.  Replace all occurrences of "gryphon" in those files
47 with "foo" and add your source files to the DISSECTOR_SRC variable.
48
49 2.2 Makefile.am
50
51 For your plugins/epan/foo/Makefile.am file, see the corresponding file in
52 plugins/epan/gryphon.  Replace all occurrences of "gryphon" in those files
53 with "foo".
54
55 Your plugins/epan/foo/Makefile.am also needs to list the main source file
56 which exports plugin_register() for your dissector in the
57 DISSECTOR_SRC variable.  All other supporting source files should be
58 listed in the DISSECTOR_SUPPORT_SRC variable.
59 The header files for your dissector, if any, must be listed in the
60 DISSECTOR_INCLUDES variable.
61
62 2.4 plugin.rc.in
63
64 Your plugins/epan/foo/plugin.rc.in is the Windows resource template file used
65 to add the plugin specific information as resources to the DLL.
66 If not provided the plugins/plugin.rc.in file will be used.
67
68 3. Changes to existing Wireshark files
69
70 There are two ways to add your plugin dissector to the build, as a custom
71 extension or as a permanent addition.  The custom extension is easy to
72 configure, but won't be used for inclusion in the distribution if that's
73 your goal.  Setting up the permanent addition is somewhat more involved.
74
75 3.1 Custom extension
76
77 Go to the plugins directory and copy the Custom.m4.example and
78 Custom.make.example files to files of the same name but without the ".example"
79 suffix.  Now you have two Custom files ready for building a plugin with the
80 name "foo".  Replace the name if you so require.
81
82 If you want to add the plugin to your own Windows installer add a text
83 file named custom_plugins.txt to the packaging/nsis directory, with a
84 "File" statement for NSIS:
85
86 File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\foo.dll"
87
88 For CMake builds, either pass the custom plugin dir on the CMake generation
89 step command line:
90
91 CMake ... -DCUSTOM_PLUGIN_SRC_DIR="plugins/epan/foo"
92
93 or copy the top-level file CMakeListsCustom.txt.example to CMakeListsCustom.txt
94 (also in the top-level source dir) and edit so that CUSTOM_PLUGIN_SRC_DIR is
95 set() to the relative path of your plugin, e.g.
96
97 set(CUSTOM_PLUGIN_SRC_DIR plugins/epan/foo)
98
99 and re-run the CMake generation step.
100
101 To build the plugin, run your normal Wireshark build step.
102
103 3.2 Permanent addition
104
105 In order to be able to permanently add a plugin take the following steps.
106 You will need to change the following files:
107         configure.ac
108         CMakeLists.txt
109         epan/Makefile.am
110         Makefile.am
111         packaging/nsis/wireshark.nsi
112         plugins/Makefile.am
113
114 You might also want to search your Wireshark development directory for
115 occurrences of an existing plugin name, in case this document is out of
116 date with the current directory structure.  For example,
117
118         grep -rl gryphon .
119
120 could be used from a shell prompt.
121
122 3.2.1  Changes to plugins/Makefile.am
123
124 The plugins directory contains a Makefile.am.  You need to add to SUBDIRS
125 (in alphabetical order) the name of your plugin:
126
127 SUBDIRS = $(_CUSTOM_SUBDIRS_) \
128         ...
129         epan/ethercat \
130         epan/foo \
131         epan/gryphon \
132         epan/irda \
133
134
135 3.2.2  Changes to the top level configure.ac
136
137 You need to add your plugins Makefile (in alphabetical order) to the
138 AC_OUTPUT rule in the configure.ac
139
140 AC_OUTPUT(
141   ...
142   plugins/epan/ethercat/Makefile
143   plugins/epan/foo/Makefile
144   plugins/epan/gryphon/Makefile
145   plugins/epan/irda/Makefile
146   ...
147   ,)
148
149 3.2.3  Changes to epan/Makefile.am
150
151 Add the relative path of all your plugin source files (in alphbetical
152 order) to plugin_src:
153
154 plugin_src = \
155         ...
156         ../plugins/epan/ethercat/packet-ioraw.c \
157         ../plugins/epan/ethercat/packet-nv.c \
158         ../plugins/epan/foo/packet-foo.c \
159         ../plugins/epan/gryphon/packet-gryphon.c \
160         ../plugins/epan/irda/packet-ircomm.c \
161         ../plugins/epan/irda/packet-irda.c \
162         ...
163
164 3.2.4  Changes to CMakeLists.txt
165
166 Add your plugin (in alphabetical order) to the PLUGIN_SRC_DIRS:
167
168 if(ENABLE_PLUGINS)
169         ...
170         set(PLUGIN_SRC_DIRS
171                 ...
172                 plugins/epan/ethercat
173                 plugins/epan/foo
174                 plugins/epan/gryphon
175                 plugins/epan/irda
176                 ...
177
178 3.2.5  Changes to the installers
179
180 If you want to include your plugin in an installer you have to add lines
181 in the NSIS installer wireshark.nsi file.
182
183 3.2.5.1  Changes to packaging/nsis/wireshark.nsi
184
185 Add the relative path of your plugin DLL (in alphbetical order) to the
186 list of "File" statements in the "Dissector Plugins" section:
187
188 File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\ethercat.dll"
189 File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\foo.dll"
190 File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\gryphon.dll"
191 File "${STAGING_DIR}\plugins\${VERSION_MAJOR}.${VERSION_MINOR}\epan\irda.dll"
192
193 3.2.5.2  Other installers
194
195 The PortableApps installer copies plugins from the build directory
196 and should not require configuration.
197
198 4. Development and plugins on Unix
199
200 Plugins make some aspects of development easier and some harder.
201
202 The first thing is that you'll have to run autogen.sh and configure once
203 more to setup your build environment.
204
205 The good news is that if you are working on a single plugin then you will
206 find recompiling the plugin MUCH faster than recompiling a dissector and
207 then linking it back into Wireshark. Use "make -C plugins" to compile just
208 your plugins.
209
210 The bad news is that Wireshark will not use the plugins unless the plugins
211 are installed in one of the places it expects them to find.
212
213 One way of dealing with this problem is to set an environment variable
214 when running Wireshark: WIRESHARK_RUN_FROM_BUILD_DIRECTORY=1.
215
216 Another way to deal with this problem is to set up a working root for
217 wireshark, say in $HOME/build/root and build wireshark to install
218 there
219
220 ./configure --prefix=${HOME}/build/root && make install
221
222 then subsequent rebuilds/installs of your plugin can be accomplished
223 by going to the plugins/foo directory and running
224
225 make install
226
227 5. Update "old style" plugins
228
229 5.1 How to update an "old style" plugin (since Wireshark 2.5)
230
231 Plugins need exactly three visible symbols: plugin_version, plugin_release and
232 plugin_register. Each plugin is either a libwscodecs plugin, libwiretap plugin or
233 libwireshark plugin and the library will call "plugin_register" after
234 loading the plugin. "plugin_register" in turn calls all the hooks necessary
235 to enable the plugin. So if you had two function like so:
236
237     WS_DLL_PUBLIC void plugin_register(void);
238     WS_DLL_PUBLIC void plugin_reg_handoff(void);
239
240     void plugin_register(void) {...};
241     void plugin_reg_handoff(void) {...};
242
243 You'll have to rewrite it as:
244
245     WS_DLL_PUBLIC void plugin_register(void);
246
247     static void proto_register_foo(void) {...};
248     static void proto_reg_handoff_foo(void) {...};
249
250     void plugin_register(void)
251     {
252         static proto_plugin plugin_foo;
253
254         plugin_foo.register_protoinfo = proto_register_foo;
255         plugin_foo.register_handoff = proto_reg_handoff_foo;
256         proto_register_plugin(&plugin_foo);
257     }
258
259 See doc/plugins.example for an example.
260
261 5.2 How to update an "old style" plugin (using plugin_register and
262     plugin_reg_handoff functions).
263
264 The plugin registration has changed with the extension of the build
265 scripts. These now generate the additional code needed for plugin
266 encapsulation in plugin.c. When using the new style build scripts,
267 stips the parts outlined below:
268
269     o Remove the following include statements:
270
271         #include <gmodule.h>
272         #include "moduleinfo.h"
273
274     o Removed the definition:
275
276         #ifndef ENABLE_STATIC
277         WS_DLL_PUBLIC_DEF gchar version[] = VERSION;
278         #endif
279
280     o Move relevant code from the blocks and delete these functions:
281
282         #ifndef ENABLE_STATIC
283         plugin_reg_handoff()
284         ....
285         #endif
286
287         #ifndef ENABLE_STATIC
288         plugin_register()
289         ....
290         #endif
291
292 This will leave a clean dissector source file without plugin specifics.
293
294 5.3 How to update an "old style" plugin (using plugin_init function)
295
296 The plugin registering has changed between 0.10.9 and 0.10.10; everyone
297 is encouraged to update their plugins as outlined below:
298
299     o Remove following include statements from all plugin sources:
300
301         #include "plugins/plugin_api.h"
302         #include "plugins/plugin_api_defs.h"
303
304     o Remove the init function.
305
306     o Change the Makefile.am file to match the one of the DOCSIS plugin.
307
308 6 How to plugin related interface options
309
310 To demonstrate the functionality of the plugin interface options, a
311 demonstration plugin exists (pluginifdemo). To build it using cmake, the
312 build option ENABLE_PLUGINIFDEMO has to be enabled.
313
314 6.1 Implement a plugin GUI menu
315
316 A plugin (as well as built-in dissectors) may implement a menu within
317 Wireshark to be used to trigger options, start tools, open Websites, ...
318
319 This menu structure is built using the plugin_if.h interface and its
320 corresponding functions.
321
322 The menu items all call a callback provided by the plugin, which takes
323 a pointer to the menuitem entry ad data. This pointer may be used to
324 provide userdata to each entry. The pointer must utilize WS_DLL_PUBLIC_DEF
325 and has the following structure:
326
327     WS_DLL_PUBLIC_DEF void
328     menu_cb(ext_menubar_gui_type gui_type, gpointer gui_data,
329             gpointer user_data _U_)
330     {
331         ... Do something ...
332     }
333
334 The menu entries themselves are generated with the following code structure:
335
336     ext_menu_t * ext_menu, *os_menu = NULL;
337
338     ext_menu = ext_menubar_register_menu (
339             <your_proto_item>, "Some Menu Entry", TRUE );
340     ext_menubar_add_entry(ext_menu, "Test Entry 1",
341             "This is a tooltip", menu_cb, <user_data>);
342     ext_menubar_add_entry(ext_menu, "Test Entry 2",
343             NULL, menu_cb, <user_data>);
344
345     os_menu = ext_menubar_add_submenu(ext_menu, "Sub Menu" );
346     ext_menubar_add_entry(os_menu, "Test Entry A",
347             NULL, menu_cb, <user_data>);
348     ext_menubar_add_entry(os_menu, "Test Entry B",
349             NULL, menu_cb, <user_data>);
350
351 For a more detailed information, please refer to plugin_if.h
352
353 6.2 Implement interactions with the main interface
354
355 Due to memory constraints on most platforms, plugin functionality cannot be
356 called directly from a DLL context. Instead special functions will be used,
357 which will implement certain options for plugins to utilize.
358
359 The following methods exist so far:
360
361         /* Applies the given filter string as display filter */
362         WS_DLL_PUBLIC void plugin_if_apply_filter
363                 (const char * filter_string, gboolean force);
364
365         /* Saves the given preference to the main preference storage */
366         WS_DLL_PUBLIC void plugin_if_save_preference
367                 (const char * pref_module, const char * pref_key, const char * pref_value);
368
369         /* Jumps to the given frame number */
370         WS_DLL_PUBLIC void plugin_if_goto_frame(guint32 framenr);
371
372 6.3 Implement a plugin specific toolbar
373
374 A toolbar may be registered which allows implementing an interactive user
375 interaction with the main application. The toolbar is generated using the following
376 code:
377
378     ext_toolbar_t * tb = ext_toolbar_register_toolbar("Plugin Interface Demo Toolbar");
379
380 This registers a toolbar, which will be shown underneath "View->Additional Toolbars" in
381 the main menu, as well as the popup action window when right-clicking on any other tool-
382 or menubar.
383
384 It behaves identically to the existing toolbars and can be hidden as well as defined to
385 appear specific to selected profiles. The name with which it is being shown is the given
386 name in this function call.
387
388 6.3.1 Register elements for the toolbar
389
390 To add items to the toolbar, 4 different types of elements do exist.
391
392   * BOOLEAN - a checkbox to select / unselect
393   * BUTTON - a button to click
394   * STRING - a text field with validation options
395   * SELECTOR - a dropdown selection field
396
397 To add an element to the toolbar, the following function is being used:
398
399     ext_toolbar_add_entry( ext_toolbar_t * parent, ext_toolbar_item_t type, const gchar *label,
400         const gchar *defvalue, const gchar *tooltip, gboolean capture_only, GList * value_list,
401         gboolean is_required, const gchar * regex, ext_toolbar_action_cb callback, gpointer user_data)
402
403     parent_bar - the parent toolbar for this entry, to be registered by ext_toolbar_register_toolbar
404     name - the entry name (the internal used one) for the item, used to send updates to the element
405     label - the entry label (the displayed name) for the item, visible to the user
406     defvalue - the default value for the toolbar element
407         - EXT_TOOLBAR_BOOLEAN - 1 is for a checked element, 0 is unchecked
408         - EXT_TOOLBAR_STRING - Text already entered upon initial display
409     tooltip - a tooltip to be displayed on mouse-over
410     capture_only - entry is only active, if a capture is active
411     callback - the action which will be invoked after the item is activated
412     value_list - a non-null list of values created by ext_toolbar_add_val(), if the item type
413         is EXT_TOOLBAR_SELECTOR
414     valid_regex - a validation regular expression for EXT_TOOLBAR_STRING
415     is_required - a zero entry for EXT_TOOLBAR_STRING is not allowed
416     user_data - a user defined pointer, which will be added to the toolbar callback
417
418 In case of the toolbar type EXT_TOOLBAR_SELECTOR a value list has to be provided. This list
419 is generated using ext_toolbar_add_val():
420
421     GList * entries = 0;
422     entries = ext_toolbar_add_val(entries, "1", "ABCD", FALSE );
423     entries = ext_toolbar_add_val(entries, "2", "EFG", FALSE );
424     entries = ext_toolbar_add_val(entries, "3", "HIJ", TRUE );
425     entries = ext_toolbar_add_val(entries, "4", "KLM", FALSE );
426
427 6.3.2 Callback for activation of an item
428
429 If an item has been activated, the provided callback is being triggered.
430
431     void toolbar_cb(gpointer toolbar_item, gpointer item_data, gpointer user_data)
432
433 For EXT_TOOLBAR_BUTTON the callback is triggered upon a click on the button, for
434 EXT_TOOLBAR_BOOLEAN and EXT_TOOLBAR_SELECTOR the callback is triggered with every change
435 of the selection.
436
437 For EXT_TOOLBAR_STRING either the return key has to be hit or the apply button pressed.
438
439 The parameters of the callback are defined as follows:
440
441     toolbar_item - an element of the type ext_toolbar_t * representing the item that has been
442                    activated
443     item_data - the data of the item during activation. The content depends on the item type:
444          - EXT_TOOLBAR_BUTTON - the entry is null
445          - EXT_TOOLBAR_BOOLEAN - the entry is 0 if the checkbox is unchecked and 1 if it is checked
446          - EXT_TOOLBAR_STRING - a string representing the context of the textbox. Only valid strings
447                    are being passed, it can be safely assumed, that an applied regular expression has
448                    been checked.
449          - EXT_TOOLBAR_SELECTOR - the value of the selected entry
450     user_data - the data provided during element registration
451
452 6.3.3 Sending updates to the toolbar items
453
454 A plugin may send updates to the toolbar entry, using one of the following methods. The parameter
455 silent defines, if the registered toolbar callback is triggered by the update or not.
456
457     void ext_toolbar_update_value(ext_toolbar_t * entry, gpointer data, gboolean silent)
458
459     - EXT_TOOLBAR_BUTTON, EXT_TOOLBAR_STRING - the displayed text (on the button or in the textbox)
460         are being changed, in that case data is expected to be a string
461     - EXT_TOOLBAR_BOOLEAN - the checkbox value is being changed, to either 0 or 1, in both cases
462         data is expected to be an integer sent by GINT_TO_POINTER(n)
463     - EXT_TOOLBAR_SELECTOR - the display text to be changed. If no element exists with this text,
464         nothing will happen
465
466     void ext_toolbar_update_data(ext_toolbar_t * entry, gpointer data, gboolean silent)
467
468     - EXT_TOOLBAR_SELECTOR - change the value list to the one provided with data. Attention! this
469         does not change the list stored within the item just the one in the displayed combobox
470
471     void ext_toolbar_update_data_by_index(ext_toolbar_t * entry, gpointer data, gpointer value,
472         gboolean silent)
473
474     - EXT_TOOLBAR_SELECTOR - change the display text for the entry with the provided value. Both
475         data and value must be gchar * pointer.
476
477
478 ----------------
479
480 Ed Warnicke <hagbard@physics.rutgers.edu>
481 Guy Harris <guy@alum.mit.edu>
482
483 Derived and expanded from the plugin section of README.developers
484 which was originally written by
485
486 James Coe <jammer@cin.net>
487 Gilbert Ramirez <gram@alumni.rice.edu>
488 Jeff Foster <jfoste@woodward.com>
489 Olivier Abad <oabad@cybercable.fr>
490 Laurent Deniel <laurent.deniel@free.fr>
491 Jaap Keuter <jaap.keuter@xs4all.nl>