· 4 years ago · Dec 29, 2020, 10:42 AM
1#
2# Listener
3#
4from scapy.all import *
5import os
6import hashlib
7import json
8
9# id = 1 --> Handshake packets
10# id = 2 --> file chunks packet
11# id = 3 --> request for resend
12
13class Receiver:
14 def __init__(self):
15 self.ip_client = '192.168.1.122'
16 self.chunk_list = []
17 self.file_size = 0
18 self.file_name = ''
19 self.total_chunks = 0
20 self.sha1_digest = 0
21 self.transport_properties_dict = {}
22
23 def handshake(self):
24 while True:
25 res = sniff(count=1, filter=f"src host {self.ip_client} and icmp")
26 if res[ICMP][0].id == 1:
27 break
28 self.transport_properties_dict = json.load(res[Raw])
29 self.file_name = self.transport_properties_dict["file_name"]
30 self.file_size = self.transport_properties_dict["file_size"]
31 self.sha1_digest = self.transport_properties_dict["file_sha1"]
32 self.total_chunks = self.transport_properties_dict["num_of_chunks"]
33
34 pkt = IP(dst=self.ip_client)/ICMP(id=1)/Raw(load='sendnow123')
35 send(pkt)
36 return True
37
38 def recv_file(self):
39
40 # Chunks list initialization
41 for i in range(self.total_chunks):
42 self.chunk_list[i] = None
43
44 while True:
45 res = sniff(count=1, filter=f"src host {self.ip_client} and icmp")
46 if res[ICMP].id == 2:
47 self.chunk_list[[ICMP][0].seq] = res[ICMP][0][Raw].load
48 if res[ICMP][0].seq == self.total_chunks - 1:
49 break
50
51 if None not in self.chunk_list:
52 with open(self.file_name, 'wb') as f:
53 for item in self.chunk_list:
54 f.write(item)
55 return True
56
57 if None in self.chunk_list:
58 return False
59
60 def hash_caluation(self):
61 BLOCKSIZE = 65536
62 hasher = hashlib.sha1()
63 with open(self.file_name, 'rb') as f:
64 buf = f.read(BLOCKSIZE)
65 while len(buf) > 0:
66 hasher.update(buf)
67 buf = f.read(BLOCKSIZE)
68 local_sha1_digest = hasher.hexdigest()
69 if self.sha1_digest == local_sha1_digest:
70 print(f'file digest is OK: {self.sha1_digest}')
71 return True
72 else:
73 print(f'file digest is wrong: local_sha1_digest')
74 return False
75
76 def packet_loss(self):
77 while None in self.chunk_list:
78 # Search chunks list for empty places (None) and asks the client to send again.
79 for index in range(len(self.chunk_list)):
80 # None chunk_list -- > needs resend.
81 if not self.chunk_list[index]:
82 pkt = IP(dst=self.ip_client)/ICMP(seq=index, id=3)
83 send(pkt)
84 res = sniff(count=1, filter=f"src host {self.ip_client} and icmp")
85 if res[ICMP][0].id == 3:
86 self.chunk_list[index] = res[ICMP][0][Raw].load
87 # Update the server that all chunks are in place.
88 pkt = IP(dst=self.ip_client)/ICMP(id=4)
89 send(pkt)
90 # writing to file.
91 with open(self.file_name, 'wb') as f:
92 for item in self.chunk_list:
93 f.write(item)
94 self.hash_caluation()
95
96
97
98server = Receiver()
99operation = server.handshake()
100if operation:
101 operation = server.recv_file()
102 if operation:
103 operation = server.hash_caluation()
104 if operation:
105 print("File received successfully!!!")
106 else:
107 server.packet_loss()
108
109
110
111
112