Measuring upload/download rates with libpcap - c

I'm using libpcap (and winpcap on Windows) in a C application to monitor network traffic. I need to differentiate between upload and download traffic on each network adapter, to produce connection speed stats, but the filter expressions used by the library don't seem to support this very easily (ie there are no 'incoming'/'outgoing' operators).
One approach that I have considered is to query the IP address of each adapter, and then use filters such as src host 1.2.3.4 (to measure uploads) and dst host 1.2.3.4 (to measure downloads).
My questions are:
Is there a better/simpler approach than the one above (something that would let me use the same filter expression for each adapter would be nice)?
If the above approach is the way to go, then is there any chance that a single adapter could have more than 1 IP address associated with it? The reason I ask is that the pcap_addr struct which holds the address details of a single adapter (in struct pcap_if) has a 'next' member suggesting that this is possible.

Firstly, remember, pcap sees only packets. It doesn't see "outgoing" or "incoming" - simply packets. So yes, you must filter using the src/dst in the ip headers. There is no other way to tell whether the packet is incoming or outgoing.
Secondly, yes, there is nothing stopping an adapter having multiple IP addresses. So you need to grab the IP addresses configured from that adapter. pcap_findalldevs() (WinPCap Documentation) ought to help you here, from which you should be able to deduce which devices you want to monitor.

Have you considered looking at pmacct - I have personally contributed to this in time past. This is a C tool that uses libpcap to passively monitor network traffic for accounting purposes.

Try tcpdump

Related

disabling TCP stack in kernel and creating Userspace TCP stack -- call it a server for something -- what may be the challenges

if I malfunctioned my computer TCP stack in kernel just commenting out single important line of code or compiling with excluding TCP stack and install. Then What are the steps in I need to take in coding. Do I need to Implement Ethernet (if creates layer 2 Socket in my stack implementation) then do I need to implement IP because that comes with if I am using layer 2 socket then implement TCP (this is what final code will be)
If that's so
Then what are the supported protocols I need to implement to cover ethernet layer, Ip layer and (TCP layer -- that I can know I may have used it in code)
Can anyone please tell the machining protocols with each layer
whats before?-->ethernet --> ip -- tcp --> http <--protocol names please that may be needed
the whole thing is just for as a research thing or learning for my self or just may be programming
I'll assume you want to be able to do something like request https://example.com from a web server.
For this the following procotols are diretly necessary:
HTTPS (i.e. HTTP and TLS), but that's usually already implemented in user space, no change here
DNS to resolve example.com to an IP address. Usually implemented in user space as well, based on UDP
UDP to run DNS on top of. Usually implemented in the kernel on top of IP.
TCP to run HTTPS on top of. Usually implemented in the kernel on top of IP.
IP to run both TCP and UDP on top of. Usually implemented in the kernel on top of Ethernet.
Ethernet to send/receive IP packages. Usually implemented in the kernel, with the help of hardware-specific NIC drivers.
But even if you had implemented those, you wouldn't be done. For example, you wouldn't know what your local IP address is.
To do this, you'd implement DHCP. You could get away without implementing this, if you just configured your IP address to a fixed value (as long as it's within the allowed range of your network and doesn't conflict with other devices, this is not a problem).
But when you try to send your first IP packet to the DNS server, you'd realize that you don't know what Ethernet address you should send that to. So you'd need to implement ARP as well. Again, you could theoretically have a static routing table and "fake" the ARP responses by your router this way, but this could be way trickier than just hard-coding the IP adress.
I may have missed some protocol (and I'm sure comments will pop up, if I did), but that should be roughly everything that you'd need to get going.

Synchronize sqlite files without a public IP

I'm trying to come up with a way to sync a sqlite database between two computers.
If this were on a machine with a public IP this would not be difficult but I'm trying to find a way to make this work for ANY two devices, and most computers don't have a static IP.
What are some of the ways I can tackle this problem?
Assuming you just need to find the peers IP address...
Broadcast a Udp packet onto Lan, if machines are same lan segment. You can also try using admin scoped multicast, but mileage will vary according to the network setup and gear in use.
If trying to find two machines across the internet (assuming you can solve the NAT address translation issue), you need to bounce off a node that will hold info for you. Eg write a packet to dweet.io or sparkfun or other website that will hold store and forward data. You can also read twitter feeds etc, basically you need a known reference point to both talk too. Look into how malware create command and control networks for some ideas. Or search for rendezvous servers and protocols.
If the address range is small, probe all possible addresses. But be careful as you might trigger anti virus or ISP action
If wanting more browser based, look at webrtc, not quite what you are after but some of the techniques for discovery might be interesting.
If you have access, you can play with your DNS records. Essentially this is a variation of (2).
There are more options too, but that get more special purpose or become a bit too stelthy for general use. Also see how mesh networks are formed.

View - but not intercept - all IPv4 traffic to Linux computer

Is there a way to view all the IPv4 packets sent to a Linux computer?
I know I can capture the packets at the ethernet level using libpcap. This can work, but I don't really want to defragment the IPv4 packets. Does libpcap provide this functionality and I'm just missing it?
One thing that kinda works is using a tun device. I can capture all the IPv4 traffic by routing all traffic to the tun device via something like ip route add default via $TUN_IP dev $TUNID. This also stops outbound traffic though, which is not what I want.
I just want to see the IPv4 packets, not intercept them. (Or, even better, optionally intercept them.)
Edit: I'm specifically looking for a programmatic interface to do this. E.g. something I can use from within a C program.
Yes, you can see all the packets that arrive at your network interface. There are several options to access or view them. Here a small list of possible solutions, where the first one is the easiest and the last one the hardest to utilize:
Wireshark
I'd say this is pretty much the standard when it comes to protocol analyzers with a GUI (uses libpcap). It has tons of options, a nice GUI, great filtering capabilities and reassembles IP datagrams. It uses libpcap and can also show the raw ethernet frame data. For example it allows you to see layer 2 packets like ARP. Furthermore you can capture the complete data arriving at your network interface in a file that can later be analyzed (also in Wireshark).
tcpdump
Very powerful, similar features like Wireshark but a command line utility, which also uses libpcap. Can also capture/dump the complete interface traffic to a file. You can view the dumped data in Wireshark since the format is compatible.
ngrep
This is known as the "network grep" and is similar to tcpdump but supports regular expressions (regex) to filter the payload data. It allows to save captured data in the file format supported by Wireshark and tcpdump (also uses libpcap).
libnids
Quotation from the official git repository:
"Libnids is a library that provides a functionality of one of NIDS
(Network Intrusion Detection System) components, namely E-component. It means
that libnids code watches all local network traffic [...] and provides convenient information on them to
analyzing modules of NIDS. Libnids performs:
assembly of TCP segments into TCP streams
IP defragmentation
TCP port scan detection"
libpcap
Of course you can also write your own programs by using the library directly. Needless to say, this requires more efforts.
Raw or Packet Sockets
In case you want to do all the dirty work yourself, this is the low level option, which of course also allows you to do everything you want. The tools listed above use them as a common basis. Raw sockets operate on OSI layer 3 and packet sockets on layer 2.
Note: This is not meant to be a complete list of available tools or options. I'm sure there are much more but these are the most common ones I can think of.
Technically you have to make a copy of the received packet via libpcap. To be more specific, what you can do is to get packets with libpcap, that way the packets will be kind of blocked, so you need to re send them to the destination. Lets say that you want to make a Fire-Wall or something, what you should do is to have a layer that can work like getting the package and then send it to the destination, in between you can make a copy of what you got for further processes. In order to make the intercept option, you need to create some predefined rules, i.e. the ones that violates the rules will not be send again to their destination.
But that needs a lot of efforts and I don't think you want to waist your life on it.
Wire-shark as mentioned by #Barmar can do the job already.
If you need some kind of command line interface option I would say that "tcpdump" is one of the best monitoring tools. for example for capturing all ipv4 HTTP packets to and from port 80 the command will be:
tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'
for more information and options see tcpdump
Please be specific if you need to write a program for it, then we can help about how to do it.

How to create a custom packet in c?

I'm trying to make a custom packet using C using the TCP/IP protocol. When I say custom, I mean being able to change any value from the packet; ex: MAC, IP address and so on.
I tried searching around but I can't find anything that is actually guiding me or giving me example source codes.
How can I create a custom packet or where should I look for guidance?
A relatively easy tool to do this that is portable is libpcap. It's better known for receiving raw packets (and indeed it's better you play with that first as you can compare received packets with your hand crafted ones) but the little known pcap_sendpacket will actually send a raw packet.
If you want to do it from scratch yourself, open a socket with AF_PACKET and SOCK_RAW (that's for Linux, other OS's may vary) - for example see http://austinmarton.wordpress.com/2011/09/14/sending-raw-ethernet-packets-from-a-specific-interface-in-c-on-linux/ and the full code at https://gist.github.com/austinmarton/1922600 . Note you need to be root (or more accurately have the appropriate capability) to do this.
Also note that if you are trying to send raw tcp/udp packets, one problem you will have is disabling the network stack automatically processing the reply (either by treating it as addressed to an existing IP address or attempting to forward it).
Doing this sort of this is not as simple as you think. Controlling the data above the IP layer is relatively easy using normal socket APIs, but controlling data below is a bit more involved. Most operating systems make changing lower-level protocol information difficult since the kernel itself manages network connections and doesn't want you messing things up. Beyond that, there are other platform differences, network controls, etc that can play havoc on you.
You should look into some of the libraries that are out there to do this. Some examples:
libnet - http://libnet.sourceforge.net/
libdnet - http://libdnet.sourceforge.net/
If your goal is to spoof packets, you should read up on network-based spoofing mitigation techniques too (for example egress filtering to prevent spoofed packets from exiting a network).

Neighbor discovery C

I need to discover all network neighbors in Linux(they are running Linux too) and I need to get theirs IP addresses(3rd layer). Any ideas how to do that?
Btw, I need to do that in C, not in shell
Many thanks in advance!
What you should do is, have the neighbours run a daemon which responds (with a unicast response to the sender) to UDP multicasts.
Then send a UDP multicast with a TTL of 1 (so it will not be routed) and listen to see who responds. You will only receive responses from the neighbours which are running the agent.
Another possibility is to use an existing protocol which already does this, for example, mDNS.
There is no guaranteed way to do this if the machines in question aren't co-operating.
The best you can do is to scan likely addresses and probe each one to see if you can get a response - that probe could be anything from a simple ICMP echo request (a ping) up to a sophisticated malformed packet that attempts to elicit a response from the remote host.
The level of sophistication required, and whether it will work at all, depends entirely on how heavily firewalled etc the host in question is.
As a commenter has already observed, there are entire programs like nmap dedicated to attempting to discover this information, which gives some idea of how non-trivial this can be.
At the other extreme, if the hosts are co-operating, then a simple broadcast ICMP echo request might be enough.
If your segment uses reasonably decent switch, you can discover the link-layer neighbours by inspecting the forwarding database of one of the switches. You should be able to obtain this fairly automatically via SNMP, check your switch's documentation.
Once you have a list of link neighbours, you can try and find out their IP addresses, but remember that they may have many or none at all. For this you'd need some sort of reverse-ARP. Perhaps your router maintains a list of MAC-to-IP associations and you can query it (again SNMP would be the most convenient solution).

Resources