From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HJMJq-0000bI-CK for qemu-devel@nongnu.org; Mon, 19 Feb 2007 23:09:34 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HJMJo-0000aV-T6 for qemu-devel@nongnu.org; Mon, 19 Feb 2007 23:09:33 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HJMJo-0000aN-Jh for qemu-devel@nongnu.org; Mon, 19 Feb 2007 23:09:32 -0500 Received: from nm01mta.dion.ne.jp ([211.5.2.79] helo=nm01omta01b.dion.ne.jp) by monty-python.gnu.org with smtp (Exim 4.52) id 1HJMJn-0000IK-GA for qemu-devel@nongnu.org; Mon, 19 Feb 2007 23:09:32 -0500 Message-ID: <001301c754a4$f10d5120$0464a8c0@athlon> From: "Kazu" Subject: [Qemu-devel][PATCH] Built-in DHCP server Date: Tue, 20 Feb 2007 13:09:39 +0900 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0010_01C754F0.60D14480" Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. ------=_NextPart_000_0010_01C754F0.60D14480 Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: 7bit Hi, After I used TAP device by -net nic -net tap,ifname=mytap and I tried to use user mode network by -net nic -net user, a Windows XP guest doesn't get IP address from a built-in DHCP server. It is fixed by an attached patch. DHCPRELEASE and DHCPNACK are introduced. DHCPRELEASE code is borrowed from VirtualBox. Windows 2000/XP tries to call DHCPREQUEST and get old IP address when it boots. I made a code to reply DHCPNACK to the request. Then the Win2k/XP called DHCPDISCOVER and try to get a new IP address. I tested Windows 98SE/2000/XP, Knoppix 3.8, Morphix, Fedora Core 3 and RedHat 7.2 guest. There is not problem except RH7.2. It can get IP address but it is 10.0.2.16. dhcpcd in RH7.2 tries to call DHCPDISCOVER two times. So it consumes two entries in the built-in DHCP server. It seems that it is a bug of dhcpcd in RH7.2. Regards, Kazu ------=_NextPart_000_0010_01C754F0.60D14480 Content-Type: application/octet-stream; name="qemu-20070220-dhcp.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="qemu-20070220-dhcp.patch" Index: slirp/bootp.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /sources/qemu/qemu/slirp/bootp.c,v=0A= retrieving revision 1.9=0A= diff -u -r1.9 bootp.c=0A= --- slirp/bootp.c 20 Feb 2007 00:05:08 -0000 1.9=0A= +++ slirp/bootp.c 20 Feb 2007 03:36:39 -0000=0A= @@ -66,6 +66,18 @@=0A= return bc;=0A= }=0A= =0A= +/* From VirtualBox */=0A= +static void release_addr(struct in_addr *paddr)=0A= +{=0A= + int i;=0A= +=0A= + i =3D ntohl(paddr->s_addr) - START_ADDR - = ntohl(special_addr.s_addr);=0A= + if (i >=3D NB_ADDR)=0A= + return;=0A= + memset(bootp_clients[i].macaddr, '\0', 6);=0A= + bootp_clients[i].allocated =3D 0;=0A= +}=0A= +=0A= static BOOTPClient *find_addr(struct in_addr *paddr, const uint8_t = *macaddr)=0A= {=0A= BOOTPClient *bc;=0A= @@ -133,6 +145,7 @@=0A= struct in_addr dns_addr;=0A= int dhcp_msg_type, val;=0A= uint8_t *q;=0A= + int freply_nack =3D 0;=0A= =0A= /* extract exact DHCP msg type */=0A= dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type);=0A= @@ -141,6 +154,13 @@=0A= if (dhcp_msg_type =3D=3D 0)=0A= dhcp_msg_type =3D DHCPREQUEST; /* Force reply for old BOOTP = clients */=0A= =0A= + if (dhcp_msg_type =3D=3D DHCPRELEASE) {=0A= + release_addr(&bp->bp_ciaddr);=0A= + dprintf("released addr=3D%08lx\n", ntohl(bp->bp_ciaddr.s_addr));=0A= + /* This message is not to be answered in any way. */=0A= + return;=0A= + }=0A= +=0A= if (dhcp_msg_type !=3D DHCPDISCOVER && =0A= dhcp_msg_type !=3D DHCPREQUEST)=0A= return;=0A= @@ -155,7 +175,6 @@=0A= memset(rbp, 0, sizeof(struct bootp_t));=0A= =0A= if (dhcp_msg_type =3D=3D DHCPDISCOVER) {=0A= - new_addr:=0A= bc =3D get_new_addr(&daddr.sin_addr);=0A= if (!bc) {=0A= dprintf("no address left\n");=0A= @@ -165,16 +184,18 @@=0A= } else {=0A= bc =3D find_addr(&daddr.sin_addr, bp->bp_hwaddr);=0A= if (!bc) {=0A= - /* if never assigned, behaves as if it was already=0A= - assigned (windows fix because it remembers its address) = */=0A= - goto new_addr;=0A= + /* if never assigned, reply DHCPNACK to BROADCAST.=0A= + (windows fix because it remembers its address). */=0A= + daddr.sin_addr.s_addr =3D htonl(0xffffffff);=0A= + freply_nack =3D 1;=0A= + dprintf("reply NACK\n");=0A= }=0A= }=0A= =0A= if (bootp_filename)=0A= snprintf(rbp->bp_file, sizeof(rbp->bp_file), "%s", = bootp_filename);=0A= =0A= - dprintf("offered addr=3D%08x\n", ntohl(daddr.sin_addr.s_addr));=0A= + dprintf("offered addr=3D%08lx\n", ntohl(daddr.sin_addr.s_addr));=0A= =0A= saddr.sin_addr.s_addr =3D htonl(ntohl(special_addr.s_addr) | = CTL_ALIAS);=0A= saddr.sin_port =3D htons(BOOTP_SERVER);=0A= @@ -187,7 +208,10 @@=0A= rbp->bp_hlen =3D 6;=0A= memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6);=0A= =0A= - rbp->bp_yiaddr =3D daddr.sin_addr; /* Client IP address */=0A= + if (freply_nack)=0A= + rbp->bp_yiaddr.s_addr =3D htonl(0); /* When NACK, IP address is = 0. */=0A= + else=0A= + rbp->bp_yiaddr =3D daddr.sin_addr; /* Client IP address */=0A= rbp->bp_siaddr =3D saddr.sin_addr; /* Server IP address */=0A= =0A= q =3D rbp->bp_vend;=0A= @@ -201,11 +225,14 @@=0A= } else if (dhcp_msg_type =3D=3D DHCPREQUEST) {=0A= *q++ =3D RFC2132_MSG_TYPE;=0A= *q++ =3D 1;=0A= - *q++ =3D DHCPACK;=0A= + if (freply_nack)=0A= + *q++ =3D DHCPNACK;=0A= + else=0A= + *q++ =3D DHCPACK;=0A= }=0A= =0A= if (dhcp_msg_type =3D=3D DHCPDISCOVER ||=0A= - dhcp_msg_type =3D=3D DHCPREQUEST) {=0A= + ((dhcp_msg_type =3D=3D DHCPREQUEST) && !freply_nack)) {=0A= *q++ =3D RFC2132_SRV_ID;=0A= *q++ =3D 4;=0A= memcpy(q, &saddr.sin_addr, 4);=0A= Index: slirp/bootp.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /sources/qemu/qemu/slirp/bootp.h,v=0A= retrieving revision 1.2=0A= diff -u -r1.2 bootp.h=0A= --- slirp/bootp.h 5 Jun 2005 17:11:42 -0000 1.2=0A= +++ slirp/bootp.h 20 Feb 2007 03:36:39 -0000=0A= @@ -71,6 +71,8 @@=0A= #define DHCPOFFER 2=0A= #define DHCPREQUEST 3=0A= #define DHCPACK 5=0A= +#define DHCPNACK 6=0A= +#define DHCPRELEASE 7=0A= =0A= #define RFC1533_VENDOR_MAJOR 0=0A= #define RFC1533_VENDOR_MINOR 0=0A= ------=_NextPart_000_0010_01C754F0.60D14480--