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