Bug Summary

File:netinet/udp_usrreq.c
Warning:line 430, column 9
Dereference of null pointer

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 udp_usrreq.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/udp_usrreq.c
1/* $OpenBSD: udp_usrreq.c,v 1.268 2022/01/04 06:32:40 yasuoka Exp $ */
2/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 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 * @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
33 *
34 * NRL grants permission for redistribution and use in source and binary
35 * forms, with or without modification, of the software and documentation
36 * created at NRL provided that the following conditions are met:
37 *
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 * must display the following acknowledgements:
45 * This product includes software developed by the University of
46 * California, Berkeley and its contributors.
47 * This product includes software developed at the Information
48 * Technology Division, US Naval Research Laboratory.
49 * 4. Neither the name of the NRL nor the names of its contributors
50 * may be used to endorse or promote products derived from this software
51 * without specific prior written permission.
52 *
53 * THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
54 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
55 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
56 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NRL OR
57 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
58 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
59 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
60 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
61 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
62 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
63 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 *
65 * The views and conclusions contained in the software and documentation
66 * are those of the authors and should not be interpreted as representing
67 * official policies, either expressed or implied, of the US Naval
68 * Research Laboratory (NRL).
69 */
70
71#include <sys/param.h>
72#include <sys/systm.h>
73#include <sys/mbuf.h>
74#include <sys/protosw.h>
75#include <sys/socket.h>
76#include <sys/socketvar.h>
77#include <sys/sysctl.h>
78#include <sys/domain.h>
79
80#include <net/if.h>
81#include <net/if_var.h>
82#include <net/if_media.h>
83#include <net/route.h>
84
85#include <netinet/in.h>
86#include <netinet/in_var.h>
87#include <netinet/ip.h>
88#include <netinet/in_pcb.h>
89#include <netinet/ip_var.h>
90#include <netinet/ip_icmp.h>
91#include <netinet/udp.h>
92#include <netinet/udp_var.h>
93
94#ifdef IPSEC1
95#include <netinet/ip_ipsp.h>
96#include <netinet/ip_esp.h>
97#endif
98
99#ifdef INET61
100#include <netinet6/in6_var.h>
101#include <netinet6/ip6_var.h>
102#include <netinet6/ip6protosw.h>
103#endif /* INET6 */
104
105#include "pf.h"
106#if NPF1 > 0
107#include <net/pfvar.h>
108#endif
109
110#ifdef PIPEX1
111#include <netinet/if_ether.h>
112#include <net/pipex.h>
113#endif
114
115#include "vxlan.h"
116#if NVXLAN1 > 0
117#include <net/if_vxlan.h>
118#endif
119
120/*
121 * UDP protocol implementation.
122 * Per RFC 768, August, 1980.
123 */
124int udpcksum = 1;
125
126u_int udp_sendspace = 9216; /* really max datagram size */
127u_int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
128 /* 40 1K datagrams */
129
130const struct sysctl_bounded_args udpctl_vars[] = {
131 { UDPCTL_CHECKSUM1, &udpcksum, 0, 1 },
132 { UDPCTL_RECVSPACE3, &udp_recvspace, 0, INT_MAX0x7fffffff },
133 { UDPCTL_SENDSPACE4, &udp_sendspace, 0, INT_MAX0x7fffffff },
134};
135
136struct inpcbtable udbtable;
137struct cpumem *udpcounters;
138
139void udp_sbappend(struct inpcb *, struct mbuf *, struct ip *,
140 struct ip6_hdr *, int, struct udphdr *, struct sockaddr *,
141 u_int32_t);
142int udp_output(struct inpcb *, struct mbuf *, struct mbuf *, struct mbuf *);
143void udp_notify(struct inpcb *, int);
144int udp_sysctl_udpstat(void *, size_t *, void *);
145
146#ifndef UDB_INITIAL_HASH_SIZE128
147#define UDB_INITIAL_HASH_SIZE128 128
148#endif
149
150void
151udp_init(void)
152{
153 udpcounters = counters_alloc(udps_ncounters);
154 in_pcbinit(&udbtable, UDB_INITIAL_HASH_SIZE128);
155}
156
157int
158udp_input(struct mbuf **mp, int *offp, int proto, int af)
159{
160 struct mbuf *m = *mp;
161 int iphlen = *offp;
162 struct ip *ip = NULL((void *)0);
1
'ip' initialized to a null pointer value
163 struct udphdr *uh;
164 struct inpcb *inp = NULL((void *)0);
165 struct ip save_ip;
166 int len;
167 u_int16_t savesum;
168 union {
169 struct sockaddr sa;
170 struct sockaddr_in sin;
171#ifdef INET61
172 struct sockaddr_in6 sin6;
173#endif /* INET6 */
174 } srcsa, dstsa;
175 struct ip6_hdr *ip6 = NULL((void *)0);
176 u_int32_t ipsecflowinfo = 0;
177
178 udpstat_inc(udps_ipackets);
179
180 IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr))do { struct mbuf *t; int tmp; if ((m)->m_hdr.mh_len >= (
iphlen) + (sizeof(struct udphdr))) (uh) = (struct udphdr *)((
(caddr_t)(((m))->m_hdr.mh_data)) + (iphlen)); else { t = m_pulldown
((m), (iphlen), (sizeof(struct udphdr)), &tmp); if (t) { if
(t->m_hdr.mh_len < tmp + (sizeof(struct udphdr))) panic
("m_pulldown malfunction"); (uh) = (struct udphdr *)(((caddr_t
)((t)->m_hdr.mh_data)) + tmp); } else { (uh) = (struct udphdr
*)((void *)0); (m) = ((void *)0); } } } while ( 0)
;
2
Assuming the condition is false
3
Taking false branch
4
Assuming 't' is non-null
5
Taking true branch
6
Assuming the condition is false
7
Taking false branch
8
Loop condition is false. Exiting loop
181 if (!uh) {
9
Assuming 'uh' is non-null
10
Taking false branch
182 udpstat_inc(udps_hdrops);
183 return IPPROTO_DONE257;
184 }
185
186 /* Check for illegal destination port 0 */
187 if (uh->uh_dport == 0) {
11
Assuming field 'uh_dport' is not equal to 0
12
Taking false branch
188 udpstat_inc(udps_noport);
189 goto bad;
190 }
191
192 /*
193 * Make mbuf data length reflect UDP length.
194 * If not enough data to reflect UDP length, drop.
195 */
196 len = ntohs((u_int16_t)uh->uh_ulen)(__uint16_t)(__builtin_constant_p((u_int16_t)uh->uh_ulen) ?
(__uint16_t)(((__uint16_t)((u_int16_t)uh->uh_ulen) & 0xffU
) << 8 | ((__uint16_t)((u_int16_t)uh->uh_ulen) &
0xff00U) >> 8) : __swap16md((u_int16_t)uh->uh_ulen)
)
;
13
'?' condition is false
197 switch (af) {
14
Control jumps to 'case 24:' at line 215
198 case AF_INET2:
199 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len - iphlen != len) {
200 if (len > (m->m_pkthdrM_dat.MH.MH_pkthdr.len - iphlen) ||
201 len < sizeof(struct udphdr)) {
202 udpstat_inc(udps_badlen);
203 goto bad;
204 }
205 m_adj(m, len - (m->m_pkthdrM_dat.MH.MH_pkthdr.len - iphlen));
206 }
207 ip = mtod(m, struct ip *)((struct ip *)((m)->m_hdr.mh_data));
208 /*
209 * Save a copy of the IP header in case we want restore it
210 * for sending an ICMP error message in response.
211 */
212 save_ip = *ip;
213 break;
214#ifdef INET61
215 case AF_INET624:
216 /* jumbograms */
217 if (len == 0 && m->m_pkthdrM_dat.MH.MH_pkthdr.len - iphlen > 0xffff)
15
Assuming 'len' is not equal to 0
218 len = m->m_pkthdrM_dat.MH.MH_pkthdr.len - iphlen;
219 if (len != m->m_pkthdrM_dat.MH.MH_pkthdr.len - iphlen) {
16
Assuming the condition is false
17
Taking false branch
220 udpstat_inc(udps_badlen);
221 goto bad;
222 }
223 ip6 = mtod(m, struct ip6_hdr *)((struct ip6_hdr *)((m)->m_hdr.mh_data));
224 break;
18
Execution continues on line 235
225#endif /* INET6 */
226 default:
227 unhandled_af(af);
228 }
229
230 /*
231 * Checksum extended UDP header and data.
232 * from W.R.Stevens: check incoming udp cksums even if
233 * udpcksum is not set.
234 */
235 savesum = uh->uh_sum;
236 if (uh->uh_sum == 0) {
19
Assuming field 'uh_sum' is not equal to 0
20
Taking false branch
237 udpstat_inc(udps_nosum);
238#ifdef INET61
239 /*
240 * In IPv6, the UDP checksum is ALWAYS used.
241 */
242 if (ip6)
243 goto bad;
244#endif /* INET6 */
245 } else {
246 if ((m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags & M_UDP_CSUM_IN_OK0x0080) == 0) {
21
Assuming the condition is false
22
Taking false branch
247 if (m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags & M_UDP_CSUM_IN_BAD0x0100) {
248 udpstat_inc(udps_badsum);
249 goto bad;
250 }
251 udpstat_inc(udps_inswcsum);
252
253 if (ip)
254 uh->uh_sum = in4_cksum(m, IPPROTO_UDP17,
255 iphlen, len);
256#ifdef INET61
257 else if (ip6)
258 uh->uh_sum = in6_cksum(m, IPPROTO_UDP17,
259 iphlen, len);
260#endif /* INET6 */
261 if (uh->uh_sum != 0) {
262 udpstat_inc(udps_badsum);
263 goto bad;
264 }
265 }
266 }
267
268#ifdef IPSEC1
269 if (udpencap_enable && udpencap_port && esp_enable &&
23
Assuming 'udpencap_enable' is 0
270#if NPF1 > 0
271 !(m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags & PF_TAG_DIVERTED0x08) &&
272#endif
273 uh->uh_dport == htons(udpencap_port)(__uint16_t)(__builtin_constant_p(udpencap_port) ? (__uint16_t
)(((__uint16_t)(udpencap_port) & 0xffU) << 8 | ((__uint16_t
)(udpencap_port) & 0xff00U) >> 8) : __swap16md(udpencap_port
))
) {
274 u_int32_t spi;
275 int skip = iphlen + sizeof(struct udphdr);
276
277 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len - skip < sizeof(u_int32_t)) {
278 /* packet too short */
279 m_freem(m);
280 return IPPROTO_DONE257;
281 }
282 m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi);
283 /*
284 * decapsulate if the SPI is not zero, otherwise pass
285 * to userland
286 */
287 if (spi != 0) {
288 int protoff;
289
290 if ((m = *mp = m_pullup(m, skip)) == NULL((void *)0)) {
291 udpstat_inc(udps_hdrops);
292 return IPPROTO_DONE257;
293 }
294
295 /* remove the UDP header */
296 bcopy(mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data)),
297 mtod(m, u_char *)((u_char *)((m)->m_hdr.mh_data)) + sizeof(struct udphdr), iphlen);
298 m_adj(m, sizeof(struct udphdr));
299 skip -= sizeof(struct udphdr);
300
301 espstat_inc(esps_udpencin);
302 protoff = af == AF_INET2 ? offsetof(struct ip, ip_p)__builtin_offsetof(struct ip, ip_p) :
303 offsetof(struct ip6_hdr, ip6_nxt)__builtin_offsetof(struct ip6_hdr, ip6_ctlun.ip6_un1.ip6_un1_nxt
)
;
304 return ipsec_common_input(mp, skip, protoff,
305 af, IPPROTO_ESP50, 1);
306 }
307 }
308#endif /* IPSEC */
309
310 switch (af) {
24
Control jumps to 'case 24:' at line 325
311 case AF_INET2:
312 bzero(&srcsa, sizeof(struct sockaddr_in))__builtin_bzero((&srcsa), (sizeof(struct sockaddr_in)));
313 srcsa.sin.sin_len = sizeof(struct sockaddr_in);
314 srcsa.sin.sin_family = AF_INET2;
315 srcsa.sin.sin_port = uh->uh_sport;
316 srcsa.sin.sin_addr = ip->ip_src;
317
318 bzero(&dstsa, sizeof(struct sockaddr_in))__builtin_bzero((&dstsa), (sizeof(struct sockaddr_in)));
319 dstsa.sin.sin_len = sizeof(struct sockaddr_in);
320 dstsa.sin.sin_family = AF_INET2;
321 dstsa.sin.sin_port = uh->uh_dport;
322 dstsa.sin.sin_addr = ip->ip_dst;
323 break;
324#ifdef INET61
325 case AF_INET624:
326 bzero(&srcsa, sizeof(struct sockaddr_in6))__builtin_bzero((&srcsa), (sizeof(struct sockaddr_in6)));
327 srcsa.sin6.sin6_len = sizeof(struct sockaddr_in6);
328 srcsa.sin6.sin6_family = AF_INET624;
329 srcsa.sin6.sin6_port = uh->uh_sport;
330#if 0 /*XXX inbound flowinfo */
331 srcsa.sin6.sin6_flowinfo = htonl(0x0fffffff)(__uint32_t)(__builtin_constant_p(0x0fffffff) ? (__uint32_t)(
((__uint32_t)(0x0fffffff) & 0xff) << 24 | ((__uint32_t
)(0x0fffffff) & 0xff00) << 8 | ((__uint32_t)(0x0fffffff
) & 0xff0000) >> 8 | ((__uint32_t)(0x0fffffff) &
0xff000000) >> 24) : __swap32md(0x0fffffff))
& ip6->ip6_flowip6_ctlun.ip6_un1.ip6_un1_flow;
332#endif
333 /* KAME hack: recover scopeid */
334 in6_recoverscope(&srcsa.sin6, &ip6->ip6_src);
335
336 bzero(&dstsa, sizeof(struct sockaddr_in6))__builtin_bzero((&dstsa), (sizeof(struct sockaddr_in6)));
337 dstsa.sin6.sin6_len = sizeof(struct sockaddr_in6);
338 dstsa.sin6.sin6_family = AF_INET624;
339 dstsa.sin6.sin6_port = uh->uh_dport;
340#if 0 /*XXX inbound flowinfo */
341 dstsa.sin6.sin6_flowinfo = htonl(0x0fffffff)(__uint32_t)(__builtin_constant_p(0x0fffffff) ? (__uint32_t)(
((__uint32_t)(0x0fffffff) & 0xff) << 24 | ((__uint32_t
)(0x0fffffff) & 0xff00) << 8 | ((__uint32_t)(0x0fffffff
) & 0xff0000) >> 8 | ((__uint32_t)(0x0fffffff) &
0xff000000) >> 24) : __swap32md(0x0fffffff))
& ip6->ip6_flowip6_ctlun.ip6_un1.ip6_un1_flow;
342#endif
343 /* KAME hack: recover scopeid */
344 in6_recoverscope(&dstsa.sin6, &ip6->ip6_dst);
345 break;
25
Execution continues on line 350
346#endif /* INET6 */
347 }
348
349#if NVXLAN1 > 0
350 if (vxlan_enable > 0 &&
26
Assuming 'vxlan_enable' is <= 0
351#if NPF1 > 0
352 !(m->m_pkthdrM_dat.MH.MH_pkthdr.pf.flags & PF_TAG_DIVERTED0x08) &&
353#endif
354 vxlan_lookup(m, uh, iphlen, &srcsa.sa, &dstsa.sa) != 0)
355 return IPPROTO_DONE257;
356#endif
357
358 if (m->m_flagsm_hdr.mh_flags & (M_BCAST0x0100|M_MCAST0x0200)) {
27
Assuming the condition is true
28
Taking true branch
359 struct inpcb *last;
360 /*
361 * Deliver a multicast or broadcast datagram to *all* sockets
362 * for which the local and remote addresses and ports match
363 * those of the incoming datagram. This allows more than
364 * one process to receive multi/broadcasts on the same port.
365 * (This really ought to be done for unicast datagrams as
366 * well, but that would cause problems with existing
367 * applications that open both address-specific sockets and
368 * a wildcard socket listening to the same port -- they would
369 * end up receiving duplicates of every unicast datagram.
370 * Those applications open the multiple sockets to overcome an
371 * inadequacy of the UDP socket interface, but for backwards
372 * compatibility we avoid the problem here rather than
373 * fixing the interface. Maybe 4.5BSD will remedy this?)
374 */
375
376 /*
377 * Locate pcb(s) for datagram.
378 * (Algorithm copied from raw_intr().)
379 */
380 last = NULL((void *)0);
381 NET_ASSERT_LOCKED()do { int _s = rw_status(&netlock); if ((splassert_ctl >
0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail
(0x0002UL, _s, __func__); } while (0)
;
29
Assuming 'splassert_ctl' is <= 0
30
Loop condition is false. Exiting loop
382 TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue)for((inp) = ((&udbtable.inpt_queue)->tqh_first); (inp)
!= ((void *)0); (inp) = ((inp)->inp_queue.tqe_next))
{
31
Assuming 'inp' is not equal to null
32
Loop condition is true. Entering loop body
383 if (inp->inp_socket->so_state & SS_CANTRCVMORE0x020)
33
Assuming the condition is false
34
Taking false branch
384 continue;
385#ifdef INET61
386 /* don't accept it if AF does not match */
387 if (ip6 && !(inp->inp_flags & INP_IPV60x100))
35
Assuming 'ip6' is null
388 continue;
389 if (!ip6
35.1
'ip6' is null
&& (inp->inp_flags & INP_IPV60x100))
36
Assuming the condition is false
37
Taking false branch
390 continue;
391#endif
392 if (rtable_l2(inp->inp_rtableid) !=
38
Assuming the condition is false
39
Taking false branch
393 rtable_l2(m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid))
394 continue;
395 if (inp->inp_lport != uh->uh_dport)
40
Assuming field 'inp_lport' is equal to field 'uh_dport'
41
Taking false branch
396 continue;
397#ifdef INET61
398 if (ip6
41.1
'ip6' is null
) {
42
Taking false branch
399 if (inp->inp_ip6_minhliminp_ip_minttl &&
400 inp->inp_ip6_minhliminp_ip_minttl > ip6->ip6_hlimip6_ctlun.ip6_un1.ip6_un1_hlim)
401 continue;
402 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)((*(const u_int32_t *)(const void *)(&(&inp->inp_laddru
.iau_addr6)->__u6_addr.__u6_addr8[0]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_laddru
.iau_addr6)->__u6_addr.__u6_addr8[4]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_laddru
.iau_addr6)->__u6_addr.__u6_addr8[8]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_laddru
.iau_addr6)->__u6_addr.__u6_addr8[12]) == 0))
)
403 if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6,(__builtin_memcmp((&(&inp->inp_laddru.iau_addr6)->
__u6_addr.__u6_addr8[0]), (&(&ip6->ip6_dst)->__u6_addr
.__u6_addr8[0]), (sizeof(struct in6_addr))) == 0)
404 &ip6->ip6_dst)(__builtin_memcmp((&(&inp->inp_laddru.iau_addr6)->
__u6_addr.__u6_addr8[0]), (&(&ip6->ip6_dst)->__u6_addr
.__u6_addr8[0]), (sizeof(struct in6_addr))) == 0)
)
405 continue;
406 } else
407#endif /* INET6 */
408 {
409 if (inp->inp_ip_minttl &&
43
Assuming field 'inp_ip_minttl' is 0
410 inp->inp_ip_minttl > ip->ip_ttl)
411 continue;
412
413 if (inp->inp_laddrinp_laddru.iau_a4u.inaddr.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
))))
) {
44
'?' condition is true
45
Assuming the condition is false
46
Taking false branch
414 if (inp->inp_laddrinp_laddru.iau_a4u.inaddr.s_addr !=
415 ip->ip_dst.s_addr)
416 continue;
417 }
418 }
419#ifdef INET61
420 if (ip6
46.1
'ip6' is null
) {
47
Taking false branch
421 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)((*(const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[0]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[4]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[8]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[12]) == 0))
)
422 if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6,(__builtin_memcmp((&(&inp->inp_faddru.iau_addr6)->
__u6_addr.__u6_addr8[0]), (&(&ip6->ip6_src)->__u6_addr
.__u6_addr8[0]), (sizeof(struct in6_addr))) == 0)
423 &ip6->ip6_src)(__builtin_memcmp((&(&inp->inp_faddru.iau_addr6)->
__u6_addr.__u6_addr8[0]), (&(&ip6->ip6_src)->__u6_addr
.__u6_addr8[0]), (sizeof(struct in6_addr))) == 0)
||
424 inp->inp_fport != uh->uh_sport)
425 continue;
426 } else
427#endif /* INET6 */
428 if (inp->inp_faddrinp_faddru.iau_a4u.inaddr.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
))))
) {
48
'?' condition is true
49
Assuming the condition is true
50
Taking true branch
429 if (inp->inp_faddrinp_faddru.iau_a4u.inaddr.s_addr !=
430 ip->ip_src.s_addr ||
51
Dereference of null pointer
431 inp->inp_fport != uh->uh_sport)
432 continue;
433 }
434
435 if (last != NULL((void *)0)) {
436 struct mbuf *n;
437
438 n = m_copym(m, 0, M_COPYALL1000000000, M_NOWAIT0x0002);
439 if (n != NULL((void *)0)) {
440 udp_sbappend(last, n, ip, ip6, iphlen,
441 uh, &srcsa.sa, 0);
442 }
443 }
444 last = inp;
445 /*
446 * Don't look for additional matches if this one does
447 * not have either the SO_REUSEPORT or SO_REUSEADDR
448 * socket options set. This heuristic avoids searching
449 * through all pcbs in the common case of a non-shared
450 * port. It assumes that an application will never
451 * clear these options after setting them.
452 */
453 if ((last->inp_socket->so_options & (SO_REUSEPORT0x0200 |
454 SO_REUSEADDR0x0004)) == 0)
455 break;
456 }
457
458 if (last == NULL((void *)0)) {
459 /*
460 * No matching pcb found; discard datagram.
461 * (No need to send an ICMP Port Unreachable
462 * for a broadcast or multicast datgram.)
463 */
464 udpstat_inc(udps_noportbcast);
465 goto bad;
466 }
467
468 udp_sbappend(last, m, ip, ip6, iphlen, uh, &srcsa.sa, 0);
469 return IPPROTO_DONE257;
470 }
471 /*
472 * Locate pcb for datagram.
473 */
474#if NPF1 > 0
475 inp = pf_inp_lookup(m);
476#endif
477 if (inp == NULL((void *)0)) {
478#ifdef INET61
479 if (ip6)
480 inp = in6_pcbhashlookup(&udbtable, &ip6->ip6_src,
481 uh->uh_sport, &ip6->ip6_dst, uh->uh_dport,
482 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid);
483 else
484#endif /* INET6 */
485 inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport,
486 ip->ip_dst, uh->uh_dport, m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid);
487 }
488 if (inp == NULL((void *)0)) {
489 udpstat_inc(udps_pcbhashmiss);
490#ifdef INET61
491 if (ip6) {
492 inp = in6_pcblookup_listen(&udbtable, &ip6->ip6_dst,
493 uh->uh_dport, m, m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid);
494 } else
495#endif /* INET6 */
496 inp = in_pcblookup_listen(&udbtable, ip->ip_dst,
497 uh->uh_dport, m, m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid);
498 }
499
500#ifdef IPSEC1
501 if (ipsec_in_use) {
502 struct m_tag *mtag;
503 struct tdb_ident *tdbi;
504 struct tdb *tdb;
505 int error;
506
507 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE0x0001, NULL((void *)0));
508 if (mtag != NULL((void *)0)) {
509 tdbi = (struct tdb_ident *)(mtag + 1);
510 tdb = gettdb(tdbi->rdomain, tdbi->spi,gettdb_dir((tdbi->rdomain),(tdbi->spi),(&tdbi->dst
),(tdbi->proto),0)
511 &tdbi->dst, tdbi->proto)gettdb_dir((tdbi->rdomain),(tdbi->spi),(&tdbi->dst
),(tdbi->proto),0)
;
512 } else
513 tdb = NULL((void *)0);
514 error = ipsp_spd_lookup(m, af, iphlen, IPSP_DIRECTION_IN0x1,
515 tdb, inp, NULL((void *)0), NULL((void *)0));
516 if (error) {
517 udpstat_inc(udps_nosec);
518 tdb_unref(tdb);
519 goto bad;
520 }
521 /* create ipsec options while we know that tdb cannot be modified */
522 if (tdb && tdb->tdb_ids)
523 ipsecflowinfo = tdb->tdb_ids->id_flow;
524 tdb_unref(tdb);
525 }
526#endif /*IPSEC */
527
528 if (inp == NULL((void *)0)) {
529 udpstat_inc(udps_noport);
530 if (m->m_flagsm_hdr.mh_flags & (M_BCAST0x0100 | M_MCAST0x0200)) {
531 udpstat_inc(udps_noportbcast);
532 goto bad;
533 }
534#ifdef INET61
535 if (ip6) {
536 uh->uh_sum = savesum;
537 icmp6_error(m, ICMP6_DST_UNREACH1,
538 ICMP6_DST_UNREACH_NOPORT4,0);
539 } else
540#endif /* INET6 */
541 {
542 *ip = save_ip;
543 uh->uh_sum = savesum;
544 icmp_error(m, ICMP_UNREACH3, ICMP_UNREACH_PORT3,
545 0, 0);
546 }
547 return IPPROTO_DONE257;
548 }
549
550 KASSERT(sotoinpcb(inp->inp_socket) == inp)((((struct inpcb *)(inp->inp_socket)->so_pcb) == inp) ?
(void)0 : __assert("diagnostic ", "/usr/src/sys/netinet/udp_usrreq.c"
, 550, "sotoinpcb(inp->inp_socket) == inp"))
;
551 soassertlocked(inp->inp_socket);
552
553#ifdef INET61
554 if (ip6 && inp->inp_ip6_minhliminp_ip_minttl &&
555 inp->inp_ip6_minhliminp_ip_minttl > ip6->ip6_hlimip6_ctlun.ip6_un1.ip6_un1_hlim) {
556 goto bad;
557 } else
558#endif
559 if (ip && inp->inp_ip_minttl &&
560 inp->inp_ip_minttl > ip->ip_ttl) {
561 goto bad;
562 }
563
564#if NPF1 > 0
565 if (inp->inp_socket->so_state & SS_ISCONNECTED0x002)
566 pf_inp_link(m, inp);
567#endif
568
569#ifdef PIPEX1
570 if (pipex_enable && inp->inp_pipex) {
571 struct pipex_session *session;
572 int off = iphlen + sizeof(struct udphdr);
573 if ((session = pipex_l2tp_lookup_session(m, off)) != NULL((void *)0)) {
574 if ((m = *mp = pipex_l2tp_input(m, off, session,
575 ipsecflowinfo)) == NULL((void *)0)) {
576 /* the packet is handled by PIPEX */
577 return IPPROTO_DONE257;
578 }
579 }
580 }
581#endif
582
583 udp_sbappend(inp, m, ip, ip6, iphlen, uh, &srcsa.sa, ipsecflowinfo);
584 return IPPROTO_DONE257;
585bad:
586 m_freem(m);
587 return IPPROTO_DONE257;
588}
589
590void
591udp_sbappend(struct inpcb *inp, struct mbuf *m, struct ip *ip,
592 struct ip6_hdr *ip6, int hlen, struct udphdr *uh,
593 struct sockaddr *srcaddr, u_int32_t ipsecflowinfo)
594{
595 struct socket *so = inp->inp_socket;
596 struct mbuf *opts = NULL((void *)0);
597
598 hlen += sizeof(*uh);
599
600 if (inp->inp_upcall != NULL((void *)0)) {
601 m = (*inp->inp_upcall)(inp->inp_upcall_arg, m,
602 ip, ip6, uh, hlen);
603 if (m == NULL((void *)0))
604 return;
605 }
606
607#ifdef INET61
608 if (ip6 && (inp->inp_flags & IN6P_CONTROLOPTS(0x010000|0x020000|0x040000| 0x080000|0x100000| 0x400000|0x800000
|0x40000000| 0x80000000|0x200)
||
609 so->so_options & SO_TIMESTAMP0x0800))
610 ip6_savecontrol(inp, m, &opts);
611#endif /* INET6 */
612 if (ip && (inp->inp_flags & INP_CONTROLOPTS(0x001|0x002|0x004| 0x010|0x020|0x080|0x040|0x200| 0x400) ||
613 so->so_options & SO_TIMESTAMP0x0800))
614 ip_savecontrol(inp, &opts, ip, m);
615#ifdef INET61
616 if (ip6 && (inp->inp_flags & IN6P_RECVDSTPORT0x200)) {
617 struct mbuf **mp = &opts;
618
619 while (*mp)
620 mp = &(*mp)->m_nextm_hdr.mh_next;
621 *mp = sbcreatecontrol((caddr_t)&uh->uh_dport, sizeof(u_int16_t),
622 IPV6_RECVDSTPORT64, IPPROTO_IPV641);
623 }
624#endif /* INET6 */
625 if (ip && (inp->inp_flags & INP_RECVDSTPORT0x200)) {
626 struct mbuf **mp = &opts;
627
628 while (*mp)
629 mp = &(*mp)->m_nextm_hdr.mh_next;
630 *mp = sbcreatecontrol((caddr_t)&uh->uh_dport, sizeof(u_int16_t),
631 IP_RECVDSTPORT33, IPPROTO_IP0);
632 }
633#ifdef IPSEC1
634 if (ipsecflowinfo && (inp->inp_flags & INP_IPSECFLOWINFO0x800)) {
635 struct mbuf **mp = &opts;
636
637 while (*mp)
638 mp = &(*mp)->m_nextm_hdr.mh_next;
639 *mp = sbcreatecontrol((caddr_t)&ipsecflowinfo,
640 sizeof(u_int32_t), IP_IPSECFLOWINFO36, IPPROTO_IP0);
641 }
642#endif
643 m_adj(m, hlen);
644 if (sbappendaddr(so, &so->so_rcv, srcaddr, m, opts) == 0) {
645 udpstat_inc(udps_fullsock);
646 m_freem(m);
647 m_freem(opts);
648 return;
649 }
650 sorwakeup(so);
651}
652
653/*
654 * Notify a udp user of an asynchronous error;
655 * just wake up so that he can collect error status.
656 */
657void
658udp_notify(struct inpcb *inp, int errno)
659{
660 inp->inp_socket->so_error = errno;
661 sorwakeup(inp->inp_socket);
662 sowwakeup(inp->inp_socket);
663}
664
665#ifdef INET61
666void
667udp6_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *d)
668{
669 struct udphdr uh;
670 struct sockaddr_in6 sa6;
671 struct ip6_hdr *ip6;
672 struct mbuf *m;
673 int off;
674 void *cmdarg;
675 struct ip6ctlparam *ip6cp = NULL((void *)0);
676 struct udp_portonly {
677 u_int16_t uh_sport;
678 u_int16_t uh_dport;
679 } *uhp;
680 void (*notify)(struct inpcb *, int) = udp_notify;
681
682 if (sa == NULL((void *)0))
683 return;
684 if (sa->sa_family != AF_INET624 ||
685 sa->sa_len != sizeof(struct sockaddr_in6))
686 return;
687
688 if ((unsigned)cmd >= PRC_NCMDS21)
689 return;
690 if (PRC_IS_REDIRECT(cmd)((cmd) >= 14 && (cmd) <= 17))
691 notify = in_rtchange, d = NULL((void *)0);
692 else if (cmd == PRC_HOSTDEAD6)
693 d = NULL((void *)0);
694 else if (cmd == PRC_MSGSIZE5)
695 ; /* special code is present, see below */
696 else if (inet6ctlerrmap[cmd] == 0)
697 return;
698
699 /* if the parameter is from icmp6, decode it. */
700 if (d != NULL((void *)0)) {
701 ip6cp = (struct ip6ctlparam *)d;
702 m = ip6cp->ip6c_m;
703 ip6 = ip6cp->ip6c_ip6;
704 off = ip6cp->ip6c_off;
705 cmdarg = ip6cp->ip6c_cmdarg;
706 } else {
707 m = NULL((void *)0);
708 ip6 = NULL((void *)0);
709 cmdarg = NULL((void *)0);
710 /* XXX: translate addresses into internal form */
711 sa6 = *satosin6(sa);
712 if (in6_embedscope(&sa6.sin6_addr, &sa6, NULL((void *)0))) {
713 /* should be impossible */
714 return;
715 }
716 }
717
718 if (ip6cp && ip6cp->ip6c_finaldst) {
719 bzero(&sa6, sizeof(sa6))__builtin_bzero((&sa6), (sizeof(sa6)));
720 sa6.sin6_family = AF_INET624;
721 sa6.sin6_len = sizeof(sa6);
722 sa6.sin6_addr = *ip6cp->ip6c_finaldst;
723 /* XXX: assuming M is valid in this case */
724 sa6.sin6_scope_id = in6_addr2scopeid(m->m_pkthdrM_dat.MH.MH_pkthdr.ph_ifidx,
725 ip6cp->ip6c_finaldst);
726 if (in6_embedscope(ip6cp->ip6c_finaldst, &sa6, NULL((void *)0))) {
727 /* should be impossible */
728 return;
729 }
730 } else {
731 /* XXX: translate addresses into internal form */
732 sa6 = *satosin6(sa);
733 if (in6_embedscope(&sa6.sin6_addr, &sa6, NULL((void *)0))) {
734 /* should be impossible */
735 return;
736 }
737 }
738
739 if (ip6) {
740 /*
741 * XXX: We assume that when IPV6 is non NULL,
742 * M and OFF are valid.
743 */
744 struct sockaddr_in6 sa6_src;
745
746 /* check if we can safely examine src and dst ports */
747 if (m->m_pkthdrM_dat.MH.MH_pkthdr.len < off + sizeof(*uhp))
748 return;
749
750 bzero(&uh, sizeof(uh))__builtin_bzero((&uh), (sizeof(uh)));
751 m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
752
753 bzero(&sa6_src, sizeof(sa6_src))__builtin_bzero((&sa6_src), (sizeof(sa6_src)));
754 sa6_src.sin6_family = AF_INET624;
755 sa6_src.sin6_len = sizeof(sa6_src);
756 sa6_src.sin6_addr = ip6->ip6_src;
757 sa6_src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdrM_dat.MH.MH_pkthdr.ph_ifidx,
758 &ip6->ip6_src);
759 if (in6_embedscope(&sa6_src.sin6_addr, &sa6_src, NULL((void *)0))) {
760 /* should be impossible */
761 return;
762 }
763
764 if (cmd == PRC_MSGSIZE5) {
765 int valid = 0;
766
767 /*
768 * Check to see if we have a valid UDP socket
769 * corresponding to the address in the ICMPv6 message
770 * payload.
771 */
772 if (in6_pcbhashlookup(&udbtable, &sa6.sin6_addr,
773 uh.uh_dport, &sa6_src.sin6_addr, uh.uh_sport,
774 rdomain))
775 valid = 1;
776#if 0
777 /*
778 * As the use of sendto(2) is fairly popular,
779 * we may want to allow non-connected pcb too.
780 * But it could be too weak against attacks...
781 * We should at least check if the local address (= s)
782 * is really ours.
783 */
784 else if (in6_pcblookup_listen(&udbtable,
785 &sa6_src.sin6_addr, uh.uh_sport, NULL((void *)0),
786 rdomain))
787 valid = 1;
788#endif
789
790 /*
791 * Depending on the value of "valid" and routing table
792 * size (mtudisc_{hi,lo}wat), we will:
793 * - recalculate the new MTU and create the
794 * corresponding routing entry, or
795 * - ignore the MTU change notification.
796 */
797 icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
798
799 /*
800 * regardless of if we called icmp6_mtudisc_update(),
801 * we need to call in6_pcbnotify(), to notify path
802 * MTU change to the userland (2292bis-02), because
803 * some unconnected sockets may share the same
804 * destination and want to know the path MTU.
805 */
806 }
807
808 (void) in6_pcbnotify(&udbtable, &sa6, uh.uh_dport,
809 &sa6_src, uh.uh_sport, rdomain, cmd, cmdarg, notify);
810 } else {
811 (void) in6_pcbnotify(&udbtable, &sa6, 0,
812 &sa6_any, 0, rdomain, cmd, cmdarg, notify);
813 }
814}
815#endif
816
817void
818udp_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
819{
820 struct ip *ip = v;
821 struct udphdr *uhp;
822 struct in_addr faddr;
823 struct inpcb *inp;
824 void (*notify)(struct inpcb *, int) = udp_notify;
825 int errno;
826
827 if (sa == NULL((void *)0))
828 return;
829 if (sa->sa_family != AF_INET2 ||
830 sa->sa_len != sizeof(struct sockaddr_in))
831 return;
832 faddr = satosin(sa)->sin_addr;
833 if (faddr.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
))))
)
834 return;
835
836 if ((unsigned)cmd >= PRC_NCMDS21)
837 return;
838 errno = inetctlerrmap[cmd];
839 if (PRC_IS_REDIRECT(cmd)((cmd) >= 14 && (cmd) <= 17))
840 notify = in_rtchange, ip = 0;
841 else if (cmd == PRC_HOSTDEAD6)
842 ip = 0;
843 else if (errno == 0)
844 return;
845 if (ip) {
846 uhp = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
847
848#ifdef IPSEC1
849 /* PMTU discovery for udpencap */
850 if (cmd == PRC_MSGSIZE5 && ip_mtudisc && udpencap_enable &&
851 udpencap_port && uhp->uh_sport == htons(udpencap_port)(__uint16_t)(__builtin_constant_p(udpencap_port) ? (__uint16_t
)(((__uint16_t)(udpencap_port) & 0xffU) << 8 | ((__uint16_t
)(udpencap_port) & 0xff00U) >> 8) : __swap16md(udpencap_port
))
) {
852 udpencap_ctlinput(cmd, sa, rdomain, v);
853 return;
854 }
855#endif
856 inp = in_pcbhashlookup(&udbtable,
857 ip->ip_dst, uhp->uh_dport, ip->ip_src, uhp->uh_sport,
858 rdomain);
859 if (inp && inp->inp_socket != NULL((void *)0))
860 notify(inp, errno);
861 } else
862 in_pcbnotifyall(&udbtable, sa, rdomain, errno, notify);
863}
864
865int
866udp_output(struct inpcb *inp, struct mbuf *m, struct mbuf *addr,
867 struct mbuf *control)
868{
869 struct sockaddr_in *sin = NULL((void *)0);
870 struct udpiphdr *ui;
871 u_int32_t ipsecflowinfo = 0;
872 struct sockaddr_in src_sin;
873 int len = m->m_pkthdrM_dat.MH.MH_pkthdr.len;
874 struct in_addr *laddr;
875 int error = 0;
876
877#ifdef DIAGNOSTIC1
878 if ((inp->inp_flags & INP_IPV60x100) != 0)
879 panic("IPv6 inpcb to %s", __func__);
880#endif
881
882 /*
883 * Compute the packet length of the IP header, and
884 * punt if the length looks bogus.
885 */
886 if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET65535) {
887 error = EMSGSIZE40;
888 goto release;
889 }
890
891 memset(&src_sin, 0, sizeof(src_sin))__builtin_memset((&src_sin), (0), (sizeof(src_sin)));
892
893 if (control) {
894 u_int clen;
895 struct cmsghdr *cm;
896 caddr_t cmsgs;
897
898 /*
899 * XXX: Currently, we assume all the optional information is
900 * stored in a single mbuf.
901 */
902 if (control->m_nextm_hdr.mh_next) {
903 error = EINVAL22;
904 goto release;
905 }
906
907 clen = control->m_lenm_hdr.mh_len;
908 cmsgs = mtod(control, caddr_t)((caddr_t)((control)->m_hdr.mh_data));
909 do {
910 if (clen < CMSG_LEN(0)((((unsigned long)(sizeof(struct cmsghdr)) + (sizeof(long) - 1
)) &~(sizeof(long) - 1)) + (0))
) {
911 error = EINVAL22;
912 goto release;
913 }
914 cm = (struct cmsghdr *)cmsgs;
915 if (cm->cmsg_len < CMSG_LEN(0)((((unsigned long)(sizeof(struct cmsghdr)) + (sizeof(long) - 1
)) &~(sizeof(long) - 1)) + (0))
||
916 CMSG_ALIGN(cm->cmsg_len)(((unsigned long)(cm->cmsg_len) + (sizeof(long) - 1)) &
~(sizeof(long) - 1))
> clen) {
917 error = EINVAL22;
918 goto release;
919 }
920#ifdef IPSEC1
921 if ((inp->inp_flags & INP_IPSECFLOWINFO0x800) != 0 &&
922 cm->cmsg_len == CMSG_LEN(sizeof(ipsecflowinfo))((((unsigned long)(sizeof(struct cmsghdr)) + (sizeof(long) - 1
)) &~(sizeof(long) - 1)) + (sizeof(ipsecflowinfo)))
&&
923 cm->cmsg_level == IPPROTO_IP0 &&
924 cm->cmsg_type == IP_IPSECFLOWINFO36) {
925 ipsecflowinfo = *(u_int32_t *)CMSG_DATA(cm)((unsigned char *)(cm) + (((unsigned long)(sizeof(struct cmsghdr
)) + (sizeof(long) - 1)) &~(sizeof(long) - 1)))
;
926 } else
927#endif
928 if (cm->cmsg_len == CMSG_LEN(sizeof(struct in_addr))((((unsigned long)(sizeof(struct cmsghdr)) + (sizeof(long) - 1
)) &~(sizeof(long) - 1)) + (sizeof(struct in_addr)))
&&
929 cm->cmsg_level == IPPROTO_IP0 &&
930 cm->cmsg_type == IP_SENDSRCADDR7) {
931 memcpy(&src_sin.sin_addr, CMSG_DATA(cm),__builtin_memcpy((&src_sin.sin_addr), (((unsigned char *)
(cm) + (((unsigned long)(sizeof(struct cmsghdr)) + (sizeof(long
) - 1)) &~(sizeof(long) - 1)))), (sizeof(struct in_addr))
)
932 sizeof(struct in_addr))__builtin_memcpy((&src_sin.sin_addr), (((unsigned char *)
(cm) + (((unsigned long)(sizeof(struct cmsghdr)) + (sizeof(long
) - 1)) &~(sizeof(long) - 1)))), (sizeof(struct in_addr))
)
;
933 src_sin.sin_family = AF_INET2;
934 src_sin.sin_len = sizeof(src_sin);
935 /* no check on reuse when sin->sin_port == 0 */
936 if ((error = in_pcbaddrisavail(inp, &src_sin,
937 0, curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc
)))
938 goto release;
939 }
940 clen -= CMSG_ALIGN(cm->cmsg_len)(((unsigned long)(cm->cmsg_len) + (sizeof(long) - 1)) &
~(sizeof(long) - 1))
;
941 cmsgs += CMSG_ALIGN(cm->cmsg_len)(((unsigned long)(cm->cmsg_len) + (sizeof(long) - 1)) &
~(sizeof(long) - 1))
;
942 } while (clen);
943 }
944
945 if (addr) {
946 if ((error = in_nam2sin(addr, &sin)))
947 goto release;
948 if (sin->sin_port == 0) {
949 error = EADDRNOTAVAIL49;
950 goto release;
951 }
952 if (inp->inp_faddrinp_faddru.iau_a4u.inaddr.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
))))
) {
953 error = EISCONN56;
954 goto release;
955 }
956 error = in_pcbselsrc(&laddr, sin, inp);
957 if (error)
958 goto release;
959
960 if (inp->inp_lport == 0) {
961 error = in_pcbbind(inp, NULL((void *)0), curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc
);
962 if (error)
963 goto release;
964 }
965
966 if (src_sin.sin_len > 0 &&
967 src_sin.sin_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
))))
&&
968 src_sin.sin_addr.s_addr != inp->inp_laddrinp_laddru.iau_a4u.inaddr.s_addr) {
969 src_sin.sin_port = inp->inp_lport;
970 if (inp->inp_laddrinp_laddru.iau_a4u.inaddr.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
))))
&&
971 (error =
972 in_pcbaddrisavail(inp, &src_sin, 0, curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc
)))
973 goto release;
974 laddr = &src_sin.sin_addr;
975 }
976 } else {
977 if (inp->inp_faddrinp_faddru.iau_a4u.inaddr.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
))))
) {
978 error = ENOTCONN57;
979 goto release;
980 }
981 laddr = &inp->inp_laddrinp_laddru.iau_a4u.inaddr;
982 }
983
984 /*
985 * Calculate data length and get a mbuf
986 * for UDP and IP headers.
987 */
988 M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT)(m) = m_prepend((m), (sizeof(struct udpiphdr)), (0x0002));
989 if (m == NULL((void *)0)) {
990 error = ENOBUFS55;
991 goto bail;
992 }
993
994 /*
995 * Fill in mbuf with extended UDP header
996 * and addresses and length put into network format.
997 */
998 ui = mtod(m, struct udpiphdr *)((struct udpiphdr *)((m)->m_hdr.mh_data));
999 bzero(ui->ui_x1, sizeof ui->ui_x1)__builtin_bzero((ui->ui_i.ih_x1), (sizeof ui->ui_i.ih_x1
))
;
1000 ui->ui_prui_i.ih_pr = IPPROTO_UDP17;
1001 ui->ui_lenui_i.ih_len = htons((u_int16_t)len + sizeof (struct udphdr))(__uint16_t)(__builtin_constant_p((u_int16_t)len + sizeof (struct
udphdr)) ? (__uint16_t)(((__uint16_t)((u_int16_t)len + sizeof
(struct udphdr)) & 0xffU) << 8 | ((__uint16_t)((u_int16_t
)len + sizeof (struct udphdr)) & 0xff00U) >> 8) : __swap16md
((u_int16_t)len + sizeof (struct udphdr)))
;
1002 ui->ui_srcui_i.ih_src = *laddr;
1003 ui->ui_dstui_i.ih_dst = sin ? sin->sin_addr : inp->inp_faddrinp_faddru.iau_a4u.inaddr;
1004 ui->ui_sportui_u.uh_sport = inp->inp_lport;
1005 ui->ui_dportui_u.uh_dport = sin ? sin->sin_port : inp->inp_fport;
1006 ui->ui_ulenui_u.uh_ulen = ui->ui_lenui_i.ih_len;
1007 ((struct ip *)ui)->ip_len = htons(sizeof (struct udpiphdr) + len)(__uint16_t)(__builtin_constant_p(sizeof (struct udpiphdr) + len
) ? (__uint16_t)(((__uint16_t)(sizeof (struct udpiphdr) + len
) & 0xffU) << 8 | ((__uint16_t)(sizeof (struct udpiphdr
) + len) & 0xff00U) >> 8) : __swap16md(sizeof (struct
udpiphdr) + len))
;
1008 ((struct ip *)ui)->ip_ttl = inp->inp_ipinp_hu.hu_ip.ip_ttl;
1009 ((struct ip *)ui)->ip_tos = inp->inp_ipinp_hu.hu_ip.ip_tos;
1010 if (udpcksum)
1011 m->m_pkthdrM_dat.MH.MH_pkthdr.csum_flags |= M_UDP_CSUM_OUT0x0004;
1012
1013 udpstat_inc(udps_opackets);
1014
1015 /* force routing table */
1016 m->m_pkthdrM_dat.MH.MH_pkthdr.ph_rtableid = inp->inp_rtableid;
1017
1018#if NPF1 > 0
1019 if (inp->inp_socket->so_state & SS_ISCONNECTED0x002)
1020 pf_mbuf_link_inpcb(m, inp);
1021#endif
1022
1023 error = ip_output(m, inp->inp_options, &inp->inp_routeinp_ru.ru_route,
1024 (inp->inp_socket->so_options & SO_BROADCAST0x0020), inp->inp_moptionsinp_mou.mou_mo,
1025 inp, ipsecflowinfo);
1026
1027bail:
1028 m_freem(control);
1029 return (error);
1030
1031release:
1032 m_freem(m);
1033 goto bail;
1034}
1035
1036/*ARGSUSED*/
1037int
1038udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
1039 struct mbuf *control, struct proc *p)
1040{
1041 struct inpcb *inp;
1042 int error = 0;
1043
1044 if (req == PRU_CONTROL11) {
1045#ifdef INET61
1046 if (sotopf(so)(so->so_proto->pr_domain->dom_family) == PF_INET624)
1047 return (in6_control(so, (u_long)m, (caddr_t)addr,
1048 (struct ifnet *)control));
1049 else
1050#endif /* INET6 */
1051 return (in_control(so, (u_long)m, (caddr_t)addr,
1052 (struct ifnet *)control));
1053 }
1054
1055 soassertlocked(so);
1056
1057 inp = sotoinpcb(so)((struct inpcb *)(so)->so_pcb);
1058 if (inp == NULL((void *)0)) {
1059 error = EINVAL22;
1060 goto release;
1061 }
1062
1063 /*
1064 * Note: need to block udp_input while changing
1065 * the udp pcb queue and/or pcb addresses.
1066 */
1067 switch (req) {
1068
1069 case PRU_BIND2:
1070 error = in_pcbbind(inp, addr, p);
1071 break;
1072
1073 case PRU_LISTEN3:
1074 error = EOPNOTSUPP45;
1075 break;
1076
1077 case PRU_CONNECT4:
1078#ifdef INET61
1079 if (inp->inp_flags & INP_IPV60x100) {
1080 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)((*(const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[0]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[4]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[8]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[12]) == 0))
) {
1081 error = EISCONN56;
1082 break;
1083 }
1084 error = in6_pcbconnect(inp, addr);
1085 } else
1086#endif /* INET6 */
1087 {
1088 if (inp->inp_faddrinp_faddru.iau_a4u.inaddr.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
))))
) {
1089 error = EISCONN56;
1090 break;
1091 }
1092 error = in_pcbconnect(inp, addr);
1093 }
1094
1095 if (error == 0)
1096 soisconnected(so);
1097 break;
1098
1099 case PRU_CONNECT217:
1100 error = EOPNOTSUPP45;
1101 break;
1102
1103 case PRU_ACCEPT5:
1104 error = EOPNOTSUPP45;
1105 break;
1106
1107 case PRU_DISCONNECT6:
1108#ifdef INET61
1109 if (inp->inp_flags & INP_IPV60x100) {
1110 if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)((*(const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[0]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[4]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[8]) == 0) && (*(
const u_int32_t *)(const void *)(&(&inp->inp_faddru
.iau_addr6)->__u6_addr.__u6_addr8[12]) == 0))
) {
1111 error = ENOTCONN57;
1112 break;
1113 }
1114 } else
1115#endif /* INET6 */
1116 {
1117 if (inp->inp_faddrinp_faddru.iau_a4u.inaddr.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
))))
) {
1118 error = ENOTCONN57;
1119 break;
1120 }
1121 }
1122
1123#ifdef INET61
1124 if (inp->inp_flags & INP_IPV60x100)
1125 inp->inp_laddr6inp_laddru.iau_addr6 = in6addr_any;
1126 else
1127#endif /* INET6 */
1128 inp->inp_laddrinp_laddru.iau_a4u.inaddr.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
))))
;
1129 in_pcbdisconnect(inp);
1130
1131 so->so_state &= ~SS_ISCONNECTED0x002; /* XXX */
1132 break;
1133
1134 case PRU_SHUTDOWN7:
1135 socantsendmore(so);
1136 break;
1137
1138 case PRU_SEND9:
1139#ifdef PIPEX1
1140 if (inp->inp_pipex) {
1141 struct pipex_session *session;
1142
1143 if (addr != NULL((void *)0))
1144 session =
1145 pipex_l2tp_userland_lookup_session(m,
1146 mtod(addr, struct sockaddr *)((struct sockaddr *)((addr)->m_hdr.mh_data)));
1147 else
1148#ifdef INET61
1149 if (inp->inp_flags & INP_IPV60x100)
1150 session =
1151 pipex_l2tp_userland_lookup_session_ipv6(
1152 m, inp->inp_faddr6inp_faddru.iau_addr6);
1153 else
1154#endif
1155 session =
1156 pipex_l2tp_userland_lookup_session_ipv4(
1157 m, inp->inp_faddrinp_faddru.iau_a4u.inaddr);
1158 if (session != NULL((void *)0))
1159 if ((m = pipex_l2tp_userland_output(
1160 m, session)) == NULL((void *)0)) {
1161 error = ENOMEM12;
1162 goto release;
1163 }
1164 }
1165#endif
1166
1167#ifdef INET61
1168 if (inp->inp_flags & INP_IPV60x100)
1169 error = udp6_output(inp, m, addr, control);
1170 else
1171#endif
1172 error = udp_output(inp, m, addr, control);
1173 return (error);
1174
1175 case PRU_ABORT10:
1176 soisdisconnected(so);
1177 in_pcbdetach(inp);
1178 break;
1179
1180 case PRU_SOCKADDR15:
1181#ifdef INET61
1182 if (inp->inp_flags & INP_IPV60x100)
1183 in6_setsockaddr(inp, addr);
1184 else
1185#endif /* INET6 */
1186 in_setsockaddr(inp, addr);
1187 break;
1188
1189 case PRU_PEERADDR16:
1190#ifdef INET61
1191 if (inp->inp_flags & INP_IPV60x100)
1192 in6_setpeeraddr(inp, addr);
1193 else
1194#endif /* INET6 */
1195 in_setpeeraddr(inp, addr);
1196 break;
1197
1198 case PRU_SENSE12:
1199 /*
1200 * stat: don't bother with a blocksize.
1201 */
1202 /*
1203 * Perhaps Path MTU might be returned for a connected
1204 * UDP socket in this case.
1205 */
1206 break;
1207
1208 case PRU_SENDOOB14:
1209 case PRU_FASTTIMO18:
1210 case PRU_SLOWTIMO19:
1211 case PRU_PROTORCV20:
1212 case PRU_PROTOSEND21:
1213 case PRU_RCVD8:
1214 case PRU_RCVOOB13:
1215 error = EOPNOTSUPP45;
1216 break;
1217
1218 default:
1219 panic("udp_usrreq");
1220 }
1221release:
1222 if (req != PRU_RCVD8 && req != PRU_RCVOOB13 && req != PRU_SENSE12) {
1223 m_freem(control);
1224 m_freem(m);
1225 }
1226 return (error);
1227}
1228
1229int
1230udp_attach(struct socket *so, int proto)
1231{
1232 int error;
1233
1234 if (so->so_pcb != NULL((void *)0))
1235 return EINVAL22;
1236
1237 if ((error = soreserve(so, udp_sendspace, udp_recvspace)))
1238 return error;
1239
1240 NET_ASSERT_LOCKED()do { int _s = rw_status(&netlock); if ((splassert_ctl >
0) && (_s != 0x0001UL && _s != 0x0002UL)) splassert_fail
(0x0002UL, _s, __func__); } while (0)
;
1241 if ((error = in_pcballoc(so, &udbtable)))
1242 return error;
1243#ifdef INET61
1244 if (sotoinpcb(so)((struct inpcb *)(so)->so_pcb)->inp_flags & INP_IPV60x100)
1245 sotoinpcb(so)((struct inpcb *)(so)->so_pcb)->inp_ipv6inp_hu.hu_ipv6.ip6_hlimip6_ctlun.ip6_un1.ip6_un1_hlim = ip6_defhlim;
1246 else
1247#endif /* INET6 */
1248 sotoinpcb(so)((struct inpcb *)(so)->so_pcb)->inp_ipinp_hu.hu_ip.ip_ttl = ip_defttl;
1249 return 0;
1250}
1251
1252int
1253udp_detach(struct socket *so)
1254{
1255 struct inpcb *inp;
1256
1257 soassertlocked(so);
1258
1259 inp = sotoinpcb(so)((struct inpcb *)(so)->so_pcb);
1260 if (inp == NULL((void *)0))
1261 return (EINVAL22);
1262
1263 in_pcbdetach(inp);
1264 return (0);
1265}
1266
1267/*
1268 * Sysctl for udp variables.
1269 */
1270int
1271udp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
1272 size_t newlen)
1273{
1274 int error;
1275
1276 /* All sysctl names at this level are terminal. */
1277 if (namelen != 1)
1278 return (ENOTDIR20);
1279
1280 switch (name[0]) {
1281 case UDPCTL_BADDYNAMIC2:
1282 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1283 error = sysctl_struct(oldp, oldlenp, newp, newlen,
1284 baddynamicports.udp, sizeof(baddynamicports.udp));
1285 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1286 return (error);
1287
1288 case UDPCTL_ROOTONLY6:
1289 if (newp && securelevel > 0)
1290 return (EPERM1);
1291 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1292 error = sysctl_struct(oldp, oldlenp, newp, newlen,
1293 rootonlyports.udp, sizeof(rootonlyports.udp));
1294 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1295 return (error);
1296
1297 case UDPCTL_STATS5:
1298 if (newp != NULL((void *)0))
1299 return (EPERM1);
1300
1301 return (udp_sysctl_udpstat(oldp, oldlenp, newp));
1302
1303 default:
1304 NET_LOCK()do { rw_enter_write(&netlock); } while (0);
1305 error = sysctl_bounded_arr(udpctl_vars, nitems(udpctl_vars)(sizeof((udpctl_vars)) / sizeof((udpctl_vars)[0])),
1306 name, namelen, oldp, oldlenp, newp, newlen);
1307 NET_UNLOCK()do { rw_exit_write(&netlock); } while (0);
1308 return (error);
1309 }
1310 /* NOTREACHED */
1311}
1312
1313int
1314udp_sysctl_udpstat(void *oldp, size_t *oldlenp, void *newp)
1315{
1316 uint64_t counters[udps_ncounters];
1317 struct udpstat udpstat;
1318 u_long *words = (u_long *)&udpstat;
1319 int i;
1320
1321 CTASSERT(sizeof(udpstat) == (nitems(counters) * sizeof(u_long)))extern char _ctassert[(sizeof(udpstat) == ((sizeof((counters)
) / sizeof((counters)[0])) * sizeof(u_long))) ? 1 : -1 ] __attribute__
((__unused__))
;
1322 memset(&udpstat, 0, sizeof udpstat)__builtin_memset((&udpstat), (0), (sizeof udpstat));
1323 counters_read(udpcounters, counters, nitems(counters)(sizeof((counters)) / sizeof((counters)[0])));
1324
1325 for (i = 0; i < nitems(counters)(sizeof((counters)) / sizeof((counters)[0])); i++)
1326 words[i] = (u_long)counters[i];
1327
1328 return (sysctl_rdstruct(oldp, oldlenp, newp,
1329 &udpstat, sizeof(udpstat)));
1330}