rsmmr / hilti

**NOTE**: This is outdated and no longer maintained. There's a new version at https://github.com/zeek/spicy.
Other
40 stars 22 forks source link

Read directly from network device #13

Open blipp opened 8 years ago

blipp commented 8 years ago

I did some initial development to enable pac-driver to read directly from a network device using libpcap. I would like to propose this as a pull request. In the following, I summarize the work I did, and at the end I list some questions regarding this implementation that should probably be discussed before considering a merge.

The reason I implemented this was because I need to analyse Ethernet packets different from TCP, UDP and ICMP, which are the only protocols that can be analyzed with the Bro plugin. On the long run, it would surely be better to adapt Bro, but for now this seemed too much to dig in.

I introduce a new parameter -n that expects the network device as argument. If it is set, then instead of the normal parseSingleInput call, libpcap is used with a callback function processPacket for every packet that arrives. The code of this function is inspired by the existing code of pac-driver.

I did not implement support for -e and -i because this had no immediate benefit for me, but I think it could be possible. I added this restriction to the help output.

Because grammars usually need to know the length of the captured content, this is done by prepending this information as uint32. Thus, this leads us to some kind of a header before the beginning of the actual Ethernet packet, like in pcap.pac2. I added an example grammar with networkinterface.pac2. After the header it immediately refers to the pcap grammar for the handling of Ethernet packets.

I added a test for this new functionality, which uses tcpreplay to replay dns.trace, which is already included in the source tree. The implementation of the test is kind of ugly, because the grammar does not compile with hilti-build because of #3. As soon as this gets fixed, there is no need for this ugly timer-based approach.

pac-driver seems to be able to process packets quite fast with this addition, although I have no statistics to show.

Questions:

blipp commented 8 years ago

Although this could be derived from the test I wrote, I should provide the commands to test this feature:

pac-driver -n lo -g tests/binpac/parsers/networkinterface/test.pac2 libbinpac/parsers/networkinterface.pac2

tcpreplay --intf1=lo bro/tests/Traces/dns.trace

Execute the first one and wait a little bit until --- pac-driver: opened network device 'lo'. appears. Then execute the second one in another shell. While tcprelay is generating packets, 6 lines with IPV4 should appear one after another in pac-driver's shell.

rsmmr commented 8 years ago

Nice patch, thanks. Couple thoughts:

Regarding your questions:

0xxon commented 8 years ago

Just a bit of context about EtherPacket and why it requires a length. Basically -- the Ethernet frame itself does not contain any length information about its payload. And the payload of the protocols it contains (like, e.g. IP) does not have to be equivalent to the actual payload of the packet (e.g. when someone adds frame-checksums or timestamp information like Arista can do to it). In those case, you would not read the entire packet if you don't have the outside information that tells you the packet length :)

Note - currently I think that length is not really used to make sure that really all data has been read - but it can and should be used for that in the future.

blipp commented 8 years ago

Thanks for your feedback!

blipp commented 8 years ago

I enhanced the patch so now the packet capture time and the actual length of the packet is given to the grammar as well. Tests and grammars still have to be adapted.