Bug Summary

File:netinet/ip_output.c
Warning:line 665, column 6
Branch condition evaluates to a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ip_output.c -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 -ffp-contract=on -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 -target-feature +retpoline-external-thunk -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/llvm16/lib/clang/16 -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/legacy-dpm -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc -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/swsmu/smu13 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/inc -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/pm/swsmu/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/inc/pmfw_if -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 SUSPEND -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 -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 -fcf-protection=branch -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 /home/ben/Projects/scan/2024-01-11-110808-61670-1 -x c /usr/src/sys/netinet/ip_output.c
1/* $OpenBSD: ip_output.c,v 1.392 2023/12/01 15:30:47 bluhm Exp $ */
2/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
3
4/*
5 * Copyright (c) 1982, 1986, 1988, 1990, 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_output.c 8.3 (Berkeley) 1/21/94
33 */
34
35#include "pf.h"
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/mbuf.h>
40#include <sys/protosw.h>
41#include <sys/socket.h>
42#include <sys/socketvar.h>
43#include <sys/proc.h>
44#include <sys/kernel.h>
45
46#include <net/if.h>
47#include <net/if_var.h>
48#include <net/if_enc.h>
49#include <net/route.h>
50
51#include <netinet/in.h>
52#include <netinet/ip.h>
53#include <netinet/in_pcb.h>
54#include <netinet/in_var.h>
55#include <netinet/ip_var.h>
56#include <netinet/ip_icmp.h>
57#include <netinet/tcp.h>
58#include <netinet/udp.h>
59#include <netinet/tcp_timer.h>
60#include <netinet/tcp_var.h>
61#include <netinet/udp_var.h>
62
63#if NPF1 > 0
64#include <net/pfvar.h>
65#endif
66
67#ifdef IPSEC1
68#ifdef ENCDEBUG
69#define DPRINTF(fmt, args...)do { } while (0) \
70 do { \
71 if (encdebug) \
72 printf("%s: " fmt "\n", __func__, ## args); \
73 } while (0)
74#else
75#define DPRINTF(fmt, args...)do { } while (0) \
76 do { } while (0)
77#endif
78#endif /* IPSEC */
79
80int ip_pcbopts(struct mbuf **, struct mbuf *);
81int ip_multicast_if(struct ip_mreqn *, u_int, unsigned int *);
82int ip_setmoptions(int, struct ip_moptions **, struct mbuf *, u_int);
83void ip_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in *);
84static u_int16_t in_cksum_phdr(u_int32_t, u_int32_t, u_int32_t);
85void in_delayed_cksum(struct mbuf *);
86
87int ip_output_ipsec_lookup(struct mbuf *m, int hlen, const u_char seclevel[],
88 struct tdb **, int ipsecflowinfo);
89void ip_output_ipsec_pmtu_update(struct tdb *, struct route *, struct in_addr,
90 int, int);
91int ip_output_ipsec_send(struct tdb *, struct mbuf *, struct route *, int);
92
93/*
94 * IP output. The packet in mbuf chain m contains a skeletal IP
95 * header (with len, off, ttl, proto, tos, src, dst).
96 * The mbuf chain containing the packet will be freed.
97 * The mbuf opt, if present, will not be freed.
98 */
99int
100ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
101 struct ip_moptions *imo, const u_char seclevel[], u_int32_t ipsecflowinfo)
102{
103 struct ip *ip;
104 struct ifnet *ifp = NULL((void *)0);
105 struct mbuf_list ml;
106 int hlen = sizeof (struct ip);
107 int error = 0;
108 struct route iproute;
109 struct sockaddr_in *dst;
110 struct tdb *tdb = NULL((void *)0);
111 u_long mtu;
112#if NPF1 > 0
113 u_int orig_rtableid;
114#endif
115
116 NET_ASSERT_LOCKED()do { int _s = rw_status(&netlock); if ((splassert_ctl >
0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail
(0x0002UL, _s, __func__); } while (0)
;
1
Assuming 'splassert_ctl' is <= 0
2
Loop condition is false. Exiting loop
117
118#ifdef DIAGNOSTIC1
119 if ((m->m_flagsm_hdr.mh_flags & M_PKTHDR0x0002) == 0)
3
Assuming the condition is false
4
Taking false branch
120 panic("ip_output no HDR");
121#endif
122 if (opt)
5
Assuming 'opt' is null
6
Taking false branch
123 m = ip_insertoptions(m, opt, &hlen);
124
125 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
126
127 /*
128 * Fill in IP header.
129 */
130 if ((flags & (IP_FORWARDING0x1|IP_RAWOUTPUT0x2)) == 0) {
7
Assuming the condition is false
8
Taking false branch
131 ip->ip_v = IPVERSION4;
132 ip->ip_off &= htons(IP_DF)(__uint16_t)(__builtin_constant_p(0x4000) ? (__uint16_t)(((__uint16_t
)(0x4000) & 0xffU) << 8 | ((__uint16_t)(0x4000) &
0xff00U) >> 8) : __swap16md(0x4000))
;
133 ip->ip_id = htons(ip_randomid())(__uint16_t)(__builtin_constant_p(ip_randomid()) ? (__uint16_t
)(((__uint16_t)(ip_randomid()) & 0xffU) << 8 | ((__uint16_t
)(ip_randomid()) & 0xff00U) >> 8) : __swap16md(ip_randomid
()))
;
134 ip->ip_hl = hlen >> 2;
135 ipstat_inc(ips_localout);
136 } else {
137 hlen = ip->ip_hl << 2;
138 }
139
140 /*
141 * We should not send traffic to 0/8 say both Stevens and RFCs
142 * 5735 section 3 and 1122 sections 3.2.1.3 and 3.3.6.
143 */
144 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) == 0
) {
9
'?' condition is false
10
Assuming the condition is false
11
Taking false branch
145 error = ENETUNREACH51;
146 goto bad;
147 }
148
149#if NPF1 > 0
150 orig_rtableid = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid;
151reroute:
152#endif
153
154 /*
155 * Do a route lookup now in case we need the source address to
156 * do an SPD lookup in IPsec; for most packets, the source address
157 * is set at a higher level protocol. ICMPs and other packets
158 * though (e.g., traceroute) have a source address of zeroes.
159 */
160 if (ro == NULL((void *)0)) {
12
Assuming 'ro' is not equal to NULL
13
Taking false branch
161 ro = &iproute;
162 memset(ro, 0, sizeof(*ro))__builtin_memset((ro), (0), (sizeof(*ro)));
163 }
164
165 dst = satosin(&ro->ro_dst);
166
167 /*
168 * If there is a cached route, check that it is to the same
169 * destination and is still up. If not, free it and try again.
170 */
171 if (!rtisvalid(ro->ro_rt) ||
14
Assuming the condition is false
17
Taking false branch
172 dst->sin_addr.s_addr != ip->ip_dst.s_addr ||
15
Assuming 'dst->sin_addr.s_addr' is equal to 'ip->ip_dst.s_addr'
173 ro->ro_tableid != m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid) {
16
Assuming field 'ro_tableid' is equal to field 'ph_rtableid'
174 rtfree(ro->ro_rt);
175 ro->ro_rt = NULL((void *)0);
176 }
177
178 if (ro->ro_rt == NULL((void *)0)) {
18
Assuming field 'ro_rt' is not equal to NULL
179 dst->sin_family = AF_INET2;
180 dst->sin_len = sizeof(*dst);
181 dst->sin_addr = ip->ip_dst;
182 ro->ro_tableid = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid;
183 }
184
185 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)))))
||
19
Taking false branch
20
'?' condition is true
21
'?' condition is true
22
Assuming the condition is false
186 (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
))))
)) &&
23
'?' condition is true
24
Assuming the condition is false
187 imo != NULL((void *)0) && (ifp = if_get(imo->imo_ifidx)) != NULL((void *)0)) {
188
189 mtu = ifp->if_mtuif_data.ifi_mtu;
190 if (ip->ip_src.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
))))
) {
191 struct in_ifaddr *ia;
192
193 IFP_TO_IA(ifp, ia)do { struct ifaddr *ifa; do { int _s = rw_status(&netlock
); if ((splassert_ctl > 0) && (_s != 0x0001UL &&
_s != 0x0002UL)) splassert_fail(0x0002UL, _s, __func__); } while
(0); for((ifa) = ((&(ifp)->if_addrlist)->tqh_first
); (ifa) != ((void *)0); (ifa) = ((ifa)->ifa_list.tqe_next
)) { if (ifa->ifa_addr->sa_family == 2) break; } (ia) =
ifatoia(ifa); } while ( 0)
;
194 if (ia != NULL((void *)0))
195 ip->ip_src = ia->ia_addr.sin_addr;
196 }
197 } else {
198 struct in_ifaddr *ia;
199
200 if (ro->ro_rt
24.1
Field 'ro_rt' is not equal to NULL
== NULL((void *)0))
25
Taking false branch
201 ro->ro_rt = rtalloc_mpath(&ro->ro_dst,
202 &ip->ip_src.s_addr, ro->ro_tableid);
203
204 if (ro->ro_rt
25.1
Field 'ro_rt' is not equal to NULL
== NULL((void *)0)) {
26
Taking false branch
205 ipstat_inc(ips_noroute);
206 error = EHOSTUNREACH65;
207 goto bad;
208 }
209
210 ia = ifatoia(ro->ro_rt->rt_ifa);
211 if (ISSET(ro->ro_rt->rt_flags, RTF_LOCAL)((ro->ro_rt->rt_flags) & (0x200000)))
27
Assuming the condition is false
28
Taking false branch
212 ifp = if_get(rtable_loindex(m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid));
213 else
214 ifp = if_get(ro->ro_rt->rt_ifidx);
215 /*
216 * We aren't using rtisvalid() here because the UP/DOWN state
217 * machine is broken with some Ethernet drivers like em(4).
218 * As a result we might try to use an invalid cached route
219 * entry while an interface is being detached.
220 */
221 if (ifp == NULL((void *)0)) {
29
Assuming 'ifp' is not equal to NULL
30
Taking false branch
222 ipstat_inc(ips_noroute);
223 error = EHOSTUNREACH65;
224 goto bad;
225 }
226 if ((mtu = ro->ro_rt->rt_mturt_rmx.rmx_mtu) == 0)
31
Assuming the condition is false
32
Taking false branch
227 mtu = ifp->if_mtuif_data.ifi_mtu;
228
229 if (ro->ro_rt->rt_flags & RTF_GATEWAY0x2)
33
Assuming the condition is false
230 dst = satosin(ro->ro_rt->rt_gateway);
231
232 /* Set the source IP address */
233 if (ip->ip_src.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
))))
&& ia)
34
'?' condition is true
35
Assuming the condition is false
234 ip->ip_src = ia->ia_addr.sin_addr;
235 }
236
237#ifdef IPSEC1
238 if (ipsec_in_use || seclevel != NULL((void *)0)) {
36
Assuming 'ipsec_in_use' is 0
37
Assuming 'seclevel' is not equal to NULL
38
Taking true branch
239 /* Do we have any pending SAs to apply ? */
240 error = ip_output_ipsec_lookup(m, hlen, seclevel, &tdb,
241 ipsecflowinfo);
242 if (error
38.1
'error' is 0
) {
39
Taking false branch
243 /* Should silently drop packet */
244 if (error == -EINVAL22)
245 error = 0;
246 goto bad;
247 }
248 if (tdb
39.1
'tdb' is not equal to NULL
!= NULL((void *)0)) {
40
Taking true branch
249 /*
250 * If it needs TCP/UDP hardware-checksumming, do the
251 * computation now.
252 */
253 in_proto_cksum_out(m, NULL((void *)0));
254 }
255 }
256#endif /* IPSEC */
257
258 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)))))
||
41
'?' condition is true
42
'?' condition is true
259 (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
))))
)) {
43
'?' condition is true
260
261 m->m_flagsm_hdr.mh_flags |= (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
))))
) ?
262 M_BCAST0x0100 : M_MCAST0x0200;
263
264 /*
265 * IP destination address is multicast. Make sure "dst"
266 * still points to the address in "ro". (It may have been
267 * changed to point to a gateway address, above.)
268 */
269 dst = satosin(&ro->ro_dst);
270
271 /*
272 * See if the caller provided any multicast options
273 */
274 if (imo != NULL((void *)0))
275 ip->ip_ttl = imo->imo_ttl;
276 else
277 ip->ip_ttl = IP_DEFAULT_MULTICAST_TTL1;
278
279 /*
280 * if we don't know the outgoing ifp yet, we can't generate
281 * output
282 */
283 if (!ifp) {
284 ipstat_inc(ips_noroute);
285 error = EHOSTUNREACH65;
286 goto bad;
287 }
288
289 /*
290 * Confirm that the outgoing interface supports multicast,
291 * but only if the packet actually is going out on that
292 * interface (i.e., no IPsec is applied).
293 */
294 if ((((m->m_flagsm_hdr.mh_flags & M_MCAST0x0200) &&
295 (ifp->if_flags & IFF_MULTICAST0x8000) == 0) ||
296 ((m->m_flagsm_hdr.mh_flags & M_BCAST0x0100) &&
297 (ifp->if_flags & IFF_BROADCAST0x2) == 0)) && (tdb == NULL((void *)0))) {
298 ipstat_inc(ips_noroute);
299 error = ENETUNREACH51;
300 goto bad;
301 }
302
303 /*
304 * If source address not specified yet, use address
305 * of outgoing interface.
306 */
307 if (ip->ip_src.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
))))
) {
308 struct in_ifaddr *ia;
309
310 IFP_TO_IA(ifp, ia)do { struct ifaddr *ifa; do { int _s = rw_status(&netlock
); if ((splassert_ctl > 0) && (_s != 0x0001UL &&
_s != 0x0002UL)) splassert_fail(0x0002UL, _s, __func__); } while
(0); for((ifa) = ((&(ifp)->if_addrlist)->tqh_first
); (ifa) != ((void *)0); (ifa) = ((ifa)->ifa_list.tqe_next
)) { if (ifa->ifa_addr->sa_family == 2) break; } (ia) =
ifatoia(ifa); } while ( 0)
;
311 if (ia != NULL((void *)0))
312 ip->ip_src = ia->ia_addr.sin_addr;
313 }
314
315 if ((imo == NULL((void *)0) || imo->imo_loop) &&
316 in_hasmulti(&ip->ip_dst, ifp)) {
317 /*
318 * If we belong to the destination multicast group
319 * on the outgoing interface, and the caller did not
320 * forbid loopback, loop back a copy.
321 * Can't defer TCP/UDP checksumming, do the
322 * computation now.
323 */
324 in_proto_cksum_out(m, NULL((void *)0));
325 ip_mloopback(ifp, m, dst);
326 }
327#ifdef MROUTING1
328 else {
329 /*
330 * If we are acting as a multicast router, perform
331 * multicast forwarding as if the packet had just
332 * arrived on the interface to which we are about
333 * to send. The multicast forwarding function
334 * recursively calls this function, using the
335 * IP_FORWARDING flag to prevent infinite recursion.
336 *
337 * Multicasts that are looped back by ip_mloopback(),
338 * above, will be forwarded by the ip_input() routine,
339 * if necessary.
340 */
341 if (ipmforwarding && ip_mrouter[ifp->if_rdomainif_data.ifi_rdomain] &&
342 (flags & IP_FORWARDING0x1) == 0) {
343 int rv;
344
345 KERNEL_LOCK()_kernel_lock();
346 rv = ip_mforward(m, ifp);
347 KERNEL_UNLOCK()_kernel_unlock();
348 if (rv != 0)
349 goto bad;
350 }
351 }
352#endif
353 /*
354 * Multicasts with a time-to-live of zero may be looped-
355 * back, above, but must not be transmitted on a network.
356 * Also, multicasts addressed to the loopback interface
357 * are not sent -- the above call to ip_mloopback() will
358 * loop back a copy if this host actually belongs to the
359 * destination group on the loopback interface.
360 */
361 if (ip->ip_ttl == 0 || (ifp->if_flags & IFF_LOOPBACK0x8) != 0)
362 goto bad;
363
364 goto sendit;
365 }
366
367 /*
368 * Look for broadcast address and verify user is allowed to send
369 * such a packet; if the packet is going in an IPsec tunnel, skip
370 * this check.
371 */
372 if ((tdb
43.1
'tdb' is not equal to NULL
== NULL((void *)0)) && ((dst->sin_addr.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
))))
) ||
373 (ro && ro->ro_rt && ISSET(ro->ro_rt->rt_flags, RTF_BROADCAST)((ro->ro_rt->rt_flags) & (0x400000))))) {
374 if ((ifp->if_flags & IFF_BROADCAST0x2) == 0) {
375 error = EADDRNOTAVAIL49;
376 goto bad;
377 }
378 if ((flags & IP_ALLOWBROADCAST0x0020) == 0) {
379 error = EACCES13;
380 goto bad;
381 }
382
383 /* Don't allow broadcast messages to be fragmented */
384 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))
> ifp->if_mtuif_data.ifi_mtu) {
385 error = EMSGSIZE40;
386 goto bad;
387 }
388 m->m_flagsm_hdr.mh_flags |= M_BCAST0x0100;
389 } else
390 m->m_flagsm_hdr.mh_flags &= ~M_BCAST0x0100;
391
392sendit:
393 /*
394 * If we're doing Path MTU discovery, we need to set DF unless
395 * the route's MTU is locked.
396 */
397 if ((flags & IP_MTUDISC0x0800) && ro && ro->ro_rt &&
44
Assuming the condition is false
398 (ro->ro_rt->rt_locksrt_rmx.rmx_locks & RTV_MTU0x1) == 0)
399 ip->ip_off |= htons(IP_DF)(__uint16_t)(__builtin_constant_p(0x4000) ? (__uint16_t)(((__uint16_t
)(0x4000) & 0xffU) << 8 | ((__uint16_t)(0x4000) &
0xff00U) >> 8) : __swap16md(0x4000))
;
400
401#ifdef IPSEC1
402 /*
403 * Check if the packet needs encapsulation.
404 */
405 if (tdb
44.1
'tdb' is not equal to NULL
!= NULL((void *)0)) {
45
Taking true branch
406 /* Callee frees mbuf */
407 error = ip_output_ipsec_send(tdb, m, ro,
48
Calling 'ip_output_ipsec_send'
408 (flags & IP_FORWARDING0x1) ? 1 : 0);
46
Assuming the condition is false
47
'?' condition is false
409 goto done;
410 }
411#endif /* IPSEC */
412
413 /*
414 * Packet filter
415 */
416#if NPF1 > 0
417 if (pf_test(AF_INET2, (flags & IP_FORWARDING0x1) ? PF_FWD : PF_OUT,
418 ifp, &m) != PF_PASS) {
419 error = EACCES13;
420 goto bad;
421 }
422 if (m == NULL((void *)0))
423 goto done;
424 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
425 hlen = ip->ip_hl << 2;
426 if ((m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags & (PF_TAG_REROUTE0x20 | PF_TAG_GENERATED0x01)) ==
427 (PF_TAG_REROUTE0x20 | PF_TAG_GENERATED0x01))
428 /* already rerun the route lookup, go on */
429 m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags &= ~(PF_TAG_GENERATED0x01 | PF_TAG_REROUTE0x20);
430 else if (m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags & PF_TAG_REROUTE0x20) {
431 /* tag as generated to skip over pf_test on rerun */
432 m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags |= PF_TAG_GENERATED0x01;
433 ro = NULL((void *)0);
434 if_put(ifp); /* drop reference since target changed */
435 ifp = NULL((void *)0);
436 goto reroute;
437 }
438#endif
439
440#ifdef IPSEC1
441 if (ipsec_in_use && (flags & IP_FORWARDING0x1) && (ipforwarding == 2) &&
442 (m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE0x0001, NULL((void *)0)) == NULL((void *)0))) {
443 error = EHOSTUNREACH65;
444 goto bad;
445 }
446#endif
447
448 /*
449 * If TSO or small enough for interface, can just send directly.
450 */
451 error = if_output_tso(ifp, &m, sintosa(dst), ro->ro_rt, mtu);
452 if (error || m == NULL((void *)0))
453 goto done;
454
455 /*
456 * Too large for interface; fragment if possible.
457 * Must be able to put at least 8 bytes per fragment.
458 */
459 if (ip->ip_off & htons(IP_DF)(__uint16_t)(__builtin_constant_p(0x4000) ? (__uint16_t)(((__uint16_t
)(0x4000) & 0xffU) << 8 | ((__uint16_t)(0x4000) &
0xff00U) >> 8) : __swap16md(0x4000))
) {
460#ifdef IPSEC1
461 if (ip_mtudisc)
462 ipsec_adjust_mtu(m, ifp->if_mtuif_data.ifi_mtu);
463#endif
464 error = EMSGSIZE40;
465#if NPF1 > 0
466 /* pf changed routing table, use orig rtable for path MTU */
467 if (ro->ro_tableid != orig_rtableid) {
468 rtfree(ro->ro_rt);
469 ro->ro_tableid = orig_rtableid;
470 ro->ro_rt = icmp_mtudisc_clone(
471 satosin(&ro->ro_dst)->sin_addr, ro->ro_tableid, 0);
472 }
473#endif
474 /*
475 * This case can happen if the user changed the MTU
476 * of an interface after enabling IP on it. Because
477 * most netifs don't keep track of routes pointing to
478 * them, there is no way for one to update all its
479 * routes when the MTU is changed.
480 */
481 if (rtisvalid(ro->ro_rt) &&
482 ISSET(ro->ro_rt->rt_flags, RTF_HOST)((ro->ro_rt->rt_flags) & (0x4)) &&
483 !(ro->ro_rt->rt_locksrt_rmx.rmx_locks & RTV_MTU0x1) &&
484 (ro->ro_rt->rt_mturt_rmx.rmx_mtu > ifp->if_mtuif_data.ifi_mtu)) {
485 ro->ro_rt->rt_mturt_rmx.rmx_mtu = ifp->if_mtuif_data.ifi_mtu;
486 }
487 ipstat_inc(ips_cantfrag);
488 goto bad;
489 }
490
491 if ((error = ip_fragment(m, &ml, ifp, mtu)) ||
492 (error = if_output_ml(ifp, &ml, sintosa(dst), ro->ro_rt)))
493 goto done;
494 ipstat_inc(ips_fragmented);
495
496done:
497 if (ro == &iproute && ro->ro_rt)
498 rtfree(ro->ro_rt);
499 if_put(ifp);
500#ifdef IPSEC1
501 tdb_unref(tdb);
502#endif /* IPSEC */
503 return (error);
504
505bad:
506 m_freem(m);
507 goto done;
508}
509
510#ifdef IPSEC1
511int
512ip_output_ipsec_lookup(struct mbuf *m, int hlen, const u_char seclevel[],
513 struct tdb **tdbout, int ipsecflowinfo)
514{
515 struct m_tag *mtag;
516 struct tdb_ident *tdbi;
517 struct tdb *tdb;
518 struct ipsec_ids *ids = NULL((void *)0);
519 int error;
520
521 /* Do we have any pending SAs to apply ? */
522 if (ipsecflowinfo)
523 ids = ipsp_ids_lookup(ipsecflowinfo);
524 error = ipsp_spd_lookup(m, AF_INET2, hlen, IPSP_DIRECTION_OUT0x2,
525 NULL((void *)0), seclevel, &tdb, ids);
526 ipsp_ids_free(ids);
527 if (error || tdb == NULL((void *)0)) {
528 *tdbout = NULL((void *)0);
529 return error;
530 }
531 /* Loop detection */
532 for (mtag = m_tag_first(m); mtag != NULL((void *)0); mtag = m_tag_next(m, mtag)) {
533 if (mtag->m_tag_id != PACKET_TAG_IPSEC_OUT_DONE0x0002)
534 continue;
535 tdbi = (struct tdb_ident *)(mtag + 1);
536 if (tdbi->spi == tdb->tdb_spi &&
537 tdbi->proto == tdb->tdb_sproto &&
538 tdbi->rdomain == tdb->tdb_rdomain &&
539 !memcmp(&tdbi->dst, &tdb->tdb_dst,__builtin_memcmp((&tdbi->dst), (&tdb->tdb_dst),
(sizeof(union sockaddr_union)))
540 sizeof(union sockaddr_union))__builtin_memcmp((&tdbi->dst), (&tdb->tdb_dst),
(sizeof(union sockaddr_union)))
) {
541 /* no IPsec needed */
542 tdb_unref(tdb);
543 *tdbout = NULL((void *)0);
544 return 0;
545 }
546 }
547 *tdbout = tdb;
548 return 0;
549}
550
551void
552ip_output_ipsec_pmtu_update(struct tdb *tdb, struct route *ro,
553 struct in_addr dst, int rtableid, int transportmode)
554{
555 struct rtentry *rt = NULL((void *)0);
556 int rt_mtucloned = 0;
557
558 /* Find a host route to store the mtu in */
559 if (ro != NULL((void *)0))
560 rt = ro->ro_rt;
561 /* but don't add a PMTU route for transport mode SAs */
562 if (transportmode)
563 rt = NULL((void *)0);
564 else if (rt == NULL((void *)0) || (rt->rt_flags & RTF_HOST0x4) == 0) {
565 rt = icmp_mtudisc_clone(dst, rtableid, 1);
566 rt_mtucloned = 1;
567 }
568 DPRINTF("spi %08x mtu %d rt %p cloned %d",do { } while (0)
569 ntohl(tdb->tdb_spi), tdb->tdb_mtu, rt, rt_mtucloned)do { } while (0);
570 if (rt != NULL((void *)0)) {
571 rt->rt_mturt_rmx.rmx_mtu = tdb->tdb_mtu;
572 if (ro != NULL((void *)0) && ro->ro_rt != NULL((void *)0)) {
573 rtfree(ro->ro_rt);
574 ro->ro_rt = rtalloc(&ro->ro_dst, RT_RESOLVE1, rtableid);
575 }
576 if (rt_mtucloned)
577 rtfree(rt);
578 }
579}
580
581int
582ip_output_ipsec_send(struct tdb *tdb, struct mbuf *m, struct route *ro, int fwd)
583{
584 struct mbuf_list ml;
585 struct ifnet *encif = NULL((void *)0);
586 struct ip *ip;
587 struct in_addr dst;
588 u_int len;
589 int error, rtableid, tso = 0;
49
'error' declared without an initial value
590
591#if NPF1 > 0
592 /*
593 * Packet filter
594 */
595 if ((encif = enc_getif(tdb->tdb_rdomain, tdb->tdb_tap)) == NULL((void *)0) ||
50
Assuming the condition is false
53
Taking false branch
596 pf_test(AF_INET2, fwd
50.1
'fwd' is 0
? PF_FWD : PF_OUT, encif, &m) != PF_PASS
) {
51
'?' condition is false
52
Assuming the condition is false
597 m_freem(m);
598 return EACCES13;
599 }
600 if (m == NULL((void *)0))
54
Assuming 'm' is not equal to NULL
55
Taking false branch
601 return 0;
602 /*
603 * PF_TAG_REROUTE handling or not...
604 * Packet is entering IPsec so the routing is
605 * already overruled by the IPsec policy.
606 * Until now the change was not reconsidered.
607 * What's the behaviour?
608 */
609#endif
610
611 /* Check if we can chop the TCP packet */
612 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
613 if (ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO)((m->M_dat.MH.MH_pkthdr.csum_flags) & (0x8000)) &&
56
Assuming the condition is false
614 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_mss <= tdb->tdb_mtu) {
615 tso = 1;
616 len = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_mss;
617 } else
618 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))
;
57
'?' condition is false
619
620 /* Check if we are allowed to fragment */
621 dst = ip->ip_dst;
622 rtableid = m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid;
623 if (ip_mtudisc && (ip->ip_off & htons(IP_DF)(__uint16_t)(__builtin_constant_p(0x4000) ? (__uint16_t)(((__uint16_t
)(0x4000) & 0xffU) << 8 | ((__uint16_t)(0x4000) &
0xff00U) >> 8) : __swap16md(0x4000))
) && tdb->tdb_mtu &&
58
Assuming 'ip_mtudisc' is 0
624 len > tdb->tdb_mtu && tdb->tdb_mtutimeout > gettime()) {
625 int transportmode;
626
627 transportmode = (tdb->tdb_dst.sa.sa_family == AF_INET2) &&
628 (tdb->tdb_dst.sin.sin_addr.s_addr == dst.s_addr);
629 ip_output_ipsec_pmtu_update(tdb, ro, dst, rtableid,
630 transportmode);
631 ipsec_adjust_mtu(m, tdb->tdb_mtu);
632 m_freem(m);
633 return EMSGSIZE40;
634 }
635 /* propagate IP_DF for v4-over-v6 */
636 if (ip_mtudisc
58.1
'ip_mtudisc' is 0
&& ip->ip_off & htons(IP_DF)(__uint16_t)(__builtin_constant_p(0x4000) ? (__uint16_t)(((__uint16_t
)(0x4000) & 0xffU) << 8 | ((__uint16_t)(0x4000) &
0xff00U) >> 8) : __swap16md(0x4000))
)
637 SET(m->m_pkthdr.csum_flags, M_IPV6_DF_OUT)((m->M_dat.MH.MH_pkthdr.csum_flags) |= (0x1000));
638
639 /*
640 * Clear these -- they'll be set in the recursive invocation
641 * as needed.
642 */
643 m->m_flagsm_hdr.mh_flags &= ~(M_MCAST0x0200 | M_BCAST0x0100);
644
645 if (tso
58.2
'tso' is 0
) {
59
Taking false branch
646 error = tcp_chopper(m, &ml, encif, len);
647 if (error)
648 goto done;
649 } else {
650 CLR(m->m_pkthdr.csum_flags, M_TCP_TSO)((m->M_dat.MH.MH_pkthdr.csum_flags) &= ~(0x8000));
651 in_proto_cksum_out(m, encif);
652 ml_init(&ml);
653 ml_enqueue(&ml, m);
654 }
655
656 KERNEL_LOCK()_kernel_lock();
657 while ((m = ml_dequeue(&ml)) != NULL((void *)0)) {
60
Assuming the condition is false
61
Loop condition is false. Execution continues on line 663
658 /* Callee frees mbuf */
659 error = ipsp_process_packet(m, tdb, AF_INET2, 0);
660 if (error)
661 break;
662 }
663 KERNEL_UNLOCK()_kernel_unlock();
664 done:
665 if (error) {
62
Branch condition evaluates to a garbage value
666 ml_purge(&ml);
667 ipsecstat_inc(ipsec_odrops);
668 tdbstat_inc(tdb, tdb_odrops);
669 }
670 if (!error && tso)
671 tcpstat_inc(tcps_outswtso);
672 if (ip_mtudisc && error == EMSGSIZE40)
673 ip_output_ipsec_pmtu_update(tdb, ro, dst, rtableid, 0);
674 return error;
675}
676#endif /* IPSEC */
677
678int
679ip_fragment(struct mbuf *m0, struct mbuf_list *ml, struct ifnet *ifp,
680 u_long mtu)
681{
682 struct ip *ip;
683 int firstlen, hlen, tlen, len, off;
684 int error;
685
686 ml_init(ml);
687 ml_enqueue(ml, m0);
688
689 ip = mtod(m0, struct ip *)((struct ip *)((m0)->m_hdr.mh_data));
690 hlen = ip->ip_hl << 2;
691 tlen = m0->m_pkthdrM_dat.MH.MH_pkthdr.len;
692 len = (mtu - hlen) &~ 7;
693 if (len < 8) {
694 error = EMSGSIZE40;
695 goto bad;
696 }
697 firstlen = len;
698
699 /*
700 * If we are doing fragmentation, we can't defer TCP/UDP
701 * checksumming; compute the checksum and clear the flag.
702 */
703 in_proto_cksum_out(m0, NULL((void *)0));
704
705 /*
706 * Loop through length of payload after first fragment,
707 * make new header and copy data of each part and link onto chain.
708 */
709 for (off = hlen + firstlen; off < tlen; off += len) {
710 struct mbuf *m;
711 struct ip *mhip;
712 int mhlen;
713
714 MGETHDR(m, M_DONTWAIT, MT_HEADER)m = m_gethdr((0x0002), (2));
715 if (m == NULL((void *)0)) {
716 error = ENOBUFS55;
717 goto bad;
718 }
719 ml_enqueue(ml, m);
720 if ((error = m_dup_pkthdr(m, m0, M_DONTWAIT0x0002)) != 0)
721 goto bad;
722 m->m_datam_hdr.mh_data += max_linkhdr;
723 mhip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
724 *mhip = *ip;
725 if (hlen > sizeof(struct ip)) {
726 mhlen = ip_optcopy(ip, mhip) + sizeof(struct ip);
727 mhip->ip_hl = mhlen >> 2;
728 } else
729 mhlen = sizeof(struct ip);
730 m->m_lenm_hdr.mh_len = mhlen;
731
732 mhip->ip_off = ((off - hlen) >> 3) +
733 (ntohs(ip->ip_off)(__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))
& ~IP_MF0x2000);
734 if (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))
)
735 mhip->ip_off |= IP_MF0x2000;
736 if (off + len >= tlen)
737 len = tlen - off;
738 else
739 mhip->ip_off |= IP_MF0x2000;
740 mhip->ip_off = htons(mhip->ip_off)(__uint16_t)(__builtin_constant_p(mhip->ip_off) ? (__uint16_t
)(((__uint16_t)(mhip->ip_off) & 0xffU) << 8 | ((
__uint16_t)(mhip->ip_off) & 0xff00U) >> 8) : __swap16md
(mhip->ip_off))
;
741
742 m->m_pkthdrM_dat.MH.MH_pkthdr.len = mhlen + len;
743 mhip->ip_len = htons(m->m_pkthdr.len)(__uint16_t)(__builtin_constant_p(m->M_dat.MH.MH_pkthdr.len
) ? (__uint16_t)(((__uint16_t)(m->M_dat.MH.MH_pkthdr.len) &
0xffU) << 8 | ((__uint16_t)(m->M_dat.MH.MH_pkthdr.len
) & 0xff00U) >> 8) : __swap16md(m->M_dat.MH.MH_pkthdr
.len))
;
744 m->m_nextm_hdr.mh_next = m_copym(m0, off, len, M_NOWAIT0x0002);
745 if (m->m_nextm_hdr.mh_next == NULL((void *)0)) {
746 error = ENOBUFS55;
747 goto bad;
748 }
749
750 in_hdr_cksum_out(m, ifp);
751 }
752
753 /*
754 * Update first fragment by trimming what's been copied out
755 * and updating header, then send each fragment (in order).
756 */
757 if (hlen + firstlen < tlen) {
758 m_adj(m0, hlen + firstlen - tlen);
759 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))
;
760 }
761 ip->ip_len = htons(m0->m_pkthdr.len)(__uint16_t)(__builtin_constant_p(m0->M_dat.MH.MH_pkthdr.len
) ? (__uint16_t)(((__uint16_t)(m0->M_dat.MH.MH_pkthdr.len)
& 0xffU) << 8 | ((__uint16_t)(m0->M_dat.MH.MH_pkthdr
.len) & 0xff00U) >> 8) : __swap16md(m0->M_dat.MH
.MH_pkthdr.len))
;
762
763 in_hdr_cksum_out(m0, ifp);
764
765 ipstat_add(ips_ofragments, ml_len(ml)((ml)->ml_len));
766 return (0);
767
768bad:
769 ipstat_inc(ips_odropped);
770 ml_purge(ml);
771 return (error);
772}
773
774/*
775 * Insert IP options into preformed packet.
776 * Adjust IP destination as required for IP source routing,
777 * as indicated by a non-zero in_addr at the start of the options.
778 */
779struct mbuf *
780ip_insertoptions(struct mbuf *m, struct mbuf *opt, int *phlen)
781{
782 struct ipoption *p = mtod(opt, struct ipoption *)((struct ipoption *)((opt)->m_hdr.mh_data));
783 struct mbuf *n;
784 struct ip *ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
785 unsigned int optlen;
786
787 optlen = opt->m_lenm_hdr.mh_len - sizeof(p->ipopt_dst);
788 if (optlen + 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))
> IP_MAXPACKET65535)
789 return (m); /* XXX should fail */
790
791 /* check if options will fit to IP header */
792 if ((optlen + sizeof(struct ip)) > (0x0f << 2)) {
793 *phlen = sizeof(struct ip);
794 return (m);
795 }
796
797 if (p->ipopt_dst.s_addr)
798 ip->ip_dst = p->ipopt_dst;
799 if (m->m_flagsm_hdr.mh_flags & M_EXT0x0001 || m->m_datam_hdr.mh_data - optlen < m->m_pktdatM_dat.MH.MH_dat.MH_databuf) {
800 MGETHDR(n, M_DONTWAIT, MT_HEADER)n = m_gethdr((0x0002), (2));
801 if (n == NULL((void *)0))
802 return (m);
803 M_MOVE_HDR(n, m)do { (n)->M_dat.MH.MH_pkthdr = (m)->M_dat.MH.MH_pkthdr;
(m)->m_hdr.mh_flags &= ~0x0002; { ((&(m)->M_dat
.MH.MH_pkthdr.ph_tags)->slh_first) = ((void *)0); }; (m)->
M_dat.MH.MH_pkthdr.pf.statekey = ((void *)0); } while ( 0)
;
804 n->m_pkthdrM_dat.MH.MH_pkthdr.len += optlen;
805 m->m_lenm_hdr.mh_len -= sizeof(struct ip);
806 m->m_datam_hdr.mh_data += sizeof(struct ip);
807 n->m_nextm_hdr.mh_next = m;
808 m = n;
809 m->m_lenm_hdr.mh_len = optlen + sizeof(struct ip);
810 m->m_datam_hdr.mh_data += max_linkhdr;
811 memcpy(mtod(m, caddr_t), ip, sizeof(struct ip))__builtin_memcpy((((caddr_t)((m)->m_hdr.mh_data))), (ip), (
sizeof(struct ip)))
;
812 } else {
813 m->m_datam_hdr.mh_data -= optlen;
814 m->m_lenm_hdr.mh_len += optlen;
815 m->m_pkthdrM_dat.MH.MH_pkthdr.len += optlen;
816 memmove(mtod(m, caddr_t), (caddr_t)ip, sizeof(struct ip))__builtin_memmove((((caddr_t)((m)->m_hdr.mh_data))), ((caddr_t
)ip), (sizeof(struct ip)))
;
817 }
818 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
819 memcpy(ip + 1, p->ipopt_list, optlen)__builtin_memcpy((ip + 1), (p->ipopt_list), (optlen));
820 *phlen = sizeof(struct ip) + optlen;
821 ip->ip_len = htons(ntohs(ip->ip_len) + optlen)(__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)) + optlen) ? (__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)) + optlen) & 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)) + optlen) & 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)) + optlen))
;
822 return (m);
823}
824
825/*
826 * Copy options from ip to jp,
827 * omitting those not copied during fragmentation.
828 */
829int
830ip_optcopy(struct ip *ip, struct ip *jp)
831{
832 u_char *cp, *dp;
833 int opt, optlen, cnt;
834
835 cp = (u_char *)(ip + 1);
836 dp = (u_char *)(jp + 1);
837 cnt = (ip->ip_hl << 2) - sizeof (struct ip);
838 for (; cnt > 0; cnt -= optlen, cp += optlen) {
839 opt = cp[0];
840 if (opt == IPOPT_EOL0)
841 break;
842 if (opt == IPOPT_NOP1) {
843 /* Preserve for IP mcast tunnel's LSRR alignment. */
844 *dp++ = IPOPT_NOP1;
845 optlen = 1;
846 continue;
847 }
848#ifdef DIAGNOSTIC1
849 if (cnt < IPOPT_OLEN1 + sizeof(*cp))
850 panic("malformed IPv4 option passed to ip_optcopy");
851#endif
852 optlen = cp[IPOPT_OLEN1];
853#ifdef DIAGNOSTIC1
854 if (optlen < IPOPT_OLEN1 + sizeof(*cp) || optlen > cnt)
855 panic("malformed IPv4 option passed to ip_optcopy");
856#endif
857 /* bogus lengths should have been caught by ip_dooptions */
858 if (optlen > cnt)
859 optlen = cnt;
860 if (IPOPT_COPIED(opt)((opt)&0x80)) {
861 memcpy(dp, cp, optlen)__builtin_memcpy((dp), (cp), (optlen));
862 dp += optlen;
863 }
864 }
865 for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++)
866 *dp++ = IPOPT_EOL0;
867 return (optlen);
868}
869
870/*
871 * IP socket option processing.
872 */
873int
874ip_ctloutput(int op, struct socket *so, int level, int optname,
875 struct mbuf *m)
876{
877 struct inpcb *inp = sotoinpcb(so)((struct inpcb *)(so)->so_pcb);
878 int optval = 0;
879 struct proc *p = curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc
; /* XXX */
880 int error = 0;
881 u_int rtableid, rtid = 0;
882
883 if (level != IPPROTO_IP0)
884 return (EINVAL22);
885
886 rtableid = p->p_p->ps_rtableid;
887
888 switch (op) {
889 case PRCO_SETOPT1:
890 switch (optname) {
891 case IP_OPTIONS1:
892 return (ip_pcbopts(&inp->inp_options, m));
893
894 case IP_TOS3:
895 case IP_TTL4:
896 case IP_MINTTL32:
897 case IP_RECVOPTS5:
898 case IP_RECVRETOPTS6:
899 case IP_RECVDSTADDR7:
900 case IP_RECVIF30:
901 case IP_RECVTTL31:
902 case IP_RECVDSTPORT33:
903 case IP_RECVRTABLE35:
904 case IP_IPSECFLOWINFO36:
905 if (m == NULL((void *)0) || m->m_lenm_hdr.mh_len != sizeof(int))
906 error = EINVAL22;
907 else {
908 optval = *mtod(m, int *)((int *)((m)->m_hdr.mh_data));
909 switch (optname) {
910
911 case IP_TOS3:
912 inp->inp_ipinp_hu.hu_ip.ip_tos = optval;
913 break;
914
915 case IP_TTL4:
916 if (optval > 0 && optval <= MAXTTL255)
917 inp->inp_ipinp_hu.hu_ip.ip_ttl = optval;
918 else if (optval == -1)
919 inp->inp_ipinp_hu.hu_ip.ip_ttl = ip_defttl;
920 else
921 error = EINVAL22;
922 break;
923
924 case IP_MINTTL32:
925 if (optval >= 0 && optval <= MAXTTL255)
926 inp->inp_ip_minttl = optval;
927 else
928 error = EINVAL22;
929 break;
930#define OPTSET(bit) \
931 if (optval) \
932 inp->inp_flags |= bit; \
933 else \
934 inp->inp_flags &= ~bit;
935
936 case IP_RECVOPTS5:
937 OPTSET(INP_RECVOPTS0x001);
938 break;
939
940 case IP_RECVRETOPTS6:
941 OPTSET(INP_RECVRETOPTS0x002);
942 break;
943
944 case IP_RECVDSTADDR7:
945 OPTSET(INP_RECVDSTADDR0x004);
946 break;
947 case IP_RECVIF30:
948 OPTSET(INP_RECVIF0x080);
949 break;
950 case IP_RECVTTL31:
951 OPTSET(INP_RECVTTL0x040);
952 break;
953 case IP_RECVDSTPORT33:
954 OPTSET(INP_RECVDSTPORT0x200);
955 break;
956 case IP_RECVRTABLE35:
957 OPTSET(INP_RECVRTABLE0x400);
958 break;
959 case IP_IPSECFLOWINFO36:
960 OPTSET(INP_IPSECFLOWINFO0x800);
961 break;
962 }
963 }
964 break;
965#undef OPTSET
966
967 case IP_MULTICAST_IF9:
968 case IP_MULTICAST_TTL10:
969 case IP_MULTICAST_LOOP11:
970 case IP_ADD_MEMBERSHIP12:
971 case IP_DROP_MEMBERSHIP13:
972 error = ip_setmoptions(optname, &inp->inp_moptionsinp_mou.mou_mo, m,
973 inp->inp_rtableid);
974 break;
975
976 case IP_PORTRANGE19:
977 if (m == NULL((void *)0) || m->m_lenm_hdr.mh_len != sizeof(int))
978 error = EINVAL22;
979 else {
980 optval = *mtod(m, int *)((int *)((m)->m_hdr.mh_data));
981
982 switch (optval) {
983
984 case IP_PORTRANGE_DEFAULT0:
985 inp->inp_flags &= ~(INP_LOWPORT0x020);
986 inp->inp_flags &= ~(INP_HIGHPORT0x010);
987 break;
988
989 case IP_PORTRANGE_HIGH1:
990 inp->inp_flags &= ~(INP_LOWPORT0x020);
991 inp->inp_flags |= INP_HIGHPORT0x010;
992 break;
993
994 case IP_PORTRANGE_LOW2:
995 inp->inp_flags &= ~(INP_HIGHPORT0x010);
996 inp->inp_flags |= INP_LOWPORT0x020;
997 break;
998
999 default:
1000
1001 error = EINVAL22;
1002 break;
1003 }
1004 }
1005 break;
1006 case IP_AUTH_LEVEL20:
1007 case IP_ESP_TRANS_LEVEL21:
1008 case IP_ESP_NETWORK_LEVEL22:
1009 case IP_IPCOMP_LEVEL29:
1010#ifndef IPSEC1
1011 error = EOPNOTSUPP45;
1012#else
1013 if (m == NULL((void *)0) || m->m_lenm_hdr.mh_len != sizeof(int)) {
1014 error = EINVAL22;
1015 break;
1016 }
1017 optval = *mtod(m, int *)((int *)((m)->m_hdr.mh_data));
1018
1019 if (optval < IPSEC_LEVEL_BYPASS0x00 ||
1020 optval > IPSEC_LEVEL_UNIQUE0x04) {
1021 error = EINVAL22;
1022 break;
1023 }
1024
1025 switch (optname) {
1026 case IP_AUTH_LEVEL20:
1027 if (optval < IPSEC_AUTH_LEVEL_DEFAULT0x01 &&
1028 suser(p)) {
1029 error = EACCES13;
1030 break;
1031 }
1032 inp->inp_seclevel[SL_AUTH0] = optval;
1033 break;
1034
1035 case IP_ESP_TRANS_LEVEL21:
1036 if (optval < IPSEC_ESP_TRANS_LEVEL_DEFAULT0x01 &&
1037 suser(p)) {
1038 error = EACCES13;
1039 break;
1040 }
1041 inp->inp_seclevel[SL_ESP_TRANS1] = optval;
1042 break;
1043
1044 case IP_ESP_NETWORK_LEVEL22:
1045 if (optval < IPSEC_ESP_NETWORK_LEVEL_DEFAULT0x01 &&
1046 suser(p)) {
1047 error = EACCES13;
1048 break;
1049 }
1050 inp->inp_seclevel[SL_ESP_NETWORK2] = optval;
1051 break;
1052 case IP_IPCOMP_LEVEL29:
1053 if (optval < IPSEC_IPCOMP_LEVEL_DEFAULT0x01 &&
1054 suser(p)) {
1055 error = EACCES13;
1056 break;
1057 }
1058 inp->inp_seclevel[SL_IPCOMP3] = optval;
1059 break;
1060 }
1061#endif
1062 break;
1063
1064 case IP_IPSEC_LOCAL_ID23:
1065 case IP_IPSEC_REMOTE_ID24:
1066 error = EOPNOTSUPP45;
1067 break;
1068 case SO_RTABLE0x1021:
1069 if (m == NULL((void *)0) || m->m_lenm_hdr.mh_len < sizeof(u_int)) {
1070 error = EINVAL22;
1071 break;
1072 }
1073 rtid = *mtod(m, u_int *)((u_int *)((m)->m_hdr.mh_data));
1074 if (inp->inp_rtableid == rtid)
1075 break;
1076 /* needs privileges to switch when already set */
1077 if (rtableid != rtid && rtableid != 0 &&
1078 (error = suser(p)) != 0)
1079 break;
1080 /* table must exist */
1081 if (!rtable_exists(rtid)) {
1082 error = EINVAL22;
1083 break;
1084 }
1085 error = in_pcbset_rtableid(inp, rtid);
1086 break;
1087 case IP_PIPEX34:
1088 if (m != NULL((void *)0) && m->m_lenm_hdr.mh_len == sizeof(int))
1089 inp->inp_pipex = *mtod(m, int *)((int *)((m)->m_hdr.mh_data));
1090 else
1091 error = EINVAL22;
1092 break;
1093
1094 default:
1095 error = ENOPROTOOPT42;
1096 break;
1097 }
1098 break;
1099
1100 case PRCO_GETOPT0:
1101 switch (optname) {
1102 case IP_OPTIONS1:
1103 case IP_RETOPTS8:
1104 if (inp->inp_options) {
1105 m->m_lenm_hdr.mh_len = inp->inp_options->m_lenm_hdr.mh_len;
1106 memcpy(mtod(m, caddr_t),__builtin_memcpy((((caddr_t)((m)->m_hdr.mh_data))), (((caddr_t
)((inp->inp_options)->m_hdr.mh_data))), (m->m_hdr.mh_len
))
1107 mtod(inp->inp_options, caddr_t), m->m_len)__builtin_memcpy((((caddr_t)((m)->m_hdr.mh_data))), (((caddr_t
)((inp->inp_options)->m_hdr.mh_data))), (m->m_hdr.mh_len
))
;
1108 } else
1109 m->m_lenm_hdr.mh_len = 0;
1110 break;
1111
1112 case IP_TOS3:
1113 case IP_TTL4:
1114 case IP_MINTTL32:
1115 case IP_RECVOPTS5:
1116 case IP_RECVRETOPTS6:
1117 case IP_RECVDSTADDR7:
1118 case IP_RECVIF30:
1119 case IP_RECVTTL31:
1120 case IP_RECVDSTPORT33:
1121 case IP_RECVRTABLE35:
1122 case IP_IPSECFLOWINFO36:
1123 case IP_IPDEFTTL37:
1124 m->m_lenm_hdr.mh_len = sizeof(int);
1125 switch (optname) {
1126
1127 case IP_TOS3:
1128 optval = inp->inp_ipinp_hu.hu_ip.ip_tos;
1129 break;
1130
1131 case IP_TTL4:
1132 optval = inp->inp_ipinp_hu.hu_ip.ip_ttl;
1133 break;
1134
1135 case IP_MINTTL32:
1136 optval = inp->inp_ip_minttl;
1137 break;
1138
1139 case IP_IPDEFTTL37:
1140 optval = ip_defttl;
1141 break;
1142
1143#define OPTBIT(bit)(inp->inp_flags & bit ? 1 : 0) (inp->inp_flags & bit ? 1 : 0)
1144
1145 case IP_RECVOPTS5:
1146 optval = OPTBIT(INP_RECVOPTS)(inp->inp_flags & 0x001 ? 1 : 0);
1147 break;
1148
1149 case IP_RECVRETOPTS6:
1150 optval = OPTBIT(INP_RECVRETOPTS)(inp->inp_flags & 0x002 ? 1 : 0);
1151 break;
1152
1153 case IP_RECVDSTADDR7:
1154 optval = OPTBIT(INP_RECVDSTADDR)(inp->inp_flags & 0x004 ? 1 : 0);
1155 break;
1156 case IP_RECVIF30:
1157 optval = OPTBIT(INP_RECVIF)(inp->inp_flags & 0x080 ? 1 : 0);
1158 break;
1159 case IP_RECVTTL31:
1160 optval = OPTBIT(INP_RECVTTL)(inp->inp_flags & 0x040 ? 1 : 0);
1161 break;
1162 case IP_RECVDSTPORT33:
1163 optval = OPTBIT(INP_RECVDSTPORT)(inp->inp_flags & 0x200 ? 1 : 0);
1164 break;
1165 case IP_RECVRTABLE35:
1166 optval = OPTBIT(INP_RECVRTABLE)(inp->inp_flags & 0x400 ? 1 : 0);
1167 break;
1168 case IP_IPSECFLOWINFO36:
1169 optval = OPTBIT(INP_IPSECFLOWINFO)(inp->inp_flags & 0x800 ? 1 : 0);
1170 break;
1171 }
1172 *mtod(m, int *)((int *)((m)->m_hdr.mh_data)) = optval;
1173 break;
1174
1175 case IP_MULTICAST_IF9:
1176 case IP_MULTICAST_TTL10:
1177 case IP_MULTICAST_LOOP11:
1178 case IP_ADD_MEMBERSHIP12:
1179 case IP_DROP_MEMBERSHIP13:
1180 error = ip_getmoptions(optname, inp->inp_moptionsinp_mou.mou_mo, m);
1181 break;
1182
1183 case IP_PORTRANGE19:
1184 m->m_lenm_hdr.mh_len = sizeof(int);
1185
1186 if (inp->inp_flags & INP_HIGHPORT0x010)
1187 optval = IP_PORTRANGE_HIGH1;
1188 else if (inp->inp_flags & INP_LOWPORT0x020)
1189 optval = IP_PORTRANGE_LOW2;
1190 else
1191 optval = 0;
1192
1193 *mtod(m, int *)((int *)((m)->m_hdr.mh_data)) = optval;
1194 break;
1195
1196 case IP_AUTH_LEVEL20:
1197 case IP_ESP_TRANS_LEVEL21:
1198 case IP_ESP_NETWORK_LEVEL22:
1199 case IP_IPCOMP_LEVEL29:
1200#ifndef IPSEC1
1201 m->m_lenm_hdr.mh_len = sizeof(int);
1202 *mtod(m, int *)((int *)((m)->m_hdr.mh_data)) = IPSEC_LEVEL_NONE0x00;
1203#else
1204 m->m_lenm_hdr.mh_len = sizeof(int);
1205 switch (optname) {
1206 case IP_AUTH_LEVEL20:
1207 optval = inp->inp_seclevel[SL_AUTH0];
1208 break;
1209
1210 case IP_ESP_TRANS_LEVEL21:
1211 optval = inp->inp_seclevel[SL_ESP_TRANS1];
1212 break;
1213
1214 case IP_ESP_NETWORK_LEVEL22:
1215 optval = inp->inp_seclevel[SL_ESP_NETWORK2];
1216 break;
1217 case IP_IPCOMP_LEVEL29:
1218 optval = inp->inp_seclevel[SL_IPCOMP3];
1219 break;
1220 }
1221 *mtod(m, int *)((int *)((m)->m_hdr.mh_data)) = optval;
1222#endif
1223 break;
1224 case IP_IPSEC_LOCAL_ID23:
1225 case IP_IPSEC_REMOTE_ID24:
1226 error = EOPNOTSUPP45;
1227 break;
1228 case SO_RTABLE0x1021:
1229 m->m_lenm_hdr.mh_len = sizeof(u_int);
1230 *mtod(m, u_int *)((u_int *)((m)->m_hdr.mh_data)) = inp->inp_rtableid;
1231 break;
1232 case IP_PIPEX34:
1233 m->m_lenm_hdr.mh_len = sizeof(int);
1234 *mtod(m, int *)((int *)((m)->m_hdr.mh_data)) = inp->inp_pipex;
1235 break;
1236 default:
1237 error = ENOPROTOOPT42;
1238 break;
1239 }
1240 break;
1241 }
1242 return (error);
1243}
1244
1245/*
1246 * Set up IP options in pcb for insertion in output packets.
1247 * Store in mbuf with pointer in pcbopt, adding pseudo-option
1248 * with destination address if source routed.
1249 */
1250int
1251ip_pcbopts(struct mbuf **pcbopt, struct mbuf *m)
1252{
1253 struct mbuf *n;
1254 struct ipoption *p;
1255 int cnt, off, optlen;
1256 u_char *cp;
1257 u_char opt;
1258
1259 /* turn off any old options */
1260 m_freem(*pcbopt);
1261 *pcbopt = NULL((void *)0);
1262 if (m == NULL((void *)0) || m->m_lenm_hdr.mh_len == 0) {
1263 /*
1264 * Only turning off any previous options.
1265 */
1266 return (0);
1267 }
1268
1269 if (m->m_lenm_hdr.mh_len % sizeof(int32_t) ||
1270 m->m_lenm_hdr.mh_len > MAX_IPOPTLEN40 + sizeof(struct in_addr))
1271 return (EINVAL22);
1272
1273 /* Don't sleep because NET_LOCK() is hold. */
1274 if ((n = m_get(M_NOWAIT0x0002, MT_SOOPTS4)) == NULL((void *)0))
1275 return (ENOBUFS55);
1276 p = mtod(n, struct ipoption *)((struct ipoption *)((n)->m_hdr.mh_data));
1277 memset(p, 0, sizeof (*p))__builtin_memset((p), (0), (sizeof (*p))); /* 0 = IPOPT_EOL, needed for padding */
1278 n->m_lenm_hdr.mh_len = sizeof(struct in_addr);
1279
1280 off = 0;
1281 cnt = m->m_lenm_hdr.mh_len;
1282 cp = mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data));
1283
1284 while (cnt > 0) {
1285 opt = cp[IPOPT_OPTVAL0];
1286
1287 if (opt == IPOPT_NOP1 || opt == IPOPT_EOL0) {
1288 optlen = 1;
1289 } else {
1290 if (cnt < IPOPT_OLEN1 + sizeof(*cp))
1291 goto bad;
1292 optlen = cp[IPOPT_OLEN1];
1293 if (optlen < IPOPT_OLEN1 + sizeof(*cp) || optlen > cnt)
1294 goto bad;
1295 }
1296 switch (opt) {
1297 default:
1298 memcpy(p->ipopt_list + off, cp, optlen)__builtin_memcpy((p->ipopt_list + off), (cp), (optlen));
1299 break;
1300
1301 case IPOPT_LSRR131:
1302 case IPOPT_SSRR137:
1303 /*
1304 * user process specifies route as:
1305 * ->A->B->C->D
1306 * D must be our final destination (but we can't
1307 * check that since we may not have connected yet).
1308 * A is first hop destination, which doesn't appear in
1309 * actual IP option, but is stored before the options.
1310 */
1311 if (optlen < IPOPT_MINOFF4 - 1 + sizeof(struct in_addr))
1312 goto bad;
1313
1314 /*
1315 * Optlen is smaller because first address is popped.
1316 * Cnt and cp will be adjusted a bit later to reflect
1317 * this.
1318 */
1319 optlen -= sizeof(struct in_addr);
1320 p->ipopt_list[off + IPOPT_OPTVAL0] = opt;
1321 p->ipopt_list[off + IPOPT_OLEN1] = optlen;
1322
1323 /*
1324 * Move first hop before start of options.
1325 */
1326 memcpy(&p->ipopt_dst, cp + IPOPT_OFFSET,__builtin_memcpy((&p->ipopt_dst), (cp + 2), (sizeof(struct
in_addr)))
1327 sizeof(struct in_addr))__builtin_memcpy((&p->ipopt_dst), (cp + 2), (sizeof(struct
in_addr)))
;
1328 cp += sizeof(struct in_addr);
1329 cnt -= sizeof(struct in_addr);
1330 /*
1331 * Then copy rest of options
1332 */
1333 memcpy(p->ipopt_list + off + IPOPT_OFFSET,__builtin_memcpy((p->ipopt_list + off + 2), (cp + 2), (optlen
- 2))
1334 cp + IPOPT_OFFSET, optlen - IPOPT_OFFSET)__builtin_memcpy((p->ipopt_list + off + 2), (cp + 2), (optlen
- 2))
;
1335 break;
1336 }
1337 off += optlen;
1338 cp += optlen;
1339 cnt -= optlen;
1340
1341 if (opt == IPOPT_EOL0)
1342 break;
1343 }
1344 /* pad options to next word, since p was zeroed just adjust off */
1345 off = (off + sizeof(int32_t) - 1) & ~(sizeof(int32_t) - 1);
1346 n->m_lenm_hdr.mh_len += off;
1347 if (n->m_lenm_hdr.mh_len > sizeof(*p)) {
1348 bad:
1349 m_freem(n);
1350 return (EINVAL22);
1351 }
1352
1353 *pcbopt = n;
1354 return (0);
1355}
1356
1357/*
1358 * Lookup the interface based on the information in the ip_mreqn struct.
1359 */
1360int
1361ip_multicast_if(struct ip_mreqn *mreq, u_int rtableid, unsigned int *ifidx)
1362{
1363 struct sockaddr_in sin;
1364 struct rtentry *rt;
1365
1366 /*
1367 * In case userland provides the imr_ifindex use this as interface.
1368 * If no interface address was provided, use the interface of
1369 * the route to the given multicast address.
1370 */
1371 if (mreq->imr_ifindex != 0) {
1372 *ifidx = mreq->imr_ifindex;
1373 } else if (mreq->imr_address.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
))))
) {
1374 memset(&sin, 0, sizeof(sin))__builtin_memset((&sin), (0), (sizeof(sin)));
1375 sin.sin_len = sizeof(sin);
1376 sin.sin_family = AF_INET2;
1377 sin.sin_addr = mreq->imr_multiaddr;
1378 rt = rtalloc(sintosa(&sin), RT_RESOLVE1, rtableid);
1379 if (!rtisvalid(rt)) {
1380 rtfree(rt);
1381 return EADDRNOTAVAIL49;
1382 }
1383 *ifidx = rt->rt_ifidx;
1384 rtfree(rt);
1385 } else {
1386 memset(&sin, 0, sizeof(sin))__builtin_memset((&sin), (0), (sizeof(sin)));
1387 sin.sin_len = sizeof(sin);
1388 sin.sin_family = AF_INET2;
1389 sin.sin_addr = mreq->imr_address;
1390 rt = rtalloc(sintosa(&sin), 0, rtableid);
1391 if (!rtisvalid(rt) || !ISSET(rt->rt_flags, RTF_LOCAL)((rt->rt_flags) & (0x200000))) {
1392 rtfree(rt);
1393 return EADDRNOTAVAIL49;
1394 }
1395 *ifidx = rt->rt_ifidx;
1396 rtfree(rt);
1397 }
1398
1399 return 0;
1400}
1401
1402/*
1403 * Set the IP multicast options in response to user setsockopt().
1404 */
1405int
1406ip_setmoptions(int optname, struct ip_moptions **imop, struct mbuf *m,
1407 u_int rtableid)
1408{
1409 struct in_addr addr;
1410 struct in_ifaddr *ia;
1411 struct ip_mreqn mreqn;
1412 struct ifnet *ifp = NULL((void *)0);
1413 struct ip_moptions *imo = *imop;
1414 struct in_multi **immp;
1415 struct sockaddr_in sin;
1416 unsigned int ifidx;
1417 int i, error = 0;
1418 u_char loop;
1419
1420 if (imo == NULL((void *)0)) {
1421 /*
1422 * No multicast option buffer attached to the pcb;
1423 * allocate one and initialize to default values.
1424 */
1425 imo = malloc(sizeof(*imo), M_IPMOPTS53, M_WAITOK0x0001|M_ZERO0x0008);
1426 immp = mallocarray(IP_MIN_MEMBERSHIPS15, sizeof(*immp), M_IPMOPTS53,
1427 M_WAITOK0x0001|M_ZERO0x0008);
1428 *imop = imo;
1429 imo->imo_ifidx = 0;
1430 imo->imo_ttl = IP_DEFAULT_MULTICAST_TTL1;
1431 imo->imo_loop = IP_DEFAULT_MULTICAST_LOOP1;
1432 imo->imo_num_memberships = 0;
1433 imo->imo_max_memberships = IP_MIN_MEMBERSHIPS15;
1434 imo->imo_membership = immp;
1435 }
1436
1437 switch (optname) {
1438
1439 case IP_MULTICAST_IF9:
1440 /*
1441 * Select the interface for outgoing multicast packets.
1442 */
1443 if (m == NULL((void *)0)) {
1444 error = EINVAL22;
1445 break;
1446 }
1447 if (m->m_lenm_hdr.mh_len == sizeof(struct in_addr)) {
1448 addr = *(mtod(m, struct in_addr *)((struct in_addr *)((m)->m_hdr.mh_data)));
1449 } else if (m->m_lenm_hdr.mh_len == sizeof(struct ip_mreq) ||
1450 m->m_lenm_hdr.mh_len == sizeof(struct ip_mreqn)) {
1451 memset(&mreqn, 0, sizeof(mreqn))__builtin_memset((&mreqn), (0), (sizeof(mreqn)));
1452 memcpy(&mreqn, mtod(m, void *), m->m_len)__builtin_memcpy((&mreqn), (((void *)((m)->m_hdr.mh_data
))), (m->m_hdr.mh_len))
;
1453
1454 /*
1455 * If an interface index is given use this
1456 * index to set the imo_ifidx but check first
1457 * that the interface actually exists.
1458 * In the other case just set the addr to
1459 * the imr_address and fall through to the
1460 * regular code.
1461 */
1462 if (mreqn.imr_ifindex != 0) {
1463 ifp = if_get(mreqn.imr_ifindex);
1464 if (ifp == NULL((void *)0) ||
1465 ifp->if_rdomainif_data.ifi_rdomain != rtable_l2(rtableid)) {
1466 error = EADDRNOTAVAIL49;
1467 if_put(ifp);
1468 break;
1469 }
1470 imo->imo_ifidx = ifp->if_index;
1471 if_put(ifp);
1472 break;
1473 } else
1474 addr = mreqn.imr_address;
1475 } else {
1476 error = EINVAL22;
1477 break;
1478 }
1479 /*
1480 * INADDR_ANY is used to remove a previous selection.
1481 * When no interface is selected, a default one is
1482 * chosen every time a multicast packet is sent.
1483 */
1484 if (addr.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
))))
) {
1485 imo->imo_ifidx = 0;
1486 break;
1487 }
1488 /*
1489 * The selected interface is identified by its local
1490 * IP address. Find the interface and confirm that
1491 * it supports multicasting.
1492 */
1493 memset(&sin, 0, sizeof(sin))__builtin_memset((&sin), (0), (sizeof(sin)));
1494 sin.sin_len = sizeof(sin);
1495 sin.sin_family = AF_INET2;
1496 sin.sin_addr = addr;
1497 ia = ifatoia(ifa_ifwithaddr(sintosa(&sin), rtableid));
1498 if (ia == NULL((void *)0) ||
1499 (ia->ia_ifpia_ifa.ifa_ifp->if_flags & IFF_MULTICAST0x8000) == 0) {
1500 error = EADDRNOTAVAIL49;
1501 break;
1502 }
1503 imo->imo_ifidx = ia->ia_ifpia_ifa.ifa_ifp->if_index;
1504 break;
1505
1506 case IP_MULTICAST_TTL10:
1507 /*
1508 * Set the IP time-to-live for outgoing multicast packets.
1509 */
1510 if (m == NULL((void *)0) || m->m_lenm_hdr.mh_len != 1) {
1511 error = EINVAL22;
1512 break;
1513 }
1514 imo->imo_ttl = *(mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data)));
1515 break;
1516
1517 case IP_MULTICAST_LOOP11:
1518 /*
1519 * Set the loopback flag for outgoing multicast packets.
1520 * Must be zero or one.
1521 */
1522 if (m == NULL((void *)0) || m->m_lenm_hdr.mh_len != 1 ||
1523 (loop = *(mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data)))) > 1) {
1524 error = EINVAL22;
1525 break;
1526 }
1527 imo->imo_loop = loop;
1528 break;
1529
1530 case IP_ADD_MEMBERSHIP12:
1531 /*
1532 * Add a multicast group membership.
1533 * Group must be a valid IP multicast address.
1534 */
1535 if (m == NULL((void *)0) || !(m->m_lenm_hdr.mh_len == sizeof(struct ip_mreq) ||
1536 m->m_lenm_hdr.mh_len == sizeof(struct ip_mreqn))) {
1537 error = EINVAL22;
1538 break;
1539 }
1540 memset(&mreqn, 0, sizeof(mreqn))__builtin_memset((&mreqn), (0), (sizeof(mreqn)));
1541 memcpy(&mreqn, mtod(m, void *), m->m_len)__builtin_memcpy((&mreqn), (((void *)((m)->m_hdr.mh_data
))), (m->m_hdr.mh_len))
;
1542 if (!IN_MULTICAST(mreqn.imr_multiaddr.s_addr)(((u_int32_t)(mreqn.imr_multiaddr.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
)))))
) {
1543 error = EINVAL22;
1544 break;
1545 }
1546
1547 error = ip_multicast_if(&mreqn, rtableid, &ifidx);
1548 if (error)
1549 break;
1550
1551 /*
1552 * See if we found an interface, and confirm that it
1553 * supports multicast.
1554 */
1555 ifp = if_get(ifidx);
1556 if (ifp == NULL((void *)0) || ifp->if_rdomainif_data.ifi_rdomain != rtable_l2(rtableid) ||
1557 (ifp->if_flags & IFF_MULTICAST0x8000) == 0) {
1558 error = EADDRNOTAVAIL49;
1559 if_put(ifp);
1560 break;
1561 }
1562
1563 /*
1564 * See if the membership already exists or if all the
1565 * membership slots are full.
1566 */
1567 for (i = 0; i < imo->imo_num_memberships; ++i) {
1568 if (imo->imo_membership[i]->inm_ifidxinm_ifma.ifma_ifidx == ifidx &&
1569 imo->imo_membership[i]->inm_addrinm_sin.sin_addr.s_addr
1570 == mreqn.imr_multiaddr.s_addr)
1571 break;
1572 }
1573 if (i < imo->imo_num_memberships) {
1574 error = EADDRINUSE48;
1575 if_put(ifp);
1576 break;
1577 }
1578 if (imo->imo_num_memberships == imo->imo_max_memberships) {
1579 struct in_multi **nmships, **omships;
1580 size_t newmax;
1581 /*
1582 * Resize the vector to next power-of-two minus 1. If
1583 * the size would exceed the maximum then we know we've
1584 * really run out of entries. Otherwise, we reallocate
1585 * the vector.
1586 */
1587 nmships = NULL((void *)0);
1588 omships = imo->imo_membership;
1589 newmax = ((imo->imo_max_memberships + 1) * 2) - 1;
1590 if (newmax <= IP_MAX_MEMBERSHIPS4095) {
1591 nmships = mallocarray(newmax, sizeof(*nmships),
1592 M_IPMOPTS53, M_NOWAIT0x0002|M_ZERO0x0008);
1593 if (nmships != NULL((void *)0)) {
1594 memcpy(nmships, omships,__builtin_memcpy((nmships), (omships), (sizeof(*omships) * imo
->imo_max_memberships))
1595 sizeof(*omships) *__builtin_memcpy((nmships), (omships), (sizeof(*omships) * imo
->imo_max_memberships))
1596 imo->imo_max_memberships)__builtin_memcpy((nmships), (omships), (sizeof(*omships) * imo
->imo_max_memberships))
;
1597 free(omships, M_IPMOPTS53,
1598 sizeof(*omships) *
1599 imo->imo_max_memberships);
1600 imo->imo_membership = nmships;
1601 imo->imo_max_memberships = newmax;
1602 }
1603 }
1604 if (nmships == NULL((void *)0)) {
1605 error = ENOBUFS55;
1606 if_put(ifp);
1607 break;
1608 }
1609 }
1610 /*
1611 * Everything looks good; add a new record to the multicast
1612 * address list for the given interface.
1613 */
1614 if ((imo->imo_membership[i] =
1615 in_addmulti(&mreqn.imr_multiaddr, ifp)) == NULL((void *)0)) {
1616 error = ENOBUFS55;
1617 if_put(ifp);
1618 break;
1619 }
1620 ++imo->imo_num_memberships;
1621 if_put(ifp);
1622 break;
1623
1624 case IP_DROP_MEMBERSHIP13:
1625 /*
1626 * Drop a multicast group membership.
1627 * Group must be a valid IP multicast address.
1628 */
1629 if (m == NULL((void *)0) || !(m->m_lenm_hdr.mh_len == sizeof(struct ip_mreq) ||
1630 m->m_lenm_hdr.mh_len == sizeof(struct ip_mreqn))) {
1631 error = EINVAL22;
1632 break;
1633 }
1634 memset(&mreqn, 0, sizeof(mreqn))__builtin_memset((&mreqn), (0), (sizeof(mreqn)));
1635 memcpy(&mreqn, mtod(m, void *), m->m_len)__builtin_memcpy((&mreqn), (((void *)((m)->m_hdr.mh_data
))), (m->m_hdr.mh_len))
;
1636 if (!IN_MULTICAST(mreqn.imr_multiaddr.s_addr)(((u_int32_t)(mreqn.imr_multiaddr.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
)))))
) {
1637 error = EINVAL22;
1638 break;
1639 }
1640
1641 /*
1642 * If an interface address was specified, get a pointer
1643 * to its ifnet structure.
1644 */
1645 error = ip_multicast_if(&mreqn, rtableid, &ifidx);
1646 if (error)
1647 break;
1648
1649 /*
1650 * Find the membership in the membership array.
1651 */
1652 for (i = 0; i < imo->imo_num_memberships; ++i) {
1653 if ((ifidx == 0 ||
1654 imo->imo_membership[i]->inm_ifidxinm_ifma.ifma_ifidx == ifidx) &&
1655 imo->imo_membership[i]->inm_addrinm_sin.sin_addr.s_addr ==
1656 mreqn.imr_multiaddr.s_addr)
1657 break;
1658 }
1659 if (i == imo->imo_num_memberships) {
1660 error = EADDRNOTAVAIL49;
1661 break;
1662 }
1663 /*
1664 * Give up the multicast address record to which the
1665 * membership points.
1666 */
1667 in_delmulti(imo->imo_membership[i]);
1668 /*
1669 * Remove the gap in the membership array.
1670 */
1671 for (++i; i < imo->imo_num_memberships; ++i)
1672 imo->imo_membership[i-1] = imo->imo_membership[i];
1673 --imo->imo_num_memberships;
1674 break;
1675
1676 default:
1677 error = EOPNOTSUPP45;
1678 break;
1679 }
1680
1681 /*
1682 * If all options have default values, no need to keep the data.
1683 */
1684 if (imo->imo_ifidx == 0 &&
1685 imo->imo_ttl == IP_DEFAULT_MULTICAST_TTL1 &&
1686 imo->imo_loop == IP_DEFAULT_MULTICAST_LOOP1 &&
1687 imo->imo_num_memberships == 0) {
1688 free(imo->imo_membership , M_IPMOPTS53,
1689 imo->imo_max_memberships * sizeof(struct in_multi *));
1690 free(*imop, M_IPMOPTS53, sizeof(**imop));
1691 *imop = NULL((void *)0);
1692 }
1693
1694 return (error);
1695}
1696
1697/*
1698 * Return the IP multicast options in response to user getsockopt().
1699 */
1700int
1701ip_getmoptions(int optname, struct ip_moptions *imo, struct mbuf *m)
1702{
1703 u_char *ttl;
1704 u_char *loop;
1705 struct in_addr *addr;
1706 struct in_ifaddr *ia;
1707 struct ifnet *ifp;
1708
1709 switch (optname) {
1710
1711 case IP_MULTICAST_IF9:
1712 addr = mtod(m, struct in_addr *)((struct in_addr *)((m)->m_hdr.mh_data));
1713 m->m_lenm_hdr.mh_len = sizeof(struct in_addr);
1714 if (imo == NULL((void *)0) || (ifp = if_get(imo->imo_ifidx)) == NULL((void *)0))
1715 addr->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
))))
;
1716 else {
1717 IFP_TO_IA(ifp, ia)do { struct ifaddr *ifa; do { int _s = rw_status(&netlock
); if ((splassert_ctl > 0) && (_s != 0x0001UL &&
_s != 0x0002UL)) splassert_fail(0x0002UL, _s, __func__); } while
(0); for((ifa) = ((&(ifp)->if_addrlist)->tqh_first
); (ifa) != ((void *)0); (ifa) = ((ifa)->ifa_list.tqe_next
)) { if (ifa->ifa_addr->sa_family == 2) break; } (ia) =
ifatoia(ifa); } while ( 0)
;
1718 addr->s_addr = (ia == NULL((void *)0)) ? 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
))))
1719 : ia->ia_addr.sin_addr.s_addr;
1720 if_put(ifp);
1721 }
1722 return (0);
1723
1724 case IP_MULTICAST_TTL10:
1725 ttl = mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data));
1726 m->m_lenm_hdr.mh_len = 1;
1727 *ttl = (imo == NULL((void *)0)) ? IP_DEFAULT_MULTICAST_TTL1
1728 : imo->imo_ttl;
1729 return (0);
1730
1731 case IP_MULTICAST_LOOP11:
1732 loop = mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data));
1733 m->m_lenm_hdr.mh_len = 1;
1734 *loop = (imo == NULL((void *)0)) ? IP_DEFAULT_MULTICAST_LOOP1
1735 : imo->imo_loop;
1736 return (0);
1737
1738 default:
1739 return (EOPNOTSUPP45);
1740 }
1741}
1742
1743/*
1744 * Discard the IP multicast options.
1745 */
1746void
1747ip_freemoptions(struct ip_moptions *imo)
1748{
1749 int i;
1750
1751 if (imo != NULL((void *)0)) {
1752 for (i = 0; i < imo->imo_num_memberships; ++i)
1753 in_delmulti(imo->imo_membership[i]);
1754 free(imo->imo_membership, M_IPMOPTS53,
1755 imo->imo_max_memberships * sizeof(struct in_multi *));
1756 free(imo, M_IPMOPTS53, sizeof(*imo));
1757 }
1758}
1759
1760/*
1761 * Routine called from ip_output() to loop back a copy of an IP multicast
1762 * packet to the input queue of a specified interface.
1763 */
1764void
1765ip_mloopback(struct ifnet *ifp, struct mbuf *m, struct sockaddr_in *dst)
1766{
1767 struct mbuf *copym;
1768
1769 copym = m_dup_pkt(m, max_linkhdr, M_DONTWAIT0x0002);
1770 if (copym != NULL((void *)0)) {
1771 /*
1772 * We don't bother to fragment if the IP length is greater
1773 * than the interface's MTU. Can this possibly matter?
1774 */
1775 in_hdr_cksum_out(copym, NULL((void *)0));
1776 if_input_local(ifp, copym, dst->sin_family);
1777 }
1778}
1779
1780void
1781in_hdr_cksum_out(struct mbuf *m, struct ifnet *ifp)
1782{
1783 struct ip *ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
1784
1785 ip->ip_sum = 0;
1786 if (in_ifcap_cksum(m, ifp, IFCAP_CSUM_IPv40x00000001)) {
1787 SET(m->m_pkthdr.csum_flags, M_IPV4_CSUM_OUT)((m->M_dat.MH.MH_pkthdr.csum_flags) |= (0x0001));
1788 } else {
1789 ipstat_inc(ips_outswcsum);
1790 ip->ip_sum = in_cksum(m, ip->ip_hl << 2);
1791 CLR(m->m_pkthdr.csum_flags, M_IPV4_CSUM_OUT)((m->M_dat.MH.MH_pkthdr.csum_flags) &= ~(0x0001));
1792 }
1793}
1794
1795/*
1796 * Compute significant parts of the IPv4 checksum pseudo-header
1797 * for use in a delayed TCP/UDP checksum calculation.
1798 */
1799static u_int16_t
1800in_cksum_phdr(u_int32_t src, u_int32_t dst, u_int32_t lenproto)
1801{
1802 u_int32_t sum;
1803
1804 sum = lenproto +
1805 (u_int16_t)(src >> 16) +
1806 (u_int16_t)(src /*& 0xffff*/) +
1807 (u_int16_t)(dst >> 16) +
1808 (u_int16_t)(dst /*& 0xffff*/);
1809
1810 sum = (u_int16_t)(sum >> 16) + (u_int16_t)(sum /*& 0xffff*/);
1811
1812 if (sum > 0xffff)
1813 sum -= 0xffff;
1814
1815 return (sum);
1816}
1817
1818/*
1819 * Process a delayed payload checksum calculation.
1820 */
1821void
1822in_delayed_cksum(struct mbuf *m)
1823{
1824 struct ip *ip;
1825 u_int16_t csum, offset;
1826
1827 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
1828 offset = ip->ip_hl << 2;
1829 csum = in4_cksum(m, 0, offset, m->m_pkthdrM_dat.MH.MH_pkthdr.len - offset);
1830 if (csum == 0 && ip->ip_p == IPPROTO_UDP17)
1831 csum = 0xffff;
1832
1833 switch (ip->ip_p) {
1834 case IPPROTO_TCP6:
1835 offset += offsetof(struct tcphdr, th_sum)__builtin_offsetof(struct tcphdr, th_sum);
1836 break;
1837
1838 case IPPROTO_UDP17:
1839 offset += offsetof(struct udphdr, uh_sum)__builtin_offsetof(struct udphdr, uh_sum);
1840 break;
1841
1842 case IPPROTO_ICMP1:
1843 offset += offsetof(struct icmp, icmp_cksum)__builtin_offsetof(struct icmp, icmp_cksum);
1844 break;
1845
1846 default:
1847 return;
1848 }
1849
1850 if ((offset + sizeof(u_int16_t)) > m->m_lenm_hdr.mh_len)
1851 m_copyback(m, offset, sizeof(csum), &csum, M_NOWAIT0x0002);
1852 else
1853 *(u_int16_t *)(mtod(m, caddr_t)((caddr_t)((m)->m_hdr.mh_data)) + offset) = csum;
1854}
1855
1856void
1857in_proto_cksum_out(struct mbuf *m, struct ifnet *ifp)
1858{
1859 struct ip *ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
1860
1861 /* some hw and in_delayed_cksum need the pseudo header cksum */
1862 if (m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags &
1863 (M_TCP_CSUM_OUT0x0002|M_UDP_CSUM_OUT0x0004|M_ICMP_CSUM_OUT0x0200)) {
1864 u_int16_t csum = 0, offset;
1865
1866 offset = ip->ip_hl << 2;
1867 if (ISSET(m->m_pkthdr.csum_flags, M_TCP_TSO)((m->M_dat.MH.MH_pkthdr.csum_flags) & (0x8000)) &&
1868 in_ifcap_cksum(m, ifp, IFCAP_TSOv40x00001000)) {
1869 csum = in_cksum_phdr(ip->ip_src.s_addr,
1870 ip->ip_dst.s_addr, htonl(ip->ip_p)(__uint32_t)(__builtin_constant_p(ip->ip_p) ? (__uint32_t)
(((__uint32_t)(ip->ip_p) & 0xff) << 24 | ((__uint32_t
)(ip->ip_p) & 0xff00) << 8 | ((__uint32_t)(ip->
ip_p) & 0xff0000) >> 8 | ((__uint32_t)(ip->ip_p)
& 0xff000000) >> 24) : __swap32md(ip->ip_p))
);
1871 } else if (ISSET(m->m_pkthdr.csum_flags,((m->M_dat.MH.MH_pkthdr.csum_flags) & (0x0002|0x0004))
1872 M_TCP_CSUM_OUT|M_UDP_CSUM_OUT)((m->M_dat.MH.MH_pkthdr.csum_flags) & (0x0002|0x0004))) {
1873 csum = in_cksum_phdr(ip->ip_src.s_addr,
1874 ip->ip_dst.s_addr, htonl(ntohs(ip->ip_len) -(__uint32_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)) - offset + ip->
ip_p) ? (__uint32_t)(((__uint32_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)) - offset + ip->
ip_p) & 0xff) << 24 | ((__uint32_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)) - offset + ip->
ip_p) & 0xff00) << 8 | ((__uint32_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)) - offset + ip->
ip_p) & 0xff0000) >> 8 | ((__uint32_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
)) - offset + ip->ip_p) & 0xff000000) >> 24) : __swap32md
((__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)) - offset + ip->ip_p))
1875 offset + ip->ip_p)(__uint32_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)) - offset + ip->
ip_p) ? (__uint32_t)(((__uint32_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)) - offset + ip->
ip_p) & 0xff) << 24 | ((__uint32_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)) - offset + ip->
ip_p) & 0xff00) << 8 | ((__uint32_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)) - offset + ip->
ip_p) & 0xff0000) >> 8 | ((__uint32_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
)) - offset + ip->ip_p) & 0xff000000) >> 24) : __swap32md
((__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)) - offset + ip->ip_p))
);
1876 }
1877 if (ip->ip_p == IPPROTO_TCP6)
1878 offset += offsetof(struct tcphdr, th_sum)__builtin_offsetof(struct tcphdr, th_sum);
1879 else if (ip->ip_p == IPPROTO_UDP17)
1880 offset += offsetof(struct udphdr, uh_sum)__builtin_offsetof(struct udphdr, uh_sum);
1881 else if (ip->ip_p == IPPROTO_ICMP1)
1882 offset += offsetof(struct icmp, icmp_cksum)__builtin_offsetof(struct icmp, icmp_cksum);
1883 if ((offset + sizeof(u_int16_t)) > m->m_lenm_hdr.mh_len)
1884 m_copyback(m, offset, sizeof(csum), &csum, M_NOWAIT0x0002);
1885 else
1886 *(u_int16_t *)(mtod(m, caddr_t)((caddr_t)((m)->m_hdr.mh_data)) + offset) = csum;
1887 }
1888
1889 if (m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags & M_TCP_CSUM_OUT0x0002) {
1890 if (!in_ifcap_cksum(m, ifp, IFCAP_CSUM_TCPv40x00000002) ||
1891 ip->ip_hl != 5) {
1892 tcpstat_inc(tcps_outswcsum);
1893 in_delayed_cksum(m);
1894 m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags &= ~M_TCP_CSUM_OUT0x0002; /* Clear */
1895 }
1896 } else if (m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags & M_UDP_CSUM_OUT0x0004) {
1897 if (!in_ifcap_cksum(m, ifp, IFCAP_CSUM_UDPv40x00000004) ||
1898 ip->ip_hl != 5) {
1899 udpstat_inc(udps_outswcsum);
1900 in_delayed_cksum(m);
1901 m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags &= ~M_UDP_CSUM_OUT0x0004; /* Clear */
1902 }
1903 } else if (m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags & M_ICMP_CSUM_OUT0x0200) {
1904 in_delayed_cksum(m);
1905 m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags &= ~M_ICMP_CSUM_OUT0x0200; /* Clear */
1906 }
1907}
1908
1909int
1910in_ifcap_cksum(struct mbuf *m, struct ifnet *ifp, int ifcap)
1911{
1912 if ((ifp == NULL((void *)0)) ||
1913 !ISSET(ifp->if_capabilities, ifcap)((ifp->if_data.ifi_capabilities) & (ifcap)) ||
1914 (ifp->if_bridgeidx != 0))
1915 return (0);
1916 /*
1917 * Simplex interface sends packet back without hardware cksum.
1918 * Keep this check in sync with the condition where ether_resolve()
1919 * calls if_input_local().
1920 */
1921 if (ISSET(m->m_flags, M_BCAST)((m->m_hdr.mh_flags) & (0x0100)) &&
1922 ISSET(ifp->if_flags, IFF_SIMPLEX)((ifp->if_flags) & (0x800)) &&
1923 !m->m_pkthdrM_dat.MH.MH_pkthdr.pf.routed)
1924 return (0);
1925 return (1);
1926}