2 * Routines for IGRP dissection
3 * Copyright 2000, Paul Ionescu <paul@acorp.ro>
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 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 #include <epan/packet.h>
33 #include <epan/expert.h>
34 #include <epan/to_str.h>
35 #include <epan/ipproto.h>
37 void proto_register_igrp(void);
38 void proto_reg_handoff_igrp(void);
40 #define IGRP_HEADER_LENGTH 12
41 #define IGRP_ENTRY_LENGTH 14
43 static gint proto_igrp = -1;
44 static gint hf_igrp_update = -1;
45 static gint hf_igrp_as = -1;
46 /* Generated from convert_proto_tree_add_text.pl */
47 static int hf_igrp_load = -1;
48 static int hf_igrp_bandwidth = -1;
49 static int hf_igrp_command = -1;
50 static int hf_igrp_reliability = -1;
51 static int hf_igrp_network = -1;
52 static int hf_igrp_version = -1;
53 static int hf_igrp_interior_routes = -1;
54 static int hf_igrp_mtu = -1;
55 static int hf_igrp_hop_count = -1;
56 static int hf_igrp_exterior_routes = -1;
57 static int hf_igrp_delay = -1;
58 static int hf_igrp_checksum = -1;
59 static int hf_igrp_system_routes = -1;
60 static gint ett_igrp = -1;
61 static gint ett_igrp_vektor = -1;
62 static gint ett_igrp_net = -1;
64 static expert_field ei_igrp_version = EI_INIT;
66 static void dissect_vektor_igrp (tvbuff_t *tvb, proto_tree *igrp_vektor_tree, guint8 network);
68 static void dissect_igrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
70 guint8 ver_and_opcode,version,opcode,network;
71 gint offset=IGRP_HEADER_LENGTH;
72 guint16 ninterior,nsystem,nexterior;
75 proto_tree *igrp_tree, *igrp_vektor_tree;
78 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IGRP");
79 col_clear(pinfo->cinfo, COL_INFO);
81 ver_and_opcode = tvb_get_guint8(tvb,0);
84 switch (ver_and_opcode) {
86 col_set_str(pinfo->cinfo, COL_INFO, "Response" );
89 col_set_str(pinfo->cinfo, COL_INFO, "Request" );
92 col_set_str(pinfo->cinfo, COL_INFO, "Unknown version or opcode");
99 ti = proto_tree_add_protocol_format(tree, proto_igrp, tvb, 0, -1,
102 igrp_tree = proto_item_add_subtree(ti, ett_igrp);
104 version = (ver_and_opcode&0xf0)>>4 ; /* version is the fist half of the byte */
105 opcode = ver_and_opcode&0x0f ; /* opcode is the last half of the byte */
107 ti = proto_tree_add_item(igrp_tree, hf_igrp_version, tvb, 0, 1, ENC_BIG_ENDIAN);
109 expert_add_info(pinfo, ti, &ei_igrp_version);
110 ti = proto_tree_add_item(igrp_tree, hf_igrp_command, tvb, 0, 1, ENC_BIG_ENDIAN);
112 proto_item_append_text(ti, " (Response)");
114 proto_item_append_text(ti, " (Request)");
115 proto_tree_add_item(igrp_tree, hf_igrp_update, tvb, 1,1, ENC_BIG_ENDIAN);
116 proto_tree_add_item(igrp_tree, hf_igrp_as, tvb, 2,2, ENC_BIG_ENDIAN);
118 ninterior = tvb_get_ntohs(tvb,4);
119 nsystem = tvb_get_ntohs(tvb,6);
120 nexterior = tvb_get_ntohs(tvb,8);
122 /* this is a ugly hack to find the first byte of the IP source address */
123 if (pinfo->net_src.type == AT_IPv4) {
124 ipsrc = (const guint8 *)pinfo->net_src.data;
127 network = 0; /* XXX - shouldn't happen */
129 ti = proto_tree_add_item(igrp_tree, hf_igrp_interior_routes, tvb, 4, 2, ENC_BIG_ENDIAN);
130 for( ; ninterior>0 ; ninterior-- ) {
131 igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor);
132 next_tvb = tvb_new_subset(tvb, offset, IGRP_ENTRY_LENGTH, -1);
133 dissect_vektor_igrp (next_tvb,igrp_vektor_tree,network);
134 offset+=IGRP_ENTRY_LENGTH;
137 ti = proto_tree_add_item(igrp_tree, hf_igrp_system_routes, tvb, 6, 2, ENC_BIG_ENDIAN);
138 for( ; nsystem>0 ; nsystem-- ) {
139 igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor);
140 next_tvb = tvb_new_subset(tvb, offset, IGRP_ENTRY_LENGTH, -1);
141 dissect_vektor_igrp (next_tvb,igrp_vektor_tree,0);
142 offset+=IGRP_ENTRY_LENGTH;
145 ti = proto_tree_add_item(igrp_tree, hf_igrp_exterior_routes, tvb, 8, 2, ENC_BIG_ENDIAN);
146 for( ; nexterior>0 ; nexterior-- ) {
147 igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor);
148 next_tvb = tvb_new_subset(tvb, offset, IGRP_ENTRY_LENGTH, -1);
149 dissect_vektor_igrp (next_tvb,igrp_vektor_tree,0);
150 offset+=IGRP_ENTRY_LENGTH;
153 proto_tree_add_item(igrp_tree, hf_igrp_checksum, tvb, 10, 2, ENC_BIG_ENDIAN);
157 static void dissect_vektor_igrp (tvbuff_t *tvb, proto_tree *igrp_vektor_tree, guint8 network)
160 guint8 addr_bytes[4];
167 * Interior route; network is the high-order byte, and the three
168 * bytes in the vector are the lower 3 bytes.
170 addr.addr_bytes[0]=network;
171 addr.addr_bytes[1]=tvb_get_guint8(tvb,0);
172 addr.addr_bytes[2]=tvb_get_guint8(tvb,1);
173 addr.addr_bytes[3]=tvb_get_guint8(tvb,2);
176 * System or exterior route; the three bytes in the vector are
177 * the three high-order bytes, and the low-order byte is 0.
179 addr.addr_bytes[0]=tvb_get_guint8(tvb,0);
180 addr.addr_bytes[1]=tvb_get_guint8(tvb,1);
181 addr.addr_bytes[2]=tvb_get_guint8(tvb,2);
182 addr.addr_bytes[3]=0;
185 set_address(&ip_addr, AT_IPv4, 4, &addr);
186 igrp_vektor_tree = proto_tree_add_subtree_format(igrp_vektor_tree, tvb, 0 ,14,
187 ett_igrp_net, NULL, "Entry for network %s", address_to_str(wmem_packet_scope(), &ip_addr));
188 proto_tree_add_ipv4(igrp_vektor_tree, hf_igrp_network, tvb, 0, 3, addr.addr_word);
189 proto_tree_add_item(igrp_vektor_tree, hf_igrp_delay, tvb, 3, 3, ENC_BIG_ENDIAN);
190 proto_tree_add_item(igrp_vektor_tree, hf_igrp_bandwidth, tvb, 6, 3, ENC_BIG_ENDIAN);
191 proto_tree_add_uint_format_value(igrp_vektor_tree, hf_igrp_mtu, tvb, 9, 2, tvb_get_ntohs(tvb,9), "%d bytes", tvb_get_ntohs(tvb,9));
192 proto_tree_add_item(igrp_vektor_tree, hf_igrp_reliability, tvb, 11, 1, ENC_BIG_ENDIAN);
193 proto_tree_add_item(igrp_vektor_tree, hf_igrp_load, tvb, 12, 1, ENC_BIG_ENDIAN);
194 proto_tree_add_item(igrp_vektor_tree, hf_igrp_hop_count, tvb, 13, 1, ENC_BIG_ENDIAN);
198 /* Register the protocol with Wireshark */
199 void proto_register_igrp(void)
202 /* Setup list of header fields */
203 static hf_register_info hf[] = {
206 { "Update Release", "igrp.update",
207 FT_UINT8, BASE_DEC, NULL, 0x0 ,
208 "Update Release number", HFILL }
211 { "Autonomous System", "igrp.as",
212 FT_UINT16, BASE_DEC, NULL, 0x0 ,
213 "Autonomous System number", HFILL }
216 /* Generated from convert_proto_tree_add_text.pl */
217 { &hf_igrp_version, { "IGRP Version", "igrp.version", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
218 { &hf_igrp_command, { "Command", "igrp.command", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }},
219 { &hf_igrp_interior_routes, { "Interior routes", "igrp.interior_routes", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
220 { &hf_igrp_system_routes, { "System routes", "igrp.system_routes", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
221 { &hf_igrp_exterior_routes, { "Exterior routes", "igrp.exterior_routes", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
222 { &hf_igrp_checksum, { "Checksum", "igrp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
223 { &hf_igrp_network, { "Network", "igrp.network", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
224 { &hf_igrp_delay, { "Delay", "igrp.delay", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }},
225 { &hf_igrp_bandwidth, { "Bandwidth", "igrp.bandwidth", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL }},
226 { &hf_igrp_mtu, { "MTU", "igrp.mtu", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
227 { &hf_igrp_reliability, { "Reliability", "igrp.reliability", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
228 { &hf_igrp_load, { "Load", "igrp.load", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
229 { &hf_igrp_hop_count, { "Hop count", "igrp.hop_count", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
232 /* Setup protocol subtree array */
233 static gint *ett[] = {
239 static ei_register_info ei[] = {
240 { &ei_igrp_version, { "igrp.version.invalid", PI_PROTOCOL, PI_WARN, "Unknown Version, The dissection may be inaccurate", EXPFILL }},
243 expert_module_t* expert_igrp;
245 /* Register the protocol name and description */
246 proto_igrp = proto_register_protocol("Cisco Interior Gateway Routing Protocol",
249 /* Required function calls to register the header fields and subtrees used */
250 proto_register_field_array(proto_igrp, hf, array_length(hf));
251 proto_register_subtree_array(ett, array_length(ett));
252 expert_igrp = expert_register_protocol(proto_igrp);
253 expert_register_field_array(expert_igrp, ei, array_length(ei));
257 proto_reg_handoff_igrp(void)
259 dissector_handle_t igrp_handle;
261 igrp_handle = create_dissector_handle(dissect_igrp, proto_igrp);
262 dissector_add_uint("ip.proto", IP_PROTO_IGRP, igrp_handle);
265 /* IGRP Packet structure:
267 HEADER structure + k * VECTOR structure
268 where: k = (Number of Interior routes) + (Number of System routes) + (Number of Exterior routes)
270 HEADER structure is 12 bytes as follows :
272 4 bits Version (only version 1 is defined)
273 4 bits Opcode (1=Replay, 2=Request)
274 8 bits Update Release
275 16 bits Autonomous system number
276 16 bits Number of Interior routes
277 16 bits Number of System routes
278 16 bits Number of Exterior routes
283 VECTOR structure is 14 bytes as follows :
294 It is interesting how is coded an ip network address in 3 bytes because IGRP is a classful routing protocol:
295 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
296 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
298 If the Delay is 0xFFFFFF then the network is unreachable
303 * Editor modelines - http://www.wireshark.org/tools/modelines.html
308 * indent-tabs-mode: nil
311 * ex: set shiftwidth=2 tabstop=8 expandtab:
312 * :indentSize=2:tabSize=8:noTabs=true: