From 692ed0dd328ede9ed8e39335fecac11f3814e0c4 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Wed, 23 Apr 2025 12:53:51 +0100 Subject: [PATCH] Log source address of leasequeries. --- src/dhcp.c | 15 ++++++++++----- src/dnsmasq.h | 2 +- src/rfc2131.c | 18 +++++++++++------- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/dhcp.c b/src/dhcp.c index f060851..e25e3b1 100644 --- a/src/dhcp.c +++ b/src/dhcp.c @@ -230,19 +230,22 @@ void dhcp_packet(time_t now, int pxe_fd) return; mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base; - loopback = !mess->giaddr.s_addr && (ifr.ifr_flags & IFF_LOOPBACK); - + /* Non-standard extension: If giaddr == 255.255.255.255 we reply to the source address in the request packet header. This makes stand-alone leasequery clients easier, as they - can leave source address determination to the kernel. */ + can leave source address determination to the kernel. + In this case, set a flag and clear giaddr here, + to avoid massive relay confusion. */ if (mess->giaddr.s_addr == INADDR_BROADCAST) { mess->giaddr.s_addr = 0; is_relay_use_source = 1; } - + + loopback = !mess->giaddr.s_addr && (ifr.ifr_flags & IFF_LOOPBACK); + #ifdef HAVE_LINUX_NETWORK /* ARP fiddling uses original interface even if we pretend to use a different one. */ safe_strncpy(arp_req.arp_dev, ifr.ifr_name, sizeof(arp_req.arp_dev)); @@ -349,7 +352,8 @@ void dhcp_packet(time_t now, int pxe_fd) lease_prune(NULL, now); /* lose any expired leases */ iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz, now, unicast_dest, - loopback, &is_inform, pxe_fd, iface_addr, recvtime, is_relay_use_source); + loopback, &is_inform, pxe_fd, iface_addr, recvtime, + is_relay_use_source ? dest.sin_addr : mess->giaddr); lease_update_file(now); lease_update_dns(0); @@ -380,6 +384,7 @@ void dhcp_packet(time_t now, int pxe_fd) { /* Send to BOOTP relay. */ if (is_relay_use_source) + /* restore as-recieved value */ mess->giaddr.s_addr = INADDR_BROADCAST; else { diff --git a/src/dnsmasq.h b/src/dnsmasq.h index dbb9fbb..e346b2c 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -1659,7 +1659,7 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, size_t sz, time_t now, int unicast_dest, int loopback, int *is_inform, int pxe, struct in_addr fallback, - time_t recvtime, int is_relay_use_source); + time_t recvtime, struct in_addr leasequery_source); unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr, int clid_len, unsigned char *clid, int *len_out); #endif diff --git a/src/rfc2131.c b/src/rfc2131.c index 9f5adf8..70cbc34 100644 --- a/src/rfc2131.c +++ b/src/rfc2131.c @@ -74,7 +74,7 @@ static void handle_encap(struct dhcp_packet *mess, unsigned char *end, unsigned size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, size_t sz, time_t now, int unicast_dest, int loopback, - int *is_inform, int pxe, struct in_addr fallback, time_t recvtime, int is_relay_use_source) + int *is_inform, int pxe, struct in_addr fallback, time_t recvtime, struct in_addr leasequery_source) { unsigned char *opt, *clid = NULL; struct dhcp_lease *ltmp, *lease = NULL; @@ -109,7 +109,7 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, #endif subnet_addr.s_addr = override.s_addr = 0; - + /* set tag with name == interface */ iface_id.net = iface_name; iface_id.next = NULL; @@ -1059,11 +1059,13 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index, if (!option_bool(OPT_LEASEQUERY)) return 0; - if (mess->giaddr.s_addr == 0 && !is_relay_use_source) + if (leasequery_source.s_addr == 0) return 0; - + daemon->metrics[METRIC_DHCPLEASEQUERY]++; - log_packet("DHCPLEASEQUERY", mess->ciaddr.s_addr ? &mess->ciaddr : NULL, emac_len != 0 ? emac : NULL, emac_len, iface_name, NULL, NULL, mess->xid); + inet_ntop(AF_INET, &leasequery_source, daemon->workspacename, ADDRSTRLEN); + log_packet("DHCPLEASEQUERY", mess->ciaddr.s_addr ? &mess->ciaddr : NULL, emac_len != 0 ? emac : NULL, emac_len, + iface_name, "from ", daemon->workspacename, mess->xid); /* Put all the contexts on the ->current list for the next stages. */ for (context = daemon->dhcp; context; context = context->next) @@ -1901,22 +1903,24 @@ static void log_packet(char *type, void *addr, unsigned char *ext_mac, print_mac(daemon->namebuff, ext_mac, mac_len); if (option_bool(OPT_LOG_OPTS)) - my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s %s%s", + my_syslog(MS_DHCP | LOG_INFO, "%u %s(%s) %s%s%s%s%s%s", ntohl(xid), type, interface, daemon->addrbuff, addr ? " " : "", daemon->namebuff, + ext_mac ? " " : "", string ? string : "", err ? err : ""); else - my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s %s%s", + my_syslog(MS_DHCP | LOG_INFO, "%s(%s) %s%s%s%s%s%s", type, interface, daemon->addrbuff, addr ? " " : "", daemon->namebuff, + ext_mac ? " " : "", string ? string : "", err ? err : "");