text:
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

// +godefs map struct_in6_addr [16]byte /* in6_addr */

package ipv6

/*
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
#include <linux/filter.h>
#include <sys/socket.h>
*/
import "C"

const (
	sysIPV6_ADDRFORM       = C.IPV6_ADDRFORM
	sysIPV6_2292PKTINFO    = C.IPV6_2292PKTINFO
	sysIPV6_2292HOPOPTS    = C.IPV6_2292HOPOPTS
	sysIPV6_2292DSTOPTS    = C.IPV6_2292DSTOPTS
	sysIPV6_2292RTHDR      = C.IPV6_2292RTHDR
	sysIPV6_2292PKTOPTIONS = C.IPV6_2292PKTOPTIONS
	sysIPV6_CHECKSUM       = C.IPV6_CHECKSUM
	sysIPV6_2292HOPLIMIT   = C.IPV6_2292HOPLIMIT
	sysIPV6_NEXTHOP        = C.IPV6_NEXTHOP
	sysIPV6_FLOWINFO       = C.IPV6_FLOWINFO

	sysIPV6_UNICAST_HOPS        = C.IPV6_UNICAST_HOPS
	sysIPV6_MULTICAST_IF        = C.IPV6_MULTICAST_IF
	sysIPV6_MULTICAST_HOPS      = C.IPV6_MULTICAST_HOPS
	sysIPV6_MULTICAST_LOOP      = C.IPV6_MULTICAST_LOOP
	sysIPV6_ADD_MEMBERSHIP      = C.IPV6_ADD_MEMBERSHIP
	sysIPV6_DROP_MEMBERSHIP     = C.IPV6_DROP_MEMBERSHIP
	sysMCAST_JOIN_GROUP         = C.MCAST_JOIN_GROUP
	sysMCAST_LEAVE_GROUP        = C.MCAST_LEAVE_GROUP
	sysMCAST_JOIN_SOURCE_GROUP  = C.MCAST_JOIN_SOURCE_GROUP
	sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP
	sysMCAST_BLOCK_SOURCE       = C.MCAST_BLOCK_SOURCE
	sysMCAST_UNBLOCK_SOURCE     = C.MCAST_UNBLOCK_SOURCE
	sysMCAST_MSFILTER           = C.MCAST_MSFILTER
	sysIPV6_ROUTER_ALERT        = C.IPV6_ROUTER_ALERT
	sysIPV6_MTU_DISCOVER        = C.IPV6_MTU_DISCOVER
	sysIPV6_MTU                 = C.IPV6_MTU
	sysIPV6_RECVERR             = C.IPV6_RECVERR
	sysIPV6_V6ONLY              = C.IPV6_V6ONLY
	sysIPV6_JOIN_ANYCAST        = C.IPV6_JOIN_ANYCAST
	sysIPV6_LEAVE_ANYCAST       = C.IPV6_LEAVE_ANYCAST

	//sysIPV6_PMTUDISC_DONT      = C.IPV6_PMTUDISC_DONT
	//sysIPV6_PMTUDISC_WANT      = C.IPV6_PMTUDISC_WANT
	//sysIPV6_PMTUDISC_DO        = C.IPV6_PMTUDISC_DO
	//sysIPV6_PMTUDISC_PROBE     = C.IPV6_PMTUDISC_PROBE
	//sysIPV6_PMTUDISC_INTERFACE = C.IPV6_PMTUDISC_INTERFACE
	//sysIPV6_PMTUDISC_OMIT      = C.IPV6_PMTUDISC_OMIT

	sysIPV6_FLOWLABEL_MGR = C.IPV6_FLOWLABEL_MGR
	sysIPV6_FLOWINFO_SEND = C.IPV6_FLOWINFO_SEND

	sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY
	sysIPV6_XFRM_POLICY  = C.IPV6_XFRM_POLICY

	sysIPV6_RECVPKTINFO  = C.IPV6_RECVPKTINFO
	sysIPV6_PKTINFO      = C.IPV6_PKTINFO
	sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
	sysIPV6_HOPLIMIT     = C.IPV6_HOPLIMIT
	sysIPV6_RECVHOPOPTS  = C.IPV6_RECVHOPOPTS
	sysIPV6_HOPOPTS      = C.IPV6_HOPOPTS
	sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS
	sysIPV6_RECVRTHDR    = C.IPV6_RECVRTHDR
	sysIPV6_RTHDR        = C.IPV6_RTHDR
	sysIPV6_RECVDSTOPTS  = C.IPV6_RECVDSTOPTS
	sysIPV6_DSTOPTS      = C.IPV6_DSTOPTS
	sysIPV6_RECVPATHMTU  = C.IPV6_RECVPATHMTU
	sysIPV6_PATHMTU      = C.IPV6_PATHMTU
	sysIPV6_DONTFRAG     = C.IPV6_DONTFRAG

	sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS
	sysIPV6_TCLASS     = C.IPV6_TCLASS

	sysIPV6_ADDR_PREFERENCES = C.IPV6_ADDR_PREFERENCES

	sysIPV6_PREFER_SRC_TMP            = C.IPV6_PREFER_SRC_TMP
	sysIPV6_PREFER_SRC_PUBLIC         = C.IPV6_PREFER_SRC_PUBLIC
	sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = C.IPV6_PREFER_SRC_PUBTMP_DEFAULT
	sysIPV6_PREFER_SRC_COA            = C.IPV6_PREFER_SRC_COA
	sysIPV6_PREFER_SRC_HOME           = C.IPV6_PREFER_SRC_HOME
	sysIPV6_PREFER_SRC_CGA            = C.IPV6_PREFER_SRC_CGA
	sysIPV6_PREFER_SRC_NONCGA         = C.IPV6_PREFER_SRC_NONCGA

	sysIPV6_MINHOPCOUNT = C.IPV6_MINHOPCOUNT

	sysIPV6_ORIGDSTADDR     = C.IPV6_ORIGDSTADDR
	sysIPV6_RECVORIGDSTADDR = C.IPV6_RECVORIGDSTADDR
	sysIPV6_TRANSPARENT     = C.IPV6_TRANSPARENT
	sysIPV6_UNICAST_IF      = C.IPV6_UNICAST_IF

	sysICMPV6_FILTER = C.ICMPV6_FILTER

	sysICMPV6_FILTER_BLOCK       = C.ICMPV6_FILTER_BLOCK
	sysICMPV6_FILTER_PASS        = C.ICMPV6_FILTER_PASS
	sysICMPV6_FILTER_BLOCKOTHERS = C.ICMPV6_FILTER_BLOCKOTHERS
	sysICMPV6_FILTER_PASSONLY    = C.ICMPV6_FILTER_PASSONLY

	sysSOL_SOCKET       = C.SOL_SOCKET
	sysSO_ATTACH_FILTER = C.SO_ATTACH_FILTER

	sizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage
	sizeofSockaddrInet6         = C.sizeof_struct_sockaddr_in6
	sizeofInet6Pktinfo          = C.sizeof_struct_in6_pktinfo
	sizeofIPv6Mtuinfo           = C.sizeof_struct_ip6_mtuinfo
	sizeofIPv6FlowlabelReq      = C.sizeof_struct_in6_flowlabel_req

	sizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
	sizeofGroupReq       = C.sizeof_struct_group_req
	sizeofGroupSourceReq = C.sizeof_struct_group_source_req

	sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter

	sizeofSockFprog = C.sizeof_struct_sock_fprog
)

type kernelSockaddrStorage C.struct___kernel_sockaddr_storage

type sockaddrInet6 C.struct_sockaddr_in6

type inet6Pktinfo C.struct_in6_pktinfo

type ipv6Mtuinfo C.struct_ip6_mtuinfo

type ipv6FlowlabelReq C.struct_in6_flowlabel_req

type ipv6Mreq C.struct_ipv6_mreq

type groupReq C.struct_group_req

type groupSourceReq C.struct_group_source_req

type icmpv6Filter C.struct_icmp6_filter

type sockFProg C.struct_sock_fprog

type sockFilter C.struct_sock_filter


text:
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build go1.9
// +build !nacl,!plan9,!windows

package ipv6

import (
	"net"

	"golang.org/x/net/internal/socket"
)

func (c *payloadHandler) readFrom(b []byte) (int, *ControlMessage, net.Addr, error) {
	c.rawOpt.RLock()
	m := socket.Message{
		Buffers: [][]byte{b},
		OOB:     NewControlMessage(c.rawOpt.cflags),
	}
	c.rawOpt.RUnlock()
	switch c.PacketConn.(type) {
	case *net.UDPConn:
		if err := c.RecvMsg(&m, 0); err != nil {
			return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
		}
	case *net.IPConn:
		if err := c.RecvMsg(&m, 0); err != nil {
			return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
		}
	default:
		return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errInvalidConnType}
	}
	var cm *ControlMessage
	if m.NN > 0 {
		cm = new(ControlMessage)
		if err := cm.Parse(m.OOB[:m.NN]); err != nil {
			return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
		}
		cm.Src = netAddrToIP16(m.Addr)
	}
	return m.N, cm, m.Addr, nil
}

func (c *payloadHandler) writeTo(b []byte, cm *ControlMessage, dst net.Addr) (int, error) {
	m := socket.Message{
		Buffers: [][]byte{b},
		OOB:     cm.Marshal(),
		Addr:    dst,
	}
	err := c.SendMsg(&m, 0)
	if err != nil {
		err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Addr: opAddr(dst), Err: err}
	}
	return m.N, err
}

repo_name: dan-v/dosxvpn

repo_language: Go

mime_type: text/x-shellscript


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6

import (
	"net"
	"strconv"
	"strings"
	"syscall"
	"unsafe"

	"golang.org/x/net/internal/iana"
	"golang.org/x/net/internal/socket"
)

var (
	ctlOpts = [ctlMax]ctlOpt{
		ctlHopLimit:   {sysIPV6_2292HOPLIMIT, 4, marshal2292HopLimit, parseHopLimit},
		ctlPacketInfo: {sysIPV6_2292PKTINFO, sizeofInet6Pktinfo, marshal2292PacketInfo, parsePacketInfo},
	}

	sockOpts = map[int]*sockOpt{
		ssoHopLimit:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
		ssoMulticastInterface: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
		ssoMulticastHopLimit:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
		ssoMulticastLoopback:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
		ssoReceiveHopLimit:    {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_2292HOPLIMIT, Len: 4}},
		ssoReceivePacketInfo:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_2292PKTINFO, Len: 4}},
		ssoChecksum:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
		ssoICMPFilter:         {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
		ssoJoinGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
		ssoLeaveGroup:         {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
	}
)

func init() {
	// Seems like kern.osreldate is veiled on latest OS X. We use
	// kern.osrelease instead.
	s, err := syscall.Sysctl("kern.osrelease")
	if err != nil {
		return
	}
	ss := strings.Split(s, ".")
	if len(ss) == 0 {
		return
	}
	// The IP_PKTINFO and protocol-independent multicast API were
	// introduced in OS X 10.7 (Darwin 11). But it looks like
	// those features require OS X 10.8 (Darwin 12) or above.
	// See http://support.apple.com/kb/HT1633.
	if mjver, err := strconv.Atoi(ss[0]); err != nil || mjver < 12 {
		return
	}
	ctlOpts[ctlTrafficClass] = ctlOpt{sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass}
	ctlOpts[ctlHopLimit] = ctlOpt{sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit}
	ctlOpts[ctlPacketInfo] = ctlOpt{sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo}
	ctlOpts[ctlNextHop] = ctlOpt{sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop}
	ctlOpts[ctlPathMTU] = ctlOpt{sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU}
	sockOpts[ssoTrafficClass] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}}
	sockOpts[ssoReceiveTrafficClass] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}}
	sockOpts[ssoReceiveHopLimit] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}}
	sockOpts[ssoReceivePacketInfo] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}}
	sockOpts[ssoReceivePathMTU] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}}
	sockOpts[ssoPathMTU] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}}
	sockOpts[ssoJoinGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
	sockOpts[ssoLeaveGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_GROUP, Len: sizeofGroupReq}, typ: ssoTypeGroupReq}
	sockOpts[ssoJoinSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_JOIN_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
	sockOpts[ssoLeaveSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_LEAVE_SOURCE_GROUP, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
	sockOpts[ssoBlockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_BLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
	sockOpts[ssoUnblockSourceGroup] = &sockOpt{Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysMCAST_UNBLOCK_SOURCE, Len: sizeofGroupSourceReq}, typ: ssoTypeGroupSourceReq}
}

func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
	sa.Len = sizeofSockaddrInet6
	sa.Family = syscall.AF_INET6
	copy(sa.Addr[:], ip)
	sa.Scope_id = uint32(i)
}

func (pi *inet6Pktinfo) setIfindex(i int) {
	pi.Ifindex = uint32(i)
}

func (mreq *ipv6Mreq) setIfindex(i int) {
	mreq.Interface = uint32(i)
}

func (gr *groupReq) setGroup(grp net.IP) {
	sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gr)) + 4))
	sa.Len = sizeofSockaddrInet6
	sa.Family = syscall.AF_INET6
	copy(sa.Addr[:], grp)
}

func (gsr *groupSourceReq) setSourceGroup(grp, src net.IP) {
	sa := (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 4))
	sa.Len = sizeofSockaddrInet6
	sa.Family = syscall.AF_INET6
	copy(sa.Addr[:], grp)
	sa = (*sockaddrInet6)(unsafe.Pointer(uintptr(unsafe.Pointer(gsr)) + 132))
	sa.Len = sizeofSockaddrInet6
	sa.Family = syscall.AF_INET6
	copy(sa.Addr[:], src)
}


text:
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

// +godefs map struct_in6_addr [16]byte /* in6_addr */

package ipv6

/*
#define __APPLE_USE_RFC_3542
#include <netinet/in.h>
#include <netinet/icmp6.h>
*/
import "C"

const (
	sysIPV6_UNICAST_HOPS   = C.IPV6_UNICAST_HOPS
	sysIPV6_MULTICAST_IF   = C.IPV6_MULTICAST_IF
	sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
	sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
	sysIPV6_JOIN_GROUP     = C.IPV6_JOIN_GROUP
	sysIPV6_LEAVE_GROUP    = C.IPV6_LEAVE_GROUP

	sysIPV6_PORTRANGE    = C.IPV6_PORTRANGE
	sysICMP6_FILTER      = C.ICMP6_FILTER
	sysIPV6_2292PKTINFO  = C.IPV6_2292PKTINFO
	sysIPV6_2292HOPLIMIT = C.IPV6_2292HOPLIMIT
	sysIPV6_2292NEXTHOP  = C.IPV6_2292NEXTHOP
	sysIPV6_2292HOPOPTS  = C.IPV6_2292HOPOPTS
	sysIPV6_2292DSTOPTS  = C.IPV6_2292DSTOPTS
	sysIPV6_2292RTHDR    = C.IPV6_2292RTHDR

	sysIPV6_2292PKTOPTIONS = C.IPV6_2292PKTOPTIONS

	sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
	sysIPV6_V6ONLY   = C.IPV6_V6ONLY

	sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY

	sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS
	sysIPV6_TCLASS     = C.IPV6_TCLASS

	sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS

	sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO

	sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
	sysIPV6_RECVRTHDR    = C.IPV6_RECVRTHDR
	sysIPV6_RECVHOPOPTS  = C.IPV6_RECVHOPOPTS
	sysIPV6_RECVDSTOPTS  = C.IPV6_RECVDSTOPTS

	sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU
	sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU

	sysIPV6_PATHMTU = C.IPV6_PATHMTU

	sysIPV6_PKTINFO  = C.IPV6_PKTINFO
	sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
	sysIPV6_NEXTHOP  = C.IPV6_NEXTHOP
	sysIPV6_HOPOPTS  = C.IPV6_HOPOPTS
	sysIPV6_DSTOPTS  = C.IPV6_DSTOPTS
	sysIPV6_RTHDR    = C.IPV6_RTHDR

	sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL

	sysIPV6_DONTFRAG = C.IPV6_DONTFRAG

	sysIPV6_PREFER_TEMPADDR = C.IPV6_PREFER_TEMPADDR

	sysIPV6_MSFILTER            = C.IPV6_MSFILTER
	sysMCAST_JOIN_GROUP         = C.MCAST_JOIN_GROUP
	sysMCAST_LEAVE_GROUP        = C.MCAST_LEAVE_GROUP
	sysMCAST_JOIN_SOURCE_GROUP  = C.MCAST_JOIN_SOURCE_GROUP
	sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP
	sysMCAST_BLOCK_SOURCE       = C.MCAST_BLOCK_SOURCE
	sysMCAST_UNBLOCK_SOURCE     = C.MCAST_UNBLOCK_SOURCE

	sysIPV6_BOUND_IF = C.IPV6_BOUND_IF

	sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT
	sysIPV6_PORTRANGE_HIGH    = C.IPV6_PORTRANGE_HIGH
	sysIPV6_PORTRANGE_LOW     = C.IPV6_PORTRANGE_LOW

	sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
	sizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
	sizeofInet6Pktinfo    = C.sizeof_struct_in6_pktinfo
	sizeofIPv6Mtuinfo     = C.sizeof_struct_ip6_mtuinfo

	sizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
	sizeofGroupReq       = C.sizeof_struct_group_req
	sizeofGroupSourceReq = C.sizeof_struct_group_source_req

	sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
)

type sockaddrStorage C.struct_sockaddr_storage

type sockaddrInet6 C.struct_sockaddr_in6

type inet6Pktinfo C.struct_in6_pktinfo

type ipv6Mtuinfo C.struct_ip6_mtuinfo

type ipv6Mreq C.struct_ipv6_mreq

type icmpv6Filter C.struct_icmp6_filter

type groupReq C.struct_group_req

type groupSourceReq C.struct_group_source_req


text:
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6_test

import (
	"fmt"
	"log"
	"net"
	"os"
	"time"

	"golang.org/x/net/icmp"
	"golang.org/x/net/ipv6"
)

func ExampleConn_markingTCP() {
	ln, err := net.Listen("tcp", "[::]:1024")
	if err != nil {
		log.Fatal(err)
	}
	defer ln.Close()

	for {
		c, err := ln.Accept()
		if err != nil {
			log.Fatal(err)
		}
		go func(c net.Conn) {
			defer c.Close()
			if c.RemoteAddr().(*net.TCPAddr).IP.To16() != nil && c.RemoteAddr().(*net.TCPAddr).IP.To4() == nil {
				p := ipv6.NewConn(c)
				if err := p.SetTrafficClass(0x28); err != nil { // DSCP AF11
					log.Fatal(err)
				}
				if err := p.SetHopLimit(128); err != nil {
					log.Fatal(err)
				}
			}
			if _, err := c.Write([]byte("HELLO-R-U-THERE-ACK")); err != nil {
				log.Fatal(err)
			}
		}(c)
	}
}

func ExamplePacketConn_servingOneShotMulticastDNS() {
	c, err := net.ListenPacket("udp6", "[::]:5353") // mDNS over UDP
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()
	p := ipv6.NewPacketConn(c)

	en0, err := net.InterfaceByName("en0")
	if err != nil {
		log.Fatal(err)
	}
	mDNSLinkLocal := net.UDPAddr{IP: net.ParseIP("ff02::fb")}
	if err := p.JoinGroup(en0, &mDNSLinkLocal); err != nil {
		log.Fatal(err)
	}
	defer p.LeaveGroup(en0, &mDNSLinkLocal)
	if err := p.SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true); err != nil {
		log.Fatal(err)
	}

	var wcm ipv6.ControlMessage
	b := make([]byte, 1500)
	for {
		_, rcm, peer, err := p.ReadFrom(b)
		if err != nil {
			log.Fatal(err)
		}
		if !rcm.Dst.IsMulticast() || !rcm.Dst.Equal(mDNSLinkLocal.IP) {
			continue
		}
		wcm.IfIndex = rcm.IfIndex
		answers := []byte("FAKE-MDNS-ANSWERS") // fake mDNS answers, you need to implement this
		if _, err := p.WriteTo(answers, &wcm, peer); err != nil {
			log.Fatal(err)
		}
	}
}

func ExamplePacketConn_tracingIPPacketRoute() {
	// Tracing an IP packet route to www.google.com.

	const host = "www.google.com"
	ips, err := net.LookupIP(host)
	if err != nil {
		log.Fatal(err)
	}
	var dst net.IPAddr
	for _, ip := range ips {
		if ip.To16() != nil && ip.To4() == nil {
			dst.IP = ip
			fmt.Printf("using %v for tracing an IP packet route to %s\n", dst.IP, host)
			break
		}
	}
	if dst.IP == nil {
		log.Fatal("no AAAA record found")
	}

	c, err := net.ListenPacket("ip6:58", "::") // ICMP for IPv6
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()
	p := ipv6.NewPacketConn(c)

	if err := p.SetControlMessage(ipv6.FlagHopLimit|ipv6.FlagSrc|ipv6.FlagDst|ipv6.FlagInterface, true); err != nil {
		log.Fatal(err)
	}
	wm := icmp.Message{
		Type: ipv6.ICMPTypeEchoRequest, Code: 0,
		Body: &icmp.Echo{
			ID:   os.Getpid() & 0xffff,
			Data: []byte("HELLO-R-U-THERE"),
		},
	}
	var f ipv6.ICMPFilter
	f.SetAll(true)
	f.Accept(ipv6.ICMPTypeTimeExceeded)
	f.Accept(ipv6.ICMPTypeEchoReply)
	if err := p.SetICMPFilter(&f); err != nil {
		log.Fatal(err)
	}

	var wcm ipv6.ControlMessage
	rb := make([]byte, 1500)
	for i := 1; i <= 64; i++ { // up to 64 hops
		wm.Body.(*icmp.Echo).Seq = i
		wb, err := wm.Marshal(nil)
		if err != nil {
			log.Fatal(err)
		}

		// In the real world usually there are several
		// multiple traffic-engineered paths for each hop.
		// You may need to probe a few times to each hop.
		begin := time.Now()
		wcm.HopLimit = i
		if _, err := p.WriteTo(wb, &wcm, &dst); err != nil {
			log.Fatal(err)
		}
		if err := p.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil {
			log.Fatal(err)
		}
		n, rcm, peer, err := p.ReadFrom(rb)
		if err != nil {
			if err, ok := err.(net.Error); ok && err.Timeout() {
				fmt.Printf("%v\t*\n", i)
				continue
			}
			log.Fatal(err)
		}
		rm, err := icmp.ParseMessage(58, rb[:n])
		if err != nil {
			log.Fatal(err)
		}
		rtt := time.Since(begin)

		// In the real world you need to determine whether the
		// received message is yours using ControlMessage.Src,
		// ControlMesage.Dst, icmp.Echo.ID and icmp.Echo.Seq.
		switch rm.Type {
		case ipv6.ICMPTypeTimeExceeded:
			names, _ := net.LookupAddr(peer.String())
			fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, rcm)
		case ipv6.ICMPTypeEchoReply:
			names, _ := net.LookupAddr(peer.String())
			fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, rcm)
			return
		}
	}
}

func ExamplePacketConn_advertisingOSPFHello() {
	c, err := net.ListenPacket("ip6:89", "::") // OSPF for IPv6
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()
	p := ipv6.NewPacketConn(c)

	en0, err := net.InterfaceByName("en0")
	if err != nil {
		log.Fatal(err)
	}
	allSPFRouters := net.IPAddr{IP: net.ParseIP("ff02::5")}
	if err := p.JoinGroup(en0, &allSPFRouters); err != nil {
		log.Fatal(err)
	}
	defer p.LeaveGroup(en0, &allSPFRouters)

	hello := make([]byte, 24) // fake hello data, you need to implement this
	ospf := make([]byte, 16)  // fake ospf header, you need to implement this
	ospf[0] = 3               // version 3
	ospf[1] = 1               // hello packet
	ospf = append(ospf, hello...)
	if err := p.SetChecksum(true, 12); err != nil {
		log.Fatal(err)
	}

	cm := ipv6.ControlMessage{
		TrafficClass: 0xc0, // DSCP CS6
		HopLimit:     1,
		IfIndex:      en0.Index,
	}
	if _, err := p.WriteTo(ospf, &cm, &allSPFRouters); err != nil {
		log.Fatal(err)
	}
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !go1.9
// +build !nacl,!plan9,!windows

package ipv6

import "net"

func (c *payloadHandler) readFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
	c.rawOpt.RLock()
	oob := NewControlMessage(c.rawOpt.cflags)
	c.rawOpt.RUnlock()
	var nn int
	switch c := c.PacketConn.(type) {
	case *net.UDPConn:
		if n, nn, _, src, err = c.ReadMsgUDP(b, oob); err != nil {
			return 0, nil, nil, err
		}
	case *net.IPConn:
		if n, nn, _, src, err = c.ReadMsgIP(b, oob); err != nil {
			return 0, nil, nil, err
		}
	default:
		return 0, nil, nil, &net.OpError{Op: "read", Net: c.LocalAddr().Network(), Source: c.LocalAddr(), Err: errInvalidConnType}
	}
	if nn > 0 {
		cm = new(ControlMessage)
		if err = cm.Parse(oob[:nn]); err != nil {
			return 0, nil, nil, &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
		}
	}
	if cm != nil {
		cm.Src = netAddrToIP16(src)
	}
	return
}

func (c *payloadHandler) writeTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
	oob := cm.Marshal()
	if dst == nil {
		return 0, &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: errMissingAddress}
	}
	switch c := c.PacketConn.(type) {
	case *net.UDPConn:
		n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr))
	case *net.IPConn:
		n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr))
	default:
		return 0, &net.OpError{Op: "write", Net: c.LocalAddr().Network(), Source: c.LocalAddr(), Addr: opAddr(dst), Err: errInvalidConnType}
	}
	return
}


text:
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6

import "golang.org/x/net/internal/socket"

// Sticky socket options
const (
	ssoTrafficClass        = iota // header field for unicast packet, RFC 3542
	ssoHopLimit                   // header field for unicast packet, RFC 3493
	ssoMulticastInterface         // outbound interface for multicast packet, RFC 3493
	ssoMulticastHopLimit          // header field for multicast packet, RFC 3493
	ssoMulticastLoopback          // loopback for multicast packet, RFC 3493
	ssoReceiveTrafficClass        // header field on received packet, RFC 3542
	ssoReceiveHopLimit            // header field on received packet, RFC 2292 or 3542
	ssoReceivePacketInfo          // incbound or outbound packet path, RFC 2292 or 3542
	ssoReceivePathMTU             // path mtu, RFC 3542
	ssoPathMTU                    // path mtu, RFC 3542
	ssoChecksum                   // packet checksum, RFC 2292 or 3542
	ssoICMPFilter                 // icmp filter, RFC 2292 or 3542
	ssoJoinGroup                  // any-source multicast, RFC 3493
	ssoLeaveGroup                 // any-source multicast, RFC 3493
	ssoJoinSourceGroup            // source-specific multicast
	ssoLeaveSourceGroup           // source-specific multicast
	ssoBlockSourceGroup           // any-source or source-specific multicast
	ssoUnblockSourceGroup         // any-source or source-specific multicast
	ssoAttachFilter               // attach BPF for filtering inbound traffic
)

// Sticky socket option value types
const (
	ssoTypeIPMreq = iota + 1
	ssoTypeGroupReq
	ssoTypeGroupSourceReq
)

// A sockOpt represents a binding for sticky socket option.
type sockOpt struct {
	socket.Option
	typ int // hint for option value type; optional
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows

package ipv6

type icmpv6Filter struct {
}

func (f *icmpv6Filter) accept(typ ICMPType) {
}

func (f *icmpv6Filter) block(typ ICMPType) {
}

func (f *icmpv6Filter) setAll(block bool) {
}

func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
	return false
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows

package ipv6

import (
	"net"
	"unsafe"

	"golang.org/x/net/bpf"
	"golang.org/x/net/internal/socket"
)

func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
	n, err := so.GetInt(c)
	if err != nil {
		return nil, err
	}
	return net.InterfaceByIndex(n)
}

func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
	var n int
	if ifi != nil {
		n = ifi.Index
	}
	return so.SetInt(c, n)
}

func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
	b := make([]byte, so.Len)
	n, err := so.Get(c, b)
	if err != nil {
		return nil, err
	}
	if n != sizeofICMPv6Filter {
		return nil, errOpNoSupport
	}
	return (*ICMPFilter)(unsafe.Pointer(&b[0])), nil
}

func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
	b := (*[sizeofICMPv6Filter]byte)(unsafe.Pointer(f))[:sizeofICMPv6Filter]
	return so.Set(c, b)
}

func (so *sockOpt) getMTUInfo(c *socket.Conn) (*net.Interface, int, error) {
	b := make([]byte, so.Len)
	n, err := so.Get(c, b)
	if err != nil {
		return nil, 0, err
	}
	if n != sizeofIPv6Mtuinfo {
		return nil, 0, errOpNoSupport
	}
	mi := (*ipv6Mtuinfo)(unsafe.Pointer(&b[0]))
	if mi.Addr.Scope_id == 0 {
		return nil, int(mi.Mtu), nil
	}
	ifi, err := net.InterfaceByIndex(int(mi.Addr.Scope_id))
	if err != nil {
		return nil, 0, err
	}
	return ifi, int(mi.Mtu), nil
}

func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
	switch so.typ {
	case ssoTypeIPMreq:
		return so.setIPMreq(c, ifi, grp)
	case ssoTypeGroupReq:
		return so.setGroupReq(c, ifi, grp)
	default:
		return errOpNoSupport
	}
}

func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
	return so.setGroupSourceReq(c, ifi, grp, src)
}

func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
	return so.setAttachFilter(c, f)
}


text:
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs defs_linux.go

package ipv6

const (
	sysIPV6_ADDRFORM       = 0x1
	sysIPV6_2292PKTINFO    = 0x2
	sysIPV6_2292HOPOPTS    = 0x3
	sysIPV6_2292DSTOPTS    = 0x4
	sysIPV6_2292RTHDR      = 0x5
	sysIPV6_2292PKTOPTIONS = 0x6
	sysIPV6_CHECKSUM       = 0x7
	sysIPV6_2292HOPLIMIT   = 0x8
	sysIPV6_NEXTHOP        = 0x9
	sysIPV6_FLOWINFO       = 0xb

	sysIPV6_UNICAST_HOPS        = 0x10
	sysIPV6_MULTICAST_IF        = 0x11
	sysIPV6_MULTICAST_HOPS      = 0x12
	sysIPV6_MULTICAST_LOOP      = 0x13
	sysIPV6_ADD_MEMBERSHIP      = 0x14
	sysIPV6_DROP_MEMBERSHIP     = 0x15
	sysMCAST_JOIN_GROUP         = 0x2a
	sysMCAST_LEAVE_GROUP        = 0x2d
	sysMCAST_JOIN_SOURCE_GROUP  = 0x2e
	sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
	sysMCAST_BLOCK_SOURCE       = 0x2b
	sysMCAST_UNBLOCK_SOURCE     = 0x2c
	sysMCAST_MSFILTER           = 0x30
	sysIPV6_ROUTER_ALERT        = 0x16
	sysIPV6_MTU_DISCOVER        = 0x17
	sysIPV6_MTU                 = 0x18
	sysIPV6_RECVERR             = 0x19
	sysIPV6_V6ONLY              = 0x1a
	sysIPV6_JOIN_ANYCAST        = 0x1b
	sysIPV6_LEAVE_ANYCAST       = 0x1c

	sysIPV6_FLOWLABEL_MGR = 0x20
	sysIPV6_FLOWINFO_SEND = 0x21

	sysIPV6_IPSEC_POLICY = 0x22
	sysIPV6_XFRM_POLICY  = 0x23

	sysIPV6_RECVPKTINFO  = 0x31
	sysIPV6_PKTINFO      = 0x32
	sysIPV6_RECVHOPLIMIT = 0x33
	sysIPV6_HOPLIMIT     = 0x34
	sysIPV6_RECVHOPOPTS  = 0x35
	sysIPV6_HOPOPTS      = 0x36
	sysIPV6_RTHDRDSTOPTS = 0x37
	sysIPV6_RECVRTHDR    = 0x38
	sysIPV6_RTHDR        = 0x39
	sysIPV6_RECVDSTOPTS  = 0x3a
	sysIPV6_DSTOPTS      = 0x3b
	sysIPV6_RECVPATHMTU  = 0x3c
	sysIPV6_PATHMTU      = 0x3d
	sysIPV6_DONTFRAG     = 0x3e

	sysIPV6_RECVTCLASS = 0x42
	sysIPV6_TCLASS     = 0x43

	sysIPV6_ADDR_PREFERENCES = 0x48

	sysIPV6_PREFER_SRC_TMP            = 0x1
	sysIPV6_PREFER_SRC_PUBLIC         = 0x2
	sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
	sysIPV6_PREFER_SRC_COA            = 0x4
	sysIPV6_PREFER_SRC_HOME           = 0x400
	sysIPV6_PREFER_SRC_CGA            = 0x8
	sysIPV6_PREFER_SRC_NONCGA         = 0x800

	sysIPV6_MINHOPCOUNT = 0x49

	sysIPV6_ORIGDSTADDR     = 0x4a
	sysIPV6_RECVORIGDSTADDR = 0x4a
	sysIPV6_TRANSPARENT     = 0x4b
	sysIPV6_UNICAST_IF      = 0x4c

	sysICMPV6_FILTER = 0x1

	sysICMPV6_FILTER_BLOCK       = 0x1
	sysICMPV6_FILTER_PASS        = 0x2
	sysICMPV6_FILTER_BLOCKOTHERS = 0x3
	sysICMPV6_FILTER_PASSONLY    = 0x4

	sysSOL_SOCKET       = 0x1
	sysSO_ATTACH_FILTER = 0x1a

	sizeofKernelSockaddrStorage = 0x80
	sizeofSockaddrInet6         = 0x1c
	sizeofInet6Pktinfo          = 0x14
	sizeofIPv6Mtuinfo           = 0x20
	sizeofIPv6FlowlabelReq      = 0x20

	sizeofIPv6Mreq       = 0x14
	sizeofGroupReq       = 0x88
	sizeofGroupSourceReq = 0x108

	sizeofICMPv6Filter = 0x20

	sizeofSockFprog = 0x10
)

type kernelSockaddrStorage struct {
	Family  uint16
	X__data [126]int8
}

type sockaddrInet6 struct {
	Family   uint16
	Port     uint16
	Flowinfo uint32
	Addr     [16]byte /* in6_addr */
	Scope_id uint32
}

type inet6Pktinfo struct {
	Addr    [16]byte /* in6_addr */
	Ifindex int32
}

type ipv6Mtuinfo struct {
	Addr sockaddrInet6
	Mtu  uint32
}

type ipv6FlowlabelReq struct {
	Dst        [16]byte /* in6_addr */
	Label      uint32
	Action     uint8
	Share      uint8
	Flags      uint16
	Expires    uint16
	Linger     uint16
	X__flr_pad uint32
}

type ipv6Mreq struct {
	Multiaddr [16]byte /* in6_addr */
	Ifindex   int32
}

type groupReq struct {
	Interface uint32
	Pad_cgo_0 [4]byte
	Group     kernelSockaddrStorage
}

type groupSourceReq struct {
	Interface uint32
	Pad_cgo_0 [4]byte
	Group     kernelSockaddrStorage
	Source    kernelSockaddrStorage
}

type icmpv6Filter struct {
	Data [8]uint32
}

type sockFProg struct {
	Len       uint16
	Pad_cgo_0 [6]byte
	Filter    *sockFilter
}

type sockFilter struct {
	Code uint16
	Jt   uint8
	Jf   uint8
	K    uint32
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !nacl,!plan9,!windows

package ipv6

import (
	"net"
	"syscall"
)

// ReadFrom reads a payload of the received IPv6 datagram, from the
// endpoint c, copying the payload into b. It returns the number of
// bytes copied into b, the control message cm and the source address
// src of the received datagram.
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
	if !c.ok() {
		return 0, nil, nil, syscall.EINVAL
	}
	return c.readFrom(b)
}

// WriteTo writes a payload of the IPv6 datagram, to the destination
// address dst through the endpoint c, copying the payload from b. It
// returns the number of bytes written. The control message cm allows
// the IPv6 header fields and the datagram path to be specified. The
// cm may be nil if control of the outgoing datagram is not required.
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
	if !c.ok() {
		return 0, syscall.EINVAL
	}
	return c.writeTo(b, cm, dst)
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6_test

import (
	"net"
	"runtime"
	"testing"

	"golang.org/x/net/internal/iana"
	"golang.org/x/net/internal/nettest"
	"golang.org/x/net/ipv6"
)

func TestConnUnicastSocketOptions(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if !supportsIPv6 {
		t.Skip("ipv6 is not supported")
	}

	ln, err := net.Listen("tcp6", "[::1]:0")
	if err != nil {
		t.Fatal(err)
	}
	defer ln.Close()

	errc := make(chan error, 1)
	go func() {
		c, err := ln.Accept()
		if err != nil {
			errc <- err
			return
		}
		errc <- c.Close()
	}()

	c, err := net.Dial("tcp6", ln.Addr().String())
	if err != nil {
		t.Fatal(err)
	}
	defer c.Close()

	testUnicastSocketOptions(t, ipv6.NewConn(c))

	if err := <-errc; err != nil {
		t.Errorf("server: %v", err)
	}
}

var packetConnUnicastSocketOptionTests = []struct {
	net, proto, addr string
}{
	{"udp6", "", "[::1]:0"},
	{"ip6", ":ipv6-icmp", "::1"},
}

func TestPacketConnUnicastSocketOptions(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if !supportsIPv6 {
		t.Skip("ipv6 is not supported")
	}

	m, ok := nettest.SupportsRawIPSocket()
	for _, tt := range packetConnUnicastSocketOptionTests {
		if tt.net == "ip6" && !ok {
			t.Log(m)
			continue
		}
		c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		testUnicastSocketOptions(t, ipv6.NewPacketConn(c))
	}
}

type testIPv6UnicastConn interface {
	TrafficClass() (int, error)
	SetTrafficClass(int) error
	HopLimit() (int, error)
	SetHopLimit(int) error
}

func testUnicastSocketOptions(t *testing.T, c testIPv6UnicastConn) {
	tclass := iana.DiffServCS0 | iana.NotECNTransport
	if err := c.SetTrafficClass(tclass); err != nil {
		switch runtime.GOOS {
		case "darwin": // older darwin kernels don't support IPV6_TCLASS option
			t.Logf("not supported on %s", runtime.GOOS)
			goto next
		}
		t.Fatal(err)
	}
	if v, err := c.TrafficClass(); err != nil {
		t.Fatal(err)
	} else if v != tclass {
		t.Fatalf("got %v; want %v", v, tclass)
	}

next:
	hoplim := 255
	if err := c.SetHopLimit(hoplim); err != nil {
		t.Fatal(err)
	}
	if v, err := c.HopLimit(); err != nil {
		t.Fatal(err)
	} else if v != hoplim {
		t.Fatalf("got %v; want %v", v, hoplim)
	}
}


text:
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs defs_linux.go

package ipv6

const (
	sysIPV6_ADDRFORM       = 0x1
	sysIPV6_2292PKTINFO    = 0x2
	sysIPV6_2292HOPOPTS    = 0x3
	sysIPV6_2292DSTOPTS    = 0x4
	sysIPV6_2292RTHDR      = 0x5
	sysIPV6_2292PKTOPTIONS = 0x6
	sysIPV6_CHECKSUM       = 0x7
	sysIPV6_2292HOPLIMIT   = 0x8
	sysIPV6_NEXTHOP        = 0x9
	sysIPV6_FLOWINFO       = 0xb

	sysIPV6_UNICAST_HOPS        = 0x10
	sysIPV6_MULTICAST_IF        = 0x11
	sysIPV6_MULTICAST_HOPS      = 0x12
	sysIPV6_MULTICAST_LOOP      = 0x13
	sysIPV6_ADD_MEMBERSHIP      = 0x14
	sysIPV6_DROP_MEMBERSHIP     = 0x15
	sysMCAST_JOIN_GROUP         = 0x2a
	sysMCAST_LEAVE_GROUP        = 0x2d
	sysMCAST_JOIN_SOURCE_GROUP  = 0x2e
	sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
	sysMCAST_BLOCK_SOURCE       = 0x2b
	sysMCAST_UNBLOCK_SOURCE     = 0x2c
	sysMCAST_MSFILTER           = 0x30
	sysIPV6_ROUTER_ALERT        = 0x16
	sysIPV6_MTU_DISCOVER        = 0x17
	sysIPV6_MTU                 = 0x18
	sysIPV6_RECVERR             = 0x19
	sysIPV6_V6ONLY              = 0x1a
	sysIPV6_JOIN_ANYCAST        = 0x1b
	sysIPV6_LEAVE_ANYCAST       = 0x1c

	sysIPV6_FLOWLABEL_MGR = 0x20
	sysIPV6_FLOWINFO_SEND = 0x21

	sysIPV6_IPSEC_POLICY = 0x22
	sysIPV6_XFRM_POLICY  = 0x23

	sysIPV6_RECVPKTINFO  = 0x31
	sysIPV6_PKTINFO      = 0x32
	sysIPV6_RECVHOPLIMIT = 0x33
	sysIPV6_HOPLIMIT     = 0x34
	sysIPV6_RECVHOPOPTS  = 0x35
	sysIPV6_HOPOPTS      = 0x36
	sysIPV6_RTHDRDSTOPTS = 0x37
	sysIPV6_RECVRTHDR    = 0x38
	sysIPV6_RTHDR        = 0x39
	sysIPV6_RECVDSTOPTS  = 0x3a
	sysIPV6_DSTOPTS      = 0x3b
	sysIPV6_RECVPATHMTU  = 0x3c
	sysIPV6_PATHMTU      = 0x3d
	sysIPV6_DONTFRAG     = 0x3e

	sysIPV6_RECVTCLASS = 0x42
	sysIPV6_TCLASS     = 0x43

	sysIPV6_ADDR_PREFERENCES = 0x48

	sysIPV6_PREFER_SRC_TMP            = 0x1
	sysIPV6_PREFER_SRC_PUBLIC         = 0x2
	sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
	sysIPV6_PREFER_SRC_COA            = 0x4
	sysIPV6_PREFER_SRC_HOME           = 0x400
	sysIPV6_PREFER_SRC_CGA            = 0x8
	sysIPV6_PREFER_SRC_NONCGA         = 0x800

	sysIPV6_MINHOPCOUNT = 0x49

	sysIPV6_ORIGDSTADDR     = 0x4a
	sysIPV6_RECVORIGDSTADDR = 0x4a
	sysIPV6_TRANSPARENT     = 0x4b
	sysIPV6_UNICAST_IF      = 0x4c

	sysICMPV6_FILTER = 0x1

	sysICMPV6_FILTER_BLOCK       = 0x1
	sysICMPV6_FILTER_PASS        = 0x2
	sysICMPV6_FILTER_BLOCKOTHERS = 0x3
	sysICMPV6_FILTER_PASSONLY    = 0x4

	sysSOL_SOCKET       = 0x1
	sysSO_ATTACH_FILTER = 0x1a

	sizeofKernelSockaddrStorage = 0x80
	sizeofSockaddrInet6         = 0x1c
	sizeofInet6Pktinfo          = 0x14
	sizeofIPv6Mtuinfo           = 0x20
	sizeofIPv6FlowlabelReq      = 0x20

	sizeofIPv6Mreq       = 0x14
	sizeofGroupReq       = 0x84
	sizeofGroupSourceReq = 0x104

	sizeofICMPv6Filter = 0x20

	sizeofSockFprog = 0x8
)

type kernelSockaddrStorage struct {
	Family  uint16
	X__data [126]int8
}

type sockaddrInet6 struct {
	Family   uint16
	Port     uint16
	Flowinfo uint32
	Addr     [16]byte /* in6_addr */
	Scope_id uint32
}

type inet6Pktinfo struct {
	Addr    [16]byte /* in6_addr */
	Ifindex int32
}

type ipv6Mtuinfo struct {
	Addr sockaddrInet6
	Mtu  uint32
}

type ipv6FlowlabelReq struct {
	Dst        [16]byte /* in6_addr */
	Label      uint32
	Action     uint8
	Share      uint8
	Flags      uint16
	Expires    uint16
	Linger     uint16
	X__flr_pad uint32
}

type ipv6Mreq struct {
	Multiaddr [16]byte /* in6_addr */
	Ifindex   int32
}

type groupReq struct {
	Interface uint32
	Group     kernelSockaddrStorage
}

type groupSourceReq struct {
	Interface uint32
	Group     kernelSockaddrStorage
	Source    kernelSockaddrStorage
}

type icmpv6Filter struct {
	Data [8]uint32
}

type sockFProg struct {
	Len       uint16
	Pad_cgo_0 [2]byte
	Filter    *sockFilter
}

type sockFilter struct {
	Code uint16
	Jt   uint8
	Jf   uint8
	K    uint32
}


text:
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

// +godefs map struct_in6_addr [16]byte /* in6_addr */

package ipv6

/*
#include <sys/param.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <netinet/icmp6.h>
*/
import "C"

const (
	sysIPV6_UNICAST_HOPS   = C.IPV6_UNICAST_HOPS
	sysIPV6_MULTICAST_IF   = C.IPV6_MULTICAST_IF
	sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
	sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
	sysIPV6_JOIN_GROUP     = C.IPV6_JOIN_GROUP
	sysIPV6_LEAVE_GROUP    = C.IPV6_LEAVE_GROUP
	sysIPV6_PORTRANGE      = C.IPV6_PORTRANGE
	sysICMP6_FILTER        = C.ICMP6_FILTER

	sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
	sysIPV6_V6ONLY   = C.IPV6_V6ONLY

	sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY

	sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS
	sysIPV6_RECVPKTINFO  = C.IPV6_RECVPKTINFO
	sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
	sysIPV6_RECVRTHDR    = C.IPV6_RECVRTHDR
	sysIPV6_RECVHOPOPTS  = C.IPV6_RECVHOPOPTS
	sysIPV6_RECVDSTOPTS  = C.IPV6_RECVDSTOPTS

	sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU
	sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU

	sysIPV6_PATHMTU = C.IPV6_PATHMTU

	sysIPV6_PKTINFO  = C.IPV6_PKTINFO
	sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
	sysIPV6_NEXTHOP  = C.IPV6_NEXTHOP
	sysIPV6_HOPOPTS  = C.IPV6_HOPOPTS
	sysIPV6_DSTOPTS  = C.IPV6_DSTOPTS
	sysIPV6_RTHDR    = C.IPV6_RTHDR

	sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS

	sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL

	sysIPV6_TCLASS   = C.IPV6_TCLASS
	sysIPV6_DONTFRAG = C.IPV6_DONTFRAG

	sysIPV6_PREFER_TEMPADDR = C.IPV6_PREFER_TEMPADDR

	sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT
	sysIPV6_PORTRANGE_HIGH    = C.IPV6_PORTRANGE_HIGH
	sysIPV6_PORTRANGE_LOW     = C.IPV6_PORTRANGE_LOW

	sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
	sizeofInet6Pktinfo  = C.sizeof_struct_in6_pktinfo
	sizeofIPv6Mtuinfo   = C.sizeof_struct_ip6_mtuinfo

	sizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq

	sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
)

type sockaddrInet6 C.struct_sockaddr_in6

type inet6Pktinfo C.struct_in6_pktinfo

type ipv6Mtuinfo C.struct_ip6_mtuinfo

type ipv6Mreq C.struct_ipv6_mreq

type icmpv6Filter C.struct_icmp6_filter


text:
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !linux

package ipv6

import (
	"golang.org/x/net/bpf"
	"golang.org/x/net/internal/socket"
)

func (so *sockOpt) setAttachFilter(c *socket.Conn, f []bpf.RawInstruction) error {
	return errOpNoSupport
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6

import (
	"errors"
	"net"
)

var (
	errMissingAddress  = errors.New("missing address")
	errHeaderTooShort  = errors.New("header too short")
	errInvalidConnType = errors.New("invalid conn type")
	errOpNoSupport     = errors.New("operation not supported")
	errNoSuchInterface = errors.New("no such interface")
)

func boolint(b bool) int {
	if b {
		return 1
	}
	return 0
}

func netAddrToIP16(a net.Addr) net.IP {
	switch v := a.(type) {
	case *net.UDPAddr:
		if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
			return ip
		}
	case *net.IPAddr:
		if ip := v.IP.To16(); ip != nil && ip.To4() == nil {
			return ip
		}
	}
	return nil
}

func opAddr(a net.Addr) net.Addr {
	switch a.(type) {
	case *net.TCPAddr:
		if a == nil {
			return nil
		}
	case *net.UDPAddr:
		if a == nil {
			return nil
		}
	case *net.IPAddr:
		if a == nil {
			return nil
		}
	}
	return a
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows

package ipv6

import (
	"net"
	"unsafe"

	"golang.org/x/net/internal/socket"
)

func (so *sockOpt) setIPMreq(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
	var mreq ipv6Mreq
	copy(mreq.Multiaddr[:], grp)
	if ifi != nil {
		mreq.setIfindex(ifi.Index)
	}
	b := (*[sizeofIPv6Mreq]byte)(unsafe.Pointer(&mreq))[:sizeofIPv6Mreq]
	return so.Set(c, b)
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !go1.9

package ipv6_test

import (
	"bytes"
	"fmt"
	"net"
	"runtime"
	"strings"
	"sync"
	"testing"

	"golang.org/x/net/internal/iana"
	"golang.org/x/net/internal/nettest"
	"golang.org/x/net/ipv6"
)

func BenchmarkPacketConnReadWriteUnicast(b *testing.B) {
	switch runtime.GOOS {
	case "nacl", "plan9", "windows":
		b.Skipf("not supported on %s", runtime.GOOS)
	}

	payload := []byte("HELLO-R-U-THERE")
	iph := []byte{
		0x69, 0x8b, 0xee, 0xf1, 0xca, 0xfe, 0xff, 0x01,
		0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
		0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	}
	greh := []byte{0x00, 0x00, 0x86, 0xdd, 0x00, 0x00, 0x00, 0x00}
	datagram := append(greh, append(iph, payload...)...)
	bb := make([]byte, 128)
	cm := ipv6.ControlMessage{
		TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
		HopLimit:     1,
		Src:          net.IPv6loopback,
	}
	if ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback); ifi != nil {
		cm.IfIndex = ifi.Index
	}

	b.Run("UDP", func(b *testing.B) {
		c, err := nettest.NewLocalPacketListener("udp6")
		if err != nil {
			b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
		}
		defer c.Close()
		p := ipv6.NewPacketConn(c)
		dst := c.LocalAddr()
		cf := ipv6.FlagHopLimit | ipv6.FlagInterface
		if err := p.SetControlMessage(cf, true); err != nil {
			b.Fatal(err)
		}
		b.Run("Net", func(b *testing.B) {
			for i := 0; i < b.N; i++ {
				if _, err := c.WriteTo(payload, dst); err != nil {
					b.Fatal(err)
				}
				if _, _, err := c.ReadFrom(bb); err != nil {
					b.Fatal(err)
				}
			}
		})
		b.Run("ToFrom", func(b *testing.B) {
			for i := 0; i < b.N; i++ {
				if _, err := p.WriteTo(payload, &cm, dst); err != nil {
					b.Fatal(err)
				}
				if _, _, _, err := p.ReadFrom(bb); err != nil {
					b.Fatal(err)
				}
			}
		})
	})
	b.Run("IP", func(b *testing.B) {
		switch runtime.GOOS {
		case "netbsd":
			b.Skip("need to configure gre on netbsd")
		case "openbsd":
			b.Skip("net.inet.gre.allow=0 by default on openbsd")
		}

		c, err := net.ListenPacket(fmt.Sprintf("ip6:%d", iana.ProtocolGRE), "::1")
		if err != nil {
			b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
		}
		defer c.Close()
		p := ipv6.NewPacketConn(c)
		dst := c.LocalAddr()
		cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
		if err := p.SetControlMessage(cf, true); err != nil {
			b.Fatal(err)
		}
		b.Run("Net", func(b *testing.B) {
			for i := 0; i < b.N; i++ {
				if _, err := c.WriteTo(datagram, dst); err != nil {
					b.Fatal(err)
				}
				if _, _, err := c.ReadFrom(bb); err != nil {
					b.Fatal(err)
				}
			}
		})
		b.Run("ToFrom", func(b *testing.B) {
			for i := 0; i < b.N; i++ {
				if _, err := p.WriteTo(datagram, &cm, dst); err != nil {
					b.Fatal(err)
				}
				if _, _, _, err := p.ReadFrom(bb); err != nil {
					b.Fatal(err)
				}
			}
		})
	})
}

func TestPacketConnConcurrentReadWriteUnicast(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}

	payload := []byte("HELLO-R-U-THERE")
	iph := []byte{
		0x69, 0x8b, 0xee, 0xf1, 0xca, 0xfe, 0xff, 0x01,
		0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
		0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
	}
	greh := []byte{0x00, 0x00, 0x86, 0xdd, 0x00, 0x00, 0x00, 0x00}
	datagram := append(greh, append(iph, payload...)...)

	t.Run("UDP", func(t *testing.T) {
		c, err := nettest.NewLocalPacketListener("udp6")
		if err != nil {
			t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
		}
		defer c.Close()
		p := ipv6.NewPacketConn(c)
		t.Run("ToFrom", func(t *testing.T) {
			testPacketConnConcurrentReadWriteUnicast(t, p, payload, c.LocalAddr())
		})
	})
	t.Run("IP", func(t *testing.T) {
		switch runtime.GOOS {
		case "netbsd":
			t.Skip("need to configure gre on netbsd")
		case "openbsd":
			t.Skip("net.inet.gre.allow=0 by default on openbsd")
		}

		c, err := net.ListenPacket(fmt.Sprintf("ip6:%d", iana.ProtocolGRE), "::1")
		if err != nil {
			t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
		}
		defer c.Close()
		p := ipv6.NewPacketConn(c)
		t.Run("ToFrom", func(t *testing.T) {
			testPacketConnConcurrentReadWriteUnicast(t, p, datagram, c.LocalAddr())
		})
	})
}

func testPacketConnConcurrentReadWriteUnicast(t *testing.T, p *ipv6.PacketConn, data []byte, dst net.Addr) {
	ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
	cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU

	if err := p.SetControlMessage(cf, true); err != nil { // probe before test
		if nettest.ProtocolNotSupported(err) {
			t.Skipf("not supported on %s", runtime.GOOS)
		}
		t.Fatal(err)
	}

	var wg sync.WaitGroup
	reader := func() {
		defer wg.Done()
		b := make([]byte, 128)
		n, cm, _, err := p.ReadFrom(b)
		if err != nil {
			t.Error(err)
			return
		}
		if !bytes.Equal(b[:n], data) {
			t.Errorf("got %#v; want %#v", b[:n], data)
			return
		}
		s := cm.String()
		if strings.Contains(s, ",") {
			t.Errorf("should be space-separated values: %s", s)
			return
		}
	}
	writer := func(toggle bool) {
		defer wg.Done()
		cm := ipv6.ControlMessage{
			TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
			HopLimit:     1,
			Src:          net.IPv6loopback,
		}
		if ifi != nil {
			cm.IfIndex = ifi.Index
		}
		if err := p.SetControlMessage(cf, toggle); err != nil {
			t.Error(err)
			return
		}
		n, err := p.WriteTo(data, &cm, dst)
		if err != nil {
			t.Error(err)
			return
		}
		if n != len(data) {
			t.Errorf("got %d; want %d", n, len(data))
			return
		}
	}

	const N = 10
	wg.Add(N)
	for i := 0; i < N; i++ {
		go reader()
	}
	wg.Add(2 * N)
	for i := 0; i < 2*N; i++ {
		go writer(i%2 != 0)

	}
	wg.Add(N)
	for i := 0; i < N; i++ {
		go reader()
	}
	wg.Wait()
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package ipv6 implements IP-level socket options for the Internet
// Protocol version 6.
//
// The package provides IP-level socket options that allow
// manipulation of IPv6 facilities.
//
// The IPv6 protocol is defined in RFC 8200.
// Socket interface extensions are defined in RFC 3493, RFC 3542 and
// RFC 3678.
// MLDv1 and MLDv2 are defined in RFC 2710 and RFC 3810.
// Source-specific multicast is defined in RFC 4607.
//
// On Darwin, this package requires OS X Mavericks version 10.9 or
// above, or equivalent.
//
//
// Unicasting
//
// The options for unicasting are available for net.TCPConn,
// net.UDPConn and net.IPConn which are created as network connections
// that use the IPv6 transport. When a single TCP connection carrying
// a data flow of multiple packets needs to indicate the flow is
// important, Conn is used to set the traffic class field on the IPv6
// header for each packet.
//
//	ln, err := net.Listen("tcp6", "[::]:1024")
//	if err != nil {
//		// error handling
//	}
//	defer ln.Close()
//	for {
//		c, err := ln.Accept()
//		if err != nil {
//			// error handling
//		}
//		go func(c net.Conn) {
//			defer c.Close()
//
// The outgoing packets will be labeled DiffServ assured forwarding
// class 1 low drop precedence, known as AF11 packets.
//
//			if err := ipv6.NewConn(c).SetTrafficClass(0x28); err != nil {
//				// error handling
//			}
//			if _, err := c.Write(data); err != nil {
//				// error handling
//			}
//		}(c)
//	}
//
//
// Multicasting
//
// The options for multicasting are available for net.UDPConn and
// net.IPconn which are created as network connections that use the
// IPv6 transport. A few network facilities must be prepared before
// you begin multicasting, at a minimum joining network interfaces and
// multicast groups.
//
//	en0, err := net.InterfaceByName("en0")
//	if err != nil {
//		// error handling
//	}
//	en1, err := net.InterfaceByIndex(911)
//	if err != nil {
//		// error handling
//	}
//	group := net.ParseIP("ff02::114")
//
// First, an application listens to an appropriate address with an
// appropriate service port.
//
//	c, err := net.ListenPacket("udp6", "[::]:1024")
//	if err != nil {
//		// error handling
//	}
//	defer c.Close()
//
// Second, the application joins multicast groups, starts listening to
// the groups on the specified network interfaces. Note that the
// service port for transport layer protocol does not matter with this
// operation as joining groups affects only network and link layer
// protocols, such as IPv6 and Ethernet.
//
//	p := ipv6.NewPacketConn(c)
//	if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil {
//		// error handling
//	}
//	if err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil {
//		// error handling
//	}
//
// The application might set per packet control message transmissions
// between the protocol stack within the kernel. When the application
// needs a destination address on an incoming packet,
// SetControlMessage of PacketConn is used to enable control message
// transmissions.
//
//	if err := p.SetControlMessage(ipv6.FlagDst, true); err != nil {
//		// error handling
//	}
//
// The application could identify whether the received packets are
// of interest by using the control message that contains the
// destination address of the received packet.
//
//	b := make([]byte, 1500)
//	for {
//		n, rcm, src, err := p.ReadFrom(b)
//		if err != nil {
//			// error handling
//		}
//		if rcm.Dst.IsMulticast() {
//			if rcm.Dst.Equal(group) {
//				// joined group, do something
//			} else {
//				// unknown group, discard
//				continue
//			}
//		}
//
// The application can also send both unicast and multicast packets.
//
//		p.SetTrafficClass(0x0)
//		p.SetHopLimit(16)
//		if _, err := p.WriteTo(data[:n], nil, src); err != nil {
//			// error handling
//		}
//		dst := &net.UDPAddr{IP: group, Port: 1024}
//		wcm := ipv6.ControlMessage{TrafficClass: 0xe0, HopLimit: 1}
//		for _, ifi := range []*net.Interface{en0, en1} {
//			wcm.IfIndex = ifi.Index
//			if _, err := p.WriteTo(data[:n], &wcm, dst); err != nil {
//				// error handling
//			}
//		}
//	}
//
//
// More multicasting
//
// An application that uses PacketConn may join multiple multicast
// groups. For example, a UDP listener with port 1024 might join two
// different groups across over two different network interfaces by
// using:
//
//	c, err := net.ListenPacket("udp6", "[::]:1024")
//	if err != nil {
//		// error handling
//	}
//	defer c.Close()
//	p := ipv6.NewPacketConn(c)
//	if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::1:114")}); err != nil {
//		// error handling
//	}
//	if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
//		// error handling
//	}
//	if err := p.JoinGroup(en1, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil {
//		// error handling
//	}
//
// It is possible for multiple UDP listeners that listen on the same
// UDP port to join the same multicast group. The net package will
// provide a socket that listens to a wildcard address with reusable
// UDP port when an appropriate multicast address prefix is passed to
// the net.ListenPacket or net.ListenUDP.
//
//	c1, err := net.ListenPacket("udp6", "[ff02::]:1024")
//	if err != nil {
//		// error handling
//	}
//	defer c1.Close()
//	c2, err := net.ListenPacket("udp6", "[ff02::]:1024")
//	if err != nil {
//		// error handling
//	}
//	defer c2.Close()
//	p1 := ipv6.NewPacketConn(c1)
//	if err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
//		// error handling
//	}
//	p2 := ipv6.NewPacketConn(c2)
//	if err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
//		// error handling
//	}
//
// Also it is possible for the application to leave or rejoin a
// multicast group on the network interface.
//
//	if err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil {
//		// error handling
//	}
//	if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff01::114")}); err != nil {
//		// error handling
//	}
//
//
// Source-specific multicasting
//
// An application that uses PacketConn on MLDv2 supported platform is
// able to join source-specific multicast groups.
// The application may use JoinSourceSpecificGroup and
// LeaveSourceSpecificGroup for the operation known as "include" mode,
//
//	ssmgroup := net.UDPAddr{IP: net.ParseIP("ff32::8000:9")}
//	ssmsource := net.UDPAddr{IP: net.ParseIP("fe80::cafe")}
//	if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {
//		// error handling
//	}
//	if err := p.LeaveSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil {
//		// error handling
//	}
//
// or JoinGroup, ExcludeSourceSpecificGroup,
// IncludeSourceSpecificGroup and LeaveGroup for the operation known
// as "exclude" mode.
//
//	exclsource := net.UDPAddr{IP: net.ParseIP("fe80::dead")}
//	if err := p.JoinGroup(en0, &ssmgroup); err != nil {
//		// error handling
//	}
//	if err := p.ExcludeSourceSpecificGroup(en0, &ssmgroup, &exclsource); err != nil {
//		// error handling
//	}
//	if err := p.LeaveGroup(en0, &ssmgroup); err != nil {
//		// error handling
//	}
//
// Note that it depends on each platform implementation what happens
// when an application which runs on MLDv2 unsupported platform uses
// JoinSourceSpecificGroup and LeaveSourceSpecificGroup.
// In general the platform tries to fall back to conversations using
// MLDv1 and starts to listen to multicast traffic.
// In the fallback case, ExcludeSourceSpecificGroup and
// IncludeSourceSpecificGroup may return an error.
package ipv6 // import "golang.org/x/net/ipv6"

// BUG(mikio): This package is not implemented on NaCl and Plan 9.


text:
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows

package ipv6

var (
	ctlOpts = [ctlMax]ctlOpt{}

	sockOpts = map[int]*sockOpt{}
)


text:
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs defs_openbsd.go

package ipv6

const (
	sysIPV6_UNICAST_HOPS   = 0x4
	sysIPV6_MULTICAST_IF   = 0x9
	sysIPV6_MULTICAST_HOPS = 0xa
	sysIPV6_MULTICAST_LOOP = 0xb
	sysIPV6_JOIN_GROUP     = 0xc
	sysIPV6_LEAVE_GROUP    = 0xd
	sysIPV6_PORTRANGE      = 0xe
	sysICMP6_FILTER        = 0x12

	sysIPV6_CHECKSUM = 0x1a
	sysIPV6_V6ONLY   = 0x1b

	sysIPV6_RTHDRDSTOPTS = 0x23

	sysIPV6_RECVPKTINFO  = 0x24
	sysIPV6_RECVHOPLIMIT = 0x25
	sysIPV6_RECVRTHDR    = 0x26
	sysIPV6_RECVHOPOPTS  = 0x27
	sysIPV6_RECVDSTOPTS  = 0x28

	sysIPV6_USE_MIN_MTU = 0x2a
	sysIPV6_RECVPATHMTU = 0x2b

	sysIPV6_PATHMTU = 0x2c

	sysIPV6_PKTINFO  = 0x2e
	sysIPV6_HOPLIMIT = 0x2f
	sysIPV6_NEXTHOP  = 0x30
	sysIPV6_HOPOPTS  = 0x31
	sysIPV6_DSTOPTS  = 0x32
	sysIPV6_RTHDR    = 0x33

	sysIPV6_AUTH_LEVEL        = 0x35
	sysIPV6_ESP_TRANS_LEVEL   = 0x36
	sysIPV6_ESP_NETWORK_LEVEL = 0x37
	sysIPSEC6_OUTSA           = 0x38
	sysIPV6_RECVTCLASS        = 0x39

	sysIPV6_AUTOFLOWLABEL = 0x3b
	sysIPV6_IPCOMP_LEVEL  = 0x3c

	sysIPV6_TCLASS   = 0x3d
	sysIPV6_DONTFRAG = 0x3e
	sysIPV6_PIPEX    = 0x3f

	sysIPV6_RTABLE = 0x1021

	sysIPV6_PORTRANGE_DEFAULT = 0x0
	sysIPV6_PORTRANGE_HIGH    = 0x1
	sysIPV6_PORTRANGE_LOW     = 0x2

	sizeofSockaddrInet6 = 0x1c
	sizeofInet6Pktinfo  = 0x14
	sizeofIPv6Mtuinfo   = 0x20

	sizeofIPv6Mreq = 0x14

	sizeofICMPv6Filter = 0x20
)

type sockaddrInet6 struct {
	Len      uint8
	Family   uint8
	Port     uint16
	Flowinfo uint32
	Addr     [16]byte /* in6_addr */
	Scope_id uint32
}

type inet6Pktinfo struct {
	Addr    [16]byte /* in6_addr */
	Ifindex uint32
}

type ipv6Mtuinfo struct {
	Addr sockaddrInet6
	Mtu  uint32
}

type ipv6Mreq struct {
	Multiaddr [16]byte /* in6_addr */
	Interface uint32
}

type icmpv6Filter struct {
	Filt [8]uint32
}


text:
// go generate gen.go
// Code generated by the command above; DO NOT EDIT.

package ipv6

// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2018-03-09
const (
	ICMPTypeDestinationUnreachable                ICMPType = 1   // Destination Unreachable
	ICMPTypePacketTooBig                          ICMPType = 2   // Packet Too Big
	ICMPTypeTimeExceeded                          ICMPType = 3   // Time Exceeded
	ICMPTypeParameterProblem                      ICMPType = 4   // Parameter Problem
	ICMPTypeEchoRequest                           ICMPType = 128 // Echo Request
	ICMPTypeEchoReply                             ICMPType = 129 // Echo Reply
	ICMPTypeMulticastListenerQuery                ICMPType = 130 // Multicast Listener Query
	ICMPTypeMulticastListenerReport               ICMPType = 131 // Multicast Listener Report
	ICMPTypeMulticastListenerDone                 ICMPType = 132 // Multicast Listener Done
	ICMPTypeRouterSolicitation                    ICMPType = 133 // Router Solicitation
	ICMPTypeRouterAdvertisement                   ICMPType = 134 // Router Advertisement
	ICMPTypeNeighborSolicitation                  ICMPType = 135 // Neighbor Solicitation
	ICMPTypeNeighborAdvertisement                 ICMPType = 136 // Neighbor Advertisement
	ICMPTypeRedirect                              ICMPType = 137 // Redirect Message
	ICMPTypeRouterRenumbering                     ICMPType = 138 // Router Renumbering
	ICMPTypeNodeInformationQuery                  ICMPType = 139 // ICMP Node Information Query
	ICMPTypeNodeInformationResponse               ICMPType = 140 // ICMP Node Information Response
	ICMPTypeInverseNeighborDiscoverySolicitation  ICMPType = 141 // Inverse Neighbor Discovery Solicitation Message
	ICMPTypeInverseNeighborDiscoveryAdvertisement ICMPType = 142 // Inverse Neighbor Discovery Advertisement Message
	ICMPTypeVersion2MulticastListenerReport       ICMPType = 143 // Version 2 Multicast Listener Report
	ICMPTypeHomeAgentAddressDiscoveryRequest      ICMPType = 144 // Home Agent Address Discovery Request Message
	ICMPTypeHomeAgentAddressDiscoveryReply        ICMPType = 145 // Home Agent Address Discovery Reply Message
	ICMPTypeMobilePrefixSolicitation              ICMPType = 146 // Mobile Prefix Solicitation
	ICMPTypeMobilePrefixAdvertisement             ICMPType = 147 // Mobile Prefix Advertisement
	ICMPTypeCertificationPathSolicitation         ICMPType = 148 // Certification Path Solicitation Message
	ICMPTypeCertificationPathAdvertisement        ICMPType = 149 // Certification Path Advertisement Message
	ICMPTypeMulticastRouterAdvertisement          ICMPType = 151 // Multicast Router Advertisement
	ICMPTypeMulticastRouterSolicitation           ICMPType = 152 // Multicast Router Solicitation
	ICMPTypeMulticastRouterTermination            ICMPType = 153 // Multicast Router Termination
	ICMPTypeFMIPv6                                ICMPType = 154 // FMIPv6 Messages
	ICMPTypeRPLControl                            ICMPType = 155 // RPL Control Message
	ICMPTypeILNPv6LocatorUpdate                   ICMPType = 156 // ILNPv6 Locator Update Message
	ICMPTypeDuplicateAddressRequest               ICMPType = 157 // Duplicate Address Request
	ICMPTypeDuplicateAddressConfirmation          ICMPType = 158 // Duplicate Address Confirmation
	ICMPTypeMPLControl                            ICMPType = 159 // MPL Control Message
	ICMPTypeExtendedEchoRequest                   ICMPType = 160 // Extended Echo Request
	ICMPTypeExtendedEchoReply                     ICMPType = 161 // Extended Echo Reply
)

// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2018-03-09
var icmpTypes = map[ICMPType]string{
	1:   "destination unreachable",
	2:   "packet too big",
	3:   "time exceeded",
	4:   "parameter problem",
	128: "echo request",
	129: "echo reply",
	130: "multicast listener query",
	131: "multicast listener report",
	132: "multicast listener done",
	133: "router solicitation",
	134: "router advertisement",
	135: "neighbor solicitation",
	136: "neighbor advertisement",
	137: "redirect message",
	138: "router renumbering",
	139: "icmp node information query",
	140: "icmp node information response",
	141: "inverse neighbor discovery solicitation message",
	142: "inverse neighbor discovery advertisement message",
	143: "version 2 multicast listener report",
	144: "home agent address discovery request message",
	145: "home agent address discovery reply message",
	146: "mobile prefix solicitation",
	147: "mobile prefix advertisement",
	148: "certification path solicitation message",
	149: "certification path advertisement message",
	151: "multicast router advertisement",
	152: "multicast router solicitation",
	153: "multicast router termination",
	154: "fmipv6 messages",
	155: "rpl control message",
	156: "ilnpv6 locator update message",
	157: "duplicate address request",
	158: "duplicate address confirmation",
	159: "mpl control message",
	160: "extended echo request",
	161: "extended echo reply",
}


text:
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs defs_netbsd.go

package ipv6

const (
	sysIPV6_UNICAST_HOPS   = 0x4
	sysIPV6_MULTICAST_IF   = 0x9
	sysIPV6_MULTICAST_HOPS = 0xa
	sysIPV6_MULTICAST_LOOP = 0xb
	sysIPV6_JOIN_GROUP     = 0xc
	sysIPV6_LEAVE_GROUP    = 0xd
	sysIPV6_PORTRANGE      = 0xe
	sysICMP6_FILTER        = 0x12

	sysIPV6_CHECKSUM = 0x1a
	sysIPV6_V6ONLY   = 0x1b

	sysIPV6_IPSEC_POLICY = 0x1c

	sysIPV6_RTHDRDSTOPTS = 0x23

	sysIPV6_RECVPKTINFO  = 0x24
	sysIPV6_RECVHOPLIMIT = 0x25
	sysIPV6_RECVRTHDR    = 0x26
	sysIPV6_RECVHOPOPTS  = 0x27
	sysIPV6_RECVDSTOPTS  = 0x28

	sysIPV6_USE_MIN_MTU = 0x2a
	sysIPV6_RECVPATHMTU = 0x2b
	sysIPV6_PATHMTU     = 0x2c

	sysIPV6_PKTINFO  = 0x2e
	sysIPV6_HOPLIMIT = 0x2f
	sysIPV6_NEXTHOP  = 0x30
	sysIPV6_HOPOPTS  = 0x31
	sysIPV6_DSTOPTS  = 0x32
	sysIPV6_RTHDR    = 0x33

	sysIPV6_RECVTCLASS = 0x39

	sysIPV6_TCLASS   = 0x3d
	sysIPV6_DONTFRAG = 0x3e

	sysIPV6_PORTRANGE_DEFAULT = 0x0
	sysIPV6_PORTRANGE_HIGH    = 0x1
	sysIPV6_PORTRANGE_LOW     = 0x2

	sizeofSockaddrInet6 = 0x1c
	sizeofInet6Pktinfo  = 0x14
	sizeofIPv6Mtuinfo   = 0x20

	sizeofIPv6Mreq = 0x14

	sizeofICMPv6Filter = 0x20
)

type sockaddrInet6 struct {
	Len      uint8
	Family   uint8
	Port     uint16
	Flowinfo uint32
	Addr     [16]byte /* in6_addr */
	Scope_id uint32
}

type inet6Pktinfo struct {
	Addr    [16]byte /* in6_addr */
	Ifindex uint32
}

type ipv6Mtuinfo struct {
	Addr sockaddrInet6
	Mtu  uint32
}

type ipv6Mreq struct {
	Multiaddr [16]byte /* in6_addr */
	Interface uint32
}

type icmpv6Filter struct {
	Filt [8]uint32
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6

func (f *icmpv6Filter) accept(typ ICMPType) {
	// TODO(mikio): implement this
}

func (f *icmpv6Filter) block(typ ICMPType) {
	// TODO(mikio): implement this
}

func (f *icmpv6Filter) setAll(block bool) {
	// TODO(mikio): implement this
}

func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
	// TODO(mikio): implement this
	return false
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6_test

import (
	"net"
	"runtime"
	"testing"

	"golang.org/x/net/internal/nettest"
	"golang.org/x/net/ipv6"
)

var packetConnMulticastSocketOptionTests = []struct {
	net, proto, addr string
	grp, src         net.Addr
}{
	{"udp6", "", "[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727
	{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff02::115")}, nil}, // see RFC 4727

	{"udp6", "", "[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771
	{"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff30::8000:2")}, &net.IPAddr{IP: net.IPv6loopback}},        // see RFC 5771
}

func TestPacketConnMulticastSocketOptions(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if !supportsIPv6 {
		t.Skip("ipv6 is not supported")
	}
	ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
	if ifi == nil {
		t.Skipf("not available on %s", runtime.GOOS)
	}

	m, ok := nettest.SupportsRawIPSocket()
	for _, tt := range packetConnMulticastSocketOptionTests {
		if tt.net == "ip6" && !ok {
			t.Log(m)
			continue
		}
		c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()
		p := ipv6.NewPacketConn(c)
		defer p.Close()

		if tt.src == nil {
			testMulticastSocketOptions(t, p, ifi, tt.grp)
		} else {
			testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src)
		}
	}
}

type testIPv6MulticastConn interface {
	MulticastHopLimit() (int, error)
	SetMulticastHopLimit(ttl int) error
	MulticastLoopback() (bool, error)
	SetMulticastLoopback(bool) error
	JoinGroup(*net.Interface, net.Addr) error
	LeaveGroup(*net.Interface, net.Addr) error
	JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
	LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
	ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
	IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error
}

func testMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp net.Addr) {
	const hoplim = 255
	if err := c.SetMulticastHopLimit(hoplim); err != nil {
		t.Error(err)
		return
	}
	if v, err := c.MulticastHopLimit(); err != nil {
		t.Error(err)
		return
	} else if v != hoplim {
		t.Errorf("got %v; want %v", v, hoplim)
		return
	}

	for _, toggle := range []bool{true, false} {
		if err := c.SetMulticastLoopback(toggle); err != nil {
			t.Error(err)
			return
		}
		if v, err := c.MulticastLoopback(); err != nil {
			t.Error(err)
			return
		} else if v != toggle {
			t.Errorf("got %v; want %v", v, toggle)
			return
		}
	}

	if err := c.JoinGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}
	if err := c.LeaveGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}
}

func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp, src net.Addr) {
	// MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP
	if err := c.JoinGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}
	if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil {
		switch runtime.GOOS {
		case "freebsd", "linux":
		default: // platforms that don't support MLDv2 fail here
			t.Logf("not supported on %s", runtime.GOOS)
			return
		}
		t.Error(err)
		return
	}
	if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil {
		t.Error(err)
		return
	}
	if err := c.LeaveGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}

	// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP
	if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
		t.Error(err)
		return
	}
	if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil {
		t.Error(err)
		return
	}

	// MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP
	if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil {
		t.Error(err)
		return
	}
	if err := c.LeaveGroup(ifi, grp); err != nil {
		t.Error(err)
		return
	}
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6

import (
	"net"

	"golang.org/x/net/internal/socket"
)

// BUG(mikio): On Windows, the ControlMessage for ReadFrom and WriteTo
// methods of PacketConn is not implemented.

// A payloadHandler represents the IPv6 datagram payload handler.
type payloadHandler struct {
	net.PacketConn
	*socket.Conn
	rawOpt
}

func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil && c.Conn != nil }


text:
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

// +godefs map struct_in6_addr [16]byte /* in6_addr */

package ipv6

/*
#include <sys/socket.h>

#include <netinet/in.h>
#include <netinet/icmp6.h>
*/
import "C"

const (
	sysIPV6_UNICAST_HOPS   = C.IPV6_UNICAST_HOPS
	sysIPV6_MULTICAST_IF   = C.IPV6_MULTICAST_IF
	sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
	sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
	sysIPV6_JOIN_GROUP     = C.IPV6_JOIN_GROUP
	sysIPV6_LEAVE_GROUP    = C.IPV6_LEAVE_GROUP

	sysIPV6_PKTINFO = C.IPV6_PKTINFO

	sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
	sysIPV6_NEXTHOP  = C.IPV6_NEXTHOP
	sysIPV6_HOPOPTS  = C.IPV6_HOPOPTS
	sysIPV6_DSTOPTS  = C.IPV6_DSTOPTS

	sysIPV6_RTHDR        = C.IPV6_RTHDR
	sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS

	sysIPV6_RECVPKTINFO  = C.IPV6_RECVPKTINFO
	sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
	sysIPV6_RECVHOPOPTS  = C.IPV6_RECVHOPOPTS

	sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR

	sysIPV6_RECVRTHDRDSTOPTS = C.IPV6_RECVRTHDRDSTOPTS

	sysIPV6_CHECKSUM        = C.IPV6_CHECKSUM
	sysIPV6_RECVTCLASS      = C.IPV6_RECVTCLASS
	sysIPV6_USE_MIN_MTU     = C.IPV6_USE_MIN_MTU
	sysIPV6_DONTFRAG        = C.IPV6_DONTFRAG
	sysIPV6_SEC_OPT         = C.IPV6_SEC_OPT
	sysIPV6_SRC_PREFERENCES = C.IPV6_SRC_PREFERENCES
	sysIPV6_RECVPATHMTU     = C.IPV6_RECVPATHMTU
	sysIPV6_PATHMTU         = C.IPV6_PATHMTU
	sysIPV6_TCLASS          = C.IPV6_TCLASS
	sysIPV6_V6ONLY          = C.IPV6_V6ONLY

	sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS

	sysMCAST_JOIN_GROUP         = C.MCAST_JOIN_GROUP
	sysMCAST_LEAVE_GROUP        = C.MCAST_LEAVE_GROUP
	sysMCAST_BLOCK_SOURCE       = C.MCAST_BLOCK_SOURCE
	sysMCAST_UNBLOCK_SOURCE     = C.MCAST_UNBLOCK_SOURCE
	sysMCAST_JOIN_SOURCE_GROUP  = C.MCAST_JOIN_SOURCE_GROUP
	sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP

	sysIPV6_PREFER_SRC_HOME   = C.IPV6_PREFER_SRC_HOME
	sysIPV6_PREFER_SRC_COA    = C.IPV6_PREFER_SRC_COA
	sysIPV6_PREFER_SRC_PUBLIC = C.IPV6_PREFER_SRC_PUBLIC
	sysIPV6_PREFER_SRC_TMP    = C.IPV6_PREFER_SRC_TMP
	sysIPV6_PREFER_SRC_NONCGA = C.IPV6_PREFER_SRC_NONCGA
	sysIPV6_PREFER_SRC_CGA    = C.IPV6_PREFER_SRC_CGA

	sysIPV6_PREFER_SRC_MIPMASK    = C.IPV6_PREFER_SRC_MIPMASK
	sysIPV6_PREFER_SRC_MIPDEFAULT = C.IPV6_PREFER_SRC_MIPDEFAULT
	sysIPV6_PREFER_SRC_TMPMASK    = C.IPV6_PREFER_SRC_TMPMASK
	sysIPV6_PREFER_SRC_TMPDEFAULT = C.IPV6_PREFER_SRC_TMPDEFAULT
	sysIPV6_PREFER_SRC_CGAMASK    = C.IPV6_PREFER_SRC_CGAMASK
	sysIPV6_PREFER_SRC_CGADEFAULT = C.IPV6_PREFER_SRC_CGADEFAULT

	sysIPV6_PREFER_SRC_MASK = C.IPV6_PREFER_SRC_MASK

	sysIPV6_PREFER_SRC_DEFAULT = C.IPV6_PREFER_SRC_DEFAULT

	sysIPV6_BOUND_IF   = C.IPV6_BOUND_IF
	sysIPV6_UNSPEC_SRC = C.IPV6_UNSPEC_SRC

	sysICMP6_FILTER = C.ICMP6_FILTER

	sizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage
	sizeofSockaddrInet6   = C.sizeof_struct_sockaddr_in6
	sizeofInet6Pktinfo    = C.sizeof_struct_in6_pktinfo
	sizeofIPv6Mtuinfo     = C.sizeof_struct_ip6_mtuinfo

	sizeofIPv6Mreq       = C.sizeof_struct_ipv6_mreq
	sizeofGroupReq       = C.sizeof_struct_group_req
	sizeofGroupSourceReq = C.sizeof_struct_group_source_req

	sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
)

type sockaddrStorage C.struct_sockaddr_storage

type sockaddrInet6 C.struct_sockaddr_in6

type inet6Pktinfo C.struct_in6_pktinfo

type ipv6Mtuinfo C.struct_ip6_mtuinfo

type ipv6Mreq C.struct_ipv6_mreq

type groupReq C.struct_group_req

type groupSourceReq C.struct_group_source_req

type icmpv6Filter C.struct_icmp6_filter


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build !darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris,!windows

package ipv6

import (
	"net"

	"golang.org/x/net/bpf"
	"golang.org/x/net/internal/socket"
)

func (so *sockOpt) getMulticastInterface(c *socket.Conn) (*net.Interface, error) {
	return nil, errOpNoSupport
}

func (so *sockOpt) setMulticastInterface(c *socket.Conn, ifi *net.Interface) error {
	return errOpNoSupport
}

func (so *sockOpt) getICMPFilter(c *socket.Conn) (*ICMPFilter, error) {
	return nil, errOpNoSupport
}

func (so *sockOpt) setICMPFilter(c *socket.Conn, f *ICMPFilter) error {
	return errOpNoSupport
}

func (so *sockOpt) getMTUInfo(c *socket.Conn) (*net.Interface, int, error) {
	return nil, 0, errOpNoSupport
}

func (so *sockOpt) setGroup(c *socket.Conn, ifi *net.Interface, grp net.IP) error {
	return errOpNoSupport
}

func (so *sockOpt) setSourceGroup(c *socket.Conn, ifi *net.Interface, grp, src net.IP) error {
	return errOpNoSupport
}

func (so *sockOpt) setBPF(c *socket.Conn, f []bpf.RawInstruction) error {
	return errOpNoSupport
}


text:
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs defs_linux.go

package ipv6

const (
	sysIPV6_ADDRFORM       = 0x1
	sysIPV6_2292PKTINFO    = 0x2
	sysIPV6_2292HOPOPTS    = 0x3
	sysIPV6_2292DSTOPTS    = 0x4
	sysIPV6_2292RTHDR      = 0x5
	sysIPV6_2292PKTOPTIONS = 0x6
	sysIPV6_CHECKSUM       = 0x7
	sysIPV6_2292HOPLIMIT   = 0x8
	sysIPV6_NEXTHOP        = 0x9
	sysIPV6_FLOWINFO       = 0xb

	sysIPV6_UNICAST_HOPS        = 0x10
	sysIPV6_MULTICAST_IF        = 0x11
	sysIPV6_MULTICAST_HOPS      = 0x12
	sysIPV6_MULTICAST_LOOP      = 0x13
	sysIPV6_ADD_MEMBERSHIP      = 0x14
	sysIPV6_DROP_MEMBERSHIP     = 0x15
	sysMCAST_JOIN_GROUP         = 0x2a
	sysMCAST_LEAVE_GROUP        = 0x2d
	sysMCAST_JOIN_SOURCE_GROUP  = 0x2e
	sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
	sysMCAST_BLOCK_SOURCE       = 0x2b
	sysMCAST_UNBLOCK_SOURCE     = 0x2c
	sysMCAST_MSFILTER           = 0x30
	sysIPV6_ROUTER_ALERT        = 0x16
	sysIPV6_MTU_DISCOVER        = 0x17
	sysIPV6_MTU                 = 0x18
	sysIPV6_RECVERR             = 0x19
	sysIPV6_V6ONLY              = 0x1a
	sysIPV6_JOIN_ANYCAST        = 0x1b
	sysIPV6_LEAVE_ANYCAST       = 0x1c

	sysIPV6_FLOWLABEL_MGR = 0x20
	sysIPV6_FLOWINFO_SEND = 0x21

	sysIPV6_IPSEC_POLICY = 0x22
	sysIPV6_XFRM_POLICY  = 0x23

	sysIPV6_RECVPKTINFO  = 0x31
	sysIPV6_PKTINFO      = 0x32
	sysIPV6_RECVHOPLIMIT = 0x33
	sysIPV6_HOPLIMIT     = 0x34
	sysIPV6_RECVHOPOPTS  = 0x35
	sysIPV6_HOPOPTS      = 0x36
	sysIPV6_RTHDRDSTOPTS = 0x37
	sysIPV6_RECVRTHDR    = 0x38
	sysIPV6_RTHDR        = 0x39
	sysIPV6_RECVDSTOPTS  = 0x3a
	sysIPV6_DSTOPTS      = 0x3b
	sysIPV6_RECVPATHMTU  = 0x3c
	sysIPV6_PATHMTU      = 0x3d
	sysIPV6_DONTFRAG     = 0x3e

	sysIPV6_RECVTCLASS = 0x42
	sysIPV6_TCLASS     = 0x43

	sysIPV6_ADDR_PREFERENCES = 0x48

	sysIPV6_PREFER_SRC_TMP            = 0x1
	sysIPV6_PREFER_SRC_PUBLIC         = 0x2
	sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
	sysIPV6_PREFER_SRC_COA            = 0x4
	sysIPV6_PREFER_SRC_HOME           = 0x400
	sysIPV6_PREFER_SRC_CGA            = 0x8
	sysIPV6_PREFER_SRC_NONCGA         = 0x800

	sysIPV6_MINHOPCOUNT = 0x49

	sysIPV6_ORIGDSTADDR     = 0x4a
	sysIPV6_RECVORIGDSTADDR = 0x4a
	sysIPV6_TRANSPARENT     = 0x4b
	sysIPV6_UNICAST_IF      = 0x4c

	sysICMPV6_FILTER = 0x1

	sysICMPV6_FILTER_BLOCK       = 0x1
	sysICMPV6_FILTER_PASS        = 0x2
	sysICMPV6_FILTER_BLOCKOTHERS = 0x3
	sysICMPV6_FILTER_PASSONLY    = 0x4

	sysSOL_SOCKET       = 0x1
	sysSO_ATTACH_FILTER = 0x1a

	sizeofKernelSockaddrStorage = 0x80
	sizeofSockaddrInet6         = 0x1c
	sizeofInet6Pktinfo          = 0x14
	sizeofIPv6Mtuinfo           = 0x20
	sizeofIPv6FlowlabelReq      = 0x20

	sizeofIPv6Mreq       = 0x14
	sizeofGroupReq       = 0x84
	sizeofGroupSourceReq = 0x104

	sizeofICMPv6Filter = 0x20

	sizeofSockFprog = 0x8
)

type kernelSockaddrStorage struct {
	Family  uint16
	X__data [126]uint8
}

type sockaddrInet6 struct {
	Family   uint16
	Port     uint16
	Flowinfo uint32
	Addr     [16]byte /* in6_addr */
	Scope_id uint32
}

type inet6Pktinfo struct {
	Addr    [16]byte /* in6_addr */
	Ifindex int32
}

type ipv6Mtuinfo struct {
	Addr sockaddrInet6
	Mtu  uint32
}

type ipv6FlowlabelReq struct {
	Dst        [16]byte /* in6_addr */
	Label      uint32
	Action     uint8
	Share      uint8
	Flags      uint16
	Expires    uint16
	Linger     uint16
	X__flr_pad uint32
}

type ipv6Mreq struct {
	Multiaddr [16]byte /* in6_addr */
	Ifindex   int32
}

type groupReq struct {
	Interface uint32
	Group     kernelSockaddrStorage
}

type groupSourceReq struct {
	Interface uint32
	Group     kernelSockaddrStorage
	Source    kernelSockaddrStorage
}

type icmpv6Filter struct {
	Data [8]uint32
}

type sockFProg struct {
	Len       uint16
	Pad_cgo_0 [2]byte
	Filter    *sockFilter
}

type sockFilter struct {
	Code uint16
	Jt   uint8
	Jf   uint8
	K    uint32
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build dragonfly netbsd openbsd

package ipv6

import (
	"net"
	"syscall"

	"golang.org/x/net/internal/iana"
	"golang.org/x/net/internal/socket"
)

var (
	ctlOpts = [ctlMax]ctlOpt{
		ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass},
		ctlHopLimit:     {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit},
		ctlPacketInfo:   {sysIPV6_PKTINFO, sizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo},
		ctlNextHop:      {sysIPV6_NEXTHOP, sizeofSockaddrInet6, marshalNextHop, parseNextHop},
		ctlPathMTU:      {sysIPV6_PATHMTU, sizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU},
	}

	sockOpts = map[int]*sockOpt{
		ssoTrafficClass:        {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_TCLASS, Len: 4}},
		ssoHopLimit:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_UNICAST_HOPS, Len: 4}},
		ssoMulticastInterface:  {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_IF, Len: 4}},
		ssoMulticastHopLimit:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_HOPS, Len: 4}},
		ssoMulticastLoopback:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_MULTICAST_LOOP, Len: 4}},
		ssoReceiveTrafficClass: {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVTCLASS, Len: 4}},
		ssoReceiveHopLimit:     {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVHOPLIMIT, Len: 4}},
		ssoReceivePacketInfo:   {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPKTINFO, Len: 4}},
		ssoReceivePathMTU:      {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_RECVPATHMTU, Len: 4}},
		ssoPathMTU:             {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_PATHMTU, Len: sizeofIPv6Mtuinfo}},
		ssoChecksum:            {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_CHECKSUM, Len: 4}},
		ssoICMPFilter:          {Option: socket.Option{Level: iana.ProtocolIPv6ICMP, Name: sysICMP6_FILTER, Len: sizeofICMPv6Filter}},
		ssoJoinGroup:           {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_JOIN_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
		ssoLeaveGroup:          {Option: socket.Option{Level: iana.ProtocolIPv6, Name: sysIPV6_LEAVE_GROUP, Len: sizeofIPv6Mreq}, typ: ssoTypeIPMreq},
	}
)

func (sa *sockaddrInet6) setSockaddr(ip net.IP, i int) {
	sa.Len = sizeofSockaddrInet6
	sa.Family = syscall.AF_INET6
	copy(sa.Addr[:], ip)
	sa.Scope_id = uint32(i)
}

func (pi *inet6Pktinfo) setIfindex(i int) {
	pi.Ifindex = uint32(i)
}

func (mreq *ipv6Mreq) setIfindex(i int) {
	mreq.Interface = uint32(i)
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6

func (f *icmpv6Filter) accept(typ ICMPType) {
	f.Data[typ>>5] &^= 1 << (uint32(typ) & 31)
}

func (f *icmpv6Filter) block(typ ICMPType) {
	f.Data[typ>>5] |= 1 << (uint32(typ) & 31)
}

func (f *icmpv6Filter) setAll(block bool) {
	for i := range f.Data {
		if block {
			f.Data[i] = 1<<32 - 1
		} else {
			f.Data[i] = 0
		}
	}
}

func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
	return f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0
}


text:
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

// +godefs map struct_in6_addr [16]byte /* in6_addr */

package ipv6

/*
#include <sys/param.h>
#include <sys/socket.h>

#include <netinet/in.h>
#include <netinet/icmp6.h>
*/
import "C"

const (
	sysIPV6_UNICAST_HOPS   = C.IPV6_UNICAST_HOPS
	sysIPV6_MULTICAST_IF   = C.IPV6_MULTICAST_IF
	sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS
	sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP
	sysIPV6_JOIN_GROUP     = C.IPV6_JOIN_GROUP
	sysIPV6_LEAVE_GROUP    = C.IPV6_LEAVE_GROUP
	sysIPV6_PORTRANGE      = C.IPV6_PORTRANGE
	sysICMP6_FILTER        = C.ICMP6_FILTER

	sysIPV6_CHECKSUM = C.IPV6_CHECKSUM
	sysIPV6_V6ONLY   = C.IPV6_V6ONLY

	sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY

	sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS

	sysIPV6_RECVPKTINFO  = C.IPV6_RECVPKTINFO
	sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT
	sysIPV6_RECVRTHDR    = C.IPV6_RECVRTHDR
	sysIPV6_RECVHOPOPTS  = C.IPV6_RECVHOPOPTS
	sysIPV6_RECVDSTOPTS  = C.IPV6_RECVDSTOPTS

	sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU
	sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU
	sysIPV6_PATHMTU     = C.IPV6_PATHMTU

	sysIPV6_PKTINFO  = C.IPV6_PKTINFO
	sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT
	sysIPV6_NEXTHOP  = C.IPV6_NEXTHOP
	sysIPV6_HOPOPTS  = C.IPV6_HOPOPTS
	sysIPV6_DSTOPTS  = C.IPV6_DSTOPTS
	sysIPV6_RTHDR    = C.IPV6_RTHDR

	sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS

	sysIPV6_TCLASS   = C.IPV6_TCLASS
	sysIPV6_DONTFRAG = C.IPV6_DONTFRAG

	sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT
	sysIPV6_PORTRANGE_HIGH    = C.IPV6_PORTRANGE_HIGH
	sysIPV6_PORTRANGE_LOW     = C.IPV6_PORTRANGE_LOW

	sizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6
	sizeofInet6Pktinfo  = C.sizeof_struct_in6_pktinfo
	sizeofIPv6Mtuinfo   = C.sizeof_struct_ip6_mtuinfo

	sizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq

	sizeofICMPv6Filter = C.sizeof_struct_icmp6_filter
)

type sockaddrInet6 C.struct_sockaddr_in6

type inet6Pktinfo C.struct_in6_pktinfo

type ipv6Mtuinfo C.struct_ip6_mtuinfo

type ipv6Mreq C.struct_ipv6_mreq

type icmpv6Filter C.struct_icmp6_filter


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6_test

import (
	"bytes"
	"net"
	"os"
	"runtime"
	"testing"
	"time"

	"golang.org/x/net/icmp"
	"golang.org/x/net/internal/iana"
	"golang.org/x/net/internal/nettest"
	"golang.org/x/net/ipv6"
)

var packetConnReadWriteMulticastUDPTests = []struct {
	addr     string
	grp, src *net.UDPAddr
}{
	{"[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727

	{"[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771
}

func TestPacketConnReadWriteMulticastUDP(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if !supportsIPv6 {
		t.Skip("ipv6 is not supported")
	}
	if !nettest.SupportsIPv6MulticastDeliveryOnLoopback() {
		t.Skipf("multicast delivery doesn't work correctly on %s", runtime.GOOS)
	}
	ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
	if ifi == nil {
		t.Skipf("not available on %s", runtime.GOOS)
	}

	for _, tt := range packetConnReadWriteMulticastUDPTests {
		c, err := net.ListenPacket("udp6", tt.addr)
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		grp := *tt.grp
		grp.Port = c.LocalAddr().(*net.UDPAddr).Port
		p := ipv6.NewPacketConn(c)
		defer p.Close()
		if tt.src == nil {
			if err := p.JoinGroup(ifi, &grp); err != nil {
				t.Fatal(err)
			}
			defer p.LeaveGroup(ifi, &grp)
		} else {
			if err := p.JoinSourceSpecificGroup(ifi, &grp, tt.src); err != nil {
				switch runtime.GOOS {
				case "freebsd", "linux":
				default: // platforms that don't support MLDv2 fail here
					t.Logf("not supported on %s", runtime.GOOS)
					continue
				}
				t.Fatal(err)
			}
			defer p.LeaveSourceSpecificGroup(ifi, &grp, tt.src)
		}
		if err := p.SetMulticastInterface(ifi); err != nil {
			t.Fatal(err)
		}
		if _, err := p.MulticastInterface(); err != nil {
			t.Fatal(err)
		}
		if err := p.SetMulticastLoopback(true); err != nil {
			t.Fatal(err)
		}
		if _, err := p.MulticastLoopback(); err != nil {
			t.Fatal(err)
		}

		cm := ipv6.ControlMessage{
			TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
			Src:          net.IPv6loopback,
			IfIndex:      ifi.Index,
		}
		cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
		wb := []byte("HELLO-R-U-THERE")

		for i, toggle := range []bool{true, false, true} {
			if err := p.SetControlMessage(cf, toggle); err != nil {
				if nettest.ProtocolNotSupported(err) {
					t.Logf("not supported on %s", runtime.GOOS)
					continue
				}
				t.Fatal(err)
			}
			if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
				t.Fatal(err)
			}
			cm.HopLimit = i + 1
			if n, err := p.WriteTo(wb, &cm, &grp); err != nil {
				t.Fatal(err)
			} else if n != len(wb) {
				t.Fatal(err)
			}
			rb := make([]byte, 128)
			if n, _, _, err := p.ReadFrom(rb); err != nil {
				t.Fatal(err)
			} else if !bytes.Equal(rb[:n], wb) {
				t.Fatalf("got %v; want %v", rb[:n], wb)
			}
		}
	}
}

var packetConnReadWriteMulticastICMPTests = []struct {
	grp, src *net.IPAddr
}{
	{&net.IPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727

	{&net.IPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.IPAddr{IP: net.IPv6loopback}}, // see RFC 5771
}

func TestPacketConnReadWriteMulticastICMP(t *testing.T) {
	switch runtime.GOOS {
	case "nacl", "plan9", "windows":
		t.Skipf("not supported on %s", runtime.GOOS)
	}
	if !supportsIPv6 {
		t.Skip("ipv6 is not supported")
	}
	if !nettest.SupportsIPv6MulticastDeliveryOnLoopback() {
		t.Skipf("multicast delivery doesn't work correctly on %s", runtime.GOOS)
	}
	if m, ok := nettest.SupportsRawIPSocket(); !ok {
		t.Skip(m)
	}
	ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback)
	if ifi == nil {
		t.Skipf("not available on %s", runtime.GOOS)
	}

	for _, tt := range packetConnReadWriteMulticastICMPTests {
		c, err := net.ListenPacket("ip6:ipv6-icmp", "::")
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, tt.grp.IP)
		p := ipv6.NewPacketConn(c)
		defer p.Close()
		if tt.src == nil {
			if err := p.JoinGroup(ifi, tt.grp); err != nil {
				t.Fatal(err)
			}
			defer p.LeaveGroup(ifi, tt.grp)
		} else {
			if err := p.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil {
				switch runtime.GOOS {
				case "freebsd", "linux":
				default: // platforms that don't support MLDv2 fail here
					t.Logf("not supported on %s", runtime.GOOS)
					continue
				}
				t.Fatal(err)
			}
			defer p.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src)
		}
		if err := p.SetMulticastInterface(ifi); err != nil {
			t.Fatal(err)
		}
		if _, err := p.MulticastInterface(); err != nil {
			t.Fatal(err)
		}
		if err := p.SetMulticastLoopback(true); err != nil {
			t.Fatal(err)
		}
		if _, err := p.MulticastLoopback(); err != nil {
			t.Fatal(err)
		}

		cm := ipv6.ControlMessage{
			TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
			Src:          net.IPv6loopback,
			IfIndex:      ifi.Index,
		}
		cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU

		var f ipv6.ICMPFilter
		f.SetAll(true)
		f.Accept(ipv6.ICMPTypeEchoReply)
		if err := p.SetICMPFilter(&f); err != nil {
			t.Fatal(err)
		}

		var psh []byte
		for i, toggle := range []bool{true, false, true} {
			if toggle {
				psh = nil
				if err := p.SetChecksum(true, 2); err != nil {
					// Solaris never allows to
					// modify ICMP properties.
					if runtime.GOOS != "solaris" {
						t.Fatal(err)
					}
				}
			} else {
				psh = pshicmp
				// Some platforms never allow to
				// disable the kernel checksum
				// processing.
				p.SetChecksum(false, -1)
			}
			wb, err := (&icmp.Message{
				Type: ipv6.ICMPTypeEchoRequest, Code: 0,
				Body: &icmp.Echo{
					ID: os.Getpid() & 0xffff, Seq: i + 1,
					Data: []byte("HELLO-R-U-THERE"),
				},
			}).Marshal(psh)
			if err != nil {
				t.Fatal(err)
			}
			if err := p.SetControlMessage(cf, toggle); err != nil {
				if nettest.ProtocolNotSupported(err) {
					t.Logf("not supported on %s", runtime.GOOS)
					continue
				}
				t.Fatal(err)
			}
			if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil {
				t.Fatal(err)
			}
			cm.HopLimit = i + 1
			if n, err := p.WriteTo(wb, &cm, tt.grp); err != nil {
				t.Fatal(err)
			} else if n != len(wb) {
				t.Fatalf("got %v; want %v", n, len(wb))
			}
			rb := make([]byte, 128)
			if n, _, _, err := p.ReadFrom(rb); err != nil {
				switch runtime.GOOS {
				case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket
					t.Logf("not supported on %s", runtime.GOOS)
					continue
				}
				t.Fatal(err)
			} else {
				if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil {
					t.Fatal(err)
				} else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 {
					t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0)
				}
			}
		}
	}
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ipv6

import (
	"syscall"

	"golang.org/x/net/internal/socket"
)

func setControlMessage(c *socket.Conn, opt *rawOpt, cf ControlFlags, on bool) error {
	// TODO(mikio): implement this
	return syscall.EWINDOWS
}


text:
// Created by cgo -godefs - DO NOT EDIT
// cgo -godefs defs_linux.go

package ipv6

const (
	sysIPV6_ADDRFORM       = 0x1
	sysIPV6_2292PKTINFO    = 0x2
	sysIPV6_2292HOPOPTS    = 0x3
	sysIPV6_2292DSTOPTS    = 0x4
	sysIPV6_2292RTHDR      = 0x5
	sysIPV6_2292PKTOPTIONS = 0x6
	sysIPV6_CHECKSUM       = 0x7
	sysIPV6_2292HOPLIMIT   = 0x8
	sysIPV6_NEXTHOP        = 0x9
	sysIPV6_FLOWINFO       = 0xb

	sysIPV6_UNICAST_HOPS        = 0x10
	sysIPV6_MULTICAST_IF        = 0x11
	sysIPV6_MULTICAST_HOPS      = 0x12
	sysIPV6_MULTICAST_LOOP      = 0x13
	sysIPV6_ADD_MEMBERSHIP      = 0x14
	sysIPV6_DROP_MEMBERSHIP     = 0x15
	sysMCAST_JOIN_GROUP         = 0x2a
	sysMCAST_LEAVE_GROUP        = 0x2d
	sysMCAST_JOIN_SOURCE_GROUP  = 0x2e
	sysMCAST_LEAVE_SOURCE_GROUP = 0x2f
	sysMCAST_BLOCK_SOURCE       = 0x2b
	sysMCAST_UNBLOCK_SOURCE     = 0x2c
	sysMCAST_MSFILTER           = 0x30
	sysIPV6_ROUTER_ALERT        = 0x16
	sysIPV6_MTU_DISCOVER        = 0x17
	sysIPV6_MTU                 = 0x18
	sysIPV6_RECVERR             = 0x19
	sysIPV6_V6ONLY              = 0x1a
	sysIPV6_JOIN_ANYCAST        = 0x1b
	sysIPV6_LEAVE_ANYCAST       = 0x1c

	sysIPV6_FLOWLABEL_MGR = 0x20
	sysIPV6_FLOWINFO_SEND = 0x21

	sysIPV6_IPSEC_POLICY = 0x22
	sysIPV6_XFRM_POLICY  = 0x23

	sysIPV6_RECVPKTINFO  = 0x31
	sysIPV6_PKTINFO      = 0x32
	sysIPV6_RECVHOPLIMIT = 0x33
	sysIPV6_HOPLIMIT     = 0x34
	sysIPV6_RECVHOPOPTS  = 0x35
	sysIPV6_HOPOPTS      = 0x36
	sysIPV6_RTHDRDSTOPTS = 0x37
	sysIPV6_RECVRTHDR    = 0x38
	sysIPV6_RTHDR        = 0x39
	sysIPV6_RECVDSTOPTS  = 0x3a
	sysIPV6_DSTOPTS      = 0x3b
	sysIPV6_RECVPATHMTU  = 0x3c
	sysIPV6_PATHMTU      = 0x3d
	sysIPV6_DONTFRAG     = 0x3e

	sysIPV6_RECVTCLASS = 0x42
	sysIPV6_TCLASS     = 0x43

	sysIPV6_ADDR_PREFERENCES = 0x48

	sysIPV6_PREFER_SRC_TMP            = 0x1
	sysIPV6_PREFER_SRC_PUBLIC         = 0x2
	sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100
	sysIPV6_PREFER_SRC_COA            = 0x4
	sysIPV6_PREFER_SRC_HOME           = 0x400
	sysIPV6_PREFER_SRC_CGA            = 0x8
	sysIPV6_PREFER_SRC_NONCGA         = 0x800

	sysIPV6_MINHOPCOUNT = 0x49

	sysIPV6_ORIGDSTADDR     = 0x4a
	sysIPV6_RECVORIGDSTADDR = 0x4a
	sysIPV6_TRANSPARENT     = 0x4b
	sysIPV6_UNICAST_IF      = 0x4c

	sysICMPV6_FILTER = 0x1

	sysICMPV6_FILTER_BLOCK       = 0x1
	sysICMPV6_FILTER_PASS        = 0x2
	sysICMPV6_FILTER_BLOCKOTHERS = 0x3
	sysICMPV6_FILTER_PASSONLY    = 0x4

	sysSOL_SOCKET       = 0x1
	sysSO_ATTACH_FILTER = 0x1a

	sizeofKernelSockaddrStorage = 0x80
	sizeofSockaddrInet6         = 0x1c
	sizeofInet6Pktinfo          = 0x14
	sizeofIPv6Mtuinfo           = 0x20
	sizeofIPv6FlowlabelReq      = 0x20

	sizeofIPv6Mreq       = 0x14
	sizeofGroupReq       = 0x88
	sizeofGroupSourceReq = 0x108

	sizeofICMPv6Filter = 0x20

	sizeofSockFprog = 0x10
)

type kernelSockaddrStorage struct {
	Family  uint16
	X__data [126]int8
}

type sockaddrInet6 struct {
	Family   uint16
	Port     uint16
	Flowinfo uint32
	Addr     [16]byte /* in6_addr */
	Scope_id uint32
}

type inet6Pktinfo struct {
	Addr    [16]byte /* in6_addr */
	Ifindex int32
}

type ipv6Mtuinfo struct {
	Addr sockaddrInet6
	Mtu  uint32
}

type ipv6FlowlabelReq struct {
	Dst        [16]byte /* in6_addr */
	Label      uint32
	Action     uint8
	Share      uint8
	Flags      uint16
	Expires    uint16
	Linger     uint16
	X__flr_pad uint32
}

type ipv6Mreq struct {
	Multiaddr [16]byte /* in6_addr */
	Ifindex   int32
}

type groupReq struct {
	Interface uint32
	Pad_cgo_0 [4]byte
	Group     kernelSockaddrStorage
}

type groupSourceReq struct {
	Interface uint32
	Pad_cgo_0 [4]byte
	Group     kernelSockaddrStorage
	Source    kernelSockaddrStorage
}

type icmpv6Filter struct {
	Data [8]uint32
}

type sockFProg struct {
	Len       uint16
	Pad_cgo_0 [6]byte
	Filter    *sockFilter
}

type sockFilter struct {
	Code uint16
	Jt   uint8
	Jf   uint8
	K    uint32
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin dragonfly freebsd netbsd openbsd

package ipv6

func (f *icmpv6Filter) accept(typ ICMPType) {
	f.Filt[typ>>5] |= 1 << (uint32(typ) & 31)
}

func (f *icmpv6Filter) block(typ ICMPType) {
	f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31)
}

func (f *icmpv6Filter) setAll(block bool) {
	for i := range f.Filt {
		if block {
			f.Filt[i] = 0
		} else {
			f.Filt[i] = 1<<32 - 1
		}
	}
}

func (f *icmpv6Filter) willBlock(typ ICMPType) bool {
	return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0
}


text:
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build nacl plan9 windows

package ipv6

import (
	"net"
	"syscall"
)

// ReadFrom reads a payload of the received IPv6 datagram, from the
// endpoint c, copying the payload into b. It returns the number of
// bytes copied into b, the control message cm and the source address
// src of the received datagram.
func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) {
	if !c.ok() {
		return 0, nil, nil, syscall.EINVAL
	}
	if n, src, err = c.PacketConn.ReadFrom(b); err != nil {
		return 0, nil, nil, err
	}
	return
}

// WriteTo writes a payload of the IPv6 datagram, to the destination
// address dst through the endpoint c, copying the payload from b. It
// returns the number of bytes written. The control message cm allows
// the IPv6 header fields and the datagram path to be specified. The
// cm may be nil if control of the outgoing datagram is not required.
func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) {
	if !c.ok() {
		return 0, syscall.EINVAL
	}
	if dst == nil {
		return 0, errMissingAddress
	}
	return c.PacketConn.WriteTo(b, dst)
}