forked from shell909090/utils
-
Notifications
You must be signed in to change notification settings - Fork 1
/
detectp2p.py
114 lines (98 loc) · 3.35 KB
/
detectp2p.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/python
# -*- coding: utf-8 -*-
'''
@date: 2012-09-18
@author: shell.xu
'''
import os, sys, time, socket, getopt, logging
from os import path
import dpkt, pcap
def get_netaddr(ip, mask):
return ''.join(map(lambda x, y: chr(ord(x) & ord(y)), ip, mask))
def ipfilter(ip):
src = get_netaddr(ip.src, optdict['-m']) == optdict['netaddr']
dst = get_netaddr(ip.dst, optdict['-m']) == optdict['netaddr']
if src and dst: return None
elif src: return ip.src
elif dst: return ip.dst
else: return None
class IpStatus(object):
def __init__(self, ipaddr):
self.ipaddr = ipaddr
self.tcps, self.udps = {}, {}
def add(self, eth):
ip = eth.data
if hasattr(ip, 'tcp'):
self.addsome(eth, ip, self.tcps)
else: self.addsome(eth, ip, self.udps)
def addsome(self, eth, ip, d):
p = ip.data
if ip.src == self.ipaddr:
dst = (ip.dst, p.dport)
else: dst = (ip.src, p.sport)
d.setdefault(dst, [0, 0])
if ip.src == self.ipaddr:
d[dst][0] += len(eth)
else: d[dst][1] += len(eth)
def detect(self, s):
print >>s, 'ipaddr: %s' % socket.inet_ntoa(self.ipaddr)
self.detectsome(s, self.tcps, 'tcp')
self.detectsome(s, self.udps, 'udp')
def detectsome(self, s, p, type):
for k, v in p.iteritems():
if k[1] < optdict['-s']: continue
print >>s, '\t%s:%d (%s) : sent %d, recved %d' % (
socket.inet_ntoa(k[0]), k[1], type, v[0], v[1])
def analyze(s):
ips = {}
pc = pcap.pcap(optdict['-i'])
proto = 'tcp'
if '-u' in optdict: proto += ' or udp'
pc.setfilter(proto)
t = time.time()
try:
for ts, pkt in pc:
eth = dpkt.ethernet.Ethernet(pkt)
if hasattr(eth, 'ip6'): continue
ip = eth.data
logging.info('%s:%d -> %s:%d' % (
socket.inet_ntoa(ip.src), ip.data.dport,
socket.inet_ntoa(ip.dst), ip.data.sport))
inaddr = ipfilter(ip)
if inaddr is None: continue
ips.setdefault(inaddr, IpStatus(inaddr))
ips[inaddr].add(eth)
if optdict['-k'] and time.time() - t > optdict['-k']: break
except KeyboardInterrupt: pass
for v in ips.values(): v.detect(s)
s.flush()
def main():
'''
-h: help
-i: iface, eth0 as default
-k: keep time and quit, 30 as default, use 0 for forever run
-n: network, 192.168.0.0 as default
-m: netmask, 255.255.0.0 as default
-s: system port range, 1024 as default
-u: with udp
'''
global optdict
optlist, args = getopt.getopt(sys.argv[1:], 'hi:k:n:m:s:u')
optdict = dict(optlist)
if '-h' in optdict:
exe = path.basename(sys.argv[0])
print '%s [-h] [-k keep time] [-i iface] [-u]' % exe
print main.__doc__
return
optdict.setdefault('-i', 'eth0')
optdict.setdefault('-k', '30')
optdict.setdefault('-n', '192.168.0.0')
optdict.setdefault('-m', '255.255.0.0')
optdict.setdefault('-s', '1024')
optdict['-k'] = int(optdict['-k'])
optdict['-n'] = socket.inet_aton(optdict['-n'])
optdict['-m'] = socket.inet_aton(optdict['-m'])
optdict['netaddr'] = get_netaddr(optdict['-n'], optdict['-m'])
optdict['-s'] = int(optdict['-s'])
analyze(sys.stdout)
if __name__ == '__main__': main()