In this part of my project, I am trying to create a program to sniff packets from multiple adapters using libpcap. These packets should be able to be piped to different programs with ease.
Current Plan
My current plan for this is to create 3 different major functions,
sniff(), alter(), send().
Sniff() Objectives:
- can analyze multiple adapters at once
- should be able to read packets
- analyze packet type, flags, and data
- pipe packets out at minimal latency
- doesn't read the same packets twice over a network
To start with the sniffing code, there are a couple important pcap functions that are used in code in the following order.
pcap_open_live(), pcap_lookupnet(), pcap_compile(), pcap_next().
We are not using pcap_loop() or pcap_lookupdev() for the following reasons:
- pcap_loop will only run through a single adapter thus preventing us from running this program from altering packets.
- pcap_lookupdev() will only grab the top adapter, without allowing us to choose which, this makes it harder choose which packets to run where.
A big problem I encountered was trying to create an array of (pcap_t*) devices to make my job easier on looping them. But I always encountered segfaults because pcap_t *device[size]
will throw me into inaccessible addresses. A rather inelegant way that I "bypassed" this is by creating a (char*) array and point these to the pcap_t devices via hardcode. If you know better methods, please do drop them down below.
ptr[a] = pcap_open_live(d->name, snaplen, 1, 1000, ebuf);
This function creates a device of "d->name" which is a string containing the interface name with a capture length of snaplen which is specified to 1500. This 'pcap_t *' is saved to an array via reference so that we can scroll through different interfaces for packet write out.
(pcap_lookupnet(d->name, &localnet, &netmask, ebuf)
This function grabs the netmask and IPv4 network number from the interface "d->name".
(pcap_compile(ptr[a], &fcode, cmdbuf, 1, netmask)
This function begins pcap functionality and to grab the data, we have to use pcap_next
.
while(run){
for(i = 0; i < deviceEnteredCount; i++){
packet[i] = pcap_next(ptr[0], &header);
raw_print(pcap_userdata, &header, packet[i]);
}
}
To roll through all the pcap_t devices, we use a pointer to point towards the devices and simply run it in a loop. This loop is stopped by a Ctrl-C command.
Self-reminders:
- Always read manpages whenever you use libraries so you don't waste time when implementing functions.
- Check code for memory leaks and hopefully prevent segfaults.
- Learn how to use malloc properly.
Notes for the future self:
- Try multithreading it to increase performance.
- Minimize a function size for more adaptability.
- Try to not hardcode please :( It's not pretty.
Top comments (0)