forked from nimai/mptcp-scapy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsupersocket.py
140 lines (124 loc) · 4.33 KB
/
supersocket.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
## This file is part of Scapy
## See http://www.secdev.org/projects/scapy for more informations
## Copyright (C) Philippe Biondi <[email protected]>
## This program is published under a GPLv2 license
"""
SuperSocket.
"""
import socket,time
from config import conf
from data import *
from scapy.error import warning
class _SuperSocket_metaclass(type):
def __repr__(self):
if self.desc is not None:
return "<%s: %s>" % (self.__name__,self.desc)
else:
return "<%s>" % self.__name__
class SuperSocket:
__metaclass__ = _SuperSocket_metaclass
desc = None
closed=0
def __init__(self, family=socket.AF_INET,type=socket.SOCK_STREAM, proto=0):
self.ins = socket.socket(family, type, proto)
self.outs = self.ins
self.promisc=None
def send(self, x):
sx = str(x)
x.sent_time = time.time()
return self.outs.send(sx)
def recv(self, x=MTU):
return conf.raw_layer(self.ins.recv(x))
def fileno(self):
return self.ins.fileno()
def close(self):
if self.closed:
return
self.closed=1
if self.ins != self.outs:
if self.outs and self.outs.fileno() != -1:
self.outs.close()
if self.ins and self.ins.fileno() != -1:
self.ins.close()
def sr(self, *args, **kargs):
return sendrecv.sndrcv(self, *args, **kargs)
def sr1(self, *args, **kargs):
a,b = sendrecv.sndrcv(self, *args, **kargs)
if len(a) > 0:
return a[0][1]
else:
return None
def sniff(self, *args, **kargs):
return sendrecv.sniff(opened_socket=self, *args, **kargs)
class L3RawSocket(SuperSocket):
desc = "Layer 3 using Raw sockets (PF_INET/SOCK_RAW)"
def __init__(self, type = ETH_P_IP, filter=None, iface=None, promisc=None, nofilter=0):
self.outs = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
self.outs.setsockopt(socket.SOL_IP, socket.IP_HDRINCL, 1)
self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type))
if iface is not None:
self.ins.bind((iface, type))
def recv(self, x=MTU):
pkt, sa_ll = self.ins.recvfrom(x)
if sa_ll[2] == socket.PACKET_OUTGOING:
return None
if sa_ll[3] in conf.l2types:
cls = conf.l2types[sa_ll[3]]
lvl = 2
elif sa_ll[1] in conf.l3types:
cls = conf.l3types[sa_ll[1]]
lvl = 3
else:
cls = conf.default_l2
warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using %s" % (sa_ll[0],sa_ll[1],sa_ll[3],cls.name))
lvl = 3
try:
pkt = cls(pkt)
except KeyboardInterrupt:
raise
except:
if conf.debug_dissector:
raise
pkt = conf.raw_layer(pkt)
if lvl == 2:
pkt = pkt.payload
if pkt is not None:
from arch import get_last_packet_timestamp
pkt.time = get_last_packet_timestamp(self.ins)
return pkt
def send(self, x):
try:
sx = str(x)
x.sent_time = time.time()
self.outs.sendto(sx,(x.dst,0))
except socket.error,msg:
log_runtime.error(msg)
class SimpleSocket(SuperSocket):
desc = "wrapper arround a classic socket"
def __init__(self, sock):
self.ins = sock
self.outs = sock
class StreamSocket(SimpleSocket):
desc = "transforms a stream socket into a layer 2"
def __init__(self, sock, basecls=None):
if basecls is None:
basecls = conf.raw_layer
SimpleSocket.__init__(self, sock)
self.basecls = basecls
def recv(self, x=MTU):
pkt = self.ins.recv(x, socket.MSG_PEEK)
x = len(pkt)
if x == 0:
raise socket.error((100,"Underlying stream socket tore down"))
pkt = self.basecls(pkt)
pad = pkt.getlayer(Padding)
if pad is not None and pad.underlayer is not None:
del(pad.underlayer.payload)
while pad is not None and not isinstance(pad, NoPayload):
x -= len(pad.load)
pad = pad.payload
self.ins.recv(x)
return pkt
if conf.L3socket is None:
conf.L3socket = L3RawSocket
import sendrecv