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 }
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 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() 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 }
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 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 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 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):] }
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 }
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):] }
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 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 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):] }
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):] }
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):] }
func (cm *ControlMessage) marshalPacketInfo() (oob []byte) { if l := cm.oobLen(); l > 0 { oob = make([]byte, l) m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[0])) m.Level = ianaProtocolIP m.Type = sysSockoptPacketInfo m.SetLen(syscall.CmsgLen(sysSizeofPacketInfo)) pi := (*sysPacketInfo)(unsafe.Pointer(&oob[syscall.CmsgLen(0)])) if ip := cm.Src.To4(); ip != nil { copy(pi.IP[:], ip) } if cm.IfIndex != 0 { pi.IfIndex = int32(cm.IfIndex) } } return }
// 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 }
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 }
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 }
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(FlagDst) { l += syscall.CmsgSpace(net.IPv4len) } if opt.isset(FlagInterface) { l += syscall.CmsgSpace(syscall.SizeofSockaddrDatalink) } 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(FlagDst) { m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off])) m.Level = ianaProtocolIP m.Type = syscall.IP_RECVDSTADDR 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 = syscall.IP_RECVIF m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink)) off += syscall.CmsgSpace(syscall.SizeofSockaddrDatalink) } } return }
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 }
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 }
// TestUnixRightsRoundtrip tests that UnixRights, ParseSocketControlMessage, // and ParseUnixRights are able to successfully round-trip lists of file descriptors. func TestUnixRightsRoundtrip(t *testing.T) { testCases := [...][][]int{ {{42}}, {{1, 2}}, {{3, 4, 5}}, {{}}, {{1, 2}, {3, 4, 5}, {}, {7}}, } for _, testCase := range testCases { b := []byte{} var n int for _, fds := range testCase { // Last assignment to n wins n = len(b) + syscall.CmsgLen(4*len(fds)) b = append(b, syscall.UnixRights(fds...)...) } // Truncate b b = b[:n] scms, err := syscall.ParseSocketControlMessage(b) if err != nil { t.Fatalf("ParseSocketControlMessage: %v", err) } if len(scms) != len(testCase) { t.Fatalf("expected %v SocketControlMessage; got scms = %#v", len(testCase), scms) } for i, scm := range scms { gotFds, err := syscall.ParseUnixRights(&scm) if err != nil { t.Fatalf("ParseUnixRights: %v", err) } wantFds := testCase[i] if len(gotFds) != len(wantFds) { t.Fatalf("expected %v fds, got %#v", len(wantFds), gotFds) } for j, fd := range gotFds { if fd != wantFds[j] { t.Fatalf("expected fd %v, got %v", wantFds[j], fd) } } } } }
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(syscall.SizeofInet6Pktinfo) } 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 = syscall.IPV6_TCLASS 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 = syscall.IPV6_HOPLIMIT 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 = syscall.IPV6_PKTINFO m.SetLen(syscall.CmsgLen(syscall.SizeofInet6Pktinfo)) pi := (*syscall.Inet6Pktinfo)(unsafe.Pointer(&oob[off+syscall.CmsgLen(0)])) if ip := cm.Src.To16(); ip != nil && ip.To4() == nil { copy(pi.Addr[:], ip) } if cm.IfIndex != 0 { pi.Ifindex = uint32(cm.IfIndex) } off += syscall.CmsgSpace(syscall.SizeofInet6Pktinfo) } if len(cm.NextHop) == net.IPv6len { m := (*syscall.Cmsghdr)(unsafe.Pointer(&oob[off])) m.Level = ianaProtocolIPv6 m.Type = syscall.IPV6_NEXTHOP 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) sa.Scope_id = uint32(cm.IfIndex) off += syscall.CmsgSpace(syscall.SizeofSockaddrInet6) } } return }