diff options
author | Fabien Chouteau <chouteau@adacore.com> | 2011-08-03 12:52:54 +0200 |
---|---|---|
committer | Jan Kiszka <jan.kiszka@siemens.com> | 2011-08-03 12:57:06 +0200 |
commit | 1a0ca1e1f6011a8623ec0653a1b35bbfc3f576c9 (patch) | |
tree | 1a65c353785ecb37b6444403dfd07fca535d5b55 /slirp/bootp.c | |
parent | bafc72ab01cd5a058f1d07d1bb80ae0b27ff190a (diff) | |
download | qemu-1a0ca1e1f6011a8623ec0653a1b35bbfc3f576c9.tar.gz qemu-1a0ca1e1f6011a8623ec0653a1b35bbfc3f576c9.tar.bz2 qemu-1a0ca1e1f6011a8623ec0653a1b35bbfc3f576c9.zip |
Simple ARP table
This patch adds a simple ARP table in Slirp and also adds handling of
gratuitous ARP requests.
Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Diffstat (limited to 'slirp/bootp.c')
-rw-r--r-- | slirp/bootp.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/slirp/bootp.c b/slirp/bootp.c index 1eb2ed1143..efd1fe777a 100644 --- a/slirp/bootp.c +++ b/slirp/bootp.c @@ -149,6 +149,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) struct in_addr preq_addr; int dhcp_msg_type, val; uint8_t *q; + uint8_t client_ethaddr[ETH_ALEN]; /* extract exact DHCP msg type */ dhcp_decode(bp, &dhcp_msg_type, &preq_addr); @@ -164,8 +165,9 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) if (dhcp_msg_type != DHCPDISCOVER && dhcp_msg_type != DHCPREQUEST) return; - /* XXX: this is a hack to get the client mac address */ - memcpy(slirp->client_ethaddr, bp->bp_hwaddr, 6); + + /* Get client's hardware address from bootp request */ + memcpy(client_ethaddr, bp->bp_hwaddr, ETH_ALEN); m = m_get(slirp); if (!m) { @@ -178,25 +180,25 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) if (dhcp_msg_type == DHCPDISCOVER) { if (preq_addr.s_addr != htonl(0L)) { - bc = request_addr(slirp, &preq_addr, slirp->client_ethaddr); + bc = request_addr(slirp, &preq_addr, client_ethaddr); if (bc) { daddr.sin_addr = preq_addr; } } if (!bc) { new_addr: - bc = get_new_addr(slirp, &daddr.sin_addr, slirp->client_ethaddr); + bc = get_new_addr(slirp, &daddr.sin_addr, client_ethaddr); if (!bc) { DPRINTF("no address left\n"); return; } } - memcpy(bc->macaddr, slirp->client_ethaddr, 6); + memcpy(bc->macaddr, client_ethaddr, ETH_ALEN); } else if (preq_addr.s_addr != htonl(0L)) { - bc = request_addr(slirp, &preq_addr, slirp->client_ethaddr); + bc = request_addr(slirp, &preq_addr, client_ethaddr); if (bc) { daddr.sin_addr = preq_addr; - memcpy(bc->macaddr, slirp->client_ethaddr, 6); + memcpy(bc->macaddr, client_ethaddr, ETH_ALEN); } else { daddr.sin_addr.s_addr = 0; } @@ -209,6 +211,9 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) } } + /* Update ARP table for this IP address */ + arp_table_add(slirp, daddr.sin_addr.s_addr, client_ethaddr); + saddr.sin_addr = slirp->vhost_addr; saddr.sin_port = htons(BOOTP_SERVER); @@ -218,7 +223,7 @@ static void bootp_reply(Slirp *slirp, const struct bootp_t *bp) rbp->bp_xid = bp->bp_xid; rbp->bp_htype = 1; rbp->bp_hlen = 6; - memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6); + memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, ETH_ALEN); rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */ rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */ |