]>
git.saurik.com Git - apple/network_cmds.git/blob - tcpdump.tproj/print-ip.c
6c0c31cea4e1397d079234d7df7ce341e110d35b
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
25 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that: (1) source code distributions
30 * retain the above copyright notice and this paragraph in its entirety, (2)
31 * distributions including binary code include the above copyright notice and
32 * this paragraph in its entirety in the documentation or other materials
33 * provided with the distribution, and (3) all advertising materials mentioning
34 * features or use of this software display the following acknowledgement:
35 * ``This product includes software developed by the University of California,
36 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
37 * the University nor the names of its contributors may be used to endorse
38 * or promote products derived from this software without specific prior
40 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
41 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
46 static const char rcsid
[] =
47 "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/print-ip.c,v 1.1.1.1 1999/05/02 03:58:33 wsanchez Exp $ (LBL)";
50 #include <sys/param.h>
52 #include <sys/socket.h>
54 #include <netinet/in.h>
55 #include <netinet/in_systm.h>
56 #include <netinet/ip.h>
57 #include <netinet/ip_var.h>
58 #include <netinet/udp.h>
59 #include <netinet/udp_var.h>
60 #include <netinet/tcp.h>
61 #include <netinet/tcpip.h>
68 #include "addrtoname.h"
69 #include "interface.h"
70 #include "extract.h" /* must come after interface.h */
78 #define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000)
81 /* (following from ipmulti/mrouted/prune.h) */
84 * The packet format for a traceroute request.
87 u_int tr_src
; /* traceroute source */
88 u_int tr_dst
; /* traceroute destination */
89 u_int tr_raddr
; /* traceroute response address */
90 #ifdef WORDS_BIGENDIAN
92 u_int ttl
: 8; /* traceroute response ttl */
93 u_int qid
: 24; /* traceroute query id */
97 u_int qid
: 24; /* traceroute query id */
98 u_int ttl
: 8; /* traceroute response ttl */
103 #define tr_rttl q.ttl
107 * Traceroute response format. A traceroute response has a tr_query at the
108 * beginning, followed by one tr_resp for each hop taken.
111 u_int tr_qarr
; /* query arrival time */
112 u_int tr_inaddr
; /* incoming interface address */
113 u_int tr_outaddr
; /* outgoing interface address */
114 u_int tr_rmtaddr
; /* parent address in source tree */
115 u_int tr_vifin
; /* input packet count on interface */
116 u_int tr_vifout
; /* output packet count on interface */
117 u_int tr_pktcnt
; /* total incoming packets for src-grp */
118 u_char tr_rproto
; /* routing proto deployed on router */
119 u_char tr_fttl
; /* ttl required to forward on outvif */
120 u_char tr_smask
; /* subnet mask for src addr */
121 u_char tr_rflags
; /* forwarding error codes */
124 /* defs within mtrace */
128 /* fields for tr_rflags (forwarding error codes) */
130 #define TR_WRONG_IF 1
136 #define TR_NO_SPACE 0x81
137 #define TR_OLD_ROUTER 0x82
139 /* fields for tr_rproto (routing protocol) */
140 #define TR_PROTO_DVMRP 1
141 #define TR_PROTO_MOSPF 2
142 #define TR_PROTO_PIM 3
143 #define TR_PROTO_CBT 4
145 static void print_mtrace(register const u_char
*bp
, register u_int len
)
147 register struct tr_query
*tr
= (struct tr_query
*)(bp
+ 8);
149 printf("mtrace %d: %s to %s reply-to %s", tr
->tr_qid
,
150 ipaddr_string(&tr
->tr_src
), ipaddr_string(&tr
->tr_dst
),
151 ipaddr_string(&tr
->tr_raddr
));
152 if (IN_CLASSD(ntohl(tr
->tr_raddr
)))
153 printf(" with-ttl %d", tr
->tr_rttl
);
156 static void print_mresp(register const u_char
*bp
, register u_int len
)
158 register struct tr_query
*tr
= (struct tr_query
*)(bp
+ 8);
160 printf("mresp %d: %s to %s reply-to %s", tr
->tr_qid
,
161 ipaddr_string(&tr
->tr_src
), ipaddr_string(&tr
->tr_dst
),
162 ipaddr_string(&tr
->tr_raddr
));
163 if (IN_CLASSD(ntohl(tr
->tr_raddr
)))
164 printf(" with-ttl %d", tr
->tr_rttl
);
168 igmp_print(register const u_char
*bp
, register u_int len
,
169 register const u_char
*bp2
)
171 register const struct ip
*ip
;
173 ip
= (const struct ip
*)bp2
;
174 (void)printf("%s > %s: ",
175 ipaddr_string(&ip
->ip_src
),
176 ipaddr_string(&ip
->ip_dst
));
181 (void)printf("igmp query");
183 (void)printf(" [gaddr %s]", ipaddr_string(&bp
[4]));
185 (void)printf(" [len %d]", len
);
188 (void)printf("igmp report %s", ipaddr_string(&bp
[4]));
190 (void)printf(" [len %d]", len
);
193 (void)printf("igmp nreport %s", ipaddr_string(&bp
[4]));
196 (void)printf("igmp leave %s", ipaddr_string(&bp
[4]));
199 (void)printf("igmp dvmrp");
201 (void)printf(" [len %d]", len
);
203 dvmrp_print(bp
, len
);
206 (void)printf("igmp pim");
210 print_mresp(bp
, len
);
213 print_mtrace(bp
, len
);
216 (void)printf("igmp-%d", bp
[0] & 0xf);
219 if ((bp
[0] >> 4) != 1)
220 (void)printf(" [v%d]", bp
[0] >> 4);
224 /* Check the IGMP checksum */
227 const u_short
*sp
= (u_short
*)bp
;
229 for (count
= len
/ 2; --count
>= 0; )
232 sum
+= ntohs(*(u_char
*) sp
<< 8);
234 sum
= (sum
& 0xffff) + (sum
>> 16);
237 printf(" bad igmp cksum %x!", EXTRACT_16BITS(&bp
[2]));
241 fputs("[|igmp]", stdout
);
245 * print the recorded route in an IP RR, LSRR or SSRR option.
248 ip_printroute(const char *type
, register const u_char
*cp
, u_int length
)
250 register u_int ptr
= cp
[2] - 1;
253 printf(" %s{", type
);
254 if ((length
+ 1) & 3)
255 printf(" [bad length %d]", length
);
256 if (ptr
< 3 || ((ptr
+ 1) & 3) || ptr
> length
+ 1)
257 printf(" [bad ptr %d]", cp
[2]);
260 for (len
= 3; len
< length
; len
+= 4) {
263 printf("%s%s", type
, ipaddr_string(&cp
[len
]));
266 printf("%s}", ptr
== len
? "#" : "");
273 ip_optprint(register const u_char
*cp
, u_int length
)
277 for (; length
> 0; cp
+= len
, length
-= len
) {
280 len
= (tt
== IPOPT_NOP
|| tt
== IPOPT_EOL
) ? 1 : cp
[1];
282 printf("[|ip op len %d]", len
);
285 if (&cp
[1] >= snapend
|| cp
+ len
> snapend
) {
294 printf("-%d", length
- 1);
302 printf(" TS{%d}", len
);
306 printf(" SECURITY{%d}", len
);
310 printf(" RR{%d}=", len
);
311 ip_printroute("RR", cp
, len
);
315 ip_printroute("SSRR", cp
, len
);
319 ip_printroute("LSRR", cp
, len
);
323 printf(" IPOPT-%d{%d}", cp
[0], len
);
330 * compute an IP header checksum.
331 * don't modifiy the packet.
334 in_cksum(const struct ip
*ip
)
336 register const u_short
*sp
= (u_short
*)ip
;
337 register u_int32_t sum
= 0;
341 * No need for endian conversions.
343 for (count
= ip
->ip_hl
* 2; --count
>= 0; )
346 sum
= (sum
& 0xffff) + (sum
>> 16);
353 * print an IP datagram.
356 ip_print(register const u_char
*bp
, register u_int length
)
358 register const struct ip
*ip
;
359 register u_int hlen
, len
, off
;
360 register const u_char
*cp
;
362 ip
= (const struct ip
*)bp
;
365 * If the IP header is not aligned, copy into abuf.
366 * This will never happen with BPF. It does happen raw packet
370 static u_char
*abuf
= NULL
;
371 static int didwarn
= 0;
374 abuf
= (u_char
*)malloc(snaplen
);
376 error("ip_print: malloc");
378 memcpy((char *)abuf
, (char *)ip
, min(length
, snaplen
));
379 snapend
+= abuf
- (u_char
*)ip
;
381 ip
= (struct ip
*)abuf
;
382 /* We really want libpcap to give us aligned packets */
384 warning("compensating for unaligned libpcap packets");
389 if ((u_char
*)(ip
+ 1) > snapend
) {
393 if (length
< sizeof (struct ip
)) {
394 (void)printf("truncated-ip %d", length
);
397 hlen
= ip
->ip_hl
* 4;
399 len
= ntohs(ip
->ip_len
);
401 (void)printf("truncated-ip - %d bytes missing!",
406 * If this is fragment zero, hand it to the next higher
409 off
= ntohs(ip
->ip_off
);
410 if ((off
& 0x1fff) == 0) {
411 cp
= (const u_char
*)ip
+ hlen
;
415 tcp_print(cp
, len
, (const u_char
*)ip
);
419 udp_print(cp
, len
, (const u_char
*)ip
);
423 icmp_print(cp
, (const u_char
*)ip
);
427 #define IPPROTO_IGRP 9
430 igrp_print(cp
, len
, (const u_char
*)ip
);
434 (void)printf("%s > %s:", ipaddr_string(&ip
->ip_src
),
435 ipaddr_string(&ip
->ip_dst
));
436 (void)printf(" nd %d", len
);
440 egp_print(cp
, len
, (const u_char
*)ip
);
444 #define IPPROTO_OSPF 89
447 ospf_print(cp
, len
, (const u_char
*)ip
);
451 #define IPPROTO_IGMP 2
454 igmp_print(cp
, len
, (const u_char
*)ip
);
457 #ifndef IPPROTO_ENCAP
458 #define IPPROTO_ENCAP 4
461 /* ip-in-ip encapsulation */
463 (void)printf("%s > %s: ",
464 ipaddr_string(&ip
->ip_src
),
465 ipaddr_string(&ip
->ip_dst
));
474 #define IPPROTO_GRE 47
478 (void)printf("gre %s > %s: ",
479 ipaddr_string(&ip
->ip_src
),
480 ipaddr_string(&ip
->ip_dst
));
484 printf(" (gre encap)");
490 (void)printf("%s > %s:", ipaddr_string(&ip
->ip_src
),
491 ipaddr_string(&ip
->ip_dst
));
492 (void)printf(" ip-proto-%d %d", ip
->ip_p
, len
);
497 * for fragmented datagrams, print id:size@offset. On all
498 * but the last stick a "+". For unfragmented datagrams, note
499 * the don't fragment flag.
503 * if this isn't the first frag, we're missing the
504 * next level protocol header. print the ip addr.
507 (void)printf("%s > %s:", ipaddr_string(&ip
->ip_src
),
508 ipaddr_string(&ip
->ip_dst
));
509 (void)printf(" (frag %d:%d@%d%s)", ntohs(ip
->ip_id
), len
,
511 (off
& IP_MF
)? "+" : "");
512 } else if (off
& IP_DF
)
513 (void)printf(" (DF)");
516 (void)printf(" [tos 0x%x]", (int)ip
->ip_tos
);
518 (void)printf(" [ttl %d]", (int)ip
->ip_ttl
);
525 if (ip
->ip_ttl
> 1) {
526 (void)printf("%sttl %d", sep
, (int)ip
->ip_ttl
);
529 if ((off
& 0x3fff) == 0) {
530 (void)printf("%sid %d", sep
, (int)ntohs(ip
->ip_id
));
533 if ((u_char
*)ip
+ hlen
<= snapend
) {
536 (void)printf("%sbad cksum %x!", sep
,
541 if ((hlen
-= sizeof(struct ip
)) > 0) {
542 (void)printf("%soptlen=%d", sep
, hlen
);
543 ip_optprint((u_char
*)(ip
+ 1), hlen
);