sockcmsg_linux.go 2.6 KB

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