sockopt_windows.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. package ipv4
  5. import (
  6. "net"
  7. "os"
  8. "syscall"
  9. "unsafe"
  10. )
  11. // Please refer to the online manual;
  12. // http://msdn.microsoft.com/en-us/library/windows/desktop/ms738586(v=vs.85).aspx
  13. func ipv4TOS(fd syscall.Handle) (int, error) {
  14. var v int32
  15. l := int32(4)
  16. if err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_TOS, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
  17. return 0, os.NewSyscallError("getsockopt", err)
  18. }
  19. return int(v), nil
  20. }
  21. func setIPv4TOS(fd syscall.Handle, v int) error {
  22. vv := int32(v)
  23. return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_TOS, (*byte)(unsafe.Pointer(&vv)), 4))
  24. }
  25. func ipv4TTL(fd syscall.Handle) (int, error) {
  26. var v int32
  27. l := int32(4)
  28. if err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_TTL, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
  29. return 0, os.NewSyscallError("getsockopt", err)
  30. }
  31. return int(v), nil
  32. }
  33. func setIPv4TTL(fd syscall.Handle, v int) error {
  34. vv := int32(v)
  35. return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_TTL, (*byte)(unsafe.Pointer(&vv)), 4))
  36. }
  37. func ipv4MulticastTTL(fd syscall.Handle) (int, error) {
  38. var v int32
  39. l := int32(4)
  40. if err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_TTL, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
  41. return 0, os.NewSyscallError("getsockopt", err)
  42. }
  43. return int(v), nil
  44. }
  45. func setIPv4MulticastTTL(fd syscall.Handle, v int) error {
  46. vv := int32(v)
  47. return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_TTL, (*byte)(unsafe.Pointer(&vv)), 4))
  48. }
  49. func ipv4ReceiveTTL(fd syscall.Handle) (bool, error) {
  50. // NOTE: Not supported yet on any Windows
  51. return false, syscall.EWINDOWS
  52. }
  53. func setIPv4ReceiveTTL(fd syscall.Handle, v bool) error {
  54. // NOTE: Not supported yet on any Windows
  55. return syscall.EWINDOWS
  56. }
  57. func ipv4ReceiveDestinationAddress(fd syscall.Handle) (bool, error) {
  58. // TODO(mikio): Implement this for XP and beyond
  59. return false, syscall.EWINDOWS
  60. }
  61. func setIPv4ReceiveDestinationAddress(fd syscall.Handle, v bool) error {
  62. // TODO(mikio): Implement this for XP and beyond
  63. return syscall.EWINDOWS
  64. }
  65. func ipv4HeaderPrepend(fd syscall.Handle) (bool, error) {
  66. // TODO(mikio): Implement this for XP and beyond
  67. return false, syscall.EWINDOWS
  68. }
  69. func setIPv4HeaderPrepend(fd syscall.Handle, v bool) error {
  70. // TODO(mikio): Implement this for XP and beyond
  71. return syscall.EWINDOWS
  72. }
  73. func ipv4ReceiveInterface(fd syscall.Handle) (bool, error) {
  74. // TODO(mikio): Implement this for Vista and beyond
  75. return false, syscall.EWINDOWS
  76. }
  77. func setIPv4ReceiveInterface(fd syscall.Handle, v bool) error {
  78. // TODO(mikio): Implement this for Vista and beyond
  79. return syscall.EWINDOWS
  80. }
  81. func ipv4MulticastInterface(fd syscall.Handle) (*net.Interface, error) {
  82. var v [4]byte
  83. l := int32(4)
  84. if err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_IF, (*byte)(unsafe.Pointer(&v[0])), &l); err != nil {
  85. return nil, os.NewSyscallError("getsockopt", err)
  86. }
  87. return netIP4ToInterface(net.IPv4(v[0], v[1], v[2], v[3]))
  88. }
  89. func setIPv4MulticastInterface(fd syscall.Handle, ifi *net.Interface) error {
  90. ip, err := netInterfaceToIP4(ifi)
  91. if err != nil {
  92. return os.NewSyscallError("setsockopt", err)
  93. }
  94. var v [4]byte
  95. copy(v[:], ip.To4())
  96. return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_IF, (*byte)(unsafe.Pointer(&v[0])), 4))
  97. }
  98. func ipv4MulticastLoopback(fd syscall.Handle) (bool, error) {
  99. var v int32
  100. l := int32(4)
  101. if err := syscall.Getsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_LOOP, (*byte)(unsafe.Pointer(&v)), &l); err != nil {
  102. return false, os.NewSyscallError("getsockopt", err)
  103. }
  104. return v == 1, nil
  105. }
  106. func setIPv4MulticastLoopback(fd syscall.Handle, v bool) error {
  107. vv := int32(boolint(v))
  108. return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_MULTICAST_LOOP, (*byte)(unsafe.Pointer(&vv)), 4))
  109. }
  110. func joinIPv4Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error {
  111. mreq := syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
  112. if err := setSyscallIPMreq(&mreq, ifi); err != nil {
  113. return err
  114. }
  115. return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_ADD_MEMBERSHIP, (*byte)(unsafe.Pointer(&mreq)), int32(unsafe.Sizeof(mreq))))
  116. }
  117. func leaveIPv4Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error {
  118. mreq := syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}}
  119. if err := setSyscallIPMreq(&mreq, ifi); err != nil {
  120. return err
  121. }
  122. return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, ianaProtocolIP, syscall.IP_DROP_MEMBERSHIP, (*byte)(unsafe.Pointer(&mreq)), int32(unsafe.Sizeof(mreq))))
  123. }