Skip to content

Commit 129762f

Browse files
committed
rearrange
1 parent ff82816 commit 129762f

File tree

3 files changed

+79
-74
lines changed

3 files changed

+79
-74
lines changed

pvpn/__doc__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
__title__ = "pvpn"
2-
__version__ = "0.1.2"
2+
__version__ = "0.1.3"
33
__license__ = "MIT"
44
__description__ = "VPN server that can tunnel IP network to tcp/udp proxy."
55
__keywords__ = "vpn ike spe ip tcp udp"

pvpn/ip.py

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import struct, ipaddress, os, asyncio, random, heapq, collections, time, enum
2-
from . import enums
2+
from . import enums, dns
33

44
SMSS = 1350
55

@@ -310,3 +310,77 @@ async def connect(self):
310310
self.state = State.FIN_WAIT_1
311311
self.dst_win_buf.extend(bytes([Control.ACK|Control.FIN]))
312312
self.dst_seq += 1
313+
314+
class IPPacket:
315+
def __init__(self, args):
316+
self.tcp_stack = {}
317+
self.dns_cache = None if args.nocache else dns.DNSCache()
318+
self.rserver = args.rserver
319+
self.urserver = args.urserver
320+
def handle(self, remote_id, header, data, reply):
321+
if header == enums.IpProto.IPV4:
322+
proto, src_ip, dst_ip, ip_body = parse_ipv4(data)
323+
dst_name = self.dns_cache.ip2domain(str(dst_ip)) if self.dns_cache else str(dst_ip)
324+
if proto == enums.IpProto.UDP:
325+
src_port, dst_port, udp_body = parse_udp(ip_body)
326+
key = (remote_id, src_port)
327+
if dst_port == 53:
328+
try:
329+
record = dns.DNSRecord.unpack(udp_body)
330+
answer = self.dns_cache.query(record) if self.dns_cache else None
331+
print(f'IPv4 DNS -> {dst_name}:{dst_port} Query={record.q.qname}{" (Cached)" if answer else ""}')
332+
if answer:
333+
ip_body = make_udp(dst_port, src_port, answer.pack())
334+
data = make_ipv4(proto, dst_ip, src_ip, ip_body)
335+
reply(data)
336+
return
337+
except Exception as e:
338+
print(e)
339+
else:
340+
print(f'IPv4 UDP -> {dst_name}:{dst_port} Length={len(udp_body)}')
341+
def udp_reply(udp_body):
342+
#print(f'IPv4 UDP Reply {dst_ip}:{dst_port} -> {src_ip}:{src_port}', result)
343+
if dst_port == 53:
344+
record = dns.DNSRecord.unpack(udp_body)
345+
self.dns_cache.answer(record) if self.dns_cache else None
346+
print(f'IPv4 DNS <- {dst_name}:{dst_port} Answer=['+' '.join(f'{r.rname}->{r.rdata}' for r in record.rr)+']')
347+
else:
348+
print(f'IPv4 UDP <- {dst_name}:{dst_port} Length={len(udp_body)}')
349+
ip_body = make_udp(dst_port, src_port, udp_body)
350+
data = make_ipv4(proto, dst_ip, src_ip, ip_body)
351+
reply(data)
352+
asyncio.ensure_future(self.urserver.udp_sendto(dst_name, dst_port, udp_body, udp_reply, key))
353+
elif proto == enums.IpProto.TCP:
354+
src_port, dst_port, flag, tcp_body = parse_tcp(ip_body)
355+
key = (remote_id, src_port)
356+
tcp = self.tcp_stack.get(key)
357+
if tcp is None:
358+
if flag & 2:
359+
print(f'IPv4 TCP -> {dst_name}:{dst_port} Connect')
360+
for spi, tcp in list(self.tcp_stack.items()):
361+
if tcp.obsolete():
362+
self.tcp_stack.pop(spi)
363+
self.tcp_stack[key] = tcp = TCPStack(src_ip, src_port, dst_ip, dst_name, dst_port, reply, self.rserver)
364+
tcp.parse(ip_body)
365+
elif proto == enums.IpProto.ICMP:
366+
icmptp, code, icmp_body = parse_icmp(ip_body)
367+
if icmptp == 0:
368+
tid, seq = struct.unpack('>HH', ip_body[4:8])
369+
print(f'IPv4 PING -> {dst_name} Id={tid} Seq={seq} Data={icmp_body}')
370+
elif icmptp == 8:
371+
tid, seq = struct.unpack('>HH', ip_body[4:8])
372+
print(f'IPv4 ECHO -> {dst_name} Id={tid} Seq={seq} Data={icmp_body}')
373+
# NEED ROOT PRIVILEGE TO SEND ICMP PACKET
374+
# a = socket.socket(socket.AF_INET, socket.SOCK_RAW, proto)
375+
# a.sendto(icmp_body, (dst_name, 1))
376+
# a.close()
377+
elif icmptp == 3 and code == 3:
378+
eproto, esrc_ip, edst_ip, eip_body = parse_ipv4(icmp_body)
379+
eport = int.from_bytes(eip_body[2:4], 'big')
380+
print(f'IPv4 ICMP -> {dst_name} {eproto.name} :{eport} Denied')
381+
else:
382+
print(f'IPv4 ICMP -> {dst_name} Data={ip_body}')
383+
else:
384+
print(f'IPv4 {enums.IpProto(proto).name} -> {dst_name} Data={data}')
385+
else:
386+
print(f'{enums.IpProto(header).name} Unhandled Protocol. Data={data}')

pvpn/server.py

Lines changed: 3 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import argparse, asyncio, io, os, enum, struct, collections, hashlib, ipaddress, socket, random
22
import pproxy
3-
from . import enums, message, crypto, ip, dns
3+
from . import enums, message, crypto, ip
44
from .__doc__ import *
55

66
class State(enum.Enum):
@@ -383,8 +383,7 @@ def datagram_received(self, data, addr, *, response_header=b''):
383383
class SPE_4500(IKE_500):
384384
def __init__(self, args, sessions):
385385
IKE_500.__init__(self, args, sessions)
386-
self.tcp_stack = {}
387-
self.dnscache = dns.DNSCache()
386+
self.ippacket = ip.IPPacket(args)
388387
def datagram_received(self, data, addr):
389388
spi = data[:4]
390389
if spi == b'\xff':
@@ -420,75 +419,7 @@ def reply(data):
420419
sa.msgid_out += 1
421420
self.transport.sendto(encrypted, addr)
422421
return True
423-
if header == enums.IpProto.IPV4:
424-
proto, src_ip, dst_ip, ip_body = ip.parse_ipv4(data)
425-
dst_name = self.dnscache.ip2domain(str(dst_ip))
426-
if proto == enums.IpProto.UDP:
427-
src_port, dst_port, udp_body = ip.parse_udp(ip_body)
428-
if dst_port == 53:
429-
try:
430-
record = dns.DNSRecord.unpack(udp_body)
431-
answer = self.dnscache.query(record)
432-
print(f'IPv4 DNS -> {dst_name}:{dst_port} Query={record.q.qname}{" (Cached)" if answer else ""}')
433-
if answer:
434-
ip_body = ip.make_udp(dst_port, src_port, answer.pack())
435-
data = ip.make_ipv4(proto, dst_ip, src_ip, ip_body)
436-
reply(data)
437-
return
438-
except Exception as e:
439-
print(e)
440-
else:
441-
print(f'IPv4 UDP -> {dst_name}:{dst_port} Length={len(udp_body)}')
442-
def udp_reply(udp_body):
443-
#print(f'IPv4 UDP Reply {dst_ip}:{dst_port} -> {src_ip}:{src_port}', result)
444-
if dst_port == 53:
445-
record = dns.DNSRecord.unpack(udp_body)
446-
if not self.args.nocache:
447-
self.dnscache.answer(record)
448-
print(f'IPv4 DNS <- {dst_name}:{dst_port} Answer=['+' '.join(f'{r.rname}->{r.rdata}' for r in record.rr)+']')
449-
else:
450-
print(f'IPv4 UDP <- {dst_name}:{dst_port} Length={len(udp_body)}')
451-
ip_body = ip.make_udp(dst_port, src_port, udp_body)
452-
data = ip.make_ipv4(proto, dst_ip, src_ip, ip_body)
453-
reply(data)
454-
asyncio.ensure_future(self.args.urserver.udp_sendto(dst_name, dst_port, udp_body, udp_reply, (str(src_ip), src_port)))
455-
elif proto == enums.IpProto.TCP:
456-
src_port, dst_port, flag, tcp_body = ip.parse_tcp(ip_body)
457-
#else:
458-
# print(f'IPv4 TCP {src_ip}:{src_port} -> {dst_ip}:{dst_port}', ip_body)
459-
key = (addr[0], src_port)
460-
if key not in self.tcp_stack:
461-
if flag & 2:
462-
print(f'IPv4 TCP -> {dst_name}:{dst_port} Connect')
463-
for spi, tcp in list(self.tcp_stack.items()):
464-
if tcp.obsolete():
465-
self.tcp_stack.pop(spi)
466-
self.tcp_stack[key] = tcp = ip.TCPStack(src_ip, src_port, dst_ip, dst_name, dst_port, reply, self.args.rserver)
467-
else:
468-
tcp = self.tcp_stack[key]
469-
tcp.parse(ip_body)
470-
elif proto == enums.IpProto.ICMP:
471-
icmptp, code, icmp_body = ip.parse_icmp(ip_body)
472-
if icmptp == 0:
473-
tid, seq = struct.unpack('>HH', ip_body[4:8])
474-
print(f'IPv4 PING -> {dst_name} Id={tid} Seq={seq} Data={icmp_body}')
475-
elif icmptp == 8:
476-
tid, seq = struct.unpack('>HH', ip_body[4:8])
477-
print(f'IPv4 ECHO -> {dst_name} Id={tid} Seq={seq} Data={icmp_body}')
478-
# NEED ROOT PRIVILEGE TO SEND ICMP PACKET
479-
# a = socket.socket(socket.AF_INET, socket.SOCK_RAW, proto)
480-
# a.sendto(icmp_body, (dst_name, 1))
481-
# a.close()
482-
elif icmptp == 3 and code == 3:
483-
eproto, esrc_ip, edst_ip, eip_body = ip.parse_ipv4(icmp_body)
484-
eport = int.from_bytes(eip_body[2:4], 'big')
485-
print(f'IPv4 ICMP -> {dst_name} {eproto.name} :{eport} Denied')
486-
else:
487-
print(f'IPv4 ICMP -> {dst_name} Data={ip_body}')
488-
else:
489-
print(f'IPv4 {enums.IpProto(proto).name} -> {dst_name} Data={data}')
490-
else:
491-
print(f'{enums.IpProto(header).name} Unhandled Protocol. Data={data}')
422+
self.ippacket.handle(addr[0], header, data, reply)
492423
else:
493424
print('unknown packet', data, addr)
494425

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy