Bug Summary

File:netinet/ip_input.c
Warning:line 1807, column 4
Value stored to 'mp' is never read

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 ip_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/netinet/ip_input.c
1/* $OpenBSD: ip_input.c,v 1.364 2021/11/22 13:47:10 bluhm Exp $ */
2/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
3
4/*
5 * Copyright (c) 1982, 1986, 1988, 1993
6 * The Regents of the University of California. 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 University 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 REGENTS 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 REGENTS 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 * @(#)ip_input.c 8.2 (Berkeley) 1/4/94
33 */
34
35#include "pf.h"
36#include "carp.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/mbuf.h>
41#include <sys/domain.h>
42#include <sys/mutex.h>
43#include <sys/protosw.h>
44#include <sys/socket.h>
45#include <sys/socketvar.h>
46#include <sys/sysctl.h>
47#include <sys/pool.h>
48#include <sys/task.h>
49
50#include <net/if.h>
51#include <net/if_var.h>
52#include <net/if_dl.h>
53#include <net/route.h>
54#include <net/netisr.h>
55
56#include <netinet/in.h>
57#include <netinet/in_systm.h>
58#include <netinet/if_ether.h>
59#include <netinet/ip.h>
60#include <netinet/in_pcb.h>
61#include <netinet/in_var.h>
62#include <netinet/ip_var.h>
63#include <netinet/ip_icmp.h>
64#include <net/if_types.h>
65
66#ifdef INET61
67#include <netinet6/ip6protosw.h>
68#include <netinet6/ip6_var.h>
69#endif
70
71#if NPF1 > 0
72#include <net/pfvar.h>
73#endif
74
75#ifdef MROUTING1
76#include <netinet/ip_mroute.h>
77#endif
78
79#ifdef IPSEC1
80#include <netinet/ip_ipsp.h>
81#endif /* IPSEC */
82
83#if NCARP1 > 0
84#include <netinet/ip_carp.h>
85#endif
86
87/* values controllable via sysctl */
88int ipforwarding = 0;
89int ipmforwarding = 0;
90int ipmultipath = 0;
91int ipsendredirects = 1;
92int ip_dosourceroute = 0;
93int ip_defttl = IPDEFTTL64;
94int ip_mtudisc = 1;
95u_int ip_mtudisc_timeout = IPMTUDISCTIMEOUT(10 * 60);
96int ip_directedbcast = 0;
97
98struct rttimer_queue *ip_mtudisc_timeout_q = NULL((void *)0);
99
100/* Protects `ipq' and `ip_frags'. */
101struct mutex ipq_mutex = MUTEX_INITIALIZER(IPL_SOFTNET){ ((void *)0), ((((0x5)) > 0x0 && ((0x5)) < 0x9
) ? 0x9 : ((0x5))), 0x0 }
;
102
103/* IP reassembly queue */
104LIST_HEAD(, ipq)struct { struct ipq *lh_first; } ipq;
105
106/* Keep track of memory used for reassembly */
107int ip_maxqueue = 300;
108int ip_frags = 0;
109
110#ifdef MROUTING1
111extern int ip_mrtproto;
112#endif
113
114const struct sysctl_bounded_args ipctl_vars[] = {
115#ifdef MROUTING1
116 { IPCTL_MRTPROTO34, &ip_mrtproto, SYSCTL_INT_READONLY1,0 },
117#endif
118 { IPCTL_FORWARDING1, &ipforwarding, 0, 2 },
119 { IPCTL_SENDREDIRECTS2, &ipsendredirects, 0, 1 },
120 { IPCTL_DEFTTL3, &ip_defttl, 0, 255 },
121 { IPCTL_DIRECTEDBCAST6, &ip_directedbcast, 0, 1 },
122 { IPCTL_IPPORT_FIRSTAUTO7, &ipport_firstauto, 0, 65535 },
123 { IPCTL_IPPORT_LASTAUTO8, &ipport_lastauto, 0, 65535 },
124 { IPCTL_IPPORT_HIFIRSTAUTO9, &ipport_hifirstauto, 0, 65535 },
125 { IPCTL_IPPORT_HILASTAUTO10, &ipport_hilastauto, 0, 65535 },
126 { IPCTL_IPPORT_MAXQUEUE11, &ip_maxqueue, 0, 10000 },
127 { IPCTL_MFORWARDING31, &ipmforwarding, 0, 1 },
128 { IPCTL_MULTIPATH32, &ipmultipath, 0, 1 },
129 { IPCTL_ARPTIMEOUT39, &arpt_keep, 0, INT_MAX0x7fffffff },
130 { IPCTL_ARPDOWN40, &arpt_down, 0, INT_MAX0x7fffffff },
131};
132
133struct pool ipqent_pool;
134struct pool ipq_pool;
135
136struct cpumem *ipcounters;
137
138int ip_sysctl_ipstat(void *, size_t *, void *);
139
140static struct mbuf_queue ipsend_mq;
141static struct mbuf_queue ipsendraw_mq;
142
143extern struct niqueue arpinq;
144
145int ip_ours(struct mbuf **, int *, int, int);
146int ip_dooptions(struct mbuf *, struct ifnet *);
147int in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **);
148
149static void ip_send_dispatch(void *);
150static void ip_sendraw_dispatch(void *);
151static struct task ipsend_task = TASK_INITIALIZER(ip_send_dispatch, &ipsend_mq){{ ((void *)0), ((void *)0) }, (ip_send_dispatch), (&ipsend_mq
), 0 }
;
152static struct task ipsendraw_task =
153 TASK_INITIALIZER(ip_sendraw_dispatch, &ipsendraw_mq){{ ((void *)0), ((void *)0) }, (ip_sendraw_dispatch), (&ipsendraw_mq
), 0 }
;
154
155/*
156 * Used to save the IP options in case a protocol wants to respond
157 * to an incoming packet over the same route if the packet got here
158 * using IP source routing. This allows connection establishment and
159 * maintenance when the remote end is on a network that is not known
160 * to us.
161 */
162struct ip_srcrt {
163 int isr_nhops; /* number of hops */
164 struct in_addr isr_dst; /* final destination */
165 char isr_nop; /* one NOP to align */
166 char isr_hdr[IPOPT_OFFSET2 + 1]; /* OPTVAL, OLEN & OFFSET */
167 struct in_addr isr_routes[MAX_IPOPTLEN40/sizeof(struct in_addr)];
168};
169
170void save_rte(struct mbuf *, u_char *, struct in_addr);
171
172/*
173 * IP initialization: fill in IP protocol switch table.
174 * All protocols not implemented in kernel go to raw IP protocol handler.
175 */
176void
177ip_init(void)
178{
179 const struct protosw *pr;
180 int i;
181 const u_int16_t defbaddynamicports_tcp[] = DEFBADDYNAMICPORTS_TCP{ 587, 749, 750, 751, 853, 871, 2049, 6000, 6001, 6002, 6003,
6004, 6005, 6006, 6007, 6008, 6009, 6010, 0 }
;
182 const u_int16_t defbaddynamicports_udp[] = DEFBADDYNAMICPORTS_UDP{ 623, 664, 749, 750, 751, 2049, 3784, 3785, 7784, 0 };
183 const u_int16_t defrootonlyports_tcp[] = DEFROOTONLYPORTS_TCP{ 2049, 0 };
184 const u_int16_t defrootonlyports_udp[] = DEFROOTONLYPORTS_UDP{ 2049, 0 };
185
186 ipcounters = counters_alloc(ips_ncounters);
187
188 pool_init(&ipqent_pool, sizeof(struct ipqent), 0,
189 IPL_SOFTNET0x5, 0, "ipqe", NULL((void *)0));
190 pool_init(&ipq_pool, sizeof(struct ipq), 0,
191 IPL_SOFTNET0x5, 0, "ipq", NULL((void *)0));
192
193 pr = pffindproto(PF_INET2, IPPROTO_RAW255, SOCK_RAW3);
194 if (pr == NULL((void *)0))
195 panic("ip_init");
196 for (i = 0; i < IPPROTO_MAX256; i++)
197 ip_protox[i] = pr - inetsw;
198 for (pr = inetdomain.dom_protosw;
199 pr < inetdomain.dom_protoswNPROTOSW; pr++)
200 if (pr->pr_domain->dom_family == PF_INET2 &&
201 pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW255 &&
202 pr->pr_protocol < IPPROTO_MAX256)
203 ip_protox[pr->pr_protocol] = pr - inetsw;
204 LIST_INIT(&ipq)do { ((&ipq)->lh_first) = ((void *)0); } while (0);
205 if (ip_mtudisc != 0)
206 ip_mtudisc_timeout_q =
207 rt_timer_queue_create(ip_mtudisc_timeout);
208
209 /* Fill in list of ports not to allocate dynamically. */
210 memset(&baddynamicports, 0, sizeof(baddynamicports))__builtin_memset((&baddynamicports), (0), (sizeof(baddynamicports
)))
;
211 for (i = 0; defbaddynamicports_tcp[i] != 0; i++)
212 DP_SET(baddynamicports.tcp, defbaddynamicports_tcp[i])((baddynamicports.tcp)[(defbaddynamicports_tcp[i]) / (sizeof(
u_int32_t) * 8)] |= (1 << ((defbaddynamicports_tcp[i]) %
(sizeof(u_int32_t) * 8))))
;
213 for (i = 0; defbaddynamicports_udp[i] != 0; i++)
214 DP_SET(baddynamicports.udp, defbaddynamicports_udp[i])((baddynamicports.udp)[(defbaddynamicports_udp[i]) / (sizeof(
u_int32_t) * 8)] |= (1 << ((defbaddynamicports_udp[i]) %
(sizeof(u_int32_t) * 8))))
;
215
216 /* Fill in list of ports only root can bind to. */
217 memset(&rootonlyports, 0, sizeof(rootonlyports))__builtin_memset((&rootonlyports), (0), (sizeof(rootonlyports
)))
;
218 for (i = 0; defrootonlyports_tcp[i] != 0; i++)
219 DP_SET(rootonlyports.tcp, defrootonlyports_tcp[i])((rootonlyports.tcp)[(defrootonlyports_tcp[i]) / (sizeof(u_int32_t
) * 8)] |= (1 << ((defrootonlyports_tcp[i]) % (sizeof(u_int32_t
) * 8))))
;
220 for (i = 0; defrootonlyports_udp[i] != 0; i++)
221 DP_SET(rootonlyports.udp, defrootonlyports_udp[i])((rootonlyports.udp)[(defrootonlyports_udp[i]) / (sizeof(u_int32_t
) * 8)] |= (1 << ((defrootonlyports_udp[i]) % (sizeof(u_int32_t
) * 8))))
;
222
223 mq_init(&ipsend_mq, 64, IPL_SOFTNET0x5);
224 mq_init(&ipsendraw_mq, 64, IPL_SOFTNET0x5);
225
226 arpinit();
227#ifdef IPSEC1
228 ipsec_init();
229#endif
230}
231
232/*
233 * IPv4 input routine.
234 *
235 * Checksum and byte swap header. Process options. Forward or deliver.
236 */
237void
238ipv4_input(struct ifnet *ifp, struct mbuf *m)
239{
240 int off, nxt;
241
242 off = 0;
243 nxt = ip_input_if(&m, &off, IPPROTO_IPV44, AF_UNSPEC0, ifp);
244 KASSERT(nxt == IPPROTO_DONE)((nxt == 257) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/netinet/ip_input.c"
, 244, "nxt == IPPROTO_DONE"))
;
245}
246
247struct mbuf *
248ipv4_check(struct ifnet *ifp, struct mbuf *m)
249{
250 struct ip *ip;
251 int hlen, len;
252
253 if (m->m_lenm_hdr.mh_len < sizeof(*ip)) {
254 m = m_pullup(m, sizeof(*ip));
255 if (m == NULL((void *)0)) {
256 ipstat_inc(ips_toosmall);
257 return (NULL((void *)0));
258 }
259 }
260
261 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
262 if (ip->ip_v != IPVERSION4) {
263 ipstat_inc(ips_badvers);
264 goto bad;
265 }
266
267 hlen = ip->ip_hl << 2;
268 if (hlen < sizeof(*ip)) { /* minimum header length */
269 ipstat_inc(ips_badhlen);
270 goto bad;
271 }
272 if (hlen > m->m_lenm_hdr.mh_len) {
273 m = m_pullup(m, hlen);
274 if (m == NULL((void *)0)) {
275 ipstat_inc(ips_badhlen);
276 return (NULL((void *)0));
277 }
278 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
279 }
280
281 /* 127/8 must not appear on wire - RFC1122 */
282 if ((ntohl(ip->ip_dst.s_addr)(__uint32_t)(__builtin_constant_p(ip->ip_dst.s_addr) ? (__uint32_t
)(((__uint32_t)(ip->ip_dst.s_addr) & 0xff) << 24
| ((__uint32_t)(ip->ip_dst.s_addr) & 0xff00) <<
8 | ((__uint32_t)(ip->ip_dst.s_addr) & 0xff0000) >>
8 | ((__uint32_t)(ip->ip_dst.s_addr) & 0xff000000) >>
24) : __swap32md(ip->ip_dst.s_addr))
>> IN_CLASSA_NSHIFT24) == IN_LOOPBACKNET127 ||
283 (ntohl(ip->ip_src.s_addr)(__uint32_t)(__builtin_constant_p(ip->ip_src.s_addr) ? (__uint32_t
)(((__uint32_t)(ip->ip_src.s_addr) & 0xff) << 24
| ((__uint32_t)(ip->ip_src.s_addr) & 0xff00) <<
8 | ((__uint32_t)(ip->ip_src.s_addr) & 0xff0000) >>
8 | ((__uint32_t)(ip->ip_src.s_addr) & 0xff000000) >>
24) : __swap32md(ip->ip_src.s_addr))
>> IN_CLASSA_NSHIFT24) == IN_LOOPBACKNET127) {
284 if ((ifp->if_flags & IFF_LOOPBACK0x8) == 0) {
285 ipstat_inc(ips_badaddr);
286 goto bad;
287 }
288 }
289
290 if (!ISSET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_IN_OK)((m->M_dat.MH.MH_pkthdr.csum_flags) & (0x0008))) {
291 if (ISSET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_IN_BAD)((m->M_dat.MH.MH_pkthdr.csum_flags) & (0x0010))) {
292 ipstat_inc(ips_badsum);
293 goto bad;
294 }
295
296 ipstat_inc(ips_inswcsum);
297 if (in_cksum(m, hlen) != 0) {
298 ipstat_inc(ips_badsum);
299 goto bad;
300 }
301
302 SET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_IN_OK)((m->M_dat.MH.MH_pkthdr.csum_flags) |= (0x0008));
303 }
304
305 /* Retrieve the packet length. */
306 len = ntohs(ip->ip_len)(__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t
)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t
)(ip->ip_len) & 0xff00U) >> 8) : __swap16md(ip->
ip_len))
;
307
308 /*
309 * Convert fields to host representation.
310 */
311 if (len < hlen) {
312 ipstat_inc(ips_badlen);
313 goto bad;
314 }
315
316 /*
317 * Check that the amount of data in the buffers
318 * is at least as much as the IP header would have us expect.
319 * Trim mbufs if longer than we expect.
320 * Drop packet if shorter than we expect.
321 */
322 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len < len) {
323 ipstat_inc(ips_tooshort);
324 goto bad;
325 }
326 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len > len) {
327 if (m->m_lenm_hdr.mh_len == m->m_pkthdrM_dat.MH.MH_pkthdr.len) {
328 m->m_lenm_hdr.mh_len = len;
329 m->m_pkthdrM_dat.MH.MH_pkthdr.len = len;
330 } else
331 m_adj(m, len - m->m_pkthdrM_dat.MH.MH_pkthdr.len);
332 }
333
334 return (m);
335bad:
336 m_freem(m);
337 return (NULL((void *)0));
338}
339
340int
341ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
342{
343 struct mbuf *m;
344 struct rtentry *rt = NULL((void *)0);
345 struct ip *ip;
346 int hlen;
347 in_addr_t pfrdr = 0;
348
349 KASSERT(*offp == 0)((*offp == 0) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/netinet/ip_input.c"
, 349, "*offp == 0"))
;
350
351 ipstat_inc(ips_total);
352 m = *mp = ipv4_check(ifp, *mp);
353 if (m == NULL((void *)0))
354 goto bad;
355
356 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
357
358#if NCARP1 > 0
359 if (carp_lsdrop(ifp, m, AF_INET2, &ip->ip_src.s_addr,
360 &ip->ip_dst.s_addr, (ip->ip_p == IPPROTO_ICMP1 ? 0 : 1)))
361 goto bad;
362#endif
363
364#if NPF1 > 0
365 /*
366 * Packet filter
367 */
368 pfrdr = ip->ip_dst.s_addr;
369 if (pf_test(AF_INET2, PF_IN, ifp, mp) != PF_PASS)
370 goto bad;
371 m = *mp;
372 if (m == NULL((void *)0))
373 goto bad;
374
375 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
376 pfrdr = (pfrdr != ip->ip_dst.s_addr);
377#endif
378
379 hlen = ip->ip_hl << 2;
380
381 /*
382 * Process options and, if not destined for us,
383 * ship it on. ip_dooptions returns 1 when an
384 * error was detected (causing an icmp message
385 * to be sent and the original packet to be freed).
386 */
387 if (hlen > sizeof (struct ip) && ip_dooptions(m, ifp)) {
388 m = *mp = NULL((void *)0);
389 goto bad;
390 }
391
392 if (ip->ip_dst.s_addr == INADDR_BROADCAST((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xffffffff
)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xffffffff)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)(0xffffffff)) &
0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xffffffff)) &
0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xffffffff)
) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0xffffffff
))))
||
393 ip->ip_dst.s_addr == INADDR_ANY((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x00000000
)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000000)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000000)) &
0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000000)) &
0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000000)
) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00000000
))))
) {
394 nxt = ip_ours(mp, offp, nxt, af);
395 goto out;
396 }
397
398 switch(in_ouraddr(m, ifp, &rt)) {
399 case 2:
400 goto bad;
401 case 1:
402 nxt = ip_ours(mp, offp, nxt, af);
403 goto out;
404 }
405
406 if (IN_MULTICAST(ip->ip_dst.s_addr)(((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t
)(__builtin_constant_p((u_int32_t)(0xf0000000)) ? (__uint32_t
)(((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff00) <<
8 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff000000)
>> 24) : __swap32md((u_int32_t)(0xf0000000))))) == ((u_int32_t
) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff
) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff0000
) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)(0xe0000000)))))
) {
407 /*
408 * Make sure M_MCAST is set. It should theoretically
409 * already be there, but let's play safe because upper
410 * layers check for this flag.
411 */
412 m->m_flagsm_hdr.mh_flags |= M_MCAST0x0200;
413
414#ifdef MROUTING1
415 if (ipmforwarding && ip_mrouter[ifp->if_rdomainif_data.ifi_rdomain]) {
416 int error;
417
418 if (m->m_flagsm_hdr.mh_flags & M_EXT0x0001) {
419 if ((m = *mp = m_pullup(m, hlen)) == NULL((void *)0)) {
420 ipstat_inc(ips_toosmall);
421 goto bad;
422 }
423 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
424 }
425 /*
426 * If we are acting as a multicast router, all
427 * incoming multicast packets are passed to the
428 * kernel-level multicast forwarding function.
429 * The packet is returned (relatively) intact; if
430 * ip_mforward() returns a non-zero value, the packet
431 * must be discarded, else it may be accepted below.
432 *
433 * (The IP ident field is put in the same byte order
434 * as expected when ip_mforward() is called from
435 * ip_output().)
436 */
437 KERNEL_LOCK()_kernel_lock();
438 error = ip_mforward(m, ifp);
439 KERNEL_UNLOCK()_kernel_unlock();
440 if (error) {
441 ipstat_inc(ips_cantforward);
442 goto bad;
443 }
444
445 /*
446 * The process-level routing daemon needs to receive
447 * all multicast IGMP packets, whether or not this
448 * host belongs to their destination groups.
449 */
450 if (ip->ip_p == IPPROTO_IGMP2) {
451 nxt = ip_ours(mp, offp, nxt, af);
452 goto out;
453 }
454 ipstat_inc(ips_forward);
455 }
456#endif
457 /*
458 * See if we belong to the destination multicast group on the
459 * arrival interface.
460 */
461 if (!in_hasmulti(&ip->ip_dst, ifp)) {
462 ipstat_inc(ips_notmember);
463 if (!IN_LOCAL_GROUP(ip->ip_dst.s_addr)(((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t
)(__builtin_constant_p((u_int32_t)(0xffffff00)) ? (__uint32_t
)(((__uint32_t)((u_int32_t)(0xffffff00)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)(0xffffff00)) & 0xff00) <<
8 | ((__uint32_t)((u_int32_t)(0xffffff00)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)(0xffffff00)) & 0xff000000)
>> 24) : __swap32md((u_int32_t)(0xffffff00))))) == ((u_int32_t
) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff
) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff0000
) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)(0xe0000000)))))
)
464 ipstat_inc(ips_cantforward);
465 goto bad;
466 }
467 nxt = ip_ours(mp, offp, nxt, af);
468 goto out;
469 }
470
471#if NCARP1 > 0
472 if (ip->ip_p == IPPROTO_ICMP1 &&
473 carp_lsdrop(ifp, m, AF_INET2, &ip->ip_src.s_addr,
474 &ip->ip_dst.s_addr, 1))
475 goto bad;
476#endif
477 /*
478 * Not for us; forward if possible and desirable.
479 */
480 if (ipforwarding == 0) {
481 ipstat_inc(ips_cantforward);
482 goto bad;
483 }
484#ifdef IPSEC1
485 if (ipsec_in_use) {
486 int rv;
487
488 rv = ipsec_forward_check(m, hlen, AF_INET2);
489 if (rv != 0) {
490 ipstat_inc(ips_cantforward);
491 goto bad;
492 }
493 /*
494 * Fall through, forward packet. Outbound IPsec policy
495 * checking will occur in ip_output().
496 */
497 }
498#endif /* IPSEC */
499
500 ip_forward(m, ifp, rt, pfrdr);
501 *mp = NULL((void *)0);
502 return IPPROTO_DONE257;
503 bad:
504 nxt = IPPROTO_DONE257;
505 m_freemp(mp);
506 out:
507 rtfree(rt);
508 return nxt;
509}
510
511/*
512 * IPv4 local-delivery routine.
513 *
514 * If fragmented try to reassemble. Pass to next level.
515 */
516int
517ip_ours(struct mbuf **mp, int *offp, int nxt, int af)
518{
519 struct mbuf *m = *mp;
520 struct ip *ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
521 struct ipq *fp;
522 struct ipqent *ipqe;
523 int mff, hlen;
524
525 hlen = ip->ip_hl << 2;
526
527 /*
528 * If offset or IP_MF are set, must reassemble.
529 * Otherwise, nothing need be done.
530 * (We could look in the reassembly queue to see
531 * if the packet was previously fragmented,
532 * but it's not worth the time; just let them time out.)
533 */
534 if (ip->ip_off &~ htons(IP_DF | IP_RF)(__uint16_t)(__builtin_constant_p(0x4000 | 0x8000) ? (__uint16_t
)(((__uint16_t)(0x4000 | 0x8000) & 0xffU) << 8 | ((
__uint16_t)(0x4000 | 0x8000) & 0xff00U) >> 8) : __swap16md
(0x4000 | 0x8000))
) {
535 if (m->m_flagsm_hdr.mh_flags & M_EXT0x0001) { /* XXX */
536 if ((m = *mp = m_pullup(m, hlen)) == NULL((void *)0)) {
537 ipstat_inc(ips_toosmall);
538 return IPPROTO_DONE257;
539 }
540 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
541 }
542
543 mtx_enter(&ipq_mutex);
544
545 /*
546 * Look for queue of fragments
547 * of this datagram.
548 */
549 LIST_FOREACH(fp, &ipq, ipq_q)for((fp) = ((&ipq)->lh_first); (fp)!= ((void *)0); (fp
) = ((fp)->ipq_q.le_next))
{
550 if (ip->ip_id == fp->ipq_id &&
551 ip->ip_src.s_addr == fp->ipq_src.s_addr &&
552 ip->ip_dst.s_addr == fp->ipq_dst.s_addr &&
553 ip->ip_p == fp->ipq_p)
554 break;
555 }
556
557 /*
558 * Adjust ip_len to not reflect header,
559 * set ipqe_mff if more fragments are expected,
560 * convert offset of this to bytes.
561 */
562 ip->ip_len = htons(ntohs(ip->ip_len) - hlen)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) &
0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U
) >> 8) : __swap16md(ip->ip_len)) - hlen) ? (__uint16_t
)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) :
__swap16md(ip->ip_len)) - hlen) & 0xffU) << 8 |
((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) :
__swap16md(ip->ip_len)) - hlen) & 0xff00U) >> 8
) : __swap16md((__uint16_t)(__builtin_constant_p(ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) :
__swap16md(ip->ip_len)) - hlen))
;
563 mff = (ip->ip_off & htons(IP_MF)(__uint16_t)(__builtin_constant_p(0x2000) ? (__uint16_t)(((__uint16_t
)(0x2000) & 0xffU) << 8 | ((__uint16_t)(0x2000) &
0xff00U) >> 8) : __swap16md(0x2000))
) != 0;
564 if (mff) {
565 /*
566 * Make sure that fragments have a data length
567 * that's a non-zero multiple of 8 bytes.
568 */
569 if (ntohs(ip->ip_len)(__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t
)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t
)(ip->ip_len) & 0xff00U) >> 8) : __swap16md(ip->
ip_len))
== 0 ||
570 (ntohs(ip->ip_len)(__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t
)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t
)(ip->ip_len) & 0xff00U) >> 8) : __swap16md(ip->
ip_len))
& 0x7) != 0) {
571 ipstat_inc(ips_badfrags);
572 goto bad;
573 }
574 }
575 ip->ip_off = htons(ntohs(ip->ip_off) << 3)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(ip->ip_off) ? (__uint16_t)(((__uint16_t)(ip->ip_off) &
0xffU) << 8 | ((__uint16_t)(ip->ip_off) & 0xff00U
) >> 8) : __swap16md(ip->ip_off)) << 3) ? (__uint16_t
)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_off
) ? (__uint16_t)(((__uint16_t)(ip->ip_off) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_off) & 0xff00U) >> 8) :
__swap16md(ip->ip_off)) << 3) & 0xffU) <<
8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_off
) ? (__uint16_t)(((__uint16_t)(ip->ip_off) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_off) & 0xff00U) >> 8) :
__swap16md(ip->ip_off)) << 3) & 0xff00U) >>
8) : __swap16md((__uint16_t)(__builtin_constant_p(ip->ip_off
) ? (__uint16_t)(((__uint16_t)(ip->ip_off) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_off) & 0xff00U) >> 8) :
__swap16md(ip->ip_off)) << 3))
;
576
577 /*
578 * If datagram marked as having more fragments
579 * or if this is not the first fragment,
580 * attempt reassembly; if it succeeds, proceed.
581 */
582 if (mff || ip->ip_off) {
583 ipstat_inc(ips_fragments);
584 if (ip_frags + 1 > ip_maxqueue) {
585 ip_flush();
586 ipstat_inc(ips_rcvmemdrop);
587 goto bad;
588 }
589
590 ipqe = pool_get(&ipqent_pool, PR_NOWAIT0x0002);
591 if (ipqe == NULL((void *)0)) {
592 ipstat_inc(ips_rcvmemdrop);
593 goto bad;
594 }
595 ip_frags++;
596 ipqe->ipqe_mff = mff;
597 ipqe->ipqe_m = m;
598 ipqe->ipqe_ip = ip;
599 m = *mp = ip_reass(ipqe, fp);
600 if (m == NULL((void *)0))
601 goto bad;
602 ipstat_inc(ips_reassembled);
603 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
604 hlen = ip->ip_hl << 2;
605 ip->ip_len = htons(ntohs(ip->ip_len) + hlen)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) &
0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U
) >> 8) : __swap16md(ip->ip_len)) + hlen) ? (__uint16_t
)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) :
__swap16md(ip->ip_len)) + hlen) & 0xffU) << 8 |
((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) :
__swap16md(ip->ip_len)) + hlen) & 0xff00U) >> 8
) : __swap16md((__uint16_t)(__builtin_constant_p(ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) :
__swap16md(ip->ip_len)) + hlen))
;
606 } else
607 if (fp)
608 ip_freef(fp);
609
610 mtx_leave(&ipq_mutex);
611 }
612
613 *offp = hlen;
614 nxt = ip->ip_p;
615 /* Check whether we are already in a IPv4/IPv6 local deliver loop. */
616 if (af == AF_UNSPEC0)
617 nxt = ip_deliver(mp, offp, nxt, AF_INET2);
618 return nxt;
619 bad:
620 mtx_leave(&ipq_mutex);
621 m_freemp(mp);
622 return IPPROTO_DONE257;
623}
624
625#ifndef INET61
626#define IPSTAT_INC(name) ipstat_inc(ips_##name)
627#else
628#define IPSTAT_INC(name) (af == AF_INET2 ? \
629 ipstat_inc(ips_##name) : ip6stat_inc(ip6s_##name))
630#endif
631
632int
633ip_deliver(struct mbuf **mp, int *offp, int nxt, int af)
634{
635 const struct protosw *psw;
636 int naf = af;
637#ifdef INET61
638 int nest = 0;
639#endif /* INET6 */
640
641 /* pf might have modified stuff, might have to chksum */
642 switch (af) {
643 case AF_INET2:
644 in_proto_cksum_out(*mp, NULL((void *)0));
645 break;
646#ifdef INET61
647 case AF_INET624:
648 in6_proto_cksum_out(*mp, NULL((void *)0));
649 break;
650#endif /* INET6 */
651 }
652
653 /*
654 * Tell launch routine the next header
655 */
656 IPSTAT_INC(delivered);
657
658 while (nxt != IPPROTO_DONE257) {
659#ifdef INET61
660 if (af == AF_INET624 &&
661 ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
662 ip6stat_inc(ip6s_toomanyhdr);
663 goto bad;
664 }
665#endif /* INET6 */
666
667 /*
668 * protection against faulty packet - there should be
669 * more sanity checks in header chain processing.
670 */
671 if ((*mp)->m_pkthdrM_dat.MH.MH_pkthdr.len < *offp) {
672 IPSTAT_INC(tooshort);
673 goto bad;
674 }
675
676#ifdef IPSEC1
677 if (ipsec_in_use) {
678 if (ipsec_local_check(*mp, *offp, nxt, af) != 0) {
679 IPSTAT_INC(cantforward);
680 goto bad;
681 }
682 }
683 /* Otherwise, just fall through and deliver the packet */
684#endif /* IPSEC */
685
686 switch (nxt) {
687 case IPPROTO_IPV44:
688 naf = AF_INET2;
689 ipstat_inc(ips_delivered);
690 break;
691#ifdef INET61
692 case IPPROTO_IPV641:
693 naf = AF_INET624;
694 ip6stat_inc(ip6s_delivered);
695 break;
696#endif /* INET6 */
697 }
698 switch (af) {
699 case AF_INET2:
700 psw = &inetsw[ip_protox[nxt]];
701 break;
702#ifdef INET61
703 case AF_INET624:
704 psw = &inet6sw[ip6_protox[nxt]];
705 break;
706#endif /* INET6 */
707 }
708 nxt = (*psw->pr_input)(mp, offp, nxt, af);
709 af = naf;
710 }
711 return nxt;
712 bad:
713 m_freemp(mp);
714 return IPPROTO_DONE257;
715}
716#undef IPSTAT_INC
717
718int
719in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt)
720{
721 struct rtentry *rt;
722 struct ip *ip;
723 struct sockaddr_in sin;
724 int match = 0;
725
726#if NPF1 > 0
727 switch (pf_ouraddr(m)) {
728 case 0:
729 return (0);
730 case 1:
731 return (1);
732 default:
733 /* pf does not know it */
734 break;
735 }
736#endif
737
738 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
739
740 memset(&sin, 0, sizeof(sin))__builtin_memset((&sin), (0), (sizeof(sin)));
741 sin.sin_len = sizeof(sin);
742 sin.sin_family = AF_INET2;
743 sin.sin_addr = ip->ip_dst;
744 rt = rtalloc_mpath(sintosa(&sin), &ip->ip_src.s_addr,
745 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid);
746 if (rtisvalid(rt)) {
747 if (ISSET(rt->rt_flags, RTF_LOCAL)((rt->rt_flags) & (0x200000)))
748 match = 1;
749
750 /*
751 * If directedbcast is enabled we only consider it local
752 * if it is received on the interface with that address.
753 */
754 if (ISSET(rt->rt_flags, RTF_BROADCAST)((rt->rt_flags) & (0x400000)) &&
755 (!ip_directedbcast || rt->rt_ifidx == ifp->if_index)) {
756 match = 1;
757
758 /* Make sure M_BCAST is set */
759 m->m_flagsm_hdr.mh_flags |= M_BCAST0x0100;
760 }
761 }
762 *prt = rt;
763
764 if (!match) {
765 struct ifaddr *ifa;
766
767 /*
768 * No local address or broadcast address found, so check for
769 * ancient classful broadcast addresses.
770 * It must have been broadcast on the link layer, and for an
771 * address on the interface it was received on.
772 */
773 if (!ISSET(m->m_flags, M_BCAST)((m->m_hdr.mh_flags) & (0x0100)) ||
774 !IN_CLASSFULBROADCAST(ip->ip_dst.s_addr, ip->ip_dst.s_addr)(((((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t
)(__builtin_constant_p((u_int32_t)(0xe0000000)) ? (__uint32_t
)(((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff00) <<
8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff000000)
>> 24) : __swap32md((u_int32_t)(0xe0000000))))) == ((u_int32_t
) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xc0000000)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff
) << 24 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff0000
) >> 8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)(0xc0000000))))) &&
(ip->ip_dst.s_addr | ((u_int32_t) (__uint32_t)(__builtin_constant_p
((u_int32_t)(0x000000ff)) ? (__uint32_t)(((__uint32_t)((u_int32_t
)(0x000000ff)) & 0xff) << 24 | ((__uint32_t)((u_int32_t
)(0x000000ff)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)(0x000000ff)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)(0x000000ff)) & 0xff000000) >> 24) : __swap32md((u_int32_t
)(0x000000ff))))) == ip->ip_dst.s_addr) || ((((u_int32_t)(
ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p
((u_int32_t)(0xc0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t
)(0xc0000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t
)(0xc0000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)(0xc0000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)(0xc0000000)) & 0xff000000) >> 24) : __swap32md((u_int32_t
)(0xc0000000))))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p
((u_int32_t)(0x80000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff000000) >> 24) : __swap32md((u_int32_t
)(0x80000000))))) && (ip->ip_dst.s_addr | ((u_int32_t
) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x0000ffff)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff
) << 24 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff0000
) >> 8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)(0x0000ffff))))) == ip
->ip_dst.s_addr) || ((((u_int32_t)(ip->ip_dst.s_addr) &
((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x80000000
)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x80000000)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)(0x80000000)) &
0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x80000000)) &
0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x80000000)
) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x80000000
))))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t
)(0x00000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00000000
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00000000
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00000000
)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00000000
)) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00000000
))))) && (ip->ip_dst.s_addr | ((u_int32_t) (__uint32_t
)(__builtin_constant_p((u_int32_t)(0x00ffffff)) ? (__uint32_t
)(((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff00) <<
8 | ((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)(0x00ffffff)) & 0xff000000)
>> 24) : __swap32md((u_int32_t)(0x00ffffff))))) == ip->
ip_dst.s_addr))
)
775 return (0);
776
777 if (ifp->if_rdomainif_data.ifi_rdomain != rtable_l2(m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid))
778 return (0);
779 /*
780 * The check in the loop assumes you only rx a packet on an UP
781 * interface, and that M_BCAST will only be set on a BROADCAST
782 * interface.
783 */
784 NET_ASSERT_LOCKED()do { int _s = rw_status(&netlock); if ((splassert_ctl >
0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail
(0x0002UL, _s, __func__); } while (0)
;
785 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list)for((ifa) = ((&ifp->if_addrlist)->tqh_first); (ifa)
!= ((void *)0); (ifa) = ((ifa)->ifa_list.tqe_next))
{
786 if (ifa->ifa_addr->sa_family != AF_INET2)
787 continue;
788
789 if (IN_CLASSFULBROADCAST(ip->ip_dst.s_addr,(((((u_int32_t)(ifatoia(ifa)->ia_addr.sin_addr.s_addr) &
((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000
)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) &
0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) &
0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)
) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0xe0000000
))))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t
)(0xc0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xc0000000
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xc0000000
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xc0000000
)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xc0000000
)) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0xc0000000
))))) && (ifatoia(ifa)->ia_addr.sin_addr.s_addr | (
(u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x000000ff
)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ff)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ff)) &
0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ff)) &
0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ff)
) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x000000ff
))))) == ip->ip_dst.s_addr) || ((((u_int32_t)(ifatoia(ifa)
->ia_addr.sin_addr.s_addr) & ((u_int32_t) (__uint32_t)
(__builtin_constant_p((u_int32_t)(0xc0000000)) ? (__uint32_t)
(((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff) << 24
| ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff00) <<
8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff000000)
>> 24) : __swap32md((u_int32_t)(0xc0000000))))) == ((u_int32_t
) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x80000000)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)(0x80000000)) & 0xff
) << 24 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff0000
) >> 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)(0x80000000))))) &&
(ifatoia(ifa)->ia_addr.sin_addr.s_addr | ((u_int32_t) (__uint32_t
)(__builtin_constant_p((u_int32_t)(0x0000ffff)) ? (__uint32_t
)(((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff00) <<
8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff000000)
>> 24) : __swap32md((u_int32_t)(0x0000ffff))))) == ip->
ip_dst.s_addr) || ((((u_int32_t)(ifatoia(ifa)->ia_addr.sin_addr
.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p
((u_int32_t)(0x80000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff000000) >> 24) : __swap32md((u_int32_t
)(0x80000000))))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p
((u_int32_t)(0x00000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t
)(0x00000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t
)(0x00000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)(0x00000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)(0x00000000)) & 0xff000000) >> 24) : __swap32md((u_int32_t
)(0x00000000))))) && (ifatoia(ifa)->ia_addr.sin_addr
.s_addr | ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t
)(0x00ffffff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00ffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00ffffff
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00ffffff
)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00ffffff
)) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00ffffff
))))) == ip->ip_dst.s_addr))
790 ifatoia(ifa)->ia_addr.sin_addr.s_addr)(((((u_int32_t)(ifatoia(ifa)->ia_addr.sin_addr.s_addr) &
((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000
)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) &
0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) &
0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)
) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0xe0000000
))))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t
)(0xc0000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0xc0000000
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0xc0000000
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0xc0000000
)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0xc0000000
)) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0xc0000000
))))) && (ifatoia(ifa)->ia_addr.sin_addr.s_addr | (
(u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x000000ff
)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x000000ff)) &
0xff) << 24 | ((__uint32_t)((u_int32_t)(0x000000ff)) &
0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x000000ff)) &
0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x000000ff)
) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x000000ff
))))) == ip->ip_dst.s_addr) || ((((u_int32_t)(ifatoia(ifa)
->ia_addr.sin_addr.s_addr) & ((u_int32_t) (__uint32_t)
(__builtin_constant_p((u_int32_t)(0xc0000000)) ? (__uint32_t)
(((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff) << 24
| ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff00) <<
8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)(0xc0000000)) & 0xff000000)
>> 24) : __swap32md((u_int32_t)(0xc0000000))))) == ((u_int32_t
) (__uint32_t)(__builtin_constant_p((u_int32_t)(0x80000000)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)(0x80000000)) & 0xff
) << 24 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff0000
) >> 8 | ((__uint32_t)((u_int32_t)(0x80000000)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)(0x80000000))))) &&
(ifatoia(ifa)->ia_addr.sin_addr.s_addr | ((u_int32_t) (__uint32_t
)(__builtin_constant_p((u_int32_t)(0x0000ffff)) ? (__uint32_t
)(((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff00) <<
8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)(0x0000ffff)) & 0xff000000)
>> 24) : __swap32md((u_int32_t)(0x0000ffff))))) == ip->
ip_dst.s_addr) || ((((u_int32_t)(ifatoia(ifa)->ia_addr.sin_addr
.s_addr) & ((u_int32_t) (__uint32_t)(__builtin_constant_p
((u_int32_t)(0x80000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)(0x80000000)) & 0xff000000) >> 24) : __swap32md((u_int32_t
)(0x80000000))))) == ((u_int32_t) (__uint32_t)(__builtin_constant_p
((u_int32_t)(0x00000000)) ? (__uint32_t)(((__uint32_t)((u_int32_t
)(0x00000000)) & 0xff) << 24 | ((__uint32_t)((u_int32_t
)(0x00000000)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t
)(0x00000000)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t
)(0x00000000)) & 0xff000000) >> 24) : __swap32md((u_int32_t
)(0x00000000))))) && (ifatoia(ifa)->ia_addr.sin_addr
.s_addr | ((u_int32_t) (__uint32_t)(__builtin_constant_p((u_int32_t
)(0x00ffffff)) ? (__uint32_t)(((__uint32_t)((u_int32_t)(0x00ffffff
)) & 0xff) << 24 | ((__uint32_t)((u_int32_t)(0x00ffffff
)) & 0xff00) << 8 | ((__uint32_t)((u_int32_t)(0x00ffffff
)) & 0xff0000) >> 8 | ((__uint32_t)((u_int32_t)(0x00ffffff
)) & 0xff000000) >> 24) : __swap32md((u_int32_t)(0x00ffffff
))))) == ip->ip_dst.s_addr))
) {
791 match = 1;
792 break;
793 }
794 }
795 } else if (ipforwarding == 0 && rt->rt_ifidx != ifp->if_index &&
796 !((ifp->if_flags & IFF_LOOPBACK0x8) || (ifp->if_typeif_data.ifi_type == IFT_ENC0xf4) ||
797 (m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags & PF_TAG_TRANSLATE_LOCALHOST0x04))) {
798 /* received on wrong interface. */
799#if NCARP1 > 0
800 struct ifnet *out_if;
801
802 /*
803 * Virtual IPs on carp interfaces need to be checked also
804 * against the parent interface and other carp interfaces
805 * sharing the same parent.
806 */
807 out_if = if_get(rt->rt_ifidx);
808 if (!(out_if && carp_strict_addr_chk(out_if, ifp))) {
809 ipstat_inc(ips_wrongif);
810 match = 2;
811 }
812 if_put(out_if);
813#else
814 ipstat_inc(ips_wrongif);
815 match = 2;
816#endif
817 }
818
819 return (match);
820}
821
822/*
823 * Take incoming datagram fragment and try to
824 * reassemble it into whole datagram. If a chain for
825 * reassembly of this datagram already exists, then it
826 * is given as fp; otherwise have to make a chain.
827 */
828struct mbuf *
829ip_reass(struct ipqent *ipqe, struct ipq *fp)
830{
831 struct mbuf *m = ipqe->ipqe_m;
832 struct ipqent *nq, *p, *q;
833 struct ip *ip;
834 struct mbuf *t;
835 int hlen = ipqe->ipqe_ip->ip_hl << 2;
836 int i, next;
837 u_int8_t ecn, ecn0;
838
839 MUTEX_ASSERT_LOCKED(&ipq_mutex)do { if (((&ipq_mutex)->mtx_owner != ({struct cpu_info
*__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof
(struct cpu_info, ci_self))); __ci;})) && !(panicstr ||
db_active)) panic("mutex %p not held in %s", (&ipq_mutex
), __func__); } while (0)
;
840
841 /*
842 * Presence of header sizes in mbufs
843 * would confuse code below.
844 */
845 m->m_datam_hdr.mh_data += hlen;
846 m->m_lenm_hdr.mh_len -= hlen;
847
848 /*
849 * If first fragment to arrive, create a reassembly queue.
850 */
851 if (fp == NULL((void *)0)) {
852 fp = pool_get(&ipq_pool, PR_NOWAIT0x0002);
853 if (fp == NULL((void *)0))
854 goto dropfrag;
855 LIST_INSERT_HEAD(&ipq, fp, ipq_q)do { if (((fp)->ipq_q.le_next = (&ipq)->lh_first) !=
((void *)0)) (&ipq)->lh_first->ipq_q.le_prev = &
(fp)->ipq_q.le_next; (&ipq)->lh_first = (fp); (fp)->
ipq_q.le_prev = &(&ipq)->lh_first; } while (0)
;
856 fp->ipq_ttl = IPFRAGTTL60;
857 fp->ipq_p = ipqe->ipqe_ip->ip_p;
858 fp->ipq_id = ipqe->ipqe_ip->ip_id;
859 LIST_INIT(&fp->ipq_fragq)do { ((&fp->ipq_fragq)->lh_first) = ((void *)0); } while
(0)
;
860 fp->ipq_src = ipqe->ipqe_ip->ip_src;
861 fp->ipq_dst = ipqe->ipqe_ip->ip_dst;
862 p = NULL((void *)0);
863 goto insert;
864 }
865
866 /*
867 * Handle ECN by comparing this segment with the first one;
868 * if CE is set, do not lose CE.
869 * drop if CE and not-ECT are mixed for the same packet.
870 */
871 ecn = ipqe->ipqe_ip->ip_tos & IPTOS_ECN_MASK0x03;
872 ecn0 = LIST_FIRST(&fp->ipq_fragq)((&fp->ipq_fragq)->lh_first)->ipqe_ip->ip_tos & IPTOS_ECN_MASK0x03;
873 if (ecn == IPTOS_ECN_CE0x03) {
874 if (ecn0 == IPTOS_ECN_NOTECT0x00)
875 goto dropfrag;
876 if (ecn0 != IPTOS_ECN_CE0x03)
877 LIST_FIRST(&fp->ipq_fragq)((&fp->ipq_fragq)->lh_first)->ipqe_ip->ip_tos |=
878 IPTOS_ECN_CE0x03;
879 }
880 if (ecn == IPTOS_ECN_NOTECT0x00 && ecn0 != IPTOS_ECN_NOTECT0x00)
881 goto dropfrag;
882
883 /*
884 * Find a segment which begins after this one does.
885 */
886 for (p = NULL((void *)0), q = LIST_FIRST(&fp->ipq_fragq)((&fp->ipq_fragq)->lh_first); q != NULL((void *)0);
887 p = q, q = LIST_NEXT(q, ipqe_q)((q)->ipqe_q.le_next))
888 if (ntohs(q->ipqe_ip->ip_off)(__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ?
(__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU
) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U
) >> 8) : __swap16md(q->ipqe_ip->ip_off))
> ntohs(ipqe->ipqe_ip->ip_off)(__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off
) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) &
0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off
) & 0xff00U) >> 8) : __swap16md(ipqe->ipqe_ip->
ip_off))
)
889 break;
890
891 /*
892 * If there is a preceding segment, it may provide some of
893 * our data already. If so, drop the data from the incoming
894 * segment. If it provides all of our data, drop us.
895 */
896 if (p != NULL((void *)0)) {
897 i = ntohs(p->ipqe_ip->ip_off)(__uint16_t)(__builtin_constant_p(p->ipqe_ip->ip_off) ?
(__uint16_t)(((__uint16_t)(p->ipqe_ip->ip_off) & 0xffU
) << 8 | ((__uint16_t)(p->ipqe_ip->ip_off) & 0xff00U
) >> 8) : __swap16md(p->ipqe_ip->ip_off))
+ ntohs(p->ipqe_ip->ip_len)(__uint16_t)(__builtin_constant_p(p->ipqe_ip->ip_len) ?
(__uint16_t)(((__uint16_t)(p->ipqe_ip->ip_len) & 0xffU
) << 8 | ((__uint16_t)(p->ipqe_ip->ip_len) & 0xff00U
) >> 8) : __swap16md(p->ipqe_ip->ip_len))
-
898 ntohs(ipqe->ipqe_ip->ip_off)(__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off
) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) &
0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off
) & 0xff00U) >> 8) : __swap16md(ipqe->ipqe_ip->
ip_off))
;
899 if (i > 0) {
900 if (i >= ntohs(ipqe->ipqe_ip->ip_len)(__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) &
0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len
) & 0xff00U) >> 8) : __swap16md(ipqe->ipqe_ip->
ip_len))
)
901 goto dropfrag;
902 m_adj(ipqe->ipqe_m, i);
903 ipqe->ipqe_ip->ip_off =
904 htons(ntohs(ipqe->ipqe_ip->ip_off) + i)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe
->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t
)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __swap16md
(ipqe->ipqe_ip->ip_off)) + i) ? (__uint16_t)(((__uint16_t
)((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off
) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) &
0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off
) & 0xff00U) >> 8) : __swap16md(ipqe->ipqe_ip->
ip_off)) + i) & 0xffU) << 8 | ((__uint16_t)((__uint16_t
)(__builtin_constant_p(ipqe->ipqe_ip->ip_off) ? (__uint16_t
)(((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xffU) <<
8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off) & 0xff00U
) >> 8) : __swap16md(ipqe->ipqe_ip->ip_off)) + i)
& 0xff00U) >> 8) : __swap16md((__uint16_t)(__builtin_constant_p
(ipqe->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(ipqe
->ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t
)(ipqe->ipqe_ip->ip_off) & 0xff00U) >> 8) : __swap16md
(ipqe->ipqe_ip->ip_off)) + i))
;
905 ipqe->ipqe_ip->ip_len =
906 htons(ntohs(ipqe->ipqe_ip->ip_len) - i)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(ipqe->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(ipqe
->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t
)(ipqe->ipqe_ip->ip_len) & 0xff00U) >> 8) : __swap16md
(ipqe->ipqe_ip->ip_len)) - i) ? (__uint16_t)(((__uint16_t
)((__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) &
0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len
) & 0xff00U) >> 8) : __swap16md(ipqe->ipqe_ip->
ip_len)) - i) & 0xffU) << 8 | ((__uint16_t)((__uint16_t
)(__builtin_constant_p(ipqe->ipqe_ip->ip_len) ? (__uint16_t
)(((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len) & 0xff00U
) >> 8) : __swap16md(ipqe->ipqe_ip->ip_len)) - i)
& 0xff00U) >> 8) : __swap16md((__uint16_t)(__builtin_constant_p
(ipqe->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(ipqe
->ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t
)(ipqe->ipqe_ip->ip_len) & 0xff00U) >> 8) : __swap16md
(ipqe->ipqe_ip->ip_len)) - i))
;
907 }
908 }
909
910 /*
911 * While we overlap succeeding segments trim them or,
912 * if they are completely covered, dequeue them.
913 */
914 for (; q != NULL((void *)0) &&
915 ntohs(ipqe->ipqe_ip->ip_off)(__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off
) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) &
0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off
) & 0xff00U) >> 8) : __swap16md(ipqe->ipqe_ip->
ip_off))
+ ntohs(ipqe->ipqe_ip->ip_len)(__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) &
0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len
) & 0xff00U) >> 8) : __swap16md(ipqe->ipqe_ip->
ip_len))
>
916 ntohs(q->ipqe_ip->ip_off)(__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ?
(__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU
) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U
) >> 8) : __swap16md(q->ipqe_ip->ip_off))
; q = nq) {
917 i = (ntohs(ipqe->ipqe_ip->ip_off)(__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_off
) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_off) &
0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_off
) & 0xff00U) >> 8) : __swap16md(ipqe->ipqe_ip->
ip_off))
+
918 ntohs(ipqe->ipqe_ip->ip_len)(__uint16_t)(__builtin_constant_p(ipqe->ipqe_ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ipqe->ipqe_ip->ip_len) &
0xffU) << 8 | ((__uint16_t)(ipqe->ipqe_ip->ip_len
) & 0xff00U) >> 8) : __swap16md(ipqe->ipqe_ip->
ip_len))
) - ntohs(q->ipqe_ip->ip_off)(__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ?
(__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU
) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U
) >> 8) : __swap16md(q->ipqe_ip->ip_off))
;
919 if (i < ntohs(q->ipqe_ip->ip_len)(__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_len) ?
(__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len) & 0xffU
) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len) & 0xff00U
) >> 8) : __swap16md(q->ipqe_ip->ip_len))
) {
920 q->ipqe_ip->ip_len =
921 htons(ntohs(q->ipqe_ip->ip_len) - i)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(q->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(q->
ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(q
->ipqe_ip->ip_len) & 0xff00U) >> 8) : __swap16md
(q->ipqe_ip->ip_len)) - i) ? (__uint16_t)(((__uint16_t)
((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_len) ?
(__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len) & 0xffU
) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len) & 0xff00U
) >> 8) : __swap16md(q->ipqe_ip->ip_len)) - i) &
0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p
(q->ipqe_ip->ip_len) ? (__uint16_t)(((__uint16_t)(q->
ipqe_ip->ip_len) & 0xffU) << 8 | ((__uint16_t)(q
->ipqe_ip->ip_len) & 0xff00U) >> 8) : __swap16md
(q->ipqe_ip->ip_len)) - i) & 0xff00U) >> 8) :
__swap16md((__uint16_t)(__builtin_constant_p(q->ipqe_ip->
ip_len) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len
) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len
) & 0xff00U) >> 8) : __swap16md(q->ipqe_ip->ip_len
)) - i))
;
922 q->ipqe_ip->ip_off =
923 htons(ntohs(q->ipqe_ip->ip_off) + i)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->
ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q
->ipqe_ip->ip_off) & 0xff00U) >> 8) : __swap16md
(q->ipqe_ip->ip_off)) + i) ? (__uint16_t)(((__uint16_t)
((__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ?
(__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU
) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U
) >> 8) : __swap16md(q->ipqe_ip->ip_off)) + i) &
0xffU) << 8 | ((__uint16_t)((__uint16_t)(__builtin_constant_p
(q->ipqe_ip->ip_off) ? (__uint16_t)(((__uint16_t)(q->
ipqe_ip->ip_off) & 0xffU) << 8 | ((__uint16_t)(q
->ipqe_ip->ip_off) & 0xff00U) >> 8) : __swap16md
(q->ipqe_ip->ip_off)) + i) & 0xff00U) >> 8) :
__swap16md((__uint16_t)(__builtin_constant_p(q->ipqe_ip->
ip_off) ? (__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off
) & 0xffU) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off
) & 0xff00U) >> 8) : __swap16md(q->ipqe_ip->ip_off
)) + i))
;
924 m_adj(q->ipqe_m, i);
925 break;
926 }
927 nq = LIST_NEXT(q, ipqe_q)((q)->ipqe_q.le_next);
928 m_freem(q->ipqe_m);
929 LIST_REMOVE(q, ipqe_q)do { if ((q)->ipqe_q.le_next != ((void *)0)) (q)->ipqe_q
.le_next->ipqe_q.le_prev = (q)->ipqe_q.le_prev; *(q)->
ipqe_q.le_prev = (q)->ipqe_q.le_next; ((q)->ipqe_q.le_prev
) = ((void *)-1); ((q)->ipqe_q.le_next) = ((void *)-1); } while
(0)
;
930 pool_put(&ipqent_pool, q);
931 ip_frags--;
932 }
933
934insert:
935 /*
936 * Stick new segment in its place;
937 * check for complete reassembly.
938 */
939 if (p == NULL((void *)0)) {
940 LIST_INSERT_HEAD(&fp->ipq_fragq, ipqe, ipqe_q)do { if (((ipqe)->ipqe_q.le_next = (&fp->ipq_fragq)
->lh_first) != ((void *)0)) (&fp->ipq_fragq)->lh_first
->ipqe_q.le_prev = &(ipqe)->ipqe_q.le_next; (&fp
->ipq_fragq)->lh_first = (ipqe); (ipqe)->ipqe_q.le_prev
= &(&fp->ipq_fragq)->lh_first; } while (0)
;
941 } else {
942 LIST_INSERT_AFTER(p, ipqe, ipqe_q)do { if (((ipqe)->ipqe_q.le_next = (p)->ipqe_q.le_next)
!= ((void *)0)) (p)->ipqe_q.le_next->ipqe_q.le_prev = &
(ipqe)->ipqe_q.le_next; (p)->ipqe_q.le_next = (ipqe); (
ipqe)->ipqe_q.le_prev = &(p)->ipqe_q.le_next; } while
(0)
;
943 }
944 next = 0;
945 for (p = NULL((void *)0), q = LIST_FIRST(&fp->ipq_fragq)((&fp->ipq_fragq)->lh_first); q != NULL((void *)0);
946 p = q, q = LIST_NEXT(q, ipqe_q)((q)->ipqe_q.le_next)) {
947 if (ntohs(q->ipqe_ip->ip_off)(__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_off) ?
(__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_off) & 0xffU
) << 8 | ((__uint16_t)(q->ipqe_ip->ip_off) & 0xff00U
) >> 8) : __swap16md(q->ipqe_ip->ip_off))
!= next)
948 return (0);
949 next += ntohs(q->ipqe_ip->ip_len)(__uint16_t)(__builtin_constant_p(q->ipqe_ip->ip_len) ?
(__uint16_t)(((__uint16_t)(q->ipqe_ip->ip_len) & 0xffU
) << 8 | ((__uint16_t)(q->ipqe_ip->ip_len) & 0xff00U
) >> 8) : __swap16md(q->ipqe_ip->ip_len))
;
950 }
951 if (p->ipqe_mff)
952 return (0);
953
954 /*
955 * Reassembly is complete. Check for a bogus message size and
956 * concatenate fragments.
957 */
958 q = LIST_FIRST(&fp->ipq_fragq)((&fp->ipq_fragq)->lh_first);
959 ip = q->ipqe_ip;
960 if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET65535) {
961 ipstat_inc(ips_toolong);
962 ip_freef(fp);
963 return (0);
964 }
965 m = q->ipqe_m;
966 t = m->m_nextm_hdr.mh_next;
967 m->m_nextm_hdr.mh_next = 0;
968 m_cat(m, t);
969 nq = LIST_NEXT(q, ipqe_q)((q)->ipqe_q.le_next);
970 pool_put(&ipqent_pool, q);
971 ip_frags--;
972 for (q = nq; q != NULL((void *)0); q = nq) {
973 t = q->ipqe_m;
974 nq = LIST_NEXT(q, ipqe_q)((q)->ipqe_q.le_next);
975 pool_put(&ipqent_pool, q);
976 ip_frags--;
977 m_removehdr(t);
978 m_cat(m, t);
979 }
980
981 /*
982 * Create header for new ip packet by
983 * modifying header of first packet;
984 * dequeue and discard fragment reassembly header.
985 * Make header visible.
986 */
987 ip->ip_len = htons(next)(__uint16_t)(__builtin_constant_p(next) ? (__uint16_t)(((__uint16_t
)(next) & 0xffU) << 8 | ((__uint16_t)(next) & 0xff00U
) >> 8) : __swap16md(next))
;
988 ip->ip_src = fp->ipq_src;
989 ip->ip_dst = fp->ipq_dst;
990 LIST_REMOVE(fp, ipq_q)do { if ((fp)->ipq_q.le_next != ((void *)0)) (fp)->ipq_q
.le_next->ipq_q.le_prev = (fp)->ipq_q.le_prev; *(fp)->
ipq_q.le_prev = (fp)->ipq_q.le_next; ((fp)->ipq_q.le_prev
) = ((void *)-1); ((fp)->ipq_q.le_next) = ((void *)-1); } while
(0)
;
991 pool_put(&ipq_pool, fp);
992 m->m_lenm_hdr.mh_len += (ip->ip_hl << 2);
993 m->m_datam_hdr.mh_data -= (ip->ip_hl << 2);
994 m_calchdrlen(m);
995 return (m);
996
997dropfrag:
998 ipstat_inc(ips_fragdropped);
999 m_freem(m);
1000 pool_put(&ipqent_pool, ipqe);
1001 ip_frags--;
1002 return (NULL((void *)0));
1003}
1004
1005/*
1006 * Free a fragment reassembly header and all
1007 * associated datagrams.
1008 */
1009void
1010ip_freef(struct ipq *fp)
1011{
1012 struct ipqent *q;
1013
1014 MUTEX_ASSERT_LOCKED(&ipq_mutex)do { if (((&ipq_mutex)->mtx_owner != ({struct cpu_info
*__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof
(struct cpu_info, ci_self))); __ci;})) && !(panicstr ||
db_active)) panic("mutex %p not held in %s", (&ipq_mutex
), __func__); } while (0)
;
1015
1016 while ((q = LIST_FIRST(&fp->ipq_fragq)((&fp->ipq_fragq)->lh_first)) != NULL((void *)0)) {
1017 LIST_REMOVE(q, ipqe_q)do { if ((q)->ipqe_q.le_next != ((void *)0)) (q)->ipqe_q
.le_next->ipqe_q.le_prev = (q)->ipqe_q.le_prev; *(q)->
ipqe_q.le_prev = (q)->ipqe_q.le_next; ((q)->ipqe_q.le_prev
) = ((void *)-1); ((q)->ipqe_q.le_next) = ((void *)-1); } while
(0)
;
1018 m_freem(q->ipqe_m);
1019 pool_put(&ipqent_pool, q);
1020 ip_frags--;
1021 }
1022 LIST_REMOVE(fp, ipq_q)do { if ((fp)->ipq_q.le_next != ((void *)0)) (fp)->ipq_q
.le_next->ipq_q.le_prev = (fp)->ipq_q.le_prev; *(fp)->
ipq_q.le_prev = (fp)->ipq_q.le_next; ((fp)->ipq_q.le_prev
) = ((void *)-1); ((fp)->ipq_q.le_next) = ((void *)-1); } while
(0)
;
1023 pool_put(&ipq_pool, fp);
1024}
1025
1026/*
1027 * IP timer processing;
1028 * if a timer expires on a reassembly queue, discard it.
1029 */
1030void
1031ip_slowtimo(void)
1032{
1033 struct ipq *fp, *nfp;
1034
1035 mtx_enter(&ipq_mutex);
1036 LIST_FOREACH_SAFE(fp, &ipq, ipq_q, nfp)for ((fp) = ((&ipq)->lh_first); (fp) && ((nfp)
= ((fp)->ipq_q.le_next), 1); (fp) = (nfp))
{
1037 if (--fp->ipq_ttl == 0) {
1038 ipstat_inc(ips_fragtimeout);
1039 ip_freef(fp);
1040 }
1041 }
1042 mtx_leave(&ipq_mutex);
1043}
1044
1045/*
1046 * Flush a bunch of datagram fragments, till we are down to 75%.
1047 */
1048void
1049ip_flush(void)
1050{
1051 int max = 50;
1052
1053 MUTEX_ASSERT_LOCKED(&ipq_mutex)do { if (((&ipq_mutex)->mtx_owner != ({struct cpu_info
*__ci; asm volatile("movq %%gs:%P1,%0" : "=r" (__ci) :"n" (__builtin_offsetof
(struct cpu_info, ci_self))); __ci;})) && !(panicstr ||
db_active)) panic("mutex %p not held in %s", (&ipq_mutex
), __func__); } while (0)
;
1054
1055 while (!LIST_EMPTY(&ipq)(((&ipq)->lh_first) == ((void *)0)) && ip_frags > ip_maxqueue * 3 / 4 && --max) {
1056 ipstat_inc(ips_fragdropped);
1057 ip_freef(LIST_FIRST(&ipq)((&ipq)->lh_first));
1058 }
1059}
1060
1061/*
1062 * Do option processing on a datagram,
1063 * possibly discarding it if bad options are encountered,
1064 * or forwarding it if source-routed.
1065 * Returns 1 if packet has been forwarded/freed,
1066 * 0 if the packet should be processed further.
1067 */
1068int
1069ip_dooptions(struct mbuf *m, struct ifnet *ifp)
1070{
1071 struct ip *ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
1072 unsigned int rtableid = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid;
1073 struct rtentry *rt;
1074 struct sockaddr_in ipaddr;
1075 u_char *cp;
1076 struct ip_timestamp ipt;
1077 struct in_ifaddr *ia;
1078 int opt, optlen, cnt, off, code, type = ICMP_PARAMPROB12, forward = 0;
1079 struct in_addr sin, dst;
1080 u_int32_t ntime;
1081
1082 dst = ip->ip_dst;
1083 cp = (u_char *)(ip + 1);
1084 cnt = (ip->ip_hl << 2) - sizeof (struct ip);
1085
1086 KERNEL_LOCK()_kernel_lock();
1087 for (; cnt > 0; cnt -= optlen, cp += optlen) {
1088 opt = cp[IPOPT_OPTVAL0];
1089 if (opt == IPOPT_EOL0)
1090 break;
1091 if (opt == IPOPT_NOP1)
1092 optlen = 1;
1093 else {
1094 if (cnt < IPOPT_OLEN1 + sizeof(*cp)) {
1095 code = &cp[IPOPT_OLEN1] - (u_char *)ip;
1096 goto bad;
1097 }
1098 optlen = cp[IPOPT_OLEN1];
1099 if (optlen < IPOPT_OLEN1 + sizeof(*cp) || optlen > cnt) {
1100 code = &cp[IPOPT_OLEN1] - (u_char *)ip;
1101 goto bad;
1102 }
1103 }
1104
1105 switch (opt) {
1106
1107 default:
1108 break;
1109
1110 /*
1111 * Source routing with record.
1112 * Find interface with current destination address.
1113 * If none on this machine then drop if strictly routed,
1114 * or do nothing if loosely routed.
1115 * Record interface address and bring up next address
1116 * component. If strictly routed make sure next
1117 * address is on directly accessible net.
1118 */
1119 case IPOPT_LSRR131:
1120 case IPOPT_SSRR137:
1121 if (!ip_dosourceroute) {
1122 type = ICMP_UNREACH3;
1123 code = ICMP_UNREACH_SRCFAIL5;
1124 goto bad;
1125 }
1126 if ((off = cp[IPOPT_OFFSET2]) < IPOPT_MINOFF4) {
1127 code = &cp[IPOPT_OFFSET2] - (u_char *)ip;
1128 goto bad;
1129 }
1130 memset(&ipaddr, 0, sizeof(ipaddr))__builtin_memset((&ipaddr), (0), (sizeof(ipaddr)));
1131 ipaddr.sin_family = AF_INET2;
1132 ipaddr.sin_len = sizeof(ipaddr);
1133 ipaddr.sin_addr = ip->ip_dst;
1134 ia = ifatoia(ifa_ifwithaddr(sintosa(&ipaddr),
1135 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid));
1136 if (ia == NULL((void *)0)) {
1137 if (opt == IPOPT_SSRR137) {
1138 type = ICMP_UNREACH3;
1139 code = ICMP_UNREACH_SRCFAIL5;
1140 goto bad;
1141 }
1142 /*
1143 * Loose routing, and not at next destination
1144 * yet; nothing to do except forward.
1145 */
1146 break;
1147 }
1148 off--; /* 0 origin */
1149 if ((off + sizeof(struct in_addr)) > optlen) {
1150 /*
1151 * End of source route. Should be for us.
1152 */
1153 save_rte(m, cp, ip->ip_src);
1154 break;
1155 }
1156
1157 /*
1158 * locate outgoing interface
1159 */
1160 memset(&ipaddr, 0, sizeof(ipaddr))__builtin_memset((&ipaddr), (0), (sizeof(ipaddr)));
1161 ipaddr.sin_family = AF_INET2;
1162 ipaddr.sin_len = sizeof(ipaddr);
1163 memcpy(&ipaddr.sin_addr, cp + off,__builtin_memcpy((&ipaddr.sin_addr), (cp + off), (sizeof(
ipaddr.sin_addr)))
1164 sizeof(ipaddr.sin_addr))__builtin_memcpy((&ipaddr.sin_addr), (cp + off), (sizeof(
ipaddr.sin_addr)))
;
1165 /* keep packet in the virtual instance */
1166 rt = rtalloc(sintosa(&ipaddr), RT_RESOLVE1, rtableid);
1167 if (!rtisvalid(rt) || ((opt == IPOPT_SSRR137) &&
1168 ISSET(rt->rt_flags, RTF_GATEWAY)((rt->rt_flags) & (0x2)))) {
1169 type = ICMP_UNREACH3;
1170 code = ICMP_UNREACH_SRCFAIL5;
1171 rtfree(rt);
1172 goto bad;
1173 }
1174 ia = ifatoia(rt->rt_ifa);
1175 memcpy(cp + off, &ia->ia_addr.sin_addr,__builtin_memcpy((cp + off), (&ia->ia_addr.sin_addr), (
sizeof(struct in_addr)))
1176 sizeof(struct in_addr))__builtin_memcpy((cp + off), (&ia->ia_addr.sin_addr), (
sizeof(struct in_addr)))
;
1177 rtfree(rt);
1178 cp[IPOPT_OFFSET2] += sizeof(struct in_addr);
1179 ip->ip_dst = ipaddr.sin_addr;
1180 /*
1181 * Let ip_intr's mcast routing check handle mcast pkts
1182 */
1183 forward = !IN_MULTICAST(ip->ip_dst.s_addr)(((u_int32_t)(ip->ip_dst.s_addr) & ((u_int32_t) (__uint32_t
)(__builtin_constant_p((u_int32_t)(0xf0000000)) ? (__uint32_t
)(((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff) <<
24 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff00) <<
8 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff0000) >>
8 | ((__uint32_t)((u_int32_t)(0xf0000000)) & 0xff000000)
>> 24) : __swap32md((u_int32_t)(0xf0000000))))) == ((u_int32_t
) (__uint32_t)(__builtin_constant_p((u_int32_t)(0xe0000000)) ?
(__uint32_t)(((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff
) << 24 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff00
) << 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff0000
) >> 8 | ((__uint32_t)((u_int32_t)(0xe0000000)) & 0xff000000
) >> 24) : __swap32md((u_int32_t)(0xe0000000)))))
;
1184 break;
1185
1186 case IPOPT_RR7:
1187 if (optlen < IPOPT_OFFSET2 + sizeof(*cp)) {
1188 code = &cp[IPOPT_OLEN1] - (u_char *)ip;
1189 goto bad;
1190 }
1191 if ((off = cp[IPOPT_OFFSET2]) < IPOPT_MINOFF4) {
1192 code = &cp[IPOPT_OFFSET2] - (u_char *)ip;
1193 goto bad;
1194 }
1195
1196 /*
1197 * If no space remains, ignore.
1198 */
1199 off--; /* 0 origin */
1200 if ((off + sizeof(struct in_addr)) > optlen)
1201 break;
1202 memset(&ipaddr, 0, sizeof(ipaddr))__builtin_memset((&ipaddr), (0), (sizeof(ipaddr)));
1203 ipaddr.sin_family = AF_INET2;
1204 ipaddr.sin_len = sizeof(ipaddr);
1205 ipaddr.sin_addr = ip->ip_dst;
1206 /*
1207 * locate outgoing interface; if we're the destination,
1208 * use the incoming interface (should be same).
1209 * Again keep the packet inside the virtual instance.
1210 */
1211 rt = rtalloc(sintosa(&ipaddr), RT_RESOLVE1, rtableid);
1212 if (!rtisvalid(rt)) {
1213 type = ICMP_UNREACH3;
1214 code = ICMP_UNREACH_HOST1;
1215 rtfree(rt);
1216 goto bad;
1217 }
1218 ia = ifatoia(rt->rt_ifa);
1219 memcpy(cp + off, &ia->ia_addr.sin_addr,__builtin_memcpy((cp + off), (&ia->ia_addr.sin_addr), (
sizeof(struct in_addr)))
1220 sizeof(struct in_addr))__builtin_memcpy((cp + off), (&ia->ia_addr.sin_addr), (
sizeof(struct in_addr)))
;
1221 rtfree(rt);
1222 cp[IPOPT_OFFSET2] += sizeof(struct in_addr);
1223 break;
1224
1225 case IPOPT_TS68:
1226 code = cp - (u_char *)ip;
1227 if (optlen < sizeof(struct ip_timestamp))
1228 goto bad;
1229 memcpy(&ipt, cp, sizeof(struct ip_timestamp))__builtin_memcpy((&ipt), (cp), (sizeof(struct ip_timestamp
)))
;
1230 if (ipt.ipt_ptr < 5 || ipt.ipt_len < 5)
1231 goto bad;
1232 if (ipt.ipt_ptr - 1 + sizeof(u_int32_t) > ipt.ipt_len) {
1233 if (++ipt.ipt_oflw == 0)
1234 goto bad;
1235 break;
1236 }
1237 memcpy(&sin, cp + ipt.ipt_ptr - 1, sizeof sin)__builtin_memcpy((&sin), (cp + ipt.ipt_ptr - 1), (sizeof sin
))
;
1238 switch (ipt.ipt_flg) {
1239
1240 case IPOPT_TS_TSONLY0:
1241 break;
1242
1243 case IPOPT_TS_TSANDADDR1:
1244 if (ipt.ipt_ptr - 1 + sizeof(u_int32_t) +
1245 sizeof(struct in_addr) > ipt.ipt_len)
1246 goto bad;
1247 memset(&ipaddr, 0, sizeof(ipaddr))__builtin_memset((&ipaddr), (0), (sizeof(ipaddr)));
1248 ipaddr.sin_family = AF_INET2;
1249 ipaddr.sin_len = sizeof(ipaddr);
1250 ipaddr.sin_addr = dst;
1251 ia = ifatoia(ifaof_ifpforaddr(sintosa(&ipaddr),
1252 ifp));
1253 if (ia == NULL((void *)0))
1254 continue;
1255 memcpy(&sin, &ia->ia_addr.sin_addr,__builtin_memcpy((&sin), (&ia->ia_addr.sin_addr), (
sizeof(struct in_addr)))
1256 sizeof(struct in_addr))__builtin_memcpy((&sin), (&ia->ia_addr.sin_addr), (
sizeof(struct in_addr)))
;
1257 ipt.ipt_ptr += sizeof(struct in_addr);
1258 break;
1259
1260 case IPOPT_TS_PRESPEC3:
1261 if (ipt.ipt_ptr - 1 + sizeof(u_int32_t) +
1262 sizeof(struct in_addr) > ipt.ipt_len)
1263 goto bad;
1264 memset(&ipaddr, 0, sizeof(ipaddr))__builtin_memset((&ipaddr), (0), (sizeof(ipaddr)));
1265 ipaddr.sin_family = AF_INET2;
1266 ipaddr.sin_len = sizeof(ipaddr);
1267 ipaddr.sin_addr = sin;
1268 if (ifa_ifwithaddr(sintosa(&ipaddr),
1269 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid) == NULL((void *)0))
1270 continue;
1271 ipt.ipt_ptr += sizeof(struct in_addr);
1272 break;
1273
1274 default:
1275 /* XXX can't take &ipt->ipt_flg */
1276 code = (u_char *)&ipt.ipt_ptr -
1277 (u_char *)ip + 1;
1278 goto bad;
1279 }
1280 ntime = iptime();
1281 memcpy(cp + ipt.ipt_ptr - 1, &ntime, sizeof(u_int32_t))__builtin_memcpy((cp + ipt.ipt_ptr - 1), (&ntime), (sizeof
(u_int32_t)))
;
1282 ipt.ipt_ptr += sizeof(u_int32_t);
1283 }
1284 }
1285 KERNEL_UNLOCK()_kernel_unlock();
1286 if (forward && ipforwarding > 0) {
1287 ip_forward(m, ifp, NULL((void *)0), 1);
1288 return (1);
1289 }
1290 return (0);
1291bad:
1292 KERNEL_UNLOCK()_kernel_unlock();
1293 icmp_error(m, type, code, 0, 0);
1294 ipstat_inc(ips_badoptions);
1295 return (1);
1296}
1297
1298/*
1299 * Save incoming source route for use in replies,
1300 * to be picked up later by ip_srcroute if the receiver is interested.
1301 */
1302void
1303save_rte(struct mbuf *m, u_char *option, struct in_addr dst)
1304{
1305 struct ip_srcrt *isr;
1306 struct m_tag *mtag;
1307 unsigned olen;
1308
1309 olen = option[IPOPT_OLEN1];
1310 if (olen > sizeof(isr->isr_hdr) + sizeof(isr->isr_routes))
1311 return;
1312
1313 mtag = m_tag_get(PACKET_TAG_SRCROUTE0x1000, sizeof(*isr), M_NOWAIT0x0002);
1314 if (mtag == NULL((void *)0))
1315 return;
1316 isr = (struct ip_srcrt *)(mtag + 1);
1317
1318 memcpy(isr->isr_hdr, option, olen)__builtin_memcpy((isr->isr_hdr), (option), (olen));
1319 isr->isr_nhops = (olen - IPOPT_OFFSET2 - 1) / sizeof(struct in_addr);
1320 isr->isr_dst = dst;
1321 m_tag_prepend(m, mtag);
1322}
1323
1324/*
1325 * Retrieve incoming source route for use in replies,
1326 * in the same form used by setsockopt.
1327 * The first hop is placed before the options, will be removed later.
1328 */
1329struct mbuf *
1330ip_srcroute(struct mbuf *m0)
1331{
1332 struct in_addr *p, *q;
1333 struct mbuf *m;
1334 struct ip_srcrt *isr;
1335 struct m_tag *mtag;
1336
1337 if (!ip_dosourceroute)
1338 return (NULL((void *)0));
1339
1340 mtag = m_tag_find(m0, PACKET_TAG_SRCROUTE0x1000, NULL((void *)0));
1341 if (mtag == NULL((void *)0))
1342 return (NULL((void *)0));
1343 isr = (struct ip_srcrt *)(mtag + 1);
1344
1345 if (isr->isr_nhops == 0)
1346 return (NULL((void *)0));
1347 m = m_get(M_DONTWAIT0x0002, MT_SOOPTS4);
1348 if (m == NULL((void *)0))
1349 return (NULL((void *)0));
1350
1351#define OPTSIZ (sizeof(isr->isr_nop) + sizeof(isr->isr_hdr))
1352
1353 /* length is (nhops+1)*sizeof(addr) + sizeof(nop + header) */
1354 m->m_lenm_hdr.mh_len = (isr->isr_nhops + 1) * sizeof(struct in_addr) + OPTSIZ;
1355
1356 /*
1357 * First save first hop for return route
1358 */
1359 p = &(isr->isr_routes[isr->isr_nhops - 1]);
1360 *(mtod(m, struct in_addr *)((struct in_addr *)((m)->m_hdr.mh_data))) = *p--;
1361
1362 /*
1363 * Copy option fields and padding (nop) to mbuf.
1364 */
1365 isr->isr_nop = IPOPT_NOP1;
1366 isr->isr_hdr[IPOPT_OFFSET2] = IPOPT_MINOFF4;
1367 memcpy(mtod(m, caddr_t) + sizeof(struct in_addr), &isr->isr_nop,__builtin_memcpy((((caddr_t)((m)->m_hdr.mh_data)) + sizeof
(struct in_addr)), (&isr->isr_nop), (OPTSIZ))
1368 OPTSIZ)__builtin_memcpy((((caddr_t)((m)->m_hdr.mh_data)) + sizeof
(struct in_addr)), (&isr->isr_nop), (OPTSIZ))
;
1369 q = (struct in_addr *)(mtod(m, caddr_t)((caddr_t)((m)->m_hdr.mh_data)) +
1370 sizeof(struct in_addr) + OPTSIZ);
1371#undef OPTSIZ
1372 /*
1373 * Record return path as an IP source route,
1374 * reversing the path (pointers are now aligned).
1375 */
1376 while (p >= isr->isr_routes) {
1377 *q++ = *p--;
1378 }
1379 /*
1380 * Last hop goes to final destination.
1381 */
1382 *q = isr->isr_dst;
1383 m_tag_delete(m0, (struct m_tag *)isr);
1384 return (m);
1385}
1386
1387/*
1388 * Strip out IP options, at higher level protocol in the kernel.
1389 */
1390void
1391ip_stripoptions(struct mbuf *m)
1392{
1393 int i;
1394 struct ip *ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
1395 caddr_t opts;
1396 int olen;
1397
1398 olen = (ip->ip_hl<<2) - sizeof (struct ip);
1399 opts = (caddr_t)(ip + 1);
1400 i = m->m_lenm_hdr.mh_len - (sizeof (struct ip) + olen);
1401 memmove(opts, opts + olen, i)__builtin_memmove((opts), (opts + olen), (i));
1402 m->m_lenm_hdr.mh_len -= olen;
1403 if (m->m_flagsm_hdr.mh_flags & M_PKTHDR0x0002)
1404 m->m_pkthdrM_dat.MH.MH_pkthdr.len -= olen;
1405 ip->ip_hl = sizeof(struct ip) >> 2;
1406 ip->ip_len = htons(ntohs(ip->ip_len) - olen)(__uint16_t)(__builtin_constant_p((__uint16_t)(__builtin_constant_p
(ip->ip_len) ? (__uint16_t)(((__uint16_t)(ip->ip_len) &
0xffU) << 8 | ((__uint16_t)(ip->ip_len) & 0xff00U
) >> 8) : __swap16md(ip->ip_len)) - olen) ? (__uint16_t
)(((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) :
__swap16md(ip->ip_len)) - olen) & 0xffU) << 8 |
((__uint16_t)((__uint16_t)(__builtin_constant_p(ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) :
__swap16md(ip->ip_len)) - olen) & 0xff00U) >> 8
) : __swap16md((__uint16_t)(__builtin_constant_p(ip->ip_len
) ? (__uint16_t)(((__uint16_t)(ip->ip_len) & 0xffU) <<
8 | ((__uint16_t)(ip->ip_len) & 0xff00U) >> 8) :
__swap16md(ip->ip_len)) - olen))
;
1407}
1408
1409const u_char inetctlerrmap[PRC_NCMDS21] = {
1410 0, 0, 0, 0,
1411 0, EMSGSIZE40, EHOSTDOWN64, EHOSTUNREACH65,
1412 EHOSTUNREACH65, EHOSTUNREACH65, ECONNREFUSED61, ECONNREFUSED61,
1413 EMSGSIZE40, EHOSTUNREACH65, 0, 0,
1414 0, 0, 0, 0,
1415 ENOPROTOOPT42
1416};
1417
1418/*
1419 * Forward a packet. If some error occurs return the sender
1420 * an icmp packet. Note we can't always generate a meaningful
1421 * icmp message because icmp doesn't have a large enough repertoire
1422 * of codes and types.
1423 *
1424 * If not forwarding, just drop the packet. This could be confusing
1425 * if ipforwarding was zero but some routing protocol was advancing
1426 * us as a gateway to somewhere. However, we must let the routing
1427 * protocol deal with that.
1428 *
1429 * The srcrt parameter indicates whether the packet is being forwarded
1430 * via a source route.
1431 */
1432void
1433ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
1434{
1435 struct mbuf mfake, *mcopy = NULL((void *)0);
1436 struct ip *ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
1437 struct sockaddr_in *sin;
1438 struct route ro;
1439 int error = 0, type = 0, code = 0, destmtu = 0, fake = 0, len;
1440 u_int32_t dest;
1441
1442 dest = 0;
1443 if (m->m_flagsm_hdr.mh_flags & (M_BCAST0x0100|M_MCAST0x0200) || in_canforward(ip->ip_dst) == 0) {
1444 ipstat_inc(ips_cantforward);
1445 m_freem(m);
1446 goto freecopy;
1447 }
1448 if (ip->ip_ttl <= IPTTLDEC1) {
1449 icmp_error(m, ICMP_TIMXCEED11, ICMP_TIMXCEED_INTRANS0, dest, 0);
1450 goto freecopy;
1451 }
1452
1453 memset(&ro, 0, sizeof(ro))__builtin_memset((&ro), (0), (sizeof(ro)));
1454 sin = satosin(&ro.ro_dst);
1455 sin->sin_family = AF_INET2;
1456 sin->sin_len = sizeof(*sin);
1457 sin->sin_addr = ip->ip_dst;
1458
1459 if (!rtisvalid(rt)) {
1460 rtfree(rt);
1461 rt = rtalloc_mpath(sintosa(sin), &ip->ip_src.s_addr,
1462 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid);
1463 if (rt == NULL((void *)0)) {
1464 ipstat_inc(ips_noroute);
1465 icmp_error(m, ICMP_UNREACH3, ICMP_UNREACH_HOST1, dest, 0);
1466 return;
1467 }
1468 }
1469
1470 /*
1471 * Save at most 68 bytes of the packet in case
1472 * we need to generate an ICMP message to the src.
1473 * The data is saved in the mbuf on the stack that
1474 * acts as a temporary storage not intended to be
1475 * passed down the IP stack or to the mfree.
1476 */
1477 memset(&mfake.m_hdr, 0, sizeof(mfake.m_hdr))__builtin_memset((&mfake.m_hdr), (0), (sizeof(mfake.m_hdr
)))
;
1478 mfake.m_typem_hdr.mh_type = m->m_typem_hdr.mh_type;
1479 if (m_dup_pkthdr(&mfake, m, M_DONTWAIT0x0002) == 0) {
1480 mfake.m_datam_hdr.mh_data = mfake.m_pktdatM_dat.MH.MH_dat.MH_databuf;
1481 len = min(ntohs(ip->ip_len)(__uint16_t)(__builtin_constant_p(ip->ip_len) ? (__uint16_t
)(((__uint16_t)(ip->ip_len) & 0xffU) << 8 | ((__uint16_t
)(ip->ip_len) & 0xff00U) >> 8) : __swap16md(ip->
ip_len))
, 68);
1482 m_copydata(m, 0, len, mfake.m_pktdatM_dat.MH.MH_dat.MH_databuf);
1483 mfake.m_pkthdrM_dat.MH.MH_pkthdr.len = mfake.m_lenm_hdr.mh_len = len;
1484#if NPF1 > 0
1485 pf_pkt_addr_changed(&mfake);
1486#endif /* NPF > 0 */
1487 fake = 1;
1488 }
1489
1490 ip->ip_ttl -= IPTTLDEC1;
1491
1492 /*
1493 * If forwarding packet using same interface that it came in on,
1494 * perhaps should send a redirect to sender to shortcut a hop.
1495 * Only send redirect if source is sending directly to us,
1496 * and if packet was not source routed (or has any options).
1497 * Also, don't send redirect if forwarding using a default route
1498 * or a route modified by a redirect.
1499 * Don't send redirect if we advertise destination's arp address
1500 * as ours (proxy arp).
1501 */
1502 if ((rt->rt_ifidx == ifp->if_index) &&
1503 (rt->rt_flags & (RTF_DYNAMIC0x10|RTF_MODIFIED0x20)) == 0 &&
1504 satosin(rt_key(rt)((rt)->rt_dest))->sin_addr.s_addr != 0 &&
1505 ipsendredirects && !srcrt &&
1506 !arpproxy(satosin(rt_key(rt)((rt)->rt_dest))->sin_addr, m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid)) {
1507 if ((ip->ip_src.s_addr & ifatoia(rt->rt_ifa)->ia_netmask) ==
1508 ifatoia(rt->rt_ifa)->ia_net) {
1509 if (rt->rt_flags & RTF_GATEWAY0x2)
1510 dest = satosin(rt->rt_gateway)->sin_addr.s_addr;
1511 else
1512 dest = ip->ip_dst.s_addr;
1513 /* Router requirements says to only send host redirects */
1514 type = ICMP_REDIRECT5;
1515 code = ICMP_REDIRECT_HOST1;
1516 }
1517 }
1518
1519 ro.ro_rt = rt;
1520 ro.ro_tableid = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid;
1521 error = ip_output(m, NULL((void *)0), &ro,
1522 (IP_FORWARDING0x1 | (ip_directedbcast ? IP_ALLOWBROADCAST0x0020 : 0)),
1523 NULL((void *)0), NULL((void *)0), 0);
1524 rt = ro.ro_rt;
1525 if (error)
1526 ipstat_inc(ips_cantforward);
1527 else {
1528 ipstat_inc(ips_forward);
1529 if (type)
1530 ipstat_inc(ips_redirectsent);
1531 else
1532 goto freecopy;
1533 }
1534 if (!fake)
1535 goto freecopy;
1536
1537 switch (error) {
1538 case 0: /* forwarded, but need redirect */
1539 /* type, code set above */
1540 break;
1541
1542 case EMSGSIZE40:
1543 type = ICMP_UNREACH3;
1544 code = ICMP_UNREACH_NEEDFRAG4;
1545 if (rt != NULL((void *)0)) {
1546 if (rt->rt_mturt_rmx.rmx_mtu) {
1547 destmtu = rt->rt_mturt_rmx.rmx_mtu;
1548 } else {
1549 struct ifnet *destifp;
1550
1551 destifp = if_get(rt->rt_ifidx);
1552 if (destifp != NULL((void *)0))
1553 destmtu = destifp->if_mtuif_data.ifi_mtu;
1554 if_put(destifp);
1555 }
1556 }
1557 ipstat_inc(ips_cantfrag);
1558 if (destmtu == 0)
1559 goto freecopy;
1560 break;
1561
1562 case EACCES13:
1563 /*
1564 * pf(4) blocked the packet. There is no need to send an ICMP
1565 * packet back since pf(4) takes care of it.
1566 */
1567 goto freecopy;
1568
1569 case ENOBUFS55:
1570 /*
1571 * a router should not generate ICMP_SOURCEQUENCH as
1572 * required in RFC1812 Requirements for IP Version 4 Routers.
1573 * source quench could be a big problem under DoS attacks,
1574 * or the underlying interface is rate-limited.
1575 */
1576 goto freecopy;
1577
1578 case ENETUNREACH51: /* shouldn't happen, checked above */
1579 case EHOSTUNREACH65:
1580 case ENETDOWN50:
1581 case EHOSTDOWN64:
1582 default:
1583 type = ICMP_UNREACH3;
1584 code = ICMP_UNREACH_HOST1;
1585 break;
1586 }
1587 mcopy = m_copym(&mfake, 0, len, M_DONTWAIT0x0002);
1588 if (mcopy)
1589 icmp_error(mcopy, type, code, dest, destmtu);
1590
1591freecopy:
1592 if (fake)
1593 m_tag_delete_chain(&mfake);
1594 rtfree(rt);
1595}
1596
1597int
1598ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
1599 size_t newlen)
1600{
1601 int error;
1602#ifdef MROUTING1
1603 extern struct mrtstat mrtstat;
1604#endif
1605
1606 /* Almost all sysctl names at this level are terminal. */
1607 if (namelen != 1 && name[0] != IPCTL_IFQUEUE30 &&
1608 name[0] != IPCTL_ARPQUEUE41)
1609 return (ENOTDIR20);
1610
1611 switch (name[0]) {
1612 case IPCTL_SOURCEROUTE5:
1613 /*
1614 * Don't allow this to change in a secure environment.
1615 */
1616 if (newp && securelevel > 0)
1617 return (EPERM1);
1618 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1619 error = sysctl_int(oldp, oldlenp, newp, newlen,
1620 &ip_dosourceroute);
1621 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1622 return (error);
1623 case IPCTL_MTUDISC27:
1624 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1625 error = sysctl_int(oldp, oldlenp, newp, newlen,
1626 &ip_mtudisc);
1627 if (ip_mtudisc != 0 && ip_mtudisc_timeout_q == NULL((void *)0)) {
1628 ip_mtudisc_timeout_q =
1629 rt_timer_queue_create(ip_mtudisc_timeout);
1630 } else if (ip_mtudisc == 0 && ip_mtudisc_timeout_q != NULL((void *)0)) {
1631 rt_timer_queue_destroy(ip_mtudisc_timeout_q);
1632 ip_mtudisc_timeout_q = NULL((void *)0);
1633 }
1634 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1635 return error;
1636 case IPCTL_MTUDISCTIMEOUT28:
1637 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1638 error = sysctl_int(oldp, oldlenp, newp, newlen,
1639 &ip_mtudisc_timeout);
1640 if (ip_mtudisc_timeout_q != NULL((void *)0))
1641 rt_timer_queue_change(ip_mtudisc_timeout_q,
1642 ip_mtudisc_timeout);
1643 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1644 return (error);
1645#ifdef IPSEC1
1646 case IPCTL_ENCDEBUG12:
1647 case IPCTL_IPSEC_STATS13:
1648 case IPCTL_IPSEC_EXPIRE_ACQUIRE14:
1649 case IPCTL_IPSEC_EMBRYONIC_SA_TIMEOUT15:
1650 case IPCTL_IPSEC_REQUIRE_PFS16:
1651 case IPCTL_IPSEC_SOFT_ALLOCATIONS17:
1652 case IPCTL_IPSEC_ALLOCATIONS18:
1653 case IPCTL_IPSEC_SOFT_BYTES19:
1654 case IPCTL_IPSEC_BYTES20:
1655 case IPCTL_IPSEC_TIMEOUT21:
1656 case IPCTL_IPSEC_SOFT_TIMEOUT22:
1657 case IPCTL_IPSEC_SOFT_FIRSTUSE23:
1658 case IPCTL_IPSEC_FIRSTUSE24:
1659 case IPCTL_IPSEC_ENC_ALGORITHM25:
1660 case IPCTL_IPSEC_AUTH_ALGORITHM26:
1661 case IPCTL_IPSEC_IPCOMP_ALGORITHM29:
1662 return (ipsec_sysctl(name, namelen, oldp, oldlenp, newp,
1663 newlen));
1664#endif
1665 case IPCTL_IFQUEUE30:
1666 return (EOPNOTSUPP45);
1667 case IPCTL_ARPQUEUE41:
1668 return (sysctl_niq(name + 1, namelen - 1,sysctl_mq((name + 1), (namelen - 1), (oldp), (oldlenp), (newp
), (newlen), &(&arpinq)->ni_q)
1669 oldp, oldlenp, newp, newlen, &arpinq)sysctl_mq((name + 1), (namelen - 1), (oldp), (oldlenp), (newp
), (newlen), &(&arpinq)->ni_q)
);
1670 case IPCTL_ARPQUEUED36:
1671 return (sysctl_rdint(oldp, oldlenp, newp, la_hold_total));
1672 case IPCTL_STATS33:
1673 return (ip_sysctl_ipstat(oldp, oldlenp, newp));
1674#ifdef MROUTING1
1675 case IPCTL_MRTSTATS35:
1676 return (sysctl_rdstruct(oldp, oldlenp, newp,
1677 &mrtstat, sizeof(mrtstat)));
1678 case IPCTL_MRTMFC37:
1679 if (newp)
1680 return (EPERM1);
1681 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1682 error = mrt_sysctl_mfc(oldp, oldlenp);
1683 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1684 return (error);
1685 case IPCTL_MRTVIF38:
1686 if (newp)
1687 return (EPERM1);
1688 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1689 error = mrt_sysctl_vif(oldp, oldlenp);
1690 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1691 return (error);
1692#else
1693 case IPCTL_MRTPROTO34:
1694 case IPCTL_MRTSTATS35:
1695 case IPCTL_MRTMFC37:
1696 case IPCTL_MRTVIF38:
1697 return (EOPNOTSUPP45);
1698#endif
1699 default:
1700 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1701 error = sysctl_bounded_arr(ipctl_vars, nitems(ipctl_vars)(sizeof((ipctl_vars)) / sizeof((ipctl_vars)[0])),
1702 name, namelen, oldp, oldlenp, newp, newlen);
1703 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1704 return (error);
1705 }
1706 /* NOTREACHED */
1707}
1708
1709int
1710ip_sysctl_ipstat(void *oldp, size_t *oldlenp, void *newp)
1711{
1712 uint64_t counters[ips_ncounters];
1713 struct ipstat ipstat;
1714 u_long *words = (u_long *)&ipstat;
1715 int i;
1716
1717 CTASSERT(sizeof(ipstat) == (nitems(counters) * sizeof(u_long)))extern char _ctassert[(sizeof(ipstat) == ((sizeof((counters))
/ sizeof((counters)[0])) * sizeof(u_long))) ? 1 : -1 ] __attribute__
((__unused__))
;
1718 memset(&ipstat, 0, sizeof ipstat)__builtin_memset((&ipstat), (0), (sizeof ipstat));
1719 counters_read(ipcounters, counters, nitems(counters)(sizeof((counters)) / sizeof((counters)[0])));
1720
1721 for (i = 0; i < nitems(counters)(sizeof((counters)) / sizeof((counters)[0])); i++)
1722 words[i] = (u_long)counters[i];
1723
1724 return (sysctl_rdstruct(oldp, oldlenp, newp, &ipstat, sizeof(ipstat)));
1725}
1726
1727void
1728ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
1729 struct mbuf *m)
1730{
1731 if (inp->inp_socket->so_options & SO_TIMESTAMP0x0800) {
1732 struct timeval tv;
1733
1734 m_microtime(m, &tv);
1735 *mp = sbcreatecontrol((caddr_t) &tv, sizeof(tv),
1736 SCM_TIMESTAMP0x04, SOL_SOCKET0xffff);
1737 if (*mp)
1738 mp = &(*mp)->m_nextm_hdr.mh_next;
1739 }
1740
1741 if (inp->inp_flags & INP_RECVDSTADDR0x004) {
1742 *mp = sbcreatecontrol((caddr_t) &ip->ip_dst,
1743 sizeof(struct in_addr), IP_RECVDSTADDR7, IPPROTO_IP0);
1744 if (*mp)
1745 mp = &(*mp)->m_nextm_hdr.mh_next;
1746 }
1747#ifdef notyet
1748 /* this code is broken and will probably never be fixed. */
1749 /* options were tossed already */
1750 if (inp->inp_flags & INP_RECVOPTS0x001) {
1751 *mp = sbcreatecontrol((caddr_t) opts_deleted_above,
1752 sizeof(struct in_addr), IP_RECVOPTS5, IPPROTO_IP0);
1753 if (*mp)
1754 mp = &(*mp)->m_nextm_hdr.mh_next;
1755 }
1756 /* ip_srcroute doesn't do what we want here, need to fix */
1757 if (inp->inp_flags & INP_RECVRETOPTS0x002) {
1758 *mp = sbcreatecontrol((caddr_t) ip_srcroute(m),
1759 sizeof(struct in_addr), IP_RECVRETOPTS6, IPPROTO_IP0);
1760 if (*mp)
1761 mp = &(*mp)->m_nextm_hdr.mh_next;
1762 }
1763#endif
1764 if (inp->inp_flags & INP_RECVIF0x080) {
1765 struct sockaddr_dl sdl;
1766 struct ifnet *ifp;
1767
1768 ifp = if_get(m->m_pkthdrM_dat.MH.MH_pkthdr.ph_ifidx);
1769 if (ifp == NULL((void *)0) || ifp->if_sadl == NULL((void *)0)) {
1770 memset(&sdl, 0, sizeof(sdl))__builtin_memset((&sdl), (0), (sizeof(sdl)));
1771 sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data[0])__builtin_offsetof(struct sockaddr_dl, sdl_data[0]);
1772 sdl.sdl_family = AF_LINK18;
1773 sdl.sdl_index = ifp != NULL((void *)0) ? ifp->if_index : 0;
1774 sdl.sdl_nlen = sdl.sdl_alen = sdl.sdl_slen = 0;
1775 *mp = sbcreatecontrol((caddr_t) &sdl, sdl.sdl_len,
1776 IP_RECVIF30, IPPROTO_IP0);
1777 } else {
1778 *mp = sbcreatecontrol((caddr_t) ifp->if_sadl,
1779 ifp->if_sadl->sdl_len, IP_RECVIF30, IPPROTO_IP0);
1780 }
1781 if (*mp)
1782 mp = &(*mp)->m_nextm_hdr.mh_next;
1783 if_put(ifp);
1784 }
1785 if (inp->inp_flags & INP_RECVTTL0x040) {
1786 *mp = sbcreatecontrol((caddr_t) &ip->ip_ttl,
1787 sizeof(u_int8_t), IP_RECVTTL31, IPPROTO_IP0);
1788 if (*mp)
1789 mp = &(*mp)->m_nextm_hdr.mh_next;
1790 }
1791 if (inp->inp_flags & INP_RECVRTABLE0x400) {
1792 u_int rtableid = inp->inp_rtableid;
1793
1794#if NPF1 > 0
1795 if (m && m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags & PF_TAG_DIVERTED0x08) {
1796 struct pf_divert *divert;
1797
1798 divert = pf_find_divert(m);
1799 KASSERT(divert != NULL)((divert != ((void *)0)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/netinet/ip_input.c"
, 1799, "divert != NULL"))
;
1800 rtableid = divert->rdomain;
1801 }
1802#endif
1803
1804 *mp = sbcreatecontrol((caddr_t) &rtableid,
1805 sizeof(u_int), IP_RECVRTABLE35, IPPROTO_IP0);
1806 if (*mp)
1807 mp = &(*mp)->m_nextm_hdr.mh_next;
Value stored to 'mp' is never read
1808 }
1809}
1810
1811void
1812ip_send_do_dispatch(void *xmq, int flags)
1813{
1814 struct mbuf_queue *mq = xmq;
1815 struct mbuf *m;
1816 struct mbuf_list ml;
1817 struct m_tag *mtag;
1818 u_int32_t ipsecflowinfo = 0;
1819
1820 mq_delist(mq, &ml);
1821 if (ml_empty(&ml)((&ml)->ml_len == 0))
1822 return;
1823
1824 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1825 while ((m = ml_dequeue(&ml)) != NULL((void *)0)) {
1826 if ((mtag = m_tag_find(m, PACKET_TAG_IPSEC_FLOWINFO0x0004, NULL((void *)0)))
1827 != NULL((void *)0)) {
1828 ipsecflowinfo = *(u_int32_t *)(mtag + 1);
1829 m_tag_delete(m, mtag);
1830 }
1831 ip_output(m, NULL((void *)0), NULL((void *)0), flags, NULL((void *)0), NULL((void *)0), ipsecflowinfo);
1832 }
1833 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1834}
1835
1836void
1837ip_sendraw_dispatch(void *xmq)
1838{
1839 ip_send_do_dispatch(xmq, IP_RAWOUTPUT0x2);
1840}
1841
1842void
1843ip_send_dispatch(void *xmq)
1844{
1845 ip_send_do_dispatch(xmq, 0);
1846}
1847
1848void
1849ip_send(struct mbuf *m)
1850{
1851 mq_enqueue(&ipsend_mq, m);
1852 task_add(net_tq(0), &ipsend_task);
1853}
1854
1855void
1856ip_send_raw(struct mbuf *m)
1857{
1858 mq_enqueue(&ipsendraw_mq, m);
1859 task_add(net_tq(0), &ipsendraw_task);
1860}