Beispiel #1
0
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
	if cm == nil {
		return
	}
	l, off := 0, 0
	pion := false
	if cm.Src.To4() != nil || cm.IfIndex != 0 {
		pion = true
		l += syscall.CmsgSpace(syscall.SizeofInet4Pktinfo)
	}
	if l > 0 {
		oob = make([]byte, l)
		if pion {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIP
			m.Type = syscall.IP_PKTINFO
			m.SetLen(syscall.CmsgLen(syscall.SizeofInet4Pktinfo))
			pi := (*syscall.Inet4Pktinfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
			if ip := cm.Src.To4(); ip != nil {
				copy(pi.Addr[:], ip)
			}
			if cm.IfIndex != 0 {
				pi.Ifindex = int32(cm.IfIndex)
			}
			off += syscall.CmsgSpace(syscall.SizeofInet4Pktinfo)
		}
	}
	return
}
func newControlMessage(opt *rawOpt) (oob []byte) {
	opt.Lock()
	defer opt.Unlock()
	l, off := 0, 0
	if opt.isset(FlagHopLimit) {
		l += syscall.CmsgSpace(4)
	}
	if opt.isset(pktinfo) {
		l += syscall.CmsgSpace(sysSizeofPacketInfo)
	}
	if l > 0 {
		oob = make([]byte, l)
		if opt.isset(FlagHopLimit) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockopt2292HopLimit
			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 = sysSockopt2292PacketInfo
			m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
			off += syscall.CmsgSpace(sysSizeofPacketInfo)
		}
	}
	return
}
Beispiel #3
0
func newControlMessage(opt *rawOpt) (oob []byte) {
	opt.Lock()
	defer opt.Unlock()
	l, off := 0, 0
	if opt.isset(FlagTTL) {
		l += syscall.CmsgSpace(1)
	}
	if opt.isset(pktinfo) {
		l += syscall.CmsgSpace(syscall.SizeofInet4Pktinfo)
	}
	if l > 0 {
		oob = make([]byte, l)
		if opt.isset(FlagTTL) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIP
			m.Type = syscall.IP_RECVTTL
			m.SetLen(syscall.CmsgLen(1))
			off += syscall.CmsgSpace(1)
		}
		if opt.isset(pktinfo) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIP
			m.Type = syscall.IP_PKTINFO
			m.SetLen(syscall.CmsgLen(syscall.SizeofInet4Pktinfo))
			off += syscall.CmsgSpace(syscall.SizeofInet4Pktinfo)
		}
	}
	return
}
func newControlMessage(opt *rawOpt) (oob []byte) {
	opt.RLock()
	var l int
	if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 {
		l += syscall.CmsgSpace(ctlOpts[ctlTrafficClass].length)
	}
	if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 {
		l += syscall.CmsgSpace(ctlOpts[ctlHopLimit].length)
	}
	if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 {
		l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
	}
	if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 {
		l += syscall.CmsgSpace(ctlOpts[ctlPathMTU].length)
	}
	if l > 0 {
		oob = make([]byte, l)
		b := oob
		if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 {
			b = ctlOpts[ctlTrafficClass].marshal(b, nil)
		}
		if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 {
			b = ctlOpts[ctlHopLimit].marshal(b, nil)
		}
		if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 {
			b = ctlOpts[ctlPacketInfo].marshal(b, nil)
		}
		if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 {
			b = ctlOpts[ctlPathMTU].marshal(b, nil)
		}
	}
	opt.RUnlock()
	return
}
Beispiel #5
0
func newControlMessage(opt *rawOpt) (oob []byte) {
	opt.lock()
	defer opt.unlock()
	if opt.isset(FlagTTL) {
		b := make([]byte, syscall.CmsgSpace(1))
		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
		cmsg.Level = ianaProtocolIP
		cmsg.Type = syscall.IP_RECVTTL
		cmsg.SetLen(syscall.CmsgLen(1))
		oob = append(oob, b...)
	}
	if opt.isset(FlagDst) {
		b := make([]byte, syscall.CmsgSpace(net.IPv4len))
		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
		cmsg.Level = ianaProtocolIP
		cmsg.Type = syscall.IP_RECVDSTADDR
		cmsg.SetLen(syscall.CmsgLen(net.IPv4len))
		oob = append(oob, b...)
	}
	if opt.isset(FlagInterface) {
		b := make([]byte, syscall.CmsgSpace(syscall.SizeofSockaddrDatalink))
		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
		cmsg.Level = ianaProtocolIP
		cmsg.Type = syscall.IP_RECVIF
		cmsg.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
		oob = append(oob, b...)
	}
	return
}
Beispiel #6
0
func (opt *rawOpt) oobLen() (l int) {
	if opt.isset(FlagTTL) {
		l += syscall.CmsgSpace(1)
	}
	if opt.isset(FlagSrc | FlagDst | FlagInterface) {
		l += syscall.CmsgSpace(sysSizeofPacketInfo)
	}
	return
}
Beispiel #7
0
func marshalTTL(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = iana.ProtocolIP
	m.Type = sysIP_RECVTTL
	m.SetLen(syscall.CmsgLen(1))
	return b[syscall.CmsgSpace(1):]
}
Beispiel #8
0
func marshalDst(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = iana.ProtocolIP
	m.Type = sysIP_RECVDSTADDR
	m.SetLen(syscall.CmsgLen(net.IPv4len))
	return b[syscall.CmsgSpace(net.IPv4len):]
}
Beispiel #9
0
func marshalInterface(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = iana.ProtocolIP
	m.Type = sysIP_RECVIF
	m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
	return b[syscall.CmsgSpace(syscall.SizeofSockaddrDatalink):]
}
Beispiel #10
0
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
	if cm == nil {
		return
	}
	pi := &syscall.Inet4Pktinfo{}
	pion := false
	if ip := cm.Src.To4(); ip != nil {
		copy(pi.Spec_dst[:], ip[:net.IPv4len])
		pion = true
	}
	if cm.IfIndex != 0 {
		pi.Ifindex = int32(cm.IfIndex)
		pion = true
	}
	if pion {
		b := make([]byte, syscall.CmsgSpace(syscall.SizeofInet4Pktinfo))
		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
		cmsg.Level = ianaProtocolIP
		cmsg.Type = syscall.IP_PKTINFO
		cmsg.SetLen(syscall.CmsgLen(syscall.SizeofInet4Pktinfo))
		data := b[syscall.CmsgLen(0):]
		copy(data[:syscall.SizeofInet4Pktinfo], (*[syscall.SizeofInet4Pktinfo]byte)(unsafe.Pointer(pi))[:syscall.SizeofInet4Pktinfo])
		oob = append(oob, b...)
	}
	return
}
func marshalPathMTU(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = iana.ProtocolIPv6
	m.Type = sysIPV6_PATHMTU
	m.SetLen(syscall.CmsgLen(sysSizeofIPv6Mtuinfo))
	return b[syscall.CmsgSpace(sysSizeofIPv6Mtuinfo):]
}
// http://golang.org/src/pkg/syscall/sockcmsg_linux.go
// UnixCredentials encodes credentials into a socket control message
// for sending to another process. This can be used for
// authentication.
func UnixCredentials(ucred *Ucred) []byte {
	b := make([]byte, syscall.CmsgSpace(SizeofUcred))
	h := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	h.Level = syscall.SOL_SOCKET
	h.Type = syscall.SCM_CREDS
	h.SetLen(syscall.CmsgLen(SizeofUcred))
	*((*Ucred)(cmsgData(h))) = *ucred
	return b
}
Beispiel #13
0
func (opt *rawOpt) oobLen() (l int) {
	if opt.isset(FlagTTL) {
		l += syscall.CmsgSpace(1)
	}
	if supportsPacketInfo {
		if opt.isset(FlagSrc | FlagDst | FlagInterface) {
			l += syscall.CmsgSpace(sysSizeofPacketInfo)
		}
	} else {
		if opt.isset(FlagDst) {
			l += syscall.CmsgSpace(net.IPv4len)
		}
		if opt.isset(FlagInterface) {
			l += syscall.CmsgSpace(syscall.SizeofSockaddrDatalink)
		}
	}
	return
}
Beispiel #14
0
func (opt *rawOpt) marshalControlMessage() (oob []byte) {
	var off int
	oob = make([]byte, opt.oobLen())
	if opt.isset(FlagTTL) {
		m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
		m.Level = ianaProtocolIP
		m.Type = sysSockoptReceiveTTL
		m.SetLen(syscall.CmsgLen(1))
		off += syscall.CmsgSpace(1)
	}
	if opt.isset(FlagSrc | FlagDst | FlagInterface) {
		m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[0]))
		m.Level = ianaProtocolIP
		m.Type = sysSockoptPacketInfo
		m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
		off += syscall.CmsgSpace(sysSizeofPacketInfo)
	}
	return
}
Beispiel #15
0
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
	if cm == nil {
		return
	}
	var l int
	tclass := false
	if ctlOpts[ctlTrafficClass].name > 0 && cm.TrafficClass > 0 {
		tclass = true
		l += syscall.CmsgSpace(ctlOpts[ctlTrafficClass].length)
	}
	hoplimit := false
	if ctlOpts[ctlHopLimit].name > 0 && cm.HopLimit > 0 {
		hoplimit = true
		l += syscall.CmsgSpace(ctlOpts[ctlHopLimit].length)
	}
	pktinfo := false
	if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To16() != nil && cm.Src.To4() == nil || cm.IfIndex > 0) {
		pktinfo = true
		l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
	}
	nexthop := false
	if ctlOpts[ctlNextHop].name > 0 && cm.NextHop.To16() != nil && cm.NextHop.To4() == nil {
		nexthop = true
		l += syscall.CmsgSpace(ctlOpts[ctlNextHop].length)
	}
	if l > 0 {
		oob = make([]byte, l)
		b := oob
		if tclass {
			b = ctlOpts[ctlTrafficClass].marshal(b, cm)
		}
		if hoplimit {
			b = ctlOpts[ctlHopLimit].marshal(b, cm)
		}
		if pktinfo {
			b = ctlOpts[ctlPacketInfo].marshal(b, cm)
		}
		if nexthop {
			b = ctlOpts[ctlNextHop].marshal(b, cm)
		}
	}
	return
}
func marshalNextHop(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = iana.ProtocolIPv6
	m.Type = sysIPV6_NEXTHOP
	m.SetLen(syscall.CmsgLen(sysSizeofSockaddrInet6))
	if cm != nil {
		sa := (*sysSockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
		sa.setSockaddr(cm.NextHop, cm.IfIndex)
	}
	return b[syscall.CmsgSpace(sysSizeofSockaddrInet6):]
}
func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = iana.ProtocolIPv6
	m.Type = sysIPV6_HOPLIMIT
	m.SetLen(syscall.CmsgLen(4))
	if cm != nil {
		data := b[syscall.CmsgLen(0):]
		nativeEndian.PutUint32(data[:4], uint32(cm.HopLimit))
	}
	return b[syscall.CmsgSpace(4):]
}
func marshal2292HopLimit(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = ianaProtocolIPv6
	m.Type = sysIPV6_2292HOPLIMIT
	m.SetLen(syscall.CmsgLen(4))
	if cm != nil {
		data := b[syscall.CmsgLen(0):]
		*(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.HopLimit)
	}
	return b[syscall.CmsgSpace(4):]
}
func marshalHopLimit(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = iana.ProtocolIPv6
	m.Type = sysIPV6_HOPLIMIT
	m.SetLen(syscall.CmsgLen(4))
	if cm != nil {
		data := b[syscall.CmsgLen(0):]
		// TODO(mikio): fix potential misaligned memory access
		*(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.HopLimit)
	}
	return b[syscall.CmsgSpace(4):]
}
Beispiel #20
0
func newControlMessage(opt *rawOpt) (oob []byte) {
	opt.lock()
	defer opt.unlock()
	if opt.isset(FlagTTL) {
		b := make([]byte, syscall.CmsgSpace(1))
		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
		cmsg.Level = ianaProtocolIP
		cmsg.Type = syscall.IP_RECVTTL
		cmsg.SetLen(syscall.CmsgLen(1))
		oob = append(oob, b...)
	}
	if opt.isset(pktinfo) {
		b := make([]byte, syscall.CmsgSpace(syscall.SizeofInet4Pktinfo))
		cmsg := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
		cmsg.Level = ianaProtocolIP
		cmsg.Type = syscall.IP_PKTINFO
		cmsg.SetLen(syscall.CmsgLen(syscall.SizeofInet4Pktinfo))
		oob = append(oob, b...)
	}
	return
}
Beispiel #21
0
func newControlMessage(opt *rawOpt) (oob []byte) {
	opt.RLock()
	var l int
	if opt.isset(FlagTTL) {
		l += syscall.CmsgSpace(ctlOpts[ctlTTL].length)
	}
	if ctlOpts[ctlPacketInfo].name > 0 {
		if opt.isset(FlagSrc | FlagDst | FlagInterface) {
			l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
		}
	} else {
		if opt.isset(FlagDst) {
			l += syscall.CmsgSpace(ctlOpts[ctlDst].length)
		}
		if opt.isset(FlagInterface) {
			l += syscall.CmsgSpace(ctlOpts[ctlInterface].length)
		}
	}
	if l > 0 {
		oob = make([]byte, l)
		b := oob
		if opt.isset(FlagTTL) {
			b = ctlOpts[ctlTTL].marshal(b, nil)
		}
		if ctlOpts[ctlPacketInfo].name > 0 {
			if opt.isset(FlagSrc | FlagDst | FlagInterface) {
				b = ctlOpts[ctlPacketInfo].marshal(b, nil)
			}
		} else {
			if opt.isset(FlagDst) {
				b = ctlOpts[ctlDst].marshal(b, nil)
			}
			if opt.isset(FlagInterface) {
				b = ctlOpts[ctlInterface].marshal(b, nil)
			}
		}
	}
	opt.RUnlock()
	return
}
Beispiel #22
0
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(syscall.SizeofInet6Pktinfo)
	}
	if opt.isset(FlagPathMTU) {
		l += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
	}
	if l > 0 {
		oob = make([]byte, l)
		if opt.isset(FlagTrafficClass) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = syscall.IPV6_RECVTCLASS
			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 = syscall.IPV6_RECVHOPLIMIT
			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 = syscall.IPV6_RECVPKTINFO
			m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo))
			off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo)
		}
		if opt.isset(FlagPathMTU) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = syscall.IPV6_RECVPATHMTU
			m.SetLen(syscall.CmsgLen(syscall.SizeofIPv6MTUInfo))
			off += syscall.CmsgSpace(syscall.SizeofIPv6MTUInfo)
		}
	}
	return
}
Beispiel #23
0
func (conn *UnixConn) receiveUnix(buf []byte) (int, error) {
	oob := make([]byte, syscall.CmsgSpace(4))
	bufn, oobn, _, _, err := conn.ReadMsgUnix(buf, oob)
	if err != nil {
		return 0, err
	}
	fd := extractFd(oob[:oobn])
	if fd != -1 {
		f := os.NewFile(uintptr(fd), "")
		conn.fds = append(conn.fds, f)
	}

	return bufn, nil
}
Beispiel #24
0
func (opt *rawOpt) marshalControlMessage() (oob []byte) {
	var off int
	oob = make([]byte, opt.oobLen())
	if opt.isset(FlagTTL) {
		m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
		m.Level = ianaProtocolIP
		m.Type = sysSockoptReceiveTTL
		m.SetLen(syscall.CmsgLen(1))
		off += syscall.CmsgSpace(1)
	}
	if supportsPacketInfo {
		if opt.isset(FlagSrc | FlagDst | FlagInterface) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIP
			m.Type = sysSockoptPacketInfo
			m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo))
			off += syscall.CmsgSpace(sysSizeofPacketInfo)
		}
	} else {
		if opt.isset(FlagDst) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIP
			m.Type = sysSockoptReceiveDst
			m.SetLen(syscall.CmsgLen(net.IPv4len))
			off += syscall.CmsgSpace(net.IPv4len)
		}
		if opt.isset(FlagInterface) {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIP
			m.Type = sysSockoptReceiveInterface
			m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink))
			off += syscall.CmsgSpace(syscall.SizeofSockaddrDatalink)
		}
	}
	return
}
Beispiel #25
0
func marshalPacketInfo(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = iana.ProtocolIP
	m.Type = sysIP_PKTINFO
	m.SetLen(syscall.CmsgLen(sysSizeofInetPktinfo))
	if cm != nil {
		pi := (*sysInetPktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
		if ip := cm.Src.To4(); ip != nil {
			copy(pi.Spec_dst[:], ip)
		}
		if cm.IfIndex > 0 {
			pi.setIfindex(cm.IfIndex)
		}
	}
	return b[syscall.CmsgSpace(sysSizeofInetPktinfo):]
}
func marshal2292PacketInfo(b []byte, cm *ControlMessage) []byte {
	m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0]))
	m.Level = iana.ProtocolIPv6
	m.Type = sysIPV6_2292PKTINFO
	m.SetLen(syscall.CmsgLen(sizeofInet6Pktinfo))
	if cm != nil {
		pi := (*inet6Pktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)]))
		if ip := cm.Src.To16(); ip != nil && ip.To4() == nil {
			copy(pi.Addr[:], ip)
		}
		if cm.IfIndex > 0 {
			pi.setIfindex(cm.IfIndex)
		}
	}
	return b[syscall.CmsgSpace(sizeofInet6Pktinfo):]
}
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
	if cm == nil {
		return
	}
	l, off := 0, 0
	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.HopLimit > 0 {
			m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off]))
			m.Level = ianaProtocolIPv6
			m.Type = sysSockopt2292HopLimit
			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 = sysSockopt2292PacketInfo
			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 = sysSockopt2292NextHop
			m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrInet6))
			sa := (*syscall.RawSockaddrInet6)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)]))
			sa.Len = syscall.SizeofSockaddrInet6
			sa.Family = syscall.AF_INET6
			copy(sa.Addr[:], cm.NextHop)
			off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6)
		}
	}
	return
}
Beispiel #28
0
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
	if cm == nil {
		return nil
	}
	var l int
	pktinfo := false
	if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To4() != nil || cm.IfIndex > 0) {
		pktinfo = true
		l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
	}
	if l > 0 {
		oob = make([]byte, l)
		b := oob
		if pktinfo {
			b = ctlOpts[ctlPacketInfo].marshal(b, cm)
		}
	}
	return
}
Beispiel #29
0
// Get receives file descriptors from a Unix domain socket.
//
// Num specifies the expected number of file descriptors in one message.
// Internal files' names to be assigned are specified via optional filenames
// argument.
//
// You need to close all files in the returned slice. The slice can be
// non-empty even if this function returns an error.
//
// Use net.FileConn() if you're receiving a network connection.
func Get(via *net.UnixConn, num int, filenames []string) ([]*os.File, error) {
	if num < 1 {
		return nil, nil
	}

	// get the underlying socket
	viaf, err := via.File()
	if err != nil {
		return nil, err
	}
	socket := int(viaf.Fd())
	defer viaf.Close()

	// recvmsg
	buf := make([]byte, syscall.CmsgSpace(num*4))
	_, _, _, _, err = syscall.Recvmsg(socket, nil, buf, 0)
	if err != nil {
		return nil, err
	}

	// parse control msgs
	var msgs []syscall.SocketControlMessage
	msgs, err = syscall.ParseSocketControlMessage(buf)

	// convert fds to files
	res := make([]*os.File, 0, len(msgs))
	for i := 0; i < len(msgs) && err == nil; i++ {
		var fds []int
		fds, err = syscall.ParseUnixRights(&msgs[i])

		for fi, fd := range fds {
			var filename string
			if fi < len(filenames) {
				filename = filenames[fi]
			}

			res = append(res, os.NewFile(uintptr(fd), filename))
		}
	}

	return res, err
}
Beispiel #30
0
func marshalControlMessage(cm *ControlMessage) (oob []byte) {
	if cm == nil {
		return nil
	}
	var l int
	if ctlOpts[ctlPacketInfo].name > 0 {
		if cm.Src.To4() != nil || cm.IfIndex != 0 {
			l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length)
		}
	}
	if l > 0 {
		oob = make([]byte, l)
		b := oob
		if ctlOpts[ctlPacketInfo].name > 0 {
			if cm.Src.To4() != nil || cm.IfIndex != 0 {
				b = ctlOpts[ctlPacketInfo].marshal(b, cm)
			}
		}
	}
	return
}