2 * Routines for IP and miscellaneous IP protocol packet disassembly
4 * Ethereal - Network traffic analyzer
5 * By Gerald Combs <gerald@zing.org>
6 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
37 #ifdef HAVE_NETINET_IN_H
38 # include <netinet/in.h>
47 dissect_ip(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
49 GtkWidget *ip_tree, *ti;
52 /* To do: check for runts, errs, etc. */
53 /* Avoids alignment problems on many architectures. */
54 memcpy(&iph, &pd[offset], sizeof(e_ip));
55 iph.ip_len = ntohs(iph.ip_len);
56 iph.ip_id = ntohs(iph.ip_id);
57 iph.ip_off = ntohs(iph.ip_off);
58 iph.ip_sum = ntohs(iph.ip_sum);
60 if (fd->win_info[0]) {
67 /* Names are set in the associated dissect_* routines */
70 strcpy(fd->win_info[3], "IP");
71 sprintf(fd->win_info[4], "Unknown IP protocol (%02x)", iph.ip_p);
74 strcpy(fd->win_info[1], get_hostname(iph.ip_src));
75 strcpy(fd->win_info[2], get_hostname(iph.ip_dst));
78 iph.ip_tos = IPTOS_TOS(iph.ip_tos);
81 strcpy(tos_str, "None");
84 strcpy(tos_str, "Minimize delay");
86 case IPTOS_THROUGHPUT:
87 strcpy(tos_str, "Maximize throughput");
89 case IPTOS_RELIABILITY:
90 strcpy(tos_str, "Maximize reliability");
93 strcpy(tos_str, "Minimize cost");
96 strcpy(tos_str, "Unknon. Malformed?");
101 ti = add_item_to_tree(GTK_WIDGET(tree), offset, (iph.ip_hl * 4),
102 "Internet Protocol");
103 ip_tree = gtk_tree_new();
104 add_subtree(ti, ip_tree, ETT_IP);
105 add_item_to_tree(ip_tree, offset, 1, "Version: %d", iph.ip_v);
106 add_item_to_tree(ip_tree, offset, 1, "Header length: %d", iph.ip_hl);
107 add_item_to_tree(ip_tree, offset + 1, 1, "Type of service: 0x%02x (%s)",
108 iph.ip_tos, tos_str);
109 add_item_to_tree(ip_tree, offset + 2, 2, "Total length: %d", iph.ip_len);
110 add_item_to_tree(ip_tree, offset + 4, 2, "Identification: 0x%04x",
112 /* To do: add flags */
113 add_item_to_tree(ip_tree, offset + 6, 2, "Fragment offset: %d",
114 iph.ip_off & 0x1fff);
115 add_item_to_tree(ip_tree, offset + 8, 1, "Time to live: %d",
117 add_item_to_tree(ip_tree, offset + 9, 1, "Protocol: 0x%02x",
119 add_item_to_tree(ip_tree, offset + 10, 2, "Header checksum: 0x%04x",
121 add_item_to_tree(ip_tree, offset + 12, 4, "Source address: %s",
122 get_hostname(iph.ip_src));
123 add_item_to_tree(ip_tree, offset + 16, 4, "Destination address: %s",
124 get_hostname(iph.ip_dst));
127 offset += iph.ip_hl * 4;
130 dissect_icmp(pd, offset, fd, tree);
133 dissect_igmp(pd, offset, fd, tree);
136 dissect_tcp(pd, offset, fd, tree);
139 dissect_udp(pd, offset, fd, tree);
142 dissect_ospf(pd, offset, fd, tree);
148 const gchar *unreach_str[] = {"Network unreachable",
150 "Protocol unreachable",
152 "Fragmentation needed",
153 "Source route failed",
154 "Administratively prohibited",
155 "Network unreachable for TOS",
156 "Host unreachable for TOS",
157 "Communication administratively filtered",
158 "Host precedence violation",
159 "Precedence cutoff in effect"};
161 const gchar *redir_str[] = {"Redirect for network",
163 "Redirect for TOS and network",
164 "Redirect for TOS and host"};
166 const gchar *ttl_str[] = {"TTL equals 0 during transit",
167 "TTL equals 0 during reassembly"};
169 const gchar *par_str[] = {"IP header bad", "Required option missing"};
172 dissect_icmp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
174 GtkWidget *icmp_tree, *ti;
176 gchar type_str[64], code_str[64] = "";
178 ih = (e_icmp *) &pd[offset];
179 /* To do: check for runts, errs, etc. */
180 cksum = ntohs(ih->icmp_cksum);
182 switch (ih->icmp_type) {
184 strcpy(type_str, "Echo (ping) reply");
187 strcpy(type_str, "Destination unreachable");
188 if (ih->icmp_code < 12) {
189 sprintf(code_str, "(%s)", unreach_str[ih->icmp_code]);
191 strcpy(code_str, "(Unknown - error?)");
194 case ICMP_SOURCEQUENCH:
195 strcpy(type_str, "Source quench (flow control)");
198 strcpy(type_str, "Redirect");
199 if (ih->icmp_code < 4) {
200 sprintf(code_str, "(%s)", redir_str[ih->icmp_code]);
202 strcpy(code_str, "(Unknown - error?)");
206 strcpy(type_str, "Echo (ping) request");
209 strcpy(type_str, "Time-to-live exceeded");
210 if (ih->icmp_code < 2) {
211 sprintf(code_str, "(%s)", ttl_str[ih->icmp_code]);
213 strcpy(code_str, "(Unknown - error?)");
217 strcpy(type_str, "Parameter problem");
218 if (ih->icmp_code < 2) {
219 sprintf(code_str, "(%s)", par_str[ih->icmp_code]);
221 strcpy(code_str, "(Unknown - error?)");
225 strcpy(type_str, "Timestamp request");
227 case ICMP_TSTAMPREPLY:
228 strcpy(type_str, "Timestamp reply");
231 strcpy(type_str, "Address mask request");
234 strcpy(type_str, "Address mask reply");
237 strcpy(type_str, "Unknown ICMP (obsolete or malformed?)");
240 if (fd->win_info[0]) {
241 strcpy(fd->win_info[3], "ICMP");
242 strcpy(fd->win_info[4], type_str);
246 ti = add_item_to_tree(GTK_WIDGET(tree), offset, 4,
247 "Internet Control Message Protocol");
248 icmp_tree = gtk_tree_new();
249 add_subtree(ti, icmp_tree, ETT_ICMP);
250 add_item_to_tree(icmp_tree, offset, 1, "Type: %d (%s)",
251 ih->icmp_type, type_str);
252 add_item_to_tree(icmp_tree, offset + 1, 1, "Code: %d %s",
253 ih->icmp_code, code_str);
254 add_item_to_tree(icmp_tree, offset + 2, 2, "Checksum: 0x%04x",
260 dissect_igmp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
262 GtkWidget *igmp_tree, *ti;
264 gchar type_str[64] = "";
266 ih = (e_igmp *) &pd[offset];
267 /* To do: check for runts, errs, etc. */
268 cksum = ntohs(ih->igmp_cksum);
270 switch (ih->igmp_t) {
272 strcpy(type_str, "Router query");
275 strcpy(type_str, "Host response (v1)");
278 strcpy(type_str, "Leave group (v2)");
281 strcpy(type_str, "DVMRP");
284 strcpy(type_str, "PIM");
287 strcpy(type_str, "Host reponse (v2)");
290 strcpy(type_str, "Traceroute response");
293 strcpy(type_str, "Traceroute message");
296 strcpy(type_str, "Unknown IGMP");
299 if (fd->win_info[0]) {
300 strcpy(fd->win_info[3], "IGMP");
304 ti = add_item_to_tree(GTK_WIDGET(tree), offset, 4,
305 "Internet Group Management Protocol");
306 igmp_tree = gtk_tree_new();
307 add_subtree(ti, igmp_tree, ETT_IGMP);
308 add_item_to_tree(igmp_tree, offset, 1, "Version: %d",
310 add_item_to_tree(igmp_tree, offset , 1, "Type: %d (%s)",
311 ih->igmp_t, type_str);
312 add_item_to_tree(igmp_tree, offset + 1, 1, "Unused: 0x%02x",
314 add_item_to_tree(igmp_tree, offset + 2, 2, "Checksum: 0x%04x",
316 add_item_to_tree(igmp_tree, offset + 4, 4, "Group address: %s",
317 ip_to_str((guint8 *) &ih->igmp_gaddr));