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