1 /*
2 * Copyright (c) 1988-1990 The Regents of the University of California.
3 * 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
22 #ifndef lint
23 static char rcsid[] =
24 "@(#) $Header: print-icmp.c,v 1.11 91/03/27 17:42:58 leres Exp $ (LBL)";
25 #endif
26
27 #include <stdio.h>
28
29 #include <sys/param.h>
30 #include <sys/types.h>
31 #include <sys/socket.h>
32 #include <net/if.h>
33 #include <netinet/in.h>
34 #include <netinet/if_ether.h>
35 #include <netinet/in_systm.h>
36 #include <netinet/ip.h>
37 #include <netinet/ip_var.h>
38 #include <netinet/udp.h>
39 #include <netinet/udp_var.h>
40 #include <netinet/tcp.h>
41 #include <netinet/tcpip.h>
42
43 #include <netinet/ip_icmp.h>
44
45 #include "interface.h"
46 #include "addrtoname.h"
47
48 void
icmp_print(dp,ip)49 icmp_print(dp, ip)
50 register struct icmp *dp;
51 register struct ip *ip;
52 {
53 char buf[256];
54 register char *str = buf;
55 register struct ip *oip;
56 register struct udphdr *ouh;
57 register int hlen;
58 u_char *ep;
59
60 #define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc
61
62 /* 'ep' points to the end of avaible data. */
63 ep = (u_char *)snapend;
64
65 (void)printf("%s > %s: ",
66 ipaddr_string(&ip->ip_src),
67 ipaddr_string(&ip->ip_dst));
68 strcpy(str, "[?]");
69
70 TCHECK(dp->icmp_code, sizeof(dp->icmp_code));
71 switch (dp->icmp_type) {
72 case ICMP_ECHOREPLY:
73 str = "echo reply";
74 break;
75 case ICMP_UNREACH:
76 TCHECK(dp->icmp_ip.ip_dst, sizeof(dp->icmp_ip.ip_dst));
77 switch (dp->icmp_code) {
78 case ICMP_UNREACH_NET:
79 (void)sprintf(buf, "net %s unreachable",
80 ipaddr_string(&dp->icmp_ip.ip_dst));
81 break;
82 case ICMP_UNREACH_HOST:
83 (void)sprintf(buf, "host %s unreachable",
84 ipaddr_string(&dp->icmp_ip.ip_dst));
85 break;
86 case ICMP_UNREACH_PROTOCOL:
87 TCHECK(dp->icmp_ip.ip_p, sizeof(dp->icmp_ip.ip_p));
88 (void)sprintf(buf, "%s protocol %d unreachable",
89 ipaddr_string(&dp->icmp_ip.ip_dst),
90 dp->icmp_ip.ip_p);
91 break;
92 case ICMP_UNREACH_PORT:
93 TCHECK(dp->icmp_ip.ip_p, sizeof(dp->icmp_ip.ip_p));
94 oip = &dp->icmp_ip;
95 hlen = oip->ip_hl * 4;
96 ouh = (struct udphdr *)(((u_char *)oip) + hlen);
97 NTOHS(ouh->uh_dport);
98 switch (oip->ip_p) {
99 case IPPROTO_TCP:
100 (void)sprintf(buf,
101 "%s tcp port %s unreachable",
102 ipaddr_string(&oip->ip_dst),
103 tcpport_string(ouh->uh_dport));
104 break;
105 case IPPROTO_UDP:
106 (void)sprintf(buf,
107 "%s udp port %s unreachable",
108 ipaddr_string(&oip->ip_dst),
109 udpport_string(ouh->uh_dport));
110 break;
111 default:
112 (void)sprintf(buf,
113 "%s protocol %d port %d unreachable",
114 ipaddr_string(&oip->ip_dst),
115 oip->ip_p, ouh->uh_dport);
116 break;
117 }
118 break;
119 case ICMP_UNREACH_NEEDFRAG:
120 (void)sprintf(buf, "%s unreachable - need to frag",
121 ipaddr_string(&dp->icmp_ip.ip_dst));
122 break;
123 case ICMP_UNREACH_SRCFAIL:
124 (void)sprintf(buf,
125 "%s unreachable - source route failed",
126 ipaddr_string(&dp->icmp_ip.ip_dst));
127 break;
128 }
129 break;
130 case ICMP_SOURCEQUENCH:
131 str = "source quench";
132 break;
133 case ICMP_REDIRECT:
134 TCHECK(dp->icmp_ip.ip_dst, sizeof(dp->icmp_ip.ip_dst));
135 switch (dp->icmp_code) {
136 case ICMP_REDIRECT_NET:
137 (void)sprintf(buf, "redirect %s to net %s",
138 ipaddr_string(&dp->icmp_ip.ip_dst),
139 ipaddr_string(&dp->icmp_gwaddr));
140 break;
141 case ICMP_REDIRECT_HOST:
142 (void)sprintf(buf, "redirect %s to host %s",
143 ipaddr_string(&dp->icmp_ip.ip_dst),
144 ipaddr_string(&dp->icmp_gwaddr));
145 break;
146 case ICMP_REDIRECT_TOSNET:
147 (void)sprintf(buf, "redirect-tos %s to net %s",
148 ipaddr_string(&dp->icmp_ip.ip_dst),
149 ipaddr_string(&dp->icmp_gwaddr));
150 break;
151 case ICMP_REDIRECT_TOSHOST:
152 (void)sprintf(buf, "redirect-tos %s to host %s",
153 ipaddr_string(&dp->icmp_ip.ip_dst),
154 ipaddr_string(&dp->icmp_gwaddr));
155 break;
156 }
157 break;
158 case ICMP_ECHO:
159 str = "echo request";
160 break;
161 case ICMP_TIMXCEED:
162 TCHECK(dp->icmp_ip.ip_dst, sizeof(dp->icmp_ip.ip_dst));
163 switch (dp->icmp_code) {
164 case ICMP_TIMXCEED_INTRANS:
165 str = "time exceeded in-transit";
166 break;
167 case ICMP_TIMXCEED_REASS:
168 str = "ip reassembly time exceeded";
169 break;
170 }
171 break;
172 case ICMP_PARAMPROB:
173 if (dp->icmp_code)
174 (void)sprintf(buf, "parameter problem - code %d",
175 dp->icmp_code);
176 else {
177 TCHECK(dp->icmp_pptr, sizeof(dp->icmp_pptr));
178 (void)sprintf(buf, "parameter problem - octet %d",
179 dp->icmp_pptr);
180 }
181 break;
182 case ICMP_TSTAMP:
183 str = "time stamp request";
184 break;
185 case ICMP_TSTAMPREPLY:
186 str = "time stamp reply";
187 break;
188 case ICMP_IREQ:
189 str = "information request";
190 break;
191 case ICMP_IREQREPLY:
192 str = "information reply";
193 break;
194 case ICMP_MASKREQ:
195 str = "address mask request";
196 break;
197 case ICMP_MASKREPLY:
198 TCHECK(dp->icmp_mask, sizeof(dp->icmp_mask));
199 (void)sprintf(buf, "address mask is 0x%08x", dp->icmp_mask);
200 break;
201 }
202 (void)printf("icmp: %s", str);
203 return;
204 trunc:
205 fputs("[|icmp]", stdout);
206 #undef TCHECK
207 }
208