Bug Summary

File:netinet/udp_usrreq.c
Warning:line 444, column 30
Access to field 'ip_ttl' results in a dereference of a null pointer (loaded from variable 'ip')

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