void dhcprelease (packet) struct packet *packet; { struct lease *lease; struct iaddr cip; int i; /* DHCPRELEASE must not specify address in requested-address option, but old protocol specs weren't explicit about this, so let it go. */ if (packet -> options [DHO_DHCP_REQUESTED_ADDRESS].len) { note ("DHCPRELEASE from %s specified requested-address.", print_hw_addr (packet -> raw -> htype, packet -> raw -> hlen, packet -> raw -> chaddr)); } i = DHO_DHCP_CLIENT_IDENTIFIER; if (packet -> options [i].len) { lease = find_lease_by_uid (packet -> options [i].data, packet -> options [i].len); /* See if we can find a lease that matches the IP address the client is claiming. */ for (; lease; lease = lease -> n_uid) { if (!memcmp (&packet -> raw -> ciaddr, lease -> ip_addr.iabuf, 4)) { break; } } } else { /* The client is supposed to pass a valid client-identifier, but the spec on this has changed historically, so try the IP address in ciaddr if the client-identifier fails. */ cip.len = 4; memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4); lease = find_lease_by_ip_addr (cip); } note ("DHCPRELEASE of %s from %s via %s (%sfound)", inet_ntoa (packet -> raw -> ciaddr), print_hw_addr (packet -> raw -> htype, packet -> raw -> hlen, packet -> raw -> chaddr), packet -> raw -> giaddr.s_addr ? inet_ntoa (packet -> raw -> giaddr) : packet -> interface -> name, lease ? "" : "not "); /* If we found a lease, release it. */ if (lease && lease -> ends > cur_time) { release_lease (lease); } }