Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 9 months ago) by niro
File MIME type: text/plain
File size: 3546 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

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