]>
The Tcpdump Group git mirrors - tcpdump/blob - print-ip.c
1 /* $NetBSD: print-ip.c,v 1.4 1995/04/24 13:27:43 cgd Exp $ */
4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that: (1) source code distributions
9 * retain the above copyright notice and this paragraph in its entirety, (2)
10 * distributions including binary code include the above copyright notice and
11 * this paragraph in its entirety in the documentation or other materials
12 * provided with the distribution, and (3) all advertising materials mentioning
13 * features or use of this software display the following acknowledgement:
14 * ``This product includes software developed by the University of California,
15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16 * the University nor the names of its contributors may be used to endorse
17 * or promote products derived from this software without specific prior
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25 static const char rcsid
[] =
26 "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.68 1999-10-17 21:56:54 mcr Exp $ (LBL)";
29 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <netinet/in_systm.h>
36 #include <netinet/ip.h>
37 #include <netinet/udp.h>
38 #include <netinet/tcp.h>
46 #include "interface.h"
47 #include "addrtoname.h"
50 igmp_print(register const u_char
*bp
, register int len
,
51 register const u_char
*bp2
)
53 register const struct ip
*ip
;
54 register const u_char
*ep
;
56 ip
= (const struct ip
*)bp2
;
57 ep
= (const u_char
*)snapend
;
58 (void)printf("%s > %s: ",
59 ipaddr_string(&ip
->ip_src
),
60 ipaddr_string(&ip
->ip_dst
));
63 (void)printf("[|igmp]");
66 switch (bp
[0] & 0xf) {
68 (void)printf("igmp query");
70 (void)printf(" [gaddr %s]", ipaddr_string(&bp
[4]));
72 (void)printf(" [len %d]", len
);
75 (void)printf("igmp report %s", ipaddr_string(&bp
[4]));
77 (void)printf(" [len %d]", len
);
80 (void)printf("igmp dvmrp %s", ipaddr_string(&bp
[4]));
82 (void)printf(" [len %d]", len
);
85 (void)printf("igmp-%d", bp
[0] & 0xf);
88 if ((bp
[0] >> 4) != 1)
89 (void)printf(" [v%d]", bp
[0] >> 4);
91 (void)printf(" [b1=0x%x]", bp
[1]);
95 * print the recorded route in an IP RR, LSRR or SSRR option.
98 ip_printroute(const char *type
, register const u_char
*cp
, int length
)
103 printf(" %s{", type
);
104 if ((length
+ 1) & 3)
105 printf(" [bad length %d]", length
);
106 if (ptr
< 3 || ((ptr
+ 1) & 3) || ptr
> length
+ 1)
107 printf(" [bad ptr %d]", cp
[2]);
110 for (len
= 3; len
< length
; len
+= 4) {
116 bcopy((char *)&cp
[len
], (char *)&addr
, sizeof(addr
));
117 printf("%s%s", type
, ipaddr_string(&addr
));
120 printf("%s%s", type
, ipaddr_string(&cp
[len
]));
124 printf("%s}", ptr
== len
? "#" : "");
131 ip_optprint(register const u_char
*cp
, int length
)
135 for (; length
> 0; cp
+= len
, length
-= len
) {
138 len
= (tt
== IPOPT_NOP
|| tt
== IPOPT_EOL
) ? 1 : cp
[1];
139 if (&cp
[1] >= snapend
|| cp
+ len
> snapend
) {
148 printf("-%d", length
- 1);
156 printf(" TS{%d}", len
);
160 printf(" SECURITY{%d}", len
);
164 printf(" RR{%d}=", len
);
165 ip_printroute("RR", cp
, len
);
169 ip_printroute("SSRR", cp
, len
);
173 ip_printroute("LSRR", cp
, len
);
177 printf(" IPOPT-%d{%d}", cp
[0], len
);
184 * compute an IP header checksum.
185 * don't modifiy the packet.
188 in_cksum(const struct ip
*ip
)
190 register const u_short
*sp
= (u_short
*)ip
;
191 register u_int32 sum
= 0;
195 * No need for endian conversions.
197 for (count
= ip
->ip_hl
* 2; --count
>= 0; )
200 sum
= (sum
& 0xffff) + (sum
>> 16);
208 print_ipproto(u_int proto
, const struct ip
*ip
,
209 const u_char
*cp
, int len
)
213 tcp_print(cp
, len
, (const u_char
*)ip
);
216 udp_print(cp
, len
, (const u_char
*)ip
);
219 icmp_print(cp
, (const u_char
*)ip
);
222 (void)printf("%s > %s:", ipaddr_string(&ip
->ip_src
),
223 ipaddr_string(&ip
->ip_dst
));
224 (void)printf(" nd %d", len
);
227 egp_print(cp
, len
, (const u_char
*)ip
);
230 #define IPPROTO_OSPF 89
233 ospf_print(cp
, len
, (const u_char
*)ip
);
236 #define IPPROTO_IGMP 2
239 igmp_print(cp
, len
, (const u_char
*)ip
);
241 #ifndef IPPROTO_ENCAP
242 #define IPPROTO_ENCAP 4
245 /* ip-in-ip encapsulation */
247 (void)printf("%s > %s: ",
248 ipaddr_string(&ip
->ip_src
),
249 ipaddr_string(&ip
->ip_dst
));
258 #define IPPROTO_ESP 50
261 esp_print(cp
, len
, (const u_char
*)ip
);
265 #define IPPROTO_AH 51
268 ah_print(cp
, len
, (const u_char
*)ip
);
272 (void)printf("%s > %s:", ipaddr_string(&ip
->ip_src
),
273 ipaddr_string(&ip
->ip_dst
));
274 (void)printf(" ip-proto-%d %d", proto
, len
);
280 * print an IP datagram.
283 ip_print(register const u_char
*bp
, register int length
)
285 register const struct ip
*ip
;
289 register const u_char
*cp
;
291 ip
= (const struct ip
*)bp
;
294 * The IP header is not word aligned, so copy into abuf.
295 * This will never happen with BPF. It does happen raw packet
298 if ((long)ip
& (sizeof(long)-1)) {
302 abuf
= (u_char
*)malloc(snaplen
);
303 bcopy((char *)ip
, (char *)abuf
, min(length
, snaplen
));
304 snapend
+= abuf
- (u_char
*)ip
;
306 ip
= (struct ip
*)abuf
;
309 if ((u_char
*)(ip
+ 1) > snapend
) {
313 if (length
< sizeof (struct ip
)) {
314 (void)printf("truncated-ip %d", length
);
317 hlen
= ip
->ip_hl
* 4;
319 len
= ntohs(ip
->ip_len
);
321 (void)printf("truncated-ip - %d bytes missing!",
326 * If this is fragment zero, hand it to the next higher
329 off
= ntohs(ip
->ip_off
);
330 if ((off
& 0x1fff) == 0) {
331 cp
= (const u_char
*)ip
+ hlen
;
332 print_ipproto(ip
->ip_p
, ip
, cp
, len
);
335 * for fragmented datagrams, print id:size@offset. On all
336 * but the last stick a "+". For unfragmented datagrams, note
337 * the don't fragment flag.
341 * if this isn't the first frag, we're missing the
342 * next level protocol header. print the ip addr.
345 (void)printf("%s > %s:", ipaddr_string(&ip
->ip_src
),
346 ipaddr_string(&ip
->ip_dst
));
347 (void)printf(" (frag %d:%d@%d%s)", ntohs(ip
->ip_id
), len
,
349 (off
& IP_MF
)? "+" : "");
350 } else if (off
& IP_DF
)
351 (void)printf(" (DF)");
354 (void)printf(" [tos 0x%x]", (int)ip
->ip_tos
);
356 (void)printf(" [ttl %d]", (int)ip
->ip_ttl
);
363 if (ip
->ip_ttl
> 1) {
364 (void)printf("%sttl %d", sep
, (int)ip
->ip_ttl
);
367 if ((off
& 0x3fff) == 0) {
368 (void)printf("%sid %d", sep
, (int)ntohs(ip
->ip_id
));
373 (void)printf("%sbad cksum %x!", sep
,
377 if ((hlen
-= sizeof(struct ip
)) > 0) {
378 (void)printf("%soptlen=%d", sep
, hlen
);
379 ip_optprint((u_char
*)(ip
+ 1), hlen
);