I know this is what 99.99% of people hope I never do, but let’s make an incredibly insecure VPN! yay!
Motivation
So the thing is that I have a cisco router and I’d love for it to connect to some Windows machine over an existing OpenVPN, and NAT out the Windows side. Â Except for getting the VPN installed, they won’t give me anything else. Â And they SURE as heck won’t let me connect a cisco router up…..
So first things first, I need to configure my cisco router for an IPIP tunnel, to my test Windows machine, and use the SLiRP default addresses:
interface Tunnel0
description “SLiRP tunnel”
ip address 10.0.2.15 255.255.255.0
ip mtu 1452
tunnel source GigabitEthernet0/1
tunnel destination 192.168.1.10
tunnel mode ipip
end
Now to start programming.
Well then I went looking and found this fun filled page, about calling winioctl’s myself, and getting winsock to do all kinds of fun things. Â Namely how IPIP actually works, as it’s is it’s own protocol (none of that pesky TCP/UDP it’s IPIP!) and more importantly I can receive the traffic.
So looking at a quick UDP client/server I figured out that I can modify that so instead of listening with UDP like this:
if((s = socket(AF_INET , SOCK_DGRAM , 0 )) == INVALID_SOCKET)
I can instead call for a RAW socket, and listen on protocol #4 aka IPIP.
if((s = socket(AF_INET , SOCK_RAW , 4 )) == INVALID_SOCKET)
One caveat I had on this, is that you need to run as Administrator on the Windows machine to create raw sockets. Â If you don’t have administrator privleges you’ll get this error:
Could not create socket : 10013socket() failed with error code : 10013
Now add in some nonblocking, and feed the data into SLiRP, and I got invalid data! Â Using wireshark I can see that I only receive the IP portion of the data, so no hardware frame, but what is more interesting is that I receive ALL of the IP information so I get the IP+IP+DATA. Â So I have to forge a L2 header, and cut out the first IP header. Â I did this by cheating, using the following for a L2 header:
0x44,0x8a,0x5b,0x62,0xcb,0xaf,0x00,0x1b,0x90,0x21,0x58,0x1b,0x08,0x00
I then just memcpy that to the start of my buffer, then copy in the rest of the received data like this:
memcpy(buf2+14,buf+20,recv_len-20);
And now I can forge data going to SLiRP to make it happy!
And sending replies didn’t make wireshark happy at all, as there is an L2 header in there, that just doesn’t make sense in L3 space, so I trimmed that with the following:
memcpy(buf,qp->data+14,qp->len-14);
Putting it all together
And now much to my amazement I can ping SLiRP from my 7206!
Ok, I know what you are thinking. ICMP is great, but how about TCP? Â Can I actually use this thing?
I add a route to my BBS over the SLiRP tunnel, with a simple route statement:
ip route 172.86.181.35 255.255.255.255 10.0.2.2
and then telnet…
So yes, it does actually work!\
I don’t think anyone will ever want to use this, but for me it’s 100% novelty in that I could.
Executable & source code is here, ipip.7z.
I suppose later I could look at ipdecap, to work out how to work with GRE.