]> The Tcpdump Group git mirrors - tcpdump/blob - print-ip6opts.c
(fs_reply_print): support parsing and printing of the errors in abort
[tcpdump] / print-ip6opts.c
1 /*
2 * Copyright (C) 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #ifdef INET6
35 #include <sys/param.h>
36 #include <sys/time.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39
40 #include <netinet/in.h>
41 #include <netinet/ip6.h>
42
43 #include <stdio.h>
44
45 #include "interface.h"
46 #include "addrtoname.h"
47
48 void
49 ip6_opt_print(const u_char *bp, int len)
50 {
51 int i;
52 int optlen;
53
54 for (i = 0; i < len; i += optlen) {
55 switch (bp[i]) {
56 case IP6OPT_PAD1:
57 optlen = 1;
58 break;
59 case IP6OPT_PADN:
60 if (len - i < IP6OPT_MINLEN) {
61 printf("(padn: trunc)");
62 goto trunc;
63 }
64 optlen = bp[i + 1] + 2;
65 break;
66 case IP6OPT_RTALERT:
67 if (len - i < IP6OPT_RTALERT_LEN) {
68 printf("(rtalert: trunc)");
69 goto trunc;
70 }
71 if (bp[i + 1] != IP6OPT_RTALERT_LEN - 2) {
72 printf("(rtalert: invalid len %d)", bp[i + 1]);
73 goto trunc;
74 }
75 printf("(rtalert: 0x%04x) ", ntohs(*(u_short *)&bp[i + 2]));
76 optlen = IP6OPT_RTALERT_LEN;
77 break;
78 case IP6OPT_JUMBO:
79 if (len - i < IP6OPT_JUMBO_LEN) {
80 printf("(jumbo: trunc)");
81 goto trunc;
82 }
83 if (bp[i + 1] != IP6OPT_JUMBO_LEN - 2) {
84 printf("(jumbo: invalid len %d)", bp[i + 1]);
85 goto trunc;
86 }
87 printf("(jumbo: %u) ", (u_int32_t)ntohl(*(u_int *)&bp[i + 2]));
88 optlen = IP6OPT_JUMBO_LEN;
89 break;
90 default:
91 if (len - i < IP6OPT_MINLEN) {
92 printf("(type %d: trunc)", bp[i]);
93 goto trunc;
94 }
95 printf("(type 0x%02x: len=%d) ", bp[i], bp[i + 1]);
96 optlen = bp[i + 1] + 2;
97 break;
98 }
99 }
100
101 #if 0
102 end:
103 #endif
104 return;
105
106 trunc:
107 printf("[trunc] ");
108 }
109
110 int
111 hbhopt_print(register const u_char *bp)
112 {
113 const struct ip6_hbh *dp = (struct ip6_hbh *)bp;
114 register const u_char *ep;
115 int hbhlen = 0;
116
117 /* 'ep' points to the end of avaible data. */
118 ep = snapend;
119 TCHECK(dp->ip6h_len);
120 hbhlen = (int)((dp->ip6h_len + 1) << 3);
121 TCHECK2(dp, hbhlen);
122 printf("HBH ");
123 if (vflag)
124 ip6_opt_print((const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp));
125
126 return(hbhlen);
127
128 trunc:
129 fputs("[|HBH]", stdout);
130 return(hbhlen);
131 }
132
133 int
134 dstopt_print(register const u_char *bp)
135 {
136 const struct ip6_dest *dp = (struct ip6_dest *)bp;
137 register const u_char *ep;
138 int dstoptlen = 0;
139
140 /* 'ep' points to the end of avaible data. */
141 ep = snapend;
142 TCHECK(dp->ip6d_len);
143 dstoptlen = (int)((dp->ip6d_len + 1) << 3);
144 TCHECK2(dp, dstoptlen);
145 printf("DSTOPT ");
146 if (vflag) {
147 ip6_opt_print((const u_char *)dp + sizeof(*dp),
148 dstoptlen - sizeof(*dp));
149 }
150
151 return(dstoptlen);
152
153 trunc:
154 fputs("[|DSTOPT]", stdout);
155 return(dstoptlen);
156 }
157 #endif /* INET6 */