ip.Frame needs to consider the pcap linktype; add a repr for icmp

This commit is contained in:
pi-rho 2013-02-15 12:50:27 -06:00
parent c4e24e04e1
commit 2df1ccd4af
1 changed files with 28 additions and 13 deletions

View File

@ -41,6 +41,9 @@ ICMP = 1
TCP = 6 TCP = 6
UDP = 17 UDP = 17
LINKTYPE_ETHER = 1
LINKTYPE_RAW = 101
def str_of_eth(d): def str_of_eth(d):
return ':'.join([('%02x' % ord(x)) for x in d]) return ':'.join([('%02x' % ord(x)) for x in d])
@ -49,18 +52,22 @@ def str_of_eth(d):
class Frame(object): class Frame(object):
"""Turn an ethernet frame into relevant parts""" """Turn an ethernet frame into relevant parts"""
def __init__(self, pkt): def __init__(self, pkt, linktype=LINKTYPE_ETHER):
((self.time, self.time_usec, _), frame) = pkt ((self.time, self.time_usec, _), frame) = pkt
# Ethernet if linktype == LINKTYPE_ETHER:
(self.eth_dhost, (self.eth_shost,
self.eth_shost, self.eth_dhost,
self.eth_type, self.eth_type,
p) = unpack('!6s6sH', frame) p) = unpack('!6s6sH', frame)
else: # Assume LINKTYPE_RAW, which contains only IP
self.eth_shost = None
self.eth_dhost = None
self.eth_type = IP
p = frame
if self.eth_type == VLAN: if self.eth_type == VLAN:
_, self.eth_type, p = unpack('!HH', p) _, self.eth_type, p = unpack('!HH', p)
if self.eth_type == ARP: if self.eth_type == ARP: # ARP
# ARP
self.name, self.protocol = ('ARP', ARP) self.name, self.protocol = ('ARP', ARP)
(self.ar_hrd, (self.ar_hrd,
self.ar_pro, self.ar_pro,
@ -75,8 +82,7 @@ class Frame(object):
self.saddr = self.ar_sip self.saddr = self.ar_sip
self.daddr = self.ar_tip self.daddr = self.ar_tip
self.__repr__ = self.__arp_repr__ self.__repr__ = self.__arp_repr__
elif self.eth_type == IP: elif self.eth_type == IP: # IP
# IP
(self.ihlvers, (self.ihlvers,
self.tos, self.tos,
self.tot_len, self.tot_len,
@ -87,7 +93,7 @@ class Frame(object):
self.check, self.check,
self.saddr, self.saddr,
self.daddr, self.daddr,
p) = unpack("!BBHHHBBHii", p) p) = unpack("!BBHHHBBHII", p)
if self.protocol == TCP: if self.protocol == TCP:
self.name = 'TCP/IP' self.name = 'TCP/IP'
@ -105,6 +111,7 @@ class Frame(object):
opt_length = self.off * 4 opt_length = self.off * 4
self.options, p = p[:opt_length - 20], p[opt_length - 20:] self.options, p = p[:opt_length - 20], p[opt_length - 20:]
self.payload = p[:self.tot_len - opt_length - 20] self.payload = p[:self.tot_len - opt_length - 20]
self.__repr__ = self.__tcp_repr__
elif self.protocol == UDP: elif self.protocol == UDP:
self.name = 'UDP/IP' self.name = 'UDP/IP'
(self.sport, (self.sport,
@ -119,10 +126,11 @@ class Frame(object):
(self.type, (self.type,
self.code, self.code,
self.cheksum, self.cheksum,
self.ipid, self.ident,
self.seq, self.seq,
p) = unpack('!BBHHH', p) p) = unpack('!BBHHH', p)
self.payload = p[:self.tot_len - 8] self.payload = p[:self.tot_len - 8]
self.__repr__ = self.__icmp_repr__
else: else:
self.name = 'IP Protocol %d' % self.protocol self.name = 'IP Protocol %d' % self.protocol
self.sport = self.dport = None self.sport = self.dport = None
@ -160,7 +168,14 @@ class Frame(object):
def dst_addr(self): def dst_addr(self):
del self._dst_addr del self._dst_addr
def __repr__(self): def __icmp_repr__(self):
return ('<Frame %s %s -> %s (%d/%d: %d, %d) length %d>' %
(self.name,
self.src_addr, self.dst_addr,
self.type, self.code, self.ident, self.seq,
len(self.payload)))
def __tcp_repr__(self):
return ('<Frame %s %s:%r(%08x) -> %s:%r(%08x) length %d>' % return ('<Frame %s %s:%r(%08x) -> %s:%r(%08x) length %d>' %
(self.name, (self.name,
self.src_addr, self.sport, self.seq, self.src_addr, self.sport, self.seq,