} else if (reqmsg == DHCPV4_MSG_REQUEST && reqaddr.s_addr &&
reqaddr.s_addr != htonl(lease->addr)) {
msg = DHCPV4_MSG_NAK;
- lease = NULL;
+ /*
+ * DHCP client requested an IP which we can't offer to him. Probably the
+ * client changed the network. The reply type is set to DHCPV4_MSG_NAK,
+ * because the client should not use that IP.
+ *
+ * For modern devices we build an answer that includes a valid IP, like
+ * a DHCPV4_MSG_ACK. The client will use that IP and doesn't need to
+ * perform additional DHCP round trips.
+ *
+ */
}
syslog(LOG_WARNING, "received %s from %x:%x:%x:%x:%x:%x",
len, search_buf);
}
- dhcpv4_put(&reply, &cookie, DHCPV4_OPT_ROUTER, 4, &ifaddr.sin_addr);
-
+ if (iface->dhcpv4_router_cnt == 0)
+ dhcpv4_put(&reply, &cookie, DHCPV4_OPT_ROUTER, 4, &ifaddr.sin_addr);
+ else
+ dhcpv4_put(&reply, &cookie, DHCPV4_OPT_ROUTER,
+ 4 * iface->dhcpv4_router_cnt, iface->dhcpv4_router);
if (iface->dhcpv4_dns_cnt == 0)
struct sockaddr_in dest = *((struct sockaddr_in*)addr);
if (req->giaddr.s_addr) {
+ /*
+ * relay agent is configured, send reply to the agent
+ */
dest.sin_addr = req->giaddr;
dest.sin_port = htons(DHCPV4_SERVER_PORT);
} else if (req->ciaddr.s_addr && req->ciaddr.s_addr != dest.sin_addr.s_addr) {
+ /*
+ * client has existing configuration (ciaddr is set) AND this address is
+ * not the address it used for the dhcp message
+ */
dest.sin_addr = req->ciaddr;
dest.sin_port = htons(DHCPV4_CLIENT_PORT);
} else if ((ntohs(req->flags) & DHCPV4_FLAG_BROADCAST) ||
req->hlen != reply.hlen || !reply.yiaddr.s_addr) {
+ /*
+ * client requests a broadcast reply OR we can't offer an IP
+ */
+ dest.sin_addr.s_addr = INADDR_BROADCAST;
+ dest.sin_port = htons(DHCPV4_CLIENT_PORT);
+ } else if (!req->ciaddr.s_addr && msg == DHCPV4_MSG_NAK) {
+ /*
+ * client has no previous configuration -> no IP, so we need to reply
+ * with a broadcast packet
+ */
dest.sin_addr.s_addr = INADDR_BROADCAST;
dest.sin_port = htons(DHCPV4_CLIENT_PORT);
} else {
+ /*
+ * send reply to the newly (in this proccess) allocated IP
+ */
dest.sin_addr = reply.yiaddr;
dest.sin_port = htons(DHCPV4_CLIENT_PORT);