Magellan Linux

Diff of /trunk/mkinitrd-magellan/busybox/networking/udhcp/leases.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 815 by niro, Sat Sep 1 22:45:15 2007 UTC revision 816 by niro, Fri Apr 24 18:33:46 2009 UTC
# Line 8  Line 8 
8  #include "dhcpd.h"  #include "dhcpd.h"
9    
10    
11  uint8_t blank_chaddr[] = {[0 ... 15] = 0};  /* Find the oldest expired lease, NULL if there are no expired leases */
12    static struct dhcpOfferedAddr *oldest_expired_lease(void)
13    {
14     struct dhcpOfferedAddr *oldest = NULL;
15    // TODO: use monotonic_sec()
16     unsigned long oldest_lease = time(0);
17     unsigned i;
18    
19     for (i = 0; i < server_config.max_leases; i++)
20     if (oldest_lease > leases[i].expires) {
21     oldest_lease = leases[i].expires;
22     oldest = &(leases[i]);
23     }
24     return oldest;
25    }
26    
27    
28  /* clear every lease out that chaddr OR yiaddr matches and is nonzero */  /* clear every lease out that chaddr OR yiaddr matches and is nonzero */
29  void clear_lease(uint8_t *chaddr, uint32_t yiaddr)  static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
30  {  {
31   unsigned int i, j;   unsigned i, j;
32    
33   for (j = 0; j < 16 && !chaddr[j]; j++);   for (j = 0; j < 16 && !chaddr[j]; j++)
34     continue;
35    
36   for (i = 0; i < server_config.max_leases; i++)   for (i = 0; i < server_config.max_leases; i++)
37   if ((j != 16 && !memcmp(leases[i].chaddr, chaddr, 16)) ||   if ((j != 16 && memcmp(leases[i].chaddr, chaddr, 16) == 0)
38      (yiaddr && leases[i].yiaddr == yiaddr)) {   || (yiaddr && leases[i].yiaddr == yiaddr)
39   memset(&(leases[i]), 0, sizeof(struct dhcpOfferedAddr));   ) {
40     memset(&(leases[i]), 0, sizeof(leases[i]));
41   }   }
42  }  }
43    
44    
45  /* add a lease into the table, clearing out any old ones */  /* add a lease into the table, clearing out any old ones */
46  struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease)  struct dhcpOfferedAddr* FAST_FUNC add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease)
47  {  {
48   struct dhcpOfferedAddr *oldest;   struct dhcpOfferedAddr *oldest;
49    
# Line 46  struct dhcpOfferedAddr *add_lease(uint8_ Line 63  struct dhcpOfferedAddr *add_lease(uint8_
63    
64    
65  /* true if a lease has expired */  /* true if a lease has expired */
66  int lease_expired(struct dhcpOfferedAddr *lease)  int FAST_FUNC lease_expired(struct dhcpOfferedAddr *lease)
67  {  {
68   return (lease->expires < (unsigned long) time(0));   return (lease->expires < (unsigned long) time(0));
69  }  }
70    
71    
 /* Find the oldest expired lease, NULL if there are no expired leases */  
 struct dhcpOfferedAddr *oldest_expired_lease(void)  
 {  
  struct dhcpOfferedAddr *oldest = NULL;  
  unsigned long oldest_lease = time(0);  
  unsigned int i;  
   
   
  for (i = 0; i < server_config.max_leases; i++)  
  if (oldest_lease > leases[i].expires) {  
  oldest_lease = leases[i].expires;  
  oldest = &(leases[i]);  
  }  
  return oldest;  
   
 }  
   
   
72  /* Find the first lease that matches chaddr, NULL if no match */  /* Find the first lease that matches chaddr, NULL if no match */
73  struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr)  struct dhcpOfferedAddr* FAST_FUNC find_lease_by_chaddr(const uint8_t *chaddr)
74  {  {
75   unsigned int i;   unsigned i;
76    
77   for (i = 0; i < server_config.max_leases; i++)   for (i = 0; i < server_config.max_leases; i++)
78   if (!memcmp(leases[i].chaddr, chaddr, 16)) return &(leases[i]);   if (!memcmp(leases[i].chaddr, chaddr, 16))
79     return &(leases[i]);
80    
81   return NULL;   return NULL;
82  }  }
83    
84    
85  /* Find the first lease that matches yiaddr, NULL is no match */  /* Find the first lease that matches yiaddr, NULL is no match */
86  struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr)  struct dhcpOfferedAddr* FAST_FUNC find_lease_by_yiaddr(uint32_t yiaddr)
87  {  {
88   unsigned int i;   unsigned i;
89    
90   for (i = 0; i < server_config.max_leases; i++)   for (i = 0; i < server_config.max_leases; i++)
91   if (leases[i].yiaddr == yiaddr) return &(leases[i]);   if (leases[i].yiaddr == yiaddr)
92     return &(leases[i]);
93    
94   return NULL;   return NULL;
95  }  }
96    
97    
98  /* check is an IP is taken, if it is, add it to the lease table */  /* check is an IP is taken, if it is, add it to the lease table */
99  static int check_ip(uint32_t addr)  static int nobody_responds_to_arp(uint32_t addr)
100  {  {
101     /* 16 zero bytes */
102     static const uint8_t blank_chaddr[16] = { 0 };
103     /* = { 0 } helps gcc to put it in rodata, not bss */
104    
105   struct in_addr temp;   struct in_addr temp;
106     int r;
107    
108   if (arpping(addr, server_config.server, server_config.arp, server_config.interface) == 0) {   r = arpping(addr, server_config.server, server_config.arp, server_config.interface);
109   temp.s_addr = addr;   if (r)
110   bb_info_msg("%s belongs to someone, reserving it for %ld seconds",   return r;
111   inet_ntoa(temp), server_config.conflict_time);  
112   add_lease(blank_chaddr, addr, server_config.conflict_time);   temp.s_addr = addr;
113   return 1;   bb_info_msg("%s belongs to someone, reserving it for %u seconds",
114   } else return 0;   inet_ntoa(temp), (unsigned)server_config.conflict_time);
115     add_lease(blank_chaddr, addr, server_config.conflict_time);
116     return 0;
117  }  }
118    
119    
120  /* find an assignable address, it check_expired is true, we check all the expired leases as well.  /* find an assignable address, if check_expired is true, we check all the expired leases as well.
121   * Maybe this should try expired leases by age... */   * Maybe this should try expired leases by age... */
122  uint32_t find_address(int check_expired)  uint32_t FAST_FUNC find_address(int check_expired)
123  {  {
124   uint32_t addr, ret;   uint32_t addr, ret;
125   struct dhcpOfferedAddr *lease = NULL;   struct dhcpOfferedAddr *lease = NULL;
126    
127   addr = ntohl(server_config.start); /* addr is in host order here */   addr = server_config.start_ip; /* addr is in host order here */
128   for (;addr <= ntohl(server_config.end); addr++) {   for (; addr <= server_config.end_ip; addr++) {
   
129   /* ie, 192.168.55.0 */   /* ie, 192.168.55.0 */
130   if (!(addr & 0xFF)) continue;   if (!(addr & 0xFF))
131     continue;
132   /* ie, 192.168.55.255 */   /* ie, 192.168.55.255 */
133   if ((addr & 0xFF) == 0xFF) continue;   if ((addr & 0xFF) == 0xFF)
134     continue;
135   /* Only do if it isn't an assigned as a static lease */   /* Only do if it isn't assigned as a static lease */
136   if (!reservedIp(server_config.static_leases, htonl(addr))) {   ret = htonl(addr);
137     if (!reservedIp(server_config.static_leases, ret)) {
138   /* lease is not taken */   /* lease is not taken */
  ret = htonl(addr);  
139   lease = find_lease_by_yiaddr(ret);   lease = find_lease_by_yiaddr(ret);
   
140   /* no lease or it expired and we are checking for expired leases */   /* no lease or it expired and we are checking for expired leases */
141   if ( (!lease || (check_expired && lease_expired(lease)))   if ((!lease || (check_expired && lease_expired(lease)))
142   && /* and it isn't on the network */ !check_ip(ret)   && nobody_responds_to_arp(ret) /* it isn't used on the network */
143   ) {   ) {
144   return ret;   return ret;
  break;  
145   }   }
146   }   }
147   }   }

Legend:
Removed from v.815  
changed lines
  Added in v.816