// 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 freebsd linux netbsd openbsd

package ipv6

import (
	"net"
	"os"
	"syscall"
	"unsafe"
)

const pktinfo = FlagDst | FlagInterface

func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error {
	opt.Lock()
	defer opt.Unlock()
	if cf&FlagTrafficClass != 0 {
		if err := setIPv6ReceiveTrafficClass(fd, on); err != nil {
			return err
		}
		if on {
			opt.set(FlagTrafficClass)
		} else {
			opt.clear(FlagTrafficClass)
		}
	}
	if cf&FlagHopLimit != 0 {
		if err := setIPv6ReceiveHopLimit(fd, on); err != nil {
			return err
		}
		if on {
			opt.set(FlagHopLimit)
		} else {
			opt.clear(FlagHopLimit)
		}
	}
	if cf&pktinfo != 0 {
		if err := setIPv6ReceivePacketInfo(fd, on); err != nil {
			return err
		}
		if on {
			opt.set(cf & pktinfo)
		} else {
			opt.clear(cf & pktinfo)
		}
	}
	if cf&FlagPathMTU != 0 {
		if err := setIPv6ReceivePathMTU(fd, on); err != nil {
			return err
		}
		if on {
			opt.set(FlagPathMTU)
		} else {
			opt.clear(FlagPathMTU)
		}
	}
	return nil
}

func newControlMessage(opt *rawOpt) (oob []byte) {
	opt.Lock()
	defer opt.Unlock()
	l, off := 0, 0
	if opt.isset(FlagTrafficClass) {
		l += syscall.CmsgSpace(4)
	}
	if opt.isset(FlagHopLimit) {
		l += syscall.CmsgSpace(4)
	}
	if opt.isset(pktinfo) {
		l += syscall.CmsgSpace(sysSizeofPacketInfo)
	}
	if opt.isset(FlagPathMTU) {
		l += syscall.CmsgSpace(sysSizeofMTUInfo)
	}
	if l > 0 {
		oob = make([]byte, l)
		if opt.isset(FlagTrafficClass) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockoptReceiveTrafficClass
			m.SetLen(syscall.CmsgLen(4))
			off += syscall.CmsgSpace(4)
		}
		if opt.isset(FlagHopLimit) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockoptReceiveHopLimit
			m.SetLen(syscall.CmsgLen(4))
			off += syscall.CmsgSpace(4)
		}
		if opt.isset(pktinfo) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockoptReceivePacketInfo
			m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
			off += syscall.CmsgSpace(sysSizeofPacketInfo)
		}
		if opt.isset(FlagPathMTU) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockoptReceivePathMTU
			m.SetLen(syscall.CmsgLen(sysSizeofMTUInfo))
			off += syscall.CmsgSpace(sysSizeofMTUInfo)
		}
	}
	return
}

func parseControlMessage(b []byte) (*ControlMessage, error) {
	if len(b) == 0 {
		return nil, nil
	}
	cmsgs, err := syscall.ParseSocketControlMessage(b)
	if err != nil {
		return nil, os.NewSyscallError("parse socket control message", err)
	}
	cm := &ControlMessage{}
	for _, m := range cmsgs {
		if m.Header.Level != ianaProtocolIPv6 {
			continue
		}
		switch m.Header.Type {
		case sysSockoptTrafficClass:
			cm.TrafficClass = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
		case sysSockoptHopLimit:
			cm.HopLimit = int(*(*byte)(unsafe.Pointer(&m.Data[:1][0])))
		case sysSockoptPacketInfo:
			pi := (*sysPacketInfo)(unsafe.Pointer(&m.Data[0]))
			cm.Dst = pi.IP[:]
			cm.IfIndex = int(pi.IfIndex)
		case sysSockoptPathMTU:
			mi := (*sysMTUInfo)(unsafe.Pointer(&m.Data[0]))
			cm.Dst = mi.Addr.Addr[:]
			cm.IfIndex = int(mi.Addr.Scope_id)
			cm.MTU = int(mi.MTU)
		}
	}
	return cm, nil
}

func marshalControlMessage(cm *ControlMessage) (oob []byte) {
	if cm == nil {
		return
	}
	l, off := 0, 0
	if cm.TrafficClass > 0 {
		l += syscall.CmsgSpace(4)
	}
	if cm.HopLimit > 0 {
		l += syscall.CmsgSpace(4)
	}
	pion := false
	if cm.Src.To4() == nil && cm.Src.To16() != nil || cm.IfIndex != 0 {
		pion = true
		l += syscall.CmsgSpace(sysSizeofPacketInfo)
	}
	if len(cm.NextHop) == net.IPv6len {
		l += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
	}
	if l > 0 {
		oob = make([]byte, l)
		if cm.TrafficClass > 0 {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockoptTrafficClass
			m.SetLen(syscall.CmsgLen(4))
			data := oob[off+syscall.CmsgLen(0):]
			*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.TrafficClass)
			off += syscall.CmsgSpace(4)
		}
		if cm.HopLimit > 0 {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockoptHopLimit
			m.SetLen(syscall.CmsgLen(4))
			data := oob[off+syscall.CmsgLen(0):]
			*(*byte)(unsafe.Pointer(&data[:1][0])) = byte(cm.HopLimit)
			off += syscall.CmsgSpace(4)
		}
		if pion {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockoptPacketInfo
			m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
			pi := (*sysPacketInfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
			if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
				copy(pi.IP[:], ip)
			}
			if cm.IfIndex != 0 {
				pi.IfIndex = uint32(cm.IfIndex)
			}
			off += syscall.CmsgSpace(sysSizeofPacketInfo)
		}
		if len(cm.NextHop) == net.IPv6len {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockoptNextHop
			m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
			setSockaddr(sa, cm.NextHop, cm.IfIndex)
			off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
		}
	}
	return
}
