One of them is libtins, a library I have been actively developing for the past few years. It has support for several protocols, including Ethernet, IP, IPv6, TCP, UDP, DHCP, DNS and IEEE 802.11, and it works on GNU/Linux, Windows, OSX and FreeBSD. It even works on different architectures such as ARM and MIPS, so you could go ahead and develop some application which could be executed inside routers and other devices.
Let's see how you would sniff some TCP packets and print their source and destination port and addresses:
#include <iostream> #include <tins/tins.h>
using namespace std;using namespace Tins;
bool callback(const PDU &pdu) { const IP &ip = pdu.rfind_pdu<IP>(); const TCP &tcp = pdu.rfind_pdu<TCP>(); cout << ip.src_addr() << ':' << tcp.sport() << " -> " << ip.dst_addr() << ':' << tcp.dport() << endl; return true; } int main() { // Sniff on interface eth0 Sniffer sniffer("eth0"); sniffer.sniff_loop(callback); }This is the output I get when executing it:
- The callback function is the one that libtins will call for us each time a new packet is sniffed. It returns a boolean, whch indicates whether sniffing should go on or not, and takes a parameter of type PDU, which will hold the sniffed packet. This library represents packets as a series of Protocol Data Units(PDU) stacked over each other. So in this case, every packet would contain an EthernetII, IP and TCP PDUs.
- Inside callback's body, you can see that we're calling PDU::rfind_pdu. This is a member function template which looks for the provided PDU type inside the packet, and returns a reference to it. So in the first two lines we're retrieving the IP and TCP layers, and then we're simply printing the addresses and ports.
- Finally, in main an object of type Sniffer is constructed. When constructing it, we indicate that we want to sniff on interface eth0. After that, Sniffer::sniff_loop is called, which will start sniffing packets and calling our callback for each of them.
Now, you may be wondering whether using libtins will make your code significantly slower. If that is your concern, then you should not worry about it at all! This library was designed keeping efficiency in mind at all times. As a consequence it's the fastest packet sniffing and interpretation library I've tried out (note that I tried several, such as scapy, dpkt, impacket and libcrafter). Go ahead and have a look at these benchmarks to see how fast it actually works.
libtins allows you to implement fast packet sniffers in very few lines of code. It also supports additional features like reassembling and following TCP streams, decrypting WPA2 traffic (both TKIP and AES) and defragmenting IP datagrams.
If you want to learn more about libtins, please visit this tutorial, which covers everything you should know before starting to develop your network sniffing application!