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

          Line data    Source code
       1             : /*      $OpenBSD: udp6_output.c,v 1.56 2018/09/13 19:53:58 bluhm Exp $  */
       2             : /*      $KAME: udp6_output.c,v 1.21 2001/02/07 11:51:54 itojun Exp $    */
       3             : 
       4             : /*
       5             :  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
       6             :  * 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 project 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 PROJECT 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 PROJECT 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             : 
      33             : /*
      34             :  * Copyright (c) 1982, 1986, 1989, 1993
      35             :  *      The Regents of the University of California.  All rights reserved.
      36             :  *
      37             :  * Redistribution and use in source and binary forms, with or without
      38             :  * modification, are permitted provided that the following conditions
      39             :  * are met:
      40             :  * 1. Redistributions of source code must retain the above copyright
      41             :  *    notice, this list of conditions and the following disclaimer.
      42             :  * 2. Redistributions in binary form must reproduce the above copyright
      43             :  *    notice, this list of conditions and the following disclaimer in the
      44             :  *    documentation and/or other materials provided with the distribution.
      45             :  * 3. Neither the name of the University nor the names of its contributors
      46             :  *    may be used to endorse or promote products derived from this software
      47             :  *    without specific prior written permission.
      48             :  *
      49             :  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
      50             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      51             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      52             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
      53             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      54             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      55             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      56             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      57             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      58             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      59             :  * SUCH DAMAGE.
      60             :  */
      61             : 
      62             : #include "pf.h"
      63             : 
      64             : #include <sys/param.h>
      65             : #include <sys/mbuf.h>
      66             : #include <sys/protosw.h>
      67             : #include <sys/socket.h>
      68             : #include <sys/socketvar.h>
      69             : #include <sys/errno.h>
      70             : #include <sys/stat.h>
      71             : #include <sys/systm.h>
      72             : #include <sys/syslog.h>
      73             : 
      74             : #include <net/if.h>
      75             : #include <net/if_var.h>
      76             : #include <net/route.h>
      77             : #if NPF > 0
      78             : #include <net/pfvar.h>
      79             : #endif
      80             : 
      81             : #include <netinet/in.h>
      82             : #include <netinet6/in6_var.h>
      83             : #include <netinet/ip.h>
      84             : #include <netinet/ip_var.h>
      85             : #include <netinet/in_pcb.h>
      86             : #include <netinet/udp.h>
      87             : #include <netinet/udp_var.h>
      88             : #include <netinet/ip6.h>
      89             : #include <netinet6/ip6_var.h>
      90             : #include <netinet/icmp6.h>
      91             : #include <netinet6/ip6protosw.h>
      92             : 
      93             : /*
      94             :  * UDP protocol inplementation.
      95             :  * Per RFC 768, August, 1980.
      96             :  */
      97             : int
      98           0 : udp6_output(struct inpcb *in6p, struct mbuf *m, struct mbuf *addr6,
      99             :         struct mbuf *control)
     100             : {
     101           0 :         u_int32_t ulen = m->m_pkthdr.len;
     102           0 :         u_int32_t plen = sizeof(struct udphdr) + ulen;
     103             :         int error = 0, priv = 0, hlen, flags;
     104             :         struct ip6_hdr *ip6;
     105             :         struct udphdr *udp6;
     106           0 :         struct in6_addr *laddr, *faddr;
     107           0 :         struct ip6_pktopts *optp, opt;
     108           0 :         struct sockaddr_in6 tmp, valid;
     109           0 :         struct proc *p = curproc;       /* XXX */
     110             :         u_short fport;
     111             : 
     112           0 :         if ((in6p->inp_socket->so_state & SS_PRIV) != 0)
     113           0 :                 priv = 1;
     114           0 :         if (control) {
     115           0 :                 if ((error = ip6_setpktopts(control, &opt,
     116           0 :                     in6p->inp_outputopts6, priv, IPPROTO_UDP)) != 0)
     117             :                         goto release;
     118             :                 optp = &opt;
     119           0 :         } else
     120           0 :                 optp = in6p->inp_outputopts6;
     121             : 
     122           0 :         if (addr6) {
     123           0 :                 struct sockaddr_in6 *sin6;
     124             : 
     125           0 :                 if ((error = in6_nam2sin6(addr6, &sin6)))
     126           0 :                         goto release;
     127           0 :                 if (sin6->sin6_port == 0) {
     128             :                         error = EADDRNOTAVAIL;
     129           0 :                         goto release;
     130             :                 }
     131           0 :                 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
     132             :                         error = EADDRNOTAVAIL;
     133           0 :                         goto release;
     134             :                 }
     135           0 :                 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_faddr6)) {
     136             :                         error = EISCONN;
     137           0 :                         goto release;
     138             :                 }
     139             : 
     140             :                 /* protect *sin6 from overwrites */
     141           0 :                 tmp = *sin6;
     142           0 :                 sin6 = &tmp;
     143             : 
     144           0 :                 faddr = &sin6->sin6_addr;
     145           0 :                 fport = sin6->sin6_port; /* allow 0 port */
     146             : 
     147             :                 /* KAME hack: embed scopeid */
     148           0 :                 if (in6_embedscope(&sin6->sin6_addr, sin6, in6p) != 0) {
     149             :                         error = EINVAL;
     150           0 :                         goto release;
     151             :                 }
     152             : 
     153           0 :                 error = in6_pcbselsrc(&laddr, sin6, in6p, optp);
     154           0 :                 if (error)
     155           0 :                         goto release;
     156             : 
     157           0 :                 if (in6p->inp_lport == 0){
     158           0 :                         error = in_pcbbind(in6p, NULL, p);
     159           0 :                         if (error)
     160           0 :                                 goto release;
     161             :                 }
     162             : 
     163           0 :                 if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_laddr6) &&
     164           0 :                     !IN6_ARE_ADDR_EQUAL(&in6p->inp_laddr6, laddr)) {
     165           0 :                         valid.sin6_addr = *laddr;
     166           0 :                         valid.sin6_port = in6p->inp_lport;
     167           0 :                         valid.sin6_scope_id = 0;
     168           0 :                         valid.sin6_family = AF_INET6;
     169           0 :                         valid.sin6_len = sizeof(valid);
     170           0 :                         error = in6_pcbaddrisavail(in6p, &valid, 0, p);
     171           0 :                         if (error)
     172           0 :                                 goto release;
     173             :                 }
     174           0 :         } else {
     175           0 :                 if (IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_faddr6)) {
     176             :                         error = ENOTCONN;
     177           0 :                         goto release;
     178             :                 }
     179           0 :                 laddr = &in6p->inp_laddr6;
     180             :                 faddr = &in6p->inp_faddr6;
     181           0 :                 fport = in6p->inp_fport;
     182             :         }
     183             : 
     184             :         hlen = sizeof(struct ip6_hdr);
     185             : 
     186             :         /*
     187             :          * Calculate data length and get a mbuf
     188             :          * for UDP and IP6 headers.
     189             :          */
     190           0 :         M_PREPEND(m, hlen + sizeof(struct udphdr), M_DONTWAIT);
     191           0 :         if (m == NULL) {
     192             :                 error = ENOBUFS;
     193           0 :                 goto releaseopt;
     194             :         }
     195             : 
     196             :         /*
     197             :          * Stuff checksum and output datagram.
     198             :          */
     199           0 :         udp6 = (struct udphdr *)(mtod(m, caddr_t) + hlen);
     200           0 :         udp6->uh_sport = in6p->inp_lport; /* lport is always set in the PCB */
     201           0 :         udp6->uh_dport = fport;
     202           0 :         if (plen <= 0xffff)
     203           0 :                 udp6->uh_ulen = htons((u_short)plen);
     204             :         else
     205           0 :                 udp6->uh_ulen = 0;
     206           0 :         udp6->uh_sum = 0;
     207             : 
     208           0 :         ip6 = mtod(m, struct ip6_hdr *);
     209           0 :         ip6->ip6_flow        = in6p->inp_flowinfo & IPV6_FLOWINFO_MASK;
     210           0 :         ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
     211           0 :         ip6->ip6_vfc |= IPV6_VERSION;
     212             : #if 0   /* ip6_plen will be filled in ip6_output. */
     213             :         ip6->ip6_plen        = htons((u_short)plen);
     214             : #endif
     215           0 :         ip6->ip6_nxt = IPPROTO_UDP;
     216           0 :         ip6->ip6_hlim        = in6_selecthlim(in6p);
     217           0 :         ip6->ip6_src = *laddr;
     218           0 :         ip6->ip6_dst = *faddr;
     219             : 
     220           0 :         m->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
     221             : 
     222             :         flags = 0;
     223           0 :         if (in6p->inp_flags & IN6P_MINMTU)
     224           0 :                 flags |= IPV6_MINMTU;
     225             : 
     226           0 :         udpstat_inc(udps_opackets);
     227             : 
     228             :         /* force routing table */
     229           0 :         m->m_pkthdr.ph_rtableid = in6p->inp_rtableid;
     230             : 
     231             : #if NPF > 0
     232           0 :         if (in6p->inp_socket->so_state & SS_ISCONNECTED)
     233           0 :                 pf_mbuf_link_inpcb(m, in6p);
     234             : #endif
     235             : 
     236           0 :         error = ip6_output(m, optp, &in6p->inp_route6,
     237           0 :             flags, in6p->inp_moptions6, in6p);
     238           0 :         goto releaseopt;
     239             : 
     240             : release:
     241           0 :         m_freem(m);
     242             : 
     243             : releaseopt:
     244           0 :         if (control) {
     245           0 :                 ip6_clearpktopts(&opt, -1);
     246           0 :                 m_freem(control);
     247           0 :         }
     248           0 :         return (error);
     249           0 : }

Generated by: LCOV version 1.13