2 * Traffic analyzer for the CN/IP (EIA-852) protocol
3 * Daniel Willmann <daniel@totalueberwachung.de>
4 * (c) 2011 Daniel Willmann
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <epan/packet.h>
16 #include <epan/expert.h>
18 #define DATA_PACKET 0x01
20 #define CNIP_UDP_PORT_RANGE "1628-1629" /* Not IANA registered */
22 static const value_string type_tuple
[]=
24 {0x01, "Data Packet"},
25 {0x63, "Device Configuration Request"},
26 {0x03, "Device Registration"},
27 {0x71, "Device Configuration"},
28 {0x64, "Channel Membership Request"},
29 {0x04, "Channel Membership"},
30 {0x66, "Send List Request"},
32 {0x68, "Channel Routing Request"},
33 {0x08, "Channel Routing"},
34 {0x07, "Acknowledge"},
36 {0x60, "Status/Health/Statistics Request"},
37 {0x70, "Status/Health/Statistics Response"},
41 void proto_register_cnip(void);
42 void proto_reg_handoff_cnip(void);
44 static dissector_handle_t cnip_handle
;
46 static int hf_cnip_len
;
47 static int hf_cnip_ver
;
48 static int hf_cnip_type
;
49 static int hf_cnip_exth
;
50 static int hf_cnip_pf
;
51 static int hf_cnip_pf_sec
;
52 static int hf_cnip_pf_pcode
;
53 static int hf_cnip_vcode
;
54 static int hf_cnip_sessid
;
55 static int hf_cnip_seqno
;
56 static int hf_cnip_tstamp
;
58 static int proto_cnip
;
63 static expert_field ei_cnip_type_unknown
;
65 static dissector_table_t cnip_dissector_table
;
67 static int dissect_cnip (tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
71 int type
, exth_len
, pf_pcode
;
74 proto_tree
*cnip_tree
;
76 static int * const pf_fields
[] = {
82 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CN/IP");
83 col_clear(pinfo
->cinfo
, COL_INFO
);
85 type
= tvb_get_uint8(tvb
, 3);
86 col_add_fstr(pinfo
->cinfo
, COL_INFO
,"Priority: %s Type: %s",
87 (pinfo
->destport
== 1629 )? "urgent":"normal",
88 val_to_str_const(type
, type_tuple
, "Unknown"));
90 exth_len
= tvb_get_uint8(tvb
, 4);
91 pf_pcode
= tvb_get_uint8(tvb
, 5) & 0x1F;
95 /* Take whole packet for now, we'll adjust it later */
96 ti
= proto_tree_add_item(tree
, proto_cnip
, tvb
, offset
, -1, ENC_NA
);
97 cnip_tree
= proto_item_add_subtree(ti
, ett_cnip
);
99 proto_tree_add_item(cnip_tree
, hf_cnip_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
102 proto_tree_add_item(cnip_tree
, hf_cnip_ver
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
105 proto_tree_add_item(cnip_tree
, hf_cnip_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
108 proto_tree_add_item(cnip_tree
, hf_cnip_exth
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
111 proto_tree_add_bitmask(cnip_tree
, tvb
, offset
,
112 hf_cnip_pf
, ett_pf
, pf_fields
, ENC_BIG_ENDIAN
);
115 proto_tree_add_item(cnip_tree
, hf_cnip_vcode
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
118 proto_tree_add_item(cnip_tree
, hf_cnip_sessid
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
121 proto_tree_add_item(cnip_tree
, hf_cnip_seqno
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
124 proto_tree_add_item(cnip_tree
, hf_cnip_tstamp
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
127 /* Jump over any unknown header extensions */
128 offset
+= 4 * exth_len
;
130 proto_item_set_len(ti
, offset
);
132 next_tvb
= tvb_new_subset_remaining(tvb
, offset
);
133 if (type
== DATA_PACKET
) {
134 if (dissector_try_uint(cnip_dissector_table
, pf_pcode
, next_tvb
, pinfo
, tree
))
135 return tvb_captured_length(tvb
);
138 expert_add_info_format(pinfo
, cnip_tree
, &ei_cnip_type_unknown
,
139 "This dissector doesn't yet decode packets of type %s (0x%x)",
140 val_to_str_const(type
, type_tuple
, "Unknown"), type
);
142 call_data_dissector(next_tvb
, pinfo
, tree
);
143 return tvb_captured_length(tvb
);
146 void proto_register_cnip(void)
148 static hf_register_info hf
[] =
151 {"Packet length", "cnip.len",
152 FT_UINT16
, BASE_DEC
, NULL
, 0,
156 {"Version", "cnip.ver",
157 FT_UINT8
, BASE_DEC
, NULL
, 0,
161 {"Packet type", "cnip.type",
162 FT_UINT8
, BASE_HEX
, VALS(type_tuple
), 0,
166 {"Ext. Header Size", "cnip.exth",
167 FT_UINT8
, BASE_DEC
, NULL
, 0,
171 {"Protocol Flags", "cnip.pf",
172 FT_UINT8
, BASE_DEC
, NULL
, 0,
176 {"Protocol Flags", "cnip.sec",
177 FT_UINT8
, BASE_DEC
, NULL
, 0x20,
181 {"Protocol Code", "cnip.protocol",
182 FT_UINT8
, BASE_DEC
, NULL
, 0x1F,
186 {"Vendor Code", "cnip.vendorcode",
187 FT_UINT16
, BASE_DEC
, NULL
, 0,
191 {"Session ID", "cnip.sessid",
192 FT_UINT32
, BASE_DEC
, NULL
, 0,
196 {"Sequence Number", "cnip.seqno",
197 FT_UINT32
, BASE_DEC
, NULL
, 0,
201 {"Time Stamp", "cnip.tstamp",
202 FT_UINT32
, BASE_DEC
, NULL
, 0,
213 static ei_register_info ei
[] = {
214 { &ei_cnip_type_unknown
, { "cnip.type.unknown", PI_UNDECODED
, PI_WARN
, "This dissector doesn't yet decode packets of type", EXPFILL
}},
217 expert_module_t
* expert_cnip
;
219 proto_cnip
= proto_register_protocol("Component Network over IP",
222 proto_register_field_array(proto_cnip
, hf
, array_length (hf
));
223 proto_register_subtree_array(ett
, array_length (ett
));
224 expert_cnip
= expert_register_protocol(proto_cnip
);
225 expert_register_field_array(expert_cnip
, ei
, array_length(ei
));
227 /* Register table for subdissectors */
228 cnip_dissector_table
= register_dissector_table("cnip.protocol",
229 "CN/IP Protocol", proto_cnip
, FT_UINT8
, BASE_DEC
);
231 cnip_handle
= register_dissector("cnip", dissect_cnip
, proto_cnip
);
234 void proto_reg_handoff_cnip(void)
236 dissector_add_uint_range_with_preference("udp.port", CNIP_UDP_PORT_RANGE
, cnip_handle
);
240 * Editor modelines - https://www.wireshark.org/tools/modelines.html
245 * indent-tabs-mode: nil
248 * vi: set shiftwidth=4 tabstop=8 expandtab:
249 * :indentSize=4:tabSize=8:noTabs=true: