2  * Copyright (c) 2000-2007 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  29  * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995 
  30  *      The Regents of the University of California.  All rights reserved. 
  32  * Redistribution and use in source and binary forms, with or without 
  33  * modification, are permitted provided that the following conditions 
  35  * 1. Redistributions of source code must retain the above copyright 
  36  *    notice, this list of conditions and the following disclaimer. 
  37  * 2. Redistributions in binary form must reproduce the above copyright 
  38  *    notice, this list of conditions and the following disclaimer in the 
  39  *    documentation and/or other materials provided with the distribution. 
  40  * 3. All advertising materials mentioning features or use of this software 
  41  *    must display the following acknowledgement: 
  42  *      This product includes software developed by the University of 
  43  *      California, Berkeley and its contributors. 
  44  * 4. Neither the name of the University nor the names of its contributors 
  45  *    may be used to endorse or promote products derived from this software 
  46  *    without specific prior written permission. 
  48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  60  *      @(#)udp_usrreq.c        8.6 (Berkeley) 5/23/95 
  61  * $FreeBSD: src/sys/netinet/udp_usrreq.c,v 1.64.2.13 2001/08/08 18:59:54 ghelmer Exp $ 
  64 #include <sys/param.h> 
  65 #include <sys/systm.h> 
  66 #include <sys/kernel.h> 
  67 #include <sys/malloc.h> 
  69 #include <sys/domain.h> 
  70 #include <sys/protosw.h> 
  71 #include <sys/socket.h> 
  72 #include <sys/socketvar.h> 
  73 #include <sys/sysctl.h> 
  74 #include <sys/syslog.h> 
  76 #include <kern/zalloc.h> 
  79 #include <net/if_types.h> 
  80 #include <net/route.h> 
  82 #include <netinet/in.h> 
  83 #include <netinet/in_systm.h> 
  84 #include <netinet/ip.h> 
  86 #include <netinet/ip6.h> 
  88 #include <netinet/in_pcb.h> 
  89 #include <netinet/in_var.h> 
  90 #include <netinet/ip_var.h> 
  92 #include <netinet6/ip6_var.h> 
  94 #include <netinet/ip_icmp.h> 
  95 #include <netinet/icmp_var.h> 
  96 #include <netinet/udp.h> 
  97 #include <netinet/udp_var.h> 
  98 #include <sys/kdebug.h> 
 101 #include <netinet6/ipsec.h> 
 102 #include <netinet6/esp.h> 
 103 extern int ipsec_bypass
; 
 107 #define DBG_LAYER_IN_BEG        NETDBG_CODE(DBG_NETUDP, 0) 
 108 #define DBG_LAYER_IN_END        NETDBG_CODE(DBG_NETUDP, 2) 
 109 #define DBG_LAYER_OUT_BEG       NETDBG_CODE(DBG_NETUDP, 1) 
 110 #define DBG_LAYER_OUT_END       NETDBG_CODE(DBG_NETUDP, 3) 
 111 #define DBG_FNC_UDP_INPUT       NETDBG_CODE(DBG_NETUDP, (5 << 8)) 
 112 #define DBG_FNC_UDP_OUTPUT      NETDBG_CODE(DBG_NETUDP, (6 << 8) | 1) 
 115  * UDP protocol implementation. 
 116  * Per RFC 768, August, 1980. 
 119 static int      udpcksum 
= 1; 
 121 static int      udpcksum 
= 0;           /* XXX */ 
 123 SYSCTL_INT(_net_inet_udp
, UDPCTL_CHECKSUM
, checksum
, CTLFLAG_RW
, 
 126 static u_int32_t udps_in_sw_cksum
; 
 127 SYSCTL_UINT(_net_inet_udp
, OID_AUTO
, in_sw_cksum
, CTLFLAG_RD
, 
 128     &udps_in_sw_cksum
, 0, 
 129     "Number of received packets checksummed in software"); 
 131 static u_int64_t udps_in_sw_cksum_bytes
; 
 132 SYSCTL_QUAD(_net_inet_udp
, OID_AUTO
, in_sw_cksum_bytes
, CTLFLAG_RD
, 
 133     &udps_in_sw_cksum_bytes
, 
 134     "Amount of received data checksummed in software"); 
 136 static u_int32_t udps_out_sw_cksum
; 
 137 SYSCTL_UINT(_net_inet_udp
, OID_AUTO
, out_sw_cksum
, CTLFLAG_RD
, 
 138     &udps_out_sw_cksum
, 0, 
 139     "Number of transmitted packets checksummed in software"); 
 141 static u_int64_t udps_out_sw_cksum_bytes
; 
 142 SYSCTL_QUAD(_net_inet_udp
, OID_AUTO
, out_sw_cksum_bytes
, CTLFLAG_RD
, 
 143     &udps_out_sw_cksum_bytes
, 
 144     "Amount of transmitted data checksummed in software"); 
 147 SYSCTL_INT(_net_inet_udp
, OID_AUTO
, log_in_vain
, CTLFLAG_RW
,  
 148     &log_in_vain
, 0, "Log all incoming UDP packets"); 
 150 static int      blackhole 
= 0; 
 151 SYSCTL_INT(_net_inet_udp
, OID_AUTO
, blackhole
, CTLFLAG_RW
, 
 152         &blackhole
, 0, "Do not send port unreachables for refused connects"); 
 154 struct  inpcbhead udb
;          /* from udp_var.h */ 
 155 #define udb6    udb  /* for KAME src sync over BSD*'s */ 
 156 struct  inpcbinfo udbinfo
; 
 159 #define UDBHASHSIZE 16 
 162 extern  int     esp_udp_encap_port
; 
 163 extern  u_long  route_generation
; 
 165 extern  void    ipfwsyslog( int level
, const char *format
,...); 
 167 extern int fw_verbose
; 
 168 static int udp_gc_done 
= FALSE
; /* Garbage collection performed last slowtimo */ 
 171 #define log_in_vain_log( a ) {            \ 
 172         if ( (log_in_vain == 3 ) && (fw_verbose == 2)) {        /* Apple logging, log to ipfw.log */ \ 
 178 #define log_in_vain_log( a ) { log a; } 
 181 struct  udpstat udpstat
;        /* from udp_var.h */ 
 182 SYSCTL_STRUCT(_net_inet_udp
, UDPCTL_STATS
, stats
, CTLFLAG_RD
, 
 183     &udpstat
, udpstat
, "UDP statistics (struct udpstat, netinet/udp_var.h)"); 
 184 SYSCTL_INT(_net_inet_udp
, OID_AUTO
, pcbcount
, CTLFLAG_RD
,  
 185     &udbinfo
.ipi_count
, 0, "Number of active PCBs"); 
 189         struct sockaddr_in6     uin6_sin
; 
 190         u_char                  uin6_init_done 
: 1; 
 193         struct ip6_hdr          uip6_ip6
; 
 194         u_char                  uip6_init_done 
: 1; 
 196 static void ip_2_ip6_hdr(struct ip6_hdr 
*ip6
, struct ip 
*ip
); 
 197 static void udp_append(struct inpcb 
*last
, struct ip 
*ip
, 
 198     struct mbuf 
*n
, int off
, struct sockaddr_in 
*pudp_in
, 
 199     struct udp_in6 
*pudp_in6
, struct udp_ip6 
*pudp_ip6
); 
 201 static void udp_append(struct inpcb 
*last
, struct ip 
*ip
, 
 202     struct mbuf 
*n
, int off
, struct sockaddr_in 
*pudp_in
); 
 205 static int udp_detach(struct socket 
*so
); 
 206 static  int udp_output(struct inpcb 
*, struct mbuf 
*, struct sockaddr 
*, 
 207                             struct mbuf 
*, struct proc 
*); 
 208 extern int ChkAddressOK( __uint32_t dstaddr
, __uint32_t srcaddr 
); 
 214         struct inpcbinfo        
*pcbinfo
; 
 218         udbinfo
.listhead 
= &udb
; 
 219         udbinfo
.hashbase 
= hashinit(UDBHASHSIZE
, M_PCB
, &udbinfo
.hashmask
); 
 220         udbinfo
.porthashbase 
= hashinit(UDBHASHSIZE
, M_PCB
, 
 221                                         &udbinfo
.porthashmask
); 
 223         str_size 
= (vm_size_t
) sizeof(struct inpcb
); 
 224         udbinfo
.ipi_zone 
= (void *) zinit(str_size
, 80000*str_size
, 8192, "udpcb"); 
 228          * allocate lock group attribute and group for udp pcb mutexes 
 230         pcbinfo
->mtx_grp_attr 
= lck_grp_attr_alloc_init(); 
 232         pcbinfo
->mtx_grp 
= lck_grp_alloc_init("udppcb", pcbinfo
->mtx_grp_attr
); 
 234         pcbinfo
->mtx_attr 
= lck_attr_alloc_init(); 
 236         if ((pcbinfo
->mtx 
= lck_rw_alloc_init(pcbinfo
->mtx_grp
, pcbinfo
->mtx_attr
)) == NULL
) 
 237                 return; /* pretty much dead if this fails... */ 
 239         in_pcb_nat_init(&udbinfo
, AF_INET
, IPPROTO_UDP
, SOCK_DGRAM
); 
 241         udbinfo
.ipi_zone 
= zinit("udpcb", sizeof(struct inpcb
), maxsockets
, 
 246         /* for pcb sharing testing only */ 
 247         stat 
= in_pcb_new_share_client(&udbinfo
, &fake_owner
); 
 248         kprintf("udp_init in_pcb_new_share_client - stat = %d\n", stat
); 
 250         laddr
.s_addr 
= 0x11646464; 
 251         faddr
.s_addr 
= 0x11646465; 
 254         in_pcb_grab_port(&udbinfo
, 0, laddr
, &lport
, faddr
, 1600, 0, fake_owner
);  
 255         kprintf("udp_init in_pcb_grab_port - stat = %d\n", stat
); 
 257         stat 
= in_pcb_rem_share_client(&udbinfo
, fake_owner
); 
 258         kprintf("udp_init in_pcb_rem_share_client - stat = %d\n", stat
); 
 260         stat 
= in_pcb_new_share_client(&udbinfo
, &fake_owner
); 
 261         kprintf("udp_init in_pcb_new_share_client(2) - stat = %d\n", stat
); 
 263         laddr
.s_addr 
= 0x11646464; 
 264         faddr
.s_addr 
= 0x11646465; 
 267         stat 
= in_pcb_grab_port(&udbinfo
, 0, laddr
, &lport
, faddr
, 1600, 0, fake_owner
);  
 268         kprintf("udp_init in_pcb_grab_port(2) - stat = %d\n", stat
); 
 274         register struct mbuf 
*m
; 
 277         register struct ip 
*ip
; 
 278         register struct udphdr 
*uh
; 
 279         register struct inpcb 
*inp
; 
 280         struct mbuf 
*opts 
= 0; 
 283         struct sockaddr 
*append_sa
; 
 284         struct inpcbinfo 
*pcbinfo 
= &udbinfo
; 
 285         struct sockaddr_in udp_in 
= { 
 286                 sizeof (udp_in
), AF_INET
, 0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 } 
 289         struct udp_in6 udp_in6 
= { 
 290                 { sizeof (udp_in6
.uin6_sin
), AF_INET6
, 0, 0, 
 291                     IN6ADDR_ANY_INIT
, 0 }, 
 294         struct udp_ip6 udp_ip6
; 
 297         udpstat
.udps_ipackets
++; 
 299         KERNEL_DEBUG(DBG_FNC_UDP_INPUT 
| DBG_FUNC_START
, 0,0,0,0,0); 
 300         if (m
->m_pkthdr
.csum_flags 
& CSUM_TCP_SUM16
) 
 301                 m
->m_pkthdr
.csum_flags 
= 0; /* invalidate hwcksum for UDP */ 
 304          * Strip IP options, if any; should skip this, 
 305          * make available to user, and use on returned packets, 
 306          * but we don't yet have a way to check the checksum 
 307          * with options still present. 
 309         if (iphlen 
> sizeof (struct ip
)) { 
 310                 ip_stripoptions(m
, (struct mbuf 
*)0); 
 311                 iphlen 
= sizeof(struct ip
); 
 315          * Get IP and UDP header together in first mbuf. 
 317         ip 
= mtod(m
, struct ip 
*); 
 318         if (m
->m_len 
< iphlen 
+ sizeof(struct udphdr
)) { 
 319                 if ((m 
= m_pullup(m
, iphlen 
+ sizeof(struct udphdr
))) == 0) { 
 320                         udpstat
.udps_hdrops
++; 
 321                         KERNEL_DEBUG(DBG_FNC_UDP_INPUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
 324                 ip 
= mtod(m
, struct ip 
*); 
 326         uh 
= (struct udphdr 
*)((caddr_t
)ip 
+ iphlen
); 
 328         /* destination port of 0 is illegal, based on RFC768. */ 
 329         if (uh
->uh_dport 
== 0) 
 332         KERNEL_DEBUG(DBG_LAYER_IN_BEG
, uh
->uh_dport
, uh
->uh_sport
, 
 333                      ip
->ip_src
.s_addr
, ip
->ip_dst
.s_addr
, uh
->uh_ulen
); 
 336          * Make mbuf data length reflect UDP length. 
 337          * If not enough data to reflect UDP length, drop. 
 339         len 
= ntohs((u_short
)uh
->uh_ulen
); 
 340         if (ip
->ip_len 
!= len
) { 
 341                 if (len 
> ip
->ip_len 
|| len 
< sizeof(struct udphdr
)) { 
 342                         udpstat
.udps_badlen
++; 
 345                 m_adj(m
, len 
- ip
->ip_len
); 
 346                 /* ip->ip_len = len; */ 
 349          * Save a copy of the IP header in case we want restore it 
 350          * for sending an ICMP error message in response. 
 355          * Checksum extended UDP header and data. 
 358                 if (m
->m_pkthdr
.csum_flags 
& CSUM_DATA_VALID
) { 
 359                         if (m
->m_pkthdr
.csum_flags 
& CSUM_PSEUDO_HDR
) 
 360                                 uh
->uh_sum 
= m
->m_pkthdr
.csum_data
; 
 363                         uh
->uh_sum 
^= 0xffff; 
 367                         *(uint32_t*)&b
[0] = *(uint32_t*)&((struct ipovly 
*)ip
)->ih_x1
[0]; 
 368                         *(uint32_t*)&b
[4] = *(uint32_t*)&((struct ipovly 
*)ip
)->ih_x1
[4]; 
 369                         *(uint8_t*)&b
[8] = *(uint8_t*)&((struct ipovly 
*)ip
)->ih_x1
[8]; 
 371                         bzero(((struct ipovly 
*)ip
)->ih_x1
, 9); 
 372                         ((struct ipovly 
*)ip
)->ih_len 
= uh
->uh_ulen
; 
 373                         uh
->uh_sum 
= in_cksum(m
, len 
+ sizeof (struct ip
)); 
 375                         *(uint32_t*)&((struct ipovly 
*)ip
)->ih_x1
[0] = *(uint32_t*)&b
[0]; 
 376                         *(uint32_t*)&((struct ipovly 
*)ip
)->ih_x1
[4] = *(uint32_t*)&b
[4]; 
 377                         *(uint8_t*)&((struct ipovly 
*)ip
)->ih_x1
[8] = *(uint8_t*)&b
[8]; 
 378                         udp_in_cksum_stats(len
); 
 381                         udpstat
.udps_badsum
++; 
 383                         KERNEL_DEBUG(DBG_FNC_UDP_INPUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
 389                 udpstat
.udps_nosum
++; 
 392         if (IN_MULTICAST(ntohl(ip
->ip_dst
.s_addr
)) || 
 393             in_broadcast(ip
->ip_dst
, m
->m_pkthdr
.rcvif
)) { 
 395                 int reuse_sock 
= 0, mcast_delivered 
= 0; 
 396                 struct mbuf 
*n 
= NULL
; 
 398                 lck_rw_lock_shared(pcbinfo
->mtx
); 
 400                  * Deliver a multicast or broadcast datagram to *all* sockets 
 401                  * for which the local and remote addresses and ports match 
 402                  * those of the incoming datagram.  This allows more than 
 403                  * one process to receive multi/broadcasts on the same port. 
 404                  * (This really ought to be done for unicast datagrams as 
 405                  * well, but that would cause problems with existing 
 406                  * applications that open both address-specific sockets and 
 407                  * a wildcard socket listening to the same port -- they would 
 408                  * end up receiving duplicates of every unicast datagram. 
 409                  * Those applications open the multiple sockets to overcome an 
 410                  * inadequacy of the UDP socket interface, but for backwards 
 411                  * compatibility we avoid the problem here rather than 
 412                  * fixing the interface.  Maybe 4.5BSD will remedy this?) 
 417                  * Construct sockaddr format source address. 
 419                 udp_in
.sin_port 
= uh
->uh_sport
; 
 420                 udp_in
.sin_addr 
= ip
->ip_src
; 
 422                  * Locate pcb(s) for datagram. 
 423                  * (Algorithm copied from raw_intr().) 
 426                 udp_in6
.uin6_init_done 
= udp_ip6
.uip6_init_done 
= 0; 
 428                 LIST_FOREACH(inp
, &udb
, inp_list
) { 
 430                         /* Ignore nat/SharedIP dummy pcbs */ 
 431                         if (inp
->inp_socket 
== &udbinfo
.nat_dummy_socket
) 
 434                         if (inp
->inp_socket 
== NULL
)  
 436                         if (inp 
!= sotoinpcb(inp
->inp_socket
)) 
 437                                 panic("udp_input: bad so back ptr inp=%p\n", inp
); 
 439                         if ((inp
->inp_vflag 
& INP_IPV4
) == 0) 
 443                         if (in_pcb_checkstate(inp
, WNT_ACQUIRE
, 0) == WNT_STOPUSING
) { 
 447                         udp_lock(inp
->inp_socket
, 1, 0);         
 449                         if (in_pcb_checkstate(inp
, WNT_RELEASE
, 1) == WNT_STOPUSING
) { 
 450                                 udp_unlock(inp
->inp_socket
, 1, 0); 
 454                         if (inp
->inp_lport 
!= uh
->uh_dport
) { 
 455                                 udp_unlock(inp
->inp_socket
, 1, 0); 
 458                         if (inp
->inp_laddr
.s_addr 
!= INADDR_ANY
) { 
 459                                 if (inp
->inp_laddr
.s_addr 
!= 
 461                                         udp_unlock(inp
->inp_socket
, 1, 0); 
 465                         if (inp
->inp_faddr
.s_addr 
!= INADDR_ANY
) { 
 466                                 if (inp
->inp_faddr
.s_addr 
!= 
 468                                     inp
->inp_fport 
!= uh
->uh_sport
) { 
 469                                         udp_unlock(inp
->inp_socket
, 1, 0); 
 474                         reuse_sock 
= inp
->inp_socket
->so_options
& (SO_REUSEPORT
|SO_REUSEADDR
); 
 478                                 /* check AH/ESP integrity. */ 
 479                                 if (ipsec_bypass 
== 0) { 
 480                                         if (ipsec4_in_reject_so(m
, inp
->inp_socket
)) { 
 481                                                 IPSEC_STAT_INCREMENT(ipsecstat
.in_polvio
); 
 482                                                 /* do not inject data to pcb */ 
 490                                                 n 
= m_copy(m
, 0, M_COPYALL
); 
 492                                         udp_append(inp
, ip
, m
, 
 493                                             iphlen 
+ sizeof(struct udphdr
), 
 494                                             &udp_in
, &udp_in6
, &udp_ip6
); 
 496                                         udp_append(inp
, ip
, m
, 
 497                                             iphlen 
+ sizeof(struct udphdr
), 
 502                                 udp_unlock(inp
->inp_socket
, 1, 0); 
 505                          * Don't look for additional matches if this one does 
 506                          * not have either the SO_REUSEPORT or SO_REUSEADDR 
 507                          * socket options set.  This heuristic avoids searching 
 508                          * through all pcbs in the common case of a non-shared 
 509                          * port.  It assumes that an application will never 
 510                          * clear these options after setting them. 
 512                         if (reuse_sock 
== 0 || ((m 
= n
) == NULL
)) 
 515                 lck_rw_done(pcbinfo
->mtx
); 
 517                 if (mcast_delivered 
== 0) { 
 519                          * No matching pcb found; discard datagram. 
 520                          * (No need to send an ICMP Port Unreachable 
 521                          * for a broadcast or multicast datgram.) 
 523                         udpstat
.udps_noportbcast
++; 
 527                 if (reuse_sock 
!= 0)    /* free the extra copy of mbuf */ 
 534          * UDP to port 4500 with a payload where the first four bytes are 
 535          * not zero is a UDP encapsulated IPSec packet. Packets where 
 536          * the payload is one byte and that byte is 0xFF are NAT keepalive 
 537          * packets. Decapsulate the ESP packet and carry on with IPSec input 
 538          * or discard the NAT keep-alive. 
 540         if (ipsec_bypass 
== 0 && (esp_udp_encap_port 
& 0xFFFF) != 0 && 
 541                 uh
->uh_dport 
== ntohs((u_short
)esp_udp_encap_port
)) { 
 542                 int     payload_len 
= len 
- sizeof(struct udphdr
) > 4 ? 4 : len 
- sizeof(struct udphdr
); 
 543                 if (m
->m_len 
< iphlen 
+ sizeof(struct udphdr
) + payload_len
) { 
 544                         if ((m 
= m_pullup(m
, iphlen 
+ sizeof(struct udphdr
) + payload_len
)) == 0) { 
 545                                 udpstat
.udps_hdrops
++; 
 546                                 KERNEL_DEBUG(DBG_FNC_UDP_INPUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
 549                         ip 
= mtod(m
, struct ip 
*); 
 550                         uh 
= (struct udphdr 
*)((caddr_t
)ip 
+ iphlen
); 
 552                 /* Check for NAT keepalive packet */ 
 553                 if (payload_len 
== 1 && *(u_int8_t
*)((caddr_t
)uh 
+ sizeof(struct udphdr
)) == 0xFF) { 
 555                         KERNEL_DEBUG(DBG_FNC_UDP_INPUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
 558                 else if (payload_len 
== 4 && *(u_int32_t
*)((caddr_t
)uh 
+ sizeof(struct udphdr
)) != 0) { 
 559                         /* UDP encapsulated IPSec packet to pass through NAT */ 
 562                         stripsiz 
= sizeof(struct udphdr
); 
 564                         ip 
= mtod(m
, struct ip 
*); 
 565                         ovbcopy((caddr_t
)ip
, (caddr_t
)(((u_char 
*)ip
) + stripsiz
), iphlen
); 
 566                         m
->m_data 
+= stripsiz
; 
 567                         m
->m_len 
-= stripsiz
; 
 568                         m
->m_pkthdr
.len 
-= stripsiz
; 
 569                         ip 
= mtod(m
, struct ip 
*); 
 570                         ip
->ip_len 
= ip
->ip_len 
- stripsiz
; 
 571                         ip
->ip_p 
= IPPROTO_ESP
; 
 573                         KERNEL_DEBUG(DBG_FNC_UDP_INPUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
 574                         esp4_input(m
, iphlen
); 
 581          * Locate pcb for datagram. 
 583         inp 
= in_pcblookup_hash(&udbinfo
, ip
->ip_src
, uh
->uh_sport
, 
 584             ip
->ip_dst
, uh
->uh_dport
, 1, m
->m_pkthdr
.rcvif
); 
 587                         char buf
[MAX_IPv4_STR_LEN
]; 
 588                         char buf2
[MAX_IPv4_STR_LEN
]; 
 590                         /* check src and dst address */ 
 591                         if (log_in_vain 
!= 3) 
 593                                         "Connection attempt to UDP %s:%d from %s:%d\n", 
 594                                         inet_ntop(AF_INET
, &ip
->ip_dst
, buf
, sizeof(buf
)), 
 596                                         inet_ntop(AF_INET
, &ip
->ip_src
, buf2
, sizeof(buf2
)), 
 597                                         ntohs(uh
->uh_sport
)); 
 598                         else if (!(m
->m_flags 
& (M_BCAST 
| M_MCAST
)) && 
 599                                          ip
->ip_dst
.s_addr 
!= ip
->ip_src
.s_addr
) 
 600                                 log_in_vain_log((LOG_INFO
, 
 601                                         "Stealth Mode connection attempt to UDP %s:%d from %s:%d\n", 
 602                                         inet_ntop(AF_INET
, &ip
->ip_dst
, buf
, sizeof(buf
)), 
 604                                         inet_ntop(AF_INET
, &ip
->ip_src
, buf2
, sizeof(buf2
)), 
 605                                         ntohs(uh
->uh_sport
))) 
 607                 udpstat
.udps_noport
++; 
 608                 if (m
->m_flags 
& (M_BCAST 
| M_MCAST
)) { 
 609                         udpstat
.udps_noportbcast
++; 
 613                 if (badport_bandlim(BANDLIM_ICMP_UNREACH
) < 0) 
 617                         if (m
->m_pkthdr
.rcvif 
&& m
->m_pkthdr
.rcvif
->if_type 
!= IFT_LOOP
) 
 620                 ip
->ip_len 
+= iphlen
; 
 621                 icmp_error(m
, ICMP_UNREACH
, ICMP_UNREACH_PORT
, 0, 0); 
 622                 KERNEL_DEBUG(DBG_FNC_UDP_INPUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
 625         udp_lock(inp
->inp_socket
, 1, 0); 
 627         if (in_pcb_checkstate(inp
, WNT_RELEASE
, 1) == WNT_STOPUSING
) { 
 628                 udp_unlock(inp
->inp_socket
, 1, 0); 
 632         if (ipsec_bypass 
== 0 && inp 
!= NULL
) { 
 633                 if (ipsec4_in_reject_so(m
, inp
->inp_socket
)) { 
 634                         IPSEC_STAT_INCREMENT(ipsecstat
.in_polvio
); 
 635                         udp_unlock(inp
->inp_socket
, 1, 0); 
 642          * Construct sockaddr format source address. 
 643          * Stuff source address and datagram in user buffer. 
 645         udp_in
.sin_port 
= uh
->uh_sport
; 
 646         udp_in
.sin_addr 
= ip
->ip_src
; 
 647         if (inp
->inp_flags 
& INP_CONTROLOPTS
 
 648             || inp
->inp_socket
->so_options 
& SO_TIMESTAMP
) { 
 650                 if (inp
->inp_vflag 
& INP_IPV6
) { 
 653                         ip_2_ip6_hdr(&udp_ip6
.uip6_ip6
, ip
); 
 654                         savedflags 
= inp
->inp_flags
; 
 655                         inp
->inp_flags 
&= ~INP_UNMAPPABLEOPTS
; 
 656                         ip6_savecontrol(inp
, &opts
, &udp_ip6
.uip6_ip6
, m
); 
 657                         inp
->inp_flags 
= savedflags
; 
 660                 ip_savecontrol(inp
, &opts
, ip
, m
); 
 662         m_adj(m
, iphlen 
+ sizeof(struct udphdr
)); 
 664         KERNEL_DEBUG(DBG_LAYER_IN_END
, uh
->uh_dport
, uh
->uh_sport
, 
 665                      save_ip
.ip_src
.s_addr
, save_ip
.ip_dst
.s_addr
, uh
->uh_ulen
); 
 668         if (inp
->inp_vflag 
& INP_IPV6
) { 
 669                 in6_sin_2_v4mapsin6(&udp_in
, &udp_in6
.uin6_sin
); 
 670                 append_sa 
= (struct sockaddr 
*)&udp_in6
.uin6_sin
; 
 673         append_sa 
= (struct sockaddr 
*)&udp_in
; 
 674         if (sbappendaddr(&inp
->inp_socket
->so_rcv
, append_sa
, m
, opts
, NULL
) == 0) { 
 675                 udpstat
.udps_fullsock
++; 
 678                 sorwakeup(inp
->inp_socket
); 
 680         udp_unlock(inp
->inp_socket
, 1, 0); 
 681         KERNEL_DEBUG(DBG_FNC_UDP_INPUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
 687         KERNEL_DEBUG(DBG_FNC_UDP_INPUT 
| DBG_FUNC_END
, 0,0,0,0,0); 
 693 ip_2_ip6_hdr(ip6
, ip
) 
 697         bzero(ip6
, sizeof(*ip6
)); 
 699         ip6
->ip6_vfc 
= IPV6_VERSION
; 
 700         ip6
->ip6_plen 
= ip
->ip_len
; 
 701         ip6
->ip6_nxt 
= ip
->ip_p
; 
 702         ip6
->ip6_hlim 
= ip
->ip_ttl
; 
 703         ip6
->ip6_src
.s6_addr32
[2] = ip6
->ip6_dst
.s6_addr32
[2] = 
 705         ip6
->ip6_src
.s6_addr32
[3] = ip
->ip_src
.s_addr
; 
 706         ip6
->ip6_dst
.s6_addr32
[3] = ip
->ip_dst
.s_addr
; 
 711  * subroutine of udp_input(), mainly for source code readability. 
 715 udp_append(struct inpcb 
*last
, struct ip 
*ip
, struct mbuf 
*n
, int off
, 
 716     struct sockaddr_in 
*pudp_in
, struct udp_in6 
*pudp_in6
, 
 717     struct udp_ip6 
*pudp_ip6
) 
 719 udp_append(struct inpcb 
*last
, struct ip 
*ip
, struct mbuf 
*n
, int off
, 
 720     struct sockaddr_in 
*pudp_in
) 
 723         struct sockaddr 
*append_sa
; 
 724         struct mbuf 
*opts 
= 0; 
 727         if (mac_inpcb_check_deliver(last
, n
, AF_INET
, SOCK_DGRAM
) != 0) { 
 732         if (last
->inp_flags 
& INP_CONTROLOPTS 
|| 
 733             last
->inp_socket
->so_options 
& SO_TIMESTAMP
) { 
 735                 if (last
->inp_vflag 
& INP_IPV6
) { 
 738                         if (pudp_ip6
->uip6_init_done 
== 0) { 
 739                                 ip_2_ip6_hdr(&pudp_ip6
->uip6_ip6
, ip
); 
 740                                 pudp_ip6
->uip6_init_done 
= 1; 
 742                         savedflags 
= last
->inp_flags
; 
 743                         last
->inp_flags 
&= ~INP_UNMAPPABLEOPTS
; 
 744                         ip6_savecontrol(last
, &opts
, &pudp_ip6
->uip6_ip6
, n
); 
 745                         last
->inp_flags 
= savedflags
; 
 748                 ip_savecontrol(last
, &opts
, ip
, n
); 
 751         if (last
->inp_vflag 
& INP_IPV6
) { 
 752                 if (pudp_in6
->uin6_init_done 
== 0) { 
 753                         in6_sin_2_v4mapsin6(pudp_in
, &pudp_in6
->uin6_sin
); 
 754                         pudp_in6
->uin6_init_done 
= 1; 
 756                 append_sa 
= (struct sockaddr 
*)&pudp_in6
->uin6_sin
; 
 759         append_sa 
= (struct sockaddr 
*)pudp_in
; 
 761         if (sbappendaddr(&last
->inp_socket
->so_rcv
, append_sa
, n
, opts
, NULL
) == 0) { 
 762                 udpstat
.udps_fullsock
++; 
 764                 sorwakeup(last
->inp_socket
); 
 768  * Notify a udp user of an asynchronous error; 
 769  * just wake up so that he can collect error status. 
 772 udp_notify(inp
, errno
) 
 773         register struct inpcb 
*inp
; 
 776         inp
->inp_socket
->so_error 
= errno
; 
 777         sorwakeup(inp
->inp_socket
); 
 778         sowwakeup(inp
->inp_socket
); 
 782 udp_ctlinput(cmd
, sa
, vip
) 
 789         void (*notify
)(struct inpcb 
*, int) = udp_notify
; 
 790         struct in_addr faddr
; 
 793         faddr 
= ((struct sockaddr_in 
*)sa
)->sin_addr
; 
 794         if (sa
->sa_family 
!= AF_INET 
|| faddr
.s_addr 
== INADDR_ANY
) 
 797         if (PRC_IS_REDIRECT(cmd
)) { 
 799                 notify 
= in_rtchange
; 
 800         } else if (cmd 
== PRC_HOSTDEAD
) 
 802         else if ((unsigned)cmd 
>= PRC_NCMDS 
|| inetctlerrmap
[cmd
] == 0) 
 805                 uh 
= (struct udphdr 
*)((caddr_t
)ip 
+ (ip
->ip_hl 
<< 2)); 
 806                 inp 
= in_pcblookup_hash(&udbinfo
, faddr
, uh
->uh_dport
, 
 807                     ip
->ip_src
, uh
->uh_sport
, 0, NULL
); 
 808                 if (inp 
!= NULL 
&& inp
->inp_socket 
!= NULL
) { 
 809                         udp_lock(inp
->inp_socket
, 1, 0); 
 810                         if (in_pcb_checkstate(inp
, WNT_RELEASE
, 1) == WNT_STOPUSING
)  { 
 811                                 udp_unlock(inp
->inp_socket
, 1, 0); 
 814                         (*notify
)(inp
, inetctlerrmap
[cmd
]); 
 815                         udp_unlock(inp
->inp_socket
, 1, 0); 
 818                 in_pcbnotifyall(&udbinfo
, faddr
, inetctlerrmap
[cmd
], notify
); 
 822 udp_ctloutput(struct socket 
*so
, struct sockopt 
*sopt
) 
 827         if (sopt
->sopt_level 
!= IPPROTO_UDP
) 
 828                 return (ip_ctloutput(so
, sopt
)); 
 833         switch (sopt
->sopt_dir
) { 
 835                 switch (sopt
->sopt_name
) { 
 837                         /* This option is settable only for UDP over IPv4 */ 
 838                         if (!(inp
->inp_vflag 
& INP_IPV4
)) { 
 843                         if ((error 
= sooptcopyin(sopt
, &optval
, sizeof (optval
), 
 844                             sizeof (optval
))) != 0) 
 848                                 inp
->inp_flags 
|= INP_UDP_NOCKSUM
; 
 850                                 inp
->inp_flags 
&= ~INP_UDP_NOCKSUM
; 
 860                 switch (sopt
->sopt_name
) { 
 862                         optval 
= inp
->inp_flags 
& INP_UDP_NOCKSUM
; 
 870                         error 
= sooptcopyout(sopt
, &optval
, sizeof (optval
)); 
 877 udp_pcblist SYSCTL_HANDLER_ARGS
 
 879 #pragma unused(oidp, arg1, arg2) 
 881         struct inpcb 
*inp
, **inp_list
; 
 886          * The process of preparing the TCB list is too time-consuming and 
 887          * resource-intensive to repeat twice on every request. 
 889         lck_rw_lock_exclusive(udbinfo
.mtx
); 
 890         if (req
->oldptr 
== USER_ADDR_NULL
) { 
 891                 n 
= udbinfo
.ipi_count
; 
 892                 req
->oldidx 
= 2 * (sizeof xig
) 
 893                         + (n 
+ n
/8) * sizeof(struct xinpcb
); 
 894                 lck_rw_done(udbinfo
.mtx
); 
 898         if (req
->newptr 
!= USER_ADDR_NULL
) { 
 899                 lck_rw_done(udbinfo
.mtx
); 
 904          * OK, now we're committed to doing something. 
 906         gencnt 
= udbinfo
.ipi_gencnt
; 
 907         n 
= udbinfo
.ipi_count
; 
 909         bzero(&xig
, sizeof(xig
)); 
 910         xig
.xig_len 
= sizeof xig
; 
 912         xig
.xig_gen 
= gencnt
; 
 913         xig
.xig_sogen 
= so_gencnt
; 
 914         error 
= SYSCTL_OUT(req
, &xig
, sizeof xig
); 
 916                 lck_rw_done(udbinfo
.mtx
); 
 920      * We are done if there is no pcb 
 923         lck_rw_done(udbinfo
.mtx
); 
 927         inp_list 
= _MALLOC(n 
* sizeof *inp_list
, M_TEMP
, M_WAITOK
); 
 929                 lck_rw_done(udbinfo
.mtx
); 
 933         for (inp 
= LIST_FIRST(udbinfo
.listhead
), i 
= 0; inp 
&& i 
< n
; 
 934              inp 
= LIST_NEXT(inp
, inp_list
)) { 
 935                 if (inp
->inp_gencnt 
<= gencnt 
&& inp
->inp_state 
!= INPCB_STATE_DEAD
) 
 941         for (i 
= 0; i 
< n
; i
++) { 
 943                 if (inp
->inp_gencnt 
<= gencnt 
&& inp
->inp_state 
!= INPCB_STATE_DEAD
) { 
 946                         bzero(&xi
, sizeof(xi
)); 
 947                         xi
.xi_len 
= sizeof xi
; 
 948                         /* XXX should avoid extra copy */ 
 949                         inpcb_to_compat(inp
, &xi
.xi_inp
); 
 951                                 sotoxsocket(inp
->inp_socket
, &xi
.xi_socket
); 
 952                         error 
= SYSCTL_OUT(req
, &xi
, sizeof xi
); 
 957                  * Give the user an updated idea of our state. 
 958                  * If the generation differs from what we told 
 959                  * her before, she knows that something happened 
 960                  * while we were processing this request, and it 
 961                  * might be necessary to retry. 
 963                 bzero(&xig
, sizeof(xig
)); 
 964                 xig
.xig_len 
= sizeof xig
; 
 965                 xig
.xig_gen 
= udbinfo
.ipi_gencnt
; 
 966                 xig
.xig_sogen 
= so_gencnt
; 
 967                 xig
.xig_count 
= udbinfo
.ipi_count
; 
 968                 error 
= SYSCTL_OUT(req
, &xig
, sizeof xig
); 
 970         FREE(inp_list
, M_TEMP
); 
 971         lck_rw_done(udbinfo
.mtx
); 
 975 SYSCTL_PROC(_net_inet_udp
, UDPCTL_PCBLIST
, pcblist
, CTLFLAG_RD
, 0, 0, 
 976             udp_pcblist
, "S,xinpcb", "List of active UDP sockets"); 
 980 static __inline__ u_int16_t
 
 981 get_socket_id(struct socket 
* s
) 
 988         val 
= (u_int16_t
)(((u_int32_t
)s
) / sizeof(struct socket
)); 
 996 udp_output(inp
, m
, addr
, control
, p
) 
 997         register struct inpcb 
*inp
; 
 999         struct sockaddr 
*addr
; 
1000         struct mbuf 
*control
; 
1003         register struct udpiphdr 
*ui
; 
1004         register int len 
= m
->m_pkthdr
.len
; 
1005         struct sockaddr_in 
*sin
; 
1006         struct in_addr origladdr
, laddr
, faddr
; 
1007         u_short lport
, fport
; 
1008         struct sockaddr_in 
*ifaddr
; 
1009         int error 
= 0, udp_dodisconnect 
= 0; 
1010         struct socket 
*so 
= inp
->inp_socket
; 
1012         struct mbuf 
*inpopts
; 
1013         struct ip_moptions 
*mopts
; 
1016         KERNEL_DEBUG(DBG_FNC_UDP_OUTPUT 
| DBG_FUNC_START
, 0,0,0,0,0); 
1019                 m_freem(control
);               /* XXX */ 
1021         KERNEL_DEBUG(DBG_LAYER_OUT_BEG
, inp
->inp_fport
, inp
->inp_lport
, 
1022                      inp
->inp_laddr
.s_addr
, inp
->inp_faddr
.s_addr
, 
1023                      (htons((u_short
)len 
+ sizeof (struct udphdr
)))); 
1025         if (len 
+ sizeof(struct udpiphdr
) > IP_MAXPACKET
) { 
1030         /* If there was a routing change, discard cached route and check 
1031          * that we have a valid source address.  
1032          * Reacquire a new source address if INADDR_ANY was specified 
1036         lck_mtx_assert(inp
->inpcb_mtx
, LCK_MTX_ASSERT_OWNED
); 
1039         if (inp
->inp_route
.ro_rt 
&& inp
->inp_route
.ro_rt
->generation_id 
!= route_generation
) { 
1040                 if (ifa_foraddr(inp
->inp_laddr
.s_addr
) == 0) { /* src address is gone */ 
1041                         if (inp
->inp_flags 
& INP_INADDR_ANY
) 
1042                                 inp
->inp_laddr
.s_addr 
= INADDR_ANY
; /* new src will be set later */ 
1044                                 error 
= EADDRNOTAVAIL
; 
1048                 rtfree(inp
->inp_route
.ro_rt
); 
1049                 inp
->inp_route
.ro_rt 
= (struct rtentry 
*)0; 
1052         origladdr
= laddr 
= inp
->inp_laddr
; 
1053         faddr 
= inp
->inp_faddr
; 
1054         lport 
= inp
->inp_lport
; 
1055         fport 
= inp
->inp_fport
; 
1058                 sin 
= (struct sockaddr_in 
*)addr
; 
1059                 if (faddr
.s_addr 
!= INADDR_ANY
) { 
1065                          * In case we don't have a local port set, go through the full connect. 
1066                          * We don't have a local port yet (ie, we can't be looked up), 
1067                          * so it's not an issue if the input runs at the same time we do this. 
1069                         error 
= in_pcbconnect(inp
, addr
, p
); 
1073                         laddr 
= inp
->inp_laddr
; 
1074                         lport 
= inp
->inp_lport
; 
1075                         faddr 
= inp
->inp_faddr
; 
1076                         fport 
= inp
->inp_fport
; 
1077                         udp_dodisconnect 
= 1; 
1081                          * we have a full address and a local port. 
1082                          * use those info to build the packet without changing the pcb 
1083                          * and interfering with the input path. See 3851370 
1085                         if (laddr
.s_addr 
== INADDR_ANY
) { 
1086                            if ((error 
= in_pcbladdr(inp
, addr
, &ifaddr
)) != 0) 
1088                            laddr 
= ifaddr
->sin_addr
; 
1089                            inp
->inp_flags 
|= INP_INADDR_ANY
; /* from pcbconnect: remember we don't care about src addr.*/ 
1092                         faddr 
= sin
->sin_addr
; 
1093                         fport 
= sin
->sin_port
; 
1096                 if (faddr
.s_addr 
== INADDR_ANY
) { 
1103         mac_mbuf_label_associate_inpcb(inp
, m
); 
1108          * Calculate data length and get a mbuf 
1109          * for UDP and IP headers. 
1111         M_PREPEND(m
, sizeof(struct udpiphdr
), M_DONTWAIT
); 
1118          * Fill in mbuf with extended UDP header 
1119          * and addresses and length put into network format. 
1121         ui 
= mtod(m
, struct udpiphdr 
*); 
1122         bzero(ui
->ui_x1
, sizeof(ui
->ui_x1
));    /* XXX still needed? */ 
1123         ui
->ui_pr 
= IPPROTO_UDP
; 
1126         ui
->ui_sport 
= lport
; 
1127         ui
->ui_dport 
= fport
; 
1128         ui
->ui_ulen 
= htons((u_short
)len 
+ sizeof(struct udphdr
)); 
1131          * Set up checksum and output datagram. 
1133         if (udpcksum 
&& !(inp
->inp_flags 
& INP_UDP_NOCKSUM
)) { 
1134                 ui
->ui_sum 
= in_pseudo(ui
->ui_src
.s_addr
, ui
->ui_dst
.s_addr
, 
1135                     htons((u_short
)len 
+ sizeof(struct udphdr
) + IPPROTO_UDP
)); 
1136                 m
->m_pkthdr
.csum_flags 
= CSUM_UDP
; 
1137                 m
->m_pkthdr
.csum_data 
= offsetof(struct udphdr
, uh_sum
); 
1141         ((struct ip 
*)ui
)->ip_len 
= sizeof (struct udpiphdr
) + len
; 
1142         ((struct ip 
*)ui
)->ip_ttl 
= inp
->inp_ip_ttl
;    /* XXX */ 
1143         ((struct ip 
*)ui
)->ip_tos 
= inp
->inp_ip_tos
;    /* XXX */ 
1144         udpstat
.udps_opackets
++; 
1146         KERNEL_DEBUG(DBG_LAYER_OUT_END
, ui
->ui_dport
, ui
->ui_sport
, 
1147                      ui
->ui_src
.s_addr
, ui
->ui_dst
.s_addr
, ui
->ui_ulen
); 
1150         if (ipsec_bypass 
== 0 && ipsec_setsocket(m
, inp
->inp_socket
) != 0) { 
1155         m
->m_pkthdr
.socket_id 
= get_socket_id(inp
->inp_socket
); 
1157         inpopts 
= inp
->inp_options
; 
1158         soopts 
= (inp
->inp_socket
->so_options 
& (SO_DONTROUTE 
| SO_BROADCAST
)); 
1159         mopts 
= inp
->inp_moptions
; 
1161         /* We don't want to cache the route for non-connected UDP */ 
1162         if (udp_dodisconnect
) { 
1163                 bcopy(&inp
->inp_route
, &ro
, sizeof (ro
)); 
1167         socket_unlock(so
, 0); 
1168         /* XXX jgraessley please look at XXX */ 
1169         error 
= ip_output_list(m
, 0, inpopts
, 
1170             udp_dodisconnect 
? &ro 
: &inp
->inp_route
, soopts
, mopts
, NULL
); 
1173         if (udp_dodisconnect
) { 
1174                 /* Discard the cached route, if there is one */ 
1175                 if (ro
.ro_rt 
!= NULL
) 
1177                 in_pcbdisconnect(inp
); 
1178                 inp
->inp_laddr 
= origladdr
;     /* XXX rehash? */ 
1180         KERNEL_DEBUG(DBG_FNC_UDP_OUTPUT 
| DBG_FUNC_END
, error
, 0,0,0,0); 
1184         if (udp_dodisconnect
) { 
1185                 in_pcbdisconnect(inp
); 
1186                 inp
->inp_laddr 
= origladdr
; /* XXX rehash? */ 
1191         KERNEL_DEBUG(DBG_FNC_UDP_OUTPUT 
| DBG_FUNC_END
, error
, 0,0,0,0); 
1195 u_long  udp_sendspace 
= 9216;           /* really max datagram size */ 
1196                                         /* 40 1K datagrams */ 
1197 SYSCTL_INT(_net_inet_udp
, UDPCTL_MAXDGRAM
, maxdgram
, CTLFLAG_RW
, 
1198     &udp_sendspace
, 0, "Maximum outgoing UDP datagram size"); 
1200 u_long  udp_recvspace 
= 40 * (1024 + 
1202                                       sizeof(struct sockaddr_in6
) 
1204                                       sizeof(struct sockaddr_in
) 
1207 SYSCTL_INT(_net_inet_udp
, UDPCTL_RECVSPACE
, recvspace
, CTLFLAG_RW
, 
1208     &udp_recvspace
, 0, "Maximum incoming UDP datagram size"); 
1211 udp_abort(struct socket 
*so
) 
1215         inp 
= sotoinpcb(so
); 
1217                 panic("udp_abort: so=%p null inp\n", so
);       /* ??? possible? panic instead? */ 
1218         soisdisconnected(so
); 
1224 udp_attach(struct socket 
*so
, __unused 
int proto
, struct proc 
*p
) 
1229         inp 
= sotoinpcb(so
); 
1231                 panic ("udp_attach so=%p inp=%p\n", so
, inp
); 
1233         error 
= in_pcballoc(so
, &udbinfo
, p
); 
1236         error 
= soreserve(so
, udp_sendspace
, udp_recvspace
); 
1239         inp 
= (struct inpcb 
*)so
->so_pcb
; 
1240         inp
->inp_vflag 
|= INP_IPV4
; 
1241         inp
->inp_ip_ttl 
= ip_defttl
; 
1246 udp_bind(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
1251         if (nam
->sa_family 
!= 0 && nam
->sa_family 
!= AF_INET
 
1252             && nam
->sa_family 
!= AF_INET6
) { 
1253                 return EAFNOSUPPORT
; 
1255         inp 
= sotoinpcb(so
); 
1258         error 
= in_pcbbind(inp
, nam
, p
); 
1263 udp_connect(struct socket 
*so
, struct sockaddr 
*nam
, struct proc 
*p
) 
1268         inp 
= sotoinpcb(so
); 
1271         if (inp
->inp_faddr
.s_addr 
!= INADDR_ANY
) 
1273         error 
= in_pcbconnect(inp
, nam
, p
); 
1280 udp_detach(struct socket 
*so
) 
1284         inp 
= sotoinpcb(so
); 
1286                 panic("udp_detach: so=%p null inp\n", so
);      /* ??? possible? panic instead? */ 
1288         inp
->inp_state 
= INPCB_STATE_DEAD
; 
1293 udp_disconnect(struct socket 
*so
) 
1297         inp 
= sotoinpcb(so
); 
1300         if (inp
->inp_faddr
.s_addr 
== INADDR_ANY
) 
1303         in_pcbdisconnect(inp
); 
1304         inp
->inp_laddr
.s_addr 
= INADDR_ANY
; 
1305         so
->so_state 
&= ~SS_ISCONNECTED
;                /* XXX */ 
1310 udp_send(struct socket 
*so
, __unused 
int flags
, struct mbuf 
*m
, struct sockaddr 
*addr
, 
1311             struct mbuf 
*control
, struct proc 
*p
) 
1315         inp 
= sotoinpcb(so
); 
1320         return udp_output(inp
, m
, addr
, control
, p
); 
1324 udp_shutdown(struct socket 
*so
) 
1328         inp 
= sotoinpcb(so
); 
1335 struct pr_usrreqs udp_usrreqs 
= { 
1336         udp_abort
, pru_accept_notsupp
, udp_attach
, udp_bind
, udp_connect
,  
1337         pru_connect2_notsupp
, in_control
, udp_detach
, udp_disconnect
,  
1338         pru_listen_notsupp
, in_setpeeraddr
, pru_rcvd_notsupp
,  
1339         pru_rcvoob_notsupp
, udp_send
, pru_sense_null
, udp_shutdown
, 
1340         in_setsockaddr
, sosend
, soreceive
, pru_sopoll_notsupp
 
1345 udp_lock(struct socket 
*so
, int refcount
, int debug
) 
1349                 lr_saved 
= (unsigned int) __builtin_return_address(0); 
1350         else lr_saved 
= debug
; 
1353                 lck_mtx_assert(((struct inpcb 
*)so
->so_pcb
)->inpcb_mtx
, LCK_MTX_ASSERT_NOTOWNED
); 
1354                 lck_mtx_lock(((struct inpcb 
*)so
->so_pcb
)->inpcb_mtx
); 
1357                 panic("udp_lock: so=%p NO PCB! lr=%x\n", so
, lr_saved
); 
1362         so
->lock_lr
[so
->next_lock_lr
] = (u_int32_t
)lr_saved
; 
1363         so
->next_lock_lr 
= (so
->next_lock_lr
+1) % SO_LCKDBG_MAX
; 
1368 udp_unlock(struct socket 
*so
, int refcount
, int debug
) 
1373                 lr_saved 
= (unsigned int) __builtin_return_address(0); 
1374         else lr_saved 
= debug
; 
1380                         struct inpcb 
*inp 
= sotoinpcb(so
); 
1381                     struct inpcbinfo 
*pcbinfo   
= &udbinfo
; 
1383                         if (so
->so_usecount 
== 0 && (inp
->inp_wantcnt 
== WNT_STOPUSING
)) { 
1385                                 if (lck_rw_try_lock_exclusive(pcbinfo
->mtx
)) { 
1387                                         lck_rw_done(pcbinfo
->mtx
); 
1394         if (so
->so_pcb 
== NULL
)  
1395                 panic("udp_unlock: so=%p NO PCB! lr=%x\n", so
, lr_saved
); 
1397                 lck_mtx_assert(((struct inpcb 
*)so
->so_pcb
)->inpcb_mtx
, LCK_MTX_ASSERT_OWNED
); 
1398                 so
->unlock_lr
[so
->next_unlock_lr
] = (u_int32_t
)lr_saved
; 
1399                 so
->next_unlock_lr 
= (so
->next_unlock_lr
+1) % SO_LCKDBG_MAX
; 
1400                 lck_mtx_unlock(((struct inpcb 
*)so
->so_pcb
)->inpcb_mtx
); 
1408 udp_getlock(struct socket 
*so
, __unused 
int locktype
) 
1410         struct inpcb 
*inp 
= sotoinpcb(so
); 
1414                 return(inp
->inpcb_mtx
); 
1416                 panic("udp_getlock: so=%p NULL so_pcb\n", so
); 
1417                 return (so
->so_proto
->pr_domain
->dom_mtx
); 
1424         struct inpcb 
*inp
, *inpnxt
; 
1426         struct inpcbinfo 
*pcbinfo       
= &udbinfo
; 
1428         if (lck_rw_try_lock_exclusive(pcbinfo
->mtx
) == FALSE
) { 
1429                 if (udp_gc_done 
== TRUE
) { 
1430                         udp_gc_done 
= FALSE
; 
1431                         return; /* couldn't get the lock, better lock next time */ 
1433                 lck_rw_lock_exclusive(pcbinfo
->mtx
); 
1438         for (inp 
= udb
.lh_first
; inp 
!= NULL
; inp 
= inpnxt
) { 
1439                 inpnxt 
= inp
->inp_list
.le_next
; 
1441                 /* Ignore nat/SharedIP dummy pcbs */ 
1442                 if (inp
->inp_socket 
== &udbinfo
.nat_dummy_socket
) 
1445                 if (inp
->inp_wantcnt 
!= WNT_STOPUSING
)  
1448                 so 
= inp
->inp_socket
; 
1449                 if (!lck_mtx_try_lock(inp
->inpcb_mtx
))  /* skip if busy, no hurry for cleanup... */ 
1452                 if (so
->so_usecount 
== 0) 
1455                         lck_mtx_unlock(inp
->inpcb_mtx
); 
1457         lck_rw_done(pcbinfo
->mtx
); 
1461 ChkAddressOK( __uint32_t dstaddr
, __uint32_t srcaddr 
) 
1463         if ( dstaddr 
== srcaddr 
){ 
1470 udp_in_cksum_stats(u_int32_t len
) 
1473         udps_in_sw_cksum_bytes 
+= len
; 
1477 udp_out_cksum_stats(u_int32_t len
) 
1479         udps_out_sw_cksum
++; 
1480         udps_out_sw_cksum_bytes 
+= len
;