From: Fabrice Bellard <fabrice@bellard.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [5498] allow SLIRP to make an ARP request to get the client MAC address.
Date: Fri, 17 Oct 2008 17:28:59 +0000 [thread overview]
Message-ID: <E1Kqt8F-0004ZU-QT@cvs.savannah.gnu.org> (raw)
Revision: 5498
http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=5498
Author: bellard
Date: 2008-10-17 17:28:58 +0000 (Fri, 17 Oct 2008)
Log Message:
-----------
allow SLIRP to make an ARP request to get the client MAC address. It is useful if an inbound connection is done to a VM which did not send outbound IP packets
Modified Paths:
--------------
trunk/slirp/slirp.c
Modified: trunk/slirp/slirp.c
===================================================================
--- trunk/slirp/slirp.c 2008-10-17 08:08:56 UTC (rev 5497)
+++ trunk/slirp/slirp.c 2008-10-17 17:28:58 UTC (rev 5498)
@@ -16,8 +16,12 @@
0x52, 0x54, 0x00, 0x12, 0x35, 0x00
};
+/* ARP cache for the guest IP addresses (XXX: allow many entries) */
uint8_t client_ethaddr[6];
+static struct in_addr client_ipaddr;
+static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
+
int do_slowtimo;
int link_up;
struct timeval tt;
@@ -597,6 +601,13 @@
slirp_output(arp_reply, sizeof(arp_reply));
}
break;
+ case ARPOP_REPLY:
+ /* reply to request of client mac address ? */
+ if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN) &&
+ !memcmp(ah->ar_sip, &client_ipaddr.s_addr, 4)) {
+ memcpy(client_ethaddr, ah->ar_sha, ETH_ALEN);
+ }
+ break;
default:
break;
}
@@ -641,14 +652,47 @@
if (ip_data_len + ETH_HLEN > sizeof(buf))
return;
+
+ if (!memcmp(client_ethaddr, zero_ethaddr, ETH_ALEN)) {
+ uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)];
+ struct ethhdr *reh = (struct ethhdr *)arp_req;
+ struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN);
+ const struct ip *iph = (const struct ip *)ip_data;
- memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
- memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
- /* XXX: not correct */
- eh->h_source[5] = CTL_ALIAS;
- eh->h_proto = htons(ETH_P_IP);
- memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
- slirp_output(buf, ip_data_len + ETH_HLEN);
+ /* If the client addr is not known, there is no point in
+ sending the packet to it. Normally the sender should have
+ done an ARP request to get its MAC address. Here we do it
+ in place of sending the packet and we hope that the sender
+ will retry sending its packet. */
+ memset(reh->h_dest, 0xff, ETH_ALEN);
+ memcpy(reh->h_source, special_ethaddr, ETH_ALEN - 1);
+ reh->h_source[5] = CTL_ALIAS;
+ reh->h_proto = htons(ETH_P_ARP);
+ rah->ar_hrd = htons(1);
+ rah->ar_pro = htons(ETH_P_IP);
+ rah->ar_hln = ETH_ALEN;
+ rah->ar_pln = 4;
+ rah->ar_op = htons(ARPOP_REQUEST);
+ /* source hw addr */
+ memcpy(rah->ar_sha, special_ethaddr, ETH_ALEN - 1);
+ rah->ar_sha[5] = CTL_ALIAS;
+ /* source IP */
+ memcpy(rah->ar_sip, &alias_addr, 4);
+ /* target hw addr (none) */
+ memset(rah->ar_tha, 0, ETH_ALEN);
+ /* target IP */
+ memcpy(rah->ar_tip, &iph->ip_dst, 4);
+ client_ipaddr = iph->ip_dst;
+ slirp_output(arp_req, sizeof(arp_req));
+ } else {
+ memcpy(eh->h_dest, client_ethaddr, ETH_ALEN);
+ memcpy(eh->h_source, special_ethaddr, ETH_ALEN - 1);
+ /* XXX: not correct */
+ eh->h_source[5] = CTL_ALIAS;
+ eh->h_proto = htons(ETH_P_IP);
+ memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
+ slirp_output(buf, ip_data_len + ETH_HLEN);
+ }
}
int slirp_redir(int is_udp, int host_port,
reply other threads:[~2008-10-17 17:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=E1Kqt8F-0004ZU-QT@cvs.savannah.gnu.org \
--to=fabrice@bellard.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).