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           case IPPROTO_NONE:
218                     ND_PRINT("no next header");
219                     break;
220 
221           default:
222                     if (ndo->ndo_nflag==0 && (p_name = netdb_protoname(nh)) != NULL)
223                               ND_PRINT(" %s", p_name);
224                     else
225                               ND_PRINT(" ip-proto-%u", nh);
226                     ND_PRINT(" %u", length);
227                     break;
228           }
229 }
230