#include "slirp.h"
#include "hw/hw.h"
-/* host address */
-struct in_addr our_addr;
-/* host dns address */
-struct in_addr dns_addr;
/* host loopback address */
struct in_addr loopback_addr;
static u_int time_fasttimo, last_slowtimo;
static int do_slowtimo;
-static TAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
- TAILQ_HEAD_INITIALIZER(slirp_instances);
+static QTAILQ_HEAD(slirp_instances, Slirp) slirp_instances =
+ QTAILQ_HEAD_INITIALIZER(slirp_instances);
+
+static struct in_addr dns_addr;
+static u_int dns_addr_time;
#ifdef _WIN32
-static int get_dns_addr(struct in_addr *pdns_addr)
+int get_dns_addr(struct in_addr *pdns_addr)
{
FIXED_INFO *FixedInfo=NULL;
ULONG BufLen;
IP_ADDR_STRING *pIPAddr;
struct in_addr tmp_addr;
+ if (dns_addr.s_addr != 0 && (curtime - dns_addr_time) < 1000) {
+ *pdns_addr = dns_addr;
+ return 0;
+ }
+
FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, sizeof(FIXED_INFO));
BufLen = sizeof(FIXED_INFO);
pIPAddr = &(FixedInfo->DnsServerList);
inet_aton(pIPAddr->IpAddress.String, &tmp_addr);
*pdns_addr = tmp_addr;
+ dns_addr = tmp_addr;
+ dns_addr_time = curtime;
if (FixedInfo) {
GlobalFree(FixedInfo);
FixedInfo = NULL;
#else
-static int get_dns_addr(struct in_addr *pdns_addr)
+static struct stat dns_addr_stat;
+
+int get_dns_addr(struct in_addr *pdns_addr)
{
char buff[512];
char buff2[257];
int found = 0;
struct in_addr tmp_addr;
+ if (dns_addr.s_addr != 0) {
+ struct stat old_stat;
+ if ((curtime - dns_addr_time) < 1000) {
+ *pdns_addr = dns_addr;
+ return 0;
+ }
+ old_stat = dns_addr_stat;
+ if (stat("/etc/resolv.conf", &dns_addr_stat) != 0)
+ return -1;
+ if ((dns_addr_stat.st_dev == old_stat.st_dev)
+ && (dns_addr_stat.st_ino == old_stat.st_ino)
+ && (dns_addr_stat.st_size == old_stat.st_size)
+ && (dns_addr_stat.st_mtime == old_stat.st_mtime)) {
+ *pdns_addr = dns_addr;
+ return 0;
+ }
+ }
+
f = fopen("/etc/resolv.conf", "r");
if (!f)
return -1;
if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
if (!inet_aton(buff2, &tmp_addr))
continue;
- if (tmp_addr.s_addr == loopback_addr.s_addr)
- tmp_addr = our_addr;
/* If it's the first one, set it to dns_addr */
- if (!found)
+ if (!found) {
*pdns_addr = tmp_addr;
+ dns_addr = tmp_addr;
+ dns_addr_time = curtime;
+ }
#ifdef DEBUG
else
lprint(", ");
static void slirp_init_once(void)
{
static int initialized;
- struct hostent *he;
- char our_name[256];
#ifdef _WIN32
WSADATA Data;
#endif
#endif
loopback_addr.s_addr = htonl(INADDR_LOOPBACK);
-
- /* FIXME: This address may change during runtime */
- if (gethostname(our_name, sizeof(our_name)) == 0) {
- he = gethostbyname(our_name);
- if (he) {
- our_addr = *(struct in_addr *)he->h_addr;
- }
- }
- if (our_addr.s_addr == 0) {
- our_addr = loopback_addr;
- }
-
- /* FIXME: This address may change during runtime */
- if (get_dns_addr(&dns_addr) < 0) {
- dns_addr = loopback_addr;
- }
}
static void slirp_state_save(QEMUFile *f, void *opaque);
slirp->opaque = opaque;
- register_savevm("slirp", 0, 3, slirp_state_save, slirp_state_load, slirp);
+ register_savevm(NULL, "slirp", 0, 3,
+ slirp_state_save, slirp_state_load, slirp);
- TAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
+ QTAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);
return slirp;
}
void slirp_cleanup(Slirp *slirp)
{
- TAILQ_REMOVE(&slirp_instances, slirp, entry);
+ QTAILQ_REMOVE(&slirp_instances, slirp, entry);
- unregister_savevm("slirp", slirp);
+ unregister_savevm(NULL, "slirp", slirp);
qemu_free(slirp->tftp_prefix);
qemu_free(slirp->bootp_filename);
struct socket *so, *so_next;
int nfds;
- if (TAILQ_EMPTY(&slirp_instances)) {
+ if (QTAILQ_EMPTY(&slirp_instances)) {
return;
}
*/
do_slowtimo = 0;
- TAILQ_FOREACH(slirp, &slirp_instances, entry) {
+ QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
/*
* *_slowtimo needs calling if there are IP fragments
* in the fragment queue, or there are TCP connections active
struct socket *so, *so_next;
int ret;
- if (TAILQ_EMPTY(&slirp_instances)) {
+ if (QTAILQ_EMPTY(&slirp_instances)) {
return;
}
curtime = qemu_get_clock(rt_clock);
- TAILQ_FOREACH(slirp, &slirp_instances, entry) {
+ QTAILQ_FOREACH(slirp, &slirp_instances, entry) {
/*
* See if anything has timed out
*/
{
struct ethhdr *eh = (struct ethhdr *)pkt;
struct arphdr *ah = (struct arphdr *)(pkt + ETH_HLEN);
- uint8_t arp_reply[ETH_HLEN + sizeof(struct arphdr)];
+ uint8_t arp_reply[max(ETH_HLEN + sizeof(struct arphdr), 64)];
struct ethhdr *reh = (struct ethhdr *)arp_reply;
struct arphdr *rah = (struct arphdr *)(arp_reply + ETH_HLEN);
int ar_op;
}
return;
arp_ok:
+ memset(arp_reply, 0, sizeof(arp_reply));
/* XXX: make an ARP request to have the client address */
memcpy(slirp->client_ethaddr, eh->h_source, ETH_ALEN);
{
Slirp *slirp = opaque;
struct ex_list *ex_ptr;
- int r;
- while ((r = qemu_get_byte(f))) {
+ while (qemu_get_byte(f)) {
int ret;
struct socket *so = socreate(slirp);