xref: /freebsd/contrib/tcpdump/print-ip-demux.c (revision 0a7e5f1f02aad2ff5fff1c60f44c6975fd07e1d9)
1ee67461eSJoseph Mingrone /*
2ee67461eSJoseph Mingrone  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3ee67461eSJoseph Mingrone  *	The Regents of the University of California.  All rights reserved.
4ee67461eSJoseph Mingrone  *
5ee67461eSJoseph Mingrone  * Redistribution and use in source and binary forms, with or without
6ee67461eSJoseph Mingrone  * modification, are permitted provided that: (1) source code distributions
7ee67461eSJoseph Mingrone  * retain the above copyright notice and this paragraph in its entirety, (2)
8ee67461eSJoseph Mingrone  * distributions including binary code include the above copyright notice and
9ee67461eSJoseph Mingrone  * this paragraph in its entirety in the documentation or other materials
10ee67461eSJoseph Mingrone  * provided with the distribution, and (3) all advertising materials mentioning
11ee67461eSJoseph Mingrone  * features or use of this software display the following acknowledgement:
12ee67461eSJoseph Mingrone  * ``This product includes software developed by the University of California,
13ee67461eSJoseph Mingrone  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14ee67461eSJoseph Mingrone  * the University nor the names of its contributors may be used to endorse
15ee67461eSJoseph Mingrone  * or promote products derived from this software without specific prior
16ee67461eSJoseph Mingrone  * written permission.
17ee67461eSJoseph Mingrone  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18ee67461eSJoseph Mingrone  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19ee67461eSJoseph Mingrone  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20ee67461eSJoseph Mingrone  */
21ee67461eSJoseph Mingrone 
22ee67461eSJoseph Mingrone /* \summary: IPv4/IPv6 payload printer */
23ee67461eSJoseph Mingrone 
24ee67461eSJoseph Mingrone #include <config.h>
25ee67461eSJoseph Mingrone 
26ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
27ee67461eSJoseph Mingrone 
28ee67461eSJoseph Mingrone #include "netdissect.h"
29ee67461eSJoseph Mingrone #include "addrtoname.h"
30ee67461eSJoseph Mingrone #include "extract.h"
31ee67461eSJoseph Mingrone 
32ee67461eSJoseph Mingrone #include "ip.h"
33ee67461eSJoseph Mingrone #include "ipproto.h"
34ee67461eSJoseph Mingrone 
35ee67461eSJoseph Mingrone void
ip_demux_print(netdissect_options * ndo,const u_char * bp,u_int length,u_int ver,int fragmented,u_int ttl_hl,uint8_t nh,const u_char * iph)36ee67461eSJoseph Mingrone ip_demux_print(netdissect_options *ndo,
37ee67461eSJoseph Mingrone 	       const u_char *bp,
38ee67461eSJoseph Mingrone 	       u_int length, u_int ver, int fragmented, u_int ttl_hl,
39ee67461eSJoseph Mingrone 	       uint8_t nh, const u_char *iph)
40ee67461eSJoseph Mingrone {
41ee67461eSJoseph Mingrone 	int advance;
42ee67461eSJoseph Mingrone 	const char *p_name;
43ee67461eSJoseph Mingrone 
44ee67461eSJoseph Mingrone 	advance = 0;
45ee67461eSJoseph Mingrone 
46ee67461eSJoseph Mingrone again:
47ee67461eSJoseph Mingrone 	switch (nh) {
48ee67461eSJoseph Mingrone 
49ee67461eSJoseph Mingrone 	case IPPROTO_AH:
50ee67461eSJoseph Mingrone 		if (!ND_TTEST_1(bp)) {
51ee67461eSJoseph Mingrone 			ndo->ndo_protocol = "ah";
52ee67461eSJoseph Mingrone 			nd_print_trunc(ndo);
53ee67461eSJoseph Mingrone 			break;
54ee67461eSJoseph Mingrone 		}
55ee67461eSJoseph Mingrone 		nh = GET_U_1(bp);
56ee67461eSJoseph Mingrone 		advance = ah_print(ndo, bp);
57ee67461eSJoseph Mingrone 		if (advance <= 0)
58ee67461eSJoseph Mingrone 			break;
59ee67461eSJoseph Mingrone 		bp += advance;
60ee67461eSJoseph Mingrone 		length -= advance;
61ee67461eSJoseph Mingrone 		goto again;
62ee67461eSJoseph Mingrone 
63ee67461eSJoseph Mingrone 	case IPPROTO_ESP:
64ee67461eSJoseph Mingrone 	{
65ee67461eSJoseph Mingrone 		esp_print(ndo, bp, length, iph, ver, fragmented, ttl_hl);
66ee67461eSJoseph Mingrone 		/*
67ee67461eSJoseph Mingrone 		 * Either this has decrypted the payload and
68ee67461eSJoseph Mingrone 		 * printed it, in which case there's nothing more
69ee67461eSJoseph Mingrone 		 * to do, or it hasn't, in which case there's
70ee67461eSJoseph Mingrone 		 * nothing more to do.
71ee67461eSJoseph Mingrone 		 */
72ee67461eSJoseph Mingrone 		break;
73ee67461eSJoseph Mingrone 	}
74ee67461eSJoseph Mingrone 
75ee67461eSJoseph Mingrone 	case IPPROTO_IPCOMP:
76ee67461eSJoseph Mingrone 	{
77ee67461eSJoseph Mingrone 		ipcomp_print(ndo, bp);
78ee67461eSJoseph Mingrone 		/*
79ee67461eSJoseph Mingrone 		 * Either this has decompressed the payload and
80ee67461eSJoseph Mingrone 		 * printed it, in which case there's nothing more
81ee67461eSJoseph Mingrone 		 * to do, or it hasn't, in which case there's
82ee67461eSJoseph Mingrone 		 * nothing more to do.
83ee67461eSJoseph Mingrone 		 */
84ee67461eSJoseph Mingrone 		break;
85ee67461eSJoseph Mingrone 	}
86ee67461eSJoseph Mingrone 
87ee67461eSJoseph Mingrone 	case IPPROTO_SCTP:
88ee67461eSJoseph Mingrone 		sctp_print(ndo, bp, iph, length);
89ee67461eSJoseph Mingrone 		break;
90ee67461eSJoseph Mingrone 
91ee67461eSJoseph Mingrone 	case IPPROTO_DCCP:
92ee67461eSJoseph Mingrone 		dccp_print(ndo, bp, iph, length);
93ee67461eSJoseph Mingrone 		break;
94ee67461eSJoseph Mingrone 
95ee67461eSJoseph Mingrone 	case IPPROTO_TCP:
96ee67461eSJoseph Mingrone 		tcp_print(ndo, bp, length, iph, fragmented);
97ee67461eSJoseph Mingrone 		break;
98ee67461eSJoseph Mingrone 
99ee67461eSJoseph Mingrone 	case IPPROTO_UDP:
100ee67461eSJoseph Mingrone 		udp_print(ndo, bp, length, iph, fragmented, ttl_hl);
101ee67461eSJoseph Mingrone 		break;
102ee67461eSJoseph Mingrone 
103ee67461eSJoseph Mingrone 	case IPPROTO_ICMP:
104ee67461eSJoseph Mingrone 		if (ver == 4)
105ee67461eSJoseph Mingrone 			icmp_print(ndo, bp, length, iph, fragmented);
106ee67461eSJoseph Mingrone 		else {
107ee67461eSJoseph Mingrone 			ND_PRINT("[%s requires IPv4]",
108ee67461eSJoseph Mingrone 				 tok2str(ipproto_values,"unknown",nh));
109ee67461eSJoseph Mingrone 			nd_print_invalid(ndo);
110ee67461eSJoseph Mingrone 		}
111ee67461eSJoseph Mingrone 		break;
112ee67461eSJoseph Mingrone 
113ee67461eSJoseph Mingrone 	case IPPROTO_ICMPV6:
114ee67461eSJoseph Mingrone 		if (ver == 6)
115ee67461eSJoseph Mingrone 			icmp6_print(ndo, bp, length, iph, fragmented);
116ee67461eSJoseph Mingrone 		else {
117ee67461eSJoseph Mingrone 			ND_PRINT("[%s requires IPv6]",
118ee67461eSJoseph Mingrone 				 tok2str(ipproto_values,"unknown",nh));
119ee67461eSJoseph Mingrone 			nd_print_invalid(ndo);
120ee67461eSJoseph Mingrone 		}
121ee67461eSJoseph Mingrone 		break;
122ee67461eSJoseph Mingrone 
123ee67461eSJoseph Mingrone 	case IPPROTO_PIGP:
124ee67461eSJoseph Mingrone 		/*
125ee67461eSJoseph Mingrone 		 * XXX - the current IANA protocol number assignments
126ee67461eSJoseph Mingrone 		 * page lists 9 as "any private interior gateway
127ee67461eSJoseph Mingrone 		 * (used by Cisco for their IGRP)" and 88 as
128ee67461eSJoseph Mingrone 		 * "EIGRP" from Cisco.
129ee67461eSJoseph Mingrone 		 *
130ee67461eSJoseph Mingrone 		 * Recent BSD <netinet/in.h> headers define
131ee67461eSJoseph Mingrone 		 * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88.
132ee67461eSJoseph Mingrone 		 * We define IP_PROTO_PIGP as 9 and
133ee67461eSJoseph Mingrone 		 * IP_PROTO_EIGRP as 88; those names better
134ee67461eSJoseph Mingrone 		 * match was the current protocol number
135ee67461eSJoseph Mingrone 		 * assignments say.
136ee67461eSJoseph Mingrone 		 */
137ee67461eSJoseph Mingrone 		igrp_print(ndo, bp, length);
138ee67461eSJoseph Mingrone 		break;
139ee67461eSJoseph Mingrone 
140ee67461eSJoseph Mingrone 	case IPPROTO_EIGRP:
141ee67461eSJoseph Mingrone 		eigrp_print(ndo, bp, length);
142ee67461eSJoseph Mingrone 		break;
143ee67461eSJoseph Mingrone 
144ee67461eSJoseph Mingrone 	case IPPROTO_ND:
145ee67461eSJoseph Mingrone 		ND_PRINT(" nd %u", length);
146ee67461eSJoseph Mingrone 		break;
147ee67461eSJoseph Mingrone 
148ee67461eSJoseph Mingrone 	case IPPROTO_EGP:
149ee67461eSJoseph Mingrone 		egp_print(ndo, bp, length);
150ee67461eSJoseph Mingrone 		break;
151ee67461eSJoseph Mingrone 
152ee67461eSJoseph Mingrone 	case IPPROTO_OSPF:
153ee67461eSJoseph Mingrone 		if (ver == 6)
154ee67461eSJoseph Mingrone 			ospf6_print(ndo, bp, length);
155ee67461eSJoseph Mingrone 		else
156ee67461eSJoseph Mingrone 			ospf_print(ndo, bp, length, iph);
157ee67461eSJoseph Mingrone 		break;
158ee67461eSJoseph Mingrone 
159ee67461eSJoseph Mingrone 	case IPPROTO_IGMP:
160ee67461eSJoseph Mingrone 		if (ver == 4)
161ee67461eSJoseph Mingrone 			igmp_print(ndo, bp, length);
162ee67461eSJoseph Mingrone 		else {
163ee67461eSJoseph Mingrone 			ND_PRINT("[%s requires IPv4]",
164ee67461eSJoseph Mingrone 				 tok2str(ipproto_values,"unknown",nh));
165ee67461eSJoseph Mingrone 			nd_print_invalid(ndo);
166ee67461eSJoseph Mingrone 		}
167ee67461eSJoseph Mingrone 		break;
168ee67461eSJoseph Mingrone 
169ee67461eSJoseph Mingrone 	case IPPROTO_IPV4:
170ee67461eSJoseph Mingrone 		/* ipv4-in-ip encapsulation */
171ee67461eSJoseph Mingrone 		ip_print(ndo, bp, length);
172ee67461eSJoseph Mingrone 		break;
173ee67461eSJoseph Mingrone 
174ee67461eSJoseph Mingrone 	case IPPROTO_IPV6:
175ee67461eSJoseph Mingrone 		/* ip6-in-ip encapsulation */
176ee67461eSJoseph Mingrone 		ip6_print(ndo, bp, length);
177ee67461eSJoseph Mingrone 		break;
178ee67461eSJoseph Mingrone 
179ee67461eSJoseph Mingrone 	case IPPROTO_RSVP:
180ee67461eSJoseph Mingrone 		rsvp_print(ndo, bp, length);
181ee67461eSJoseph Mingrone 		break;
182ee67461eSJoseph Mingrone 
183ee67461eSJoseph Mingrone 	case IPPROTO_GRE:
184ee67461eSJoseph Mingrone 		gre_print(ndo, bp, length);
185ee67461eSJoseph Mingrone 		break;
186ee67461eSJoseph Mingrone 
187ee67461eSJoseph Mingrone 	case IPPROTO_MOBILE:
188ee67461eSJoseph Mingrone 		mobile_print(ndo, bp, length);
189ee67461eSJoseph Mingrone 		break;
190ee67461eSJoseph Mingrone 
191ee67461eSJoseph Mingrone 	case IPPROTO_PIM:
192ee67461eSJoseph Mingrone 		pim_print(ndo, bp, length, iph);
193ee67461eSJoseph Mingrone 		break;
194ee67461eSJoseph Mingrone 
195ee67461eSJoseph Mingrone 	case IPPROTO_VRRP:
196ee67461eSJoseph Mingrone 		if (ndo->ndo_packettype == PT_CARP) {
197ee67461eSJoseph Mingrone 			carp_print(ndo, bp, length, ttl_hl);
198ee67461eSJoseph Mingrone 		} else {
199ee67461eSJoseph Mingrone 			vrrp_print(ndo, bp, length, iph, ttl_hl, ver);
200ee67461eSJoseph Mingrone 		}
201ee67461eSJoseph Mingrone 		break;
202ee67461eSJoseph Mingrone 
203ee67461eSJoseph Mingrone 	case IPPROTO_PGM:
204ee67461eSJoseph Mingrone 		pgm_print(ndo, bp, length, iph);
205ee67461eSJoseph Mingrone 		break;
206ee67461eSJoseph Mingrone 
207ee67461eSJoseph Mingrone 	case IPPROTO_ETHERNET:
208ee67461eSJoseph Mingrone 		if (ver == 6)
209ee67461eSJoseph Mingrone 			ether_print(ndo, bp, length, ND_BYTES_AVAILABLE_AFTER(bp), NULL, NULL);
210ee67461eSJoseph Mingrone 		else {
211ee67461eSJoseph Mingrone 			ND_PRINT("[%s requires IPv6]",
212ee67461eSJoseph Mingrone 				 tok2str(ipproto_values,"unknown",nh));
213ee67461eSJoseph Mingrone 			nd_print_invalid(ndo);
214ee67461eSJoseph Mingrone 		}
215ee67461eSJoseph Mingrone 		break;
216ee67461eSJoseph Mingrone 
217*85247ee6SLuiz Amaral #ifdef HAVE_NET_IF_PFLOG_H
218*85247ee6SLuiz Amaral 	case IPPROTO_PFSYNC:
219*85247ee6SLuiz Amaral 		pfsync_ip_print(ndo, bp, length);
220*85247ee6SLuiz Amaral 		break;
221*85247ee6SLuiz Amaral #endif
222*85247ee6SLuiz Amaral 
223ee67461eSJoseph Mingrone 	case IPPROTO_NONE:
224ee67461eSJoseph Mingrone 		ND_PRINT("no next header");
225ee67461eSJoseph Mingrone 		break;
226ee67461eSJoseph Mingrone 
227ee67461eSJoseph Mingrone 	default:
228ee67461eSJoseph Mingrone 		if (ndo->ndo_nflag==0 && (p_name = netdb_protoname(nh)) != NULL)
229ee67461eSJoseph Mingrone 			ND_PRINT(" %s", p_name);
230ee67461eSJoseph Mingrone 		else
231ee67461eSJoseph Mingrone 			ND_PRINT(" ip-proto-%u", nh);
232ee67461eSJoseph Mingrone 		ND_PRINT(" %u", length);
233ee67461eSJoseph Mingrone 		break;
234ee67461eSJoseph Mingrone 	}
235ee67461eSJoseph Mingrone }
236