LCOV - code coverage report
Current view: top level - netinet - udp_usrreq.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 560 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: udp_usrreq.c,v 1.251 2018/09/13 19:53:58 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 IPSEC
      95             : #include <netinet/ip_ipsp.h>
      96             : #include <netinet/ip_esp.h>
      97             : #endif
      98             : 
      99             : #ifdef INET6
     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 NPF > 0
     107             : #include <net/pfvar.h>
     108             : #endif
     109             : 
     110             : #ifdef PIPEX 
     111             : #include <netinet/if_ether.h>
     112             : #include <net/pipex.h>
     113             : #endif
     114             : 
     115             : #include "vxlan.h"
     116             : #if NVXLAN > 0
     117             : #include <net/if_vxlan.h>
     118             : #endif
     119             : 
     120             : /*
     121             :  * UDP protocol implementation.
     122             :  * Per RFC 768, August, 1980.
     123             :  */
     124             : int     udpcksum = 1;
     125             : 
     126             : u_int   udp_sendspace = 9216;           /* really max datagram size */
     127             : u_int   udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
     128             :                                         /* 40 1K datagrams */
     129             : 
     130             : int *udpctl_vars[UDPCTL_MAXID] = UDPCTL_VARS;
     131             : 
     132             : struct  inpcbtable udbtable;
     133             : struct  cpumem *udpcounters;
     134             : 
     135             : void    udp_sbappend(struct inpcb *, struct mbuf *, struct ip *,
     136             :             struct ip6_hdr *, int, struct udphdr *, struct sockaddr *,
     137             :             u_int32_t);
     138             : int     udp_output(struct inpcb *, struct mbuf *, struct mbuf *, struct mbuf *);
     139             : void    udp_notify(struct inpcb *, int);
     140             : int     udp_sysctl_udpstat(void *, size_t *, void *);
     141             : 
     142             : #ifndef UDB_INITIAL_HASH_SIZE
     143             : #define UDB_INITIAL_HASH_SIZE   128
     144             : #endif
     145             : 
     146             : void
     147           0 : udp_init(void)
     148             : {
     149           0 :         udpcounters = counters_alloc(udps_ncounters);
     150           0 :         in_pcbinit(&udbtable, UDB_INITIAL_HASH_SIZE);
     151           0 : }
     152             : 
     153             : int
     154           0 : udp_input(struct mbuf **mp, int *offp, int proto, int af)
     155             : {
     156           0 :         struct mbuf *m = *mp;
     157           0 :         int iphlen = *offp;
     158             :         struct ip *ip = NULL;
     159             :         struct udphdr *uh;
     160             :         struct inpcb *inp = NULL;
     161           0 :         struct ip save_ip;
     162             :         int len;
     163             :         u_int16_t savesum;
     164           0 :         union {
     165             :                 struct sockaddr sa;
     166             :                 struct sockaddr_in sin;
     167             : #ifdef INET6
     168             :                 struct sockaddr_in6 sin6;
     169             : #endif /* INET6 */
     170             :         } srcsa, dstsa;
     171             :         struct ip6_hdr *ip6 = NULL;
     172             : #ifdef IPSEC
     173             :         struct m_tag *mtag;
     174             :         struct tdb_ident *tdbi;
     175             :         struct tdb *tdb;
     176           0 :         int error, protoff;
     177             : #endif /* IPSEC */
     178             :         u_int32_t ipsecflowinfo = 0;
     179             : 
     180           0 :         udpstat_inc(udps_ipackets);
     181             : 
     182           0 :         IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr));
     183           0 :         if (!uh) {
     184           0 :                 udpstat_inc(udps_hdrops);
     185           0 :                 return IPPROTO_DONE;
     186             :         }
     187             : 
     188             :         /* Check for illegal destination port 0 */
     189           0 :         if (uh->uh_dport == 0) {
     190           0 :                 udpstat_inc(udps_noport);
     191           0 :                 goto bad;
     192             :         }
     193             : 
     194             :         /*
     195             :          * Make mbuf data length reflect UDP length.
     196             :          * If not enough data to reflect UDP length, drop.
     197             :          */
     198           0 :         len = ntohs((u_int16_t)uh->uh_ulen);
     199           0 :         switch (af) {
     200             :         case AF_INET:
     201           0 :                 if (m->m_pkthdr.len - iphlen != len) {
     202           0 :                         if (len > (m->m_pkthdr.len - iphlen) ||
     203           0 :                             len < sizeof(struct udphdr)) {
     204           0 :                                 udpstat_inc(udps_badlen);
     205           0 :                                 goto bad;
     206             :                         }
     207           0 :                         m_adj(m, len - (m->m_pkthdr.len - iphlen));
     208           0 :                 }
     209           0 :                 ip = mtod(m, struct ip *);
     210             :                 /*
     211             :                  * Save a copy of the IP header in case we want restore it
     212             :                  * for sending an ICMP error message in response.
     213             :                  */
     214           0 :                 save_ip = *ip;
     215           0 :                 break;
     216             : #ifdef INET6
     217             :         case AF_INET6:
     218             :                 /* jumbograms */
     219           0 :                 if (len == 0 && m->m_pkthdr.len - iphlen > 0xffff)
     220           0 :                         len = m->m_pkthdr.len - iphlen;
     221           0 :                 if (len != m->m_pkthdr.len - iphlen) {
     222           0 :                         udpstat_inc(udps_badlen);
     223           0 :                         goto bad;
     224             :                 }
     225           0 :                 ip6 = mtod(m, struct ip6_hdr *);
     226           0 :                 break;
     227             : #endif /* INET6 */
     228             :         default:
     229           0 :                 unhandled_af(af);
     230             :         }
     231             : 
     232             :         /*
     233             :          * Checksum extended UDP header and data.
     234             :          * from W.R.Stevens: check incoming udp cksums even if
     235             :          *      udpcksum is not set.
     236             :          */
     237           0 :         savesum = uh->uh_sum;
     238           0 :         if (uh->uh_sum == 0) {
     239           0 :                 udpstat_inc(udps_nosum);
     240             : #ifdef INET6
     241             :                 /*
     242             :                  * In IPv6, the UDP checksum is ALWAYS used.
     243             :                  */
     244           0 :                 if (ip6)
     245             :                         goto bad;
     246             : #endif /* INET6 */
     247             :         } else {
     248           0 :                 if ((m->m_pkthdr.csum_flags & M_UDP_CSUM_IN_OK) == 0) {
     249           0 :                         if (m->m_pkthdr.csum_flags & M_UDP_CSUM_IN_BAD) {
     250           0 :                                 udpstat_inc(udps_badsum);
     251           0 :                                 goto bad;
     252             :                         }
     253           0 :                         udpstat_inc(udps_inswcsum);
     254             : 
     255           0 :                         if (ip)
     256           0 :                                 uh->uh_sum = in4_cksum(m, IPPROTO_UDP,
     257             :                                     iphlen, len);
     258             : #ifdef INET6
     259           0 :                         else if (ip6)
     260           0 :                                 uh->uh_sum = in6_cksum(m, IPPROTO_UDP,
     261             :                                     iphlen, len);
     262             : #endif /* INET6 */
     263           0 :                         if (uh->uh_sum != 0) {
     264           0 :                                 udpstat_inc(udps_badsum);
     265           0 :                                 goto bad;
     266             :                         }
     267             :                 }
     268             :         }
     269             : 
     270             : #ifdef IPSEC
     271           0 :         if (udpencap_enable && udpencap_port && esp_enable &&
     272             : #if NPF > 0
     273           0 :             !(m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) &&
     274             : #endif
     275           0 :             uh->uh_dport == htons(udpencap_port)) {
     276           0 :                 u_int32_t spi;
     277           0 :                 int skip = iphlen + sizeof(struct udphdr);
     278             : 
     279           0 :                 if (m->m_pkthdr.len - skip < sizeof(u_int32_t)) {
     280             :                         /* packet too short */
     281           0 :                         m_freem(m);
     282           0 :                         return IPPROTO_DONE;
     283             :                 }
     284           0 :                 m_copydata(m, skip, sizeof(u_int32_t), (caddr_t) &spi);
     285             :                 /*
     286             :                  * decapsulate if the SPI is not zero, otherwise pass
     287             :                  * to userland
     288             :                  */
     289           0 :                 if (spi != 0) {
     290           0 :                         if ((m = *mp = m_pullup(m, skip)) == NULL) {
     291           0 :                                 udpstat_inc(udps_hdrops);
     292           0 :                                 return IPPROTO_DONE;
     293             :                         }
     294             : 
     295             :                         /* remove the UDP header */
     296           0 :                         bcopy(mtod(m, u_char *),
     297           0 :                             mtod(m, u_char *) + sizeof(struct udphdr), iphlen);
     298           0 :                         m_adj(m, sizeof(struct udphdr));
     299           0 :                         skip -= sizeof(struct udphdr);
     300             : 
     301           0 :                         espstat_inc(esps_udpencin);
     302           0 :                         protoff = af == AF_INET ? offsetof(struct ip, ip_p) :
     303             :                             offsetof(struct ip6_hdr, ip6_nxt);
     304           0 :                         ipsec_common_input(m, skip, protoff,
     305             :                             af, IPPROTO_ESP, 1);
     306           0 :                         return IPPROTO_DONE;
     307             :                 }
     308           0 :         }
     309             : #endif
     310             : 
     311           0 :         switch (af) {
     312             :         case AF_INET:
     313           0 :                 bzero(&srcsa, sizeof(struct sockaddr_in));
     314           0 :                 srcsa.sin.sin_len = sizeof(struct sockaddr_in);
     315           0 :                 srcsa.sin.sin_family = AF_INET;
     316           0 :                 srcsa.sin.sin_port = uh->uh_sport;
     317           0 :                 srcsa.sin.sin_addr = ip->ip_src;
     318             : 
     319           0 :                 bzero(&dstsa, sizeof(struct sockaddr_in));
     320           0 :                 dstsa.sin.sin_len = sizeof(struct sockaddr_in);
     321           0 :                 dstsa.sin.sin_family = AF_INET;
     322           0 :                 dstsa.sin.sin_port = uh->uh_dport;
     323           0 :                 dstsa.sin.sin_addr = ip->ip_dst;
     324           0 :                 break;
     325             : #ifdef INET6
     326             :         case AF_INET6:
     327           0 :                 bzero(&srcsa, sizeof(struct sockaddr_in6));
     328           0 :                 srcsa.sin6.sin6_len = sizeof(struct sockaddr_in6);
     329           0 :                 srcsa.sin6.sin6_family = AF_INET6;
     330           0 :                 srcsa.sin6.sin6_port = uh->uh_sport;
     331             : #if 0 /*XXX inbound flowinfo */
     332             :                 srcsa.sin6.sin6_flowinfo = htonl(0x0fffffff) & ip6->ip6_flow;
     333             : #endif
     334             :                 /* KAME hack: recover scopeid */
     335           0 :                 in6_recoverscope(&srcsa.sin6, &ip6->ip6_src);
     336             : 
     337           0 :                 bzero(&dstsa, sizeof(struct sockaddr_in6));
     338           0 :                 dstsa.sin6.sin6_len = sizeof(struct sockaddr_in6);
     339           0 :                 dstsa.sin6.sin6_family = AF_INET6;
     340           0 :                 dstsa.sin6.sin6_port = uh->uh_dport;
     341             : #if 0 /*XXX inbound flowinfo */
     342             :                 dstsa.sin6.sin6_flowinfo = htonl(0x0fffffff) & ip6->ip6_flow;
     343             : #endif
     344             :                 /* KAME hack: recover scopeid */
     345           0 :                 in6_recoverscope(&dstsa.sin6, &ip6->ip6_dst);
     346           0 :                 break;
     347             : #endif /* INET6 */
     348             :         }
     349             : 
     350             : #if NVXLAN > 0
     351           0 :         if (vxlan_enable > 0 &&
     352             : #if NPF > 0
     353           0 :             !(m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) &&
     354             : #endif
     355           0 :             vxlan_lookup(m, uh, iphlen, &srcsa.sa, &dstsa.sa) != 0)
     356           0 :                 return IPPROTO_DONE;
     357             : #endif
     358             : 
     359           0 :         if (m->m_flags & (M_BCAST|M_MCAST)) {
     360             :                 struct inpcb *last;
     361             :                 /*
     362             :                  * Deliver a multicast or broadcast datagram to *all* sockets
     363             :                  * for which the local and remote addresses and ports match
     364             :                  * those of the incoming datagram.  This allows more than
     365             :                  * one process to receive multi/broadcasts on the same port.
     366             :                  * (This really ought to be done for unicast datagrams as
     367             :                  * well, but that would cause problems with existing
     368             :                  * applications that open both address-specific sockets and
     369             :                  * a wildcard socket listening to the same port -- they would
     370             :                  * end up receiving duplicates of every unicast datagram.
     371             :                  * Those applications open the multiple sockets to overcome an
     372             :                  * inadequacy of the UDP socket interface, but for backwards
     373             :                  * compatibility we avoid the problem here rather than
     374             :                  * fixing the interface.  Maybe 4.5BSD will remedy this?)
     375             :                  */
     376             : 
     377             :                 /*
     378             :                  * Locate pcb(s) for datagram.
     379             :                  * (Algorithm copied from raw_intr().)
     380             :                  */
     381             :                 last = NULL;
     382           0 :                 NET_ASSERT_LOCKED();
     383           0 :                 TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue) {
     384           0 :                         if (inp->inp_socket->so_state & SS_CANTRCVMORE)
     385             :                                 continue;
     386             : #ifdef INET6
     387             :                         /* don't accept it if AF does not match */
     388           0 :                         if (ip6 && !(inp->inp_flags & INP_IPV6))
     389             :                                 continue;
     390           0 :                         if (!ip6 && (inp->inp_flags & INP_IPV6))
     391             :                                 continue;
     392             : #endif
     393           0 :                         if (rtable_l2(inp->inp_rtableid) !=
     394           0 :                             rtable_l2(m->m_pkthdr.ph_rtableid))
     395             :                                 continue;
     396           0 :                         if (inp->inp_lport != uh->uh_dport)
     397             :                                 continue;
     398             : #ifdef INET6
     399           0 :                         if (ip6) {
     400           0 :                                 if (inp->inp_ip6_minhlim &&
     401           0 :                                     inp->inp_ip6_minhlim > ip6->ip6_hlim)
     402             :                                         continue;
     403           0 :                                 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6))
     404           0 :                                         if (!IN6_ARE_ADDR_EQUAL(&inp->inp_laddr6,
     405             :                                             &ip6->ip6_dst))
     406             :                                                 continue;
     407             :                         } else
     408             : #endif /* INET6 */
     409             :                         {
     410           0 :                                 if (inp->inp_ip_minttl &&
     411           0 :                                     inp->inp_ip_minttl > ip->ip_ttl)
     412             :                                         continue;
     413             : 
     414           0 :                                 if (inp->inp_laddr.s_addr != INADDR_ANY) {
     415           0 :                                         if (inp->inp_laddr.s_addr !=
     416           0 :                                             ip->ip_dst.s_addr)
     417             :                                                 continue;
     418             :                                 }
     419             :                         }
     420             : #ifdef INET6
     421           0 :                         if (ip6) {
     422           0 :                                 if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6))
     423           0 :                                         if (!IN6_ARE_ADDR_EQUAL(&inp->inp_faddr6,
     424           0 :                                             &ip6->ip6_src) ||
     425           0 :                                             inp->inp_fport != uh->uh_sport)
     426             :                                                 continue;
     427             :                         } else
     428             : #endif /* INET6 */
     429           0 :                         if (inp->inp_faddr.s_addr != INADDR_ANY) {
     430           0 :                                 if (inp->inp_faddr.s_addr !=
     431           0 :                                     ip->ip_src.s_addr ||
     432           0 :                                     inp->inp_fport != uh->uh_sport)
     433             :                                         continue;
     434             :                         }
     435             : 
     436           0 :                         if (last != NULL) {
     437             :                                 struct mbuf *n;
     438             : 
     439           0 :                                 n = m_copym(m, 0, M_COPYALL, M_NOWAIT);
     440           0 :                                 if (n != NULL) {
     441           0 :                                         udp_sbappend(last, n, ip, ip6, iphlen,
     442           0 :                                             uh, &srcsa.sa, 0);
     443           0 :                                 }
     444           0 :                         }
     445             :                         last = inp;
     446             :                         /*
     447             :                          * Don't look for additional matches if this one does
     448             :                          * not have either the SO_REUSEPORT or SO_REUSEADDR
     449             :                          * socket options set.  This heuristic avoids searching
     450             :                          * through all pcbs in the common case of a non-shared
     451             :                          * port.  It assumes that an application will never
     452             :                          * clear these options after setting them.
     453             :                          */
     454           0 :                         if ((last->inp_socket->so_options & (SO_REUSEPORT |
     455           0 :                             SO_REUSEADDR)) == 0)
     456             :                                 break;
     457             :                 }
     458             : 
     459           0 :                 if (last == NULL) {
     460             :                         /*
     461             :                          * No matching pcb found; discard datagram.
     462             :                          * (No need to send an ICMP Port Unreachable
     463             :                          * for a broadcast or multicast datgram.)
     464             :                          */
     465           0 :                         udpstat_inc(udps_noportbcast);
     466           0 :                         goto bad;
     467             :                 }
     468             : 
     469           0 :                 udp_sbappend(last, m, ip, ip6, iphlen, uh, &srcsa.sa, 0);
     470           0 :                 return IPPROTO_DONE;
     471             :         }
     472             :         /*
     473             :          * Locate pcb for datagram.
     474             :          */
     475             : #if NPF > 0
     476           0 :         inp = pf_inp_lookup(m);
     477             : #endif
     478           0 :         if (inp == NULL) {
     479             : #ifdef INET6
     480           0 :                 if (ip6)
     481           0 :                         inp = in6_pcbhashlookup(&udbtable, &ip6->ip6_src,
     482           0 :                             uh->uh_sport, &ip6->ip6_dst, uh->uh_dport,
     483           0 :                             m->m_pkthdr.ph_rtableid);
     484             :                 else
     485             : #endif /* INET6 */
     486           0 :                 inp = in_pcbhashlookup(&udbtable, ip->ip_src, uh->uh_sport,
     487           0 :                     ip->ip_dst, uh->uh_dport, m->m_pkthdr.ph_rtableid);
     488             :         }
     489           0 :         if (inp == 0) {
     490           0 :                 udpstat_inc(udps_pcbhashmiss);
     491             : #ifdef INET6
     492           0 :                 if (ip6) {
     493           0 :                         inp = in6_pcblookup_listen(&udbtable, &ip6->ip6_dst,
     494           0 :                             uh->uh_dport, m, m->m_pkthdr.ph_rtableid);
     495           0 :                 } else
     496             : #endif /* INET6 */
     497           0 :                 inp = in_pcblookup_listen(&udbtable, ip->ip_dst,
     498           0 :                     uh->uh_dport, m, m->m_pkthdr.ph_rtableid);
     499           0 :                 if (inp == 0) {
     500           0 :                         udpstat_inc(udps_noport);
     501           0 :                         if (m->m_flags & (M_BCAST | M_MCAST)) {
     502           0 :                                 udpstat_inc(udps_noportbcast);
     503           0 :                                 goto bad;
     504             :                         }
     505             : #ifdef INET6
     506           0 :                         if (ip6) {
     507           0 :                                 uh->uh_sum = savesum;
     508           0 :                                 icmp6_error(m, ICMP6_DST_UNREACH,
     509             :                                     ICMP6_DST_UNREACH_NOPORT,0);
     510           0 :                         } else
     511             : #endif /* INET6 */
     512             :                         {
     513           0 :                                 *ip = save_ip;
     514           0 :                                 uh->uh_sum = savesum;
     515           0 :                                 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT,
     516             :                                     0, 0);
     517             :                         }
     518           0 :                         return IPPROTO_DONE;
     519             :                 }
     520             :         }
     521           0 :         KASSERT(sotoinpcb(inp->inp_socket) == inp);
     522           0 :         soassertlocked(inp->inp_socket);
     523             : 
     524             : #ifdef INET6
     525           0 :         if (ip6 && inp->inp_ip6_minhlim &&
     526           0 :             inp->inp_ip6_minhlim > ip6->ip6_hlim) {
     527             :                 goto bad;
     528             :         } else
     529             : #endif
     530           0 :         if (ip && inp->inp_ip_minttl &&
     531           0 :             inp->inp_ip_minttl > ip->ip_ttl) {
     532             :                 goto bad;
     533             :         }
     534             : 
     535             : #if NPF > 0
     536           0 :         if (inp->inp_socket->so_state & SS_ISCONNECTED)
     537           0 :                 pf_inp_link(m, inp);
     538             : #endif
     539             : 
     540             : #ifdef IPSEC
     541           0 :         mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
     542           0 :         if (mtag != NULL) {
     543           0 :                 tdbi = (struct tdb_ident *)(mtag + 1);
     544           0 :                 tdb = gettdb(tdbi->rdomain, tdbi->spi,
     545           0 :                     &tdbi->dst, tdbi->proto);
     546           0 :         } else
     547             :                 tdb = NULL;
     548           0 :         ipsp_spd_lookup(m, af, iphlen, &error,
     549             :             IPSP_DIRECTION_IN, tdb, inp, 0);
     550           0 :         if (error) {
     551           0 :                 udpstat_inc(udps_nosec);
     552           0 :                 goto bad;
     553             :         }
     554             :         /* create ipsec options while we know that tdb cannot be modified */
     555           0 :         if (tdb && tdb->tdb_ids)
     556           0 :                 ipsecflowinfo = tdb->tdb_ids->id_flow;
     557             : #endif /*IPSEC */
     558             : 
     559             : #ifdef PIPEX
     560           0 :         if (pipex_enable && inp->inp_pipex) {
     561             :                 struct pipex_session *session;
     562           0 :                 int off = iphlen + sizeof(struct udphdr);
     563           0 :                 if ((session = pipex_l2tp_lookup_session(m, off)) != NULL) {
     564           0 :                         if ((m = *mp = pipex_l2tp_input(m, off, session,
     565           0 :                             ipsecflowinfo)) == NULL) {
     566             :                                 /* the packet is handled by PIPEX */
     567           0 :                                 return IPPROTO_DONE;
     568             :                         }
     569             :                 }
     570           0 :         }
     571             : #endif
     572             : 
     573           0 :         udp_sbappend(inp, m, ip, ip6, iphlen, uh, &srcsa.sa, ipsecflowinfo);
     574           0 :         return IPPROTO_DONE;
     575             : bad:
     576           0 :         m_freem(m);
     577           0 :         return IPPROTO_DONE;
     578           0 : }
     579             : 
     580             : void
     581           0 : udp_sbappend(struct inpcb *inp, struct mbuf *m, struct ip *ip,
     582             :     struct ip6_hdr *ip6, int iphlen, struct udphdr *uh,
     583             :     struct sockaddr *srcaddr, u_int32_t ipsecflowinfo)
     584             : {
     585           0 :         struct socket *so = inp->inp_socket;
     586           0 :         struct mbuf *opts = NULL;
     587             : 
     588             : #ifdef INET6
     589           0 :         if (ip6 && (inp->inp_flags & IN6P_CONTROLOPTS ||
     590           0 :             so->so_options & SO_TIMESTAMP))
     591           0 :                 ip6_savecontrol(inp, m, &opts);
     592             : #endif /* INET6 */
     593           0 :         if (ip && (inp->inp_flags & INP_CONTROLOPTS ||
     594           0 :             so->so_options & SO_TIMESTAMP))
     595           0 :                 ip_savecontrol(inp, &opts, ip, m);
     596             : #ifdef INET6
     597           0 :         if (ip6 && (inp->inp_flags & IN6P_RECVDSTPORT)) {
     598             :                 struct mbuf **mp = &opts;
     599             : 
     600           0 :                 while (*mp)
     601           0 :                         mp = &(*mp)->m_next;
     602           0 :                 *mp = sbcreatecontrol((caddr_t)&uh->uh_dport, sizeof(u_int16_t),
     603             :                     IPV6_RECVDSTPORT, IPPROTO_IPV6);
     604           0 :         }
     605             : #endif /* INET6 */
     606           0 :         if (ip && (inp->inp_flags & INP_RECVDSTPORT)) {
     607             :                 struct mbuf **mp = &opts;
     608             : 
     609           0 :                 while (*mp)
     610           0 :                         mp = &(*mp)->m_next;
     611           0 :                 *mp = sbcreatecontrol((caddr_t)&uh->uh_dport, sizeof(u_int16_t),
     612             :                     IP_RECVDSTPORT, IPPROTO_IP);
     613           0 :         }
     614             : #ifdef IPSEC
     615           0 :         if (ipsecflowinfo && (inp->inp_flags & INP_IPSECFLOWINFO)) {
     616             :                 struct mbuf **mp = &opts;
     617             : 
     618           0 :                 while (*mp)
     619           0 :                         mp = &(*mp)->m_next;
     620           0 :                 *mp = sbcreatecontrol((caddr_t)&ipsecflowinfo,
     621             :                     sizeof(u_int32_t), IP_IPSECFLOWINFO, IPPROTO_IP);
     622           0 :         }
     623             : #endif
     624           0 :         m_adj(m, iphlen + sizeof(struct udphdr));
     625           0 :         if (sbappendaddr(so, &so->so_rcv, srcaddr, m, opts) == 0) {
     626           0 :                 udpstat_inc(udps_fullsock);
     627           0 :                 m_freem(m);
     628           0 :                 m_freem(opts);
     629           0 :                 return;
     630             :         }
     631           0 :         sorwakeup(so);
     632           0 : }
     633             : 
     634             : /*
     635             :  * Notify a udp user of an asynchronous error;
     636             :  * just wake up so that he can collect error status.
     637             :  */
     638             : void
     639           0 : udp_notify(struct inpcb *inp, int errno)
     640             : {
     641           0 :         inp->inp_socket->so_error = errno;
     642           0 :         sorwakeup(inp->inp_socket);
     643           0 :         sowwakeup(inp->inp_socket);
     644           0 : }
     645             : 
     646             : #ifdef INET6
     647             : void
     648           0 : udp6_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *d)
     649             : {
     650           0 :         struct udphdr uh;
     651           0 :         struct sockaddr_in6 sa6;
     652             :         struct ip6_hdr *ip6;
     653             :         struct mbuf *m;
     654             :         int off;
     655             :         void *cmdarg;
     656             :         struct ip6ctlparam *ip6cp = NULL;
     657             :         struct udp_portonly {
     658             :                 u_int16_t uh_sport;
     659             :                 u_int16_t uh_dport;
     660             :         } *uhp;
     661             :         void (*notify)(struct inpcb *, int) = udp_notify;
     662             : 
     663           0 :         if (sa == NULL)
     664           0 :                 return;
     665           0 :         if (sa->sa_family != AF_INET6 ||
     666           0 :             sa->sa_len != sizeof(struct sockaddr_in6))
     667           0 :                 return;
     668             : 
     669           0 :         if ((unsigned)cmd >= PRC_NCMDS)
     670           0 :                 return;
     671           0 :         if (PRC_IS_REDIRECT(cmd))
     672           0 :                 notify = in_rtchange, d = NULL;
     673           0 :         else if (cmd == PRC_HOSTDEAD)
     674           0 :                 d = NULL;
     675           0 :         else if (cmd == PRC_MSGSIZE)
     676             :                 ; /* special code is present, see below */
     677           0 :         else if (inet6ctlerrmap[cmd] == 0)
     678           0 :                 return;
     679             : 
     680             :         /* if the parameter is from icmp6, decode it. */
     681           0 :         if (d != NULL) {
     682           0 :                 ip6cp = (struct ip6ctlparam *)d;
     683           0 :                 m = ip6cp->ip6c_m;
     684           0 :                 ip6 = ip6cp->ip6c_ip6;
     685           0 :                 off = ip6cp->ip6c_off;
     686           0 :                 cmdarg = ip6cp->ip6c_cmdarg;
     687           0 :         } else {
     688             :                 m = NULL;
     689             :                 ip6 = NULL;
     690             :                 cmdarg = NULL;
     691             :                 /* XXX: translate addresses into internal form */
     692           0 :                 sa6 = *satosin6(sa);
     693           0 :                 if (in6_embedscope(&sa6.sin6_addr, &sa6, NULL)) {
     694             :                         /* should be impossible */
     695           0 :                         return;
     696             :                 }
     697             :         }
     698             : 
     699           0 :         if (ip6cp && ip6cp->ip6c_finaldst) {
     700           0 :                 bzero(&sa6, sizeof(sa6));
     701           0 :                 sa6.sin6_family = AF_INET6;
     702           0 :                 sa6.sin6_len = sizeof(sa6);
     703           0 :                 sa6.sin6_addr = *ip6cp->ip6c_finaldst;
     704             :                 /* XXX: assuming M is valid in this case */
     705           0 :                 sa6.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.ph_ifidx,
     706           0 :                     ip6cp->ip6c_finaldst);
     707           0 :                 if (in6_embedscope(ip6cp->ip6c_finaldst, &sa6, NULL)) {
     708             :                         /* should be impossible */
     709           0 :                         return;
     710             :                 }
     711             :         } else {
     712             :                 /* XXX: translate addresses into internal form */
     713           0 :                 sa6 = *satosin6(sa);
     714           0 :                 if (in6_embedscope(&sa6.sin6_addr, &sa6, NULL)) {
     715             :                         /* should be impossible */
     716           0 :                         return;
     717             :                 }
     718             :         }
     719             : 
     720           0 :         if (ip6) {
     721             :                 /*
     722             :                  * XXX: We assume that when IPV6 is non NULL,
     723             :                  * M and OFF are valid.
     724             :                  */
     725           0 :                 struct sockaddr_in6 sa6_src;
     726             : 
     727             :                 /* check if we can safely examine src and dst ports */
     728           0 :                 if (m->m_pkthdr.len < off + sizeof(*uhp))
     729           0 :                         return;
     730             : 
     731           0 :                 bzero(&uh, sizeof(uh));
     732           0 :                 m_copydata(m, off, sizeof(*uhp), (caddr_t)&uh);
     733             : 
     734           0 :                 bzero(&sa6_src, sizeof(sa6_src));
     735           0 :                 sa6_src.sin6_family = AF_INET6;
     736           0 :                 sa6_src.sin6_len = sizeof(sa6_src);
     737           0 :                 sa6_src.sin6_addr = ip6->ip6_src;
     738           0 :                 sa6_src.sin6_scope_id = in6_addr2scopeid(m->m_pkthdr.ph_ifidx,
     739             :                     &ip6->ip6_src);
     740           0 :                 if (in6_embedscope(&sa6_src.sin6_addr, &sa6_src, NULL)) {
     741             :                         /* should be impossible */
     742           0 :                         return;
     743             :                 }
     744             : 
     745           0 :                 if (cmd == PRC_MSGSIZE) {
     746             :                         int valid = 0;
     747             : 
     748             :                         /*
     749             :                          * Check to see if we have a valid UDP socket
     750             :                          * corresponding to the address in the ICMPv6 message
     751             :                          * payload.
     752             :                          */
     753           0 :                         if (in6_pcbhashlookup(&udbtable, &sa6.sin6_addr,
     754           0 :                             uh.uh_dport, &sa6_src.sin6_addr, uh.uh_sport,
     755             :                             rdomain))
     756           0 :                                 valid = 1;
     757             : #if 0
     758             :                         /*
     759             :                          * As the use of sendto(2) is fairly popular,
     760             :                          * we may want to allow non-connected pcb too.
     761             :                          * But it could be too weak against attacks...
     762             :                          * We should at least check if the local address (= s)
     763             :                          * is really ours.
     764             :                          */
     765             :                         else if (in6_pcblookup_listen(&udbtable,
     766             :                             &sa6_src.sin6_addr, uh.uh_sport, NULL,
     767             :                             rdomain))
     768             :                                 valid = 1;
     769             : #endif
     770             : 
     771             :                         /*
     772             :                          * Depending on the value of "valid" and routing table
     773             :                          * size (mtudisc_{hi,lo}wat), we will:
     774             :                          * - recalculate the new MTU and create the
     775             :                          *   corresponding routing entry, or
     776             :                          * - ignore the MTU change notification.
     777             :                          */
     778           0 :                         icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
     779             : 
     780             :                         /*
     781             :                          * regardless of if we called icmp6_mtudisc_update(),
     782             :                          * we need to call in6_pcbnotify(), to notify path
     783             :                          * MTU change to the userland (2292bis-02), because
     784             :                          * some unconnected sockets may share the same
     785             :                          * destination and want to know the path MTU.
     786             :                          */
     787           0 :                 }
     788             : 
     789           0 :                 (void) in6_pcbnotify(&udbtable, &sa6, uh.uh_dport,
     790           0 :                     &sa6_src, uh.uh_sport, rdomain, cmd, cmdarg, notify);
     791           0 :         } else {
     792           0 :                 (void) in6_pcbnotify(&udbtable, &sa6, 0,
     793             :                     &sa6_any, 0, rdomain, cmd, cmdarg, notify);
     794             :         }
     795           0 : }
     796             : #endif
     797             : 
     798             : void
     799           0 : udp_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
     800             : {
     801           0 :         struct ip *ip = v;
     802             :         struct udphdr *uhp;
     803             :         struct in_addr faddr;
     804             :         struct inpcb *inp;
     805             :         void (*notify)(struct inpcb *, int) = udp_notify;
     806             :         int errno;
     807             : 
     808           0 :         if (sa == NULL)
     809           0 :                 return;
     810           0 :         if (sa->sa_family != AF_INET ||
     811           0 :             sa->sa_len != sizeof(struct sockaddr_in))
     812           0 :                 return;
     813           0 :         faddr = satosin(sa)->sin_addr;
     814           0 :         if (faddr.s_addr == INADDR_ANY)
     815           0 :                 return;
     816             : 
     817           0 :         if ((unsigned)cmd >= PRC_NCMDS)
     818           0 :                 return;
     819           0 :         errno = inetctlerrmap[cmd];
     820           0 :         if (PRC_IS_REDIRECT(cmd))
     821           0 :                 notify = in_rtchange, ip = 0;
     822           0 :         else if (cmd == PRC_HOSTDEAD)
     823           0 :                 ip = 0;
     824           0 :         else if (errno == 0)
     825           0 :                 return;
     826           0 :         if (ip) {
     827           0 :                 uhp = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
     828             : 
     829             : #ifdef IPSEC
     830             :                 /* PMTU discovery for udpencap */
     831           0 :                 if (cmd == PRC_MSGSIZE && ip_mtudisc && udpencap_enable &&
     832           0 :                     udpencap_port && uhp->uh_sport == htons(udpencap_port)) {
     833           0 :                         udpencap_ctlinput(cmd, sa, rdomain, v);
     834           0 :                         return;
     835             :                 }
     836             : #endif
     837           0 :                 inp = in_pcbhashlookup(&udbtable,
     838           0 :                     ip->ip_dst, uhp->uh_dport, ip->ip_src, uhp->uh_sport,
     839             :                     rdomain);
     840           0 :                 if (inp && inp->inp_socket != NULL)
     841           0 :                         notify(inp, errno);
     842             :         } else
     843           0 :                 in_pcbnotifyall(&udbtable, sa, rdomain, errno, notify);
     844           0 : }
     845             : 
     846             : int
     847           0 : udp_output(struct inpcb *inp, struct mbuf *m, struct mbuf *addr,
     848             :     struct mbuf *control)
     849             : {
     850           0 :         struct sockaddr_in *sin = NULL;
     851             :         struct udpiphdr *ui;
     852             :         u_int32_t ipsecflowinfo = 0;
     853           0 :         struct sockaddr_in src_sin;
     854           0 :         int len = m->m_pkthdr.len;
     855           0 :         struct in_addr *laddr;
     856             :         int error = 0;
     857             : 
     858             : #ifdef DIAGNOSTIC
     859           0 :         if ((inp->inp_flags & INP_IPV6) != 0)
     860           0 :                 panic("IPv6 inpcb to %s", __func__);
     861             : #endif
     862             : 
     863             :         /*
     864             :          * Compute the packet length of the IP header, and
     865             :          * punt if the length looks bogus.
     866             :          */
     867           0 :         if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) {
     868             :                 error = EMSGSIZE;
     869           0 :                 goto release;
     870             :         }
     871             : 
     872           0 :         memset(&src_sin, 0, sizeof(src_sin));
     873             : 
     874           0 :         if (control) {
     875             :                 u_int clen;
     876             :                 struct cmsghdr *cm;
     877             :                 caddr_t cmsgs;
     878             : 
     879             :                 /*
     880             :                  * XXX: Currently, we assume all the optional information is
     881             :                  * stored in a single mbuf.
     882             :                  */
     883           0 :                 if (control->m_next) {
     884             :                         error = EINVAL;
     885           0 :                         goto release;
     886             :                 }
     887             : 
     888           0 :                 clen = control->m_len;
     889           0 :                 cmsgs = mtod(control, caddr_t);
     890           0 :                 do {
     891           0 :                         if (clen < CMSG_LEN(0)) {
     892             :                                 error = EINVAL;
     893           0 :                                 goto release;
     894             :                         }
     895           0 :                         cm = (struct cmsghdr *)cmsgs;
     896           0 :                         if (cm->cmsg_len < CMSG_LEN(0) ||
     897           0 :                             CMSG_ALIGN(cm->cmsg_len) > clen) {
     898             :                                 error = EINVAL;
     899           0 :                                 goto release;
     900             :                         }
     901             : #ifdef IPSEC
     902           0 :                         if ((inp->inp_flags & INP_IPSECFLOWINFO) != 0 &&
     903           0 :                             cm->cmsg_len == CMSG_LEN(sizeof(ipsecflowinfo)) &&
     904           0 :                             cm->cmsg_level == IPPROTO_IP &&
     905           0 :                             cm->cmsg_type == IP_IPSECFLOWINFO) {
     906           0 :                                 ipsecflowinfo = *(u_int32_t *)CMSG_DATA(cm);
     907           0 :                         } else
     908             : #endif
     909           0 :                         if (cm->cmsg_len == CMSG_LEN(sizeof(struct in_addr)) &&
     910           0 :                             cm->cmsg_level == IPPROTO_IP &&
     911           0 :                             cm->cmsg_type == IP_SENDSRCADDR) {
     912           0 :                                 memcpy(&src_sin.sin_addr, CMSG_DATA(cm),
     913             :                                     sizeof(struct in_addr));
     914           0 :                                 src_sin.sin_family = AF_INET;
     915           0 :                                 src_sin.sin_len = sizeof(src_sin);
     916             :                                 /* no check on reuse when sin->sin_port == 0 */
     917           0 :                                 if ((error = in_pcbaddrisavail(inp, &src_sin,
     918           0 :                                     0, curproc)))
     919           0 :                                         goto release;
     920             :                         }
     921           0 :                         clen -= CMSG_ALIGN(cm->cmsg_len);
     922           0 :                         cmsgs += CMSG_ALIGN(cm->cmsg_len);
     923           0 :                 } while (clen);
     924           0 :         }
     925             : 
     926           0 :         if (addr) {
     927           0 :                 if ((error = in_nam2sin(addr, &sin)))
     928             :                         goto release;
     929           0 :                 if (sin->sin_port == 0) {
     930             :                         error = EADDRNOTAVAIL;
     931           0 :                         goto release;
     932             :                 }
     933           0 :                 if (inp->inp_faddr.s_addr != INADDR_ANY) {
     934             :                         error = EISCONN;
     935           0 :                         goto release;
     936             :                 }
     937           0 :                 error = in_pcbselsrc(&laddr, sin, inp);
     938           0 :                 if (error)
     939             :                         goto release;
     940             : 
     941           0 :                 if (inp->inp_lport == 0) {
     942           0 :                         error = in_pcbbind(inp, NULL, curproc);
     943           0 :                         if (error)
     944             :                                 goto release;
     945             :                 }
     946             : 
     947           0 :                 if (src_sin.sin_len > 0 &&
     948           0 :                     src_sin.sin_addr.s_addr != INADDR_ANY &&
     949           0 :                     src_sin.sin_addr.s_addr != inp->inp_laddr.s_addr) {
     950           0 :                         src_sin.sin_port = inp->inp_lport;
     951           0 :                         if (inp->inp_laddr.s_addr != INADDR_ANY &&
     952           0 :                             (error =
     953           0 :                             in_pcbaddrisavail(inp, &src_sin, 0, curproc)))
     954             :                                 goto release;
     955           0 :                         laddr = &src_sin.sin_addr;
     956           0 :                 }
     957             :         } else {
     958           0 :                 if (inp->inp_faddr.s_addr == INADDR_ANY) {
     959             :                         error = ENOTCONN;
     960           0 :                         goto release;
     961             :                 }
     962           0 :                 laddr = &inp->inp_laddr;
     963             :         }
     964             : 
     965             :         /*
     966             :          * Calculate data length and get a mbuf
     967             :          * for UDP and IP headers.
     968             :          */
     969           0 :         M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
     970           0 :         if (m == NULL) {
     971             :                 error = ENOBUFS;
     972           0 :                 goto bail;
     973             :         }
     974             : 
     975             :         /*
     976             :          * Fill in mbuf with extended UDP header
     977             :          * and addresses and length put into network format.
     978             :          */
     979           0 :         ui = mtod(m, struct udpiphdr *);
     980           0 :         bzero(ui->ui_x1, sizeof ui->ui_x1);
     981           0 :         ui->ui_pr = IPPROTO_UDP;
     982           0 :         ui->ui_len = htons((u_int16_t)len + sizeof (struct udphdr));
     983           0 :         ui->ui_src = *laddr;
     984           0 :         ui->ui_dst = sin ? sin->sin_addr : inp->inp_faddr;
     985           0 :         ui->ui_sport = inp->inp_lport;
     986           0 :         ui->ui_dport = sin ? sin->sin_port : inp->inp_fport;
     987           0 :         ui->ui_ulen = ui->ui_len;
     988           0 :         ((struct ip *)ui)->ip_len = htons(sizeof (struct udpiphdr) + len);
     989           0 :         ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl;
     990           0 :         ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos;
     991           0 :         if (udpcksum)
     992           0 :                 m->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
     993             : 
     994           0 :         udpstat_inc(udps_opackets);
     995             : 
     996             :         /* force routing table */
     997           0 :         m->m_pkthdr.ph_rtableid = inp->inp_rtableid;
     998             : 
     999             : #if NPF > 0
    1000           0 :         if (inp->inp_socket->so_state & SS_ISCONNECTED)
    1001           0 :                 pf_mbuf_link_inpcb(m, inp);
    1002             : #endif
    1003             : 
    1004           0 :         error = ip_output(m, inp->inp_options, &inp->inp_route,
    1005           0 :             (inp->inp_socket->so_options & SO_BROADCAST), inp->inp_moptions,
    1006             :             inp, ipsecflowinfo);
    1007           0 :         if (error == EACCES)    /* translate pf(4) error for userland */
    1008             :                 error = EHOSTUNREACH;
    1009             : 
    1010             : bail:
    1011           0 :         m_freem(control);
    1012           0 :         return (error);
    1013             : 
    1014             : release:
    1015           0 :         m_freem(m);
    1016           0 :         goto bail;
    1017           0 : }
    1018             : 
    1019             : /*ARGSUSED*/
    1020             : int
    1021           0 : udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
    1022             :     struct mbuf *control, struct proc *p)
    1023             : {
    1024             :         struct inpcb *inp;
    1025             :         int error = 0;
    1026             : 
    1027           0 :         if (req == PRU_CONTROL) {
    1028             : #ifdef INET6
    1029           0 :                 if (sotopf(so) == PF_INET6)
    1030           0 :                         return (in6_control(so, (u_long)m, (caddr_t)addr,
    1031             :                             (struct ifnet *)control));
    1032             :                 else
    1033             : #endif /* INET6 */
    1034           0 :                         return (in_control(so, (u_long)m, (caddr_t)addr,
    1035             :                             (struct ifnet *)control));
    1036             :         }
    1037             : 
    1038           0 :         soassertlocked(so);
    1039             : 
    1040           0 :         inp = sotoinpcb(so);
    1041           0 :         if (inp == NULL) {
    1042             :                 error = EINVAL;
    1043           0 :                 goto release;
    1044             :         }
    1045             : 
    1046             :         /*
    1047             :          * Note: need to block udp_input while changing
    1048             :          * the udp pcb queue and/or pcb addresses.
    1049             :          */
    1050           0 :         switch (req) {
    1051             : 
    1052             :         case PRU_BIND:
    1053           0 :                 error = in_pcbbind(inp, addr, p);
    1054           0 :                 break;
    1055             : 
    1056             :         case PRU_LISTEN:
    1057             :                 error = EOPNOTSUPP;
    1058           0 :                 break;
    1059             : 
    1060             :         case PRU_CONNECT:
    1061             : #ifdef INET6
    1062           0 :                 if (inp->inp_flags & INP_IPV6) {
    1063           0 :                         if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
    1064             :                                 error = EISCONN;
    1065           0 :                                 break;
    1066             :                         }
    1067           0 :                         error = in6_pcbconnect(inp, addr);
    1068           0 :                 } else
    1069             : #endif /* INET6 */
    1070             :                 {
    1071           0 :                         if (inp->inp_faddr.s_addr != INADDR_ANY) {
    1072             :                                 error = EISCONN;
    1073           0 :                                 break;
    1074             :                         }
    1075           0 :                         error = in_pcbconnect(inp, addr);
    1076             :                 }
    1077             : 
    1078           0 :                 if (error == 0)
    1079           0 :                         soisconnected(so);
    1080             :                 break;
    1081             : 
    1082             :         case PRU_CONNECT2:
    1083             :                 error = EOPNOTSUPP;
    1084           0 :                 break;
    1085             : 
    1086             :         case PRU_ACCEPT:
    1087             :                 error = EOPNOTSUPP;
    1088           0 :                 break;
    1089             : 
    1090             :         case PRU_DISCONNECT:
    1091             : #ifdef INET6
    1092           0 :                 if (inp->inp_flags & INP_IPV6) {
    1093           0 :                         if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
    1094             :                                 error = ENOTCONN;
    1095           0 :                                 break;
    1096             :                         }
    1097             :                 } else
    1098             : #endif /* INET6 */
    1099             :                 {
    1100           0 :                         if (inp->inp_faddr.s_addr == INADDR_ANY) {
    1101             :                                 error = ENOTCONN;
    1102           0 :                                 break;
    1103             :                         }
    1104             :                 }
    1105             : 
    1106             : #ifdef INET6
    1107           0 :                 if (inp->inp_flags & INP_IPV6)
    1108           0 :                         inp->inp_laddr6 = in6addr_any;
    1109             :                 else
    1110             : #endif /* INET6 */
    1111           0 :                         inp->inp_laddr.s_addr = INADDR_ANY;
    1112           0 :                 in_pcbdisconnect(inp);
    1113             : 
    1114           0 :                 so->so_state &= ~SS_ISCONNECTED;         /* XXX */
    1115           0 :                 break;
    1116             : 
    1117             :         case PRU_SHUTDOWN:
    1118           0 :                 socantsendmore(so);
    1119           0 :                 break;
    1120             : 
    1121             :         case PRU_SEND:
    1122             : #ifdef PIPEX
    1123           0 :                 if (inp->inp_pipex) {
    1124             :                         struct pipex_session *session;
    1125             : 
    1126           0 :                         if (addr != NULL) 
    1127           0 :                                 session =
    1128           0 :                                     pipex_l2tp_userland_lookup_session(m,
    1129           0 :                                         mtod(addr, struct sockaddr *));
    1130             :                         else
    1131             : #ifdef INET6
    1132           0 :                         if (inp->inp_flags & INP_IPV6)
    1133           0 :                                 session =
    1134           0 :                                     pipex_l2tp_userland_lookup_session_ipv6(
    1135           0 :                                         m, inp->inp_faddr6);
    1136             :                         else
    1137             : #endif
    1138             :                                 session =
    1139           0 :                                     pipex_l2tp_userland_lookup_session_ipv4(
    1140           0 :                                         m, inp->inp_faddr);
    1141           0 :                         if (session != NULL)
    1142           0 :                                 if ((m = pipex_l2tp_userland_output(
    1143           0 :                                     m, session)) == NULL) {
    1144             :                                         error = ENOMEM;
    1145           0 :                                         goto release;
    1146             :                                 }
    1147           0 :                 }
    1148             : #endif
    1149             : 
    1150             : #ifdef INET6
    1151           0 :                 if (inp->inp_flags & INP_IPV6)
    1152           0 :                         error = udp6_output(inp, m, addr, control);
    1153             :                 else
    1154             : #endif
    1155           0 :                         error = udp_output(inp, m, addr, control);
    1156           0 :                 return (error);
    1157             : 
    1158             :         case PRU_ABORT:
    1159           0 :                 soisdisconnected(so);
    1160           0 :                 in_pcbdetach(inp);
    1161           0 :                 break;
    1162             : 
    1163             :         case PRU_SOCKADDR:
    1164             : #ifdef INET6
    1165           0 :                 if (inp->inp_flags & INP_IPV6)
    1166           0 :                         in6_setsockaddr(inp, addr);
    1167             :                 else
    1168             : #endif /* INET6 */
    1169           0 :                         in_setsockaddr(inp, addr);
    1170             :                 break;
    1171             : 
    1172             :         case PRU_PEERADDR:
    1173             : #ifdef INET6
    1174           0 :                 if (inp->inp_flags & INP_IPV6)
    1175           0 :                         in6_setpeeraddr(inp, addr);
    1176             :                 else
    1177             : #endif /* INET6 */
    1178           0 :                         in_setpeeraddr(inp, addr);
    1179             :                 break;
    1180             : 
    1181             :         case PRU_SENSE:
    1182             :                 /*
    1183             :                  * stat: don't bother with a blocksize.
    1184             :                  */
    1185             :                 /*
    1186             :                  * Perhaps Path MTU might be returned for a connected
    1187             :                  * UDP socket in this case.
    1188             :                  */
    1189           0 :                 return (0);
    1190             : 
    1191             :         case PRU_SENDOOB:
    1192             :         case PRU_FASTTIMO:
    1193             :         case PRU_SLOWTIMO:
    1194             :         case PRU_PROTORCV:
    1195             :         case PRU_PROTOSEND:
    1196             :                 error =  EOPNOTSUPP;
    1197           0 :                 break;
    1198             : 
    1199             :         case PRU_RCVD:
    1200             :         case PRU_RCVOOB:
    1201           0 :                 return (EOPNOTSUPP);    /* do not free mbuf's */
    1202             : 
    1203             :         default:
    1204           0 :                 panic("udp_usrreq");
    1205             :         }
    1206             : release:
    1207           0 :         m_freem(control);
    1208           0 :         m_freem(m);
    1209           0 :         return (error);
    1210           0 : }
    1211             : 
    1212             : int
    1213           0 : udp_attach(struct socket *so, int proto)
    1214             : {
    1215             :         int error;
    1216             : 
    1217           0 :         if (so->so_pcb != NULL)
    1218           0 :                 return EINVAL;
    1219             : 
    1220           0 :         if ((error = soreserve(so, udp_sendspace, udp_recvspace)))
    1221           0 :                 return error;
    1222             : 
    1223           0 :         NET_ASSERT_LOCKED();
    1224           0 :         if ((error = in_pcballoc(so, &udbtable)))
    1225           0 :                 return error;
    1226             : #ifdef INET6
    1227           0 :         if (sotoinpcb(so)->inp_flags & INP_IPV6)
    1228           0 :                 sotoinpcb(so)->inp_ipv6.ip6_hlim = ip6_defhlim;
    1229             :         else
    1230             : #endif /* INET6 */
    1231           0 :                 sotoinpcb(so)->inp_ip.ip_ttl = ip_defttl;
    1232           0 :         return 0;
    1233           0 : }
    1234             : 
    1235             : int
    1236           0 : udp_detach(struct socket *so)
    1237             : {
    1238             :         struct inpcb *inp;
    1239             : 
    1240           0 :         soassertlocked(so);
    1241             : 
    1242           0 :         inp = sotoinpcb(so);
    1243           0 :         if (inp == NULL)
    1244           0 :                 return (EINVAL);
    1245             : 
    1246           0 :         in_pcbdetach(inp);
    1247           0 :         return (0);
    1248           0 : }
    1249             : 
    1250             : /*
    1251             :  * Sysctl for udp variables.
    1252             :  */
    1253             : int
    1254           0 : udp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
    1255             :     size_t newlen)
    1256             : {
    1257             :         int error;
    1258             : 
    1259             :         /* All sysctl names at this level are terminal. */
    1260           0 :         if (namelen != 1)
    1261           0 :                 return (ENOTDIR);
    1262             : 
    1263           0 :         switch (name[0]) {
    1264             :         case UDPCTL_BADDYNAMIC:
    1265           0 :                 NET_LOCK();
    1266           0 :                 error = sysctl_struct(oldp, oldlenp, newp, newlen,
    1267             :                     baddynamicports.udp, sizeof(baddynamicports.udp));
    1268           0 :                 NET_UNLOCK();
    1269           0 :                 return (error);
    1270             : 
    1271             :         case UDPCTL_ROOTONLY:
    1272           0 :                 if (newp && securelevel > 0)
    1273           0 :                         return (EPERM);
    1274           0 :                 NET_LOCK();
    1275           0 :                 error = sysctl_struct(oldp, oldlenp, newp, newlen,
    1276             :                     rootonlyports.udp, sizeof(rootonlyports.udp));
    1277           0 :                 NET_UNLOCK();
    1278           0 :                 return (error);
    1279             : 
    1280             :         case UDPCTL_STATS:
    1281           0 :                 if (newp != NULL)
    1282           0 :                         return (EPERM);
    1283             : 
    1284           0 :                 return (udp_sysctl_udpstat(oldp, oldlenp, newp));
    1285             : 
    1286             :         default:
    1287           0 :                 if (name[0] < UDPCTL_MAXID) {
    1288           0 :                         NET_LOCK();
    1289           0 :                         error = sysctl_int_arr(udpctl_vars, name, namelen,
    1290             :                             oldp, oldlenp, newp, newlen);
    1291           0 :                         NET_UNLOCK();
    1292           0 :                         return (error);
    1293             :                 }
    1294           0 :                 return (ENOPROTOOPT);
    1295             :         }
    1296             :         /* NOTREACHED */
    1297           0 : }
    1298             : 
    1299             : int
    1300           0 : udp_sysctl_udpstat(void *oldp, size_t *oldlenp, void *newp)
    1301             : {
    1302           0 :         uint64_t counters[udps_ncounters];
    1303           0 :         struct udpstat udpstat;
    1304           0 :         u_long *words = (u_long *)&udpstat;
    1305             :         int i;
    1306             : 
    1307             :         CTASSERT(sizeof(udpstat) == (nitems(counters) * sizeof(u_long)));
    1308           0 :         memset(&udpstat, 0, sizeof udpstat);
    1309           0 :         counters_read(udpcounters, counters, nitems(counters));
    1310             : 
    1311           0 :         for (i = 0; i < nitems(counters); i++)
    1312           0 :                 words[i] = (u_long)counters[i];
    1313             : 
    1314           0 :         return (sysctl_rdstruct(oldp, oldlenp, newp,
    1315             :             &udpstat, sizeof(udpstat)));
    1316           0 : }

Generated by: LCOV version 1.13