6

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?

tshepang
  • 12,111
  • 21
  • 91
  • 136

2 Answers2

3

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

abligh
  • 24,573
  • 4
  • 47
  • 84
  • I'm on Linux and have root access, but how do you disable the network stack automatically processing the reply or make the packet skip it so it doesn't have to get its IP changed? –  Feb 09 '14 at 12:29
  • 1
    That's non-trivial. Probably the easiest route is to use an ip address not assigned to the system, and either do your own `arp` or set a manual arp entry. You may need to turn on ip forwarding then ask `iptables` to drop packets (`libpcap` should still pick them up) in the `FORWARD` chain to prevent it sending ICMP host unreachable. – abligh Feb 09 '14 at 12:34
  • If you absolutely must use the same IP address as the server's OS, the issue is finding which TCP ports are free - essentially you want two TCP stacks sharing the same IP. I've done this once by using NAT and a tunnel interface, so my connection comes from the remote end of a tunnel (i.e. user space) then masquerades (using NAT) as the real IP address. This is fiddly to get right. – abligh Feb 09 '14 at 12:36
  • True, but what if I wanted to insert a code were the sender's ip is in the packet, how do I do that? –  Feb 09 '14 at 12:49
  • You can send it out, but what the OS will do with the reply packet is the problem. See my second comment for how I got around this. If you are not using a protocol the OS is using or can persuade `iptables` to drop these packets on its `INPUT` chain, you won't have an issue. – abligh Feb 09 '14 at 12:55
  • I'm intending to actually put the receiver's IP has the receiver and sender's IP in the packet. Well use TCP has the protocol, wich is used by both the sender and receiver's OS. But will the OS try to block or stop this? –  Feb 09 '14 at 13:06
  • Yes it will (unless you stop it), because either the OS will see it as a TCP session it doesn't recognise (and probably send an `RST`), or it will see it as a TCP session it does recognise (as you have reused existing port tuples), in which case your sequence number will inevitably be wrong; what it does there 'depends' - probably ignores it. – abligh Feb 09 '14 at 13:16
  • ,thanks for the tips bro, but how do you get to send it and that your OS doesn't stop it or modifies it?Is it possible in c or do I have go into assembler? –  Feb 09 '14 at 13:21
  • Assembler won't help you. I think I've already told you how to do this. Persuade the OS to drop the incoming packet (you will still pick it up with `libpcap`) using `iptables`. I've told you how I used an entirely different technique and persuaded my app and the OS to share TCP port space using a tunnel (`tun` device) and using `iptables` to masquerade routed packets from the tunnel as the source IP of the box; in this method you read and write bytes from an FD which are the raw bytes of the IP packet. You write your packets as if they come from a dummy IP and the OS rewrites the source addr. – abligh Feb 09 '14 at 13:25
1

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:

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

jduck
  • 109
  • 3
  • Believe me I was prepared for it to be pretty complicated and thanks for the libraries but do you have anything else then libraries? –  Feb 09 '14 at 12:25
  • 1
    There are a lot of moving parts in doing this. The reason I recommend these libraries is because they deal with many of them for you. If you're interested in how they work, I recommend reading the source code. – jduck Feb 10 '14 at 19:57