Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/networking/udhcp/leases.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/networking/udhcp/leases.c
r1765 r2725 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * leases.c -- tools to manage DHCP leases4 3 * Russ Dill <Russ.Dill@asu.edu> July 2001 4 * 5 * Licensed under GPLv2, see file LICENSE in this source tree. 5 6 */ 6 7 7 #include "common.h" 8 8 #include "dhcpd.h" 9 9 10 11 10 /* Find the oldest expired lease, NULL if there are no expired leases */ 12 static struct d hcpOfferedAddr*oldest_expired_lease(void)11 static struct dyn_lease *oldest_expired_lease(void) 13 12 { 14 struct dhcpOfferedAddr *oldest = NULL; 15 // TODO: use monotonic_sec() 16 unsigned long oldest_lease = time(0); 13 struct dyn_lease *oldest_lease = NULL; 14 leasetime_t oldest_time = time(NULL); 17 15 unsigned i; 18 16 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]); 17 /* Unexpired leases have g_leases[i].expires >= current time 18 * and therefore can't ever match */ 19 for (i = 0; i < server_config.max_leases; i++) { 20 if (g_leases[i].expires < oldest_time) { 21 oldest_time = g_leases[i].expires; 22 oldest_lease = &g_leases[i]; 23 23 } 24 return oldest; 24 } 25 return oldest_lease; 25 26 } 26 27 28 /* Clear out all leases with matching nonzero chaddr OR yiaddr. 29 * If chaddr == NULL, this is a conflict lease. 30 */ 31 static void clear_leases(const uint8_t *chaddr, uint32_t yiaddr) 32 { 33 unsigned i; 27 34 28 /* clear every lease out that chaddr OR yiaddr matches and is nonzero */ 29 static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr) 30 { 31 unsigned i, j; 32 33 for (j = 0; j < 16 && !chaddr[j]; j++) 34 continue; 35 36 for (i = 0; i < server_config.max_leases; i++) 37 if ((j != 16 && memcmp(leases[i].chaddr, chaddr, 16) == 0) 38 || (yiaddr && leases[i].yiaddr == yiaddr) 35 for (i = 0; i < server_config.max_leases; i++) { 36 if ((chaddr && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0) 37 || (yiaddr && g_leases[i].lease_nip == yiaddr) 39 38 ) { 40 memset(& (leases[i]), 0, sizeof(leases[i]));39 memset(&g_leases[i], 0, sizeof(g_leases[i])); 41 40 } 41 } 42 42 } 43 43 44 45 /* add a lease into the table, clearing out any old ones */ 46 struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) 44 /* Add a lease into the table, clearing out any old ones. 45 * If chaddr == NULL, this is a conflict lease. 46 */ 47 struct dyn_lease* FAST_FUNC add_lease( 48 const uint8_t *chaddr, uint32_t yiaddr, 49 leasetime_t leasetime, 50 const char *hostname, int hostname_len) 47 51 { 48 struct d hcpOfferedAddr*oldest;52 struct dyn_lease *oldest; 49 53 50 54 /* clean out any old ones */ 51 clear_lease (chaddr, yiaddr);55 clear_leases(chaddr, yiaddr); 52 56 53 57 oldest = oldest_expired_lease(); 54 58 55 59 if (oldest) { 56 memcpy(oldest->chaddr, chaddr, 16); 57 oldest->yiaddr = yiaddr; 58 oldest->expires = time(0) + lease; 60 memset(oldest, 0, sizeof(*oldest)); 61 if (hostname) { 62 char *p; 63 64 hostname_len++; /* include NUL */ 65 if (hostname_len > sizeof(oldest->hostname)) 66 hostname_len = sizeof(oldest->hostname); 67 p = safe_strncpy(oldest->hostname, hostname, hostname_len); 68 /* sanitization (s/non-ASCII/^/g) */ 69 while (*p) { 70 if (*p < ' ' || *p > 126) 71 *p = '^'; 72 p++; 73 } 74 } 75 if (chaddr) 76 memcpy(oldest->lease_mac, chaddr, 6); 77 oldest->lease_nip = yiaddr; 78 oldest->expires = time(NULL) + leasetime; 59 79 } 60 80 … … 62 82 } 63 83 64 65 /* true if a lease has expired */ 66 int lease_expired(struct dhcpOfferedAddr *lease) 84 /* True if a lease has expired */ 85 int FAST_FUNC is_expired_lease(struct dyn_lease *lease) 67 86 { 68 return (lease->expires < ( unsigned long) time(0));87 return (lease->expires < (leasetime_t) time(NULL)); 69 88 } 70 89 71 72 /* Find the first lease that matches chaddr, NULL if no match */ 73 struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr) 90 /* Find the first lease that matches MAC, NULL if no match */ 91 struct dyn_lease* FAST_FUNC find_lease_by_mac(const uint8_t *mac) 74 92 { 75 93 unsigned i; 76 94 77 95 for (i = 0; i < server_config.max_leases; i++) 78 if ( !memcmp(leases[i].chaddr, chaddr, 16))79 return & (leases[i]);96 if (memcmp(g_leases[i].lease_mac, mac, 6) == 0) 97 return &g_leases[i]; 80 98 81 99 return NULL; 82 100 } 83 101 84 85 /* Find the first lease that matches yiaddr, NULL is no match */ 86 struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) 102 /* Find the first lease that matches IP, NULL is no match */ 103 struct dyn_lease* FAST_FUNC find_lease_by_nip(uint32_t nip) 87 104 { 88 105 unsigned i; 89 106 90 107 for (i = 0; i < server_config.max_leases; i++) 91 if ( leases[i].yiaddr == yiaddr)92 return & (leases[i]);108 if (g_leases[i].lease_nip == nip) 109 return &g_leases[i]; 93 110 94 111 return NULL; 95 112 } 96 113 97 98 /* check is an IP is taken, if it is, add it to the lease table */ 99 static int nobody_responds_to_arp(uint32_t addr) 114 /* Check if the IP is taken; if it is, add it to the lease table */ 115 static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac) 100 116 { 101 static const uint8_t blank_chaddr[16]; /* 16 zero bytes */102 103 117 struct in_addr temp; 104 118 int r; 105 119 106 r = arpping(addr, server_config.server, server_config.arp, server_config.interface); 120 r = arpping(nip, safe_mac, 121 server_config.server_nip, 122 server_config.server_mac, 123 server_config.interface); 107 124 if (r) 108 125 return r; 109 126 110 temp.s_addr = addr;127 temp.s_addr = nip; 111 128 bb_info_msg("%s belongs to someone, reserving it for %u seconds", 112 129 inet_ntoa(temp), (unsigned)server_config.conflict_time); 113 add_lease( blank_chaddr, addr, server_config.conflict_time);130 add_lease(NULL, nip, server_config.conflict_time, NULL, 0); 114 131 return 0; 115 132 } 116 133 117 118 /* find an assignable address, if check_expired is true, we check all the expired leases as well. 119 * Maybe this should try expired leases by age... */ 120 uint32_t find_address(int check_expired) 134 /* Find a new usable (we think) address */ 135 uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) 121 136 { 122 uint32_t addr , ret;123 struct d hcpOfferedAddr *lease = NULL;137 uint32_t addr; 138 struct dyn_lease *oldest_lease = NULL; 124 139 125 140 addr = server_config.start_ip; /* addr is in host order here */ 126 141 for (; addr <= server_config.end_ip; addr++) { 142 uint32_t nip; 143 struct dyn_lease *lease; 144 127 145 /* ie, 192.168.55.0 */ 128 if ( !(addr & 0xFF))146 if ((addr & 0xff) == 0) 129 147 continue; 130 148 /* ie, 192.168.55.255 */ 131 if ((addr & 0x FF) == 0xFF)149 if ((addr & 0xff) == 0xff) 132 150 continue; 133 /* Only do if it isn't assigned as a static lease */ 134 ret = htonl(addr); 135 if (!reservedIp(server_config.static_leases, ret)) { 136 /* lease is not taken */ 137 lease = find_lease_by_yiaddr(ret); 138 /* no lease or it expired and we are checking for expired leases */ 139 if ((!lease || (check_expired && lease_expired(lease))) 140 && nobody_responds_to_arp(ret) /* it isn't used on the network */ 141 ) { 142 return ret; 143 } 151 nip = htonl(addr); 152 /* is this a static lease addr? */ 153 if (is_nip_reserved(server_config.static_leases, nip)) 154 continue; 155 156 lease = find_lease_by_nip(nip); 157 if (!lease) { 158 //TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! 159 if (nobody_responds_to_arp(nip, safe_mac)) 160 return nip; 161 } else { 162 if (!oldest_lease || lease->expires < oldest_lease->expires) 163 oldest_lease = lease; 144 164 } 145 165 } 166 167 if (oldest_lease 168 && is_expired_lease(oldest_lease) 169 && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac) 170 ) { 171 return oldest_lease->lease_nip; 172 } 173 146 174 return 0; 147 175 }
Note:
See TracChangeset
for help on using the changeset viewer.