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