Commit 2265d4da88af76d553f8b0e74071b8d237bb175b
1 parent
9f4d511e63
Exists in
master
Added basic classes and functionality to make and send IP packets
Showing 1 changed file with 106 additions and 0 deletions Side-by-side Diff
network.py
View file @
2265d4d
1 | +import sys | |
2 | +import socket | |
3 | +from struct import * | |
4 | + | |
5 | +class OutPipe: | |
6 | + socket = None | |
7 | + | |
8 | + #def __init__(self): | |
9 | + | |
10 | + def start(self): | |
11 | + try: | |
12 | + self.socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW) | |
13 | + except socket.error , msg: | |
14 | + print('There was an issue with OutPipe. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]) | |
15 | + sys.exit() | |
16 | + | |
17 | + def transmit(self, data, addr): | |
18 | + if(self.socket != None): | |
19 | + self.socket.sendto(data, addr) | |
20 | + else: | |
21 | + print('OutPipe is not initialized') | |
22 | + | |
23 | + #Replace Later.. Maybe Cython Implementation | |
24 | + def checksum(self, msg): | |
25 | + s = 0 | |
26 | + for i in range(0, len(msg), 2): | |
27 | + w = ord(msg[i]) + (ord(msg[i+1]) << 8 ) | |
28 | + s = s + w | |
29 | + s = (s>>16) + (s & 0xffff); | |
30 | + s = s + (s >> 16); | |
31 | + s = ~s & 0xffff | |
32 | + return s | |
33 | + | |
34 | + #Simple IP Test | |
35 | + def ip_packet_test(self): | |
36 | + # tell kernel not to put in headers, since we are providing it, when using IPPROTO_RAW this is not necessary | |
37 | + # s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1) | |
38 | + | |
39 | + # now start constructing the packet | |
40 | + packet = ''; | |
41 | + | |
42 | + source_ip = '192.168.1.101' | |
43 | + dest_ip = '192.168.1.114' # or socket.gethostbyname('www.google.com') | |
44 | + | |
45 | + # ip header fields | |
46 | + ip_ihl = 5 | |
47 | + ip_ver = 4 | |
48 | + ip_tos = 0 | |
49 | + ip_tot_len = 0 # kernel will fill the correct total length | |
50 | + ip_id = 54321 #Id of this packet | |
51 | + ip_frag_off = 0 | |
52 | + ip_ttl = 255 | |
53 | + ip_proto = socket.IPPROTO_TCP | |
54 | + ip_check = 0 # kernel will fill the correct checksum | |
55 | + ip_saddr = socket.inet_aton ( source_ip ) #Spoof the source ip address if you want to | |
56 | + ip_daddr = socket.inet_aton ( dest_ip ) | |
57 | + | |
58 | + ip_ihl_ver = (ip_ver << 4) + ip_ihl | |
59 | + | |
60 | + # the ! in the pack format string means network order | |
61 | + ip_header = pack('!BBHHHBBH4s4s' , ip_ihl_ver, ip_tos, ip_tot_len, ip_id, ip_frag_off, ip_ttl, ip_proto, ip_check, ip_saddr, ip_daddr) | |
62 | + | |
63 | + # tcp header fields | |
64 | + tcp_source = 1234 # source port | |
65 | + tcp_dest = 80 # destination port | |
66 | + tcp_seq = 454 | |
67 | + tcp_ack_seq = 0 | |
68 | + tcp_doff = 5 #4 bit field, size of tcp header, 5 * 4 = 20 bytes | |
69 | + #tcp flags | |
70 | + tcp_fin = 0 | |
71 | + tcp_syn = 1 | |
72 | + tcp_rst = 0 | |
73 | + tcp_psh = 0 | |
74 | + tcp_ack = 0 | |
75 | + tcp_urg = 0 | |
76 | + tcp_window = socket.htons (5840) # maximum allowed window size | |
77 | + tcp_check = 0 | |
78 | + tcp_urg_ptr = 0 | |
79 | + | |
80 | + tcp_offset_res = (tcp_doff << 4) + 0 | |
81 | + tcp_flags = tcp_fin + (tcp_syn << 1) + (tcp_rst << 2) + (tcp_psh <<3) + (tcp_ack << 4) + (tcp_urg << 5) | |
82 | + | |
83 | + # the ! in the pack format string means network order | |
84 | + tcp_header = pack('!HHLLBBHHH' , tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags, tcp_window, tcp_check, tcp_urg_ptr) | |
85 | + | |
86 | + user_data = 'Hello, how are you' | |
87 | + | |
88 | + # pseudo header fields | |
89 | + source_address = socket.inet_aton( source_ip ) | |
90 | + dest_address = socket.inet_aton(dest_ip) | |
91 | + placeholder = 0 | |
92 | + protocol = socket.IPPROTO_TCP | |
93 | + tcp_length = len(tcp_header) + len(user_data) | |
94 | + | |
95 | + psh = pack('!4s4sBBH' , source_address , dest_address , placeholder , protocol , tcp_length); | |
96 | + psh = psh + tcp_header + user_data; | |
97 | + | |
98 | + tcp_check = self.checksum(psh) | |
99 | + #print tcp_checksum | |
100 | + | |
101 | + # make the tcp header again and fill the correct checksum - remember checksum is NOT in network byte order | |
102 | + tcp_header = pack('!HHLLBBH' , tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags, tcp_window) + pack('H' , tcp_check) + pack('!H' , tcp_urg_ptr) | |
103 | + | |
104 | + # final full packet - syn packets dont have any data | |
105 | + packet = ip_header + tcp_header + user_data | |
106 | + return packet |