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 |
13 func ipv4TOS(f *os.File) (int, error) { | 14 // Please refer to the online manual; |
14 » v, err := syscall.GetsockoptInt(syscall.Handle(f.Fd()), syscall.IPPROTO_
IP, syscall.IP_TOS) | 15 // http://msdn.microsoft.com/en-us/library/windows/desktop/ms738586(v=vs.85).asp
x |
| 16 |
| 17 func ipv4TOS(fd syscall.Handle) (int, error) { |
| 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(f *os.File, v int) error { | 27 func setIPv4TOS(fd syscall.Handle, v int) error { |
22 » err := syscall.SetsockoptInt(syscall.Handle(f.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(f *os.File) (int, error) { | 36 func ipv4TTL(fd syscall.Handle) (int, error) { |
30 » v, err := syscall.GetsockoptInt(syscall.Handle(f.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(f *os.File, v int) error { | 46 func setIPv4TTL(fd syscall.Handle, v int) error { |
38 » err := syscall.SetsockoptInt(syscall.Handle(f.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(f *os.File) (int, error) { | 55 func ipv4MulticastTTL(fd syscall.Handle) (int, error) { |
46 » v, err := syscall.GetsockoptInt(syscall.Handle(f.Fd()), syscall.IPPROTO_
IP, syscall.IP_MULTICAST_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 0, 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(f *os.File, v int) error { | 65 func setIPv4MulticastTTL(fd syscall.Handle, v int) error { |
54 » err := syscall.SetsockoptInt(syscall.Handle(f.Fd()), syscall.IPPROTO_IP,
syscall.IP_MULTICAST_TTL, v) | 66 » vv := int32(v) |
55 » if err != nil { | 67 » err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_MULTICAST_TTL), (*byte)(unsafe.Pointer(&vv)), 4) |
56 » » return os.NewSyscallError("setsockopt", err) | |
57 » } | |
58 » return nil | |
59 | |
60 } | |
61 | |
62 func ipv4ReceiveTTL(f *os.File) (bool, error) { | |
63 » // TODO: Implement this | |
64 » return false, syscall.EWINDOWS | |
65 } | |
66 | |
67 func setIPv4ReceiveTTL(f *os.File, v bool) error { | |
68 » // TODO: Implement this | |
69 » return syscall.EWINDOWS | |
70 } | |
71 | |
72 func ipv4ReceiveDestinationAddress(f *os.File) (bool, error) { | |
73 » // TODO: Implement this | |
74 » return false, syscall.EWINDOWS | |
75 } | |
76 | |
77 func setIPv4ReceiveDestinationAddress(f *os.File, v bool) error { | |
78 » // TODO: Implement this | |
79 » return syscall.EWINDOWS | |
80 } | |
81 | |
82 func ipv4HeaderPrepend(f *os.File) (bool, error) { | |
83 » // TODO: Implement this | |
84 » return false, syscall.EWINDOWS | |
85 } | |
86 | |
87 func setIPv4HeaderPrepend(f *os.File, v bool) error { | |
88 » // TODO: Implement this | |
89 » return syscall.EWINDOWS | |
90 } | |
91 | |
92 func ipv4ReceiveInterface(f *os.File) (bool, error) { | |
93 » // TODO: Implement this | |
94 » return false, syscall.EWINDOWS | |
95 } | |
96 | |
97 func setIPv4ReceiveInterface(f *os.File, v bool) error { | |
98 » // TODO: Implement this | |
99 » return syscall.EWINDOWS | |
100 } | |
101 | |
102 func ipv4MulticastInterface(f *os.File) (*net.Interface, error) { | |
103 » // TODO: Implement this | |
104 » return nil, syscall.EWINDOWS | |
105 } | |
106 | |
107 func setIPv4MulticastInterface(f *os.File, ifi *net.Interface) error { | |
108 » ip, err := netInterfaceToIP4(ifi) | |
109 » if err != nil { | |
110 » » return os.NewSyscallError("setsockopt", err) | |
111 » } | |
112 » var x [4]byte | |
113 » copy(x[:], ip.To4()) | |
114 » err = syscall.SetsockoptInet4Addr(syscall.Handle(f.Fd()), syscall.IPPROT
O_IP, syscall.IP_MULTICAST_IF, x) | |
115 if err != nil { | 68 if err != nil { |
116 return os.NewSyscallError("setsockopt", err) | 69 return os.NewSyscallError("setsockopt", err) |
117 } | 70 } |
118 return nil | 71 return nil |
119 } | 72 } |
120 | 73 |
121 func ipv4MulticastLoopback(f *os.File) (bool, error) { | 74 func ipv4ReceiveTTL(fd syscall.Handle) (bool, error) { |
122 » v, err := syscall.GetsockoptInt(syscall.Handle(f.Fd()), syscall.IPPROTO_
IP, syscall.IP_MULTICAST_LOOP) | 75 » // NOTE: Not supported yet on any Windows |
| 76 » return false, syscall.EWINDOWS |
| 77 } |
| 78 |
| 79 func setIPv4ReceiveTTL(fd syscall.Handle, v bool) error { |
| 80 » // NOTE: Not supported yet on any Windows |
| 81 » return syscall.EWINDOWS |
| 82 } |
| 83 |
| 84 func ipv4ReceiveDestinationAddress(fd syscall.Handle) (bool, error) { |
| 85 » // TODO(mikio): Implement this for XP and beyond |
| 86 » return false, syscall.EWINDOWS |
| 87 } |
| 88 |
| 89 func setIPv4ReceiveDestinationAddress(fd syscall.Handle, v bool) error { |
| 90 » // TODO(mikio): Implement this for XP and beyond |
| 91 » return syscall.EWINDOWS |
| 92 } |
| 93 |
| 94 func ipv4HeaderPrepend(fd syscall.Handle) (bool, error) { |
| 95 » // TODO(mikio): Implement this for XP and beyond |
| 96 » return false, syscall.EWINDOWS |
| 97 } |
| 98 |
| 99 func setIPv4HeaderPrepend(fd syscall.Handle, v bool) error { |
| 100 » // TODO(mikio): Implement this for XP and beyond |
| 101 » return syscall.EWINDOWS |
| 102 } |
| 103 |
| 104 func ipv4ReceiveInterface(fd syscall.Handle) (bool, error) { |
| 105 » // TODO(mikio): Implement this for Vista and beyond |
| 106 » return false, syscall.EWINDOWS |
| 107 } |
| 108 |
| 109 func setIPv4ReceiveInterface(fd syscall.Handle, v bool) error { |
| 110 » // TODO(mikio): Implement this for Vista and beyond |
| 111 » return syscall.EWINDOWS |
| 112 } |
| 113 |
| 114 func ipv4MulticastInterface(fd syscall.Handle) (*net.Interface, error) { |
| 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) |
| 118 » if err != nil { |
| 119 » » return nil, os.NewSyscallError("getsockopt", err) |
| 120 » } |
| 121 » return netIP4ToInterface(net.IPv4(a[0], a[1], a[2], a[3])) |
| 122 } |
| 123 |
| 124 func setIPv4MulticastInterface(fd syscall.Handle, ifi *net.Interface) error { |
| 125 » ip, err := netInterfaceToIP4(ifi) |
| 126 » if err != nil { |
| 127 » » return os.NewSyscallError("setsockopt", err) |
| 128 » } |
| 129 » var a [4]byte |
| 130 » copy(a[:], ip.To4()) |
| 131 » err = syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.IP
_MULTICAST_IF), (*byte)(unsafe.Pointer(&a[0])), 4) |
| 132 » if err != nil { |
| 133 » » return os.NewSyscallError("setsockopt", err) |
| 134 » } |
| 135 » return nil |
| 136 } |
| 137 |
| 138 func ipv4MulticastLoopback(fd syscall.Handle) (bool, error) { |
| 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) |
123 if err != nil { | 142 if err != nil { |
124 return false, os.NewSyscallError("getsockopt", err) | 143 return false, os.NewSyscallError("getsockopt", err) |
125 } | 144 } |
126 return v == 1, nil | 145 return v == 1, nil |
127 } | 146 } |
128 | 147 |
129 func setIPv4MulticastLoopback(f *os.File, v bool) error { | 148 func setIPv4MulticastLoopback(fd syscall.Handle, v bool) error { |
130 » err := syscall.SetsockoptInt(syscall.Handle(f.Fd()), syscall.IPPROTO_IP,
syscall.IP_MULTICAST_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) |
131 if err != nil { | 151 if err != nil { |
132 return os.NewSyscallError("setsockopt", err) | 152 return os.NewSyscallError("setsockopt", err) |
133 } | 153 } |
134 return nil | 154 return nil |
135 } | 155 } |
136 | 156 |
137 func joinIPv4Group(f *os.File, ifi *net.Interface, grp net.IP) error { | 157 func joinIPv4Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error { |
138 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
]}} |
139 if err := setSyscallIPMreq(mreq, ifi); err != nil { | 159 if err := setSyscallIPMreq(mreq, ifi); err != nil { |
140 return err | 160 return err |
141 } | 161 } |
142 » err := syscall.SetsockoptIPMreq(syscall.Handle(f.Fd()), syscall.IPPROTO_
IP, syscall.IP_ADD_MEMBERSHIP, mreq) | 162 » err := syscall.Setsockopt(fd, int32(syscall.IPPROTO_IP), int32(syscall.I
P_ADD_MEMBERSHIP), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq))) |
143 if err != nil { | 163 if err != nil { |
144 return os.NewSyscallError("setsockopt", err) | 164 return os.NewSyscallError("setsockopt", err) |
145 } | 165 } |
146 return nil | 166 return nil |
147 } | 167 } |
148 | 168 |
149 func leaveIPv4Group(f *os.File, ifi *net.Interface, grp net.IP) error { | 169 func leaveIPv4Group(fd syscall.Handle, ifi *net.Interface, grp net.IP) error { |
150 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
]}} |
151 if err := setSyscallIPMreq(mreq, ifi); err != nil { | 171 if err := setSyscallIPMreq(mreq, ifi); err != nil { |
152 return err | 172 return err |
153 } | 173 } |
154 » err := syscall.SetsockoptIPMreq(syscall.Handle(f.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))) |
155 if err != nil { | 175 if err != nil { |
156 return os.NewSyscallError("setsockopt", err) | 176 return os.NewSyscallError("setsockopt", err) |
157 } | 177 } |
158 return nil | 178 return nil |
159 } | 179 } |
LEFT | RIGHT |