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
11 * Wireshark - Network traffic analyzer
12 * By Gerald Combs <gerald@wireshark.org>
13 * Copyright 1998 Gerald Combs
15 * Copied from packet-syslog.c
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * as published by the Free Software Foundation; either version 2
20 * of the License, or (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 #include <epan/packet.h>
37 #include <epan/to_str.h>
38 #include <epan/ipproto.h>
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;
47 static gint ett_igrp
= -1;
48 static gint ett_igrp_vektor
= -1;
49 static gint ett_igrp_net
= -1;
51 static void dissect_vektor_igrp (tvbuff_t
*tvb
, proto_tree
*igrp_vektor_tree
, guint8 network
);
53 static void dissect_igrp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
55 guint8 ver_and_opcode
,version
,opcode
,network
;
56 gint offset
=IGRP_HEADER_LENGTH
;
57 guint16 ninterior
,nsystem
,nexterior
;
60 proto_tree
*igrp_tree
, *igrp_vektor_tree
;
63 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "IGRP");
64 col_clear(pinfo
->cinfo
, COL_INFO
);
66 ver_and_opcode
= tvb_get_guint8(tvb
,0);
69 switch (ver_and_opcode
) {
71 col_set_str(pinfo
->cinfo
, COL_INFO
, "Response" );
74 col_set_str(pinfo
->cinfo
, COL_INFO
, "Request" );
77 col_set_str(pinfo
->cinfo
, COL_INFO
, "Unknown version or opcode");
84 ti
= proto_tree_add_protocol_format(tree
, proto_igrp
, tvb
, 0, -1,
87 igrp_tree
= proto_item_add_subtree(ti
, ett_igrp
);
89 version
= (ver_and_opcode
&0xf0)>>4 ; /* version is the fist half of the byte */
90 opcode
= ver_and_opcode
&0x0f ; /* opcode is the last half of the byte */
92 proto_tree_add_text(igrp_tree
, tvb
, 0,1,"IGRP Version : %d %s",version
,(version
==1?" ":" - Unknown Version, The dissection may be inaccurate"));
93 proto_tree_add_text(igrp_tree
, tvb
, 0,1,"Command : %d %s",opcode
,(opcode
==1?"(Response)":"(Request)"));
94 proto_tree_add_item(igrp_tree
, hf_igrp_update
, tvb
, 1,1, ENC_BIG_ENDIAN
);
95 proto_tree_add_item(igrp_tree
, hf_igrp_as
, tvb
, 2,2, ENC_BIG_ENDIAN
);
97 ninterior
= tvb_get_ntohs(tvb
,4);
98 nsystem
= tvb_get_ntohs(tvb
,6);
99 nexterior
= tvb_get_ntohs(tvb
,8);
101 /* this is a ugly hack to find the first byte of the IP source address */
102 if (pinfo
->net_src
.type
== AT_IPv4
) {
103 ipsrc
= (guint8
*)pinfo
->net_src
.data
;
106 network
= 0; /* XXX - shouldn't happen */
108 ti
= proto_tree_add_text(igrp_tree
, tvb
, 4,2,"Interior routes : %d",ninterior
);
109 for( ; ninterior
>0 ; ninterior
-- ) {
110 igrp_vektor_tree
= proto_item_add_subtree(ti
,ett_igrp_vektor
);
111 next_tvb
= tvb_new_subset(tvb
, offset
, IGRP_ENTRY_LENGTH
, -1);
112 dissect_vektor_igrp (next_tvb
,igrp_vektor_tree
,network
);
113 offset
+=IGRP_ENTRY_LENGTH
;
116 ti
= proto_tree_add_text(igrp_tree
, tvb
, 6,2,"System routes : %d",nsystem
);
117 for( ; nsystem
>0 ; nsystem
-- ) {
118 igrp_vektor_tree
= proto_item_add_subtree(ti
,ett_igrp_vektor
);
119 next_tvb
= tvb_new_subset(tvb
, offset
, IGRP_ENTRY_LENGTH
, -1);
120 dissect_vektor_igrp (next_tvb
,igrp_vektor_tree
,0);
121 offset
+=IGRP_ENTRY_LENGTH
;
124 ti
= proto_tree_add_text(igrp_tree
, tvb
, 8,2,"Exterior routes : %d",nexterior
);
125 for( ; nexterior
>0 ; nexterior
-- ) {
126 igrp_vektor_tree
= proto_item_add_subtree(ti
,ett_igrp_vektor
);
127 next_tvb
= tvb_new_subset(tvb
, offset
, IGRP_ENTRY_LENGTH
, -1);
128 dissect_vektor_igrp (next_tvb
,igrp_vektor_tree
,0);
129 offset
+=IGRP_ENTRY_LENGTH
;
132 proto_tree_add_text(igrp_tree
, tvb
, 10,2,"Checksum = 0x%4x",tvb_get_ntohs(tvb
,10));
136 static void dissect_vektor_igrp (tvbuff_t
*tvb
, proto_tree
*igrp_vektor_tree
, guint8 network
)
139 guint8
*ptr_addr
,addr
[5];
142 addr
[1]=tvb_get_guint8(tvb
,0);
143 addr
[2]=tvb_get_guint8(tvb
,1);
144 addr
[3]=tvb_get_guint8(tvb
,2);
148 if (network
==0) ptr_addr
=&addr
[1];
150 ti
= proto_tree_add_text (igrp_vektor_tree
, tvb
, 0 ,14,
151 "Entry for network %s", ip_to_str(ptr_addr
)) ;
152 igrp_vektor_tree
= proto_item_add_subtree(ti
,ett_igrp_net
);
153 proto_tree_add_text (igrp_vektor_tree
, tvb
, 0 ,3,"Network = %s",ip_to_str(ptr_addr
)) ;
154 proto_tree_add_text (igrp_vektor_tree
, tvb
, 3 ,3,"Delay = %d",tvb_get_ntoh24(tvb
,3)) ;
155 proto_tree_add_text (igrp_vektor_tree
, tvb
, 6 ,3,"Bandwidth = %d",tvb_get_ntoh24(tvb
,6)) ;
156 proto_tree_add_text (igrp_vektor_tree
, tvb
, 9 ,2,"MTU = %d bytes",tvb_get_ntohs(tvb
,9)) ;
157 proto_tree_add_text (igrp_vektor_tree
, tvb
, 11,1,"Reliability = %d",tvb_get_guint8(tvb
,11)) ;
158 proto_tree_add_text (igrp_vektor_tree
, tvb
, 12,1,"Load = %d",tvb_get_guint8(tvb
,12)) ;
159 proto_tree_add_text (igrp_vektor_tree
, tvb
, 13,1,"Hop count = %d hops",tvb_get_guint8(tvb
,13)) ;
163 /* Register the protocol with Wireshark */
164 void proto_register_igrp(void)
167 /* Setup list of header fields */
168 static hf_register_info hf
[] = {
171 { "Update Release", "igrp.update",
172 FT_UINT8
, BASE_DEC
, NULL
, 0x0 ,
173 "Update Release number", HFILL
}
176 { "Autonomous System", "igrp.as",
177 FT_UINT16
, BASE_DEC
, NULL
, 0x0 ,
178 "Autonomous System number", HFILL
}
182 /* Setup protocol subtree array */
183 static gint
*ett
[] = {
189 /* Register the protocol name and description */
190 proto_igrp
= proto_register_protocol("Cisco Interior Gateway Routing Protocol",
193 /* Required function calls to register the header fields and subtrees used */
194 proto_register_field_array(proto_igrp
, hf
, array_length(hf
));
195 proto_register_subtree_array(ett
, array_length(ett
));
199 proto_reg_handoff_igrp(void)
201 dissector_handle_t igrp_handle
;
203 igrp_handle
= create_dissector_handle(dissect_igrp
, proto_igrp
);
204 dissector_add_uint("ip.proto", IP_PROTO_IGRP
, igrp_handle
);
207 /* IGRP Packet structure:
209 HEADER structure + k * VECTOR structure
210 where: k = (Number of Interior routes) + (Number of System routes) + (Number of Exterior routes)
212 HEADER structure is 12 bytes as follows :
214 4 bits Version (only version 1 is defined)
215 4 bits Opcode (1=Replay, 2=Request)
216 8 bits Update Release
217 16 bits Autonomous system number
218 16 bits Number of Interior routes
219 16 bits Number of System routes
220 16 bits Number of Exterior routes
225 VECTOR structure is 14 bytes as follows :
236 It is interesting how is coded an ip network address in 3 bytes because IGRP is a classful routing protocol:
237 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
238 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
240 If the Delay is 0xFFFFFF then the network is unreachable