Extract MAC addresses from ARP packets
PATCH 1/1 Extract MAC addresses from ARP packets
From: "Vladimir V. Kamarzin" <[email protected]...>
When working in TAP mode, openvpn at server side maintains mapping table "MAC" -> "client". It needs to know what MAC belongs to what client to be able to forward traffic.
Before this change extraction of MAC addresses was performed only from ethernet headers of packets, coming from the client. This patch introduces extraction from ARP packets.
Why extraction only from ethernet header may be not enought? Obviously in such cases, when MAC in ethernet header differs from ARP message "Sender Hardware Address" field. For example, one device (A) performs handling of ARP traffic for other device (B) on the client side (C) connected to server (S) via TAP (server bridge mode). Unless (B) send some traffic to server-side network, it will be inaccessible because ARP handling performed by (A) and not (B) itself.
--- src/openvpn/mroute.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)
src/openvpn/mroute.c +20 -1
@@ -226,7 +226,26 @@ mroute_extract_addr_ether (struct mroute_addr *src, src->type =MR_ADDR_ETHER ; src->netbits =0 ; src->len =6 ; -memcpy (src->addr, eth->source,6 ); +struct buffer b = *buf; +if (buf_advance (&b,sizeof (struct openvpn_ethhdr ))) + { +if (ntohs (eth->proto) ==OPENVPN_ETH_P_ARP + &&BLEN (&b) >= (int )sizeof (struct openvpn_arp )) + { +const struct openvpn_arp *arp = (const struct openvpn_arp *)BPTR (&b); +if (arp->mac_addr_type ==htons (0x0001 ) + && arp->proto_addr_type ==htons (0x0800 ) + && arp->mac_addr_size ==0x06 + && arp->proto_addr_size ==0x04 ) + { +memcpy (src->addr, arp->mac_src,6 ); + } + } +else + { +memcpy (src->addr, eth->source,6 ); + } + } }if (dest) {
Signature · 1 line
1.8.3.2
Tested on versions 2.2 and 2.3, patch applies to git master branch. I'm not sure this functionality should be wrapped with #ifdef.
Waiting for comments and your opinion regarding this change.
Hi,
Quoted 9 lines · Vladimir V. Kamarzin
From: "Vladimir V. Kamarzin" <[email protected]...>
When working in TAP mode, openvpn at server side maintains mapping table "MAC" -> "client". It needs to know what MAC belongs to what client to be able to forward traffic.
Before this change extraction of MAC addresses was performed only from ethernet headers of packets, coming from the client. This patch introduces extraction from ARP packets.
Feature-NAK from me. If you want to play ARP tricks on the client side, do it right - keep the ethernet source, or change ethernet source and ARP source, not change the ethernet source but forward ARP packet unchanged.
There is too much special case code already that nobody is able to maintain and properly test(!) for future builds, wo do not want to add more.
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...Am 04.03.14 11:37, schrieb Vladimir V. Kamarzin:
Quoted 10 lines
From: "Vladimir V. Kamarzin" <[email protected]...>
When working in TAP mode, openvpn at server side maintains mapping table "MAC" -> "client". It needs to know what MAC belongs to what client to be able to forward traffic.
Before this change extraction of MAC addresses was performed only from ethernet headers of packets, coming from the client. This patch introduces extraction from ARP packets.
Quoted 9 lines
Why extraction only from ethernet header may be not enought? Obviously in such cases, when MAC in ethernet header differs from ARP message "Sender Hardware Address" field. For example, one device (A) performs handling of ARP traffic for other device (B) on the client side (C) connected to server (S) via TAP (server bridge mode). Unless (B) send some traffic to server-side network, it will be inaccessible because ARP handling performed by (A) and not (B) itself.
OpenVPN basically just emulates a learning switch. Learning switches also don't need these special logic. If your setup does not work with OpenVPN then either
a) it won't work with a learning switch either or
b) OpenVPN learning switch implementation has a bug
I would like to have either a) confirmed or b) fixed than to included a band aid.
Arne
Hi,
Quoted 5 lines · Arne Schwabe
a) it won't work with a learning switch either or
b) OpenVPN learning switch implementation has a bugI would like to have either a) confirmed or b) fixed than to included a band aid.
It looks like some sort of proxy-ARP where the ARP is *forwarded* instead of being *bridged* (= new ethernet frame, unchanged payload).
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...05.03.2014, 02:49, "Arne Schwabe" <[email protected]...>:
Quoted 9 lines
OpenVPN basically just emulates a learning switch. Learning switches also don't need these special logic. If your setup does not work with OpenVPN then either
a) it won't work with a learning switch either or
b) OpenVPN learning switch implementation has a bugI would like to have either a) confirmed or b) fixed than to included a band aid.
My setup does work with learning switches (tested before openvpn). So it looks like openvpn behavior not 100% the same.
Example setup contains following:
- S: switch
- A: generic network host, 192.168.0.1/24
- B: special device which provides access to C, 192.168.0.2/24 and MAC 00:00:00:11:11:11
- C: special device that we want access, 192.168.0.3/24, MAC 00:00:00:22:22:22
Plug scheme: (A) and (B) are plugged to (S). (C) is plugged to (B). ARP handling for (B) is performed by (C).
Here is step-by-step scheme how it works:
1. (A) wants to "ping" (C). So it sends ARP request "who has 192.168.0.3 tell 192.168.0.1" with broadcast destination in ethernet frame. Switch forwards this packet to all ports.
2. (B) receives ARP request and generates reply: "192.168.0.3 is at 00:00:00:22:22:22". Although MAC in ethernet header is 00:00:00:11:11:11!
3. Switch (S) see this reply and learns 00:00:00:11:11:11 to it MAC address table. (A) see this reply and add entry to ARP cache: 192.168.0.3 -> 00:00:00:22:22:22
4. (A) sends unicast packet (ICMP echo request) to 192.168.0.3, with ethernet destination address 00:00:00:22:22:22
5. Switch (S) does not know where is 00:00:00:22:22:22, so it sends this packet to all ports
6. (C) receives ICMP echo request and generates ICMP echo reply. Ethernet header now contains 00:00:00:22:22:22.
7. Switch see frame with src 00:00:00:22:22:22 and learns it. All happy, traffic passes.
In openvpn case, it looks like there is no step 5, so probably it is a bug. So I better should fix this instead of doing tricks with ARP.
Hi,
Quoted 1 line · Vladimir Kamarzin
5. Switch (S) does not know where is 00:00:00:22:22:22, so it sends this packet to all ports
Yeah, I think that's the difference. We don't do unicast flooding ("send frames to unknown unicast destinations to every single port") because bandwidth on the VPN is limited & more expensive.
Adding it would solve the issue at hand, but I'm not convinced that you'll be happy with the end - it might actually end up saturating VPN links and making users unhappy if you have "much flooded traffic" (which happens in some of the networks).
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...Quoted 4 lines
Adding it would solve the issue at hand, but I'm not convinced that you'll be happy with the end - it might actually end up saturating VPN links and making users unhappy if you have "much flooded traffic" (which happens in some of the networks).
I've patched openvpn this way and testing this setup right now, it working well for now. I think it may be implemented as an option (config or ifdef). What do you think?
Hi,
Quoted 8 lines · Vladimir Kamarzin
Quoted 4 lines
Adding it would solve the issue at hand, but I'm not convinced that you'll be happy with the end - it might actually end up saturating VPN links and making users unhappy if you have "much flooded traffic" (which happens in some of the networks).
I've patched openvpn this way and testing this setup right now, it working well for now. I think it may be implemented as an option (config or ifdef). What do you think?
I'm torn.
We do not want more options, we really have enough - but that *should* be configurable, and not the default, so if we integrate it, it needs to have an option ("tap-flood-unknown-unicast" or something like that).
So on the feature itself, if it has an option, I'd stay neutral in regards to ACK/NAKing, and focus on the code review.
gert
Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
//www.muc.de/~gert/
Gert Doering - Munich, Germany [email protected]...
fax: +49-89-35655025 [email protected]...