edisona / dpkt

Automatically exported from code.google.com/p/dpkt
Other
1 stars 0 forks source link

FCS field on dpkt.ethernet.Ethernet #122

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Suppose you have a string with a raw Ethernet packet, *including* the FCS 
bytes on the last 4 positions.
2. p = dpkt.ethernet.Ethernet(raw_ethernet_packet_string)
3. p.data has all the packet payload but FCS bytes are lost/not saved.

What is the expected output? What do you see instead?
I expect to have FCS data somewhere on Ethernet packet object. There isn't any 
FCS field to look. 

What version of the product are you using? On what operating system?
dpkt 1.6 on debian jessie

Please provide any additional information below.
I'm not sure if this is a needed feature to other users (in fact, most of the 
HW and pcap files don't return FCS field to software layers), my need for FCS 
support is somehow special (I'm programming a MAC HW). However, it would be 
nice to have an optional FCS support. Thanks.

Original issue reported on code.google.com by oscar....@gmail.com on 12 Mar 2014 at 3:30

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Did not mean to comment on this issue

Original comment by timur.al...@gmail.com on 2 Jul 2014 at 5:17

GoogleCodeExporter commented 9 years ago
Here I put a extended class I use in my project. Feel free to use it to update 
Ethernet class.

Best regards.

### Begin code ###

import dpkt
from zlib import crc32

class EthWithFcs(dpkt.ethernet.Ethernet):
    def __len__(self):
        if hasattr(self, "fcs"):
            return dpkt.ethernet.Ethernet.__len__(self) + 4
        else:
            return dpkt.ethernet.Ethernet.__len__(self)

    def __str__(self):
        if hasattr(self, "fcs"):
            return self.pack_hdr() + str(self.data) + self._fcs_tostr()
        else:
            return self.pack_hdr() + str(self.data)

    def add_fcs(self):
        self.fcs = self._fcs_calc()

    def is_fcs_valid(self):
        return self.fcs == self._fcs_calc()

    def unpack(self, buf):
        dpkt.ethernet.Ethernet.unpack(self, buf)
        if dpkt.ethernet.Ethernet.__len__(self) < len(buf):
            self.fcs = self._fcs_toint(buf[-4:])
        elif isinstance(self.data, str):
            self.fcs = self._fcs_toint(self.data[-4:])
            self.data = self.data[:-4]

    def _fcs_toint(self, buf):
        return int(buf.encode("hex"), 16)

    def _fcs_tostr(self):
        return "".join([chr((self.fcs >> (i*8)) & 0xff) for i in range(3,-1,-1)])

    def _fcs_calc(self):
        revcrc = crc32(self.pack_hdr() + str(self.data) & 0xffffffff
        return sum([((int(revcrc) >> i*4) & 0xf) << ((7-i)*4) for i in range(8)])

### End code ###

Original comment by oscar....@gmail.com on 8 Jul 2014 at 6:41

GoogleCodeExporter commented 9 years ago
Thanks for that! That would be useful.

Do you know if there is a way to indicate whether FCS is set on specific 
packets? For example, Radiotap headers include the FCS-included flag.

I'll try to add at least the option to include FCS, as I did that with the 
ieee80211 parser.

Original comment by timur.al...@gmail.com on 9 Jul 2014 at 5:23