qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] FreeBSD port update, FreeSBIE, X, more slirp dhcp probl


From: Juergen Lock
Subject: Re: [Qemu-devel] FreeBSD port update, FreeSBIE, X, more slirp dhcp problems...
Date: Sat, 5 Jun 2004 22:30:58 +0200 (CEST)

In article <address@hidden> you write:
>...
>For DHCP, I need to look at it, but I would need a small disk image to 
>test it. You can also try the patch Renzo published on the mailing list.

Did that (had to edit it a bit, see below), and FreeSBIE now gets
an address and a default route, but still no nameserver.  Well this
_could_ also be normal but somehow i doubt it.  (Could also be
that I broke the patch somehow, I'm no dhcp expert...)

        Juergen

Index: slirp/bootp.c
===================================================================
RCS file: /cvsroot/qemu/qemu/slirp/bootp.c,v
retrieving revision 1.3
diff -u -r1.3 bootp.c
--- slirp/bootp.c       4 Jun 2004 15:30:48 -0000       1.3
+++ slirp/bootp.c       5 Jun 2004 19:34:22 -0000
@@ -29,11 +29,12 @@
 
 #define START_ADDR 15
 
-#define LEASE_TIME (24 * 3600)
+#define LEASE_TIME (120)
 
 typedef struct {
     uint8_t allocated;
     uint8_t macaddr[6];
+    int time;
 } BOOTPClient;
 
 BOOTPClient bootp_clients[NB_ADDR];
@@ -68,26 +69,54 @@
 {
     BOOTPClient *bc;
     int i;
+    int now=time(NULL);
 
     for(i = 0; i < NB_ADDR; i++) {
         if (!memcmp(macaddr, bootp_clients[i].macaddr, 6))
             goto found;
     }
+    for(i = 0; i < NB_ADDR; i++) {
+       if (now-bootp_clients[i].time > 3*LEASE_TIME)
+           goto found;
+    }
     return NULL;
  found:
     bc = &bootp_clients[i];
-    bc->allocated = 1;
     paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR));
     return bc;
 }
 
+static BOOTPClient *find_reqaddr(struct in_addr *paddr, struct in_addr 
*reqaddr, const uint8_t *macaddr)
+{
+    BOOTPClient *bc=NULL;
+    int i;
+    /*check the net prefix*/
+    if ((ntohl(reqaddr->s_addr) & 0xffffff00) ==
+                   (ntohl(special_addr.s_addr) & 0xffffff00)) {
+           i=(ntohl(reqaddr->s_addr) & 0xff) - START_ADDR;
+           if (i>=0 && i< NB_ADDR) {
+                   bc = &bootp_clients[i];
+                   if (bc->allocated &&
+                                   (memcmp(macaddr, bootp_clients[i].macaddr, 
6)==0)) {
+                           paddr->s_addr = reqaddr->s_addr;
+                           return bc;
+                   }
+                   else
+                           bc=NULL;
+           }
+    }
+    return bc;
+}
+
+
 static void dhcp_decode(const uint8_t *buf, int size,
-                        int *pmsg_type)
+                        int *pmsg_type, struct sockaddr_in *preqaddr)
 {
     const uint8_t *p, *p_end;
     int len, tag;
 
     *pmsg_type = 0;    
+    preqaddr->sin_addr.s_addr=htonl(0L);
 
     p = buf;
     p_end = buf + size;
@@ -114,6 +143,10 @@
                 if (len >= 1)
                     *pmsg_type = p[0];
                 break;
+            case RFC2132_REQ_ADDR:
+               if (len == 4) {
+                       memcpy(&(preqaddr->sin_addr),p,4);
+               }
             default:
                 break;
             }
@@ -127,14 +160,14 @@
     BOOTPClient *bc;
     struct mbuf *m;
     struct bootp_t *rbp;
-    struct sockaddr_in saddr, daddr;
+    struct sockaddr_in saddr, daddr, reqaddr;
     struct in_addr dns_addr;
     int dhcp_msg_type, val;
-    uint8_t *q;
+    uint8_t *q,replytype;
 
     /* extract exact DHCP msg type */
-    dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type);
-    dprintf("bootp packet op=%d msgtype=%d\n", bp->bp_op, dhcp_msg_type);
+    dhcp_decode(bp->bp_vend, DHCP_OPT_LEN, &dhcp_msg_type,&reqaddr);
+    dprintf("bootp packet op=%d msgtype=%d reqaddr=%x\n", bp->bp_op, 
dhcp_msg_type,ntohl(reqaddr.sin_addr.s_addr));
     
     if (dhcp_msg_type != DHCPDISCOVER && 
         dhcp_msg_type != DHCPREQUEST)
@@ -149,19 +182,18 @@
     m->m_data += sizeof(struct udpiphdr);
     memset(rbp, 0, sizeof(struct bootp_t));
 
-    if (dhcp_msg_type == DHCPDISCOVER) {
-        bc = get_new_addr(&daddr.sin_addr);
-        if (!bc) {
-            dprintf("no address left\n");
-            return;
-        }
-        memcpy(bc->macaddr, client_ethaddr, 6);
-    } else {
-        bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
-        if (!bc) {
-            dprintf("no address assigned\n");
-            return;
-        }
+    bc=NULL;
+    daddr.sin_addr.s_addr=htonl(0L);
+    if (dhcp_msg_type == DHCPREQUEST) {
+          if (reqaddr.sin_addr.s_addr != htonl(0L))
+                  bc = find_reqaddr(&daddr.sin_addr, &reqaddr.sin_addr, 
bp->bp_hwaddr);
+          else 
+                  bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
+    }
+    else if (dhcp_msg_type == DHCPDISCOVER) {
+          bc = find_addr(&daddr.sin_addr, bp->bp_hwaddr);
+          if (!bc)
+              bc = get_new_addr(&daddr.sin_addr);
     }
     dprintf("offered addr=%08x\n", ntohl(daddr.sin_addr.s_addr));
 
@@ -182,18 +214,21 @@
     memcpy(q, rfc1533_cookie, 4);
     q += 4;
 
-    if (dhcp_msg_type == DHCPDISCOVER) {
-        *q++ = RFC2132_MSG_TYPE;
-        *q++ = 1;
-        *q++ = DHCPOFFER;
-    } else if (dhcp_msg_type == DHCPREQUEST) {
+    if (bc != NULL) {
+        memcpy(bc->macaddr, client_ethaddr, 6);
+       bc->allocated = 1;
+       bc->time = time(NULL);
+       replytype=(dhcp_msg_type == DHCPDISCOVER)?DHCPOFFER:DHCPACK;
+    }
+    else
+       replytype=DHCPNACK;
+
         *q++ = RFC2132_MSG_TYPE;
         *q++ = 1;
-        *q++ = DHCPACK;
-    }
+    *q++ = replytype;
         
-    if (dhcp_msg_type == DHCPDISCOVER ||
-        dhcp_msg_type == DHCPREQUEST) {
+    if ((dhcp_msg_type == DHCPDISCOVER ||
+        dhcp_msg_type == DHCPREQUEST) && replytype!=DHCPNACK) {
         *q++ = RFC2132_SRV_ID;
         *q++ = 4;
         memcpy(q, &saddr.sin_addr, 4);
Index: slirp/bootp.h
===================================================================
RCS file: /cvsroot/qemu/qemu/slirp/bootp.h,v
retrieving revision 1.1
diff -u -r1.1 bootp.h
--- slirp/bootp.h       22 Apr 2004 00:10:47 -0000      1.1
+++ slirp/bootp.h       5 Jun 2004 19:34:22 -0000
@@ -71,6 +71,7 @@
 #define DHCPOFFER              2
 #define DHCPREQUEST            3
 #define DHCPACK                        5
+#define DHCPNACK               6
 
 #define RFC1533_VENDOR_MAJOR   0
 #define RFC1533_VENDOR_MINOR   0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]