2 * Routines for IGRP dissection
3 * Copyright 2000, Paul Ionescu <paul@acorp.ro>
5 * $Id: packet-igrp.c,v 1.14 2003/12/21 05:51:33 jmayer Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * Copied from packet-syslog.c
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 #include <epan/packet.h>
41 #define IGRP_HEADER_LENGTH 12
42 #define IGRP_ENTRY_LENGTH 14
44 static gint proto_igrp = -1;
45 static gint hf_igrp_update = -1;
46 static gint hf_igrp_as = -1;
48 static gint ett_igrp = -1;
49 static gint ett_igrp_vektor = -1;
50 static gint ett_igrp_net = -1;
52 static void dissect_vektor_igrp (tvbuff_t *tvb, proto_tree *igrp_vektor_tree, guint8 network);
54 static void dissect_igrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
56 guint8 ver_and_opcode,version,opcode,update,network;
57 gint offset=IGRP_HEADER_LENGTH;
58 guint16 as,net1,net2,net3;
60 proto_tree *igrp_tree, *igrp_vektor_tree;
63 if (check_col(pinfo->cinfo, COL_PROTOCOL))
64 col_set_str(pinfo->cinfo, COL_PROTOCOL, "IGRP");
65 if (check_col(pinfo->cinfo, COL_INFO))
66 col_clear(pinfo->cinfo, COL_INFO);
68 ver_and_opcode = tvb_get_guint8(tvb,0);
69 update = tvb_get_guint8(tvb,1);
70 as = tvb_get_ntohs(tvb,2);
73 if (check_col(pinfo->cinfo, COL_INFO)) {
74 switch (ver_and_opcode) {
76 col_add_fstr(pinfo->cinfo, COL_INFO, "Response" );
79 col_add_fstr(pinfo->cinfo, COL_INFO, "Request" );
82 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown version or opcode");
90 ti = proto_tree_add_protocol_format(tree, proto_igrp, tvb, 0, -1,
93 igrp_tree = proto_item_add_subtree(ti, ett_igrp);
95 version = (ver_and_opcode&0xf0)>>4 ; /* version is the fist half of the byte */
96 opcode = ver_and_opcode&0x0f ; /* opcode is the last half of the byte */
98 proto_tree_add_text(igrp_tree, tvb, 0,1,"IGRP Version : %d %s",version,(version==1?" ":" - Unknown Version, The dissection may be innacurate"));
99 proto_tree_add_text(igrp_tree, tvb, 0,1,"Command : %d %s",opcode,(opcode==1?"(Response)":"(Request)"));
100 proto_tree_add_uint(igrp_tree, hf_igrp_update, tvb, 1,1, update);
101 proto_tree_add_uint(igrp_tree, hf_igrp_as, tvb, 2,2,as);
103 net1 = tvb_get_ntohs(tvb,4);
104 net2 = tvb_get_ntohs(tvb,6);
105 net3 = tvb_get_ntohs(tvb,8);
107 /* this is a ugly hack to find the first byte of the IP source address */
108 network = pinfo->net_src.data[0];
110 ti = proto_tree_add_text(igrp_tree, tvb, 4,2,"Interior routes : %d",net1);
111 for( ; net1>0 ; net1-- )
113 igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor);
114 next_tvb = tvb_new_subset(tvb, offset, IGRP_ENTRY_LENGTH, -1);
115 dissect_vektor_igrp (next_tvb,igrp_vektor_tree,network);
116 offset+=IGRP_ENTRY_LENGTH;
119 ti = proto_tree_add_text(igrp_tree, tvb, 6,2,"System routes : %d",net2);
120 for( ; net2>0 ; net2-- )
122 igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_vektor);
123 next_tvb = tvb_new_subset(tvb, offset, IGRP_ENTRY_LENGTH, -1);
124 dissect_vektor_igrp (next_tvb,igrp_vektor_tree,0);
125 offset+=IGRP_ENTRY_LENGTH;
128 ti = proto_tree_add_text(igrp_tree, tvb, 8,2,"Exterior routes : %d",net3);
129 for( ; net3>0 ; net3-- )
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,0);
134 offset+=IGRP_ENTRY_LENGTH;
137 proto_tree_add_text(igrp_tree, tvb, 10,2,"Checksum = 0x%4x",tvb_get_ntohs(tvb,10));
143 static void dissect_vektor_igrp (tvbuff_t *tvb, proto_tree *igrp_vektor_tree, guint8 network)
146 guint8 *ptr_addr,addr[5];
149 addr[1]=tvb_get_guint8(tvb,0);
150 addr[2]=tvb_get_guint8(tvb,1);
151 addr[3]=tvb_get_guint8(tvb,2);
155 if (network==0) ptr_addr=&addr[1];
157 ti = proto_tree_add_text (igrp_vektor_tree, tvb, 0 ,14,
158 "Entry for network %s", ip_to_str(ptr_addr)) ;
159 igrp_vektor_tree = proto_item_add_subtree(ti,ett_igrp_net);
160 proto_tree_add_text (igrp_vektor_tree, tvb, 0 ,3,"Network = %s",ip_to_str(ptr_addr)) ;
161 proto_tree_add_text (igrp_vektor_tree, tvb, 3 ,3,"Delay = %d",tvb_get_ntoh24(tvb,3)) ;
162 proto_tree_add_text (igrp_vektor_tree, tvb, 6 ,3,"Bandwidth = %d",tvb_get_ntoh24(tvb,6)) ;
163 proto_tree_add_text (igrp_vektor_tree, tvb, 9 ,2,"MTU = %d bytes",tvb_get_ntohs(tvb,9)) ;
164 proto_tree_add_text (igrp_vektor_tree, tvb, 11,1,"Reliability = %d",tvb_get_guint8(tvb,11)) ;
165 proto_tree_add_text (igrp_vektor_tree, tvb, 12,1,"Load = %d",tvb_get_guint8(tvb,12)) ;
166 proto_tree_add_text (igrp_vektor_tree, tvb, 13,1,"Hop count = %d hops",tvb_get_guint8(tvb,13)) ;
170 /* Register the protocol with Ethereal */
171 void proto_register_igrp(void)
174 /* Setup list of header fields */
175 static hf_register_info hf[] = {
178 { "Update Release", "igrp.update",
179 FT_UINT8, BASE_DEC, NULL, 0x0 ,
180 "Update Release number", HFILL }
183 { "Autonomous System", "igrp.as",
184 FT_UINT16, BASE_DEC, NULL, 0x0 ,
185 "Autonomous System number", HFILL }
189 /* Setup protocol subtree array */
190 static gint *ett[] = {
196 /* Register the protocol name and description */
197 proto_igrp = proto_register_protocol("Cisco Interior Gateway Routing Protocol",
200 /* Required function calls to register the header fields and subtrees used */
201 proto_register_field_array(proto_igrp, hf, array_length(hf));
202 proto_register_subtree_array(ett, array_length(ett));
206 proto_reg_handoff_igrp(void)
208 dissector_handle_t igrp_handle;
210 igrp_handle = create_dissector_handle(dissect_igrp, proto_igrp);
211 dissector_add("ip.proto", IP_PROTO_IGRP, igrp_handle);
214 /* IGRP Packet structure:
216 HEADER structure + k * VECTOR structure
217 where: k = (Number of Interior routes) + (Number of System routes) + (Number of Exterior routes)
219 HEADER structure is 12 bytes as follows :
221 4 bits Version (only version 1 is defined)
222 4 bits Opcode (1=Replay, 2=Request)
223 8 bits Update Release
224 16 bits Autonomous system number
225 16 bits Number of Interior routes
226 16 bits Number of System routes
227 16 bits Number of Exterior routes
232 VECTOR structure is 14 bytes as follows :
243 It is interesting how is coded an ip network address in 3 bytes because IGRP is a classful routing protocol:
244 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
245 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
247 If the Delay is 0xFFFFFF then the network is unreachable