LEFT | RIGHT |
1 // Copyright 2012 The Go Authors. All rights reserved. | 1 // Copyright 2012 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package ipv4 | 5 package ipv4 |
6 | 6 |
7 import ( | 7 import ( |
8 "net" | 8 "net" |
9 "os" | 9 "os" |
10 "syscall" | 10 "syscall" |
| 11 "unsafe" |
11 ) | 12 ) |
12 | 13 |
| 14 // Please refer to the online manual; |
| 15 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms738586(v=vs.85).asp
x |
| 16 |
13 func ipv4TOS(fd syscall.Handle) (int, error) { | 17 func ipv4TOS(fd syscall.Handle) (int, error) { |
14 » v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_TOS) | 18 » var v int32 |
| 19 » l := int32(4) |
| 20 » err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_TOS), (*byte)(unsafe.Pointer(&v)), &l) |
15 if err != nil { | 21 if err != nil { |
16 return 0, os.NewSyscallError("getsockopt", err) | 22 return 0, os.NewSyscallError("getsockopt", err) |
17 } | 23 } |
18 » return v, nil | 24 » return int(v), nil |
19 } | 25 } |
20 | 26 |
21 func setIPv4TOS(fd syscall.Handle, v int) error { | 27 func setIPv4TOS(fd syscall.Handle, v int) error { |
22 » err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_TOS, v) | 28 » vv := int32(v) |
| 29 » err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_TOS), (*byte)(unsafe.Pointer(&vv)), 4) |
23 if err != nil { | 30 if err != nil { |
24 return os.NewSyscallError("setsockopt", err) | 31 return os.NewSyscallError("setsockopt", err) |
25 } | 32 } |
26 return nil | 33 return nil |
27 } | 34 } |
28 | 35 |
29 func ipv4TTL(fd syscall.Handle) (int, error) { | 36 func ipv4TTL(fd syscall.Handle) (int, error) { |
30 » v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_TTL) | 37 » var v int32 |
| 38 » l := int32(4) |
| 39 » err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_TTL), (*byte)(unsafe.Pointer(&v)), &l) |
31 if err != nil { | 40 if err != nil { |
32 return 0, os.NewSyscallError("getsockopt", err) | 41 return 0, os.NewSyscallError("getsockopt", err) |
33 } | 42 } |
34 » return v, nil | 43 » return int(v), nil |
35 } | 44 } |
36 | 45 |
37 func setIPv4TTL(fd syscall.Handle, v int) error { | 46 func setIPv4TTL(fd syscall.Handle, v int) error { |
38 » err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_TTL, v) | 47 » vv := int32(v) |
| 48 » err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_TTL), (*byte)(unsafe.Pointer(&vv)), 4) |
39 if err != nil { | 49 if err != nil { |
40 return os.NewSyscallError("setsockopt", err) | 50 return os.NewSyscallError("setsockopt", err) |
41 } | 51 } |
42 return nil | 52 return nil |
43 } | 53 } |
44 | 54 |
45 func ipv4MulticastTTL(fd syscall.Handle) (int, error) { | 55 func ipv4MulticastTTL(fd syscall.Handle) (int, error) { |
46 » v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MULTI
CAST_TTL) | 56 » var v int32 |
| 57 » l := int32(4) |
| 58 » err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_MULTICAST_TTL), (*byte)(unsafe.Pointer(&v)), &l) |
47 if err != nil { | 59 if err != nil { |
48 » » return -1, os.NewSyscallError("getsockopt", err) | 60 » » return 0, os.NewSyscallError("getsockopt", err) |
49 } | 61 } |
50 » return v, nil | 62 » return int(v), nil |
51 } | 63 } |
52 | 64 |
53 func setIPv4MulticastTTL(fd syscall.Handle, v int) error { | 65 func setIPv4MulticastTTL(fd syscall.Handle, v int) error { |
54 » err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAS
T_TTL, v) | 66 » vv := int32(v) |
| 67 » err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_MULTICAST_TTL), (*byte)(unsafe.Pointer(&vv)), 4) |
55 if err != nil { | 68 if err != nil { |
56 return os.NewSyscallError("setsockopt", err) | 69 return os.NewSyscallError("setsockopt", err) |
57 } | 70 } |
58 return nil | 71 return nil |
59 | |
60 } | 72 } |
61 | 73 |
62 func ipv4ReceiveTTL(fd syscall.Handle) (bool, error) { | 74 func ipv4ReceiveTTL(fd syscall.Handle) (bool, error) { |
63 » // TODO(mikio): Implement this for Vista and beyond | 75 » // NOTE: Not supported yet on any Windows |
64 return false, syscall.EWINDOWS | 76 return false, syscall.EWINDOWS |
65 } | 77 } |
66 | 78 |
67 func setIPv4ReceiveTTL(fd syscall.Handle, v bool) error { | 79 func setIPv4ReceiveTTL(fd syscall.Handle, v bool) error { |
68 » // TODO(mikio): Implement this for Vista and beyond | 80 » // NOTE: Not supported yet on any Windows |
69 return syscall.EWINDOWS | 81 return syscall.EWINDOWS |
70 } | 82 } |
71 | 83 |
72 func ipv4ReceiveDestinationAddress(fd syscall.Handle) (bool, error) { | 84 func ipv4ReceiveDestinationAddress(fd syscall.Handle) (bool, error) { |
73 » // TODO(mikio): Implement this for Vista and beyond | 85 » // TODO(mikio): Implement this for XP and beyond |
74 return false, syscall.EWINDOWS | 86 return false, syscall.EWINDOWS |
75 } | 87 } |
76 | 88 |
77 func setIPv4ReceiveDestinationAddress(fd syscall.Handle, v bool) error { | 89 func setIPv4ReceiveDestinationAddress(fd syscall.Handle, v bool) error { |
78 » // TODO(mikio): Implement this for Vista and beyond | 90 » // TODO(mikio): Implement this for XP and beyond |
79 return syscall.EWINDOWS | 91 return syscall.EWINDOWS |
80 } | 92 } |
81 | 93 |
82 func ipv4HeaderPrepend(fd syscall.Handle) (bool, error) { | 94 func ipv4HeaderPrepend(fd syscall.Handle) (bool, error) { |
83 » // TODO(mikio): Implement this for Vista and beyond | 95 » // TODO(mikio): Implement this for XP and beyond |
84 return false, syscall.EWINDOWS | 96 return false, syscall.EWINDOWS |
85 } | 97 } |
86 | 98 |
87 func setIPv4HeaderPrepend(fd syscall.Handle, v bool) error { | 99 func setIPv4HeaderPrepend(fd syscall.Handle, v bool) error { |
88 » // TODO(mikio): Implement this for Vista and beyond | 100 » // TODO(mikio): Implement this for XP and beyond |
89 return syscall.EWINDOWS | 101 return syscall.EWINDOWS |
90 } | 102 } |
91 | 103 |
92 func ipv4ReceiveInterface(fd syscall.Handle) (bool, error) { | 104 func ipv4ReceiveInterface(fd syscall.Handle) (bool, error) { |
93 // TODO(mikio): Implement this for Vista and beyond | 105 // TODO(mikio): Implement this for Vista and beyond |
94 return false, syscall.EWINDOWS | 106 return false, syscall.EWINDOWS |
95 } | 107 } |
96 | 108 |
97 func setIPv4ReceiveInterface(fd syscall.Handle, v bool) error { | 109 func setIPv4ReceiveInterface(fd syscall.Handle, v bool) error { |
98 // TODO(mikio): Implement this for Vista and beyond | 110 // TODO(mikio): Implement this for Vista and beyond |
99 return syscall.EWINDOWS | 111 return syscall.EWINDOWS |
100 } | 112 } |
101 | 113 |
102 func ipv4MulticastInterface(fd syscall.Handle) (*net.Interface, error) { | 114 func ipv4MulticastInterface(fd syscall.Handle) (*net.Interface, error) { |
103 » a, err := syscall.GetsockoptInet4Addr(fd, syscall.IPPROTO_IP, syscall.IP
_MULTICAST_IF) | 115 » var a [4]byte |
| 116 » l := int32(4) |
| 117 » err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_MULTICAST_IF), (*byte)(unsafe.Pointer(&a[0])), &l) |
104 if err != nil { | 118 if err != nil { |
105 return nil, os.NewSyscallError("getsockopt", err) | 119 return nil, os.NewSyscallError("getsockopt", err) |
106 } | 120 } |
107 return netIP4ToInterface(net.IPv4(a[0], a[1], a[2], a[3])) | 121 return netIP4ToInterface(net.IPv4(a[0], a[1], a[2], a[3])) |
108 } | 122 } |
109 | 123 |
110 func setIPv4MulticastInterface(fd syscall.Handle, ifi *net.Interface) error { | 124 func setIPv4MulticastInterface(fd syscall.Handle, ifi *net.Interface) error { |
111 ip, err := netInterfaceToIP4(ifi) | 125 ip, err := netInterfaceToIP4(ifi) |
112 if err != nil { | 126 if err != nil { |
113 return os.NewSyscallError("setsockopt", err) | 127 return os.NewSyscallError("setsockopt", err) |
114 } | 128 } |
115 var a [4]byte | 129 var a [4]byte |
116 copy(a[:], ip.To4()) | 130 copy(a[:], ip.To4()) |
117 » err = syscall.SetsockoptInet4Addr(fd, syscall.IPPROTO_IP, syscall.IP_MUL
TICAST_IF, a) | 131 » err = syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP
_MULTICAST_IF), (*byte)(unsafe.Pointer(&a[0])), 4) |
118 if err != nil { | 132 if err != nil { |
119 return os.NewSyscallError("setsockopt", err) | 133 return os.NewSyscallError("setsockopt", err) |
120 } | 134 } |
121 return nil | 135 return nil |
122 } | 136 } |
123 | 137 |
124 func ipv4MulticastLoopback(fd syscall.Handle) (bool, error) { | 138 func ipv4MulticastLoopback(fd syscall.Handle) (bool, error) { |
125 » v, err := syscall.GetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MULTI
CAST_LOOP) | 139 » var v int32 |
| 140 » l := int32(4) |
| 141 » err := syscall.Getsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_MULTICAST_LOOP), (*byte)(unsafe.Pointer(&v)), &l) |
126 if err != nil { | 142 if err != nil { |
127 return false, os.NewSyscallError("getsockopt", err) | 143 return false, os.NewSyscallError("getsockopt", err) |
128 } | 144 } |
129 return v == 1, nil | 145 return v == 1, nil |
130 } | 146 } |
131 | 147 |
132 func setIPv4MulticastLoopback(fd syscall.Handle, v bool) error { | 148 func setIPv4MulticastLoopback(fd syscall.Handle, v bool) error { |
133 » err := syscall.SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAS
T_LOOP, boolint(v)) | 149 » vv := int32(boolint(v)) |
| 150 » err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_MULTICAST_LOOP), (*byte)(unsafe.Pointer(&vv)), 4) |
134 if err != nil { | 151 if err != nil { |
135 return os.NewSyscallError("setsockopt", err) | 152 return os.NewSyscallError("setsockopt", err) |
136 } | 153 } |
137 return nil | 154 return nil |
138 } | 155 } |
139 | 156 |
140 func joinIPv4Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error { | 157 func joinIPv4Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error { |
141 mreq := &syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3
]}} | 158 mreq := &syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3
]}} |
142 if err := setSyscallIPMreq(mreq, ifi); err != nil { | 159 if err := setSyscallIPMreq(mreq, ifi); err != nil { |
143 return err | 160 return err |
144 } | 161 } |
145 » err := syscall.SetsockoptIPMreq(fd, syscall.IPPROTO_IP, syscall.IP_ADD_M
EMBERSHIP, mreq) | 162 » err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_ADD_MEMBERSHIP), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) |
146 if err != nil { | 163 if err != nil { |
147 return os.NewSyscallError("setsockopt", err) | 164 return os.NewSyscallError("setsockopt", err) |
148 } | 165 } |
149 return nil | 166 return nil |
150 } | 167 } |
151 | 168 |
152 func leaveIPv4Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error { | 169 func leaveIPv4Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error { |
153 mreq := &syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3
]}} | 170 mreq := &syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3
]}} |
154 if err := setSyscallIPMreq(mreq, ifi); err != nil { | 171 if err := setSyscallIPMreq(mreq, ifi); err != nil { |
155 return err | 172 return err |
156 } | 173 } |
157 » err := syscall.SetsockoptIPMreq(fd, syscall.IPPROTO_IP, syscall.IP_DROP_
MEMBERSHIP, mreq) | 174 » err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_DROP_MEMBERSHIP), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) |
158 if err != nil { | 175 if err != nil { |
159 return os.NewSyscallError("setsockopt", err) | 176 return os.NewSyscallError("setsockopt", err) |
160 } | 177 } |
161 return nil | 178 return nil |
162 } | 179 } |
LEFT | RIGHT |