3
3
import threading
4
4
import time
5
5
import sys
6
+ import random
6
7
from optparse import OptionParser
7
8
8
9
ETH_P_IP = 0x0800 # Internet Protocol Packet
@@ -18,95 +19,36 @@ def checksum(data):
18
19
s = (s & 0xFFFF ) + (s >> 16 )
19
20
s = ~ s & 0xffff
20
21
return s
21
-
22
- def recv (event , iface , src , dst , srcp , dstp , buff , timeout ):
23
- """
24
- event: should be set when a packet is sent
25
- src: source ip
26
- dst: destination ip
27
- srcp: source port
28
- dstp: destination port
29
- buff: buffer for received data
30
- """
31
- sock = socket .socket (socket .AF_PACKET ,
32
- socket .SOCK_DGRAM ,
33
- socket .htons (ETH_P_IP ))
34
- sock .settimeout (timeout )
35
- sock .bind ((iface , ETH_P_IP ))
36
- event .wait ()
37
- while True :
38
- try :
39
- data , sa_ll = sock .recvfrom (65535 )
40
- if sa_ll [1 ]== ETH_P_IP and sa_ll [2 ]== socket .PACKET_HOST :
41
- break # break if we captured incoming ip packet,
42
- except socket .timeout :
43
- sock .close ()
44
- return
45
-
46
- sip = data [12 :16 ] # src ip
47
- dip = data [16 :20 ] # dst ip
48
- sp = data [20 :22 ] # src port
49
- dp = data [22 :24 ] # dst port
50
- if sip == dst and dip == src and sp == dstp and dp == srcp :
51
- buff .append (data ) # return received packet
52
- event .clear ()
53
- sock .close ()
54
22
55
- def send (network , transport , payload = "" , iface = None , retry = 3 , timeout = 1 ):
56
- if timeout <= 0 :
57
- # Avoid entering an infinite waiting loop
58
- timeout = 0.1
59
- response = []
60
- event = threading .Event ()
61
- sock = socket .socket (socket .AF_INET ,
62
- socket .SOCK_RAW ,
63
- socket .IPPROTO_RAW )
64
- # Extracting identifiers
65
- # ip
66
- src = network .source
67
- dst = network .destination
68
- # port
69
- srcp = struct .pack ("!H" , transport .srcp )
70
- dstp = struct .pack ("!H" , transport .dstp )
71
-
72
- transport .payload = payload
73
- packet = network .pack () + transport .pack (network .source , network .destination ) + payload
74
-
75
- for i in range (retry ):
76
- t = threading .Thread (target = recv ,
77
- args = (event , iface ,
78
- src , dst , srcp ,
79
- dstp , response , timeout )
80
- )
81
- t .start ()
82
- sock .sendto (packet , (socket .inet_ntoa (dst ), 0 ))
83
- event .set ()
84
- t .join ()
85
- if not event .isSet ():
86
- break
87
-
88
- if event .isSet ():
89
- return None
90
- else :
91
- return response [0 ]
92
-
93
23
class layer ():
94
24
pass
95
25
26
+ class ETHER (object ):
27
+ def __init__ (self , src , dst , type = ETH_P_IP ):
28
+ self .src = src
29
+ self .dst = dst
30
+ self .type = type
31
+ def pack (self ):
32
+ ethernet = struct .pack ('!6s6sH' ,
33
+ self .dst ,
34
+ self .src ,
35
+ self .type )
36
+ return ethernet
37
+
96
38
class IP (object ):
97
- def __init__ (self , source , destination ):
98
- self .version = 4
99
- self .ihl = 5 # Internet Header Length
100
- self .tos = 0 # Type of Service
101
- self .tl = 0 # total length will be filled by kernel
102
- self .id = 54321
103
- self .flags = 0
104
- self .offset = 0
105
- self .ttl = 255
106
- self .protocol = socket . IPPROTO_TCP
107
- self .checksum = 0 # will be filled by kernel
108
- self .source = socket .inet_aton (source )
109
- self .destination = socket .inet_aton (destination )
39
+ def __init__ (self , source , destination , payload = '' , proto = socket . IPPROTO_TCP ):
40
+ self .version = 4
41
+ self .ihl = 5 # Internet Header Length
42
+ self .tos = 0 # Type of Service
43
+ self .tl = 20 + len ( payload )
44
+ self .id = 0 #random.randint(0, 65535)
45
+ self .flags = 0 # Don't fragment
46
+ self .offset = 0
47
+ self .ttl = 255
48
+ self .protocol = proto
49
+ self .checksum = 2 # will be filled by kernel
50
+ self .source = socket .inet_aton (source )
51
+ self .destination = socket .inet_aton (destination )
110
52
def pack (self ):
111
53
ver_ihl = (self .version << 4 ) + self .ihl
112
54
flags_offset = (self .flags << 13 ) + self .offset
@@ -121,35 +63,47 @@ def pack(self):
121
63
self .checksum ,
122
64
self .source ,
123
65
self .destination )
66
+ self .checksum = checksum (ip_header )
67
+ ip_header = struct .pack ("!BBHHHBBH4s4s" ,
68
+ ver_ihl ,
69
+ self .tos ,
70
+ self .tl ,
71
+ self .id ,
72
+ flags_offset ,
73
+ self .ttl ,
74
+ self .protocol ,
75
+ socket .htons (self .checksum ),
76
+ self .source ,
77
+ self .destination )
124
78
return ip_header
125
79
def unpack (self , packet ):
126
- _ip = layer ()
127
- _ip .ihl = (ord (packet [0 ]) & 0xf ) * 4
128
- iph = struct .unpack ("!BBHHHBBH4s4s" , packet [:_ip .ihl ])
129
- _ip .ver = iph [0 ] >> 4
130
- _ip .tos = iph [1 ]
131
- _ip .length = iph [2 ]
132
- _ip .ids = iph [3 ]
133
- _ip .flags = iph [4 ] >> 13
134
- _ip .offset = iph [4 ] & 0x1FFF
135
- _ip .ttl = iph [5 ]
136
- _ip .protocol = iph [6 ]
137
- _ip .checksum = hex (iph [7 ])
138
- _ip .src = socket .inet_ntoa (iph [8 ])
139
- _ip .dst = socket .inet_ntoa (iph [9 ])
140
- _ip .list = [
141
- _ip .ihl ,
142
- _ip .ver ,
143
- _ip .tos ,
144
- _ip .length ,
145
- _ip .ids ,
146
- _ip .flags ,
147
- _ip .offset ,
148
- _ip .ttl ,
149
- _ip .protocol ,
150
- _ip .src ,
151
- _ip .dst ]
152
- return _ip
80
+ _ip = layer ()
81
+ _ip .ihl = (ord (packet [0 ]) & 0xf ) * 4
82
+ iph = struct .unpack ("!BBHHHBBH4s4s" , packet [:_ip .ihl ])
83
+ _ip .ver = iph [0 ] >> 4
84
+ _ip .tos = iph [1 ]
85
+ _ip .length = iph [2 ]
86
+ _ip .ids = iph [3 ]
87
+ _ip .flags = iph [4 ] >> 13
88
+ _ip .offset = iph [4 ] & 0x1FFF
89
+ _ip .ttl = iph [5 ]
90
+ _ip .protocol = iph [6 ]
91
+ _ip .checksum = hex (iph [7 ])
92
+ _ip .src = socket .inet_ntoa (iph [8 ])
93
+ _ip .dst = socket .inet_ntoa (iph [9 ])
94
+ _ip .list = [
95
+ _ip .ihl ,
96
+ _ip .ver ,
97
+ _ip .tos ,
98
+ _ip .length ,
99
+ _ip .ids ,
100
+ _ip .flags ,
101
+ _ip .offset ,
102
+ _ip .ttl ,
103
+ _ip .protocol ,
104
+ _ip .src ,
105
+ _ip .dst ]
106
+ return _ip
153
107
154
108
class TCP (object ):
155
109
def __init__ (self , srcp , dstp ):
@@ -243,7 +197,25 @@ def unpack(self, packet):
243
197
_tcp .urg ,
244
198
_tcp .options ,
245
199
_tcp .payload ]
246
- return _tcp
200
+ return _tcp
201
+
202
+ class UDP (object ):
203
+ def __init__ (self , src , dst , payload = '' ):
204
+ self .src = src
205
+ self .dst = dst
206
+ self .payload = payload
207
+ self .checksum = 0
208
+ self .length = 8 # UDP Header length
209
+ def pack (self , src , dst , proto = socket .IPPROTO_UDP ):
210
+ length = self .length + len (self .payload )
211
+ pseudo_header = struct .pack ('!4s4sBBH' ,
212
+ socket .inet_aton (src ), socket .inet_aton (dst ), 0 ,
213
+ proto , length )
214
+ self .checksum = checksum (pseudo_header )
215
+ packet = struct .pack ('!HHHH' ,
216
+ self .src , self .dst , length , 0 )
217
+ return packet
218
+
247
219
def main ():
248
220
parser = OptionParser ()
249
221
parser .add_option ("-s" , "--src" , dest = "src" , type = "string" ,
0 commit comments