The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/udp_usrreq.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: udp_usrreq.c,v 1.156 2006/11/14 12:05:55 rpaulo Exp $  */
    2 
    3 /*
    4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the project nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Copyright (c) 1982, 1986, 1988, 1990, 1993, 1995
   34  *      The Regents of the University of California.  All rights reserved.
   35  *
   36  * Redistribution and use in source and binary forms, with or without
   37  * modification, are permitted provided that the following conditions
   38  * are met:
   39  * 1. Redistributions of source code must retain the above copyright
   40  *    notice, this list of conditions and the following disclaimer.
   41  * 2. Redistributions in binary form must reproduce the above copyright
   42  *    notice, this list of conditions and the following disclaimer in the
   43  *    documentation and/or other materials provided with the distribution.
   44  * 3. 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.
   47  *
   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
   58  * SUCH DAMAGE.
   59  *
   60  *      @(#)udp_usrreq.c        8.6 (Berkeley) 5/23/95
   61  */
   62 
   63 #include <sys/cdefs.h>
   64 __KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.156 2006/11/14 12:05:55 rpaulo Exp $");
   65 
   66 #include "opt_inet.h"
   67 #include "opt_ipsec.h"
   68 #include "opt_inet_csum.h"
   69 #include "opt_ipkdb.h"
   70 #include "opt_mbuftrace.h"
   71 
   72 #include <sys/param.h>
   73 #include <sys/malloc.h>
   74 #include <sys/mbuf.h>
   75 #include <sys/protosw.h>
   76 #include <sys/socket.h>
   77 #include <sys/socketvar.h>
   78 #include <sys/errno.h>
   79 #include <sys/stat.h>
   80 #include <sys/systm.h>
   81 #include <sys/proc.h>
   82 #include <sys/domain.h>
   83 #include <sys/sysctl.h>
   84 
   85 #include <net/if.h>
   86 #include <net/route.h>
   87 
   88 #include <netinet/in.h>
   89 #include <netinet/in_systm.h>
   90 #include <netinet/in_var.h>
   91 #include <netinet/ip.h>
   92 #include <netinet/in_pcb.h>
   93 #include <netinet/ip_var.h>
   94 #include <netinet/ip_icmp.h>
   95 #include <netinet/udp.h>
   96 #include <netinet/udp_var.h>
   97 
   98 #ifdef INET6
   99 #include <netinet/ip6.h>
  100 #include <netinet/icmp6.h>
  101 #include <netinet6/ip6_var.h>
  102 #include <netinet6/in6_pcb.h>
  103 #include <netinet6/udp6_var.h>
  104 #include <netinet6/scope6_var.h>
  105 #endif
  106 
  107 #ifndef INET6
  108 /* always need ip6.h for IP6_EXTHDR_GET */
  109 #include <netinet/ip6.h>
  110 #endif
  111 
  112 #include "faith.h"
  113 #if defined(NFAITH) && NFAITH > 0
  114 #include <net/if_faith.h>
  115 #endif
  116 
  117 #include <machine/stdarg.h>
  118 
  119 #ifdef FAST_IPSEC
  120 #include <netipsec/ipsec.h>
  121 #include <netipsec/ipsec_var.h>                 /* XXX ipsecstat namespace */
  122 #include <netipsec/esp.h>
  123 #ifdef INET6
  124 #include <netipsec/ipsec6.h>
  125 #endif
  126 #endif  /* FAST_IPSEC*/
  127 
  128 #ifdef IPSEC
  129 #include <netinet6/ipsec.h>
  130 #include <netinet6/esp.h>
  131 #include <netkey/key.h>
  132 #endif /*IPSEC*/
  133 
  134 #ifdef IPKDB
  135 #include <ipkdb/ipkdb.h>
  136 #endif
  137 
  138 /*
  139  * UDP protocol implementation.
  140  * Per RFC 768, August, 1980.
  141  */
  142 int     udpcksum = 1;
  143 int     udp_do_loopback_cksum = 0;
  144 
  145 struct  inpcbtable udbtable;
  146 struct  udpstat udpstat;
  147 
  148 #ifdef INET
  149 #ifdef IPSEC_NAT_T
  150 static int udp4_espinudp (struct mbuf **, int, struct sockaddr *,
  151         struct socket *);
  152 #endif
  153 static void udp4_sendup (struct mbuf *, int, struct sockaddr *,
  154         struct socket *);
  155 static int udp4_realinput (struct sockaddr_in *, struct sockaddr_in *,
  156         struct mbuf **, int);
  157 static int udp4_input_checksum(struct mbuf *, const struct udphdr *, int, int);
  158 #endif
  159 #ifdef INET6
  160 static void udp6_sendup (struct mbuf *, int, struct sockaddr *,
  161         struct socket *);
  162 static int udp6_realinput (int, struct sockaddr_in6 *,
  163         struct sockaddr_in6 *, struct mbuf *, int);
  164 static int udp6_input_checksum(struct mbuf *, const struct udphdr *, int, int);
  165 #endif
  166 #ifdef INET
  167 static  void udp_notify (struct inpcb *, int);
  168 #endif
  169 
  170 #ifndef UDBHASHSIZE
  171 #define UDBHASHSIZE     128
  172 #endif
  173 int     udbhashsize = UDBHASHSIZE;
  174 
  175 #ifdef MBUFTRACE
  176 struct mowner udp_mowner = MOWNER_INIT("udp", "");
  177 struct mowner udp_rx_mowner = MOWNER_INIT("udp", "rx");
  178 struct mowner udp_tx_mowner = MOWNER_INIT("udp", "tx");
  179 #endif
  180 
  181 #ifdef UDP_CSUM_COUNTERS
  182 #include <sys/device.h>
  183 
  184 #if defined(INET)
  185 struct evcnt udp_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
  186     NULL, "udp", "hwcsum bad");
  187 struct evcnt udp_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
  188     NULL, "udp", "hwcsum ok");
  189 struct evcnt udp_hwcsum_data = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
  190     NULL, "udp", "hwcsum data");
  191 struct evcnt udp_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
  192     NULL, "udp", "swcsum");
  193 
  194 EVCNT_ATTACH_STATIC(udp_hwcsum_bad);
  195 EVCNT_ATTACH_STATIC(udp_hwcsum_ok);
  196 EVCNT_ATTACH_STATIC(udp_hwcsum_data);
  197 EVCNT_ATTACH_STATIC(udp_swcsum);
  198 #endif /* defined(INET) */
  199 
  200 #if defined(INET6)
  201 struct evcnt udp6_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
  202     NULL, "udp6", "hwcsum bad");
  203 struct evcnt udp6_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
  204     NULL, "udp6", "hwcsum ok");
  205 struct evcnt udp6_hwcsum_data = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
  206     NULL, "udp6", "hwcsum data");
  207 struct evcnt udp6_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
  208     NULL, "udp6", "swcsum");
  209 
  210 EVCNT_ATTACH_STATIC(udp6_hwcsum_bad);
  211 EVCNT_ATTACH_STATIC(udp6_hwcsum_ok);
  212 EVCNT_ATTACH_STATIC(udp6_hwcsum_data);
  213 EVCNT_ATTACH_STATIC(udp6_swcsum);
  214 #endif /* defined(INET6) */
  215 
  216 #define UDP_CSUM_COUNTER_INCR(ev)       (ev)->ev_count++
  217 
  218 #else
  219 
  220 #define UDP_CSUM_COUNTER_INCR(ev)       /* nothing */
  221 
  222 #endif /* UDP_CSUM_COUNTERS */
  223 
  224 void
  225 udp_init(void)
  226 {
  227 
  228         in_pcbinit(&udbtable, udbhashsize, udbhashsize);
  229 
  230         MOWNER_ATTACH(&udp_tx_mowner);
  231         MOWNER_ATTACH(&udp_rx_mowner);
  232         MOWNER_ATTACH(&udp_mowner);
  233 }
  234 
  235 /*
  236  * Checksum extended UDP header and data.
  237  */
  238 
  239 int
  240 udp_input_checksum(int af, struct mbuf *m, const struct udphdr *uh,
  241     int iphlen, int len)
  242 {
  243 
  244         switch (af) {
  245 #ifdef INET
  246         case AF_INET:
  247                 return udp4_input_checksum(m, uh, iphlen, len);
  248 #endif
  249 #ifdef INET6
  250         case AF_INET6:
  251                 return udp6_input_checksum(m, uh, iphlen, len);
  252 #endif
  253         }
  254 #ifdef DIAGNOSTIC
  255         panic("udp_input_checksum: unknown af %d", af);
  256 #endif
  257         /* NOTREACHED */
  258         return -1;
  259 }
  260 
  261 #ifdef INET
  262 
  263 /*
  264  * Checksum extended UDP header and data.
  265  */
  266 
  267 static int
  268 udp4_input_checksum(struct mbuf *m, const struct udphdr *uh,
  269     int iphlen, int len)
  270 {
  271 
  272         /*
  273          * XXX it's better to record and check if this mbuf is
  274          * already checked.
  275          */
  276 
  277         if (uh->uh_sum == 0)
  278                 return 0;
  279 
  280         switch (m->m_pkthdr.csum_flags &
  281             ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_UDPv4) |
  282             M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
  283         case M_CSUM_UDPv4|M_CSUM_TCP_UDP_BAD:
  284                 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_bad);
  285                 goto badcsum;
  286 
  287         case M_CSUM_UDPv4|M_CSUM_DATA: {
  288                 u_int32_t hw_csum = m->m_pkthdr.csum_data;
  289 
  290                 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_data);
  291                 if (m->m_pkthdr.csum_flags & M_CSUM_NO_PSEUDOHDR) {
  292                         const struct ip *ip =
  293                             mtod(m, const struct ip *);
  294 
  295                         hw_csum = in_cksum_phdr(ip->ip_src.s_addr,
  296                             ip->ip_dst.s_addr,
  297                             htons(hw_csum + len + IPPROTO_UDP));
  298                 }
  299                 if ((hw_csum ^ 0xffff) != 0)
  300                         goto badcsum;
  301                 break;
  302         }
  303 
  304         case M_CSUM_UDPv4:
  305                 /* Checksum was okay. */
  306                 UDP_CSUM_COUNTER_INCR(&udp_hwcsum_ok);
  307                 break;
  308 
  309         default:
  310                 /*
  311                  * Need to compute it ourselves.  Maybe skip checksum
  312                  * on loopback interfaces.
  313                  */
  314                 if (__predict_true(!(m->m_pkthdr.rcvif->if_flags &
  315                                      IFF_LOOPBACK) ||
  316                                    udp_do_loopback_cksum)) {
  317                         UDP_CSUM_COUNTER_INCR(&udp_swcsum);
  318                         if (in4_cksum(m, IPPROTO_UDP, iphlen, len) != 0)
  319                                 goto badcsum;
  320                 }
  321                 break;
  322         }
  323 
  324         return 0;
  325 
  326 badcsum:
  327         udpstat.udps_badsum++;
  328         return -1;
  329 }
  330 
  331 void
  332 udp_input(struct mbuf *m, ...)
  333 {
  334         va_list ap;
  335         struct sockaddr_in src, dst;
  336         struct ip *ip;
  337         struct udphdr *uh;
  338         int iphlen;
  339         int len;
  340         int n;
  341         u_int16_t ip_len;
  342 
  343         va_start(ap, m);
  344         iphlen = va_arg(ap, int);
  345         (void)va_arg(ap, int);          /* ignore value, advance ap */
  346         va_end(ap);
  347 
  348         MCLAIM(m, &udp_rx_mowner);
  349         udpstat.udps_ipackets++;
  350 
  351         /*
  352          * Get IP and UDP header together in first mbuf.
  353          */
  354         ip = mtod(m, struct ip *);
  355         IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr));
  356         if (uh == NULL) {
  357                 udpstat.udps_hdrops++;
  358                 return;
  359         }
  360         KASSERT(UDP_HDR_ALIGNED_P(uh));
  361 
  362         /* destination port of 0 is illegal, based on RFC768. */
  363         if (uh->uh_dport == 0)
  364                 goto bad;
  365 
  366         /*
  367          * Make mbuf data length reflect UDP length.
  368          * If not enough data to reflect UDP length, drop.
  369          */
  370         ip_len = ntohs(ip->ip_len);
  371         len = ntohs((u_int16_t)uh->uh_ulen);
  372         if (ip_len != iphlen + len) {
  373                 if (ip_len < iphlen + len || len < sizeof(struct udphdr)) {
  374                         udpstat.udps_badlen++;
  375                         goto bad;
  376                 }
  377                 m_adj(m, iphlen + len - ip_len);
  378         }
  379 
  380         /*
  381          * Checksum extended UDP header and data.
  382          */
  383         if (udp4_input_checksum(m, uh, iphlen, len))
  384                 goto badcsum;
  385 
  386         /* construct source and dst sockaddrs. */
  387         bzero(&src, sizeof(src));
  388         src.sin_family = AF_INET;
  389         src.sin_len = sizeof(struct sockaddr_in);
  390         bcopy(&ip->ip_src, &src.sin_addr, sizeof(src.sin_addr));
  391         src.sin_port = uh->uh_sport;
  392         bzero(&dst, sizeof(dst));
  393         dst.sin_family = AF_INET;
  394         dst.sin_len = sizeof(struct sockaddr_in);
  395         bcopy(&ip->ip_dst, &dst.sin_addr, sizeof(dst.sin_addr));
  396         dst.sin_port = uh->uh_dport;
  397 
  398         if ((n = udp4_realinput(&src, &dst, &m, iphlen)) == -1) {
  399                 udpstat.udps_hdrops++;
  400                 return;
  401         }
  402 #ifdef INET6
  403         if (IN_MULTICAST(ip->ip_dst.s_addr) || n == 0) {
  404                 struct sockaddr_in6 src6, dst6;
  405 
  406                 bzero(&src6, sizeof(src6));
  407                 src6.sin6_family = AF_INET6;
  408                 src6.sin6_len = sizeof(struct sockaddr_in6);
  409                 src6.sin6_addr.s6_addr[10] = src6.sin6_addr.s6_addr[11] = 0xff;
  410                 bcopy(&ip->ip_src, &src6.sin6_addr.s6_addr[12],
  411                         sizeof(ip->ip_src));
  412                 src6.sin6_port = uh->uh_sport;
  413                 bzero(&dst6, sizeof(dst6));
  414                 dst6.sin6_family = AF_INET6;
  415                 dst6.sin6_len = sizeof(struct sockaddr_in6);
  416                 dst6.sin6_addr.s6_addr[10] = dst6.sin6_addr.s6_addr[11] = 0xff;
  417                 bcopy(&ip->ip_dst, &dst6.sin6_addr.s6_addr[12],
  418                         sizeof(ip->ip_dst));
  419                 dst6.sin6_port = uh->uh_dport;
  420 
  421                 n += udp6_realinput(AF_INET, &src6, &dst6, m, iphlen);
  422         }
  423 #endif
  424 
  425         if (n == 0) {
  426                 if (m->m_flags & (M_BCAST | M_MCAST)) {
  427                         udpstat.udps_noportbcast++;
  428                         goto bad;
  429                 }
  430                 udpstat.udps_noport++;
  431 #ifdef IPKDB
  432                 if (checkipkdb(&ip->ip_src, uh->uh_sport, uh->uh_dport,
  433                                 m, iphlen + sizeof(struct udphdr),
  434                                 m->m_pkthdr.len - iphlen - sizeof(struct udphdr))) {
  435                         /*
  436                          * It was a debugger connect packet,
  437                          * just drop it now
  438                          */
  439                         goto bad;
  440                 }
  441 #endif
  442                 icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
  443                 m = NULL;
  444         }
  445 
  446 bad:
  447         if (m)
  448                 m_freem(m);
  449         return;
  450 
  451 badcsum:
  452         m_freem(m);
  453 }
  454 #endif
  455 
  456 #ifdef INET6
  457 static int
  458 udp6_input_checksum(struct mbuf *m, const struct udphdr *uh, int off, int len)
  459 {
  460 
  461         /*
  462          * XXX it's better to record and check if this mbuf is
  463          * already checked.
  464          */
  465 
  466         if (__predict_false((m->m_flags & M_LOOP) && !udp_do_loopback_cksum)) {
  467                 goto good;
  468         }
  469         if (uh->uh_sum == 0) {
  470                 udp6stat.udp6s_nosum++;
  471                 goto bad;
  472         }
  473 
  474         switch (m->m_pkthdr.csum_flags &
  475             ((m->m_pkthdr.rcvif->if_csum_flags_rx & M_CSUM_UDPv6) |
  476             M_CSUM_TCP_UDP_BAD | M_CSUM_DATA)) {
  477         case M_CSUM_UDPv6|M_CSUM_TCP_UDP_BAD:
  478                 UDP_CSUM_COUNTER_INCR(&udp6_hwcsum_bad);
  479                 udp6stat.udp6s_badsum++;
  480                 goto bad;
  481 
  482 #if 0 /* notyet */
  483         case M_CSUM_UDPv6|M_CSUM_DATA:
  484 #endif
  485 
  486         case M_CSUM_UDPv6:
  487                 /* Checksum was okay. */
  488                 UDP_CSUM_COUNTER_INCR(&udp6_hwcsum_ok);
  489                 break;
  490 
  491         default:
  492                 /*
  493                  * Need to compute it ourselves.  Maybe skip checksum
  494                  * on loopback interfaces.
  495                  */
  496                 UDP_CSUM_COUNTER_INCR(&udp6_swcsum);
  497                 if (in6_cksum(m, IPPROTO_UDP, off, len) != 0) {
  498                         udp6stat.udp6s_badsum++;
  499                         goto bad;
  500                 }
  501         }
  502 
  503 good:
  504         return 0;
  505 bad:
  506         return -1;
  507 }
  508 
  509 int
  510 udp6_input(struct mbuf **mp, int *offp, int proto)
  511 {
  512         struct mbuf *m = *mp;
  513         int off = *offp;
  514         struct sockaddr_in6 src, dst;
  515         struct ip6_hdr *ip6;
  516         struct udphdr *uh;
  517         u_int32_t plen, ulen;
  518 
  519         ip6 = mtod(m, struct ip6_hdr *);
  520 
  521 #if defined(NFAITH) && 0 < NFAITH
  522         if (faithprefix(&ip6->ip6_dst)) {
  523                 /* send icmp6 host unreach? */
  524                 m_freem(m);
  525                 return IPPROTO_DONE;
  526         }
  527 #endif
  528 
  529         udp6stat.udp6s_ipackets++;
  530 
  531         /* check for jumbogram is done in ip6_input.  we can trust pkthdr.len */
  532         plen = m->m_pkthdr.len - off;
  533         IP6_EXTHDR_GET(uh, struct udphdr *, m, off, sizeof(struct udphdr));
  534         if (uh == NULL) {
  535                 ip6stat.ip6s_tooshort++;
  536                 return IPPROTO_DONE;
  537         }
  538         KASSERT(UDP_HDR_ALIGNED_P(uh));
  539         ulen = ntohs((u_short)uh->uh_ulen);
  540         /*
  541          * RFC2675 section 4: jumbograms will have 0 in the UDP header field,
  542          * iff payload length > 0xffff.
  543          */
  544         if (ulen == 0 && plen > 0xffff)
  545                 ulen = plen;
  546 
  547         if (plen != ulen) {
  548                 udp6stat.udp6s_badlen++;
  549                 goto bad;
  550         }
  551 
  552         /* destination port of 0 is illegal, based on RFC768. */
  553         if (uh->uh_dport == 0)
  554                 goto bad;
  555 
  556         /* Be proactive about malicious use of IPv4 mapped address */
  557         if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
  558             IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
  559                 /* XXX stat */
  560                 goto bad;
  561         }
  562 
  563         /*
  564          * Checksum extended UDP header and data.  Maybe skip checksum
  565          * on loopback interfaces.
  566          */
  567         if (udp6_input_checksum(m, uh, off, ulen))
  568                 goto bad;
  569 
  570         /*
  571          * Construct source and dst sockaddrs.
  572          */
  573         bzero(&src, sizeof(src));
  574         src.sin6_family = AF_INET6;
  575         src.sin6_len = sizeof(struct sockaddr_in6);
  576         src.sin6_addr = ip6->ip6_src;
  577         src.sin6_port = uh->uh_sport;
  578         bzero(&dst, sizeof(dst));
  579         dst.sin6_family = AF_INET6;
  580         dst.sin6_len = sizeof(struct sockaddr_in6);
  581         dst.sin6_addr = ip6->ip6_dst;
  582         dst.sin6_port = uh->uh_dport;
  583 
  584         if (udp6_realinput(AF_INET6, &src, &dst, m, off) == 0) {
  585                 if (m->m_flags & M_MCAST) {
  586                         udp6stat.udp6s_noportmcast++;
  587                         goto bad;
  588                 }
  589                 udp6stat.udp6s_noport++;
  590                 icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0);
  591                 m = NULL;
  592         }
  593 
  594 bad:
  595         if (m)
  596                 m_freem(m);
  597         return IPPROTO_DONE;
  598 }
  599 #endif
  600 
  601 #ifdef INET
  602 static void
  603 udp4_sendup(struct mbuf *m, int off /* offset of data portion */,
  604         struct sockaddr *src, struct socket *so)
  605 {
  606         struct mbuf *opts = NULL;
  607         struct mbuf *n;
  608         struct inpcb *inp = NULL;
  609 
  610         if (!so)
  611                 return;
  612         switch (so->so_proto->pr_domain->dom_family) {
  613         case AF_INET:
  614                 inp = sotoinpcb(so);
  615                 break;
  616 #ifdef INET6
  617         case AF_INET6:
  618                 break;
  619 #endif
  620         default:
  621                 return;
  622         }
  623 
  624 #if defined(IPSEC) || defined(FAST_IPSEC)
  625         /* check AH/ESP integrity. */
  626         if (so != NULL && ipsec4_in_reject_so(m, so)) {
  627                 ipsecstat.in_polvio++;
  628                 if ((n = m_copy(m, 0, M_COPYALL)) != NULL)
  629                         icmp_error(n, ICMP_UNREACH, ICMP_UNREACH_ADMIN_PROHIBIT,
  630                             0, 0);
  631                 return;
  632         }
  633 #endif /*IPSEC*/
  634 
  635         if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
  636                 if (inp && (inp->inp_flags & INP_CONTROLOPTS
  637                          || so->so_options & SO_TIMESTAMP)) {
  638                         struct ip *ip = mtod(n, struct ip *);
  639                         ip_savecontrol(inp, &opts, ip, n);
  640                 }
  641 
  642                 m_adj(n, off);
  643                 if (sbappendaddr(&so->so_rcv, src, n,
  644                                 opts) == 0) {
  645                         m_freem(n);
  646                         if (opts)
  647                                 m_freem(opts);
  648                         so->so_rcv.sb_overflowed++;
  649                         udpstat.udps_fullsock++;
  650                 } else
  651                         sorwakeup(so);
  652         }
  653 }
  654 #endif
  655 
  656 #ifdef INET6
  657 static void
  658 udp6_sendup(struct mbuf *m, int off /* offset of data portion */,
  659         struct sockaddr *src, struct socket *so)
  660 {
  661         struct mbuf *opts = NULL;
  662         struct mbuf *n;
  663         struct in6pcb *in6p = NULL;
  664 
  665         if (!so)
  666                 return;
  667         if (so->so_proto->pr_domain->dom_family != AF_INET6)
  668                 return;
  669         in6p = sotoin6pcb(so);
  670 
  671 #if defined(IPSEC) || defined(FAST_IPSEC)
  672         /* check AH/ESP integrity. */
  673         if (so != NULL && ipsec6_in_reject_so(m, so)) {
  674                 ipsec6stat.in_polvio++;
  675                 if ((n = m_copy(m, 0, M_COPYALL)) != NULL)
  676                         icmp6_error(n, ICMP6_DST_UNREACH,
  677                             ICMP6_DST_UNREACH_ADMIN, 0);
  678                 return;
  679         }
  680 #endif /*IPSEC*/
  681 
  682         if ((n = m_copy(m, 0, M_COPYALL)) != NULL) {
  683                 if (in6p && (in6p->in6p_flags & IN6P_CONTROLOPTS
  684                           || in6p->in6p_socket->so_options & SO_TIMESTAMP)) {
  685                         struct ip6_hdr *ip6 = mtod(n, struct ip6_hdr *);
  686                         ip6_savecontrol(in6p, &opts, ip6, n);
  687                 }
  688 
  689                 m_adj(n, off);
  690                 if (sbappendaddr(&so->so_rcv, src, n, opts) == 0) {
  691                         m_freem(n);
  692                         if (opts)
  693                                 m_freem(opts);
  694                         so->so_rcv.sb_overflowed++;
  695                         udp6stat.udp6s_fullsock++;
  696                 } else
  697                         sorwakeup(so);
  698         }
  699 }
  700 #endif
  701 
  702 #ifdef INET
  703 static int
  704 udp4_realinput(struct sockaddr_in *src, struct sockaddr_in *dst,
  705         struct mbuf **mp, int off /* offset of udphdr */)
  706 {
  707         u_int16_t *sport, *dport;
  708         int rcvcnt;
  709         struct in_addr *src4, *dst4;
  710         struct inpcb_hdr *inph;
  711         struct inpcb *inp;
  712         struct mbuf *m = *mp;
  713 
  714         rcvcnt = 0;
  715         off += sizeof(struct udphdr);   /* now, offset of payload */
  716 
  717         if (src->sin_family != AF_INET || dst->sin_family != AF_INET)
  718                 goto bad;
  719 
  720         src4 = &src->sin_addr;
  721         sport = &src->sin_port;
  722         dst4 = &dst->sin_addr;
  723         dport = &dst->sin_port;
  724 
  725         if (IN_MULTICAST(dst4->s_addr) ||
  726             in_broadcast(*dst4, m->m_pkthdr.rcvif)) {
  727                 /*
  728                  * Deliver a multicast or broadcast datagram to *all* sockets
  729                  * for which the local and remote addresses and ports match
  730                  * those of the incoming datagram.  This allows more than
  731                  * one process to receive multi/broadcasts on the same port.
  732                  * (This really ought to be done for unicast datagrams as
  733                  * well, but that would cause problems with existing
  734                  * applications that open both address-specific sockets and
  735                  * a wildcard socket listening to the same port -- they would
  736                  * end up receiving duplicates of every unicast datagram.
  737                  * Those applications open the multiple sockets to overcome an
  738                  * inadequacy of the UDP socket interface, but for backwards
  739                  * compatibility we avoid the problem here rather than
  740                  * fixing the interface.  Maybe 4.5BSD will remedy this?)
  741                  */
  742 
  743                 /*
  744                  * KAME note: traditionally we dropped udpiphdr from mbuf here.
  745                  * we need udpiphdr for IPsec processing so we do that later.
  746                  */
  747                 /*
  748                  * Locate pcb(s) for datagram.
  749                  */
  750                 CIRCLEQ_FOREACH(inph, &udbtable.inpt_queue, inph_queue) {
  751                         inp = (struct inpcb *)inph;
  752                         if (inp->inp_af != AF_INET)
  753                                 continue;
  754 
  755                         if (inp->inp_lport != *dport)
  756                                 continue;
  757                         if (!in_nullhost(inp->inp_laddr)) {
  758                                 if (!in_hosteq(inp->inp_laddr, *dst4))
  759                                         continue;
  760                         }
  761                         if (!in_nullhost(inp->inp_faddr)) {
  762                                 if (!in_hosteq(inp->inp_faddr, *src4) ||
  763                                     inp->inp_fport != *sport)
  764                                         continue;
  765                         }
  766 
  767                         udp4_sendup(m, off, (struct sockaddr *)src,
  768                                 inp->inp_socket);
  769                         rcvcnt++;
  770 
  771                         /*
  772                          * Don't look for additional matches if this one does
  773                          * not have either the SO_REUSEPORT or SO_REUSEADDR
  774                          * socket options set.  This heuristic avoids searching
  775                          * through all pcbs in the common case of a non-shared
  776                          * port.  It assumes that an application will never
  777                          * clear these options after setting them.
  778                          */
  779                         if ((inp->inp_socket->so_options &
  780                             (SO_REUSEPORT|SO_REUSEADDR)) == 0)
  781                                 break;
  782                 }
  783         } else {
  784                 /*
  785                  * Locate pcb for datagram.
  786                  */
  787                 inp = in_pcblookup_connect(&udbtable, *src4, *sport, *dst4, *dport);
  788                 if (inp == 0) {
  789                         ++udpstat.udps_pcbhashmiss;
  790                         inp = in_pcblookup_bind(&udbtable, *dst4, *dport);
  791                         if (inp == 0)
  792                                 return rcvcnt;
  793                 }
  794 
  795 #ifdef IPSEC_NAT_T
  796                 /* Handle ESP over UDP */
  797                 if (inp->inp_flags & INP_ESPINUDP_ALL) {
  798                         struct sockaddr *sa = (struct sockaddr *)src;
  799 
  800                         switch(udp4_espinudp(mp, off, sa, inp->inp_socket)) {
  801                         case -1:        /* Error, m was freeed */
  802                                 rcvcnt = -1;
  803                                 goto bad;
  804                                 break;
  805 
  806                         case 1:         /* ESP over UDP */
  807                                 rcvcnt++;
  808                                 goto bad;
  809                                 break;
  810 
  811                         case 0:         /* plain UDP */
  812                         default:        /* Unexpected */
  813                                 /* 
  814                                  * Normal UDP processing will take place 
  815                                  * m may have changed.
  816                                  */
  817                                 m = *mp;
  818                                 break;
  819                         }
  820                 }
  821 #endif
  822 
  823                 udp4_sendup(m, off, (struct sockaddr *)src, inp->inp_socket);
  824                 rcvcnt++;
  825         }
  826 
  827 bad:
  828         return rcvcnt;
  829 }
  830 #endif
  831 
  832 #ifdef INET6
  833 static int
  834 udp6_realinput(int af, struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
  835         struct mbuf *m, int off)
  836 {
  837         u_int16_t sport, dport;
  838         int rcvcnt;
  839         struct in6_addr src6, *dst6;
  840         const struct in_addr *dst4;
  841         struct inpcb_hdr *inph;
  842         struct in6pcb *in6p;
  843 
  844         rcvcnt = 0;
  845         off += sizeof(struct udphdr);   /* now, offset of payload */
  846 
  847         if (af != AF_INET && af != AF_INET6)
  848                 goto bad;
  849         if (src->sin6_family != AF_INET6 || dst->sin6_family != AF_INET6)
  850                 goto bad;
  851 
  852         src6 = src->sin6_addr;
  853         if (sa6_recoverscope(src) != 0) {
  854                 /* XXX: should be impossible. */
  855                 goto bad;
  856         }
  857         sport = src->sin6_port;
  858 
  859         dport = dst->sin6_port;
  860         dst4 = (struct in_addr *)&dst->sin6_addr.s6_addr[12];
  861         dst6 = &dst->sin6_addr;
  862 
  863         if (IN6_IS_ADDR_MULTICAST(dst6) ||
  864             (af == AF_INET && IN_MULTICAST(dst4->s_addr))) {
  865                 /*
  866                  * Deliver a multicast or broadcast datagram to *all* sockets
  867                  * for which the local and remote addresses and ports match
  868                  * those of the incoming datagram.  This allows more than
  869                  * one process to receive multi/broadcasts on the same port.
  870                  * (This really ought to be done for unicast datagrams as
  871                  * well, but that would cause problems with existing
  872                  * applications that open both address-specific sockets and
  873                  * a wildcard socket listening to the same port -- they would
  874                  * end up receiving duplicates of every unicast datagram.
  875                  * Those applications open the multiple sockets to overcome an
  876                  * inadequacy of the UDP socket interface, but for backwards
  877                  * compatibility we avoid the problem here rather than
  878                  * fixing the interface.  Maybe 4.5BSD will remedy this?)
  879                  */
  880 
  881                 /*
  882                  * KAME note: traditionally we dropped udpiphdr from mbuf here.
  883                  * we need udpiphdr for IPsec processing so we do that later.
  884                  */
  885                 /*
  886                  * Locate pcb(s) for datagram.
  887                  */
  888                 CIRCLEQ_FOREACH(inph, &udbtable.inpt_queue, inph_queue) {
  889                         in6p = (struct in6pcb *)inph;
  890                         if (in6p->in6p_af != AF_INET6)
  891                                 continue;
  892 
  893                         if (in6p->in6p_lport != dport)
  894                                 continue;
  895                         if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_laddr)) {
  896                                 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_laddr,
  897                                     dst6))
  898                                         continue;
  899                         } else {
  900                                 if (IN6_IS_ADDR_V4MAPPED(dst6) &&
  901                                     (in6p->in6p_flags & IN6P_IPV6_V6ONLY))
  902                                         continue;
  903                         }
  904                         if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
  905                                 if (!IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr,
  906                                     &src6) || in6p->in6p_fport != sport)
  907                                         continue;
  908                         } else {
  909                                 if (IN6_IS_ADDR_V4MAPPED(&src6) &&
  910                                     (in6p->in6p_flags & IN6P_IPV6_V6ONLY))
  911                                         continue;
  912                         }
  913 
  914                         udp6_sendup(m, off, (struct sockaddr *)src,
  915                                 in6p->in6p_socket);
  916                         rcvcnt++;
  917 
  918                         /*
  919                          * Don't look for additional matches if this one does
  920                          * not have either the SO_REUSEPORT or SO_REUSEADDR
  921                          * socket options set.  This heuristic avoids searching
  922                          * through all pcbs in the common case of a non-shared
  923                          * port.  It assumes that an application will never
  924                          * clear these options after setting them.
  925                          */
  926                         if ((in6p->in6p_socket->so_options &
  927                             (SO_REUSEPORT|SO_REUSEADDR)) == 0)
  928                                 break;
  929                 }
  930         } else {
  931                 /*
  932                  * Locate pcb for datagram.
  933                  */
  934                 in6p = in6_pcblookup_connect(&udbtable, &src6, sport, dst6,
  935                     dport, 0);
  936                 if (in6p == 0) {
  937                         ++udpstat.udps_pcbhashmiss;
  938                         in6p = in6_pcblookup_bind(&udbtable, dst6, dport, 0);
  939                         if (in6p == 0)
  940                                 return rcvcnt;
  941                 }
  942 
  943                 udp6_sendup(m, off, (struct sockaddr *)src, in6p->in6p_socket);
  944                 rcvcnt++;
  945         }
  946 
  947 bad:
  948         return rcvcnt;
  949 }
  950 #endif
  951 
  952 #ifdef INET
  953 /*
  954  * Notify a udp user of an asynchronous error;
  955  * just wake up so that he can collect error status.
  956  */
  957 static void
  958 udp_notify(struct inpcb *inp, int errno)
  959 {
  960         inp->inp_socket->so_error = errno;
  961         sorwakeup(inp->inp_socket);
  962         sowwakeup(inp->inp_socket);
  963 }
  964 
  965 void *
  966 udp_ctlinput(int cmd, struct sockaddr *sa, void *v)
  967 {
  968         struct ip *ip = v;
  969         struct udphdr *uh;
  970         void (*notify)(struct inpcb *, int) = udp_notify;
  971         int errno;
  972 
  973         if (sa->sa_family != AF_INET
  974          || sa->sa_len != sizeof(struct sockaddr_in))
  975                 return NULL;
  976         if ((unsigned)cmd >= PRC_NCMDS)
  977                 return NULL;
  978         errno = inetctlerrmap[cmd];
  979         if (PRC_IS_REDIRECT(cmd))
  980                 notify = in_rtchange, ip = 0;
  981         else if (cmd == PRC_HOSTDEAD)
  982                 ip = 0;
  983         else if (errno == 0)
  984                 return NULL;
  985         if (ip) {
  986                 uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
  987                 in_pcbnotify(&udbtable, satosin(sa)->sin_addr, uh->uh_dport,
  988                     ip->ip_src, uh->uh_sport, errno, notify);
  989 
  990                 /* XXX mapped address case */
  991         } else
  992                 in_pcbnotifyall(&udbtable, satosin(sa)->sin_addr, errno,
  993                     notify);
  994         return NULL;
  995 }
  996 
  997 int
  998 udp_ctloutput(int op, struct socket *so, int level, int optname,
  999     struct mbuf **mp)
 1000 {
 1001         int s;
 1002         int error = 0;
 1003         struct mbuf *m;
 1004         struct inpcb *inp;
 1005         int family;
 1006 
 1007         family = so->so_proto->pr_domain->dom_family;
 1008 
 1009         s = splsoftnet();
 1010         switch (family) {
 1011 #ifdef INET
 1012         case PF_INET:
 1013                 if (level != IPPROTO_UDP) {
 1014                         error = ip_ctloutput(op, so, level, optname, mp);
 1015                         goto end;
 1016                 }
 1017                 break;
 1018 #endif
 1019 #ifdef INET6
 1020         case PF_INET6:
 1021                 if (level != IPPROTO_UDP) {
 1022                         error = ip6_ctloutput(op, so, level, optname, mp);
 1023                         goto end;
 1024                 }
 1025                 break;
 1026 #endif
 1027         default:
 1028                 error = EAFNOSUPPORT;
 1029                 goto end;
 1030         }
 1031 
 1032 
 1033         switch (op) {
 1034         case PRCO_SETOPT:
 1035                 m = *mp;
 1036                 inp = sotoinpcb(so);
 1037 
 1038                 switch (optname) {
 1039                 case UDP_ENCAP:
 1040                         if (m == NULL || m->m_len < sizeof (int)) {
 1041                                 error = EINVAL;
 1042                                 break;
 1043                         }
 1044 
 1045                         switch(*mtod(m, int *)) {
 1046 #ifdef IPSEC_NAT_T
 1047                         case 0:
 1048                                 inp->inp_flags &= ~INP_ESPINUDP_ALL;
 1049                                 break;
 1050 
 1051                         case UDP_ENCAP_ESPINUDP:
 1052                                 inp->inp_flags &= ~INP_ESPINUDP_ALL;
 1053                                 inp->inp_flags |= INP_ESPINUDP;
 1054                                 break;
 1055 
 1056                         case UDP_ENCAP_ESPINUDP_NON_IKE:
 1057                                 inp->inp_flags &= ~INP_ESPINUDP_ALL;
 1058                                 inp->inp_flags |= INP_ESPINUDP_NON_IKE;
 1059                                 break;
 1060 #endif
 1061                         default:
 1062                                 error = EINVAL;
 1063                                 break;
 1064                         }
 1065                         break;
 1066 
 1067                 default:
 1068                         error = ENOPROTOOPT;
 1069                         break;
 1070                 }
 1071                 if (m != NULL) {
 1072                         m_free(m);
 1073                 }
 1074                 break;
 1075 
 1076         default:
 1077                 error = EINVAL;
 1078                 break;
 1079         }
 1080 
 1081 end:
 1082         splx(s);
 1083         return error;
 1084 }
 1085 
 1086 
 1087 int
 1088 udp_output(struct mbuf *m, ...)
 1089 {
 1090         struct inpcb *inp;
 1091         struct udpiphdr *ui;
 1092         struct route *ro;
 1093         int len = m->m_pkthdr.len;
 1094         int error = 0;
 1095         va_list ap;
 1096 
 1097         MCLAIM(m, &udp_tx_mowner);
 1098         va_start(ap, m);
 1099         inp = va_arg(ap, struct inpcb *);
 1100         va_end(ap);
 1101 
 1102         /*
 1103          * Calculate data length and get a mbuf
 1104          * for UDP and IP headers.
 1105          */
 1106         M_PREPEND(m, sizeof(struct udpiphdr), M_DONTWAIT);
 1107         if (m == 0) {
 1108                 error = ENOBUFS;
 1109                 goto release;
 1110         }
 1111 
 1112         /*
 1113          * Compute the packet length of the IP header, and
 1114          * punt if the length looks bogus.
 1115          */
 1116         if (len + sizeof(struct udpiphdr) > IP_MAXPACKET) {
 1117                 error = EMSGSIZE;
 1118                 goto release;
 1119         }
 1120 
 1121         /*
 1122          * Fill in mbuf with extended UDP header
 1123          * and addresses and length put into network format.
 1124          */
 1125         ui = mtod(m, struct udpiphdr *);
 1126         ui->ui_pr = IPPROTO_UDP;
 1127         ui->ui_src = inp->inp_laddr;
 1128         ui->ui_dst = inp->inp_faddr;
 1129         ui->ui_sport = inp->inp_lport;
 1130         ui->ui_dport = inp->inp_fport;
 1131         ui->ui_ulen = htons((u_int16_t)len + sizeof(struct udphdr));
 1132 
 1133         ro = &inp->inp_route;
 1134 
 1135         /*
 1136          * Set up checksum and output datagram.
 1137          */
 1138         if (udpcksum) {
 1139                 /*
 1140                  * XXX Cache pseudo-header checksum part for
 1141                  * XXX "connected" UDP sockets.
 1142                  */
 1143                 ui->ui_sum = in_cksum_phdr(ui->ui_src.s_addr,
 1144                     ui->ui_dst.s_addr, htons((u_int16_t)len +
 1145                     sizeof(struct udphdr) + IPPROTO_UDP));
 1146                 m->m_pkthdr.csum_flags = M_CSUM_UDPv4;
 1147                 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
 1148         } else
 1149                 ui->ui_sum = 0;
 1150         ((struct ip *)ui)->ip_len = htons(sizeof (struct udpiphdr) + len);
 1151         ((struct ip *)ui)->ip_ttl = inp->inp_ip.ip_ttl; /* XXX */
 1152         ((struct ip *)ui)->ip_tos = inp->inp_ip.ip_tos; /* XXX */
 1153         udpstat.udps_opackets++;
 1154 
 1155         return (ip_output(m, inp->inp_options, ro,
 1156             inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST),
 1157             inp->inp_moptions, inp->inp_socket));
 1158 
 1159 release:
 1160         m_freem(m);
 1161         return (error);
 1162 }
 1163 
 1164 int     udp_sendspace = 9216;           /* really max datagram size */
 1165 int     udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
 1166                                         /* 40 1K datagrams */
 1167 
 1168 /*ARGSUSED*/
 1169 int
 1170 udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
 1171         struct mbuf *control, struct lwp *l)
 1172 {
 1173         struct inpcb *inp;
 1174         int s;
 1175         int error = 0;
 1176 
 1177         if (req == PRU_CONTROL)
 1178                 return (in_control(so, (long)m, (caddr_t)nam,
 1179                     (struct ifnet *)control, l));
 1180 
 1181         s = splsoftnet();
 1182 
 1183         if (req == PRU_PURGEIF) {
 1184                 in_pcbpurgeif0(&udbtable, (struct ifnet *)control);
 1185                 in_purgeif((struct ifnet *)control);
 1186                 in_pcbpurgeif(&udbtable, (struct ifnet *)control);
 1187                 splx(s);
 1188                 return (0);
 1189         }
 1190 
 1191         inp = sotoinpcb(so);
 1192 #ifdef DIAGNOSTIC
 1193         if (req != PRU_SEND && req != PRU_SENDOOB && control)
 1194                 panic("udp_usrreq: unexpected control mbuf");
 1195 #endif
 1196         if (inp == 0 && req != PRU_ATTACH) {
 1197                 error = EINVAL;
 1198                 goto release;
 1199         }
 1200 
 1201         /*
 1202          * Note: need to block udp_input while changing
 1203          * the udp pcb queue and/or pcb addresses.
 1204          */
 1205         switch (req) {
 1206 
 1207         case PRU_ATTACH:
 1208                 if (inp != 0) {
 1209                         error = EISCONN;
 1210                         break;
 1211                 }
 1212 #ifdef MBUFTRACE
 1213                 so->so_mowner = &udp_mowner;
 1214                 so->so_rcv.sb_mowner = &udp_rx_mowner;
 1215                 so->so_snd.sb_mowner = &udp_tx_mowner;
 1216 #endif
 1217                 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
 1218                         error = soreserve(so, udp_sendspace, udp_recvspace);
 1219                         if (error)
 1220                                 break;
 1221                 }
 1222                 error = in_pcballoc(so, &udbtable);
 1223                 if (error)
 1224                         break;
 1225                 inp = sotoinpcb(so);
 1226                 inp->inp_ip.ip_ttl = ip_defttl;
 1227                 break;
 1228 
 1229         case PRU_DETACH:
 1230                 in_pcbdetach(inp);
 1231                 break;
 1232 
 1233         case PRU_BIND:
 1234                 error = in_pcbbind(inp, nam, l);
 1235                 break;
 1236 
 1237         case PRU_LISTEN:
 1238                 error = EOPNOTSUPP;
 1239                 break;
 1240 
 1241         case PRU_CONNECT:
 1242                 error = in_pcbconnect(inp, nam, l);
 1243                 if (error)
 1244                         break;
 1245                 soisconnected(so);
 1246                 break;
 1247 
 1248         case PRU_CONNECT2:
 1249                 error = EOPNOTSUPP;
 1250                 break;
 1251 
 1252         case PRU_DISCONNECT:
 1253                 /*soisdisconnected(so);*/
 1254                 so->so_state &= ~SS_ISCONNECTED;        /* XXX */
 1255                 in_pcbdisconnect(inp);
 1256                 inp->inp_laddr = zeroin_addr;           /* XXX */
 1257                 in_pcbstate(inp, INP_BOUND);            /* XXX */
 1258                 break;
 1259 
 1260         case PRU_SHUTDOWN:
 1261                 socantsendmore(so);
 1262                 break;
 1263 
 1264         case PRU_RCVD:
 1265                 error = EOPNOTSUPP;
 1266                 break;
 1267 
 1268         case PRU_SEND:
 1269                 if (control && control->m_len) {
 1270                         m_freem(control);
 1271                         m_freem(m);
 1272                         error = EINVAL;
 1273                         break;
 1274                 }
 1275         {
 1276                 struct in_addr laddr;                   /* XXX */
 1277 
 1278                 if (nam) {
 1279                         laddr = inp->inp_laddr;         /* XXX */
 1280                         if ((so->so_state & SS_ISCONNECTED) != 0) {
 1281                                 error = EISCONN;
 1282                                 goto die;
 1283                         }
 1284                         error = in_pcbconnect(inp, nam, l);
 1285                         if (error)
 1286                                 goto die;
 1287                 } else {
 1288                         if ((so->so_state & SS_ISCONNECTED) == 0) {
 1289                                 error = ENOTCONN;
 1290                                 goto die;
 1291                         }
 1292                 }
 1293                 error = udp_output(m, inp);
 1294                 m = NULL;
 1295                 if (nam) {
 1296                         in_pcbdisconnect(inp);
 1297                         inp->inp_laddr = laddr;         /* XXX */
 1298                         in_pcbstate(inp, INP_BOUND);    /* XXX */
 1299                 }
 1300           die:
 1301                 if (m)
 1302                         m_freem(m);
 1303         }
 1304                 break;
 1305 
 1306         case PRU_SENSE:
 1307                 /*
 1308                  * stat: don't bother with a blocksize.
 1309                  */
 1310                 splx(s);
 1311                 return (0);
 1312 
 1313         case PRU_RCVOOB:
 1314                 error =  EOPNOTSUPP;
 1315                 break;
 1316 
 1317         case PRU_SENDOOB:
 1318                 m_freem(control);
 1319                 m_freem(m);
 1320                 error =  EOPNOTSUPP;
 1321                 break;
 1322 
 1323         case PRU_SOCKADDR:
 1324                 in_setsockaddr(inp, nam);
 1325                 break;
 1326 
 1327         case PRU_PEERADDR:
 1328                 in_setpeeraddr(inp, nam);
 1329                 break;
 1330 
 1331         default:
 1332                 panic("udp_usrreq");
 1333         }
 1334 
 1335 release:
 1336         splx(s);
 1337         return (error);
 1338 }
 1339 
 1340 /*
 1341  * Sysctl for udp variables.
 1342  */
 1343 SYSCTL_SETUP(sysctl_net_inet_udp_setup, "sysctl net.inet.udp subtree setup")
 1344 {
 1345 
 1346         sysctl_createv(clog, 0, NULL, NULL,
 1347                        CTLFLAG_PERMANENT,
 1348                        CTLTYPE_NODE, "net", NULL,
 1349                        NULL, 0, NULL, 0,
 1350                        CTL_NET, CTL_EOL);
 1351         sysctl_createv(clog, 0, NULL, NULL,
 1352                        CTLFLAG_PERMANENT,
 1353                        CTLTYPE_NODE, "inet", NULL,
 1354                        NULL, 0, NULL, 0,
 1355                        CTL_NET, PF_INET, CTL_EOL);
 1356         sysctl_createv(clog, 0, NULL, NULL,
 1357                        CTLFLAG_PERMANENT,
 1358                        CTLTYPE_NODE, "udp",
 1359                        SYSCTL_DESCR("UDPv4 related settings"),
 1360                        NULL, 0, NULL, 0,
 1361                        CTL_NET, PF_INET, IPPROTO_UDP, CTL_EOL);
 1362 
 1363         sysctl_createv(clog, 0, NULL, NULL,
 1364                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1365                        CTLTYPE_INT, "checksum",
 1366                        SYSCTL_DESCR("Compute UDP checksums"),
 1367                        NULL, 0, &udpcksum, 0,
 1368                        CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_CHECKSUM,
 1369                        CTL_EOL);
 1370         sysctl_createv(clog, 0, NULL, NULL,
 1371                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1372                        CTLTYPE_INT, "sendspace",
 1373                        SYSCTL_DESCR("Default UDP send buffer size"),
 1374                        NULL, 0, &udp_sendspace, 0,
 1375                        CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_SENDSPACE,
 1376                        CTL_EOL);
 1377         sysctl_createv(clog, 0, NULL, NULL,
 1378                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1379                        CTLTYPE_INT, "recvspace",
 1380                        SYSCTL_DESCR("Default UDP receive buffer size"),
 1381                        NULL, 0, &udp_recvspace, 0,
 1382                        CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_RECVSPACE,
 1383                        CTL_EOL);
 1384         sysctl_createv(clog, 0, NULL, NULL,
 1385                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 1386                        CTLTYPE_INT, "do_loopback_cksum",
 1387                        SYSCTL_DESCR("Perform UDP checksum on loopback"),
 1388                        NULL, 0, &udp_do_loopback_cksum, 0,
 1389                        CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_LOOPBACKCKSUM,
 1390                        CTL_EOL);
 1391         sysctl_createv(clog, 0, NULL, NULL,
 1392                        CTLFLAG_PERMANENT,
 1393                        CTLTYPE_STRUCT, "pcblist",
 1394                        SYSCTL_DESCR("UDP protocol control block list"),
 1395                        sysctl_inpcblist, 0, &udbtable, 0,
 1396                        CTL_NET, PF_INET, IPPROTO_UDP, CTL_CREATE,
 1397                        CTL_EOL);
 1398         sysctl_createv(clog, 0, NULL, NULL,
 1399                        CTLFLAG_PERMANENT,
 1400                        CTLTYPE_STRUCT, "stats",
 1401                        SYSCTL_DESCR("UDP statistics"),
 1402                        NULL, 0, &udpstat, sizeof(udpstat),
 1403                        CTL_NET, PF_INET, IPPROTO_UDP, UDPCTL_STATS,
 1404                        CTL_EOL);
 1405 }
 1406 #endif
 1407 
 1408 #if (defined INET && defined IPSEC_NAT_T)
 1409 /*
 1410  * Returns:
 1411  * 1 if the packet was processed
 1412  * 0 if normal UDP processing should take place
 1413  * -1 if an error occurent and m was freed
 1414  */
 1415 static int
 1416 udp4_espinudp(struct mbuf **mp, int off, struct sockaddr *src,
 1417     struct socket *so)
 1418 {
 1419         size_t len;
 1420         caddr_t data;
 1421         struct inpcb *inp;
 1422         size_t skip = 0;
 1423         size_t minlen;
 1424         size_t iphdrlen;
 1425         struct ip *ip;
 1426         struct mbuf *n;
 1427         struct m_tag *tag;
 1428         struct udphdr *udphdr;
 1429         u_int16_t sport, dport;
 1430         struct mbuf *m = *mp;
 1431 
 1432         /*
 1433          * Collapse the mbuf chain if the first mbuf is too short
 1434          * The longest case is: UDP + non ESP marker + ESP
 1435          */
 1436         minlen = off + sizeof(u_int64_t) + sizeof(struct esp);
 1437         if (minlen > m->m_pkthdr.len)
 1438                 minlen = m->m_pkthdr.len;
 1439 
 1440         if (m->m_len < minlen) {
 1441                 if ((*mp = m_pullup(m, minlen)) == NULL) {
 1442                         printf("udp4_espinudp: m_pullup failed\n");
 1443                         return -1;
 1444                 }
 1445                 m = *mp;
 1446         }
 1447 
 1448         len = m->m_len - off;
 1449         data = mtod(m, caddr_t) + off;
 1450         inp = sotoinpcb(so);
 1451 
 1452         /* Ignore keepalive packets */
 1453         if ((len == 1) && (data[0] == '\xff')) {
 1454                 return 1;
 1455         }
 1456 
 1457         /*
 1458          * Check that the payload is long enough to hold
 1459          * an ESP header and compute the length of encapsulation
 1460          * header to remove
 1461          */
 1462         if (inp->inp_flags & INP_ESPINUDP) {
 1463                 u_int32_t *st = (u_int32_t *)data;
 1464 
 1465                 if ((len <= sizeof(struct esp)) || (*st == 0))
 1466                         return 0; /* Normal UDP processing */
 1467 
 1468                 skip = sizeof(struct udphdr);
 1469         }
 1470 
 1471         if (inp->inp_flags & INP_ESPINUDP_NON_IKE) {
 1472                 u_int32_t *st = (u_int32_t *)data;
 1473 
 1474                 if ((len <= sizeof(u_int64_t) + sizeof(struct esp))
 1475                     || ((st[0] | st[1]) != 0))
 1476                         return 0; /* Normal UDP processing */
 1477 
 1478                 skip = sizeof(struct udphdr) + sizeof(u_int64_t);
 1479         }
 1480 
 1481         /*
 1482          * Get the UDP ports. They are handled in network 
 1483          * order everywhere in IPSEC_NAT_T code.
 1484          */
 1485         udphdr = (struct udphdr *)(data - skip);
 1486         sport = udphdr->uh_sport;
 1487         dport = udphdr->uh_dport;
 1488 
 1489         /*
 1490          * Remove the UDP header (and possibly the non ESP marker)
 1491          * IP header lendth is iphdrlen
 1492          * Before:
 1493          *   <--- off --->
 1494          *   +----+------+-----+
 1495          *   | IP |  UDP | ESP |
 1496          *   +----+------+-----+
 1497          *        <-skip->
 1498          * After:
 1499          *          +----+-----+
 1500          *          | IP | ESP |
 1501          *          +----+-----+
 1502          *   <-skip->
 1503          */
 1504         iphdrlen = off - sizeof(struct udphdr);
 1505         memmove(mtod(m, caddr_t) + skip, mtod(m, caddr_t), iphdrlen);
 1506         m_adj(m, skip);
 1507 
 1508         ip = mtod(m, struct ip *);
 1509         ip->ip_len = htons(ntohs(ip->ip_len) - skip);
 1510         ip->ip_p = IPPROTO_ESP;
 1511 
 1512         /*
 1513          * Copy the mbuf to avoid multiple free, as both
 1514          * esp4_input (which we call) and udp_input (which
 1515          * called us) free the mbuf.
 1516          */
 1517         if ((n = m_dup(m, 0, M_COPYALL, M_DONTWAIT)) == NULL) {
 1518                 printf("udp4_espinudp: m_dup failed\n");
 1519                 return 0;
 1520         }
 1521 
 1522         /*
 1523          * Add a PACKET_TAG_IPSEC_NAT_T_PORT tag to remember
 1524          * the source UDP port. This is required if we want
 1525          * to select the right SPD for multiple hosts behind 
 1526          * same NAT 
 1527          */
 1528         if ((tag = m_tag_get(PACKET_TAG_IPSEC_NAT_T_PORTS,
 1529             sizeof(sport) + sizeof(dport), M_DONTWAIT)) == NULL) {
 1530                 printf("udp4_espinudp: m_tag_get failed\n");
 1531                 m_freem(n);
 1532                 return 0;
 1533         }
 1534         ((u_int16_t *)(tag + 1))[0] = sport;
 1535         ((u_int16_t *)(tag + 1))[1] = dport;
 1536         m_tag_prepend(n, tag);
 1537 
 1538 #ifdef FAST_IPSEC
 1539         ipsec4_common_input(n, iphdrlen);
 1540 #else
 1541         esp4_input(n, iphdrlen);
 1542 #endif
 1543 
 1544         /* We handled it, it shoudln't be handled by UDP */
 1545         return 1;
 1546 }
 1547 #endif

Cache object: 67e5f95edc60c4d8f7ce92bad95db43f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.