-
Notifications
You must be signed in to change notification settings - Fork 3
/
arp.py
57 lines (49 loc) · 2.29 KB
/
arp.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
from socket import inet_ntoa
from struct import pack, unpack, calcsize
ARP_PKT_FMT = '!HHBBH6s4s6s4s'
'''
Simple Python model for an ARP Packet
'''
class ARPPacket:
def __init__(self, htype=0x0001, ptype=0x0800, hlen=0x0006,
plen=0x0004, optr=1, sha='', spa='', tha='', tpa=''):
self.arp_htype = htype # hardware type
self.arp_ptype = ptype # protocol type
self.arp_hlen = hlen # Hardware length (HLEN)
self.arp_plen = plen # Protocol length (PLEN)
self.arp_optr = optr # Operator 1 is broadcast to request next destination mac, 2 is reply
self.arp_sha = sha # sender hardware address (SHA) Mac
self.arp_spa = spa # Sender protocol address (SPA) eg IP
self.arp_tha = tha # Target hardware address (THA) Mac
self.arp_tpa = tpa # Target protocol address (TPA) eg IP
def __repr__(self):
repr = ('ARPPacket: ' +
'[htype: 0x%04x, ptype: 0x%04x, hlen: 0x%04x, plen: 0x%04x,' +
' optration: %s, sha: %s, spa: %s, tha: %s, tpa: %s]') \
% (self.arp_htype, self.arp_ptype, self.arp_hlen, self.arp_plen,
'REQUEST' if self.arp_optr == 1 else 'REPLY',
self._eth_addr(self.arp_sha), inet_ntoa(self.arp_spa),
self._eth_addr(self.arp_tha), inet_ntoa(self.arp_tpa))
return repr
def pack(self):
arp_packet = pack(ARP_PKT_FMT,
self.arp_htype, self.arp_ptype, self.arp_hlen,
self.arp_plen, self.arp_optr, self.arp_sha,
self.arp_spa, self.arp_tha, self.arp_tpa)
return arp_packet
def unpack(self, arp_packet):
arp_fields = unpack(ARP_PKT_FMT, arp_packet[:calcsize(ARP_PKT_FMT)])
self.arp_htype = arp_fields[0]
self.arp_ptype = arp_fields[1]
self.arp_hlen = arp_fields[2]
self.arp_plen = arp_fields[3]
self.arp_optr = arp_fields[4]
self.arp_sha = arp_fields[5]
self.arp_spa = arp_fields[6]
self.arp_tha = arp_fields[7]
self.arp_tpa = arp_fields[8]
def _eth_addr(self, raw):
hex = '%.2x:%.2x:%.2x:%.2x:%.2x:%.2x' \
% (ord(raw[0]), ord(raw[1]), ord(raw[2]),
ord(raw[3]), ord(raw[4]), ord(raw[5]))
return hex