1/* 2 * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 *
| 1/* 2 * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 *
|
21 * $FreeBSD: head/contrib/tcpdump/print-icmp.c 111729 2003-03-02 08:25:48Z fenner $
| 21 * $FreeBSD: head/contrib/tcpdump/print-icmp.c 127675 2004-03-31 14:57:24Z bms $
|
22 */ 23 24#ifndef lint
| 22 */ 23 24#ifndef lint
|
25static const char rcsid[] = 26 "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.62.4.1 2002/06/01 23:51:13 guy Exp $ (LBL)";
| 25static const char rcsid[] _U_ = 26 "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.73.2.3 2004/03/24 00:56:34 guy Exp $ (LBL)";
|
27#endif 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32
| 27#endif 28 29#ifdef HAVE_CONFIG_H 30#include "config.h" 31#endif 32
|
33#include <sys/param.h> 34#include <sys/time.h> 35#include <sys/socket.h>
| 33#include <tcpdump-stdinc.h>
|
36
| 34
|
37#include <netinet/in.h> 38
| |
39#include <stdio.h> 40#include <string.h>
| 35#include <stdio.h> 36#include <string.h>
|
41#include <netdb.h> /* for MAXHOSTNAMELEN on some platforms */
| |
42 43#include "interface.h" 44#include "addrtoname.h" 45#include "extract.h" /* must come after interface.h */ 46 47#include "ip.h" 48#include "udp.h"
| 37 38#include "interface.h" 39#include "addrtoname.h" 40#include "extract.h" /* must come after interface.h */ 41 42#include "ip.h" 43#include "udp.h"
|
| 44#include "ipproto.h"
|
49 50/* 51 * Interface Control Message Protocol Definitions. 52 * Per RFC 792, September 1981. 53 */ 54 55/* 56 * Structure of an icmp header. 57 */ 58struct icmp { 59 u_int8_t icmp_type; /* type of message, see below */ 60 u_int8_t icmp_code; /* type sub code */ 61 u_int16_t icmp_cksum; /* ones complement cksum of struct */ 62 union { 63 u_int8_t ih_pptr; /* ICMP_PARAMPROB */ 64 struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ 65 struct ih_idseq { 66 u_int16_t icd_id; 67 u_int16_t icd_seq; 68 } ih_idseq; 69 u_int32_t ih_void; 70 71 /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ 72 struct ih_pmtu {
| 45 46/* 47 * Interface Control Message Protocol Definitions. 48 * Per RFC 792, September 1981. 49 */ 50 51/* 52 * Structure of an icmp header. 53 */ 54struct icmp { 55 u_int8_t icmp_type; /* type of message, see below */ 56 u_int8_t icmp_code; /* type sub code */ 57 u_int16_t icmp_cksum; /* ones complement cksum of struct */ 58 union { 59 u_int8_t ih_pptr; /* ICMP_PARAMPROB */ 60 struct in_addr ih_gwaddr; /* ICMP_REDIRECT */ 61 struct ih_idseq { 62 u_int16_t icd_id; 63 u_int16_t icd_seq; 64 } ih_idseq; 65 u_int32_t ih_void; 66 67 /* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */ 68 struct ih_pmtu {
|
73 u_int16_t ipm_void;
| 69 u_int16_t ipm_void;
|
74 u_int16_t ipm_nextmtu; 75 } ih_pmtu; 76 } icmp_hun; 77#define icmp_pptr icmp_hun.ih_pptr 78#define icmp_gwaddr icmp_hun.ih_gwaddr 79#define icmp_id icmp_hun.ih_idseq.icd_id 80#define icmp_seq icmp_hun.ih_idseq.icd_seq 81#define icmp_void icmp_hun.ih_void 82#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void 83#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu 84 union { 85 struct id_ts { 86 u_int32_t its_otime; 87 u_int32_t its_rtime; 88 u_int32_t its_ttime; 89 } id_ts; 90 struct id_ip { 91 struct ip idi_ip; 92 /* options and then 64 bits of data */ 93 } id_ip; 94 u_int32_t id_mask; 95 u_int8_t id_data[1]; 96 } icmp_dun; 97#define icmp_otime icmp_dun.id_ts.its_otime 98#define icmp_rtime icmp_dun.id_ts.its_rtime 99#define icmp_ttime icmp_dun.id_ts.its_ttime 100#define icmp_ip icmp_dun.id_ip.idi_ip 101#define icmp_mask icmp_dun.id_mask 102#define icmp_data icmp_dun.id_data 103}; 104 105/* 106 * Lower bounds on packet lengths for various types. 107 * For the error advice packets must first insure that the 108 * packet is large enought to contain the returned ip header. 109 * Only then can we do the check to see if 64 bits of packet 110 * data have been returned, since we need to check the returned 111 * ip header length. 112 */ 113#define ICMP_MINLEN 8 /* abs minimum */ 114#define ICMP_TSLEN (8 + 3 * sizeof (u_int32_t)) /* timestamp */ 115#define ICMP_MASKLEN 12 /* address mask */ 116#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ 117#define ICMP_ADVLEN(p) (8 + (IP_HL(&(p)->icmp_ip) << 2) + 8) 118 /* N.B.: must separately check that ip_hl >= 5 */ 119 120/* 121 * Definition of type and code field values. 122 */ 123#define ICMP_ECHOREPLY 0 /* echo reply */ 124#define ICMP_UNREACH 3 /* dest unreachable, codes: */ 125#define ICMP_UNREACH_NET 0 /* bad net */ 126#define ICMP_UNREACH_HOST 1 /* bad host */ 127#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ 128#define ICMP_UNREACH_PORT 3 /* bad port */ 129#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ 130#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ 131#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ 132#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ 133#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ 134#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ 135#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ 136#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ 137#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ 138#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ 139#define ICMP_REDIRECT 5 /* shorter route, codes: */ 140#define ICMP_REDIRECT_NET 0 /* for network */ 141#define ICMP_REDIRECT_HOST 1 /* for host */ 142#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ 143#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ 144#define ICMP_ECHO 8 /* echo service */ 145#define ICMP_ROUTERADVERT 9 /* router advertisement */ 146#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ 147#define ICMP_TIMXCEED 11 /* time exceeded, code: */ 148#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ 149#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ 150#define ICMP_PARAMPROB 12 /* ip header bad */ 151#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ 152#define ICMP_TSTAMP 13 /* timestamp request */ 153#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ 154#define ICMP_IREQ 15 /* information request */ 155#define ICMP_IREQREPLY 16 /* information reply */ 156#define ICMP_MASKREQ 17 /* address mask request */ 157#define ICMP_MASKREPLY 18 /* address mask reply */ 158 159#define ICMP_MAXTYPE 18 160 161#define ICMP_INFOTYPE(type) \ 162 ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ 163 (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ 164 (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ 165 (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ 166 (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) 167/* rfc1700 */ 168#ifndef ICMP_UNREACH_NET_UNKNOWN 169#define ICMP_UNREACH_NET_UNKNOWN 6 /* destination net unknown */ 170#endif 171#ifndef ICMP_UNREACH_HOST_UNKNOWN 172#define ICMP_UNREACH_HOST_UNKNOWN 7 /* destination host unknown */ 173#endif 174#ifndef ICMP_UNREACH_ISOLATED 175#define ICMP_UNREACH_ISOLATED 8 /* source host isolated */ 176#endif 177#ifndef ICMP_UNREACH_NET_PROHIB 178#define ICMP_UNREACH_NET_PROHIB 9 /* admin prohibited net */ 179#endif 180#ifndef ICMP_UNREACH_HOST_PROHIB 181#define ICMP_UNREACH_HOST_PROHIB 10 /* admin prohibited host */ 182#endif 183#ifndef ICMP_UNREACH_TOSNET 184#define ICMP_UNREACH_TOSNET 11 /* tos prohibited net */ 185#endif 186#ifndef ICMP_UNREACH_TOSHOST 187#define ICMP_UNREACH_TOSHOST 12 /* tos prohibited host */ 188#endif 189 190/* rfc1716 */ 191#ifndef ICMP_UNREACH_FILTER_PROHIB 192#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */ 193#endif 194#ifndef ICMP_UNREACH_HOST_PRECEDENCE 195#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host precedence violation */ 196#endif 197#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF 198#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */ 199#endif 200 201/* Most of the icmp types */ 202static struct tok icmp2str[] = { 203 { ICMP_ECHOREPLY, "echo reply" }, 204 { ICMP_SOURCEQUENCH, "source quench" }, 205 { ICMP_ECHO, "echo request" }, 206 { ICMP_ROUTERSOLICIT, "router solicitation" }, 207 { ICMP_TSTAMP, "time stamp request" }, 208 { ICMP_TSTAMPREPLY, "time stamp reply" }, 209 { ICMP_IREQ, "information request" }, 210 { ICMP_IREQREPLY, "information reply" }, 211 { ICMP_MASKREQ, "address mask request" }, 212 { 0, NULL } 213}; 214 215/* Formats for most of the ICMP_UNREACH codes */ 216static struct tok unreach2str[] = { 217 { ICMP_UNREACH_NET, "net %s unreachable" }, 218 { ICMP_UNREACH_HOST, "host %s unreachable" }, 219 { ICMP_UNREACH_SRCFAIL, 220 "%s unreachable - source route failed" }, 221 { ICMP_UNREACH_NET_UNKNOWN, "net %s unreachable - unknown" }, 222 { ICMP_UNREACH_HOST_UNKNOWN, "host %s unreachable - unknown" }, 223 { ICMP_UNREACH_ISOLATED, 224 "%s unreachable - source host isolated" }, 225 { ICMP_UNREACH_NET_PROHIB, 226 "net %s unreachable - admin prohibited" }, 227 { ICMP_UNREACH_HOST_PROHIB, 228 "host %s unreachable - admin prohibited" }, 229 { ICMP_UNREACH_TOSNET, 230 "net %s unreachable - tos prohibited" }, 231 { ICMP_UNREACH_TOSHOST, 232 "host %s unreachable - tos prohibited" }, 233 { ICMP_UNREACH_FILTER_PROHIB, 234 "host %s unreachable - admin prohibited filter" }, 235 { ICMP_UNREACH_HOST_PRECEDENCE, 236 "host %s unreachable - host precedence violation" }, 237 { ICMP_UNREACH_PRECEDENCE_CUTOFF, 238 "host %s unreachable - precedence cutoff" }, 239 { 0, NULL } 240}; 241 242/* Formats for the ICMP_REDIRECT codes */ 243static struct tok type2str[] = { 244 { ICMP_REDIRECT_NET, "redirect %s to net %s" }, 245 { ICMP_REDIRECT_HOST, "redirect %s to host %s" }, 246 { ICMP_REDIRECT_TOSNET, "redirect-tos %s to net %s" }, 247 { ICMP_REDIRECT_TOSHOST, "redirect-tos %s to host %s" }, 248 { 0, NULL } 249}; 250 251/* rfc1191 */ 252struct mtu_discovery { 253 u_int16_t unused; 254 u_int16_t nexthopmtu; 255}; 256 257/* rfc1256 */ 258struct ih_rdiscovery { 259 u_int8_t ird_addrnum; 260 u_int8_t ird_addrsiz; 261 u_int16_t ird_lifetime; 262}; 263 264struct id_rdiscovery { 265 u_int32_t ird_addr; 266 u_int32_t ird_pref; 267}; 268 269void
| 70 u_int16_t ipm_nextmtu; 71 } ih_pmtu; 72 } icmp_hun; 73#define icmp_pptr icmp_hun.ih_pptr 74#define icmp_gwaddr icmp_hun.ih_gwaddr 75#define icmp_id icmp_hun.ih_idseq.icd_id 76#define icmp_seq icmp_hun.ih_idseq.icd_seq 77#define icmp_void icmp_hun.ih_void 78#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void 79#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu 80 union { 81 struct id_ts { 82 u_int32_t its_otime; 83 u_int32_t its_rtime; 84 u_int32_t its_ttime; 85 } id_ts; 86 struct id_ip { 87 struct ip idi_ip; 88 /* options and then 64 bits of data */ 89 } id_ip; 90 u_int32_t id_mask; 91 u_int8_t id_data[1]; 92 } icmp_dun; 93#define icmp_otime icmp_dun.id_ts.its_otime 94#define icmp_rtime icmp_dun.id_ts.its_rtime 95#define icmp_ttime icmp_dun.id_ts.its_ttime 96#define icmp_ip icmp_dun.id_ip.idi_ip 97#define icmp_mask icmp_dun.id_mask 98#define icmp_data icmp_dun.id_data 99}; 100 101/* 102 * Lower bounds on packet lengths for various types. 103 * For the error advice packets must first insure that the 104 * packet is large enought to contain the returned ip header. 105 * Only then can we do the check to see if 64 bits of packet 106 * data have been returned, since we need to check the returned 107 * ip header length. 108 */ 109#define ICMP_MINLEN 8 /* abs minimum */ 110#define ICMP_TSLEN (8 + 3 * sizeof (u_int32_t)) /* timestamp */ 111#define ICMP_MASKLEN 12 /* address mask */ 112#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */ 113#define ICMP_ADVLEN(p) (8 + (IP_HL(&(p)->icmp_ip) << 2) + 8) 114 /* N.B.: must separately check that ip_hl >= 5 */ 115 116/* 117 * Definition of type and code field values. 118 */ 119#define ICMP_ECHOREPLY 0 /* echo reply */ 120#define ICMP_UNREACH 3 /* dest unreachable, codes: */ 121#define ICMP_UNREACH_NET 0 /* bad net */ 122#define ICMP_UNREACH_HOST 1 /* bad host */ 123#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */ 124#define ICMP_UNREACH_PORT 3 /* bad port */ 125#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */ 126#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */ 127#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */ 128#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */ 129#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */ 130#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */ 131#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */ 132#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */ 133#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */ 134#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */ 135#define ICMP_REDIRECT 5 /* shorter route, codes: */ 136#define ICMP_REDIRECT_NET 0 /* for network */ 137#define ICMP_REDIRECT_HOST 1 /* for host */ 138#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */ 139#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */ 140#define ICMP_ECHO 8 /* echo service */ 141#define ICMP_ROUTERADVERT 9 /* router advertisement */ 142#define ICMP_ROUTERSOLICIT 10 /* router solicitation */ 143#define ICMP_TIMXCEED 11 /* time exceeded, code: */ 144#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */ 145#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */ 146#define ICMP_PARAMPROB 12 /* ip header bad */ 147#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */ 148#define ICMP_TSTAMP 13 /* timestamp request */ 149#define ICMP_TSTAMPREPLY 14 /* timestamp reply */ 150#define ICMP_IREQ 15 /* information request */ 151#define ICMP_IREQREPLY 16 /* information reply */ 152#define ICMP_MASKREQ 17 /* address mask request */ 153#define ICMP_MASKREPLY 18 /* address mask reply */ 154 155#define ICMP_MAXTYPE 18 156 157#define ICMP_INFOTYPE(type) \ 158 ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \ 159 (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \ 160 (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \ 161 (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \ 162 (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) 163/* rfc1700 */ 164#ifndef ICMP_UNREACH_NET_UNKNOWN 165#define ICMP_UNREACH_NET_UNKNOWN 6 /* destination net unknown */ 166#endif 167#ifndef ICMP_UNREACH_HOST_UNKNOWN 168#define ICMP_UNREACH_HOST_UNKNOWN 7 /* destination host unknown */ 169#endif 170#ifndef ICMP_UNREACH_ISOLATED 171#define ICMP_UNREACH_ISOLATED 8 /* source host isolated */ 172#endif 173#ifndef ICMP_UNREACH_NET_PROHIB 174#define ICMP_UNREACH_NET_PROHIB 9 /* admin prohibited net */ 175#endif 176#ifndef ICMP_UNREACH_HOST_PROHIB 177#define ICMP_UNREACH_HOST_PROHIB 10 /* admin prohibited host */ 178#endif 179#ifndef ICMP_UNREACH_TOSNET 180#define ICMP_UNREACH_TOSNET 11 /* tos prohibited net */ 181#endif 182#ifndef ICMP_UNREACH_TOSHOST 183#define ICMP_UNREACH_TOSHOST 12 /* tos prohibited host */ 184#endif 185 186/* rfc1716 */ 187#ifndef ICMP_UNREACH_FILTER_PROHIB 188#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */ 189#endif 190#ifndef ICMP_UNREACH_HOST_PRECEDENCE 191#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host precedence violation */ 192#endif 193#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF 194#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */ 195#endif 196 197/* Most of the icmp types */ 198static struct tok icmp2str[] = { 199 { ICMP_ECHOREPLY, "echo reply" }, 200 { ICMP_SOURCEQUENCH, "source quench" }, 201 { ICMP_ECHO, "echo request" }, 202 { ICMP_ROUTERSOLICIT, "router solicitation" }, 203 { ICMP_TSTAMP, "time stamp request" }, 204 { ICMP_TSTAMPREPLY, "time stamp reply" }, 205 { ICMP_IREQ, "information request" }, 206 { ICMP_IREQREPLY, "information reply" }, 207 { ICMP_MASKREQ, "address mask request" }, 208 { 0, NULL } 209}; 210 211/* Formats for most of the ICMP_UNREACH codes */ 212static struct tok unreach2str[] = { 213 { ICMP_UNREACH_NET, "net %s unreachable" }, 214 { ICMP_UNREACH_HOST, "host %s unreachable" }, 215 { ICMP_UNREACH_SRCFAIL, 216 "%s unreachable - source route failed" }, 217 { ICMP_UNREACH_NET_UNKNOWN, "net %s unreachable - unknown" }, 218 { ICMP_UNREACH_HOST_UNKNOWN, "host %s unreachable - unknown" }, 219 { ICMP_UNREACH_ISOLATED, 220 "%s unreachable - source host isolated" }, 221 { ICMP_UNREACH_NET_PROHIB, 222 "net %s unreachable - admin prohibited" }, 223 { ICMP_UNREACH_HOST_PROHIB, 224 "host %s unreachable - admin prohibited" }, 225 { ICMP_UNREACH_TOSNET, 226 "net %s unreachable - tos prohibited" }, 227 { ICMP_UNREACH_TOSHOST, 228 "host %s unreachable - tos prohibited" }, 229 { ICMP_UNREACH_FILTER_PROHIB, 230 "host %s unreachable - admin prohibited filter" }, 231 { ICMP_UNREACH_HOST_PRECEDENCE, 232 "host %s unreachable - host precedence violation" }, 233 { ICMP_UNREACH_PRECEDENCE_CUTOFF, 234 "host %s unreachable - precedence cutoff" }, 235 { 0, NULL } 236}; 237 238/* Formats for the ICMP_REDIRECT codes */ 239static struct tok type2str[] = { 240 { ICMP_REDIRECT_NET, "redirect %s to net %s" }, 241 { ICMP_REDIRECT_HOST, "redirect %s to host %s" }, 242 { ICMP_REDIRECT_TOSNET, "redirect-tos %s to net %s" }, 243 { ICMP_REDIRECT_TOSHOST, "redirect-tos %s to host %s" }, 244 { 0, NULL } 245}; 246 247/* rfc1191 */ 248struct mtu_discovery { 249 u_int16_t unused; 250 u_int16_t nexthopmtu; 251}; 252 253/* rfc1256 */ 254struct ih_rdiscovery { 255 u_int8_t ird_addrnum; 256 u_int8_t ird_addrsiz; 257 u_int16_t ird_lifetime; 258}; 259 260struct id_rdiscovery { 261 u_int32_t ird_addr; 262 u_int32_t ird_pref; 263}; 264 265void
|
270icmp_print(const u_char *bp, u_int plen, const u_char *bp2)
| 266icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented)
|
271{ 272 char *cp; 273 const struct icmp *dp; 274 const struct ip *ip; 275 const char *str, *fmt; 276 const struct ip *oip; 277 const struct udphdr *ouh; 278 u_int hlen, dport, mtu; 279 char buf[MAXHOSTNAMELEN + 100]; 280 281 dp = (struct icmp *)bp; 282 ip = (struct ip *)bp2; 283 str = buf; 284 285 TCHECK(dp->icmp_code); 286 switch (dp->icmp_type) { 287
| 267{ 268 char *cp; 269 const struct icmp *dp; 270 const struct ip *ip; 271 const char *str, *fmt; 272 const struct ip *oip; 273 const struct udphdr *ouh; 274 u_int hlen, dport, mtu; 275 char buf[MAXHOSTNAMELEN + 100]; 276 277 dp = (struct icmp *)bp; 278 ip = (struct ip *)bp2; 279 str = buf; 280 281 TCHECK(dp->icmp_code); 282 switch (dp->icmp_type) { 283
|
| 284 case ICMP_ECHO: 285 case ICMP_ECHOREPLY: 286 TCHECK(dp->icmp_seq); 287 (void)snprintf(buf, sizeof(buf), "echo %s seq %u", 288 dp->icmp_type == ICMP_ECHO ? 289 "request" : "reply", 290 EXTRACT_16BITS(&dp->icmp_seq)); 291 break; 292
|
288 case ICMP_UNREACH: 289 TCHECK(dp->icmp_ip.ip_dst); 290 switch (dp->icmp_code) { 291 292 case ICMP_UNREACH_PROTOCOL: 293 TCHECK(dp->icmp_ip.ip_p); 294 (void)snprintf(buf, sizeof(buf), 295 "%s protocol %d unreachable", 296 ipaddr_string(&dp->icmp_ip.ip_dst), 297 dp->icmp_ip.ip_p); 298 break; 299 300 case ICMP_UNREACH_PORT: 301 TCHECK(dp->icmp_ip.ip_p); 302 oip = &dp->icmp_ip; 303 hlen = IP_HL(oip) * 4; 304 ouh = (struct udphdr *)(((u_char *)oip) + hlen);
| 293 case ICMP_UNREACH: 294 TCHECK(dp->icmp_ip.ip_dst); 295 switch (dp->icmp_code) { 296 297 case ICMP_UNREACH_PROTOCOL: 298 TCHECK(dp->icmp_ip.ip_p); 299 (void)snprintf(buf, sizeof(buf), 300 "%s protocol %d unreachable", 301 ipaddr_string(&dp->icmp_ip.ip_dst), 302 dp->icmp_ip.ip_p); 303 break; 304 305 case ICMP_UNREACH_PORT: 306 TCHECK(dp->icmp_ip.ip_p); 307 oip = &dp->icmp_ip; 308 hlen = IP_HL(oip) * 4; 309 ouh = (struct udphdr *)(((u_char *)oip) + hlen);
|
305 dport = ntohs(ouh->uh_dport);
| 310 TCHECK(ouh->uh_dport); 311 dport = EXTRACT_16BITS(&ouh->uh_dport);
|
306 switch (oip->ip_p) { 307 308 case IPPROTO_TCP: 309 (void)snprintf(buf, sizeof(buf), 310 "%s tcp port %s unreachable", 311 ipaddr_string(&oip->ip_dst), 312 tcpport_string(dport)); 313 break; 314 315 case IPPROTO_UDP: 316 (void)snprintf(buf, sizeof(buf), 317 "%s udp port %s unreachable", 318 ipaddr_string(&oip->ip_dst), 319 udpport_string(dport)); 320 break; 321 322 default: 323 (void)snprintf(buf, sizeof(buf), 324 "%s protocol %d port %d unreachable", 325 ipaddr_string(&oip->ip_dst), 326 oip->ip_p, dport); 327 break; 328 } 329 break; 330 331 case ICMP_UNREACH_NEEDFRAG: 332 { 333 register const struct mtu_discovery *mp; 334 mp = (struct mtu_discovery *)&dp->icmp_void; 335 mtu = EXTRACT_16BITS(&mp->nexthopmtu); 336 if (mtu) { 337 (void)snprintf(buf, sizeof(buf), 338 "%s unreachable - need to frag (mtu %d)", 339 ipaddr_string(&dp->icmp_ip.ip_dst), mtu); 340 } else { 341 (void)snprintf(buf, sizeof(buf), 342 "%s unreachable - need to frag", 343 ipaddr_string(&dp->icmp_ip.ip_dst)); 344 } 345 } 346 break; 347 348 default: 349 fmt = tok2str(unreach2str, "#%d %%s unreachable", 350 dp->icmp_code); 351 (void)snprintf(buf, sizeof(buf), fmt, 352 ipaddr_string(&dp->icmp_ip.ip_dst)); 353 break; 354 } 355 break; 356 357 case ICMP_REDIRECT: 358 TCHECK(dp->icmp_ip.ip_dst); 359 fmt = tok2str(type2str, "redirect-#%d %%s to net %%s", 360 dp->icmp_code); 361 (void)snprintf(buf, sizeof(buf), fmt, 362 ipaddr_string(&dp->icmp_ip.ip_dst), 363 ipaddr_string(&dp->icmp_gwaddr)); 364 break; 365 366 case ICMP_ROUTERADVERT: 367 { 368 register const struct ih_rdiscovery *ihp; 369 register const struct id_rdiscovery *idp; 370 u_int lifetime, num, size; 371 372 (void)snprintf(buf, sizeof(buf), "router advertisement"); 373 cp = buf + strlen(buf); 374 375 ihp = (struct ih_rdiscovery *)&dp->icmp_void; 376 TCHECK(*ihp); 377 (void)strncpy(cp, " lifetime ", sizeof(buf) - (cp - buf)); 378 cp = buf + strlen(buf); 379 lifetime = EXTRACT_16BITS(&ihp->ird_lifetime); 380 if (lifetime < 60) { 381 (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u", 382 lifetime); 383 } else if (lifetime < 60 * 60) { 384 (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u:%02u", 385 lifetime / 60, lifetime % 60); 386 } else { 387 (void)snprintf(cp, sizeof(buf) - (cp - buf), 388 "%u:%02u:%02u", 389 lifetime / 3600, 390 (lifetime % 3600) / 60, 391 lifetime % 60); 392 } 393 cp = buf + strlen(buf); 394 395 num = ihp->ird_addrnum; 396 (void)snprintf(cp, sizeof(buf) - (cp - buf), " %d:", num); 397 cp = buf + strlen(buf); 398 399 size = ihp->ird_addrsiz; 400 if (size != 2) { 401 (void)snprintf(cp, sizeof(buf) - (cp - buf), 402 " [size %d]", size); 403 break; 404 } 405 idp = (struct id_rdiscovery *)&dp->icmp_data; 406 while (num-- > 0) { 407 TCHECK(*idp); 408 (void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}", 409 ipaddr_string(&idp->ird_addr), 410 EXTRACT_32BITS(&idp->ird_pref)); 411 cp = buf + strlen(buf); 412 ++idp; 413 } 414 } 415 break; 416 417 case ICMP_TIMXCEED: 418 TCHECK(dp->icmp_ip.ip_dst); 419 switch (dp->icmp_code) { 420 421 case ICMP_TIMXCEED_INTRANS: 422 str = "time exceeded in-transit"; 423 break; 424 425 case ICMP_TIMXCEED_REASS: 426 str = "ip reassembly time exceeded"; 427 break; 428 429 default: 430 (void)snprintf(buf, sizeof(buf), "time exceeded-#%d", 431 dp->icmp_code); 432 break; 433 } 434 break; 435 436 case ICMP_PARAMPROB: 437 if (dp->icmp_code) 438 (void)snprintf(buf, sizeof(buf), 439 "parameter problem - code %d", dp->icmp_code); 440 else { 441 TCHECK(dp->icmp_pptr); 442 (void)snprintf(buf, sizeof(buf), 443 "parameter problem - octet %d", dp->icmp_pptr); 444 } 445 break; 446 447 case ICMP_MASKREPLY: 448 TCHECK(dp->icmp_mask); 449 (void)snprintf(buf, sizeof(buf), "address mask is 0x%08x",
| 312 switch (oip->ip_p) { 313 314 case IPPROTO_TCP: 315 (void)snprintf(buf, sizeof(buf), 316 "%s tcp port %s unreachable", 317 ipaddr_string(&oip->ip_dst), 318 tcpport_string(dport)); 319 break; 320 321 case IPPROTO_UDP: 322 (void)snprintf(buf, sizeof(buf), 323 "%s udp port %s unreachable", 324 ipaddr_string(&oip->ip_dst), 325 udpport_string(dport)); 326 break; 327 328 default: 329 (void)snprintf(buf, sizeof(buf), 330 "%s protocol %d port %d unreachable", 331 ipaddr_string(&oip->ip_dst), 332 oip->ip_p, dport); 333 break; 334 } 335 break; 336 337 case ICMP_UNREACH_NEEDFRAG: 338 { 339 register const struct mtu_discovery *mp; 340 mp = (struct mtu_discovery *)&dp->icmp_void; 341 mtu = EXTRACT_16BITS(&mp->nexthopmtu); 342 if (mtu) { 343 (void)snprintf(buf, sizeof(buf), 344 "%s unreachable - need to frag (mtu %d)", 345 ipaddr_string(&dp->icmp_ip.ip_dst), mtu); 346 } else { 347 (void)snprintf(buf, sizeof(buf), 348 "%s unreachable - need to frag", 349 ipaddr_string(&dp->icmp_ip.ip_dst)); 350 } 351 } 352 break; 353 354 default: 355 fmt = tok2str(unreach2str, "#%d %%s unreachable", 356 dp->icmp_code); 357 (void)snprintf(buf, sizeof(buf), fmt, 358 ipaddr_string(&dp->icmp_ip.ip_dst)); 359 break; 360 } 361 break; 362 363 case ICMP_REDIRECT: 364 TCHECK(dp->icmp_ip.ip_dst); 365 fmt = tok2str(type2str, "redirect-#%d %%s to net %%s", 366 dp->icmp_code); 367 (void)snprintf(buf, sizeof(buf), fmt, 368 ipaddr_string(&dp->icmp_ip.ip_dst), 369 ipaddr_string(&dp->icmp_gwaddr)); 370 break; 371 372 case ICMP_ROUTERADVERT: 373 { 374 register const struct ih_rdiscovery *ihp; 375 register const struct id_rdiscovery *idp; 376 u_int lifetime, num, size; 377 378 (void)snprintf(buf, sizeof(buf), "router advertisement"); 379 cp = buf + strlen(buf); 380 381 ihp = (struct ih_rdiscovery *)&dp->icmp_void; 382 TCHECK(*ihp); 383 (void)strncpy(cp, " lifetime ", sizeof(buf) - (cp - buf)); 384 cp = buf + strlen(buf); 385 lifetime = EXTRACT_16BITS(&ihp->ird_lifetime); 386 if (lifetime < 60) { 387 (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u", 388 lifetime); 389 } else if (lifetime < 60 * 60) { 390 (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u:%02u", 391 lifetime / 60, lifetime % 60); 392 } else { 393 (void)snprintf(cp, sizeof(buf) - (cp - buf), 394 "%u:%02u:%02u", 395 lifetime / 3600, 396 (lifetime % 3600) / 60, 397 lifetime % 60); 398 } 399 cp = buf + strlen(buf); 400 401 num = ihp->ird_addrnum; 402 (void)snprintf(cp, sizeof(buf) - (cp - buf), " %d:", num); 403 cp = buf + strlen(buf); 404 405 size = ihp->ird_addrsiz; 406 if (size != 2) { 407 (void)snprintf(cp, sizeof(buf) - (cp - buf), 408 " [size %d]", size); 409 break; 410 } 411 idp = (struct id_rdiscovery *)&dp->icmp_data; 412 while (num-- > 0) { 413 TCHECK(*idp); 414 (void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}", 415 ipaddr_string(&idp->ird_addr), 416 EXTRACT_32BITS(&idp->ird_pref)); 417 cp = buf + strlen(buf); 418 ++idp; 419 } 420 } 421 break; 422 423 case ICMP_TIMXCEED: 424 TCHECK(dp->icmp_ip.ip_dst); 425 switch (dp->icmp_code) { 426 427 case ICMP_TIMXCEED_INTRANS: 428 str = "time exceeded in-transit"; 429 break; 430 431 case ICMP_TIMXCEED_REASS: 432 str = "ip reassembly time exceeded"; 433 break; 434 435 default: 436 (void)snprintf(buf, sizeof(buf), "time exceeded-#%d", 437 dp->icmp_code); 438 break; 439 } 440 break; 441 442 case ICMP_PARAMPROB: 443 if (dp->icmp_code) 444 (void)snprintf(buf, sizeof(buf), 445 "parameter problem - code %d", dp->icmp_code); 446 else { 447 TCHECK(dp->icmp_pptr); 448 (void)snprintf(buf, sizeof(buf), 449 "parameter problem - octet %d", dp->icmp_pptr); 450 } 451 break; 452 453 case ICMP_MASKREPLY: 454 TCHECK(dp->icmp_mask); 455 (void)snprintf(buf, sizeof(buf), "address mask is 0x%08x",
|
450 (unsigned)ntohl(dp->icmp_mask));
| 456 EXTRACT_32BITS(&dp->icmp_mask));
|
451 break; 452 453 case ICMP_TSTAMP: 454 TCHECK(dp->icmp_seq); 455 (void)snprintf(buf, sizeof(buf), 456 "time stamp query id %u seq %u",
| 457 break; 458 459 case ICMP_TSTAMP: 460 TCHECK(dp->icmp_seq); 461 (void)snprintf(buf, sizeof(buf), 462 "time stamp query id %u seq %u",
|
457 (unsigned)ntohs(dp->icmp_id), 458 (unsigned)ntohs(dp->icmp_seq));
| 463 EXTRACT_16BITS(&dp->icmp_id), 464 EXTRACT_16BITS(&dp->icmp_seq));
|
459 break; 460 461 case ICMP_TSTAMPREPLY: 462 TCHECK(dp->icmp_ttime); 463 (void)snprintf(buf, sizeof(buf),
| 465 break; 466 467 case ICMP_TSTAMPREPLY: 468 TCHECK(dp->icmp_ttime); 469 (void)snprintf(buf, sizeof(buf),
|
464 "time stamp reply id %u seq %u : org 0x%lx recv 0x%lx xmit 0x%lx", 465 (unsigned)ntohs(dp->icmp_id), 466 (unsigned)ntohs(dp->icmp_seq), 467 (unsigned long)ntohl(dp->icmp_otime), 468 (unsigned long)ntohl(dp->icmp_rtime), 469 (unsigned long)ntohl(dp->icmp_ttime));
| 470 "time stamp reply id %u seq %u : org 0x%x recv 0x%x xmit 0x%x", 471 EXTRACT_16BITS(&dp->icmp_id), 472 EXTRACT_16BITS(&dp->icmp_seq), 473 EXTRACT_32BITS(&dp->icmp_otime), 474 EXTRACT_32BITS(&dp->icmp_rtime), 475 EXTRACT_32BITS(&dp->icmp_ttime));
|
470 break; 471 472 default: 473 str = tok2str(icmp2str, "type-#%d", dp->icmp_type); 474 break; 475 }
| 476 break; 477 478 default: 479 str = tok2str(icmp2str, "type-#%d", dp->icmp_type); 480 break; 481 }
|
476 (void)printf("icmp: %s", str); 477 if (vflag) {
| 482 (void)printf("icmp %d: %s", plen, str); 483 if (vflag && !fragmented) { /* don't attempt checksumming if this is a frag */ 484 u_int16_t sum, icmp_sum;
|
478 if (TTEST2(*bp, plen)) {
| 485 if (TTEST2(*bp, plen)) {
|
479 if (in_cksum((u_short*)dp, plen, 0)) 480 printf(" (wrong icmp csum)");
| 486 sum = in_cksum((u_short*)dp, plen, 0); 487 if (sum != 0) { 488 icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum); 489 (void)printf(" (wrong icmp cksum %x (->%x)!)", 490 icmp_sum, 491 in_cksum_shouldbe(icmp_sum, sum)); 492 }
|
481 } 482 }
| 493 } 494 }
|
483 if (vflag > 1 && !ICMP_INFOTYPE(dp->icmp_type)) { 484 bp += 8; 485 (void)printf(" for "); 486 ip = (struct ip *)bp; 487 snaplen = snapend - bp; 488 ip_print(bp, ntohs(ip->ip_len)); 489 }
| 495 if (vflag > 1 && !ICMP_INFOTYPE(dp->icmp_type)) { 496 bp += 8; 497 (void)printf(" for "); 498 ip = (struct ip *)bp; 499 snaplen = snapend - bp; 500 ip_print(bp, EXTRACT_16BITS(&ip->ip_len)); 501 }
|
490 return; 491trunc: 492 fputs("[|icmp]", stdout); 493}
| 502 return; 503trunc: 504 fputs("[|icmp]", stdout); 505}
|