Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-igrp.c
blobb876f1d7e1dfd0208199481819b6fd5ddfb6dd73
1 /* packet-igrp.c
2 * Routines for IGRP dissection
3 * Copyright 2000, Paul Ionescu <paul@acorp.ro>
5 * See
7 * http://www.cisco.com/en/US/tech/tk365/technologies_white_paper09186a00800c8ae1.shtml
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * Copied from packet-syslog.c
15 * SPDX-License-Identifier: GPL-2.0-or-later
18 #include "config.h"
20 #include <epan/packet.h>
21 #include <epan/expert.h>
22 #include <epan/to_str.h>
23 #include <epan/ipproto.h>
24 #include <epan/tfs.h>
25 #include <epan/unit_strings.h>
27 void proto_register_igrp(void);
28 void proto_reg_handoff_igrp(void);
30 #define IGRP_HEADER_LENGTH 12
31 #define IGRP_ENTRY_LENGTH 14
33 static dissector_handle_t igrp_handle;
35 static int proto_igrp;
36 static int hf_igrp_update;
37 static int hf_igrp_as;
38 /* Generated from convert_proto_tree_add_text.pl */
39 static int hf_igrp_load;
40 static int hf_igrp_bandwidth;
41 static int hf_igrp_command;
42 static int hf_igrp_reliability;
43 static int hf_igrp_network;
44 static int hf_igrp_version;
45 static int hf_igrp_interior_routes;
46 static int hf_igrp_mtu;
47 static int hf_igrp_hop_count;
48 static int hf_igrp_exterior_routes;
49 static int hf_igrp_delay;
50 static int hf_igrp_checksum;
51 static int hf_igrp_system_routes;
52 static int ett_igrp;
53 static int ett_igrp_vektor;
54 static int ett_igrp_net;
56 static expert_field ei_igrp_version;
58 static void dissect_vektor_igrp (packet_info *pinfo, tvbuff_t *tvb, proto_tree *igrp_vektor_tree, uint8_t network);
60 static int dissect_igrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
62 uint8_t ver_and_opcode,version,opcode,network;
63 int offset=IGRP_HEADER_LENGTH;
64 uint16_t ninterior,nsystem,nexterior;
65 const uint8_t *ipsrc;
66 proto_item *ti;
67 proto_tree *igrp_tree, *igrp_vektor_tree;
68 tvbuff_t *next_tvb;
70 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IGRP");
71 col_clear(pinfo->cinfo, COL_INFO);
73 ver_and_opcode = tvb_get_uint8(tvb,0);
75 switch (ver_and_opcode) {
76 case 0x11:
77 col_set_str(pinfo->cinfo, COL_INFO, "Response" );
78 break;
79 case 0x12:
80 col_set_str(pinfo->cinfo, COL_INFO, "Request" );
81 break;
82 default:
83 col_set_str(pinfo->cinfo, COL_INFO, "Unknown version or opcode");
87 if (tree) {
88 ti = proto_tree_add_protocol_format(tree, proto_igrp, tvb, 0, -1,
89 "Cisco IGRP");
91 igrp_tree = proto_item_add_subtree(ti, ett_igrp);
93 version = (ver_and_opcode&0xf0)>>4 ; /* version is the fist half of the byte */
94 opcode = ver_and_opcode&0x0f ; /* opcode is the last half of the byte */
96 ti = proto_tree_add_item(igrp_tree, hf_igrp_version, tvb, 0, 1, ENC_BIG_ENDIAN);
97 if (version != 1)
98 expert_add_info(pinfo, ti, &ei_igrp_version);
99 ti = proto_tree_add_item(igrp_tree, hf_igrp_command, tvb, 0, 1, ENC_BIG_ENDIAN);
100 if (opcode==1)
101 proto_item_append_text(ti, " (Response)");
102 else
103 proto_item_append_text(ti, " (Request)");
104 proto_tree_add_item(igrp_tree, hf_igrp_update, tvb, 1,1, ENC_BIG_ENDIAN);
105 proto_tree_add_item(igrp_tree, hf_igrp_as, tvb, 2,2, ENC_BIG_ENDIAN);
107 ninterior = tvb_get_ntohs(tvb,4);
108 nsystem = tvb_get_ntohs(tvb,6);
109 nexterior = tvb_get_ntohs(tvb,8);
111 /* this is a ugly hack to find the first byte of the IP source address */
112 if (pinfo->net_src.type == AT_IPv4) {
113 ipsrc = (const uint8_t *)pinfo->net_src.data;
114 network = ipsrc[0];
115 } else
116 network = 0; /* XXX - shouldn't happen */
118 ti = proto_tree_add_item(igrp_tree, hf_igrp_interior_routes, tvb, 4, 2, ENC_BIG_ENDIAN);
119 for( ; ninterior>0 ; ninterior-- ) {
120 igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor);
121 next_tvb = tvb_new_subset_length_caplen(tvb, offset, IGRP_ENTRY_LENGTH, -1);
122 dissect_vektor_igrp (pinfo,next_tvb,igrp_vektor_tree,network);
123 offset+=IGRP_ENTRY_LENGTH;
126 ti = proto_tree_add_item(igrp_tree, hf_igrp_system_routes, tvb, 6, 2, ENC_BIG_ENDIAN);
127 for( ; nsystem>0 ; nsystem-- ) {
128 igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor);
129 next_tvb = tvb_new_subset_length_caplen(tvb, offset, IGRP_ENTRY_LENGTH, -1);
130 dissect_vektor_igrp (pinfo,next_tvb,igrp_vektor_tree,0);
131 offset+=IGRP_ENTRY_LENGTH;
134 ti = proto_tree_add_item(igrp_tree, hf_igrp_exterior_routes, tvb, 8, 2, ENC_BIG_ENDIAN);
135 for( ; nexterior>0 ; nexterior-- ) {
136 igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor);
137 next_tvb = tvb_new_subset_length_caplen(tvb, offset, IGRP_ENTRY_LENGTH, -1);
138 dissect_vektor_igrp (pinfo,next_tvb,igrp_vektor_tree,0);
139 offset+=IGRP_ENTRY_LENGTH;
142 proto_tree_add_checksum(igrp_tree, tvb, 10, hf_igrp_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
144 return tvb_captured_length(tvb);
147 static void dissect_vektor_igrp (packet_info *pinfo, tvbuff_t *tvb, proto_tree *igrp_vektor_tree, uint8_t network)
149 union {
150 uint8_t addr_bytes[4];
151 uint32_t addr_word;
152 } addr;
153 address ip_addr;
155 if (network != 0) {
157 * Interior route; network is the high-order byte, and the three
158 * bytes in the vector are the lower 3 bytes.
160 addr.addr_bytes[0]=network;
161 addr.addr_bytes[1]=tvb_get_uint8(tvb,0);
162 addr.addr_bytes[2]=tvb_get_uint8(tvb,1);
163 addr.addr_bytes[3]=tvb_get_uint8(tvb,2);
164 } else {
166 * System or exterior route; the three bytes in the vector are
167 * the three high-order bytes, and the low-order byte is 0.
169 addr.addr_bytes[0]=tvb_get_uint8(tvb,0);
170 addr.addr_bytes[1]=tvb_get_uint8(tvb,1);
171 addr.addr_bytes[2]=tvb_get_uint8(tvb,2);
172 addr.addr_bytes[3]=0;
175 set_address(&ip_addr, AT_IPv4, 4, &addr);
176 igrp_vektor_tree = proto_tree_add_subtree_format(igrp_vektor_tree, tvb, 0 ,14,
177 ett_igrp_net, NULL, "Entry for network %s", address_to_str(pinfo->pool, &ip_addr));
178 proto_tree_add_ipv4(igrp_vektor_tree, hf_igrp_network, tvb, 0, 3, addr.addr_word);
179 proto_tree_add_item(igrp_vektor_tree, hf_igrp_delay, tvb, 3, 3, ENC_BIG_ENDIAN);
180 proto_tree_add_item(igrp_vektor_tree, hf_igrp_bandwidth, tvb, 6, 3, ENC_BIG_ENDIAN);
181 proto_tree_add_item(igrp_vektor_tree, hf_igrp_mtu, tvb, 9, 2, ENC_BIG_ENDIAN);
182 proto_tree_add_item(igrp_vektor_tree, hf_igrp_reliability, tvb, 11, 1, ENC_BIG_ENDIAN);
183 proto_tree_add_item(igrp_vektor_tree, hf_igrp_load, tvb, 12, 1, ENC_BIG_ENDIAN);
184 proto_tree_add_item(igrp_vektor_tree, hf_igrp_hop_count, tvb, 13, 1, ENC_BIG_ENDIAN);
188 /* Register the protocol with Wireshark */
189 void proto_register_igrp(void)
192 /* Setup list of header fields */
193 static hf_register_info hf[] = {
195 { &hf_igrp_update,
196 { "Update Release", "igrp.update",
197 FT_UINT8, BASE_DEC, NULL, 0x0 ,
198 "Update Release number", HFILL }
200 { &hf_igrp_as,
201 { "Autonomous System", "igrp.as",
202 FT_UINT16, BASE_DEC, NULL, 0x0 ,
203 "Autonomous System number", HFILL }
206 /* Generated from convert_proto_tree_add_text.pl */
207 { &hf_igrp_version, { "IGRP Version", "igrp.version", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
208 { &hf_igrp_command, { "Command", "igrp.command", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }},
209 { &hf_igrp_interior_routes, { "Interior routes", "igrp.interior_routes", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
210 { &hf_igrp_system_routes, { "System routes", "igrp.system_routes", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
211 { &hf_igrp_exterior_routes, { "Exterior routes", "igrp.exterior_routes", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
212 { &hf_igrp_checksum, { "Checksum", "igrp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
213 { &hf_igrp_network, { "Network", "igrp.network", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
214 { &hf_igrp_delay, { "Delay", "igrp.delay", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }},
215 { &hf_igrp_bandwidth, { "Bandwidth", "igrp.bandwidth", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }},
216 { &hf_igrp_mtu, { "MTU", "igrp.mtu", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0, NULL, HFILL }},
217 { &hf_igrp_reliability, { "Reliability", "igrp.reliability", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
218 { &hf_igrp_load, { "Load", "igrp.load", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
219 { &hf_igrp_hop_count, { "Hop count", "igrp.hop_count", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
222 /* Setup protocol subtree array */
223 static int *ett[] = {
224 &ett_igrp,
225 &ett_igrp_vektor,
226 &ett_igrp_net
229 static ei_register_info ei[] = {
230 { &ei_igrp_version, { "igrp.version.invalid", PI_PROTOCOL, PI_WARN, "Unknown Version, The dissection may be inaccurate", EXPFILL }},
233 expert_module_t* expert_igrp;
235 /* Register the protocol name and description */
236 proto_igrp = proto_register_protocol("Cisco Interior Gateway Routing Protocol",
237 "IGRP", "igrp");
238 igrp_handle = register_dissector("igrp", dissect_igrp, proto_igrp);
240 /* Required function calls to register the header fields and subtrees used */
241 proto_register_field_array(proto_igrp, hf, array_length(hf));
242 proto_register_subtree_array(ett, array_length(ett));
243 expert_igrp = expert_register_protocol(proto_igrp);
244 expert_register_field_array(expert_igrp, ei, array_length(ei));
247 void
248 proto_reg_handoff_igrp(void)
250 dissector_add_uint("ip.proto", IP_PROTO_IGRP, igrp_handle);
253 /* IGRP Packet structure:
255 HEADER structure + k * VECTOR structure
256 where: k = (Number of Interior routes) + (Number of System routes) + (Number of Exterior routes)
258 HEADER structure is 12 bytes as follows :
260 4 bits Version (only version 1 is defined)
261 4 bits Opcode (1=Replay, 2=Request)
262 8 bits Update Release
263 16 bits Autonomous system number
264 16 bits Number of Interior routes
265 16 bits Number of System routes
266 16 bits Number of Exterior routes
267 16 bits Checksum
268 -------
269 12 bytes in header
271 VECTOR structure is 14 bytes as follows :
272 24 bits Network
273 24 bits Delay
274 24 bits Bandwidth
275 16 bits MTU
276 8 bits Reliability
277 8 bits Load
278 8 bits Hop count
279 -------
280 14 bytes in 1 vector
282 It is interesting how is coded an ip network address in 3 bytes because IGRP is a classful routing protocol:
283 If it is a interior route then this 3 bytes are the final bytes, and the first one is taken from the source ip address of the ip packet
284 If it is a system route or a exterior route then this 3 bytes are the first three and the last byte is not important
286 If the Delay is 0xFFFFFF then the network is unreachable
291 * Editor modelines - https://www.wireshark.org/tools/modelines.html
293 * Local Variables:
294 * c-basic-offset: 2
295 * tab-width: 8
296 * indent-tabs-mode: nil
297 * End:
299 * ex: set shiftwidth=2 tabstop=8 expandtab:
300 * :indentSize=2:tabSize=8:noTabs=true: