gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

sockcmsg_linux.go (2658B)


      1 // Copyright 2011 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Socket control messages
      6 
      7 package unix
      8 
      9 import "unsafe"
     10 
     11 // UnixCredentials encodes credentials into a socket control message
     12 // for sending to another process. This can be used for
     13 // authentication.
     14 func UnixCredentials(ucred *Ucred) []byte {
     15 	b := make([]byte, CmsgSpace(SizeofUcred))
     16 	h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
     17 	h.Level = SOL_SOCKET
     18 	h.Type = SCM_CREDENTIALS
     19 	h.SetLen(CmsgLen(SizeofUcred))
     20 	*(*Ucred)(h.data(0)) = *ucred
     21 	return b
     22 }
     23 
     24 // ParseUnixCredentials decodes a socket control message that contains
     25 // credentials in a Ucred structure. To receive such a message, the
     26 // SO_PASSCRED option must be enabled on the socket.
     27 func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
     28 	if m.Header.Level != SOL_SOCKET {
     29 		return nil, EINVAL
     30 	}
     31 	if m.Header.Type != SCM_CREDENTIALS {
     32 		return nil, EINVAL
     33 	}
     34 	ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
     35 	return &ucred, nil
     36 }
     37 
     38 // PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.
     39 func PktInfo4(info *Inet4Pktinfo) []byte {
     40 	b := make([]byte, CmsgSpace(SizeofInet4Pktinfo))
     41 	h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
     42 	h.Level = SOL_IP
     43 	h.Type = IP_PKTINFO
     44 	h.SetLen(CmsgLen(SizeofInet4Pktinfo))
     45 	*(*Inet4Pktinfo)(h.data(0)) = *info
     46 	return b
     47 }
     48 
     49 // PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.
     50 func PktInfo6(info *Inet6Pktinfo) []byte {
     51 	b := make([]byte, CmsgSpace(SizeofInet6Pktinfo))
     52 	h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
     53 	h.Level = SOL_IPV6
     54 	h.Type = IPV6_PKTINFO
     55 	h.SetLen(CmsgLen(SizeofInet6Pktinfo))
     56 	*(*Inet6Pktinfo)(h.data(0)) = *info
     57 	return b
     58 }
     59 
     60 // ParseOrigDstAddr decodes a socket control message containing the original
     61 // destination address. To receive such a message the IP_RECVORIGDSTADDR or
     62 // IPV6_RECVORIGDSTADDR option must be enabled on the socket.
     63 func ParseOrigDstAddr(m *SocketControlMessage) (Sockaddr, error) {
     64 	switch {
     65 	case m.Header.Level == SOL_IP && m.Header.Type == IP_ORIGDSTADDR:
     66 		pp := (*RawSockaddrInet4)(unsafe.Pointer(&m.Data[0]))
     67 		sa := new(SockaddrInet4)
     68 		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
     69 		sa.Port = int(p[0])<<8 + int(p[1])
     70 		sa.Addr = pp.Addr
     71 		return sa, nil
     72 
     73 	case m.Header.Level == SOL_IPV6 && m.Header.Type == IPV6_ORIGDSTADDR:
     74 		pp := (*RawSockaddrInet6)(unsafe.Pointer(&m.Data[0]))
     75 		sa := new(SockaddrInet6)
     76 		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
     77 		sa.Port = int(p[0])<<8 + int(p[1])
     78 		sa.ZoneId = pp.Scope_id
     79 		sa.Addr = pp.Addr
     80 		return sa, nil
     81 
     82 	default:
     83 		return nil, EINVAL
     84 	}
     85 }