|
12 | 12 | import sys |
13 | 13 | from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper |
14 | 14 | from helpers import log, debug1, debug2, debug3, Fatal, islocal |
15 | | -from fcntl import ioctl |
16 | | -from ctypes import c_char, c_uint8, c_uint16, c_uint32, Union, Structure, sizeof, addressof, memmove |
17 | 15 |
|
18 | 16 | recvmsg = None |
19 | 17 | try: |
@@ -186,79 +184,22 @@ def daemon_cleanup(): |
186 | 184 | else: |
187 | 185 | raise |
188 | 186 |
|
189 | | - |
190 | | -class pf_state_xport(Union): |
191 | | - _fields_ = [("port", c_uint16), |
192 | | - ("call_id", c_uint16), |
193 | | - ("spi", c_uint32)] |
194 | | - |
195 | | -class pf_addr(Structure): |
196 | | - class _pfa(Union): |
197 | | - _fields_ = [("v4", c_uint32), # struct in_addr |
198 | | - ("v6", c_uint32 * 4), # struct in6_addr |
199 | | - ("addr8", c_uint8 * 16), |
200 | | - ("addr16", c_uint16 * 8), |
201 | | - ("addr32", c_uint32 * 4)] |
202 | | - |
203 | | - _fields_ = [("pfa", _pfa)] |
204 | | - _anonymous_ = ("pfa",) |
205 | | - |
206 | | -class pfioc_natlook(Structure): |
207 | | - _fields_ = [("saddr", pf_addr), |
208 | | - ("daddr", pf_addr), |
209 | | - ("rsaddr", pf_addr), |
210 | | - ("rdaddr", pf_addr), |
211 | | - ("sxport", pf_state_xport), |
212 | | - ("dxport", pf_state_xport), |
213 | | - ("rsxport", pf_state_xport), |
214 | | - ("rdxport", pf_state_xport), |
215 | | - ("af", c_uint8), # sa_family_t |
216 | | - ("proto", c_uint8), |
217 | | - ("proto_variant", c_uint8), |
218 | | - ("direction", c_uint8)] |
219 | | - |
220 | | -DIOCNATLOOK = ((0x40000000L | 0x80000000L) | ((sizeof(pfioc_natlook) & 0x1fff) << 16) | ((ord('D')) << 8) | (23)) |
221 | | -PF_OUT = 2 |
222 | | - |
223 | | -_pf_fd = None |
| 187 | +pf_command_file = None |
224 | 188 |
|
225 | 189 | def pf_dst(sock): |
226 | | - global _pf_fd |
227 | | - try: |
228 | | - peer = sock.getpeername() |
229 | | - proxy = sock.getsockname() |
230 | | - |
231 | | - pnl = pfioc_natlook() |
232 | | - pnl.proto = socket.IPPROTO_TCP |
233 | | - pnl.direction = PF_OUT |
234 | | - if sock.family == socket.AF_INET: |
235 | | - pnl.af = socket.AF_INET |
236 | | - memmove(addressof(pnl.saddr), socket.inet_pton(socket.AF_INET, peer[0]), 4) |
237 | | - pnl.sxport.port = socket.htons(peer[1]) |
238 | | - memmove(addressof(pnl.daddr), socket.inet_pton(socket.AF_INET, proxy[0]), 4) |
239 | | - pnl.dxport.port = socket.htons(proxy[1]) |
240 | | - elif sock.family == socket.AF_INET6: |
241 | | - pnl.af = socket.AF_INET6 |
242 | | - memmove(addressof(pnl.saddr), socket.inet_pton(socket.AF_INET6, peer[0]), 16) |
243 | | - pnl.sxport.port = socket.htons(peer[1]) |
244 | | - memmove(addressof(pnl.daddr), socket.inet_pton(socket.AF_INET6, proxy[0]), 16) |
245 | | - pnl.dxport.port = socket.htons(proxy[1]) |
246 | | - |
247 | | - if _pf_fd == None: |
248 | | - _pf_fd = open('/dev/pf', 'r') |
249 | | - |
250 | | - ioctl(_pf_fd, DIOCNATLOOK, (c_char * sizeof(pnl)).from_address(addressof(pnl))) |
251 | | - |
252 | | - if pnl.af == socket.AF_INET: |
253 | | - ip = socket.inet_ntop(socket.AF_INET, (c_char * 4).from_address(addressof(pnl.rdaddr))) |
254 | | - elif pnl.af == socket.AF_INET6: |
255 | | - ip = socket.inet_ntop(socket.AF_INET6, (c_char * 16).from_address(addressof(pnl.rdaddr))) |
256 | | - port = socket.ntohs(pnl.rdxport.port) |
257 | | - return (ip, port) |
258 | | - except IOError, e: |
259 | | - return sock.getsockname() |
260 | | - raise |
| 190 | + peer = sock.getpeername() |
| 191 | + proxy = sock.getsockname() |
| 192 | + |
| 193 | + argv = (sock.family, socket.IPPROTO_TCP, peer[0], peer[1], proxy[0], proxy[1]) |
| 194 | + pf_command_file.write("QUERY_PF_NAT %r,%r,%s,%r,%s,%r\n" % argv) |
| 195 | + pf_command_file.flush() |
| 196 | + line = pf_command_file.readline() |
| 197 | + debug2("QUERY_PF_NAT %r,%r,%s,%r,%s,%r" % argv + ' > ' + line) |
| 198 | + if line.startswith('QUERY_PF_NAT_SUCCESS '): |
| 199 | + (ip, port) = line[21:].split(',') |
| 200 | + return (ip, int(port)) |
261 | 201 |
|
| 202 | + return sock.getsockname() |
262 | 203 |
|
263 | 204 | def original_dst(sock): |
264 | 205 | try: |
@@ -815,6 +756,10 @@ def main(listenip_v6, listenip_v4, |
815 | 756 | if dns_listener.v6 is not None: |
816 | 757 | dns_listener.v6.setsockopt(SOL_IPV6, IPV6_RECVORIGDSTADDR, 1) |
817 | 758 |
|
| 759 | + if fw.method == "pf": |
| 760 | + global pf_command_file |
| 761 | + pf_command_file = fw.pfile |
| 762 | + |
818 | 763 | try: |
819 | 764 | return _main(tcp_listener, udp_listener, fw, ssh_cmd, remotename, |
820 | 765 | python, latency_control, dns_listener, |
|
0 commit comments