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