I'd like to ask you a question about tun interfaces, but without OpenVPN.
I have two applications that tunnel traffic:
"sgsn userspace app" reads IP packets from the tun interface "tun sgsn", sends them to "ggsn userspace app", this app writes them to "tun ggsn".
It works the other way too, so I can have a working ssh session, copy files, etc.
So, the packets go this way:
scp client --> sgsn tun interface ---> tunneling through my app -----> ggsn tun interface (dropped here) ----------> sshd
Now, I've tried it with IPv4 and it works, but when I switch to IPv6 the IP packet is written to "tun ggsn" and the IP stack discards it. I've seen it with dropwatch, which says the discard is in ip_rcv+c0.
The routes must be correct because otherwise the packet wouldn't have made it into tun_sgsn in the first place.
I've tried this in both CentOS 6.7 and 7.1 with same result. However, in the 7.1 I only have a single host, so I've done a few tricks with ip6tables to NAT addresses, so the traffic from each user space app (scp and sshd) goes through the tun interfaces. I'm saying this just so it's clear from the beginning, but with the 6.7 I have two machines and no NAT (I'm aware that NAT doesn't work in CentOS 6.7 for IPv6). I've used tcpdump in the tun ggsn interface and the IPv6 datagram seems all right.
Another hint: If I scp to the tun_ggsn interface directly, it works, but I don't think this discards anything with the tun driver, since being in the same machine that means the IP packets don't go down the TCP/IP stack to reach the tun driver (in fact, tcpdump does not capture the packet if I do this).
Any help would be appreciated, thank you very much in advance.
Related
For the sake of simplicity, I will refer you to http://en.wikipedia.org/wiki/Berkeley_sockets and the UDP server and client source code there.
I am trying to send a packet using UDP protocol to a linux VirtualMachine server program. Both my host and VM ping well; all packets sent are received in both directions. However my server program is either not receiving any packets, or it is simply not printing. Either way, it isn't printing the confirmation or contents of any packets I send to it from the host.
I do not have another PC handy, but both programs communicate well enough if I stage them on the same computer and Wireshark reports that the packets are being sent.
Mine is a three part question: first, how can I fix this. Second, why would the host and VM receive each others ping messages, but not pass these on to the open sockets of both ends of my UDP system? Finally, do you have any suggestions about the form or intent of this question?
EDIT: I've tried running my VM with the NAT and bridged adapter network setups. However, I can't conceptualize the relationship between those setups and my problems right now.
With NAT networking, the VM gets a private IP address (usually 192.168.x.y) and the host does NAT translation of outgoing packets, and translates reply packets back to the VM. In this mode, all communication must be initiated by the VM -- outside machines can only send packets to the VM in reply to packets the VM sent to them. On the network, the packets will look like they're coming from/going to the host on some unrelated port.
With bridged networking, the VM gets a device that connects directly to the host's network device. In this mode, the VM appears as a separate machine on the same network LAN as the host, with its own IP address. You need to allocate an IP address for it, the same as the host get allocated an IP address (usually via DHCP).
In either case, to debug what is going on, use tcpdump/wireshark on the host to monitor the host's network device. Send packets from the VM, and you should see them in the trace -- they'll appear to come from the host and a different port in the NAT case, and will appear to come from the VM's IP address (and unchanged ports) in the bridged case.
Once you see that, you should be able to send packets back to the VM, though in the NAT case, they must come FROM the address/port the original packet(s) were sent to.
There are known issues with VirtualBox bridged networking not working properly on wifi devices; in general you can only use bridged networking with wired networks.
Oracles VB manual page clear all the terminology used in settings.
I've had similar problem, where my VB program didn't receive any packets, which I solved by setting "Bridged Networking" and setting up proper source/destination IP address in my program by analyzing WLAN interface with wireshark and using ifconfig (or ipconfig) in terminal.
I wrote a bridge (layer 2 switch) using my Boost.Asio extension. We can easily make additional sockets, endpoints and protocols which meet their type requirements. And my extension uses linux packet socket with AF_PACKET, SOCK_RAW and htons(ETH_P_ALL) (See man 7 packet for more information about packet socket).
Here's an example for explaining how my bridge works:
[PC1] <----> IF1[PC2]IF2 <----> [PC3]
Bridge connects the network interfaces(e.g. eth0) IF1 and IF2 so PC1 can communicate with PC3 via bridge running on PC2. The way to connect interfaces is sending packets received from IF1 to IF2 (and vice versa)
My bridge works under the wired connections as expected, but it doesn't work under the wireless connections. So I tried to find what causes this problem and I found that ARP request never succeeded.
The actual environment which causes this problem is:
[PC1] <--wired--> eth0[PC2]wlan0 <--wireless(802.11g)--> [router1]
Under the environment above, for example, now PC1 tries to send ping(ICMP) packet to router1. To send it to PC3, PC1 has to know the MAC address of router1 so PC1 sends ARP request to FF:FF:FF:FF:FF:FF And my bridge running on PC2 receives it from eth0 and send it to wlan0, but router1 never sends arp reply to PC1.
note: SOCK_RAW packets are passed to and from the device driver without any changes in the packet data. (quoted from man page of packet)
What should I do to allow PC1 to communicate with router1?
Thank you.
Edit:
Here is my Boost.Asio extension.
github: pfpacket/libarex
And this is my bridge using above.
libarex/example/layer2_switch/interface_bridge.cpp
I'm writing up what we discussed in the comments.
It is a common problem that wireless bridging is problematic (under linux at least, I don't know for others). Investigation has shown that most probably the wireless driver or chipset of the hardware used as bridge is incapable of doing bridging operations (brctl failing supports this assumption).
Other possible reasons, as explained in the link above, may be the AP dropping packets with unassociated MAC adresses or the likes.
Additionally, the code works fine for wired interfaces, so it is a hardware problem on some layer. Not much more to say about it.
I am developing an application that filters and mangles packets using netfilter queue's. It's rather complicated and needs to perform well so I would like to automate some rigorous testing. To do this I need to be to be able to route some TCP connections through my system, however, I don't want to have to rely on two other machines to act as client and server. I would prefer to run a local client that sends data and a local server that checks the mangled result.
The problem is that my application needs to intercept packets at the PREROUTING stage and so packets generated by the local client can't just be routed to the loopback interface.
So I need some way to inject packets before the prerouting stage and intercept them back after postrouting. If I could somehow use stream sockets to send and receive the data that would be great!
The most straightforward way I can think of doing this is to use a tun device. The tun device allows you to inject packets from userspace that appear to arrive through the tun interface. You could either write code to create and manipulate the tun interface yourself, or you can make use of an application like OpenVPN that already does this. With OpenVPN it would be easy: no special raw sockets or anything: you just send it IP packets encapsulated in UDP and it will make them arrive through a tun interface.
I've been thinking a bit about this and using the tun devices my client and server test applications should be able to use plain linux sockets. I will explain how this can work by describing the path of a packet sent by the test client.
Prerequisites:
a) Two tun devices each providing access to a distinct subnetwork
b) routing table was set up to route traffic to the correct tun device
1) the client sends a packet to an address in the tun1 subnetwork
2) the app attached to tun1 (tun1app) will translate the dst address of the packet to an address in tun2 subnetwork and the source address to an address in the tun1 subnetwork different from the address of the tun1 interface
3) tun1app will send the modified packet back out
4) after routing tun2app will receive the packet and translate the destination address to the tun2 interface and the source address to an address in the tun2 network different from the interface address
5) tun2app will send it back out and the server will receive the packet assuming the destination port is the one the server is listening on
Packets from the server will follow the inverse path.
This seems like the core idea of a very useful tool. Does anyone know of a tool that is able to do this?
All connections from-and-to localhost itself do go over PREROUTING and POSTROUTING. Whoever tells something else is mistaken. (You can verify that with ip6tables -t raw -I OUTPUT -j TRACE, and you will see that it passes through OUTPUT-POSTROUTING-PREROUTING-INPUT when, for example, you ping6 ::1 yourself.)
I have two machines each with two valid network interfaces, an Ethernet interface eth0 and a tun/tap interface gr0. The goal is to start a TCP connection on machine A using interface gr0 but then have the responses (ACKs, etc) from machine B come back over the Ethernet interface, eth0. So, machine A sends out a SYN on gr0 and machine B receives the SYN on its own gr0 but then sends its SYN/ACK back through eth0. The tun/tap device is a GNU Radio wireless link and we just want the responses to come through the Ethernet.
What's the easiest way to accomplish this? I need to research more on TCP/IP, but I was initially thinking that source-spoofing outgoing packets would tell the receiver to respond to the spoofed address (which should get routed to eth0). This would involve routing the IPs from the tun/tap interfaces through gr0 and leave the other traffic to eth0.
We are using Linux and a Python solution would be preferable.
Thanks for looking!
You could add an additional address to the lo interface on each system and use these new addresses as the TCP connection endpoints. You can then use static routes to direct which path each machine takes to get to the other machine's lo address.
For example:
Machine A:
ip addr add 1.1.1.1/32 dev lo
ip route add 2.2.2.2/32 dev eth0 via <eth0 default gateway>
Machine B:
ip addr add 2.2.2.2/32 dev lo
ip route add 1.1.1.1/32 dev gr0
Then bind to 1.1.1.1 on machine A and connect to 2.2.2.2.
You may be interested in enabling logging of martian packets net.ipv4.conf.all.log_martians, and disable reverse path filtering net.ipv4.conf.<interface>.rp_filter on the affected interfaces.
This sysctl vars are accesible via the sysctl utility and/or the /proc filesystem.
I'm working with a cluster of about 40 nodes running Debian 4. Each node runs a daemon which sits and listens on a multicast IP.
I wrote some client software to send out a multicast over the LAN with a client computer on the same switch as the cluster, so that each node in the cluster would receive the packet and respond.
It works great, except when I run the client software on a computer that has both LAN and WAN interfaces. If there is a WAN interface, the multicast doesn't work. So obviously, I figure the multicast is incorrectly going over the WAN interface (eth0), rather than the LAN (eth1.) So, I use the SO_BINDTODEVICE socket option to force the multicast socket to use eth1, and all is well.
But I thought that the kernel's routing table should determine that the LAN (eth1) is obviously a lower cost destination for the multicast. Is there some reason I have to explicitly force the socket to use eth1? And, is there some way (perhaps an ioctl call) that I can have the application automatically determine if a particular interface is a LAN or WAN?
If you don't explicitly bind to an
interface, I believe Linux uses the
interface for the default unicast
route for multicast sending.
Linux needs a multicast route, if none exists you will get a EHOSTUNREACH or ENETUNREACH error. The LCM project documents this possible problem. The routing will be overridden if you use the socket option IP_MULTICAST_IF or IPV6_MULTICAST_IF. You are supposed be able to specify the interface via scope-id field in IPv6 addresses but not all platforms properly support it. As dameiss points out, Stevens' Unix Network Programming book covers these details, you can browse most of the chapter on multicast via Google Books for free.
If you don't explicitly bind to an interface, I believe Linux uses the interface for the default unicast route for multicast sending. So my guess is that your default route is via the WAN interface.
Richard Stevens' "Unix Network Programming, Vol. 1", chapter 17 (at least in the 3rd edition), has some good information and examples of how to enumerate the network interfaces.