From Benjamin Roch:
[obnox/wireshark/wip.git] / epan / dissectors / packet-tte.c
1 /* packet-tte.c
2  * Routines for Time Triggered Ethernet dissection
3  *
4  * Author: Valentin Ecker, valentin.ecker (AT) tttech.com
5  * TTTech Computertechnik AG, Austria.
6  * http://www.tttech.com/solutions/ttethernet/
7  *
8  * $Id$
9  *
10  * Wireshark - Network traffic analyzer
11  * By Gerald Combs <gerald@wireshark.org>
12  * Copyright 1998 Gerald Combs
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
27  * USA.
28  */
29
30 #ifdef HAVE_CONFIG_H
31  #include "config.h"
32 #endif
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <glib.h>
38
39 #include <epan/packet.h>
40 #include <epan/prefs.h>
41 #include <epan/etypes.h>
42
43 #include "packet-tte.h"
44
45
46 /* Forward declaration we need below */
47 void proto_reg_handoff_tte(void);
48
49 /* Initialize the protocol and registered fields */
50 static int proto_tte = -1;
51
52 static int hf_tte_macdest = -1;
53 static int hf_tte_macdest_cf1 = -1;
54 static int hf_tte_macdest_ctid = -1;
55 static int hf_tte_macsrc = -1;
56 static int hf_tte_ethertype = -1;
57
58 /* preference value pointers */
59 static guint32    tte_pref_ct_marker    = 0xFFFFFFFF;
60 static guint32    tte_pref_ct_mask      = 0x0;
61 static dissector_table_t ethertype_dissector_table;
62
63 /* Initialize the subtree pointers */
64 static gint ett_tte = -1;
65 static gint ett_tte_macdest = -1;
66 static gint ett_tte_macsrc = -1;
67
68
69
70 /* Code to actually dissect the packets */
71 static int
72 dissect_tte(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
73 {
74     tvbuff_t* tvb_next;
75     int is_frame_pcf;
76
77     /* Set up structures needed to add the protocol subtree and manage it */
78     proto_item *tte_root_item, *tte_macdest_item, *tte_macsrc_item;
79     proto_tree *tte_tree, *tte_macdest_tree/*, *tte_macsrc_tree*/;
80
81     /* Check that there's enough data */
82     if (tvb_length(tvb) < TTE_HEADER_LENGTH)
83         return 0;
84
85     /* check if data of pcf frame */
86     is_frame_pcf = 
87        (tvb_get_ntohs(tvb, TTE_MAC_LENGTH * 2) == ETHERTYPE_TTE_PCF);
88
89     /* return if no valid cosntant field is found */
90     if (!is_frame_pcf)
91     {
92         if ( (tvb_get_ntohl(tvb, 0) & tte_pref_ct_mask) != tte_pref_ct_marker)
93             return 0;
94     }
95
96     /* Make entries in Protocol column and Info column on summary display */
97     if (check_col(pinfo->cinfo, COL_PROTOCOL))
98         col_set_str(pinfo->cinfo, COL_PROTOCOL, "TTE ");
99
100     if (check_col(pinfo->cinfo, COL_INFO))
101         col_set_str(pinfo->cinfo, COL_INFO, "Bogus TTEthernet Frame");
102
103     if (tree) {
104
105         /* create display subtree for the protocol */
106         tte_root_item = proto_tree_add_item(tree, proto_tte, tvb, 0,
107             TTE_HEADER_LENGTH, FALSE);
108
109         tte_tree = proto_item_add_subtree(tte_root_item, ett_tte);
110
111         tte_macdest_item = proto_tree_add_item(tte_tree,
112             hf_tte_macdest, tvb, 0, TTE_MAC_LENGTH, FALSE);
113
114         tte_macsrc_item = proto_tree_add_item(tte_tree,
115             hf_tte_macsrc, tvb, TTE_MAC_LENGTH, TTE_MAC_LENGTH, FALSE);
116
117         proto_tree_add_item(tte_tree,
118             hf_tte_ethertype, tvb, TTE_MAC_LENGTH*2, TTE_ETHERTYPE_LENGTH,
119             FALSE);
120
121         tte_macdest_tree = proto_item_add_subtree(tte_macdest_item,
122             ett_tte_macdest);
123
124         proto_tree_add_item(tte_macdest_tree,
125             hf_tte_macdest_cf1, tvb, 0, TTE_MACDEST_CF_LENGTH, FALSE);
126
127         proto_tree_add_item(tte_macdest_tree,
128             hf_tte_macdest_ctid, tvb, TTE_MACDEST_CF_LENGTH,
129             TTE_MACDEST_CTID_LENGTH, FALSE);
130     }
131
132     tvb_next = tvb_new_subset(tvb, TTE_HEADER_LENGTH, -1, -1);
133
134     /* prevent the Columns to be cleared...appending cannot be prevented */
135     col_set_fence(pinfo->cinfo, COL_PROTOCOL);
136
137     /* call std Ethernet dissector */
138     dissector_try_port(ethertype_dissector_table,
139         tvb_get_ntohs(tvb, TTE_MAC_LENGTH * 2), tvb_next, pinfo, tree);
140
141     return tvb_length(tvb);
142 }
143
144
145 void
146 proto_register_tte(void)
147 {
148     module_t *tte_module;
149
150     static hf_register_info hf[] = {
151
152         { &hf_tte_macdest,
153             { "Destination", "tte.macdest",
154             FT_ETHER, BASE_HEX, NULL, 0x0,
155             NULL, HFILL }
156         },
157         { &hf_tte_macdest_cf1,
158             { "Constant Field", "tte.cf1",
159             FT_UINT32, BASE_HEX, NULL, 0x0,
160             NULL, HFILL }
161         },
162         { &hf_tte_macdest_ctid,
163             { "Critical Traffic Identifier", "tte.ctid",
164             FT_UINT16, BASE_HEX, NULL, 0x0,
165             NULL, HFILL }
166         },
167         { &hf_tte_macsrc,
168             { "Source", "tte.macsrc",
169             FT_ETHER, BASE_HEX, NULL, 0x0,
170             NULL, HFILL }
171         },
172         { &hf_tte_ethertype,
173             { "Type", "tte.type",
174             FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
175             NULL, HFILL }
176         }
177     };
178
179     /* Setup protocol subtree array */
180     static gint *ett[] = {
181         &ett_tte,
182         &ett_tte_macdest,
183         &ett_tte_macsrc
184     };
185
186     /* Register the protocol name and description */
187     proto_tte = proto_register_protocol("TTEthernet", "TTE", "tte");
188
189     /* Required function calls to register header fields and subtrees used */
190     proto_register_field_array(proto_tte, hf, array_length(hf));
191     proto_register_subtree_array(ett, array_length(ett));
192
193     /* Register preferences module */
194     tte_module = prefs_register_protocol(proto_tte, proto_reg_handoff_tte);
195
196     /* Register preferences */
197     prefs_register_uint_preference(tte_module, "ct_mask_value",
198         "CT Mask",
199         "Critical Traffic Mask (base hex)",
200         16, &tte_pref_ct_mask);
201
202     prefs_register_uint_preference(tte_module, "ct_marker_value",
203         "CT Marker",
204         "Critical Traffic Marker (base hex)",
205         16, &tte_pref_ct_marker);
206 }
207
208
209 void
210 proto_reg_handoff_tte(void)
211 {
212     heur_dissector_add("eth", dissect_tte, proto_tte);
213
214     /* find the ethertype dissector table */
215     ethertype_dissector_table = find_dissector_table("ethertype");
216 }