EBTABLES. Type of packets "otherhost" - linux

I've got a question concerning ebtables.
The question is concerned with --pkttype-type option.
In description of this option (MAN) I see there are four possible values:
broadcast
multicast
host
otherhost (non of the above)
Please explain me what 4-th option otherhost means. As I know packet can be broadcast, multicast and unicast. Perhaps more packet types exist which I don't know? What happens when I use option --pkttype-type otherhost?

From man ebtables:
a) broadcast (MAC destination is the broadcast address)
b) multiā€cast (MAC destination is a multicast address)
c) host (MAC destination is the receiving network device) This is your MAC address.
d) otherhost (none of the above). MAC addresses of other devices.
What does otherhost mean?
For Ethernet networks, for example when using Ethernet hubs, data going to some computer (with its own MAC address) connected to the Ethernet hub may be seen by any other device (with different MAC address) connected to the same Ethernet hub. You can check this behaviour using wireshark or tcpdump. With Hubs, Ethernet frames going to your computer (MAC addres of your network device as destination) may be seen by any other computer using the same Hub as you.
By default, your network device will pass to your CPU the Ethernet frames that the controller is intended to receive (broadcast, multicast or with your MAC address as destination) even if it is receiving many others (case of using Ethernet hubs)
You can change the default behaviour of your network device by means of the promiscuous mode (wireshark and tcpdump make use of this configuration)
What happens when you use option --pkttype-type otherhost?
Data intended to be received by other devices will match the ebtables rule.

Related

I am working with vlan, I have to write a server which used vlan interface to accept the packet?

Hints about working with VLAN? I have to write a client-server program, where the client will send a packet through eth0 and the server will receive the packet on VLAN, and to send it to a concerned VLAN client should parse on which command line VLAN will receive it?
Usually there is nothing to do in the application to work with a VLAN. The VLAN is realized using a virtual network interface with its own IP address. From the perspective of the application this is not different from a real network interface with own IP address. The OS will take care about routing and encapsulation of packets and there is nothing to do from the application itself.

Programatically inject packets to virtual interface

We are currently developing a prototype aiming to "bridge" a local virtual interface in Linux to an API sending/receiving Ethernet packets using proprietary hardware. The idea is in the end to use standard libraries and tools transparently with this proprietary hardware.
As a first step ensuring that what we want to do is indeed possible, we made a first version of the prototype bridging a virtual interface to an actual Ethernet interface using libpcap. Here is what we did :
create a local dummy interface on PC1 with a MAC/IP address (192.168.0.1)
configure PC2 with an IP on the same network (192.168.0.2)
link PC1 and PC2 using a non-configured interface on PC1
use a simple 'bridge' program on PC1, developed with libpcap that listens on one interface and inject packets on the second one (using pcap_sendpacket), and the other way around, to bridge dummy interface and actual Ethernet interface
launch ping from PC1 to PC2
When spying on the dummy interface on PC1, we observe ICMP requests and responses, so the bridge program works OK, but the ping tool does not get the ICMP responses at application level.
I'm guessing we inject packets too late in the kernel routing process...or something.
Do you know how to do this properly? Maybe use an alternate type of virtual interface? (bridge, tun/tap...) It cannot be a full system/command line solution since in the end we want to bridge packets to a proprietary API and not to an Ethernet interface, so we need programmatic access to the packets (hence libpcap).
Thanks in advance for your help.
This is not possible with dummy module interfaces in Linux. They can only transmit packets 'downwards', from the kernel to the network hardware device. And, as in the case of dummy interfaces there is no hardware device, packets are discarded when they reach the bottom of this path (dummy_xmit function). You can treat it as a one-way sink.
Here is the call graph:
[applications]
[tcp/ip stack]
|
|
v
pcap_sendpacket -> tpacket_snd -> dev_queue_xmit -> dev_hard_start_xmit -> xmit_one -> netdev_start_xmit -> ndo_start_xmit -> dummy_xmit -> dev_kfree_skb
|
|
pcap_next <- tpacket_rcv <- prot_hook.func <- deliver_skb <-dev_queue_xmit_nit <-----
So, in your case, ping requests from ping application go into the device transmission path. They are discarded at the end of this path, but before that, they are copied and these copies are being passed into the pcap bridge listening on the interface. Bridge application forwards them to the PC2. PC2 answers ping requests and send responses back to the bridge application. The bridge application injects these responses into the device transmission path, they go downwards it and are discarded. But before that, they are copied to all pcap listeners, including tcpdump you use to spy and observe traffic, but excluding your bridge application which injected them:
++ net/core/dev.c
## void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
...
/* Never send packets back to the socket
* they originated from - MvS (miquels#drinkel.ow.org)
*/
if (skb_loop_sk(ptype, skb))
continue;
This is why you see both requests and responses. But responses are not being passed up to the kernel TCP/IP stack and ping application, because this is not possible with dummy interface. They are transmitted downwards to dummy_xmit and discarded.
Therefore, in your case, you should use either TAP interface, or, if you want to still use pcap to exchange packets, veth virtual links.

Multicast packets are not sent if I use an address different from 224.0.0.1

I am using this code to experiment with multicast.
I have wireshark running on another PC in the LAN and I am trying to see the packets sent over the network.
If packets are sent to the IP address 224.0.0.1 they are correctly received, if I send them to the address 239.255.255.250 they are not.
I have this entry in my routing table
224.0.0.0/4 dev eth0.100 src 192.0.0.1
I know 192.0.0.1 looks weird, but it is the correct interface address
Do you know why packets are not being sent?
The PC that you are attempting to capture the multicast traffic most likely has multicast filtering enabled and has not enabled reception of the 239.255.255.250 group.
Any host device that communicates multicast joins the 224.0.0.1 (All Hosts group) so packets sent to that group pass the filter, but not packets sent to 239.255.255.250.
Multicast filtering is usually implemented in the network interface and received frames that don't pass the filter will be dropped in hardware instead of being passed up to the Kernel driver. If the frames are not passed to the Kernel, then Wireshark can not capture them.
You can verify the active multicast groups per interface with netstat. I'm assuming you're on a Linux system since you tagged the question with "Linux"
netstat -g
Multicast groups are joined when a socket enables the IP_ADD_MEMBERSHIP socket option. In order to join the group on your capturing device, you'll need a program that creates a socket and joins the multicast group using the IP_ADD_MEMBERSHIP socket option
To add to Joel Cunningham's answer in the case of switched LAN:
There's nothing listening for multicast on 239.255.255.250, thus no IGMP joins are sent out. thus the switch does not propagate these multicast frames to the port where you have the wireshark(1)-running PC.
Again, 226.0.0.1 is well known and is always joined to by all hosts.

Cannot send or receive packets from my VirtualBox debian linux VM using UDP

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.

Linux bridge of my own making: arp request never succeeds

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.

Resources