How to drop packet before full download - c

I'm creating a personal app for network filtering using C. I already know that you can log and analyze a downloaded packet's info using this code:
tcpPacket = recvfrom(raw_socket , buffer , 65536 , 0 , &serverAddress , &serverAddressSize);
but this requires that the tcp packet be downloaded first. What I need is that the filter will be acted out even before it is downloaded, let's say it examines the source IP and based on that, it either accepts or rejects it.
Note: Yes I am aware of iptables, but I do not want to use it because I want to learn how to do it using raw sockets.

In a packet-oriented network (like TCP/IP is), the each packet contains both address information and actual payload.
So it doesn't make sense to say that you want to drop the packet before it's downloaded, based on data that is in the packet.
It would perhaps be imaginable if you could stop the actual (hardware) receiver mid-packet, but I don't think any "normal" networking hardware or APIs expose such functionality.

I've got what I needed now. I need to call getpeername(2) after accepting a connection http://man7.org/linux/man-pages/man2/getpeername.2.html.

Related

What's the easiest way to send 802.11 frames using C?

I'm a beginner to C, I've recently decided to make migrate this project to C from using Scapy/Python, solely because I want better performance. I wish to send layer 2 data, specifically beacon frames to advertise an access point.
So far I have found that I need to (or rather could) use libpcap and a Linux header called ieee80211.h that pre-defines packets, that's all I could gather from the other questions. I've found other information which says I should use raw sockets instead of libpcap? I'm not sure if this is all I need. Most of the information and tutorials I have found on Google refer to packet sniffing, not sending.
How do I define a custom frame and/or packet (e.g. a beacon frame or association request) and then simply send it to wlan0 etc.?
Thought I might update this. I used libpcap.
You just need to create a handle with your device, set it to monitor mode successfully (important), check the data link type (e.g. 802.11 with Radiotap for layer 2) then use pcap_sendpacket(handle, packetArrayContainingHex, size);. Hard part is forming legal packets that aren't rejected or dropped, taking a look in wireshark helps.
This link might help. It basically opens the driver at raw packet level and creates the whole packet to send over the wire, as your question suggests.

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).

NDIS Hook sendPacketsHandler

I use NdisRegisterProtocol() to register a protocol driver, and use _NDIS_OPEN_BLOCK and _NDIS_PROTOCOL_BLOCK structures to hook the ReceivePacketHandler successful, use MyRecivePacket() to instead of NDIS receive packet functions, when I open a website, MyRecievePacket() will be run.
My question is:
When I open a website(like www.stackoverflow.com) using IE, how can I hook the SendPacketsHandler to get this packet and get the url www.stackoverflow.com string. In other words, how to capture the url in kernel mode. thanks
That's not something you should normally do, URL data belongs to the application layer of network stack and shouldn't be accessed by the lower layers which reside in Kernel space. See more here on protocol driver layering inside Windows network architecture: http://msdn.microsoft.com/en-us/library/windows/hardware/ff571073(v=vs.85).aspx
However, it might be possible by removing the headers that where added to packets on the way down to your protocol driver by the protocols sitting on top of it, such as HTTP, TCP, IP etc. You need to know the exact protocols that where applied to your data packet on the way to your protocol driver. The headers are added incrementally, for each underlying layer the input from the above layer is an opaque block of data (which consists of the upper layer data and header). E.g., your packet may start as a pure data, to which HTTP header was added at start, TCP header after that, and IP header after that. You need to remove the headers in the opposite order to restore the original data.
Note, this is not always possible as the protocols on the way down may change the data, e.g. by encrypting it. In this case you won't be able to extract the original data with doing the reverse operation (such as decryption).
There are tools and techniques that called Deep Packet Inspection(DPI) which used to unpacked the transfered packet upon rich its application layer , there are libraries like openDPI which can be used even on kernel land to track the packets content.
When you can unpack the network packets up-to application layer then you can change its content. You should be award that its not easy to capture and unpack each packets which throw your NIC.
First of all, I have not really clear what you want to do... My main doubt:
¿are you registering a Protocol Driver, or hooking the ReceivePacketHandler of a previously existing driver? It's something really different.
I'll assume that your target is just to intercept URL's, not hooking an exising protocol driver. As #icepack comments, using a procol driver it's not 'the easy way' beacause you should track all TCP connections to extract HTTP stuff.
But, if it's mandatory for you to use NDIS, you should check the PassThru example[1] of the DDK, or the NDIS Filter driver [2] example, and implement the necessary logic to parse TCP protocol and HTTP headers.
If NDIS it's not mandatory there are easier techniques like using a TDI (deprecated but still functionally[3]) or a WFP driver [4] to intercept communications in a higher level than TCP stack.
[1] http://code.msdn.microsoft.com/windowshardware/NDISLWFSYS-Sample-NDIS-60-42b76875
[2] http://msdn.microsoft.com/en-us/library/windows/hardware/ff565501(v=vs.85).aspx
[3] http://technet.microsoft.com/en-us/library/cc939977.aspx
[4] http://msdn.microsoft.com/en-us/library/windows/hardware/gg463267.aspx

How do I block packets coming on port 23 on my computer?

I am using libpcap library. I have made one packet sniffer C program using pcap.h. Now I want to block packets coming on port 23 on my computer via eth0 device. I tried pcap_filter function but it is not useful for blocking.
Please explain to me how to code this functionality using c program.
Libpcap is just used for packet capturing, i.e. making packets available for use in other programs. It does not perform any network setup, like blocking, opening ports. In this sense pcap is a purely passive monitoring tool.
I am not sure what you want to do. As far as I see it, there are two possibilities:
You actually want to block the packets, so that your computer will not process them in any way. You should use a firewall for that and just block this port. Any decent firewall should be able to do that fairly easy. But you should be aware, that this also means no one will be able to ssh into your system. So if you do that on a remote system, you have effectively locked out yourself.
You still want other programs (sshd) to listen on port 23 but all this traffic is annoying you in your application. Libpcap has a filtering function for that, that is quite powerful. With this function you can pass small scripts to libpcap and have it only report packets that fit. Look up filtering in the pcap documentation for more information. This will however not "block the traffic" just stop pcap from capturing it.
Actually using pcap you are not able to build firewall. This is because packets seen inside your sniffer (built using pcap) are just copy of packets which (with or without sniffer) are consumed by network stack.
In other words: using filters in pcap will cause that you will not see copies of original packets (as far as I know pcap compiles filters and add those to kernel so that on kernel level copy will not be done); anyway original packet will go to network stack anyway.
The solution of your problem most probably could be done by netfilter. You can register in NF_IP_PRE_ROUTING hook and there decide to drop or allow given traffic.

Resources