aboutsummaryrefslogblamecommitdiff
path: root/emulators/qemu-devel/files/patch-bk
blob: 09281f31aef2d6a227a2e633dfec29a1dce95787 (plain) (tree)
1
2
3
4
5
6
7
8
                         


                      
 

                               
 







                                    
  


                        
 


                                                           
      










































































                                                                                                                    


                                                                             



                                            
              








                                                        


                                                                          
          











                                                                                        
      

                                                                  








                                                             









































                                                                    
 

                                 
Index: qemu/slirp/bootp.c
@@ -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 == 0)
         dhcp_msg_type = DHCPREQUEST; /* Force reply for old BOOTP clients */
@@ -152,21 +185,18 @@
     m->m_data += sizeof(struct udpiphdr);
     memset(rbp, 0, sizeof(struct bootp_t));
 
-    if (dhcp_msg_type == DHCPDISCOVER) {
-    new_addr:
-        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) {
-            /* if never assigned, behaves as if it was already
-               assigned (windows fix because it remembers its address) */
-            goto new_addr;
-        }
+    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));
 
@@ -181,25 +211,27 @@
     rbp->bp_hlen = 6;
     memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6);
 
-    rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
-    rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
+    rbp->bp_yiaddr = daddr.sin_addr; /* IP address */
 
     q = rbp->bp_vend;
     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: qemu/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