Also add query-ids with log-queries=extra.
return;
#ifdef HAVE_DUMPFILE
- dump_packet(DUMP_DHCP, (void *)daemon->dhcp_packet.iov_base, sz, (union mysockaddr *)&dest, NULL,
- pxe_fd ? PXE_PORT : daemon->dhcp_server_port);
+ dump_packet_udp(DUMP_DHCP, (void *)daemon->dhcp_packet.iov_base, sz, (union mysockaddr *)&dest, NULL, fd);
#endif
#if defined (HAVE_LINUX_NETWORK)
dest.sin_addr = mess->yiaddr;
dest.sin_port = htons(daemon->dhcp_client_port);
- dump_packet(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
- (union mysockaddr *)&dest, daemon->dhcp_server_port);
+ dump_packet_udp(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
+ (union mysockaddr *)&dest, fd);
#endif
send_via_bpf(mess, iov.iov_len, iface_addr, &ifr);
#endif
#ifdef HAVE_DUMPFILE
- dump_packet(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
- (union mysockaddr *)&dest, daemon->dhcp_server_port);
+ dump_packet_udp(DUMP_DHCP, (void *)iov.iov_base, iov.iov_len, NULL,
+ (union mysockaddr *)&dest, fd);
#endif
while(retry_send(sendmsg(fd, &msg, 0)));
fromsock.in.sin_port = htons(daemon->dhcp_server_port);
fromsock.in.sin_addr = from.addr4;
fromsock.sa.sa_family = AF_INET;
-
- dump_packet(DUMP_DHCP, (void *)mess, sz, &fromsock, &to, 0);
+
+ dump_packet_udp(DUMP_DHCP, (void *)mess, sz, &fromsock, &to, -1);
}
#endif
return;
#ifdef HAVE_DUMPFILE
- dump_packet(DUMP_DHCPV6, (void *)daemon->dhcp_packet.iov_base, sz,
- (union mysockaddr *)&from, NULL, DHCPV6_SERVER_PORT);
+ dump_packet_udp(DUMP_DHCPV6, (void *)daemon->dhcp_packet.iov_base, sz,
+ (union mysockaddr *)&from, NULL, daemon->dhcp6fd);
#endif
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (relay_reply6(&from, sz, ifr.ifr_name))
{
#ifdef HAVE_DUMPFILE
- dump_packet(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL,
- (union mysockaddr *)&from, DHCPV6_SERVER_PORT);
+ dump_packet_udp(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1), NULL,
+ (union mysockaddr *)&from, daemon->dhcp6fd);
#endif
while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base,
from.sin6_port = htons(port);
#ifdef HAVE_DUMPFILE
- dump_packet(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1),
- NULL, (union mysockaddr *)&from, DHCPV6_SERVER_PORT);
+ dump_packet_udp(DUMP_DHCPV6, (void *)daemon->outpacket.iov_base, save_counter(-1),
+ NULL, (union mysockaddr *)&from, daemon->dhcp6fd);
#endif
while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base,
/* dump.c */
#ifdef HAVE_DUMPFILE
void dump_init(void);
-void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src,
- union mysockaddr *dst, int port);
+void dump_packet_udp(int mask, void *packet, size_t len, union mysockaddr *src,
+ union mysockaddr *dst, int fd);
+void dump_packet_icmp(int mask, void *packet, size_t len, union mysockaddr *src,
+ union mysockaddr *dst);
#endif
/* domain-match.c */
#include <netinet/icmp6.h>
static u32 packet_count;
+static void do_dump_packet(int mask, void *packet, size_t len,
+ union mysockaddr *src, union mysockaddr *dst, int port, int proto);
/* https://wiki.wireshark.org/Development/LibpcapFileFormat */
struct pcap_hdr_s {
}
}
-/* port == -1 ->ICMPv6 */
-void dump_packet(int mask, void *packet, size_t len,
- union mysockaddr *src, union mysockaddr *dst, int port)
+void dump_packet_udp(int mask, void *packet, size_t len,
+ union mysockaddr *src, union mysockaddr *dst, int fd)
+{
+ union mysockaddr fd_addr;
+ socklen_t addr_len = sizeof(fd_addr);
+
+ if (daemon->dumpfd != -1 && (mask & daemon->dump_mask))
+ {
+ /* if fd is negative it carries a port number (negated)
+ which we use as a source or destination when not otherwise
+ specified so wireshark can ID the packet.
+ If both src and dst are specified, set this to -1 to avoid
+ a spurious getsockname() call. */
+ int port = (fd < 0) ? -fd : -1;
+
+ /* fd >= 0 is a file descriptor and the address of that file descriptor is used
+ in place of a NULL src or dst. */
+ if (fd >= 0 && getsockname(fd, (struct sockaddr *)&fd_addr, &addr_len) != -1)
+ {
+ if (!src)
+ src = &fd_addr;
+
+ if (!dst)
+ dst = &fd_addr;
+ }
+
+ do_dump_packet(mask, packet, len, src, dst, port, IPPROTO_UDP);
+ }
+}
+
+void dump_packet_icmp(int mask, void *packet, size_t len,
+ union mysockaddr *src, union mysockaddr *dst)
+{
+ if (daemon->dumpfd != -1 && (mask & daemon->dump_mask))
+ do_dump_packet(mask, packet, len, src, dst, -1, IPPROTO_ICMP);
+}
+
+static void do_dump_packet(int mask, void *packet, size_t len,
+ union mysockaddr *src, union mysockaddr *dst, int port, int proto)
{
struct ip ip;
struct ip6_hdr ip6;
void *iphdr;
size_t ipsz;
int rc;
+
+ /* if port != -1 it carries a port number
+ which we use as a source or destination when not otherwise
+ specified so wireshark can ID the packet.
+ If both src and dst are specified, set this to -1 to avoid
+ a spurious getsockname() call. */
+ udp.uh_sport = udp.uh_dport = htons(port < 0 ? 0 : port);
- if (daemon->dumpfd == -1 || !(mask & daemon->dump_mask))
- return;
-
- /* So wireshark can Id the packet. */
- udp.uh_sport = udp.uh_dport = htons(port);
-
if (src)
family = src->sa.sa_family;
else
ip6.ip6_vfc = 6 << 4;
ip6.ip6_hops = 64;
- if (port == -1)
- {
- ip6.ip6_plen = htons(len);
- ip6.ip6_nxt = IPPROTO_ICMPV6;
- }
+ if ((ip6.ip6_nxt = proto) == IPPROTO_UDP)
+ ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
else
{
- ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
- ip6.ip6_nxt = IPPROTO_UDP;
+ proto = ip6.ip6_nxt = IPPROTO_ICMPV6;
+ ip6.ip6_plen = htons(len);
}
if (src)
ip.ip_hl = sizeof(struct ip) / 4;
ip.ip_ttl = IPDEFTTL;
- if (port == -1)
- {
- ip.ip_len = htons(sizeof(struct ip) + len);
- ip.ip_p = IPPROTO_ICMP;
- }
+ if ((ip.ip_p = proto) == IPPROTO_UDP)
+ ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
else
{
- ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
- ip.ip_p = IPPROTO_UDP;
+ ip.ip_len = htons(sizeof(struct ip) + len);
+ proto = ip.ip_p = IPPROTO_ICMP;
}
if (src)
sum = (sum & 0xffff) + (sum >> 16);
ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
- /* start UDP checksum */
+ /* start UDP/ICMP checksum */
sum = ip.ip_src.s_addr & 0xffff;
sum += (ip.ip_src.s_addr >> 16) & 0xffff;
sum += ip.ip_dst.s_addr & 0xffff;