Bug Summary

File:netinet6/ip6_input.c
Warning:line 336, column 30
Assigned value is garbage or undefined

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ip6_input.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/netinet6/ip6_input.c
1/* $OpenBSD: ip6_input.c,v 1.239 2022/01/02 22:36:04 jsg Exp $ */
2/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
3
4/*
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/*
34 * Copyright (c) 1982, 1986, 1988, 1993
35 * The Regents of the University of California. All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
61 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
62 */
63
64#include "pf.h"
65#include "carp.h"
66
67#include <sys/param.h>
68#include <sys/systm.h>
69#include <sys/mbuf.h>
70#include <sys/domain.h>
71#include <sys/sysctl.h>
72#include <sys/protosw.h>
73#include <sys/socket.h>
74#include <sys/socketvar.h>
75#include <sys/errno.h>
76#include <sys/time.h>
77#include <sys/timeout.h>
78#include <sys/kernel.h>
79#include <sys/syslog.h>
80#include <sys/task.h>
81
82#include <net/if.h>
83#include <net/if_var.h>
84#include <net/if_types.h>
85#include <net/route.h>
86#include <net/netisr.h>
87
88#include <netinet/in.h>
89
90#include <netinet/ip.h>
91
92#include <netinet/in_pcb.h>
93#include <netinet/ip_var.h>
94#include <netinet6/in6_var.h>
95#include <netinet6/in6_ifattach.h>
96#include <netinet/ip6.h>
97#include <netinet6/ip6_var.h>
98#include <netinet/icmp6.h>
99#include <netinet6/nd6.h>
100
101#include <netinet6/ip6protosw.h>
102
103#include "gif.h"
104#include "bpfilter.h"
105
106#ifdef MROUTING1
107#include <netinet6/ip6_mroute.h>
108#endif
109
110#if NPF1 > 0
111#include <net/pfvar.h>
112#endif
113
114#if NCARP1 > 0
115#include <netinet/ip_carp.h>
116#endif
117
118struct cpumem *ip6counters;
119
120uint8_t ip6_soiikey[IP6_SOIIKEY_LEN16];
121
122int ip6_ours(struct mbuf **, int *, int, int);
123int ip6_check_rh0hdr(struct mbuf *, int *);
124int ip6_hbhchcheck(struct mbuf *, int *, int *, int *);
125int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *);
126struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int);
127int ip6_sysctl_soiikey(void *, size_t *, void *, size_t);
128
129static struct mbuf_queue ip6send_mq;
130
131static void ip6_send_dispatch(void *);
132static struct task ip6send_task =
133 TASK_INITIALIZER(ip6_send_dispatch, &ip6send_mq){{ ((void *)0), ((void *)0) }, (ip6_send_dispatch), (&ip6send_mq
), 0 }
;
134
135/*
136 * IP6 initialization: fill in IP6 protocol switch table.
137 * All protocols not implemented in kernel go to raw IP6 protocol handler.
138 */
139void
140ip6_init(void)
141{
142 const struct protosw *pr;
143 int i;
144
145 pr = pffindproto(PF_INET624, IPPROTO_RAW255, SOCK_RAW3);
146 if (pr == NULL((void *)0))
147 panic("%s", __func__);
148 for (i = 0; i < IPPROTO_MAX256; i++)
149 ip6_protox[i] = pr - inet6sw;
150 for (pr = inet6domain.dom_protosw;
151 pr < inet6domain.dom_protoswNPROTOSW; pr++)
152 if (pr->pr_domain->dom_family == PF_INET624 &&
153 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW255 &&
154 pr->pr_protocol < IPPROTO_MAX256)
155 ip6_protox[pr->pr_protocol] = pr - inet6sw;
156 ip6_randomid_init();
157 nd6_init();
158 frag6_init();
159
160 mq_init(&ip6send_mq, 64, IPL_SOFTNET0x5);
161
162 ip6counters = counters_alloc(ip6s_ncounters);
163}
164
165void
166ipv6_input(struct ifnet *ifp, struct mbuf *m)
167{
168 int off, nxt;
169
170 off = 0;
171 nxt = ip6_input_if(&m, &off, IPPROTO_IPV641, AF_UNSPEC0, ifp);
172 KASSERT(nxt == IPPROTO_DONE)((nxt == 257) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/netinet6/ip6_input.c"
, 172, "nxt == IPPROTO_DONE"))
;
173}
174
175struct mbuf *
176ipv6_check(struct ifnet *ifp, struct mbuf *m)
177{
178 struct ip6_hdr *ip6;
179
180 if (m->m_lenm_hdr.mh_len < sizeof(*ip6)) {
181 m = m_pullup(m, sizeof(*ip6));
182 if (m == NULL((void *)0)) {
183 ip6stat_inc(ip6s_toosmall);
184 return (NULL((void *)0));
185 }
186 }
187
188 ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
189
190 if ((ip6->ip6_vfcip6_ctlun.ip6_un2_vfc & IPV6_VERSION_MASK0xf0) != IPV6_VERSION0x60) {
191 ip6stat_inc(ip6s_badvers);
192 goto bad;
193 }
194
195 /*
196 * Check against address spoofing/corruption.
197 */
198 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)((&ip6->ip6_src)->__u6_addr.__u6_addr8[0] == 0xff) ||
199 IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)((*(const u_int32_t *)(const void *)(&(&ip6->ip6_dst
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&ip6->ip6_dst)->__u6_addr.__u6_addr8
[4]) == 0) && (*(const u_int32_t *)(const void *)(&
(&ip6->ip6_dst)->__u6_addr.__u6_addr8[8]) == 0) &&
(*(const u_int32_t *)(const void *)(&(&ip6->ip6_dst
)->__u6_addr.__u6_addr8[12]) == 0))
) {
200 /*
201 * XXX: "badscope" is not very suitable for a multicast source.
202 */
203 ip6stat_inc(ip6s_badscope);
204 goto bad;
205 }
206 if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src)((*(const u_int32_t *)(const void *)(&(&ip6->ip6_src
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&ip6->ip6_src)->__u6_addr.__u6_addr8
[4]) == 0) && (*(const u_int32_t *)(const void *)(&
(&ip6->ip6_src)->__u6_addr.__u6_addr8[8]) == 0) &&
(*(const u_int32_t *)(const void *)(&(&ip6->ip6_src
)->__u6_addr.__u6_addr8[12]) == (__uint32_t)(__builtin_constant_p
(1) ? (__uint32_t)(((__uint32_t)(1) & 0xff) << 24 |
((__uint32_t)(1) & 0xff00) << 8 | ((__uint32_t)(1)
& 0xff0000) >> 8 | ((__uint32_t)(1) & 0xff000000
) >> 24) : __swap32md(1))))
||
207 IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)((*(const u_int32_t *)(const void *)(&(&ip6->ip6_dst
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&ip6->ip6_dst)->__u6_addr.__u6_addr8
[4]) == 0) && (*(const u_int32_t *)(const void *)(&
(&ip6->ip6_dst)->__u6_addr.__u6_addr8[8]) == 0) &&
(*(const u_int32_t *)(const void *)(&(&ip6->ip6_dst
)->__u6_addr.__u6_addr8[12]) == (__uint32_t)(__builtin_constant_p
(1) ? (__uint32_t)(((__uint32_t)(1) & 0xff) << 24 |
((__uint32_t)(1) & 0xff00) << 8 | ((__uint32_t)(1)
& 0xff0000) >> 8 | ((__uint32_t)(1) & 0xff000000
) >> 24) : __swap32md(1))))
) &&
208 (ifp->if_flags & IFF_LOOPBACK0x8) == 0) {
209 ip6stat_inc(ip6s_badscope);
210 goto bad;
211 }
212 /* Drop packets if interface ID portion is already filled. */
213 if (((IN6_IS_SCOPE_EMBED(&ip6->ip6_src)(((((&ip6->ip6_src)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&ip6->ip6_src)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))) || ((((&ip6->ip6_src)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6->ip6_src)->
__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))) || ((((&ip6
->ip6_src)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&ip6->ip6_src)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x01))))
&& ip6->ip6_src.s6_addr16__u6_addr.__u6_addr16[1]) ||
214 (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)(((((&ip6->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&ip6->ip6_dst)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))) || ((((&ip6->ip6_dst)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6->ip6_dst)->
__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))) || ((((&ip6
->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&ip6->ip6_dst)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x01))))
&& ip6->ip6_dst.s6_addr16__u6_addr.__u6_addr16[1])) &&
215 (ifp->if_flags & IFF_LOOPBACK0x8) == 0) {
216 ip6stat_inc(ip6s_badscope);
217 goto bad;
218 }
219 if (IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst)(((&ip6->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xff)
&& (((&ip6->ip6_dst)->__u6_addr.__u6_addr8
[1] & 0x0f) == 0x01))
&&
220 !(m->m_flagsm_hdr.mh_flags & M_LOOP0x0040)) {
221 /*
222 * In this case, the packet should come from the loopback
223 * interface. However, we cannot just check the if_flags,
224 * because ip6_mloopback() passes the "actual" interface
225 * as the outgoing/incoming interface.
226 */
227 ip6stat_inc(ip6s_badscope);
228 goto bad;
229 }
230
231 /*
232 * The following check is not documented in specs. A malicious
233 * party may be able to use IPv4 mapped addr to confuse tcp/udp stack
234 * and bypass security checks (act as if it was from 127.0.0.1 by using
235 * IPv6 src ::ffff:127.0.0.1). Be cautious.
236 *
237 * This check chokes if we are in an SIIT cloud. As none of BSDs
238 * support IPv4-less kernel compilation, we cannot support SIIT
239 * environment at all. So, it makes more sense for us to reject any
240 * malicious packets for non-SIIT environment, than try to do a
241 * partial support for SIIT environment.
242 */
243 if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src)((*(const u_int32_t *)(const void *)(&(&ip6->ip6_src
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&ip6->ip6_src)->__u6_addr.__u6_addr8
[4]) == 0) && (*(const u_int32_t *)(const void *)(&
(&ip6->ip6_src)->__u6_addr.__u6_addr8[8]) == (__uint32_t
)(__builtin_constant_p(0x0000ffff) ? (__uint32_t)(((__uint32_t
)(0x0000ffff) & 0xff) << 24 | ((__uint32_t)(0x0000ffff
) & 0xff00) << 8 | ((__uint32_t)(0x0000ffff) & 0xff0000
) >> 8 | ((__uint32_t)(0x0000ffff) & 0xff000000) >>
24) : __swap32md(0x0000ffff))))
||
244 IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)((*(const u_int32_t *)(const void *)(&(&ip6->ip6_dst
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&ip6->ip6_dst)->__u6_addr.__u6_addr8
[4]) == 0) && (*(const u_int32_t *)(const void *)(&
(&ip6->ip6_dst)->__u6_addr.__u6_addr8[8]) == (__uint32_t
)(__builtin_constant_p(0x0000ffff) ? (__uint32_t)(((__uint32_t
)(0x0000ffff) & 0xff) << 24 | ((__uint32_t)(0x0000ffff
) & 0xff00) << 8 | ((__uint32_t)(0x0000ffff) & 0xff0000
) >> 8 | ((__uint32_t)(0x0000ffff) & 0xff000000) >>
24) : __swap32md(0x0000ffff))))
) {
245 ip6stat_inc(ip6s_badscope);
246 goto bad;
247 }
248
249 /*
250 * Reject packets with IPv4 compatible addresses (auto tunnel).
251 *
252 * The code forbids automatic tunneling as per RFC4213.
253 */
254 if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src)((*(const u_int32_t *)(const void *)(&(&ip6->ip6_src
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&ip6->ip6_src)->__u6_addr.__u6_addr8
[4]) == 0) && (*(const u_int32_t *)(const void *)(&
(&ip6->ip6_src)->__u6_addr.__u6_addr8[8]) == 0) &&
(*(const u_int32_t *)(const void *)(&(&ip6->ip6_src
)->__u6_addr.__u6_addr8[12]) != 0) && (*(const u_int32_t
*)(const void *)(&(&ip6->ip6_src)->__u6_addr.__u6_addr8
[12]) != (__uint32_t)(__builtin_constant_p(1) ? (__uint32_t)(
((__uint32_t)(1) & 0xff) << 24 | ((__uint32_t)(1) &
0xff00) << 8 | ((__uint32_t)(1) & 0xff0000) >>
8 | ((__uint32_t)(1) & 0xff000000) >> 24) : __swap32md
(1))))
||
255 IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)((*(const u_int32_t *)(const void *)(&(&ip6->ip6_dst
)->__u6_addr.__u6_addr8[0]) == 0) && (*(const u_int32_t
*)(const void *)(&(&ip6->ip6_dst)->__u6_addr.__u6_addr8
[4]) == 0) && (*(const u_int32_t *)(const void *)(&
(&ip6->ip6_dst)->__u6_addr.__u6_addr8[8]) == 0) &&
(*(const u_int32_t *)(const void *)(&(&ip6->ip6_dst
)->__u6_addr.__u6_addr8[12]) != 0) && (*(const u_int32_t
*)(const void *)(&(&ip6->ip6_dst)->__u6_addr.__u6_addr8
[12]) != (__uint32_t)(__builtin_constant_p(1) ? (__uint32_t)(
((__uint32_t)(1) & 0xff) << 24 | ((__uint32_t)(1) &
0xff00) << 8 | ((__uint32_t)(1) & 0xff0000) >>
8 | ((__uint32_t)(1) & 0xff000000) >> 24) : __swap32md
(1))))
) {
256 ip6stat_inc(ip6s_badscope);
257 goto bad;
258 }
259
260 return (m);
261bad:
262 m_freem(m);
263 return (NULL((void *)0));
264}
265
266int
267ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
268{
269 struct mbuf *m;
270 struct ip6_hdr *ip6;
271 struct sockaddr_in6 sin6;
272 struct rtentry *rt = NULL((void *)0);
273 int ours = 0;
274 u_int16_t src_scope, dst_scope;
1
'dst_scope' declared without an initial value
275#if NPF1 > 0
276 struct in6_addr odst;
277#endif
278 int srcrt = 0;
279
280 KASSERT(*offp == 0)((*offp == 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/netinet6/ip6_input.c"
, 280, "*offp == 0"))
;
2
Assuming the condition is true
3
'?' condition is true
281
282 ip6stat_inc(ip6s_total);
283
284 m = *mp = ipv6_check(ifp, *mp);
285 if (m
3.1
'm' is not equal to NULL
== NULL((void *)0))
4
Taking false branch
286 goto bad;
287
288 ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
289
290#if NCARP1 > 0
291 if (carp_lsdrop(ifp, m, AF_INET624, ip6->ip6_src.s6_addr32__u6_addr.__u6_addr32,
7
Assuming the condition is false
8
Taking false branch
292 ip6->ip6_dst.s6_addr32__u6_addr.__u6_addr32, (ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMPV658 ? 0 : 1)))
5
Assuming field 'ip6_un1_nxt' is not equal to IPPROTO_ICMPV6
6
'?' condition is false
293 goto bad;
294#endif
295 ip6stat_inc(ip6s_nxthist + ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt);
296
297 /*
298 * If the packet has been received on a loopback interface it
299 * can be destined to any local address, not necessarily to
300 * an address configured on `ifp'.
301 */
302 if (ifp->if_flags & IFF_LOOPBACK0x8) {
9
Assuming the condition is false
10
Taking false branch
303 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)(((((&ip6->ip6_src)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&ip6->ip6_src)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))) || ((((&ip6->ip6_src)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6->ip6_src)->
__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))) || ((((&ip6
->ip6_src)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&ip6->ip6_src)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x01))))
) {
304 src_scope = ip6->ip6_src.s6_addr16__u6_addr.__u6_addr16[1];
305 ip6->ip6_src.s6_addr16__u6_addr.__u6_addr16[1] = 0;
306 }
307 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)(((((&ip6->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&ip6->ip6_dst)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))) || ((((&ip6->ip6_dst)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6->ip6_dst)->
__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))) || ((((&ip6
->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&ip6->ip6_dst)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x01))))
) {
308 dst_scope = ip6->ip6_dst.s6_addr16__u6_addr.__u6_addr16[1];
309 ip6->ip6_dst.s6_addr16__u6_addr.__u6_addr16[1] = 0;
310 }
311 }
312
313#if NPF1 > 0
314 /*
315 * Packet filter
316 */
317 odst = ip6->ip6_dst;
318 if (pf_test(AF_INET624, PF_IN, ifp, mp) != PF_PASS)
11
Assuming the condition is false
12
Taking false branch
319 goto bad;
320 m = *mp;
321 if (m == NULL((void *)0))
13
Assuming 'm' is not equal to NULL
14
Taking false branch
322 goto bad;
323
324 ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
325 srcrt = !IN6_ARE_ADDR_EQUAL(&odst, &ip6->ip6_dst)(__builtin_memcmp((&(&odst)->__u6_addr.__u6_addr8[
0]), (&(&ip6->ip6_dst)->__u6_addr.__u6_addr8[0]
), (sizeof(struct in6_addr))) == 0)
;
15
Assuming the condition is false
326#endif
327
328 /*
329 * Without embedded scope ID we cannot find link-local
330 * addresses in the routing table.
331 */
332 if (ifp->if_flags & IFF_LOOPBACK0x8) {
16
Assuming the condition is true
17
Taking true branch
333 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)(((((&ip6->ip6_src)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&ip6->ip6_src)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))) || ((((&ip6->ip6_src)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6->ip6_src)->
__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))) || ((((&ip6
->ip6_src)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&ip6->ip6_src)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x01))))
)
18
Assuming the condition is false
19
Assuming the condition is false
334 ip6->ip6_src.s6_addr16__u6_addr.__u6_addr16[1] = src_scope;
335 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)(((((&ip6->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&ip6->ip6_dst)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))) || ((((&ip6->ip6_dst)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6->ip6_dst)->
__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))) || ((((&ip6
->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&ip6->ip6_dst)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x01))))
)
20
Assuming the condition is true
21
Assuming the condition is true
336 ip6->ip6_dst.s6_addr16__u6_addr.__u6_addr16[1] = dst_scope;
22
Assigned value is garbage or undefined
337 } else {
338 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src)(((((&ip6->ip6_src)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&ip6->ip6_src)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))) || ((((&ip6->ip6_src)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6->ip6_src)->
__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))) || ((((&ip6
->ip6_src)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&ip6->ip6_src)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x01))))
)
339 ip6->ip6_src.s6_addr16__u6_addr.__u6_addr16[1] = htons(ifp->if_index)(__uint16_t)(__builtin_constant_p(ifp->if_index) ? (__uint16_t
)(((__uint16_t)(ifp->if_index) & 0xffU) << 8 | (
(__uint16_t)(ifp->if_index) & 0xff00U) >> 8) : __swap16md
(ifp->if_index))
;
340 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst)(((((&ip6->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xfe
) && (((&ip6->ip6_dst)->__u6_addr.__u6_addr8
[1] & 0xc0) == 0x80))) || ((((&ip6->ip6_dst)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&ip6->ip6_dst)->
__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))) || ((((&ip6
->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xff) &&
(((&ip6->ip6_dst)->__u6_addr.__u6_addr8[1] & 0x0f
) == 0x01))))
)
341 ip6->ip6_dst.s6_addr16__u6_addr.__u6_addr16[1] = htons(ifp->if_index)(__uint16_t)(__builtin_constant_p(ifp->if_index) ? (__uint16_t
)(((__uint16_t)(ifp->if_index) & 0xffU) << 8 | (
(__uint16_t)(ifp->if_index) & 0xff00U) >> 8) : __swap16md
(ifp->if_index))
;
342 }
343
344 /*
345 * Be more secure than RFC5095 and scan for type 0 routing headers.
346 * If pf has already scanned the header chain, do not do it twice.
347 */
348 if (!(m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags & PF_TAG_PROCESSED0x80) &&
349 ip6_check_rh0hdr(m, offp)) {
350 ip6stat_inc(ip6s_badoptions);
351 icmp6_error(m, ICMP6_PARAM_PROB4, ICMP6_PARAMPROB_HEADER0, *offp);
352 m = *mp = NULL((void *)0);
353 goto bad;
354 }
355
356#if NPF1 > 0
357 if (pf_ouraddr(m) == 1) {
358 nxt = ip6_ours(mp, offp, nxt, af);
359 goto out;
360 }
361#endif
362
363 /*
364 * Multicast check
365 */
366 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)((&ip6->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xff)) {
367 /*
368 * Make sure M_MCAST is set. It should theoretically
369 * already be there, but let's play safe because upper
370 * layers check for this flag.
371 */
372 m->m_flagsm_hdr.mh_flags |= M_MCAST0x0200;
373
374 /*
375 * See if we belong to the destination multicast group on the
376 * arrival interface.
377 */
378 if (in6_hasmulti(&ip6->ip6_dst, ifp))
379 ours = 1;
380
381#ifdef MROUTING1
382 if (ip6_mforwarding && ip6_mrouter[ifp->if_rdomainif_data.ifi_rdomain]) {
383 int error;
384
385 if (ip6_hbhchcheck(m, offp, &nxt, &ours))
386 goto out;
387
388 ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
389
390 /*
391 * If we are acting as a multicast router, all
392 * incoming multicast packets are passed to the
393 * kernel-level multicast forwarding function.
394 * The packet is returned (relatively) intact; if
395 * ip6_mforward() returns a non-zero value, the packet
396 * must be discarded, else it may be accepted below.
397 */
398 KERNEL_LOCK()_kernel_lock();
399 error = ip6_mforward(ip6, ifp, m);
400 KERNEL_UNLOCK()_kernel_unlock();
401 if (error) {
402 ip6stat_inc(ip6s_cantforward);
403 goto bad;
404 }
405
406 if (ours) {
407 if (af == AF_UNSPEC0)
408 nxt = ip_deliver(mp, offp, nxt,
409 AF_INET624);
410 goto out;
411 }
412 goto bad;
413 }
414#endif
415 if (!ours) {
416 ip6stat_inc(ip6s_notmember);
417 if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)(((&ip6->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xff)
&& (((&ip6->ip6_dst)->__u6_addr.__u6_addr8
[1] & 0x0f) == 0x02))
)
418 ip6stat_inc(ip6s_cantforward);
419 goto bad;
420 }
421 nxt = ip6_ours(mp, offp, nxt, af);
422 goto out;
423 }
424
425
426 /*
427 * Unicast check
428 */
429 memset(&sin6, 0, sizeof(struct sockaddr_in6))__builtin_memset((&sin6), (0), (sizeof(struct sockaddr_in6
)))
;
430 sin6.sin6_len = sizeof(struct sockaddr_in6);
431 sin6.sin6_family = AF_INET624;
432 sin6.sin6_addr = ip6->ip6_dst;
433 rt = rtalloc_mpath(sin6tosa(&sin6), &ip6->ip6_src.s6_addr32__u6_addr.__u6_addr32[0],
434 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid);
435
436 /*
437 * Accept the packet if the route to the destination is marked
438 * as local.
439 */
440 if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL)((rt->rt_flags) & (0x200000))) {
441 struct in6_ifaddr *ia6 = ifatoia6(rt->rt_ifa);
442
443 if (ip6_forwarding == 0 && rt->rt_ifidx != ifp->if_index &&
444 !((ifp->if_flags & IFF_LOOPBACK0x8) ||
445 (ifp->if_typeif_data.ifi_type == IFT_ENC0xf4) ||
446 (m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags & PF_TAG_TRANSLATE_LOCALHOST0x04))) {
447 /* received on wrong interface */
448#if NCARP1 > 0
449 struct ifnet *out_if;
450
451 /*
452 * Virtual IPs on carp interfaces need to be checked
453 * also against the parent interface and other carp
454 * interfaces sharing the same parent.
455 */
456 out_if = if_get(rt->rt_ifidx);
457 if (!(out_if && carp_strict_addr_chk(out_if, ifp))) {
458 ip6stat_inc(ip6s_wrongif);
459 if_put(out_if);
460 goto bad;
461 }
462 if_put(out_if);
463#else
464 ip6stat_inc(ip6s_wrongif);
465 goto bad;
466#endif
467 }
468 /*
469 * packets to a tentative, duplicated, or somehow invalid
470 * address must not be accepted.
471 */
472 if ((ia6->ia6_flags & (IN6_IFF_TENTATIVE0x02|IN6_IFF_DUPLICATED0x04))) {
473 char src[INET6_ADDRSTRLEN46], dst[INET6_ADDRSTRLEN46];
474
475 inet_ntop(AF_INET624, &ip6->ip6_src, src, sizeof(src));
476 inet_ntop(AF_INET624, &ip6->ip6_dst, dst, sizeof(dst));
477 /* address is not ready, so discard the packet. */
478 nd6log((LOG_INFO,do { if (nd6_debug) log (6, "%s: packet to an unready address %s->%s\n"
, __func__, src, dst); } while (0)
479 "%s: packet to an unready address %s->%s\n",do { if (nd6_debug) log (6, "%s: packet to an unready address %s->%s\n"
, __func__, src, dst); } while (0)
480 __func__, src, dst))do { if (nd6_debug) log (6, "%s: packet to an unready address %s->%s\n"
, __func__, src, dst); } while (0)
;
481
482 goto bad;
483 } else {
484 nxt = ip6_ours(mp, offp, nxt, af);
485 goto out;
486 }
487 }
488
489#if NCARP1 > 0
490 if (ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMPV658 &&
491 carp_lsdrop(ifp, m, AF_INET624, ip6->ip6_src.s6_addr32__u6_addr.__u6_addr32,
492 ip6->ip6_dst.s6_addr32__u6_addr.__u6_addr32, 1))
493 goto bad;
494#endif
495 /*
496 * Now there is no reason to process the packet if it's not our own
497 * and we're not a router.
498 */
499 if (!ip6_forwarding) {
500 ip6stat_inc(ip6s_cantforward);
501 goto bad;
502 }
503
504 if (ip6_hbhchcheck(m, offp, &nxt, &ours))
505 goto out;
506
507 if (ours) {
508 if (af == AF_UNSPEC0)
509 nxt = ip_deliver(mp, offp, nxt, AF_INET624);
510 goto out;
511 }
512
513#ifdef IPSEC1
514 if (ipsec_in_use) {
515 int rv;
516
517 rv = ipsec_forward_check(m, *offp, AF_INET624);
518 if (rv != 0) {
519 ip6stat_inc(ip6s_cantforward);
520 goto bad;
521 }
522 /*
523 * Fall through, forward packet. Outbound IPsec policy
524 * checking will occur in ip6_forward().
525 */
526 }
527#endif /* IPSEC */
528
529 ip6_forward(m, rt, srcrt);
530 *mp = NULL((void *)0);
531 return IPPROTO_DONE257;
532 bad:
533 nxt = IPPROTO_DONE257;
534 m_freemp(mp);
535 out:
536 rtfree(rt);
537 return nxt;
538}
539
540int
541ip6_ours(struct mbuf **mp, int *offp, int nxt, int af)
542{
543 if (ip6_hbhchcheck(*mp, offp, &nxt, NULL((void *)0)))
544 return IPPROTO_DONE257;
545
546 /* Check whether we are already in a IPv4/IPv6 local deliver loop. */
547 if (af == AF_UNSPEC0)
548 nxt = ip_deliver(mp, offp, nxt, AF_INET624);
549 return nxt;
550}
551
552int
553ip6_hbhchcheck(struct mbuf *m, int *offp, int *nxtp, int *oursp)
554{
555 struct ip6_hdr *ip6;
556 u_int32_t plen, rtalert = ~0;
557
558 ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
559
560 /*
561 * Process Hop-by-Hop options header if it's contained.
562 * m may be modified in ip6_hopopts_input().
563 * If a JumboPayload option is included, plen will also be modified.
564 */
565 plen = (u_int32_t)ntohs(ip6->ip6_plen)(__uint16_t)(__builtin_constant_p(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen
) ? (__uint16_t)(((__uint16_t)(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen
) & 0xffU) << 8 | ((__uint16_t)(ip6->ip6_ctlun.ip6_un1
.ip6_un1_plen) & 0xff00U) >> 8) : __swap16md(ip6->
ip6_ctlun.ip6_un1.ip6_un1_plen))
;
566 *offp = sizeof(struct ip6_hdr);
567 if (ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_HOPOPTS0) {
568 struct ip6_hbh *hbh;
569
570 if (ip6_hopopts_input(&plen, &rtalert, &m, offp)) {
571 goto bad; /* m have already been freed */
572 }
573
574 /* adjust pointer */
575 ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
576
577 /*
578 * if the payload length field is 0 and the next header field
579 * indicates Hop-by-Hop Options header, then a Jumbo Payload
580 * option MUST be included.
581 */
582 if (ip6->ip6_plenip6_ctlun.ip6_un1.ip6_un1_plen == 0 && plen == 0) {
583 /*
584 * Note that if a valid jumbo payload option is
585 * contained, ip6_hopopts_input() must set a valid
586 * (non-zero) payload length to the variable plen.
587 */
588 ip6stat_inc(ip6s_badoptions);
589 icmp6_error(m, ICMP6_PARAM_PROB4,
590 ICMP6_PARAMPROB_HEADER0,
591 (caddr_t)&ip6->ip6_plenip6_ctlun.ip6_un1.ip6_un1_plen - (caddr_t)ip6);
592 goto bad;
593 }
594 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),do { struct mbuf *t; int tmp; if ((m)->m_hdr.mh_len >= (
sizeof(struct ip6_hdr)) + (sizeof(struct ip6_hbh))) (hbh) = (
struct ip6_hbh *)(((caddr_t)(((m))->m_hdr.mh_data)) + (sizeof
(struct ip6_hdr))); else { t = m_pulldown((m), (sizeof(struct
ip6_hdr)), (sizeof(struct ip6_hbh)), &tmp); if (t) { if (
t->m_hdr.mh_len < tmp + (sizeof(struct ip6_hbh))) panic
("m_pulldown malfunction"); (hbh) = (struct ip6_hbh *)(((caddr_t
)((t)->m_hdr.mh_data)) + tmp); } else { (hbh) = (struct ip6_hbh
*)((void *)0); (m) = ((void *)0); } } } while ( 0)
595 sizeof(struct ip6_hbh))do { struct mbuf *t; int tmp; if ((m)->m_hdr.mh_len >= (
sizeof(struct ip6_hdr)) + (sizeof(struct ip6_hbh))) (hbh) = (
struct ip6_hbh *)(((caddr_t)(((m))->m_hdr.mh_data)) + (sizeof
(struct ip6_hdr))); else { t = m_pulldown((m), (sizeof(struct
ip6_hdr)), (sizeof(struct ip6_hbh)), &tmp); if (t) { if (
t->m_hdr.mh_len < tmp + (sizeof(struct ip6_hbh))) panic
("m_pulldown malfunction"); (hbh) = (struct ip6_hbh *)(((caddr_t
)((t)->m_hdr.mh_data)) + tmp); } else { (hbh) = (struct ip6_hbh
*)((void *)0); (m) = ((void *)0); } } } while ( 0)
;
596 if (hbh == NULL((void *)0)) {
597 ip6stat_inc(ip6s_tooshort);
598 goto bad;
599 }
600 *nxtp = hbh->ip6h_nxt;
601
602 /*
603 * accept the packet if a router alert option is included
604 * and we act as an IPv6 router.
605 */
606 if (rtalert != ~0 && ip6_forwarding && oursp != NULL((void *)0))
607 *oursp = 1;
608 } else
609 *nxtp = ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt;
610
611 /*
612 * Check that the amount of data in the buffers
613 * is as at least much as the IPv6 header would have us expect.
614 * Trim mbufs if longer than we expect.
615 * Drop packet if shorter than we expect.
616 */
617 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
618 ip6stat_inc(ip6s_tooshort);
619 m_freem(m);
620 goto bad;
621 }
622 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
623 if (m->m_lenm_hdr.mh_len == m->m_pkthdrM_dat.MH.MH_pkthdr.len) {
624 m->m_lenm_hdr.mh_len = sizeof(struct ip6_hdr) + plen;
625 m->m_pkthdrM_dat.MH.MH_pkthdr.len = sizeof(struct ip6_hdr) + plen;
626 } else {
627 m_adj(m,
628 sizeof(struct ip6_hdr) + plen - m->m_pkthdrM_dat.MH.MH_pkthdr.len);
629 }
630 }
631
632 return (0);
633
634 bad:
635 *nxtp = IPPROTO_DONE257;
636 return (-1);
637}
638
639/* scan packet for RH0 routing header. Mostly stolen from pf.c:pf_test() */
640int
641ip6_check_rh0hdr(struct mbuf *m, int *offp)
642{
643 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
644 struct ip6_rthdr rthdr;
645 struct ip6_ext opt6;
646 u_int8_t proto = ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt;
647 int done = 0, lim, off, rh_cnt = 0;
648
649 off = ((caddr_t)ip6 - m->m_datam_hdr.mh_data) + sizeof(struct ip6_hdr);
650 lim = min(m->m_pkthdrM_dat.MH.MH_pkthdr.len, ntohs(ip6->ip6_plen)(__uint16_t)(__builtin_constant_p(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen
) ? (__uint16_t)(((__uint16_t)(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen
) & 0xffU) << 8 | ((__uint16_t)(ip6->ip6_ctlun.ip6_un1
.ip6_un1_plen) & 0xff00U) >> 8) : __swap16md(ip6->
ip6_ctlun.ip6_un1.ip6_un1_plen))
+ sizeof(*ip6));
651 do {
652 switch (proto) {
653 case IPPROTO_ROUTING43:
654 *offp = off;
655 if (rh_cnt++) {
656 /* more than one rh header present */
657 return (1);
658 }
659
660 if (off + sizeof(rthdr) > lim) {
661 /* packet to short to make sense */
662 return (1);
663 }
664
665 m_copydata(m, off, sizeof(rthdr), &rthdr);
666
667 if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_00) {
668 *offp += offsetof(struct ip6_rthdr, ip6r_type)__builtin_offsetof(struct ip6_rthdr, ip6r_type);
669 return (1);
670 }
671
672 off += (rthdr.ip6r_len + 1) * 8;
673 proto = rthdr.ip6r_nxt;
674 break;
675 case IPPROTO_AH51:
676 case IPPROTO_HOPOPTS0:
677 case IPPROTO_DSTOPTS60:
678 /* get next header and header length */
679 if (off + sizeof(opt6) > lim) {
680 /*
681 * Packet to short to make sense, we could
682 * reject the packet but as a router we
683 * should not do that so forward it.
684 */
685 return (0);
686 }
687
688 m_copydata(m, off, sizeof(opt6), &opt6);
689
690 if (proto == IPPROTO_AH51)
691 off += (opt6.ip6e_len + 2) * 4;
692 else
693 off += (opt6.ip6e_len + 1) * 8;
694 proto = opt6.ip6e_nxt;
695 break;
696 case IPPROTO_FRAGMENT44:
697 default:
698 /* end of header stack */
699 done = 1;
700 break;
701 }
702 } while (!done);
703
704 return (0);
705}
706
707/*
708 * Hop-by-Hop options header processing. If a valid jumbo payload option is
709 * included, the real payload length will be stored in plenp.
710 *
711 * rtalertp - XXX: should be stored in a more smart way
712 */
713int
714ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, struct mbuf **mp,
715 int *offp)
716{
717 struct mbuf *m = *mp;
718 int off = *offp, hbhlen;
719 struct ip6_hbh *hbh;
720
721 /* validation of the length of the header */
722 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m,do { struct mbuf *t; int tmp; if ((m)->m_hdr.mh_len >= (
sizeof(struct ip6_hdr)) + (sizeof(struct ip6_hbh))) (hbh) = (
struct ip6_hbh *)(((caddr_t)(((m))->m_hdr.mh_data)) + (sizeof
(struct ip6_hdr))); else { t = m_pulldown((m), (sizeof(struct
ip6_hdr)), (sizeof(struct ip6_hbh)), &tmp); if (t) { if (
t->m_hdr.mh_len < tmp + (sizeof(struct ip6_hbh))) panic
("m_pulldown malfunction"); (hbh) = (struct ip6_hbh *)(((caddr_t
)((t)->m_hdr.mh_data)) + tmp); } else { (hbh) = (struct ip6_hbh
*)((void *)0); (m) = ((void *)0); } } } while ( 0)
723 sizeof(struct ip6_hdr), sizeof(struct ip6_hbh))do { struct mbuf *t; int tmp; if ((m)->m_hdr.mh_len >= (
sizeof(struct ip6_hdr)) + (sizeof(struct ip6_hbh))) (hbh) = (
struct ip6_hbh *)(((caddr_t)(((m))->m_hdr.mh_data)) + (sizeof
(struct ip6_hdr))); else { t = m_pulldown((m), (sizeof(struct
ip6_hdr)), (sizeof(struct ip6_hbh)), &tmp); if (t) { if (
t->m_hdr.mh_len < tmp + (sizeof(struct ip6_hbh))) panic
("m_pulldown malfunction"); (hbh) = (struct ip6_hbh *)(((caddr_t
)((t)->m_hdr.mh_data)) + tmp); } else { (hbh) = (struct ip6_hbh
*)((void *)0); (m) = ((void *)0); } } } while ( 0)
;
724 if (hbh == NULL((void *)0)) {
725 ip6stat_inc(ip6s_tooshort);
726 return -1;
727 }
728 hbhlen = (hbh->ip6h_len + 1) << 3;
729 IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr),do { struct mbuf *t; int tmp; if ((m)->m_hdr.mh_len >= (
sizeof(struct ip6_hdr)) + (hbhlen)) (hbh) = (struct ip6_hbh *
)(((caddr_t)(((m))->m_hdr.mh_data)) + (sizeof(struct ip6_hdr
))); else { t = m_pulldown((m), (sizeof(struct ip6_hdr)), (hbhlen
), &tmp); if (t) { if (t->m_hdr.mh_len < tmp + (hbhlen
)) panic("m_pulldown malfunction"); (hbh) = (struct ip6_hbh *
)(((caddr_t)((t)->m_hdr.mh_data)) + tmp); } else { (hbh) =
(struct ip6_hbh *)((void *)0); (m) = ((void *)0); } } } while
( 0)
730 hbhlen)do { struct mbuf *t; int tmp; if ((m)->m_hdr.mh_len >= (
sizeof(struct ip6_hdr)) + (hbhlen)) (hbh) = (struct ip6_hbh *
)(((caddr_t)(((m))->m_hdr.mh_data)) + (sizeof(struct ip6_hdr
))); else { t = m_pulldown((m), (sizeof(struct ip6_hdr)), (hbhlen
), &tmp); if (t) { if (t->m_hdr.mh_len < tmp + (hbhlen
)) panic("m_pulldown malfunction"); (hbh) = (struct ip6_hbh *
)(((caddr_t)((t)->m_hdr.mh_data)) + tmp); } else { (hbh) =
(struct ip6_hbh *)((void *)0); (m) = ((void *)0); } } } while
( 0)
;
731 if (hbh == NULL((void *)0)) {
732 ip6stat_inc(ip6s_tooshort);
733 return -1;
734 }
735 off += hbhlen;
736 hbhlen -= sizeof(struct ip6_hbh);
737
738 if (ip6_process_hopopts(m, (u_int8_t *)hbh + sizeof(struct ip6_hbh),
739 hbhlen, rtalertp, plenp) < 0)
740 return (-1);
741
742 *offp = off;
743 *mp = m;
744 return (0);
745}
746
747/*
748 * Search header for all Hop-by-hop options and process each option.
749 * This function is separate from ip6_hopopts_input() in order to
750 * handle a case where the sending node itself process its hop-by-hop
751 * options header. In such a case, the function is called from ip6_output().
752 *
753 * The function assumes that hbh header is located right after the IPv6 header
754 * (RFC2460 p7), opthead is pointer into data content in m, and opthead to
755 * opthead + hbhlen is located in continuous memory region.
756 */
757int
758ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,
759 u_int32_t *rtalertp, u_int32_t *plenp)
760{
761 struct ip6_hdr *ip6;
762 int optlen = 0;
763 u_int8_t *opt = opthead;
764 u_int16_t rtalert_val;
765 u_int32_t jumboplen;
766 const int erroff = sizeof(struct ip6_hdr) + sizeof(struct ip6_hbh);
767
768 for (; hbhlen > 0; hbhlen -= optlen, opt += optlen) {
769 switch (*opt) {
770 case IP6OPT_PAD10x00:
771 optlen = 1;
772 break;
773 case IP6OPT_PADN0x01:
774 if (hbhlen < IP6OPT_MINLEN2) {
775 ip6stat_inc(ip6s_toosmall);
776 goto bad;
777 }
778 optlen = *(opt + 1) + 2;
779 break;
780 case IP6OPT_ROUTER_ALERT0x05:
781 /* XXX may need check for alignment */
782 if (hbhlen < IP6OPT_RTALERT_LEN4) {
783 ip6stat_inc(ip6s_toosmall);
784 goto bad;
785 }
786 if (*(opt + 1) != IP6OPT_RTALERT_LEN4 - 2) {
787 /* XXX stat */
788 icmp6_error(m, ICMP6_PARAM_PROB4,
789 ICMP6_PARAMPROB_HEADER0,
790 erroff + opt + 1 - opthead);
791 return (-1);
792 }
793 optlen = IP6OPT_RTALERT_LEN4;
794 memcpy((caddr_t)&rtalert_val, (caddr_t)(opt + 2), 2)__builtin_memcpy(((caddr_t)&rtalert_val), ((caddr_t)(opt +
2)), (2))
;
795 *rtalertp = ntohs(rtalert_val)(__uint16_t)(__builtin_constant_p(rtalert_val) ? (__uint16_t)
(((__uint16_t)(rtalert_val) & 0xffU) << 8 | ((__uint16_t
)(rtalert_val) & 0xff00U) >> 8) : __swap16md(rtalert_val
))
;
796 break;
797 case IP6OPT_JUMBO0xC2:
798 /* XXX may need check for alignment */
799 if (hbhlen < IP6OPT_JUMBO_LEN6) {
800 ip6stat_inc(ip6s_toosmall);
801 goto bad;
802 }
803 if (*(opt + 1) != IP6OPT_JUMBO_LEN6 - 2) {
804 /* XXX stat */
805 icmp6_error(m, ICMP6_PARAM_PROB4,
806 ICMP6_PARAMPROB_HEADER0,
807 erroff + opt + 1 - opthead);
808 return (-1);
809 }
810 optlen = IP6OPT_JUMBO_LEN6;
811
812 /*
813 * IPv6 packets that have non 0 payload length
814 * must not contain a jumbo payload option.
815 */
816 ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
817 if (ip6->ip6_plenip6_ctlun.ip6_un1.ip6_un1_plen) {
818 ip6stat_inc(ip6s_badoptions);
819 icmp6_error(m, ICMP6_PARAM_PROB4,
820 ICMP6_PARAMPROB_HEADER0,
821 erroff + opt - opthead);
822 return (-1);
823 }
824
825 /*
826 * We may see jumbolen in unaligned location, so
827 * we'd need to perform memcpy().
828 */
829 memcpy(&jumboplen, opt + 2, sizeof(jumboplen))__builtin_memcpy((&jumboplen), (opt + 2), (sizeof(jumboplen
)))
;
830 jumboplen = (u_int32_t)htonl(jumboplen)(__uint32_t)(__builtin_constant_p(jumboplen) ? (__uint32_t)((
(__uint32_t)(jumboplen) & 0xff) << 24 | ((__uint32_t
)(jumboplen) & 0xff00) << 8 | ((__uint32_t)(jumboplen
) & 0xff0000) >> 8 | ((__uint32_t)(jumboplen) &
0xff000000) >> 24) : __swap32md(jumboplen))
;
831
832#if 1
833 /*
834 * if there are multiple jumbo payload options,
835 * *plenp will be non-zero and the packet will be
836 * rejected.
837 * the behavior may need some debate in ipngwg -
838 * multiple options does not make sense, however,
839 * there's no explicit mention in specification.
840 */
841 if (*plenp != 0) {
842 ip6stat_inc(ip6s_badoptions);
843 icmp6_error(m, ICMP6_PARAM_PROB4,
844 ICMP6_PARAMPROB_HEADER0,
845 erroff + opt + 2 - opthead);
846 return (-1);
847 }
848#endif
849
850 /*
851 * jumbo payload length must be larger than 65535.
852 */
853 if (jumboplen <= IPV6_MAXPACKET65535) {
854 ip6stat_inc(ip6s_badoptions);
855 icmp6_error(m, ICMP6_PARAM_PROB4,
856 ICMP6_PARAMPROB_HEADER0,
857 erroff + opt + 2 - opthead);
858 return (-1);
859 }
860 *plenp = jumboplen;
861
862 break;
863 default: /* unknown option */
864 if (hbhlen < IP6OPT_MINLEN2) {
865 ip6stat_inc(ip6s_toosmall);
866 goto bad;
867 }
868 optlen = ip6_unknown_opt(opt, m,
869 erroff + opt - opthead);
870 if (optlen == -1)
871 return (-1);
872 optlen += 2;
873 break;
874 }
875 }
876
877 return (0);
878
879 bad:
880 m_freem(m);
881 return (-1);
882}
883
884/*
885 * Unknown option processing.
886 * The third argument `off' is the offset from the IPv6 header to the option,
887 * which allows returning an ICMPv6 error even if the IPv6 header and the
888 * option header are not continuous.
889 */
890int
891ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off)
892{
893 struct ip6_hdr *ip6;
894
895 switch (IP6OPT_TYPE(*optp)((*optp) & 0xC0)) {
896 case IP6OPT_TYPE_SKIP0x00: /* ignore the option */
897 return ((int)*(optp + 1));
898 case IP6OPT_TYPE_DISCARD0x40: /* silently discard */
899 m_freem(m);
900 return (-1);
901 case IP6OPT_TYPE_FORCEICMP0x80: /* send ICMP even if multicasted */
902 ip6stat_inc(ip6s_badoptions);
903 icmp6_error(m, ICMP6_PARAM_PROB4, ICMP6_PARAMPROB_OPTION2, off);
904 return (-1);
905 case IP6OPT_TYPE_ICMP0xC0: /* send ICMP if not multicasted */
906 ip6stat_inc(ip6s_badoptions);
907 ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
908 if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)((&ip6->ip6_dst)->__u6_addr.__u6_addr8[0] == 0xff) ||
909 (m->m_flagsm_hdr.mh_flags & (M_BCAST0x0100|M_MCAST0x0200)))
910 m_freem(m);
911 else
912 icmp6_error(m, ICMP6_PARAM_PROB4,
913 ICMP6_PARAMPROB_OPTION2, off);
914 return (-1);
915 }
916
917 m_freem(m); /* XXX: NOTREACHED */
918 return (-1);
919}
920
921/*
922 * Create the "control" list for this pcb.
923 *
924 * The routine will be called from upper layer handlers like udp_input().
925 * Thus the routine assumes that the caller (udp_input) have already
926 * called IP6_EXTHDR_CHECK() and all the extension headers are located in the
927 * very first mbuf on the mbuf chain.
928 * We may want to add some infinite loop prevention or sanity checks for safety.
929 * (This applies only when you are using KAME mbuf chain restriction, i.e.
930 * you are using IP6_EXTHDR_CHECK() not m_pulldown())
931 */
932void
933ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp)
934{
935 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
936
937 if (in6p->inp_socket->so_options & SO_TIMESTAMP0x0800) {
938 struct timeval tv;
939
940 m_microtime(m, &tv);
941 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
942 SCM_TIMESTAMP0x04, SOL_SOCKET0xffff);
943 if (*mp)
944 mp = &(*mp)->m_nextm_hdr.mh_next;
945 }
946
947 /* RFC 2292 sec. 5 */
948 if ((in6p->inp_flags & IN6P_PKTINFO0x010000) != 0) {
949 struct in6_pktinfo pi6;
950 memcpy(&pi6.ipi6_addr, &ip6->ip6_dst, sizeof(struct in6_addr))__builtin_memcpy((&pi6.ipi6_addr), (&ip6->ip6_dst)
, (sizeof(struct in6_addr)))
;
951 if (IN6_IS_SCOPE_EMBED(&pi6.ipi6_addr)(((((&pi6.ipi6_addr)->__u6_addr.__u6_addr8[0] == 0xfe)
&& (((&pi6.ipi6_addr)->__u6_addr.__u6_addr8[1
] & 0xc0) == 0x80))) || ((((&pi6.ipi6_addr)->__u6_addr
.__u6_addr8[0] == 0xff) && (((&pi6.ipi6_addr)->
__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))) || ((((&pi6
.ipi6_addr)->__u6_addr.__u6_addr8[0] == 0xff) && (
((&pi6.ipi6_addr)->__u6_addr.__u6_addr8[1] & 0x0f)
== 0x01))))
)
952 pi6.ipi6_addr.s6_addr16__u6_addr.__u6_addr16[1] = 0;
953 pi6.ipi6_ifindex = m ? m->m_pkthdrM_dat.MH.MH_pkthdr.ph_ifidx : 0;
954 *mp = sbcreatecontrol((caddr_t) &pi6,
955 sizeof(struct in6_pktinfo),
956 IPV6_PKTINFO46, IPPROTO_IPV641);
957 if (*mp)
958 mp = &(*mp)->m_nextm_hdr.mh_next;
959 }
960
961 if ((in6p->inp_flags & IN6P_HOPLIMIT0x020000) != 0) {
962 int hlim = ip6->ip6_hlimip6_ctlun.ip6_un1.ip6_un1_hlim & 0xff;
963 *mp = sbcreatecontrol((caddr_t) &hlim, sizeof(int),
964 IPV6_HOPLIMIT47, IPPROTO_IPV641);
965 if (*mp)
966 mp = &(*mp)->m_nextm_hdr.mh_next;
967 }
968
969 if ((in6p->inp_flags & IN6P_TCLASS0x400000) != 0) {
970 u_int32_t flowinfo;
971 int tclass;
972
973 flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK)(__uint32_t)(__builtin_constant_p(ip6->ip6_ctlun.ip6_un1.ip6_un1_flow
& 0xffffff0f) ? (__uint32_t)(((__uint32_t)(ip6->ip6_ctlun
.ip6_un1.ip6_un1_flow & 0xffffff0f) & 0xff) << 24
| ((__uint32_t)(ip6->ip6_ctlun.ip6_un1.ip6_un1_flow &
0xffffff0f) & 0xff00) << 8 | ((__uint32_t)(ip6->
ip6_ctlun.ip6_un1.ip6_un1_flow & 0xffffff0f) & 0xff0000
) >> 8 | ((__uint32_t)(ip6->ip6_ctlun.ip6_un1.ip6_un1_flow
& 0xffffff0f) & 0xff000000) >> 24) : __swap32md
(ip6->ip6_ctlun.ip6_un1.ip6_un1_flow & 0xffffff0f))
;
974 flowinfo >>= 20;
975
976 tclass = flowinfo & 0xff;
977 *mp = sbcreatecontrol((caddr_t)&tclass, sizeof(tclass),
978 IPV6_TCLASS61, IPPROTO_IPV641);
979 if (*mp)
980 mp = &(*mp)->m_nextm_hdr.mh_next;
981 }
982
983 /*
984 * IPV6_HOPOPTS socket option. Recall that we required super-user
985 * privilege for the option (see ip6_ctloutput), but it might be too
986 * strict, since there might be some hop-by-hop options which can be
987 * returned to normal user.
988 * See also RFC 2292 section 6 (or RFC 3542 section 8).
989 */
990 if ((in6p->inp_flags & IN6P_HOPOPTS0x040000) != 0) {
991 /*
992 * Check if a hop-by-hop options header is contained in the
993 * received packet, and if so, store the options as ancillary
994 * data. Note that a hop-by-hop options header must be
995 * just after the IPv6 header, which is assured through the
996 * IPv6 input processing.
997 */
998 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
999 if (ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_HOPOPTS0) {
1000 struct ip6_hbh *hbh;
1001 int hbhlen = 0;
1002 struct mbuf *ext;
1003
1004 ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr),
1005 ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt);
1006 if (ext == NULL((void *)0)) {
1007 ip6stat_inc(ip6s_tooshort);
1008 return;
1009 }
1010 hbh = mtod(ext, struct ip6_hbh *)((struct ip6_hbh *)((ext)->m_hdr.mh_data));
1011 hbhlen = (hbh->ip6h_len + 1) << 3;
1012 if (hbhlen != ext->m_lenm_hdr.mh_len) {
1013 m_freem(ext);
1014 ip6stat_inc(ip6s_tooshort);
1015 return;
1016 }
1017
1018 /*
1019 * XXX: We copy the whole header even if a
1020 * jumbo payload option is included, the option which
1021 * is to be removed before returning according to
1022 * RFC2292.
1023 * Note: this constraint is removed in RFC3542.
1024 */
1025 *mp = sbcreatecontrol((caddr_t)hbh, hbhlen,
1026 IPV6_HOPOPTS49,
1027 IPPROTO_IPV641);
1028 if (*mp)
1029 mp = &(*mp)->m_nextm_hdr.mh_next;
1030 m_freem(ext);
1031 }
1032 }
1033
1034 /* IPV6_DSTOPTS and IPV6_RTHDR socket options */
1035 if ((in6p->inp_flags & (IN6P_RTHDR0x100000 | IN6P_DSTOPTS0x080000)) != 0) {
1036 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
1037 int nxt = ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt, off = sizeof(struct ip6_hdr);
1038
1039 /*
1040 * Search for destination options headers or routing
1041 * header(s) through the header chain, and stores each
1042 * header as ancillary data.
1043 * Note that the order of the headers remains in
1044 * the chain of ancillary data.
1045 */
1046 while (1) { /* is explicit loop prevention necessary? */
1047 struct ip6_ext *ip6e = NULL((void *)0);
1048 int elen;
1049 struct mbuf *ext = NULL((void *)0);
1050
1051 /*
1052 * if it is not an extension header, don't try to
1053 * pull it from the chain.
1054 */
1055 switch (nxt) {
1056 case IPPROTO_DSTOPTS60:
1057 case IPPROTO_ROUTING43:
1058 case IPPROTO_HOPOPTS0:
1059 case IPPROTO_AH51: /* is it possible? */
1060 break;
1061 default:
1062 goto loopend;
1063 }
1064
1065 ext = ip6_pullexthdr(m, off, nxt);
1066 if (ext == NULL((void *)0)) {
1067 ip6stat_inc(ip6s_tooshort);
1068 return;
1069 }
1070 ip6e = mtod(ext, struct ip6_ext *)((struct ip6_ext *)((ext)->m_hdr.mh_data));
1071 if (nxt == IPPROTO_AH51)
1072 elen = (ip6e->ip6e_len + 2) << 2;
1073 else
1074 elen = (ip6e->ip6e_len + 1) << 3;
1075 if (elen != ext->m_lenm_hdr.mh_len) {
1076 m_freem(ext);
1077 ip6stat_inc(ip6s_tooshort);
1078 return;
1079 }
1080
1081 switch (nxt) {
1082 case IPPROTO_DSTOPTS60:
1083 if (!(in6p->inp_flags & IN6P_DSTOPTS0x080000))
1084 break;
1085
1086 *mp = sbcreatecontrol((caddr_t)ip6e, elen,
1087 IPV6_DSTOPTS50,
1088 IPPROTO_IPV641);
1089 if (*mp)
1090 mp = &(*mp)->m_nextm_hdr.mh_next;
1091 break;
1092
1093 case IPPROTO_ROUTING43:
1094 if (!(in6p->inp_flags & IN6P_RTHDR0x100000))
1095 break;
1096
1097 *mp = sbcreatecontrol((caddr_t)ip6e, elen,
1098 IPV6_RTHDR51,
1099 IPPROTO_IPV641);
1100 if (*mp)
1101 mp = &(*mp)->m_nextm_hdr.mh_next;
1102 break;
1103
1104 case IPPROTO_HOPOPTS0:
1105 case IPPROTO_AH51: /* is it possible? */
1106 break;
1107
1108 default:
1109 /*
1110 * other cases have been filtered in the above.
1111 * none will visit this case. here we supply
1112 * the code just in case (nxt overwritten or
1113 * other cases).
1114 */
1115 m_freem(ext);
1116 goto loopend;
1117
1118 }
1119
1120 /* proceed with the next header. */
1121 off += elen;
1122 nxt = ip6e->ip6e_nxt;
1123 ip6e = NULL((void *)0);
1124 m_freem(ext);
1125 ext = NULL((void *)0);
1126 }
1127loopend:
1128 ;
1129 }
1130}
1131
1132/*
1133 * pull single extension header from mbuf chain. returns single mbuf that
1134 * contains the result, or NULL on error.
1135 */
1136struct mbuf *
1137ip6_pullexthdr(struct mbuf *m, size_t off, int nxt)
1138{
1139 struct ip6_ext ip6e;
1140 size_t elen;
1141 struct mbuf *n;
1142
1143#ifdef DIAGNOSTIC1
1144 switch (nxt) {
1145 case IPPROTO_DSTOPTS60:
1146 case IPPROTO_ROUTING43:
1147 case IPPROTO_HOPOPTS0:
1148 case IPPROTO_AH51: /* is it possible? */
1149 break;
1150 default:
1151 printf("ip6_pullexthdr: invalid nxt=%d\n", nxt);
1152 }
1153#endif
1154
1155 if (off + sizeof(ip6e) > m->m_pkthdrM_dat.MH.MH_pkthdr.len)
1156 return NULL((void *)0);
1157
1158 m_copydata(m, off, sizeof(ip6e), &ip6e);
1159 if (nxt == IPPROTO_AH51)
1160 elen = (ip6e.ip6e_len + 2) << 2;
1161 else
1162 elen = (ip6e.ip6e_len + 1) << 3;
1163
1164 if (off + elen > m->m_pkthdrM_dat.MH.MH_pkthdr.len)
1165 return NULL((void *)0);
1166
1167 MGET(n, M_DONTWAIT, MT_DATA)n = m_get((0x0002), (1));
1168 if (n && elen >= MLEN(256 - sizeof(struct m_hdr))) {
1169 MCLGET(n, M_DONTWAIT)(void) m_clget((n), (0x0002), (1 << 11));
1170 if ((n->m_flagsm_hdr.mh_flags & M_EXT0x0001) == 0) {
1171 m_free(n);
1172 n = NULL((void *)0);
1173 }
1174 }
1175 if (!n)
1176 return NULL((void *)0);
1177
1178 n->m_lenm_hdr.mh_len = 0;
1179 if (elen >= m_trailingspace(n)) {
1180 m_free(n);
1181 return NULL((void *)0);
1182 }
1183
1184 m_copydata(m, off, elen, mtod(n, caddr_t)((caddr_t)((n)->m_hdr.mh_data)));
1185 n->m_lenm_hdr.mh_len = elen;
1186 return n;
1187}
1188
1189/*
1190 * Get offset to the previous header followed by the header
1191 * currently processed.
1192 */
1193int
1194ip6_get_prevhdr(struct mbuf *m, int off)
1195{
1196 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
1197
1198 if (off == sizeof(struct ip6_hdr)) {
1199 return offsetof(struct ip6_hdr, ip6_nxt)__builtin_offsetof(struct ip6_hdr, ip6_ctlun.ip6_un1.ip6_un1_nxt
)
;
1200 } else if (off < sizeof(struct ip6_hdr)) {
1201 panic("%s: off < sizeof(struct ip6_hdr)", __func__);
1202 } else {
1203 int len, nlen, nxt;
1204 struct ip6_ext ip6e;
1205
1206 nxt = ip6->ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt;
1207 len = sizeof(struct ip6_hdr);
1208 nlen = 0;
1209 while (len < off) {
1210 m_copydata(m, len, sizeof(ip6e), &ip6e);
1211
1212 switch (nxt) {
1213 case IPPROTO_FRAGMENT44:
1214 nlen = sizeof(struct ip6_frag);
1215 break;
1216 case IPPROTO_AH51:
1217 nlen = (ip6e.ip6e_len + 2) << 2;
1218 break;
1219 default:
1220 nlen = (ip6e.ip6e_len + 1) << 3;
1221 break;
1222 }
1223 len += nlen;
1224 nxt = ip6e.ip6e_nxt;
1225 }
1226
1227 return (len - nlen);
1228 }
1229}
1230
1231/*
1232 * get next header offset. m will be retained.
1233 */
1234int
1235ip6_nexthdr(struct mbuf *m, int off, int proto, int *nxtp)
1236{
1237 struct ip6_hdr ip6;
1238 struct ip6_ext ip6e;
1239 struct ip6_frag fh;
1240
1241 /* just in case */
1242 if (m == NULL((void *)0))
1243 panic("%s: m == NULL", __func__);
1244 if ((m->m_flagsm_hdr.mh_flags & M_PKTHDR0x0002) == 0 || m->m_pkthdrM_dat.MH.MH_pkthdr.len < off)
1245 return -1;
1246
1247 switch (proto) {
1248 case IPPROTO_IPV641:
1249 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len < off + sizeof(ip6))
1250 return -1;
1251 m_copydata(m, off, sizeof(ip6), &ip6);
1252 if (nxtp)
1253 *nxtp = ip6.ip6_nxtip6_ctlun.ip6_un1.ip6_un1_nxt;
1254 off += sizeof(ip6);
1255 return off;
1256
1257 case IPPROTO_FRAGMENT44:
1258 /*
1259 * terminate parsing if it is not the first fragment,
1260 * it does not make sense to parse through it.
1261 */
1262 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len < off + sizeof(fh))
1263 return -1;
1264 m_copydata(m, off, sizeof(fh), &fh);
1265 if ((fh.ip6f_offlg & IP6F_OFF_MASK0xf8ff) != 0)
1266 return -1;
1267 if (nxtp)
1268 *nxtp = fh.ip6f_nxt;
1269 off += sizeof(struct ip6_frag);
1270 return off;
1271
1272 case IPPROTO_AH51:
1273 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len < off + sizeof(ip6e))
1274 return -1;
1275 m_copydata(m, off, sizeof(ip6e), &ip6e);
1276 if (nxtp)
1277 *nxtp = ip6e.ip6e_nxt;
1278 off += (ip6e.ip6e_len + 2) << 2;
1279 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len < off)
1280 return -1;
1281 return off;
1282
1283 case IPPROTO_HOPOPTS0:
1284 case IPPROTO_ROUTING43:
1285 case IPPROTO_DSTOPTS60:
1286 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len < off + sizeof(ip6e))
1287 return -1;
1288 m_copydata(m, off, sizeof(ip6e), &ip6e);
1289 if (nxtp)
1290 *nxtp = ip6e.ip6e_nxt;
1291 off += (ip6e.ip6e_len + 1) << 3;
1292 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len < off)
1293 return -1;
1294 return off;
1295
1296 case IPPROTO_NONE59:
1297 case IPPROTO_ESP50:
1298 case IPPROTO_IPCOMP108:
1299 /* give up */
1300 return -1;
1301
1302 default:
1303 return -1;
1304 }
1305
1306 return -1;
1307}
1308
1309/*
1310 * get offset for the last header in the chain. m will be kept untainted.
1311 */
1312int
1313ip6_lasthdr(struct mbuf *m, int off, int proto, int *nxtp)
1314{
1315 int newoff;
1316 int nxt;
1317
1318 if (!nxtp) {
1319 nxt = -1;
1320 nxtp = &nxt;
1321 }
1322 while (1) {
1323 newoff = ip6_nexthdr(m, off, proto, nxtp);
1324 if (newoff < 0)
1325 return off;
1326 else if (newoff < off)
1327 return -1; /* invalid */
1328 else if (newoff == off)
1329 return newoff;
1330
1331 off = newoff;
1332 proto = *nxtp;
1333 }
1334}
1335
1336/*
1337 * System control for IP6
1338 */
1339
1340const u_char inet6ctlerrmap[PRC_NCMDS21] = {
1341 0, 0, 0, 0,
1342 0, EMSGSIZE40, EHOSTDOWN64, EHOSTUNREACH65,
1343 EHOSTUNREACH65, EHOSTUNREACH65, ECONNREFUSED61, ECONNREFUSED61,
1344 EMSGSIZE40, EHOSTUNREACH65, 0, 0,
1345 0, 0, 0, 0,
1346 ENOPROTOOPT42
1347};
1348
1349#ifdef MROUTING1
1350extern int ip6_mrtproto;
1351#endif
1352
1353const struct sysctl_bounded_args ipv6ctl_vars[] = {
1354 { IPV6CTL_DAD_PENDING49, &ip6_dad_pending, SYSCTL_INT_READONLY1,0 },
1355#ifdef MROUTING1
1356 { IPV6CTL_MRTPROTO8, &ip6_mrtproto, SYSCTL_INT_READONLY1,0 },
1357#endif
1358 { IPV6CTL_FORWARDING1, &ip6_forwarding, 0, 1 },
1359 { IPV6CTL_SENDREDIRECTS2, &ip6_sendredirects, 0, 1 },
1360 { IPV6CTL_DEFHLIM3, &ip6_defhlim, 0, 255 },
1361 { IPV6CTL_MAXFRAGPACKETS9, &ip6_maxfragpackets, 0, 1000 },
1362 { IPV6CTL_LOG_INTERVAL14, &ip6_log_interval, 0, INT_MAX0x7fffffff },
1363 { IPV6CTL_HDRNESTLIMIT15, &ip6_hdrnestlimit, 0, 100 },
1364 { IPV6CTL_DAD_COUNT16, &ip6_dad_count, 0, 10 },
1365 { IPV6CTL_AUTO_FLOWLABEL17, &ip6_auto_flowlabel, 0, 1 },
1366 { IPV6CTL_DEFMCASTHLIM18, &ip6_defmcasthlim, 0, 255 },
1367 { IPV6CTL_USE_DEPRECATED21, &ip6_use_deprecated, 0, 1 },
1368 { IPV6CTL_MAXFRAGS41, &ip6_maxfrags, 0, 1000 },
1369 { IPV6CTL_MFORWARDING42, &ip6_mforwarding, 0, 1 },
1370 { IPV6CTL_MULTIPATH43, &ip6_multipath, 0, 1 },
1371 { IPV6CTL_MCAST_PMTU44, &ip6_mcast_pmtu, 0, 1 },
1372 { IPV6CTL_NEIGHBORGCTHRESH45, &ip6_neighborgcthresh, -1, 5 * 2048 },
1373 { IPV6CTL_MAXDYNROUTES48, &ip6_maxdynroutes, -1, 5 * 4096 },
1374};
1375
1376int
1377ip6_sysctl_ip6stat(void *oldp, size_t *oldlenp, void *newp)
1378{
1379 struct ip6stat *ip6stat;
1380 int ret;
1381
1382 CTASSERT(sizeof(*ip6stat) == (ip6s_ncounters * sizeof(uint64_t)))extern char _ctassert[(sizeof(*ip6stat) == (ip6s_ncounters * sizeof
(uint64_t))) ? 1 : -1 ] __attribute__((__unused__))
;
1383
1384 ip6stat = malloc(sizeof(*ip6stat), M_TEMP127, M_WAITOK0x0001);
1385 counters_read(ip6counters, (uint64_t *)ip6stat, ip6s_ncounters);
1386 ret = sysctl_rdstruct(oldp, oldlenp, newp,
1387 ip6stat, sizeof(*ip6stat));
1388 free(ip6stat, M_TEMP127, sizeof(*ip6stat));
1389
1390 return (ret);
1391}
1392
1393int
1394ip6_sysctl_soiikey(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
1395{
1396 uint8_t oldkey[IP6_SOIIKEY_LEN16];
1397 int error;
1398
1399 error = suser(curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc
);
1400 if (error != 0)
1401 return (error);
1402
1403 memcpy(oldkey, ip6_soiikey, sizeof(oldkey))__builtin_memcpy((oldkey), (ip6_soiikey), (sizeof(oldkey)));
1404
1405 error = sysctl_struct(oldp, oldlenp, newp, newlen, ip6_soiikey,
1406 sizeof(ip6_soiikey));
1407
1408 return (error);
1409}
1410
1411int
1412ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1413 void *newp, size_t newlen)
1414{
1415#ifdef MROUTING1
1416 extern struct mrt6stat mrt6stat;
1417#endif
1418 int error;
1419
1420 /* Almost all sysctl names at this level are terminal. */
1421 if (namelen != 1 && name[0] != IPV6CTL_IFQUEUE51)
1422 return (ENOTDIR20);
1423
1424 switch (name[0]) {
1425 case IPV6CTL_STATS6:
1426 return (ip6_sysctl_ip6stat(oldp, oldlenp, newp));
1427#ifdef MROUTING1
1428 case IPV6CTL_MRTSTATS7:
1429 if (newp != NULL((void *)0))
1430 return (EPERM1);
1431 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1432 error = sysctl_struct(oldp, oldlenp, newp, newlen,
1433 &mrt6stat, sizeof(mrt6stat));
1434 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1435 return (error);
1436 case IPV6CTL_MRTMIF52:
1437 if (newp)
1438 return (EPERM1);
1439 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1440 error = mrt6_sysctl_mif(oldp, oldlenp);
1441 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1442 return (error);
1443 case IPV6CTL_MRTMFC53:
1444 if (newp)
1445 return (EPERM1);
1446 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1447 error = mrt6_sysctl_mfc(oldp, oldlenp);
1448 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1449 return (error);
1450#else
1451 case IPV6CTL_MRTSTATS7:
1452 case IPV6CTL_MRTPROTO8:
1453 case IPV6CTL_MRTMIF52:
1454 case IPV6CTL_MRTMFC53:
1455 return (EOPNOTSUPP45);
1456#endif
1457 case IPV6CTL_MTUDISCTIMEOUT50:
1458 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1459 error = sysctl_int(oldp, oldlenp, newp, newlen,
1460 &ip6_mtudisc_timeout);
1461 if (icmp6_mtudisc_timeout_q != NULL((void *)0))
1462 rt_timer_queue_change(icmp6_mtudisc_timeout_q,
1463 ip6_mtudisc_timeout);
1464 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1465 return (error);
1466 case IPV6CTL_IFQUEUE51:
1467 return (EOPNOTSUPP45);
1468 case IPV6CTL_SOIIKEY54:
1469 return (ip6_sysctl_soiikey(oldp, oldlenp, newp, newlen));
1470 default:
1471 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1472 error = sysctl_bounded_arr(ipv6ctl_vars, nitems(ipv6ctl_vars)(sizeof((ipv6ctl_vars)) / sizeof((ipv6ctl_vars)[0])),
1473 name, namelen, oldp, oldlenp, newp, newlen);
1474 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1475 return (error);
1476 }
1477 /* NOTREACHED */
1478}
1479
1480void
1481ip6_send_dispatch(void *xmq)
1482{
1483 struct mbuf_queue *mq = xmq;
1484 struct mbuf *m;
1485 struct mbuf_list ml;
1486
1487 mq_delist(mq, &ml);
1488 if (ml_empty(&ml)((&ml)->ml_len == 0))
1489 return;
1490
1491 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1492 while ((m = ml_dequeue(&ml)) != NULL((void *)0)) {
1493 ip6_output(m, NULL((void *)0), NULL((void *)0), 0, NULL((void *)0), NULL((void *)0));
1494 }
1495 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1496}
1497
1498void
1499ip6_send(struct mbuf *m)
1500{
1501 mq_enqueue(&ip6send_mq, m);
1502 task_add(net_tq(0), &ip6send_task);
1503}