Final updates for 0.9.14.
[metze/wireshark/wip.git] / packet-fw1.c
1 /* packet-fw1.c
2  * Routines for Ethernet header disassembly of FW1 "monitor" files
3  * Copyright 2002, Alfred Koebler <ak@icon-sult.de>
4  *
5  * $Id: packet-fw1.c,v 1.7 2003/06/12 07:37:30 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Alfred Koebler <ak@icon-sult.de>
9  * Copyright 2002 Alfred Koebler
10  *
11  * To use this dissector use the command line option
12  * -o eth.interpret_as_fw1_monitor:TRUE
13  *
14  * At the moment the way with the option is the best one.
15  * A automatic way is not possible, because the file format isn't different
16  * to the snoop file.
17  *
18  * With "fw monitor" it is possible to collect packets on several places.
19  * The additional information:
20  * - is it a incoming or outgoing packet
21  * - is it before or after the firewall
22  *   i  incoming before the firewall
23  *   I  incoming after the firewall
24  *   o  outcoming before the firewall
25  *   O  outcoming after the firewall
26  * - the name of the interface
27  *
28  * What's the problem ?
29  * Think about one packet traveling across the firewall.
30  * With ethereal you will see 4 lines in the Top Pane.
31  * To analyze a problem it is helpful to see the additional information
32  * in the protocol tree of the Middle Pane.
33  *
34  * The presentation of the summary line is designed in the following way:
35  * Every time the next selected packet in the Top Pane includes a
36  * "new" interface name the name is added to the list in the summary line.
37  * The interface names are listed one after the other.
38  * The position of the interface names didn't change.
39  *
40  * And who are the 4 places represented ?
41  * The interface name represents the firewall module of the interface.
42  * On the left side of the interface name is the interface module.
43  * On the right side of the interface name is the "IP" module.
44  *
45  * Example for a ping from the firewall to another host:
46  * For the four lines in the Top Pane you will see the according lines
47  * in the Middle Pane:
48  *   El90x1 o
49  * O El90x1
50  * i El90x1
51  *   El90x1 I
52  *
53  * Example for a packet traversing through the Firewall, first through
54  * the inner side firewall module then through the outer side firewall module:
55  * i  El90x1        El90x2
56  *    El90x1 I      El90x2
57  *    El90x1      o E190x2
58  *    El90x1        E190x2 O
59  *
60  * 9.12.2002
61  * Add new column with summary of FW-1 interface/direction
62  *
63  * This program is free software; you can redistribute it and/or
64  * modify it under the terms of the GNU General Public License
65  * as published by the Free Software Foundation; either version 2
66  * of the License, or (at your option) any later version.
67  *
68  * This program is distributed in the hope that it will be useful,
69  * but WITHOUT ANY WARRANTY; without even the implied warranty of
70  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
71  * GNU General Public License for more details.
72  *
73  * You should have received a copy of the GNU General Public License
74  * along with this program; if not, write to the Free Software
75  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
76  */
77
78 #ifdef HAVE_CONFIG_H
79 # include "config.h"
80 #endif
81
82 #include <string.h>
83
84 #include <glib.h>
85 #include <epan/packet.h>
86 #include "prefs.h"
87 #include "etypes.h"
88
89 /* Place FW1 summary in proto tree */
90 static gboolean fw1_summary_in_tree = TRUE;
91
92 /* Initialize the protocol and registered fields */
93 static int proto_fw1 = -1;
94 static int hf_fw1_direction = -1;
95 static int hf_fw1_interface = -1;
96 static int hf_fw1_type = -1;
97 static int hf_fw1_trailer = -1;
98
99 /* Initialize the subtree pointers */
100 static gint ett_fw1 = -1;
101
102 #define ETH_HEADER_SIZE 14
103
104 static dissector_handle_t eth_handle;
105
106 static void
107 dissect_fw1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
108 {
109   /* Set up structures needed to add the protocol subtree and manage it */
110   proto_item    *ti;
111   proto_tree    *volatile fh_tree = NULL;
112   char          direction[3];
113   char          interface_name[10+1];
114   guint16       etype;
115   char          header[1000];
116   char          *p_header;
117   int           i;
118   int           found;
119
120   #define       MAX_INTERFACES  20
121   static char   *p_interfaces[MAX_INTERFACES];
122   static int    interface_anzahl=0;
123   static char   header1[] = "FW1 Monitor";
124
125 #ifdef  DID_NOT_FIND_A_PLACE_TO_START_THE_RESET_LIST_OF_INTERFACES
126   if (fw1_reset_list_of_if_on_next_begin) {
127     /* without FW1 summary delete all remembered names of interfaces */
128     for (i=0; i<interface_anzahl && i<MAX_INTERFACES; i++) {
129       free(p_interfaces[i]);
130     }
131     interface_anzahl = 0;
132     fw1_reset_list_of_if_on_next_begin = FALSE;
133   }
134 #endif
135
136   /* Make entries in Protocol column and Info column on summary display */
137   if (check_col(pinfo->cinfo, COL_PROTOCOL))
138     col_set_str(pinfo->cinfo, COL_PROTOCOL, "FW1");
139   if (check_col(pinfo->cinfo, COL_INFO))
140     col_clear(pinfo->cinfo, COL_INFO);
141
142   etype = tvb_get_ntohs(tvb, 12);
143
144   sprintf(header, header1);
145
146   /* fetch info to local variable */
147   direction[0] = tvb_get_guint8(tvb, 0);
148   direction[1] = 0;
149   tvb_get_nstringz0(tvb, 2, sizeof interface_name, interface_name);
150
151   /* Known interface name - if not, remember it */
152   found=1;
153   for (i=0; i<interface_anzahl && i<MAX_INTERFACES; i++) {
154     if ( strcmp(p_interfaces[i], interface_name) == 0 ) {
155       found=0;
156     }
157   }
158   if (found == 1 ) {
159     p_interfaces[interface_anzahl] = strdup(interface_name);
160     interface_anzahl++;
161   }
162   /* display all interfaces always in the same order */
163   for (i=0; i<interface_anzahl; i++) {
164     found=1;
165     if ( strcmp(p_interfaces[i], interface_name) == 0 ) {
166       found=0;
167     }
168     p_header = header + strlen(header);
169     sprintf(p_header, "  %c %s %c",
170         found==0 ? (direction[0]=='i' ? 'i' : (direction[0]=='O' ? 'O' : ' ')) : ' ',
171         p_interfaces[i],
172         found==0 ? (direction[0]=='I' ? 'I' : (direction[0]=='o' ? 'o' : ' ')) : ' '
173         );
174   }
175
176   if (check_col(pinfo->cinfo, COL_IF_DIR))
177     col_add_str(pinfo->cinfo, COL_IF_DIR, header + strlen(header1) + 1);
178
179   if (tree) {
180     if (!fw1_summary_in_tree) {
181       /* Do not show the summary in Protocol Tree */
182       sprintf(header, header1);
183     }
184     ti = proto_tree_add_protocol_format(tree, proto_fw1, tvb, 0, ETH_HEADER_SIZE, header);
185
186     /* create display subtree for the protocol */
187     fh_tree = proto_item_add_subtree(ti, ett_fw1);
188
189     proto_tree_add_item(fh_tree, hf_fw1_direction, tvb, 0, 1, FALSE);
190
191     proto_tree_add_string_format(fh_tree, hf_fw1_interface,
192         tvb, 2, 10,
193         interface_name, "Interface: %s", interface_name);
194   }
195   ethertype(etype, tvb, ETH_HEADER_SIZE, pinfo, tree, fh_tree, hf_fw1_type,
196           hf_fw1_trailer);
197 }
198
199 void
200 proto_register_fw1(void)
201 {
202   static hf_register_info hf[] = {
203         { &hf_fw1_direction,
204         { "Direction",  "fw1.direction", FT_STRING, BASE_NONE, NULL, 0x0,
205                 "Direction", HFILL }},
206         { &hf_fw1_interface,
207         { "Interface",  "fw1.interface", FT_STRING, BASE_NONE, NULL, 0x0,
208                 "Interface", HFILL }},
209                 /* registered here but handled in ethertype.c */
210         { &hf_fw1_type,
211         { "Type",               "fw1.type", FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
212                 "", HFILL }},
213   };
214   /* Setup protocol subtree array */
215   static gint *ett[] = {
216         &ett_fw1,
217   };
218   module_t *fw1_module;
219
220   /* Register the protocol name and description */
221   proto_fw1 = proto_register_protocol("Checkpoint FW-1", "FW-1", "fw1");
222   /* Required function calls to register the header fields and subtrees used */
223   proto_register_field_array(proto_fw1, hf, array_length(hf));
224   proto_register_subtree_array(ett, array_length(ett));
225
226   /* Register configuration preferences */
227   fw1_module = prefs_register_protocol(proto_fw1, NULL);
228   prefs_register_bool_preference(fw1_module, "summary_in_tree",
229             "Show FireWall-1 summary in protocol tree",
230             "Whether the FireWall-1 summary line should be shown in the protocol tree",
231             &fw1_summary_in_tree);
232
233   register_dissector("fw1", dissect_fw1, proto_fw1);
234 }
235
236 void
237 proto_reg_handoff_fw1(void)
238 {
239   /*
240    * Get handles for the Ethernet dissectors.
241    */
242   eth_handle = find_dissector("eth");
243 }