Define some fcns & vars as static...
[metze/wireshark/wip.git] / epan / dissectors / packet-hilscher.c
1 /* packet-hilscher.c
2  * Dissector for Hilscher analyzer protocols.
3  * Copyright 2008, Hilscher GmbH, Holger Pfrommer hpfrommer[AT]hilscher.com
4  *
5  * $Id$
6  *
7  * This is a new dissector plugin for Hilscher analyzer frames.
8  * These frames are generated by Hilscher analyzer products and are identified via
9  * their unique source MAC address (this is a reserved MAC from Hilscher-range and
10  * will never be used by another network device). Most likely these frames are
11  * only generated on a virtual network interface or the generating device is
12  * attached directly via patch cable to a real network interface, but not routed
13  * through a network. The Ethernet-header (destination MAC, source MAC and
14  * Length/Type) is not displayed in the protocol tree for these frames as this is
15  * overhead-information which has no practical use in this case.
16  *
17  * Wireshark - Network traffic analyzer
18  * By Gerald Combs <gerald[AT]wireshark.org>
19  * Copyright 1999 Gerald Combs
20  *
21  * This program is free software; you can redistribute it and/or
22  * modify it under the terms of the GNU General Public License
23  * as published by the Free Software Foundation; either version 2
24  * of the License, or (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29  * GNU General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, write to the Free Software
33  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
34  */
35
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 #include <glib.h>
42 #include <epan/packet.h>
43 #include <epan/prefs.h>
44
45
46 static int  proto_hilscher              = -1;
47 static module_t *hilscher_module;
48
49 /*  Ethernet heuristic dissectors (such as this one) get called for
50  *  every Ethernet frame Wireshark handles.  In order to not impose that
51  *  performance penalty on everyone this dissector disables itself by
52  *  default.
53  *
54  *  This is done separately from the disabled protocols list mainly so
55  *  we can disable it by default.  XXX Maybe there's a better way.
56  */
57 static gboolean  hilscher_enable_dissector = FALSE;
58
59 void proto_reg_handoff_hilscher(void);
60
61 static gint ett_information_type        = -1;
62 static gint ett_gpio_number             = -1;
63 static gint ett_gpio_edge               = -1;
64
65 static int  hf_information_type         = -1;
66 static int  hf_gpio_number              = -1;
67 static int  hf_gpio_edge                = -1;
68
69 #define  INFO_TYPE_OFFSET    14
70
71 static const value_string information_type[] = {
72         { 0x0, "netANALYZER GPIO event" },
73         { 0,   NULL }
74 };
75
76 static const value_string gpio_number[] = {
77         { 0x0, "GPIO 0" },
78         { 0x1, "GPIO 1" },
79         { 0x2, "GPIO 2" },
80         { 0x3, "GPIO 3" },
81         { 0,   NULL }
82 };
83
84 static const value_string gpio_edge[] = {
85         { 0x0, "rising edge" },
86         { 0x1, "falling edge" },
87         { 0,   NULL }
88 };
89
90 /* netANAYLZER dissector */
91 static void
92 dissect_hilscher_netanalyzer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset)
93 {
94         proto_item      *ti        = NULL;
95         guint           gpio_num;
96         guint           gpio_edgex;
97
98         col_set_str(pinfo->cinfo, COL_PROTOCOL, "netANALYZER");
99
100         if (tree)
101                 ti = proto_tree_add_item(tree, hf_information_type, tvb, offset, 1, FALSE);
102
103         /* GPIO NUMBER */
104         offset++;
105         if (tree)
106                 ti = proto_tree_add_item (tree, hf_gpio_number, tvb, offset, 1, FALSE);
107         gpio_num = (tvb_get_guint8(tvb, offset) & 0x03);
108
109         /* GPIO EDGE */
110         offset++;
111         if (tree)
112                 ti = proto_tree_add_item (tree, hf_gpio_edge, tvb, offset, 1, FALSE);
113         gpio_edgex = (tvb_get_guint8(tvb, offset) & 0x01);
114
115         if (gpio_edgex == 0x00)
116                 col_add_fstr(pinfo->cinfo, COL_INFO, "netANALYZER event on GPIO %d (rising edge)", gpio_num);
117         else
118                 col_add_fstr(pinfo->cinfo, COL_INFO, "netANALYZER event on GPIO %d (falling edge)", gpio_num);
119 }
120
121
122 /* General Hilscher analyzer dissector */
123 static gboolean
124 dissect_hilscher_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
125 {
126         guint       info_type;
127         gint        offset;
128
129         /* Check that there's enough data */
130         if (tvb_length(tvb) < 14)
131                 return FALSE;
132
133         /* check for Hilscher frame, this has a unique source MAC from Hilscher range and ethertype 0x88ff
134            First 14 bytes must be: xx xx xx xx xx xx 00 02 a2 ff ff ff 88 ff */
135         if ((tvb_get_guint8(tvb, 6) == 0x00) &&
136             (tvb_get_guint8(tvb, 7) == 0x02) &&
137             (tvb_get_guint8(tvb, 8) == 0xa2) &&
138             (tvb_get_guint8(tvb, 9) == 0xff) &&
139             (tvb_get_guint8(tvb, 10) == 0xff) &&
140             (tvb_get_guint8(tvb, 11) == 0xff) &&
141             (tvb_get_guint8(tvb, 12) == 0x88) &&
142             (tvb_get_guint8(tvb, 13) == 0xff) )
143         {
144
145                 /* determine type of analyzer */
146                 offset = INFO_TYPE_OFFSET;
147                 info_type = tvb_get_guint8(tvb, offset);
148
149                 switch (info_type)
150                 {
151                 /* this is a netANALYZER frame */
152                 case 0x00:
153                         dissect_hilscher_netanalyzer(tvb, pinfo, tree, offset);
154                         break;
155
156                 /* this is no Hilscher analyzer frame */
157                 default:
158                         return FALSE;
159                         break;
160                 }
161
162         }
163         else
164         {
165                 /* this is no Hilscher analyzer frame */
166                 return FALSE;
167         }
168
169           return TRUE;
170 }
171
172
173
174 void proto_register_hilscher(void)
175 {
176     static hf_register_info hf[] = {
177         { &hf_information_type,
178           { "Hilscher information block type", "hilscher.information_type",
179             FT_UINT8, BASE_HEX, VALS(information_type), 0x0, NULL, HFILL }
180         },
181         { &hf_gpio_number,
182           { "Event on", "hilscher.net_analyzer.gpio_number", FT_UINT8,
183             BASE_HEX, VALS(gpio_number), 0x0, NULL, HFILL }
184         },
185         { &hf_gpio_edge,
186                 { "Event type", "hilscher.net_analyzer.gpio_edge", FT_UINT8,
187                   BASE_HEX, VALS(gpio_edge), 0x0, NULL, HFILL }
188         },
189     };
190
191     static gint *ett[] = {
192         &ett_information_type,
193         &ett_gpio_number,
194         &ett_gpio_edge,
195     };
196
197     proto_hilscher = proto_register_protocol ("Hilscher analyzer dissector",    /* name */
198                                               "Hilscher",               /* short name */
199                                               "hilscher");              /* abbrev */
200
201     hilscher_module = prefs_register_protocol(proto_hilscher, proto_reg_handoff_hilscher);
202
203     prefs_register_bool_preference(hilscher_module, "enable", "Enable dissector",
204                                    "Enable this dissector (default is false)",
205                                    &hilscher_enable_dissector);
206
207     proto_register_field_array(proto_hilscher, hf, array_length(hf));
208     proto_register_subtree_array(ett, array_length(ett));
209
210 }
211
212 void proto_reg_handoff_hilscher(void)
213 {
214     static gboolean prefs_initialized = FALSE;
215
216     if (!prefs_initialized) {
217         /* add heuristic dissector */
218         heur_dissector_add("eth", dissect_hilscher_heur, proto_hilscher);
219         prefs_initialized = TRUE;
220     }
221
222     proto_set_decoding(proto_hilscher, hilscher_enable_dissector);
223 }