sockopt_bsd.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // Copyright 2012 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. // +build darwin freebsd netbsd openbsd
  5. package ipv4
  6. import (
  7. "net"
  8. "os"
  9. "syscall"
  10. )
  11. func ipv4MulticastTTL(fd int) (int, error) {
  12. v, err := syscall.GetsockoptByte(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL)
  13. if err != nil {
  14. return 0, os.NewSyscallError("getsockopt", err)
  15. }
  16. return int(v), nil
  17. }
  18. func setIPv4MulticastTTL(fd int, v int) error {
  19. err := syscall.SetsockoptByte(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_TTL, byte(v))
  20. if err != nil {
  21. return os.NewSyscallError("setsockopt", err)
  22. }
  23. return nil
  24. }
  25. func ipv4ReceiveDestinationAddress(fd int) (bool, error) {
  26. v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVDSTADDR)
  27. if err != nil {
  28. return false, os.NewSyscallError("getsockopt", err)
  29. }
  30. return v == 1, nil
  31. }
  32. func setIPv4ReceiveDestinationAddress(fd int, v bool) error {
  33. err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVDSTADDR, boolint(v))
  34. if err != nil {
  35. return os.NewSyscallError("setsockopt", err)
  36. }
  37. return nil
  38. }
  39. func ipv4ReceiveInterface(fd int) (bool, error) {
  40. v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVIF)
  41. if err != nil {
  42. return false, os.NewSyscallError("getsockopt", err)
  43. }
  44. return v == 1, nil
  45. }
  46. func setIPv4ReceiveInterface(fd int, v bool) error {
  47. err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_RECVIF, boolint(v))
  48. if err != nil {
  49. return os.NewSyscallError("setsockopt", err)
  50. }
  51. return nil
  52. }
  53. func ipv4MulticastInterface(fd int) (*net.Interface, error) {
  54. a, err := syscall.GetsockoptInet4Addr(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF)
  55. if err != nil {
  56. return nil, os.NewSyscallError("getsockopt", err)
  57. }
  58. return netIP4ToInterface(net.IPv4(a[0], a[1], a[2], a[3]))
  59. }
  60. func setIPv4MulticastInterface(fd int, ifi *net.Interface) error {
  61. ip, err := netInterfaceToIP4(ifi)
  62. if err != nil {
  63. return os.NewSyscallError("setsockopt", err)
  64. }
  65. var a [4]byte
  66. copy(a[:], ip.To4())
  67. err = syscall.SetsockoptInet4Addr(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, a)
  68. if err != nil {
  69. return os.NewSyscallError("setsockopt", err)
  70. }
  71. return nil
  72. }
  73. func ipv4MulticastLoopback(fd int) (bool, error) {
  74. v, err := syscall.GetsockoptByte(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP)
  75. if err != nil {
  76. return false, os.NewSyscallError("getsockopt", err)
  77. }
  78. return v == 1, nil
  79. }
  80. func setIPv4MulticastLoopback(fd int, v bool) error {
  81. err := syscall.SetsockoptByte(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, byte(boolint(v)))
  82. if err != nil {
  83. return os.NewSyscallError("setsockopt", err)
  84. }
  85. return nil
  86. }
  87. func joinIPv4Group(fd int, ifi *net.Interface, grp net.IP) error {
  88. mreq := &syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
  89. if err := setSyscallIPMreq(mreq, ifi); err != nil {
  90. return err
  91. }
  92. err := syscall.SetsockoptIPMreq(fd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq)
  93. if err != nil {
  94. return os.NewSyscallError("setsockopt", err)
  95. }
  96. return nil
  97. }
  98. func leaveIPv4Group(fd int, ifi *net.Interface, grp net.IP) error {
  99. mreq := &syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
  100. if err := setSyscallIPMreq(mreq, ifi); err != nil {
  101. return err
  102. }
  103. err := syscall.SetsockoptIPMreq(fd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreq)
  104. if err != nil {
  105. return os.NewSyscallError("setsockopt", err)
  106. }
  107. return nil
  108. }