|
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