Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ipdr.c
blob2055f6284e92c738fbc337be411daf69504cbaf7
1 /* packet-ipdr.c
3 * Routines for IP Detail Record (IPDR) dissection.
5 * Original dissection based off of a Lua script found at
6 * https://bitbucket.org/abn/ipdr-dissector/overview
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include "config.h"
17 #include <epan/packet.h>
18 #include <epan/expert.h>
19 #include <epan/range.h>
20 #include <epan/prefs.h>
21 #include "packet-tcp.h"
23 void proto_register_ipdr(void);
24 void proto_reg_handoff_ipdr(void);
26 static int proto_ipdr;
27 static int proto_ipdr_samis_type_1;
29 static dissector_handle_t ipdr_handle;
30 static dissector_handle_t ipdr_samis_type_1_handle;
32 static dissector_table_t ipdr_sessions_dissector_table;
34 static int hf_ipdr_version;
35 static int hf_ipdr_message_id;
36 static int hf_ipdr_session_id;
37 static int hf_ipdr_message_flags;
38 static int hf_ipdr_message_len;
39 static int hf_ipdr_initiator_id;
40 static int hf_ipdr_initiator_port;
41 static int hf_ipdr_capabilities;
42 static int hf_ipdr_keepalive_interval;
43 static int hf_ipdr_vendor_id;
44 static int hf_ipdr_timestamp;
45 static int hf_ipdr_error_code;
46 static int hf_ipdr_description;
47 static int hf_ipdr_exporter_boot_time;
48 static int hf_ipdr_first_record_sequence_number;
49 static int hf_ipdr_dropped_record_count;
50 static int hf_ipdr_reason_code;
51 static int hf_ipdr_reason_info;
52 static int hf_ipdr_request_id;
53 static int hf_ipdr_config_id;
54 static int hf_ipdr_flags;
55 static int hf_ipdr_primary;
56 static int hf_ipdr_ack_time_interval;
57 static int hf_ipdr_ack_sequence_interval;
58 static int hf_ipdr_template_id;
59 static int hf_ipdr_document_id;
60 static int hf_ipdr_sequence_num;
61 static int hf_ipdr_request_number;
62 static int hf_ipdr_data_record;
64 /* Header fields for SAMIS-TYPE-1 IPDR DATA Records */
65 static int hf_ipdr_samis_record_length;
66 static int hf_ipdr_cmts_host_name_len;
67 static int hf_ipdr_cmts_host_name;
68 static int hf_ipdr_cmts_sys_up_time;
69 static int hf_ipdr_cmts_ipv4_addr;
70 static int hf_ipdr_cmts_ipv6_addr_len;
71 static int hf_ipdr_cmts_ipv6_addr;
72 static int hf_ipdr_cmts_md_if_name_len;
73 static int hf_ipdr_cmts_md_if_name;
74 static int hf_ipdr_cmts_md_if_index;
75 static int hf_ipdr_cm_mac_addr;
76 static int hf_ipdr_cm_ipv4_addr;
77 static int hf_ipdr_cm_ipv6_addr;
78 static int hf_ipdr_cm_ipv6_addr_string_len;
79 static int hf_ipdr_cm_ipv6_addr_string;
80 static int hf_ipdr_cm_ipv6_ll_addr;
81 static int hf_ipdr_cm_ipv6_ll_addr_string_len;
82 static int hf_ipdr_cm_ipv6_ll_addr_string;
83 static int hf_ipdr_cm_qos_version;
84 static int hf_ipdr_cm_reg_status;
85 static int hf_ipdr_cm_last_reg_time;
86 static int hf_ipdr_rec_type;
87 static int hf_ipdr_rec_creation_time;
88 static int hf_ipdr_sf_ch_set;
89 static int hf_ipdr_channel_id;
90 static int hf_ipdr_service_app_id;
91 static int hf_ipdr_service_ds_multicast;
92 static int hf_ipdr_service_identifier;
93 static int hf_ipdr_service_gate_id;
94 static int hf_ipdr_service_class_name_len;
95 static int hf_ipdr_service_class_name;
96 static int hf_ipdr_service_direction;
97 static int hf_ipdr_service_octets_passed;
98 static int hf_ipdr_service_pkts_passed;
99 static int hf_ipdr_service_sla_drop_pkts;
100 static int hf_ipdr_service_sla_delay_pkts;
101 static int hf_ipdr_service_time_created;
102 static int hf_ipdr_service_time_active;
104 static int ett_ipdr;
105 static int ett_ipdr_samis_type_1;
106 static int ett_ipdr_sf_ch_set;
108 static expert_field ei_ipdr_message_id;
109 static expert_field ei_ipdr_sf_ch_set;
111 static range_t *global_sessions_samis_type_1;
113 #define IPDR_PORT 4737
114 #define IPDR_HEADER_LEN 8
116 enum
118 IPDR_FLOW_START = 0x01,
119 IPDR_FLOW_STOP = 0x03,
120 IPDR_CONNECT = 0x05,
121 IPDR_CONNECT_RESPONSE = 0x06,
122 IPDR_DISCONNECT = 0x07,
123 IPDR_SESSION_START = 0x08,
124 IPDR_SESSION_STOP = 0x09,
125 IPDR_TEMPLATE_DATA = 0x10,
126 IPDR_FINAL_TEMPLATE_DATA_ACK = 0x13,
127 IPDR_GET_SESSIONS = 0x14,
128 IPDR_GET_SESSIONS_RESPONSE = 0x15,
129 IPDR_GET_TEMPLATES = 0x16,
130 IPDR_GET_TEMPLATES_RESPONSE = 0x17,
131 IPDR_MODIFY_TEMPLATE = 0x1A,
132 IPDR_MODIFY_TEMPLATE_RESPONSE = 0x1B,
133 IPDR_START_NEGOTIATION = 0x1D,
134 IPDR_START_NEGOTIATION_REJECT = 0x1E,
135 IPDR_DATA = 0x20,
136 IPDR_DATA_ACK = 0x21,
137 IPDR_ERROR = 0x23,
138 IPDR_REQUEST = 0x30,
139 IPDR_RESPONSE = 0x31,
140 IPDR_KEEP_ALIVE = 0x40
143 static const value_string ipdr_message_type_vals[] = {
144 { IPDR_FLOW_START, "FLOW_START" },
145 { IPDR_FLOW_STOP, "FLOW_STOP" },
146 { IPDR_CONNECT, "CONNECT" },
147 { IPDR_CONNECT_RESPONSE, "CONNECT_RESPONSE" },
148 { IPDR_DISCONNECT, "DISCONNECT" },
149 { IPDR_SESSION_START, "SESSION_START" },
150 { IPDR_SESSION_STOP, "SESSION_STOP" },
151 { IPDR_TEMPLATE_DATA, "TEMPLATE_DATA" },
152 { IPDR_FINAL_TEMPLATE_DATA_ACK, "FINAL_TEMPLATE_DATA_ACK" },
153 { IPDR_GET_SESSIONS, "GET_SESSIONS" },
154 { IPDR_GET_SESSIONS_RESPONSE, "GET_SESSIONS_RESPONSE" },
155 { IPDR_GET_TEMPLATES, "GET_TEMPLATES" },
156 { IPDR_GET_TEMPLATES_RESPONSE, "GET_TEMPLATES_RESPONSE" },
157 { IPDR_MODIFY_TEMPLATE, "MODIFY_TEMPLATE" },
158 { IPDR_MODIFY_TEMPLATE_RESPONSE,"MODIFY_TEMPLATE_RESPONSE" },
159 { IPDR_START_NEGOTIATION, "START_NEGOTIATION" },
160 { IPDR_START_NEGOTIATION_REJECT,"START_NEGOTIATION_REJECT" },
161 { IPDR_DATA, "DATA" },
162 { IPDR_DATA_ACK, "DATA_ACK" },
163 { IPDR_ERROR, "ERROR" },
164 { IPDR_REQUEST, "REQUEST" },
165 { IPDR_RESPONSE, "RESPONSE" },
166 { IPDR_KEEP_ALIVE, "KEEP_ALIVE" },
167 { 0, NULL }
170 static const value_string ipdr_cm_qos_type_vals[] = {
171 { 1, "DOCSIS 1.0 QoS mode" },
172 { 2, "DOCSIS 1.1 QoS mode" },
173 { 0, NULL }
176 static const value_string ipdr_cm_reg_status_vals[] = {
177 { 1, "Other" },
178 { 2, "Initial Ranging" },
179 { 4, "Ranging Auto Adj Complete" },
180 { 5, "DHCPv4 Complete" },
181 { 6, "Registration Complete" },
182 { 8, "Operational" },
183 { 9, "BPI Init" },
184 { 10, "Start EAE" },
185 { 11, "Start DHCPv4" },
186 { 12, "Start DHCPv6" },
187 { 13, "DHCPv6 Complete" },
188 { 14, "Start Configuration File Download" },
189 { 15, "Configuration File Download Complete" },
190 { 16, "Start Registration" },
191 { 17, "Forwarding Disabled" },
192 { 18, "RF Mute All" },
193 { 0, NULL }
196 static const value_string ipdr_record_type_vals[] = {
197 { 1, "Interim" },
198 { 2, "Stop" },
199 { 3, "Start" },
200 { 4, "Event" },
201 { 0, NULL }
204 static const value_string ipdr_service_direction_vals[] = {
205 { 1, "Downstream" },
206 { 2, "Upstream" },
207 { 0, NULL }
210 static int
211 dissect_ipdr_samis_type_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
213 int offset = 0;
214 proto_item *ti;
215 proto_tree *samis_type_1_tree, *sf_ch_set_tree;
216 unsigned len, cmts_sys_up_time, channel_id;
218 //col_clear(pinfo->cinfo, COL_INFO);
219 ti = proto_tree_add_item(tree, proto_ipdr_samis_type_1, tvb, 0, -1, ENC_NA);
220 samis_type_1_tree = proto_item_add_subtree(ti, ett_ipdr_samis_type_1);
221 col_set_str(pinfo->cinfo, COL_INFO, "SAMIS-TYPE-1");
223 proto_tree_add_item(samis_type_1_tree, hf_ipdr_samis_record_length, tvb, offset, 4, ENC_BIG_ENDIAN);
224 offset += 4;
226 ti = proto_tree_add_item_ret_uint(samis_type_1_tree, hf_ipdr_cmts_host_name_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
227 proto_item_append_text(ti, " bytes");
228 offset += 4;
229 if (len > 0) {
230 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cmts_host_name, tvb, offset, len, ENC_ASCII);
231 offset += len;
234 ti = proto_tree_add_item_ret_uint(samis_type_1_tree, hf_ipdr_cmts_sys_up_time,
235 tvb, offset, 4, ENC_BIG_ENDIAN, &cmts_sys_up_time);
236 proto_item_append_text(ti, " (%d seconds)", cmts_sys_up_time / 100);
237 offset += 4;
239 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cmts_ipv4_addr, tvb, offset, 4, ENC_NA);
240 offset += 4;
242 ti = proto_tree_add_item_ret_uint(samis_type_1_tree, hf_ipdr_cmts_ipv6_addr_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
243 proto_item_append_text(ti, " bytes");
244 offset += 4;
245 if (len > 0) {
246 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cmts_ipv6_addr, tvb, offset, len, ENC_NA);
247 offset += len;
249 ti = proto_tree_add_item_ret_uint(samis_type_1_tree, hf_ipdr_cmts_md_if_name_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
250 proto_item_append_text(ti, " bytes");
251 offset += 4;
252 if (len > 0) {
253 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cmts_md_if_name, tvb, offset, len, ENC_ASCII);
254 offset += len;
257 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cmts_md_if_index, tvb, offset, 4, ENC_BIG_ENDIAN);
258 offset += 6; /* Add another 2 bytes for compatibility with XDR MAC address encoding format */
260 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cm_mac_addr, tvb, offset, 6, ENC_NA);
261 offset += 6;
263 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cm_ipv4_addr, tvb, offset, 4, ENC_NA);
264 offset += 4;
266 ti = proto_tree_add_item_ret_uint(samis_type_1_tree, hf_ipdr_cm_ipv6_addr_string_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
267 proto_item_append_text(ti, " bytes");
268 offset += 4;
269 if (len == 16) {
270 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cm_ipv6_addr, tvb, offset, len, ENC_ASCII|ENC_BIG_ENDIAN);
271 } else if (len > 0) {
272 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cm_ipv6_addr_string, tvb, offset, len, ENC_ASCII);
274 offset += len;
276 ti = proto_tree_add_item_ret_uint(samis_type_1_tree, hf_ipdr_cm_ipv6_ll_addr_string_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
277 proto_item_append_text(ti, " bytes");
278 offset += 4;
279 if (len == 16) {
280 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cm_ipv6_ll_addr, tvb, offset, len, ENC_ASCII|ENC_BIG_ENDIAN);
281 } else if (len > 0) {
282 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cm_ipv6_ll_addr_string, tvb, offset, len, ENC_ASCII);
284 offset += len;
286 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cm_qos_version, tvb, offset, 4, ENC_BIG_ENDIAN);
287 offset += 4;
289 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cm_reg_status, tvb, offset, 4, ENC_BIG_ENDIAN);
290 offset += 4;
292 proto_tree_add_item(samis_type_1_tree, hf_ipdr_cm_last_reg_time, tvb, offset, 4, ENC_BIG_ENDIAN);
293 offset += 4;
295 proto_tree_add_item(samis_type_1_tree, hf_ipdr_rec_type, tvb, offset, 4, ENC_BIG_ENDIAN);
296 offset += 4;
298 proto_tree_add_item(samis_type_1_tree, hf_ipdr_rec_creation_time, tvb, offset, 8, ENC_TIME_MSECS);
299 offset += 8;
301 len = tvb_get_ntohl(tvb, offset);
302 ti = proto_tree_add_item(samis_type_1_tree, hf_ipdr_sf_ch_set, tvb, offset, len + 4, ENC_NA);
303 offset += 4;
304 if (len > 0 && len <= 255) {
305 sf_ch_set_tree = proto_item_add_subtree(ti, ett_ipdr_sf_ch_set);
306 proto_item_append_text (ti, ": ");
307 while (len) {
308 proto_tree_add_item_ret_uint(sf_ch_set_tree, hf_ipdr_channel_id, tvb, offset, 1, ENC_BIG_ENDIAN, &channel_id);
309 proto_item_append_text (ti, "%d ", channel_id);
310 offset += 1;
311 len--;
313 } else {
314 expert_add_info(pinfo, ti, &ei_ipdr_sf_ch_set);
315 offset += len;
318 proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_app_id, tvb, offset, 4, ENC_BIG_ENDIAN);
319 offset += 4;
321 proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_ds_multicast, tvb, offset, 1, ENC_NA);
322 offset += 1;
324 proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_identifier, tvb, offset, 4, ENC_NA);
325 offset += 4;
327 proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_gate_id, tvb, offset, 4, ENC_NA);
328 offset += 4;
330 ti = proto_tree_add_item_ret_uint(samis_type_1_tree, hf_ipdr_service_class_name_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
331 proto_item_append_text(ti, " bytes");
332 offset += 4;
333 if (len > 0) {
334 proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_class_name, tvb, offset, len, ENC_ASCII);
335 offset += len;
338 proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_direction, tvb, offset, 4, ENC_NA);
339 offset += 4;
341 proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_octets_passed, tvb, offset, 8, ENC_BIG_ENDIAN);
342 offset += 8;
344 proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_pkts_passed, tvb, offset, 8, ENC_BIG_ENDIAN);
345 offset += 8;
347 ti = proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_sla_drop_pkts, tvb, offset, 4, ENC_BIG_ENDIAN);
348 proto_item_append_text (ti, " (Downstream only)");
349 offset += 4;
351 ti = proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_sla_delay_pkts, tvb, offset, 4, ENC_BIG_ENDIAN);
352 proto_item_append_text (ti, " (Downstream only)");
353 offset += 4;
355 ti = proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_time_created, tvb, offset, 4, ENC_BIG_ENDIAN);
356 proto_item_append_text(ti, " seconds");
357 offset += 4;
359 ti = proto_tree_add_item(samis_type_1_tree, hf_ipdr_service_time_active, tvb, offset, 4, ENC_BIG_ENDIAN);
360 proto_item_append_text(ti, " seconds");
361 offset += 4;
363 return offset;
366 static int
367 dissect_ipdr_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
369 proto_item *ti, *type_item;
370 proto_tree *ipdr_tree;
371 int offset = 0;
372 uint32_t session_id, message_len, message_type;
374 ti = proto_tree_add_item(tree, proto_ipdr, tvb, 0, -1, ENC_NA);
375 ipdr_tree = proto_item_add_subtree(ti, ett_ipdr);
377 proto_tree_add_item(ipdr_tree, hf_ipdr_version, tvb, offset, 1, ENC_NA);
378 offset++;
380 type_item = proto_tree_add_item_ret_uint(ipdr_tree, hf_ipdr_message_id, tvb, offset, 1, ENC_NA, &message_type);
381 col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", val_to_str(message_type, ipdr_message_type_vals, "Unknown (0x%02x)"));
382 offset++;
384 proto_tree_add_item_ret_uint(ipdr_tree, hf_ipdr_session_id, tvb, offset, 1, ENC_BIG_ENDIAN, &session_id);
385 offset++;
387 proto_tree_add_item(ipdr_tree, hf_ipdr_message_flags, tvb, offset, 1, ENC_NA);
388 offset++;
390 proto_tree_add_item_ret_uint(ipdr_tree, hf_ipdr_message_len, tvb, offset, 4, ENC_BIG_ENDIAN, &message_len);
391 offset += 4;
393 switch(message_type)
395 case IPDR_FLOW_START:
396 case IPDR_DISCONNECT:
397 case IPDR_FINAL_TEMPLATE_DATA_ACK:
398 case IPDR_START_NEGOTIATION:
399 case IPDR_START_NEGOTIATION_REJECT:
400 case IPDR_KEEP_ALIVE:
401 /* No additional fields */
402 break;
403 case IPDR_FLOW_STOP:
404 proto_tree_add_item(ipdr_tree, hf_ipdr_reason_code, tvb, offset, 2, ENC_BIG_ENDIAN);
405 offset += 2;
406 proto_tree_add_item(ipdr_tree, hf_ipdr_reason_info, tvb, offset, -1, ENC_ASCII);
407 break;
408 case IPDR_CONNECT:
409 proto_tree_add_item(ipdr_tree, hf_ipdr_initiator_id, tvb, offset, 4, ENC_BIG_ENDIAN);
410 offset += 4;
411 proto_tree_add_item(ipdr_tree, hf_ipdr_initiator_port, tvb, offset, 2, ENC_BIG_ENDIAN);
412 offset += 2;
413 proto_tree_add_item(ipdr_tree, hf_ipdr_capabilities, tvb, offset, 4, ENC_BIG_ENDIAN);
414 offset += 4;
415 proto_tree_add_item(ipdr_tree, hf_ipdr_keepalive_interval, tvb, offset, 4, ENC_BIG_ENDIAN);
416 offset += 4;
417 proto_tree_add_item(ipdr_tree, hf_ipdr_vendor_id, tvb, offset, 4, ENC_ASCII|ENC_BIG_ENDIAN);
418 break;
419 case IPDR_CONNECT_RESPONSE:
420 proto_tree_add_item(ipdr_tree, hf_ipdr_capabilities, tvb, offset, 4, ENC_BIG_ENDIAN);
421 offset += 4;
422 proto_tree_add_item(ipdr_tree, hf_ipdr_keepalive_interval, tvb, offset, 4, ENC_BIG_ENDIAN);
423 offset += 4;
424 proto_tree_add_item(ipdr_tree, hf_ipdr_vendor_id, tvb, offset, 4, ENC_ASCII|ENC_BIG_ENDIAN);
425 break;
426 case IPDR_SESSION_START:
427 proto_tree_add_item(ipdr_tree, hf_ipdr_exporter_boot_time, tvb, offset, 4, ENC_BIG_ENDIAN);
428 offset += 4;
429 proto_tree_add_item(ipdr_tree, hf_ipdr_first_record_sequence_number, tvb, offset, 8, ENC_BIG_ENDIAN);
430 offset += 8;
431 proto_tree_add_item(ipdr_tree, hf_ipdr_dropped_record_count, tvb, offset, 8, ENC_BIG_ENDIAN);
432 offset += 8;
433 proto_tree_add_item(ipdr_tree, hf_ipdr_primary, tvb, offset, 1, ENC_NA);
434 offset++;
435 proto_tree_add_item(ipdr_tree, hf_ipdr_ack_time_interval, tvb, offset, 4, ENC_BIG_ENDIAN);
436 offset += 4;
437 proto_tree_add_item(ipdr_tree, hf_ipdr_ack_sequence_interval, tvb, offset, 4, ENC_BIG_ENDIAN);
438 offset += 4;
439 proto_tree_add_item(ipdr_tree, hf_ipdr_document_id, tvb, offset, 16, ENC_NA);
440 break;
441 case IPDR_SESSION_STOP:
442 proto_tree_add_item(ipdr_tree, hf_ipdr_reason_code, tvb, offset, 2, ENC_BIG_ENDIAN);
443 offset += 2;
444 proto_tree_add_item(ipdr_tree, hf_ipdr_reason_info, tvb, offset, -1, ENC_ASCII);
445 break;
446 case IPDR_TEMPLATE_DATA:
447 proto_tree_add_item(ipdr_tree, hf_ipdr_config_id, tvb, offset, 2, ENC_BIG_ENDIAN);
448 offset += 2;
449 proto_tree_add_item(ipdr_tree, hf_ipdr_flags, tvb, offset, 1, ENC_NA);
450 break;
451 case IPDR_GET_SESSIONS:
452 proto_tree_add_item(ipdr_tree, hf_ipdr_request_id, tvb, offset, 2, ENC_BIG_ENDIAN);
453 break;
454 case IPDR_GET_SESSIONS_RESPONSE:
455 proto_tree_add_item(ipdr_tree, hf_ipdr_request_id, tvb, offset, 2, ENC_BIG_ENDIAN);
456 break;
457 case IPDR_GET_TEMPLATES:
458 proto_tree_add_item(ipdr_tree, hf_ipdr_request_id, tvb, offset, 2, ENC_BIG_ENDIAN);
459 break;
460 case IPDR_GET_TEMPLATES_RESPONSE:
461 proto_tree_add_item(ipdr_tree, hf_ipdr_request_id, tvb, offset, 2, ENC_BIG_ENDIAN);
462 offset += 2;
463 proto_tree_add_item(ipdr_tree, hf_ipdr_config_id, tvb, offset, 2, ENC_BIG_ENDIAN);
464 break;
465 case IPDR_MODIFY_TEMPLATE:
466 proto_tree_add_item(ipdr_tree, hf_ipdr_config_id, tvb, offset, 2, ENC_BIG_ENDIAN);
467 break;
468 case IPDR_MODIFY_TEMPLATE_RESPONSE:
469 proto_tree_add_item(ipdr_tree, hf_ipdr_config_id, tvb, offset, 2, ENC_BIG_ENDIAN);
470 offset += 2;
471 proto_tree_add_item(ipdr_tree, hf_ipdr_flags, tvb, offset, 1, ENC_NA);
472 offset++;
473 break;
474 case IPDR_DATA:
475 proto_tree_add_item(ipdr_tree, hf_ipdr_template_id, tvb, offset, 2, ENC_BIG_ENDIAN);
476 offset += 2;
477 proto_tree_add_item(ipdr_tree, hf_ipdr_config_id, tvb, offset, 2, ENC_BIG_ENDIAN);
478 offset += 2;
479 proto_tree_add_item(ipdr_tree, hf_ipdr_flags, tvb, offset, 1, ENC_NA);
480 offset++;
481 proto_tree_add_item(ipdr_tree, hf_ipdr_sequence_num, tvb, offset, 8, ENC_BIG_ENDIAN);
482 offset += 8;
483 if (!dissector_try_uint(ipdr_sessions_dissector_table, session_id,
484 tvb_new_subset_remaining(tvb, offset), pinfo, ipdr_tree)) {
485 proto_tree_add_item(ipdr_tree, hf_ipdr_data_record, tvb, offset, -1, ENC_NA);
487 break;
488 case IPDR_DATA_ACK:
489 proto_tree_add_item(ipdr_tree, hf_ipdr_config_id, tvb, offset, 2, ENC_BIG_ENDIAN);
490 offset += 2;
491 proto_tree_add_item(ipdr_tree, hf_ipdr_sequence_num, tvb, offset, 8, ENC_BIG_ENDIAN);
492 break;
493 case IPDR_ERROR:
494 proto_tree_add_item(ipdr_tree, hf_ipdr_timestamp, tvb, offset, 4, ENC_BIG_ENDIAN);
495 offset += 4;
496 proto_tree_add_item(ipdr_tree, hf_ipdr_error_code, tvb, offset, 2, ENC_BIG_ENDIAN);
497 offset += 2;
498 proto_tree_add_item(ipdr_tree, hf_ipdr_description, tvb, offset, -1, ENC_ASCII);
499 break;
500 case IPDR_REQUEST:
501 proto_tree_add_item(ipdr_tree, hf_ipdr_template_id, tvb, offset, 2, ENC_BIG_ENDIAN);
502 offset += 2;
503 proto_tree_add_item(ipdr_tree, hf_ipdr_config_id, tvb, offset, 2, ENC_BIG_ENDIAN);
504 offset += 2;
505 proto_tree_add_item(ipdr_tree, hf_ipdr_flags, tvb, offset, 1, ENC_NA);
506 offset++;
507 proto_tree_add_item(ipdr_tree, hf_ipdr_request_number, tvb, offset, 8, ENC_BIG_ENDIAN);
508 offset += 8;
509 proto_tree_add_item(ipdr_tree, hf_ipdr_data_record, tvb, offset, -1, ENC_NA);
510 break;
511 case IPDR_RESPONSE:
512 proto_tree_add_item(ipdr_tree, hf_ipdr_template_id, tvb, offset, 2, ENC_BIG_ENDIAN);
513 offset += 2;
514 proto_tree_add_item(ipdr_tree, hf_ipdr_config_id, tvb, offset, 2, ENC_BIG_ENDIAN);
515 offset += 2;
516 proto_tree_add_item(ipdr_tree, hf_ipdr_flags, tvb, offset, 1, ENC_NA);
517 offset++;
518 proto_tree_add_item(ipdr_tree, hf_ipdr_request_number, tvb, offset, 8, ENC_BIG_ENDIAN);
519 offset += 8;
520 proto_tree_add_item(ipdr_tree, hf_ipdr_data_record, tvb, offset, -1, ENC_NA);
521 break;
522 default:
523 expert_add_info(pinfo, type_item, &ei_ipdr_message_id);
524 break;
527 return tvb_captured_length(tvb);
530 static unsigned
531 get_ipdr_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
533 return (unsigned)tvb_get_ntohl(tvb, offset+4);
536 static int
537 dissect_ipdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
539 if (tvb_reported_length(tvb) < 1)
540 return 0;
542 if (tvb_get_uint8(tvb, 0) != 2) /* Only version 2 supported */
543 return 0;
545 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPDR/SP");
546 col_clear(pinfo->cinfo, COL_INFO);
548 tcp_dissect_pdus(tvb, pinfo, tree, true, IPDR_HEADER_LEN,
549 get_ipdr_message_len, dissect_ipdr_message, data);
550 return tvb_captured_length(tvb);
553 void
554 proto_register_ipdr(void)
556 static hf_register_info hf[] = {
557 { &hf_ipdr_version, { "Version", "ipdr.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
558 { &hf_ipdr_message_id, { "Message id", "ipdr.message_id", FT_UINT8, BASE_DEC, VALS(ipdr_message_type_vals), 0x0, NULL, HFILL } },
559 { &hf_ipdr_session_id, { "Session id", "ipdr.session_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
560 { &hf_ipdr_message_flags, { "Message flags", "ipdr.message_flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
561 { &hf_ipdr_message_len, { "Message length", "ipdr.message_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
562 { &hf_ipdr_initiator_id, { "Initiator id", "ipdr.initiator_id", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } },
563 { &hf_ipdr_initiator_port, { "Initiator port", "ipdr.initiator_port", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
564 { &hf_ipdr_capabilities, { "Capabilities", "ipdr.capabilities", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
565 { &hf_ipdr_keepalive_interval, { "Keep-alive interval", "ipdr.keepalive_interval", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
566 { &hf_ipdr_vendor_id, { "Vendor id", "ipdr.vendor_id", FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
567 { &hf_ipdr_timestamp, { "Timestamp", "ipdr.timestamp", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
568 { &hf_ipdr_error_code, { "Error code", "ipdr.error_code", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
569 { &hf_ipdr_description, { "Description", "ipdr.description", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
570 { &hf_ipdr_exporter_boot_time, { "Exporter boot time", "ipdr.exporter_boot_time", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
571 { &hf_ipdr_first_record_sequence_number, { "First record sequence number", "ipdr.first_record_sequence_number", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
572 { &hf_ipdr_dropped_record_count, { "Dropped record count", "ipdr.dropped_record_count", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
573 { &hf_ipdr_reason_code, { "Reason code", "ipdr.reason_code", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
574 { &hf_ipdr_reason_info, { "Reason info", "ipdr.reason_info", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
575 { &hf_ipdr_request_id, { "Request id", "ipdr.request_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
576 { &hf_ipdr_config_id, { "Config id", "ipdr.config_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
577 { &hf_ipdr_flags, { "Flags", "ipdr.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
578 { &hf_ipdr_primary, { "Primary", "ipdr.primary", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
579 { &hf_ipdr_ack_time_interval, { "ACK time interval", "ipdr.ack_time_interval", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
580 { &hf_ipdr_ack_sequence_interval, { "ACK sequence interval", "ipdr.ack_sequence_interval", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
581 { &hf_ipdr_template_id, { "Template id", "ipdr.template_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
582 { &hf_ipdr_document_id, { "Document id", "ipdr.document_id", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL } },
583 { &hf_ipdr_sequence_num, { "Sequence number", "ipdr.sequence_num", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
584 { &hf_ipdr_request_number, { "Request number", "ipdr.request_number", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
585 { &hf_ipdr_data_record, { "Data record", "ipdr.data_record", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
587 /* Header fields for SAMIS-TYPE-1 IPDR DATA Records */
588 { &hf_ipdr_samis_record_length, { "Record Length", "ipdr.samis_record_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
589 { &hf_ipdr_cmts_host_name_len, { "CMTS FQDN Length", "ipdr.cmts_host_name_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
590 { &hf_ipdr_cmts_host_name, { "CMTS FQDN", "ipdr.cmts_host_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
591 { &hf_ipdr_cmts_sys_up_time, { "CMTS Uptime", "ipdr.cmts_uptime", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
592 { &hf_ipdr_cmts_ipv4_addr, { "CMTS IPv4 Address", "ipdr.cmts_ipv4_addr", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } },
593 { &hf_ipdr_cmts_ipv6_addr_len, { "CMTS IPv6 Address Length", "ipdr.cmts_ipv6_addr_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
594 { &hf_ipdr_cmts_ipv6_addr, { "CMTS IPv6 Address", "ipdr.cmts_ipv6_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } },
595 { &hf_ipdr_cmts_md_if_name_len, { "MD Interface Name Length", "ipdr.cmts_md_if_name_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
596 { &hf_ipdr_cmts_md_if_name, { "MD Interface Name", "ipdr.cmts_md_if_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
597 { &hf_ipdr_cmts_md_if_index, { "MD Interface Index", "ipdr.cmts_md_if_index", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
598 { &hf_ipdr_cm_mac_addr, { "CM MAC", "ipdr.cm_mac_address", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL } },
599 { &hf_ipdr_cm_ipv4_addr, { "CM IPv4 Address", "ipdr.cm_ipv4_addr", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL } },
600 { &hf_ipdr_cm_ipv6_addr_string_len, { "CM IPv6 Address Length", "ipdr.cm_ipv6_addr_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
601 { &hf_ipdr_cm_ipv6_addr_string, { "CM IPv6 Address", "ipdr.cm_ipv6_addr_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
602 { &hf_ipdr_cm_ipv6_addr, { "CM IPv6 Address", "ipdr.cm_ipv6_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } },
603 { &hf_ipdr_cm_ipv6_ll_addr, { "CM IPv6 Link-local Address", "ipdr.cm_ipv6_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL } },
604 { &hf_ipdr_cm_ipv6_ll_addr_string_len, { "CM IPv6 Link-local Address Length", "ipdr.cm_ipv6_addr_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
605 { &hf_ipdr_cm_ipv6_ll_addr_string, { "CM IPv6 Link-local Address", "ipdr.cm_ipv6_addr_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
606 { &hf_ipdr_cm_qos_version, { "CM QoS Version", "ipdr.cm_qos_version", FT_UINT32, BASE_DEC, VALS(ipdr_cm_qos_type_vals), 0x0, NULL, HFILL } },
607 { &hf_ipdr_cm_reg_status, { "CM REG Status", "ipdr.cm_reg_status", FT_UINT32, BASE_DEC, VALS(ipdr_cm_reg_status_vals), 0x0, NULL, HFILL } },
608 { &hf_ipdr_cm_last_reg_time, { "CM Last REG Time", "ipdr.cm_last_reg_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } },
609 { &hf_ipdr_rec_type, { "Record Type", "ipdr.record_type", FT_UINT32, BASE_DEC, VALS(ipdr_record_type_vals), 0x0, NULL, HFILL } },
610 { &hf_ipdr_rec_creation_time, { "Record Creation Time", "ipdr.rec_creation_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL } },
611 { &hf_ipdr_sf_ch_set, { "SF Channel Set", "ipdr.sf_ch_set", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
612 { &hf_ipdr_channel_id, { "Channel ID", "ipdr.channel_id", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
613 { &hf_ipdr_service_app_id, { "Service Application ID", "ipdr.svc_app_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
614 { &hf_ipdr_service_ds_multicast, { "Service Multicast SF", "ipdr.service_ds_multicast", FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
615 { &hf_ipdr_service_identifier, { "Service Identifier", "ipdr.service_identifier", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
616 { &hf_ipdr_service_gate_id, { "Service Gate ID", "ipdr.service_gate_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
617 { &hf_ipdr_service_class_name_len, { "Service Class Name Length", "ipdr.service_class_name_len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
618 { &hf_ipdr_service_class_name, { "Service Class Name", "ipdr.service_class_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
619 { &hf_ipdr_service_direction, { "Service Direction", "ipdr.service_direction", FT_UINT32, BASE_DEC, VALS(ipdr_service_direction_vals), 0x0, NULL, HFILL } },
620 { &hf_ipdr_service_octets_passed, { "Octets Passed", "ipdr.octets_passed", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
621 { &hf_ipdr_service_pkts_passed, { "Packets Passed", "ipdr.packets_passed", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL } },
622 { &hf_ipdr_service_sla_drop_pkts, { "SLA Packets Dropped", "ipdr.sla_drop_pkts", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
623 { &hf_ipdr_service_sla_delay_pkts, { "SLA Packets Delayed", "ipdr.sla_delay_pkts", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
624 { &hf_ipdr_service_time_created, { "SF Creation Time", "ipdr.service_time_created", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
625 { &hf_ipdr_service_time_active, { "SF Active", "ipdr.service_time_active", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
628 static int *ett[] = {
629 &ett_ipdr,
630 &ett_ipdr_samis_type_1,
631 &ett_ipdr_sf_ch_set
634 static ei_register_info ei[] = {
635 { &ei_ipdr_message_id, { "ipdr.message_id.unknown", PI_PROTOCOL, PI_WARN, "Unknown message ID", EXPFILL }},
636 { &ei_ipdr_sf_ch_set, { "ipdr.sf_ch_set.too_big", PI_PROTOCOL, PI_WARN, "SF Channel Set Too Big", EXPFILL }},
639 expert_module_t* expert_ipdr;
640 module_t *ipdr_module;
642 proto_ipdr = proto_register_protocol("IPDR", "IPDR/SP", "ipdr");
643 proto_ipdr_samis_type_1 = proto_register_protocol_in_name_only("SAMIS-TYPE-1 Record","SAMIS-TYPE-1 Record",
644 "ipdr_samis_type_1", proto_ipdr, FT_PROTOCOL);
646 proto_register_field_array(proto_ipdr, hf, array_length(hf));
647 proto_register_subtree_array(ett, array_length(ett));
648 expert_ipdr = expert_register_protocol(proto_ipdr);
649 expert_register_field_array(expert_ipdr, ei, array_length(ei));
651 ipdr_sessions_dissector_table = register_dissector_table("ipdr.session_type", "IPDR Session Type",
652 proto_ipdr, FT_UINT8, BASE_DEC);
654 ipdr_module = prefs_register_protocol(proto_ipdr, proto_reg_handoff_ipdr);
655 prefs_register_range_preference(ipdr_module, "sessions.samis_type_1", "SAMIS-TYPE-1 Sessions",
656 "Range of session IDs to be decoded as SAMIS-TYPE-1 records",
657 &global_sessions_samis_type_1, 255);
659 ipdr_handle = register_dissector("ipdr", dissect_ipdr, proto_ipdr);
660 ipdr_samis_type_1_handle = register_dissector("ipdr-samis-type-1", dissect_ipdr_samis_type_1,
661 proto_ipdr_samis_type_1);
664 void
665 proto_reg_handoff_ipdr(void)
667 static range_t *sessions_samis_type_1;
668 static bool ipdr_prefs_initialized = false;
670 if (!ipdr_prefs_initialized) {
671 dissector_add_uint_with_preference("tcp.port", IPDR_PORT, ipdr_handle);
673 ipdr_prefs_initialized = true;
674 } else {
675 dissector_delete_uint_range("ipdr.session_type", sessions_samis_type_1, ipdr_samis_type_1_handle);
678 sessions_samis_type_1 = range_copy(wmem_epan_scope(), global_sessions_samis_type_1);
679 dissector_add_uint_range("ipdr.session_type", sessions_samis_type_1, ipdr_samis_type_1_handle);
683 * Editor modelines - https://www.wireshark.org/tools/modelines.html
685 * Local variables:
686 * c-basic-offset: 4
687 * tab-width: 8
688 * indent-tabs-mode: nil
689 * End:
691 * vi: set shiftwidth=4 tabstop=8 expandtab:
692 * :indentSize=4:tabSize=8:noTabs=true: