-
Notifications
You must be signed in to change notification settings - Fork 0
/
nprotocols.py
97 lines (72 loc) · 3.03 KB
/
nprotocols.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
import socket
import struct
import time
import textwrap
class Ethernet:
def __init__(self, raw_data):
dest, src, prototype = struct.unpack('! 6s 6s H', raw_data[:14])
self.dest_mac = get_mac_addr(dest)
self.src_mac = get_mac_addr(src)
self.proto = socket.htons(prototype)
self.data = raw_data[14:]
class HTTP:
def __init__(self, raw_data):
try:
self.data = raw_data.decode('utf-8')
except:
self.data = raw_data
class ICMP:
def __init__(self, raw_data):
self.type, self.code, self.checksum = struct.unpack('! B B H', raw_data[:4])
self.data = raw_data[4:]
class IPv4:
def __init__(self, raw_data):
version_header_length = raw_data[0]
self.version = version_header_length >> 4
self.header_length = (version_header_length & 15) * 4
self.ttl, self.proto, src, target = struct.unpack('! 8x B B 2x 4s 4s', raw_data[:20])
self.src = self.ipv4(src)
self.target = self.ipv4(target)
self.data = raw_data[self.header_length:]
# Returns properly formatted IPv4 address
def ipv4(self, addr):
return '.'.join(map(str, addr))
class Pcap:
def __init__(self, filename, link_type=1):
self.pcap_file = open(filename, 'wb')
self.pcap_file.write(struct.pack('@ I H H i I I I', 0xa1b2c3d4, 2, 4, 0, 0, 65535, link_type))
def write(self, data):
ts_sec, ts_usec = map(int, str(time.time()).split('.'))
length = len(data)
self.pcap_file.write(struct.pack('@ I I I I', ts_sec, ts_usec, length, length))
self.pcap_file.write(data)
def close(self):
self.pcap_file.close()
class TCP:
def __init__(self, raw_data):
(self.src_port, self.dest_port, self.sequence, self.acknowledgment, offset_reserved_flags) = struct.unpack(
'! H H L L H', raw_data[:14])
offset = (offset_reserved_flags >> 12) * 4
self.flag_urg = (offset_reserved_flags & 32) >> 5
self.flag_ack = (offset_reserved_flags & 16) >> 4
self.flag_psh = (offset_reserved_flags & 8) >> 3
self.flag_rst = (offset_reserved_flags & 4) >> 2
self.flag_syn = (offset_reserved_flags & 2) >> 1
self.flag_fin = offset_reserved_flags & 1
self.data = raw_data[offset:]
class UDP:
def __init__(self, raw_data):
self.src_port, self.dest_port, self.size = struct.unpack('! H H 2x H', raw_data[:8])
self.data = raw_data[8:]
# Returns MAC as string from bytes (ie AA:BB:CC:DD:EE:FF)
def get_mac_addr(mac_raw):
byte_str = map('{:02x}'.format, mac_raw)
mac_addr = ':'.join(byte_str).upper()
return mac_addr
# Formats multi-line data
def format_multi_line(string, size=64):
if isinstance(string, bytes):
string = ''.join(r'\x{:02x}'.format(byte) for byte in string)
if size % 2:
size -= 1
return str('\n'.join(['' + line for line in textwrap.wrap(string, size)]))