/src/wireshark/epan/dissectors/packet-sapigs.c
Line | Count | Source |
1 | | /* packet-sapigs.c |
2 | | * Routines for SAP IGS (Internet Graphics Server) dissection |
3 | | * Copyright 2022, Yvan Genuer (@iggy38), Devoteam |
4 | | * Copyright 2022, Martin Gallo <martin.gallo [AT] gmail.com> |
5 | | * Code contributed by SecureAuth Corp. |
6 | | * |
7 | | * Wireshark - Network traffic analyzer |
8 | | * By Gerald Combs <gerald@wireshark.org> |
9 | | * Copyright 1998 Gerald Combs |
10 | | * |
11 | | * SPDX-License-Identifier: GPL-2.0-or-later |
12 | | */ |
13 | | |
14 | | /* |
15 | | * This is a simple dissector for the IGS protocol, initially added by Yvan Genuer as part of their research around the protocol: |
16 | | * https://www.troopers.de/troopers18/agenda/3r38lr/. Some details and example requests can be found in pysap's documentation: |
17 | | * https://pysap.readthedocs.io/en/latest/protocols/SAPIGS.html |
18 | | */ |
19 | | |
20 | | #include <config.h> |
21 | | #include <inttypes.h> |
22 | | #include <stdlib.h> |
23 | | |
24 | | #include <epan/packet.h> |
25 | | #include <epan/prefs.h> |
26 | | #include <epan/expert.h> |
27 | | #include <wsutil/strtoi.h> |
28 | | #include <wsutil/wmem/wmem.h> |
29 | | |
30 | | /* |
31 | | * Define default ports. The right range should be 4NNNN, but as port numbers are proprietary and not |
32 | | * IANA assigned, we leave only the ones corresponding to the instance 00. |
33 | | */ |
34 | 14 | #define SAPIGS_PORT_RANGE "40000" |
35 | | |
36 | | /* IGS Functions values */ |
37 | | static const value_string sapigs_function_lst[] = { |
38 | | { 1, "ADM:REGPW"}, /* Register a PortWatcher */ |
39 | | { 2, "ADM:UNREGPW"}, /* Unregister a PortWatcher */ |
40 | | { 3, "ADM:REGIP"}, /* Register an Interpreter */ |
41 | | { 4, "ADM:UNREGIP"}, /* Unregister an Interpreter */ |
42 | | { 5, "ADM:FREEIP"}, /* Inform than Interpreter is free */ |
43 | | { 6, "ADM:ILLBEBACK"}, /* Call back function */ |
44 | | { 7, "ADM:ABORT"}, /* Abort Interpreter work */ |
45 | | { 8, "ADM:PING"}, /* Ping receive */ |
46 | | { 9, "ADM:PONG"}, /* Ping send */ |
47 | | { 10, "ADM:SHUTDOWNIGS"}, /* Shutdown IGS */ |
48 | | { 11, "ADM:SHUTDOWNPW"}, /* Shutdown PortWatcher */ |
49 | | { 12, "ADM:CHECKCONSUMER"}, /* Check Portwatcher status */ |
50 | | { 13, "ADM:FREECONSUMER"}, /* Inform than portwather is free */ |
51 | | { 14, "ADM:GETLOGFILE"}, /* Display log file */ |
52 | | { 15, "ADM:GETCONFIGFILE"}, /* Display configfile */ |
53 | | { 16, "ADM:GETDUMP"}, /* Display dump file */ |
54 | | { 17, "ADM:DELETEDUMP"}, /* Delete dump file */ |
55 | | { 18, "ADM:INSTALL"}, /* Upload shapefiles for GIS */ |
56 | | { 19, "ADM:SWITCH"}, /* Switch trace log level */ |
57 | | { 20, "ADM:GETVERSION"}, /* Get IGS Version */ |
58 | | { 21, "ADM:STATUS"}, /* Display IGS Status */ |
59 | | { 22, "ADM:STATISTIC"}, /* old Display IGS Statistic */ |
60 | | { 23, "ADM:STATISTICNEW"}, /* Display IGS Statistic */ |
61 | | { 24, "ADM:GETSTATCHART"}, /* Get IGS Statistic chart */ |
62 | | { 25, "ADM:SIM"}, /* Simulation function */ |
63 | | { 30, "ZIPPER"}, /* ZIP provide file(s) */ |
64 | | { 31, "IMGCONV"}, /* Image converter */ |
65 | | { 32, "RSPOCONNECTOR"}, /* Remote Spool Connector */ |
66 | | { 33, "XMLCHART"}, /* Chart generator through xml input */ |
67 | | { 34, "CHART"}, /* Chart generator through ABAP Table input */ |
68 | | { 35, "BWGIS"}, /* BW Geographic Information System */ |
69 | | { 36, "SAPGISXML"}, /* old SAP GIS through xml input */ |
70 | | /* NULL */ |
71 | | { 0, NULL} |
72 | | }; |
73 | | |
74 | | static int proto_sapigs; |
75 | | |
76 | | /* Headers */ |
77 | | static int hf_sapigs_function; |
78 | | static int hf_sapigs_listener; |
79 | | static int hf_sapigs_hostname; |
80 | | static int hf_sapigs_id; |
81 | | static int hf_sapigs_padd1; |
82 | | static int hf_sapigs_flag1; |
83 | | static int hf_sapigs_padd2; |
84 | | static int hf_sapigs_flag2; |
85 | | static int hf_sapigs_padd3; |
86 | | |
87 | | /* Data */ |
88 | | static int hf_sapigs_eye_catcher; |
89 | | static int hf_sapigs_padd4; |
90 | | static int hf_sapigs_codepage; |
91 | | static int hf_sapigs_offset_data; |
92 | | static int hf_sapigs_data_size; |
93 | | static int hf_sapigs_data; |
94 | | |
95 | | /* Table definition */ |
96 | | static int hf_sapigs_tables; |
97 | | static int hf_sapigs_table_version; |
98 | | static int hf_sapigs_table_name; |
99 | | static int hf_sapigs_table_line_number; |
100 | | static int hf_sapigs_table_width; |
101 | | static int hf_sapigs_table_column_name; |
102 | | static int hf_sapigs_table_column_number; |
103 | | static int hf_sapigs_table_column_width; |
104 | | |
105 | | /* Others */ |
106 | | static int hf_sapigs_portwatcher; |
107 | | static int hf_sapigs_portwatcher_version; |
108 | | static int hf_sapigs_portwatcher_info; |
109 | | static int hf_sapigs_interpreter; |
110 | | static int hf_sapigs_chart_config; |
111 | | |
112 | | static int ett_sapigs; |
113 | | |
114 | | /* Global port preference */ |
115 | | static range_t *global_sapigs_port_range; |
116 | | |
117 | | /* Global highlight preference */ |
118 | | static bool global_sapigs_highlight_items = true; |
119 | | |
120 | | /* Protocol handle */ |
121 | | static dissector_handle_t sapigs_handle; |
122 | | |
123 | | void proto_reg_handoff_sapigs(void); |
124 | | void proto_register_sapigs(void); |
125 | | |
126 | | |
127 | | static int |
128 | | dissect_sapigs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
129 | 1 | { |
130 | 1 | uint32_t offset = 0, err_val = 0; |
131 | 1 | const char *data_length_str; |
132 | 1 | unsigned data_offset = 0, data_length = 0; |
133 | 1 | char *sapigs_info_function = NULL, *illbeback_type = NULL, *is_table = NULL; |
134 | 1 | proto_item *ti = NULL, *sapigs_tables = NULL; |
135 | 1 | proto_tree *sapigs_tree = NULL, *sapigs_tables_tree = NULL; |
136 | | |
137 | | /* Add the protocol to the column */ |
138 | 1 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "SAPIGS"); |
139 | | /* Add function name in the info column */ |
140 | 1 | col_add_fstr(pinfo->cinfo, COL_INFO, " function: %s", tvb_get_string_enc(pinfo->pool, tvb, 0, 32, ENC_ASCII)); |
141 | | |
142 | | /* Add the main sapigs subtree */ |
143 | 1 | ti = proto_tree_add_item(tree, proto_sapigs, tvb, 0, -1, ENC_NA); |
144 | 1 | sapigs_tree = proto_item_add_subtree(ti, ett_sapigs); |
145 | | |
146 | | /* Retrieve function name */ |
147 | 1 | sapigs_info_function = (char *)tvb_get_string_enc(pinfo->pool, tvb, offset, 32, ENC_ASCII); |
148 | | |
149 | | /* Headers */ |
150 | 1 | proto_tree_add_item(sapigs_tree, hf_sapigs_function, tvb, offset, 32, ENC_ASCII); |
151 | 1 | offset += 32; |
152 | 1 | proto_tree_add_item(sapigs_tree, hf_sapigs_listener, tvb, offset, 32, ENC_ASCII); |
153 | 1 | offset += 32; |
154 | 1 | proto_tree_add_item(sapigs_tree, hf_sapigs_hostname, tvb, offset, 81, ENC_ASCII); |
155 | 1 | offset += 81; |
156 | 1 | proto_tree_add_item(sapigs_tree, hf_sapigs_id, tvb, offset, 4, ENC_ASCII); |
157 | 1 | offset += 4; |
158 | 1 | proto_tree_add_item(sapigs_tree, hf_sapigs_padd1, tvb, offset, 15, ENC_ASCII); |
159 | 1 | offset += 15; |
160 | 1 | proto_tree_add_item(sapigs_tree, hf_sapigs_flag1, tvb, offset, 1, ENC_ASCII); |
161 | 1 | offset += 1; |
162 | 1 | proto_tree_add_item(sapigs_tree, hf_sapigs_padd2, tvb, offset, 20, ENC_ASCII); |
163 | 1 | offset += 20; |
164 | 1 | proto_tree_add_item(sapigs_tree, hf_sapigs_flag2, tvb, offset, 1, ENC_ASCII); |
165 | 1 | offset += 1; |
166 | 1 | proto_tree_add_item(sapigs_tree, hf_sapigs_padd3, tvb, offset, 6, ENC_ASCII); |
167 | 1 | offset += 6; |
168 | | |
169 | | /* switch over function name value */ |
170 | 1 | switch (str_to_val(sapigs_info_function, sapigs_function_lst, err_val)){ |
171 | 0 | case 8:{ /* ADM:PING */ |
172 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_portwatcher, tvb, offset, 5, ENC_ASCII); |
173 | 0 | break; |
174 | 0 | } |
175 | 0 | case 9:{ /* ADM:PONG */ |
176 | 0 | break; |
177 | 0 | } |
178 | 0 | case 1:{ /* ADM:REGPW */ |
179 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_portwatcher, tvb, offset, 5, ENC_ASCII); |
180 | 0 | offset += 32; |
181 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_portwatcher_version, tvb, offset, 16, ENC_ASCII); |
182 | 0 | break; |
183 | 0 | } |
184 | 0 | case 3: /* ADM:REGIP */ |
185 | 0 | case 5:{ /* ADM:FREEIP */ |
186 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_portwatcher, tvb, offset, 5, ENC_ASCII); |
187 | 0 | offset += 32; |
188 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_interpreter, tvb, offset, 16, ENC_ASCII); |
189 | 0 | offset += 32; |
190 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_portwatcher_version, tvb, offset, 16, ENC_ASCII); |
191 | 0 | offset += 32; |
192 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_portwatcher_info, tvb, offset, 16, ENC_ASCII); |
193 | 0 | break; |
194 | 0 | } |
195 | 0 | case 6:{ /* ADM:ILLBEBACK */ |
196 | 0 | illbeback_type = (char *)tvb_get_string_enc(pinfo->pool, tvb, offset, 10, ENC_ASCII|ENC_NA); |
197 | 0 | if (strncmp("TransMagic", illbeback_type, 10) == 0){ |
198 | | /* data is raw after eye_catcher */ |
199 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_eye_catcher, tvb, offset, 10, ENC_ASCII); |
200 | 0 | offset += 16; |
201 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_data, tvb, offset, -1, ENC_NA); |
202 | 0 | } else { |
203 | | /* we receive sized data */ |
204 | 0 | proto_tree_add_item_ret_string(sapigs_tree, hf_sapigs_data_size, tvb, offset, 5, ENC_ASCII, pinfo->pool, (const uint8_t**)&data_length_str); |
205 | 0 | ws_strtou((char *)data_length_str, NULL, &data_length); |
206 | 0 | offset += 5; |
207 | | /* Data */ |
208 | 0 | if ((data_length > 0) && (tvb_reported_length_remaining(tvb, offset) >= data_length)) { |
209 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_data, tvb, offset, data_length, ENC_NA); |
210 | 0 | } |
211 | 0 | } |
212 | 0 | break; |
213 | 0 | } |
214 | 0 | case 30: /* ZIPPER */ |
215 | 0 | case 31: /* IMGCONV */ |
216 | 0 | case 33: /* XMLCHART */ |
217 | 0 | case 16:{ /* ADM:GETDUMP */ |
218 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_eye_catcher, tvb, offset, 10, ENC_ASCII); |
219 | 0 | offset += 10; |
220 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_padd4, tvb, offset, 2, ENC_ASCII); |
221 | 0 | offset += 2; |
222 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_codepage, tvb, offset, 4, ENC_ASCII); |
223 | 0 | offset += 4; |
224 | | /* Data offset */ |
225 | 0 | proto_tree_add_item_ret_string(sapigs_tree, hf_sapigs_offset_data, tvb, offset, 16, ENC_ASCII, pinfo->pool, (const uint8_t**)&data_length_str); |
226 | 0 | ws_strtou(data_length_str, NULL, &data_offset); |
227 | 0 | offset += 16; |
228 | | /* Data length */ |
229 | 0 | proto_tree_add_item_ret_string(sapigs_tree, hf_sapigs_data_size, tvb, offset, 5, ENC_ASCII, pinfo->pool, (const uint8_t**)&data_length_str); |
230 | 0 | ws_strtou((char *)data_length_str, NULL, &data_length); |
231 | 0 | offset += 16; |
232 | 0 | data_offset += offset; |
233 | | /* Definition tables */ |
234 | 0 | is_table = (char *)tvb_get_string_enc(pinfo->pool, tvb, offset, 4, ENC_ASCII); |
235 | | /* if the 4 next char is VERS, we are at the beginning of one definition table */ |
236 | 0 | while(strncmp("VERS", is_table, 4) == 0){ |
237 | | /* Build a tree for Tables */ |
238 | 0 | sapigs_tables = proto_tree_add_item(sapigs_tree, hf_sapigs_tables, tvb, offset, 336, ENC_NA); |
239 | 0 | sapigs_tables_tree = proto_item_add_subtree(sapigs_tables, ett_sapigs); |
240 | 0 | proto_tree_add_item(sapigs_tables_tree, hf_sapigs_table_version, tvb, offset+8, 40, ENC_ASCII); |
241 | 0 | offset += 48; |
242 | 0 | proto_tree_add_item(sapigs_tables_tree, hf_sapigs_table_name, tvb, offset+8, 40, ENC_ASCII); |
243 | 0 | offset += 48; |
244 | 0 | proto_tree_add_item(sapigs_tables_tree, hf_sapigs_table_line_number, tvb, offset+8, 40, ENC_ASCII); |
245 | 0 | offset += 48; |
246 | 0 | proto_tree_add_item(sapigs_tables_tree, hf_sapigs_table_width, tvb, offset+8, 40, ENC_ASCII); |
247 | 0 | offset += 48; |
248 | 0 | proto_tree_add_item(sapigs_tables_tree, hf_sapigs_table_column_name, tvb, offset+8, 40, ENC_ASCII); |
249 | 0 | offset += 48; |
250 | 0 | proto_tree_add_item(sapigs_tables_tree, hf_sapigs_table_column_number, tvb, offset+8, 40, ENC_ASCII); |
251 | 0 | offset += 48; |
252 | 0 | proto_tree_add_item(sapigs_tables_tree, hf_sapigs_table_column_width, tvb, offset+8, 40, ENC_ASCII); |
253 | 0 | offset += 48; |
254 | 0 | is_table = (char *)tvb_get_string_enc(pinfo->pool, tvb, offset, 4, ENC_ASCII); |
255 | 0 | } |
256 | | /* Data */ |
257 | 0 | if ((data_length > 0) && (tvb_reported_length_remaining(tvb, offset) >= data_length)) { |
258 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_data, tvb, data_offset, data_length, ENC_NA); |
259 | 0 | } |
260 | 0 | break; |
261 | 0 | } |
262 | 0 | case 34:{ /* CHART */ |
263 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_chart_config, tvb, offset, 32, ENC_ASCII); |
264 | 0 | offset += 32; |
265 | 0 | proto_tree_add_item(sapigs_tree, hf_sapigs_data, tvb, offset, -1, ENC_NA); |
266 | 0 | break; |
267 | 0 | } |
268 | 1 | } |
269 | | |
270 | 1 | return tvb_reported_length(tvb); |
271 | 1 | } |
272 | | |
273 | | |
274 | | void |
275 | | proto_register_sapigs(void) |
276 | 14 | { |
277 | 14 | static hf_register_info hf[] = { |
278 | | /* General Header fields */ |
279 | 14 | { &hf_sapigs_function, |
280 | 14 | { "Function", "sapigs.function", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
281 | 14 | { &hf_sapigs_listener, |
282 | 14 | { "Listener", "sapigs.listener", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
283 | 14 | { &hf_sapigs_hostname, |
284 | 14 | { "Hostname", "sapigs.hostname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
285 | 14 | { &hf_sapigs_id, |
286 | 14 | { "Id", "sapigs.id", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
287 | 14 | { &hf_sapigs_padd1, |
288 | 14 | { "Padd1", "sapigs.padd1", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
289 | 14 | { &hf_sapigs_flag1, |
290 | 14 | { "Flag1", "sapigs.flag1", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
291 | 14 | { &hf_sapigs_padd2, |
292 | 14 | { "Padd2", "sapigs.padd2", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
293 | 14 | { &hf_sapigs_flag2, |
294 | 14 | { "Flag2", "sapigs.flag2", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
295 | 14 | { &hf_sapigs_padd3, |
296 | 14 | { "Padd3", "sapigs.padd3", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
297 | | |
298 | | /* Data headers */ |
299 | 14 | { &hf_sapigs_eye_catcher, |
300 | 14 | { "Eye catcher", "sapigs.eye_catcher", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
301 | 14 | { &hf_sapigs_padd4, |
302 | 14 | { "Padd4", "sapigs.padd4", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
303 | 14 | { &hf_sapigs_codepage, |
304 | 14 | { "Codepage", "sapigs.codepage", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
305 | 14 | { &hf_sapigs_offset_data, |
306 | 14 | { "Offset to data", "sapigs.offset_data", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
307 | 14 | { &hf_sapigs_data_size, |
308 | 14 | { "Data size", "sapigs.data_size", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
309 | | |
310 | | /* Portwatcher fields */ |
311 | 14 | { &hf_sapigs_portwatcher, |
312 | 14 | { "Portwatcher Port", "sapigs.portwatcher", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
313 | 14 | { &hf_sapigs_portwatcher_version, |
314 | 14 | { "Portwatcher version", "sapigs.portwatcher_version", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
315 | 14 | { &hf_sapigs_portwatcher_info, |
316 | 14 | { "Portwatcher Info", "sapigs.portwatcher_info", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
317 | | |
318 | | /* Interpreter information */ |
319 | 14 | { &hf_sapigs_interpreter, |
320 | 14 | { "Interpreter name", "sapigs.interpreter", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
321 | 14 | { &hf_sapigs_chart_config, |
322 | 14 | { "Chart configuration", "sapigs.chart_config", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
323 | | |
324 | | /* Table definition fields */ |
325 | 14 | { &hf_sapigs_tables, |
326 | 14 | { "Table definition", "sapigs.tables", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
327 | 14 | { &hf_sapigs_table_version, |
328 | 14 | { "VERS", "sapigs.table_version", FT_STRING, BASE_NONE, NULL, 0x0, "Table version", HFILL }}, |
329 | 14 | { &hf_sapigs_table_name, |
330 | 14 | { "TBNM", "sapigs.table_name", FT_STRING, BASE_NONE, NULL, 0x0, "Table name", HFILL }}, |
331 | 14 | { &hf_sapigs_table_line_number, |
332 | 14 | { "TBLN", "sapigs.table_line_number", FT_STRING, BASE_NONE, NULL, 0x0, "Line count", HFILL }}, |
333 | 14 | { &hf_sapigs_table_width, |
334 | 14 | { "TBWD", "sapigs.table_width", FT_STRING, BASE_NONE, NULL, 0x0, "Table width", HFILL }}, |
335 | 14 | { &hf_sapigs_table_column_name, |
336 | 14 | { "TBCL", "sapigs.table_column_name", FT_STRING, BASE_NONE, NULL, 0x0, "Table column name", HFILL }}, |
337 | 14 | { &hf_sapigs_table_column_number, |
338 | 14 | { "CLNM", "sapigs.table_column_number", FT_STRING, BASE_NONE, NULL, 0x0, "Column count", HFILL }}, |
339 | 14 | { &hf_sapigs_table_column_width, |
340 | 14 | { "CLWD", "sapigs.table_column_width", FT_STRING, BASE_NONE, NULL, 0x0, "Column width", HFILL }}, |
341 | | |
342 | | /* Data */ |
343 | 14 | { &hf_sapigs_data, |
344 | 14 | { "Data", "sapigs.table_data", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }} |
345 | 14 | }; |
346 | | |
347 | | /* Setup protocol subtre array */ |
348 | 14 | static int *ett[] = { |
349 | 14 | &ett_sapigs |
350 | 14 | }; |
351 | | |
352 | 14 | module_t *sapigs_module; |
353 | | |
354 | | /* Register the protocol */ |
355 | 14 | proto_sapigs = proto_register_protocol("SAP Internet Graphic Server", "SAPIGS", "sapigs"); |
356 | | |
357 | 14 | register_dissector("sapigs", dissect_sapigs, proto_sapigs); |
358 | | |
359 | 14 | proto_register_field_array(proto_sapigs, hf, array_length(hf)); |
360 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
361 | | |
362 | | /* Register the preferences */ |
363 | 14 | sapigs_module = prefs_register_protocol(proto_sapigs, proto_reg_handoff_sapigs); |
364 | | |
365 | 14 | range_convert_str(wmem_epan_scope(), &global_sapigs_port_range, SAPIGS_PORT_RANGE, MAX_TCP_PORT); |
366 | 14 | prefs_register_range_preference(sapigs_module, "tcp_ports", "SAP IGS Protocol TCP port numbers", "Port numbers used for SAP IGS Protocol (default "SAPIGS_PORT_RANGE ")", &global_sapigs_port_range, MAX_TCP_PORT); |
367 | | |
368 | 14 | prefs_register_bool_preference(sapigs_module, "highlight_unknow_items", "Highlight unknown SAP IGS messages", "Whether the SAP IGS Protocol dissector should highlight unknown IGS messages", &global_sapigs_highlight_items); |
369 | | |
370 | 14 | } |
371 | | |
372 | | /** |
373 | | * Helpers for dealing with the port range |
374 | | */ |
375 | | static void range_delete_callback (uint32_t port, void *ptr _U_) |
376 | 0 | { |
377 | 0 | dissector_delete_uint("sapni.port", port, sapigs_handle); |
378 | 0 | } |
379 | | |
380 | | static void range_add_callback (uint32_t port, void *ptr _U_) |
381 | 14 | { |
382 | 14 | dissector_add_uint("sapni.port", port, sapigs_handle); |
383 | 14 | } |
384 | | |
385 | | /** |
386 | | * Register Hand off for the SAP IGS Protocol |
387 | | */ |
388 | | void |
389 | | proto_reg_handoff_sapigs(void) |
390 | 14 | { |
391 | 14 | static range_t *sapigs_port_range; |
392 | 14 | static bool initialized = false; |
393 | | |
394 | 14 | if (!initialized) { |
395 | 14 | sapigs_handle = create_dissector_handle(dissect_sapigs, proto_sapigs); |
396 | 14 | initialized = true; |
397 | 14 | } else { |
398 | 0 | range_foreach(sapigs_port_range, range_delete_callback, NULL); |
399 | 0 | wmem_free(wmem_epan_scope(), sapigs_port_range); |
400 | 0 | } |
401 | | |
402 | 14 | sapigs_port_range = range_copy(wmem_epan_scope(), global_sapigs_port_range); |
403 | | range_foreach(sapigs_port_range, range_add_callback, NULL); |
404 | 14 | } |
405 | | |
406 | | /* |
407 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
408 | | * |
409 | | * Local variables: |
410 | | * c-basic-offset: 8 |
411 | | * tab-width: 8 |
412 | | * indent-tabs-mode: t |
413 | | * End: |
414 | | * |
415 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
416 | | * :indentSize=8:tabSize=8:noTabs=false: |
417 | | */ |