mirror of
https://github.com/infinet/dnsmasq.git
synced 2025-05-08 00:56:06 +08:00
Add packet-dump debugging facility.
This commit is contained in:
parent
07ed585c38
commit
6b17335209
@ -17,6 +17,12 @@ version 2.80
|
||||
Fix DHCP broken-ness when --no-ping AND --dhcp-sequential-ip
|
||||
are set. Thanks to Daniel Miess for help with this.
|
||||
|
||||
Add a facilty to store DNS packets sent/recieved in a
|
||||
pcap-format file for later debugging. The file location
|
||||
is given by the --dumpfile option, and a bitmap controlling
|
||||
which packets should be dumped is given by the --dumpmask
|
||||
option.
|
||||
|
||||
|
||||
version 2.79
|
||||
Fix parsing of CNAME arguments, which are confused by extra spaces.
|
||||
|
2
Makefile
2
Makefile
@ -76,7 +76,7 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
||||
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
|
||||
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \
|
||||
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o \
|
||||
poll.o rrfilter.o edns0.o arp.o crypto.o
|
||||
poll.o rrfilter.o edns0.o arp.o crypto.o dump.o
|
||||
|
||||
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
||||
dns-protocol.h radv-protocol.h ip6addr.h
|
||||
|
@ -10,7 +10,8 @@ LOCAL_SRC_FILES := bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
|
||||
dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
|
||||
radv.c slaac.c auth.c ipset.c domain.c \
|
||||
dnssec.c dnssec-openssl.c blockdata.c tables.c \
|
||||
loop.c inotify.c poll.c rrfilter.c edns0.c arp.c crypto.c
|
||||
loop.c inotify.c poll.c rrfilter.c edns0.c arp.c \
|
||||
crypto.c dump.c
|
||||
|
||||
LOCAL_MODULE := dnsmasq
|
||||
|
||||
|
@ -647,6 +647,13 @@ V4 mapped IPv6 addresses, which have a representation like ::ffff:1.2.3.4 are ha
|
||||
The address range can be of the form
|
||||
<ip address>,<ip address> or <ip address>/<netmask> in both forms of the option.
|
||||
.TP
|
||||
.B --dumpfile=<path/to/file>
|
||||
Specify the location of a pcap-format file which dnsmasq uses to dump copies of network packets for debugging purposes. If the file exists when dnsmasq starts, it is not deleted; new packets are added to the end.
|
||||
.TP
|
||||
.B --dumpmask=<mask>
|
||||
Specify which types of packets should be added to the dumpfile. The argument should be the OR of the bitmasks for each type of packet to be dumped: it can be specified in hex by preceding the number with 0x in the normal way. Each time a packet is written to the dumpfile, dnsmasq logs the packet sequence and the mask
|
||||
representing its type. The current types are: 0x0001 - DNS queries from clients 0x0002 DNS replies to clients 0x0004 - DNS queries to upstream 0x0008 - DNS replies from upstream 0x0010 - queries send upstream for DNSSEC validation 0x0020 - replies to queries for DNSSEC validation 0x0040 - replies to client queries which fail DNSSEC validation 0x0080 replies to queries for DNSSEC validation which fail validation.
|
||||
.TP
|
||||
.B --add-mac[=base64|text]
|
||||
Add the MAC address of the requestor to DNS queries which are
|
||||
forwarded upstream. This may be used to DNS filtering by the upstream
|
||||
|
16
src/config.h
16
src/config.h
@ -117,6 +117,9 @@ HAVE_AUTH
|
||||
HAVE_DNSSEC
|
||||
include DNSSEC validator.
|
||||
|
||||
HAVE_DUMPFILE
|
||||
include code to dump packets to a libpcap-format file for debugging.
|
||||
|
||||
HAVE_LOOP
|
||||
include functionality to probe for and remove DNS forwarding loops.
|
||||
|
||||
@ -132,6 +135,7 @@ NO_DHCP6
|
||||
NO_SCRIPT
|
||||
NO_LARGEFILE
|
||||
NO_AUTH
|
||||
NO_DUMPFILE
|
||||
NO_INOTIFY
|
||||
these are available to explicitly disable compile time options which would
|
||||
otherwise be enabled automatically (HAVE_IPV6, >2Gb file sizes) or
|
||||
@ -164,6 +168,7 @@ RESOLVFILE
|
||||
#define HAVE_AUTH
|
||||
#define HAVE_IPSET
|
||||
#define HAVE_LOOP
|
||||
#define HAVE_DUMPFILE
|
||||
|
||||
/* Build options which require external libraries.
|
||||
|
||||
@ -363,6 +368,10 @@ HAVE_SOCKADDR_SA_LEN
|
||||
#undef HAVE_LOOP
|
||||
#endif
|
||||
|
||||
#ifdef NO_DUMPFILE
|
||||
#undef HAVE_DUMPFILE
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_LINUX_NETWORK) && !defined(NO_INOTIFY)
|
||||
#define HAVE_INOTIFY
|
||||
#endif
|
||||
@ -451,8 +460,11 @@ static char *compile_opts =
|
||||
#ifndef HAVE_INOTIFY
|
||||
"no-"
|
||||
#endif
|
||||
"inotify";
|
||||
|
||||
"inotify "
|
||||
#ifndef HAVE_DUMPFILE
|
||||
"no-"
|
||||
#endif
|
||||
"dumpfile";
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -366,7 +366,16 @@ int main (int argc, char **argv)
|
||||
else
|
||||
daemon->inotifyfd = -1;
|
||||
#endif
|
||||
|
||||
|
||||
if (daemon->dump_file)
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_init();
|
||||
else
|
||||
daemon->dumpfd = -1;
|
||||
#else
|
||||
die(_("Packet dumps not available: set HAVE_DUMP in src/config.h"), NULL, EC_BADCONF);
|
||||
#endif
|
||||
|
||||
if (option_bool(OPT_DBUS))
|
||||
#ifdef HAVE_DBUS
|
||||
{
|
||||
@ -1424,6 +1433,11 @@ static void async_event(int pipe, time_t now)
|
||||
|
||||
if (daemon->runfile)
|
||||
unlink(daemon->runfile);
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
if (daemon->dumpfd != -1)
|
||||
close(daemon->dumpfd);
|
||||
#endif
|
||||
|
||||
my_syslog(LOG_INFO, _("exiting on receipt of SIGTERM"));
|
||||
flush_log();
|
||||
|
@ -119,6 +119,9 @@ typedef unsigned long long u64;
|
||||
#include <net/if_arp.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#ifdef HAVE_IPV6
|
||||
#include <netinet/ip6.h>
|
||||
#endif
|
||||
#include <netinet/ip_icmp.h>
|
||||
#include <sys/uio.h>
|
||||
#include <syslog.h>
|
||||
@ -598,6 +601,16 @@ struct hostsfile {
|
||||
unsigned int index; /* matches to cache entries for logging */
|
||||
};
|
||||
|
||||
/* packet-dump flags */
|
||||
#define DUMP_QUERY 0x0001
|
||||
#define DUMP_REPLY 0x0002
|
||||
#define DUMP_UP_QUERY 0x0004
|
||||
#define DUMP_UP_REPLY 0x0008
|
||||
#define DUMP_SEC_QUERY 0x0010
|
||||
#define DUMP_SEC_REPLY 0x0020
|
||||
#define DUMP_BOGUS 0x0040
|
||||
#define DUMP_SEC_BOGUS 0x0080
|
||||
|
||||
|
||||
/* DNSSEC status values. */
|
||||
#define STAT_SECURE 1
|
||||
@ -1020,14 +1033,14 @@ extern struct daemon {
|
||||
unsigned int duid_enterprise, duid_config_len;
|
||||
unsigned char *duid_config;
|
||||
char *dbus_name;
|
||||
char *dump_file;
|
||||
int dump_mask;
|
||||
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
struct prefix_class *prefix_classes;
|
||||
#endif
|
||||
#ifdef HAVE_DNSSEC
|
||||
struct ds_config *ds;
|
||||
int dnssec_no_time_check;
|
||||
int back_to_the_future;
|
||||
char *timestamp_file;
|
||||
#endif
|
||||
|
||||
@ -1040,6 +1053,8 @@ extern struct daemon {
|
||||
char *workspacename; /* ditto */
|
||||
char *rr_status; /* flags for individual RRs */
|
||||
int rr_status_sz;
|
||||
int dnssec_no_time_check;
|
||||
int back_to_the_future;
|
||||
#endif
|
||||
unsigned int local_answer, queries_forwarded, auth_answer;
|
||||
struct frec *frec_list;
|
||||
@ -1094,6 +1109,10 @@ extern struct daemon {
|
||||
char *addrbuff;
|
||||
char *addrbuff2; /* only allocated when OPT_EXTRALOG */
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
/* file for packet dumps. */
|
||||
int dumpfd;
|
||||
#endif
|
||||
} *daemon;
|
||||
|
||||
/* cache.c */
|
||||
@ -1588,3 +1607,9 @@ int check_source(struct dns_header *header, size_t plen, unsigned char *pseudohe
|
||||
/* arp.c */
|
||||
int find_mac(union mysockaddr *addr, unsigned char *mac, int lazy, time_t now);
|
||||
int do_arp_script_run(void);
|
||||
|
||||
/* 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);
|
||||
#endif
|
||||
|
210
src/dump.c
Normal file
210
src/dump.c
Normal file
@ -0,0 +1,210 @@
|
||||
/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 dated June, 1991, or
|
||||
(at your option) version 3 dated 29 June, 2007.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "dnsmasq.h"
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
|
||||
static u32 packet_count;
|
||||
|
||||
/* https://wiki.wireshark.org/Development/LibpcapFileFormat */
|
||||
struct pcap_hdr_s {
|
||||
u32 magic_number; /* magic number */
|
||||
u16 version_major; /* major version number */
|
||||
u16 version_minor; /* minor version number */
|
||||
u32 thiszone; /* GMT to local correction */
|
||||
u32 sigfigs; /* accuracy of timestamps */
|
||||
u32 snaplen; /* max length of captured packets, in octets */
|
||||
u32 network; /* data link type */
|
||||
};
|
||||
|
||||
struct pcaprec_hdr_s {
|
||||
u32 ts_sec; /* timestamp seconds */
|
||||
u32 ts_usec; /* timestamp microseconds */
|
||||
u32 incl_len; /* number of octets of packet saved in file */
|
||||
u32 orig_len; /* actual length of packet */
|
||||
};
|
||||
|
||||
|
||||
void dump_init(void)
|
||||
{
|
||||
struct stat buf;
|
||||
struct pcap_hdr_s header;
|
||||
struct pcaprec_hdr_s pcap_header;
|
||||
|
||||
packet_count = 0;
|
||||
|
||||
if (stat(daemon->dump_file, &buf) == -1)
|
||||
{
|
||||
/* doesn't exist, create and add header */
|
||||
header.magic_number = 0xa1b2c3d4;
|
||||
header.version_major = 2;
|
||||
header.version_minor = 4;
|
||||
header.thiszone = 0;
|
||||
header.sigfigs = 0;
|
||||
header.snaplen = daemon->edns_pktsz + 200; /* slop for IP/UDP headers */
|
||||
header.network = 101; /* DLT_RAW http://www.tcpdump.org/linktypes.html */
|
||||
|
||||
if (errno != ENOENT ||
|
||||
(daemon->dumpfd = creat(daemon->dump_file, S_IRUSR | S_IWUSR)) == -1 ||
|
||||
!read_write(daemon->dumpfd, (void *)&header, sizeof(header), 0))
|
||||
die(_("cannot create %s: %s"), daemon->dump_file, EC_FILE);
|
||||
}
|
||||
else if ((daemon->dumpfd = open(daemon->dump_file, O_APPEND | O_RDWR)) == -1 ||
|
||||
!read_write(daemon->dumpfd, (void *)&header, sizeof(header), 1) ||
|
||||
header.magic_number != 0xa1b2c3d4)
|
||||
die(_("cannot access %s: %s"), daemon->dump_file, EC_FILE);
|
||||
else
|
||||
{
|
||||
/* count existing records */
|
||||
while (read_write(daemon->dumpfd, (void *)&pcap_header, sizeof(pcap_header), 1))
|
||||
{
|
||||
lseek(daemon->dumpfd, pcap_header.incl_len, SEEK_CUR);
|
||||
packet_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, union mysockaddr *dst)
|
||||
{
|
||||
struct ip ip;
|
||||
#ifdef HAVE_IPV6
|
||||
struct ip6_hdr ip6;
|
||||
int family;
|
||||
#endif
|
||||
struct udphdr {
|
||||
u16 uh_sport; /* source port */
|
||||
u16 uh_dport; /* destination port */
|
||||
u16 uh_ulen; /* udp length */
|
||||
u16 uh_sum; /* udp checksum */
|
||||
} udp;
|
||||
struct pcaprec_hdr_s pcap_header;
|
||||
struct timeval time;
|
||||
u32 i, sum;
|
||||
void *iphdr;
|
||||
size_t ipsz;
|
||||
int rc;
|
||||
|
||||
if (daemon->dumpfd == -1 || !(mask & daemon->dump_mask))
|
||||
return;
|
||||
|
||||
/* So wireshark can Id the packet. */
|
||||
udp.uh_sport = udp.uh_dport = htons(NAMESERVER_PORT);
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
if (src)
|
||||
family = src->sa.sa_family;
|
||||
else
|
||||
family = dst->sa.sa_family;
|
||||
|
||||
if (family == AF_INET6)
|
||||
{
|
||||
iphdr = &ip6;
|
||||
ipsz = sizeof(ip6);
|
||||
memset(&ip6, 0, sizeof(ip6));
|
||||
|
||||
ip6.ip6_vfc = 6 << 4;
|
||||
ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
|
||||
ip6.ip6_nxt = IPPROTO_UDP;
|
||||
ip6.ip6_hops = 64;
|
||||
|
||||
if (src)
|
||||
{
|
||||
memcpy(&ip6.ip6_src, &src->in6.sin6_addr, IN6ADDRSZ);
|
||||
udp.uh_sport = src->in6.sin6_port;
|
||||
}
|
||||
|
||||
if (dst)
|
||||
{
|
||||
memcpy(&ip6.ip6_dst, &dst->in6.sin6_addr, IN6ADDRSZ);
|
||||
udp.uh_dport = dst->in6.sin6_port;
|
||||
}
|
||||
|
||||
/* start UDP checksum */
|
||||
for (sum = 0, i = 0; i < IN6ADDRSZ; i++)
|
||||
sum += ((u16 *)&ip6.ip6_src)[i];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
iphdr = &ip;
|
||||
ipsz = sizeof(ip);
|
||||
memset(&ip, 0, sizeof(ip));
|
||||
|
||||
ip.ip_v = IPVERSION;
|
||||
ip.ip_hl = sizeof(struct ip) / 4;
|
||||
ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
|
||||
ip.ip_ttl = IPDEFTTL;
|
||||
ip.ip_p = IPPROTO_UDP;
|
||||
|
||||
if (src)
|
||||
{
|
||||
ip.ip_src = src->in.sin_addr;
|
||||
udp.uh_sport = src->in.sin_port;
|
||||
}
|
||||
|
||||
if (dst)
|
||||
{
|
||||
ip.ip_dst = dst->in.sin_addr;
|
||||
udp.uh_dport = dst->in.sin_port;
|
||||
}
|
||||
|
||||
ip.ip_sum = 0;
|
||||
for (sum = 0, i = 0; i < sizeof(struct ip) / 2; i++)
|
||||
sum += ((u16 *)&ip)[i];
|
||||
while (sum >> 16)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
|
||||
|
||||
/* start UDP checksum */
|
||||
sum = ip.ip_src.s_addr & 0xffff;
|
||||
sum += (ip.ip_src.s_addr >> 16) & 0xffff;
|
||||
sum += ip.ip_dst.s_addr & 0xffff;
|
||||
sum += (ip.ip_dst.s_addr >> 16) & 0xffff;
|
||||
}
|
||||
|
||||
if (len & 1)
|
||||
((unsigned char *)packet)[len] = 0; /* for checksum, in case length is odd. */
|
||||
|
||||
udp.uh_sum = 0;
|
||||
udp.uh_ulen = htons(sizeof(struct udphdr) + len);
|
||||
sum += htons(IPPROTO_UDP);
|
||||
sum += htons(sizeof(struct udphdr) + len);
|
||||
for (i = 0; i < sizeof(struct udphdr)/2; i++)
|
||||
sum += ((u16 *)&udp)[i];
|
||||
for (i = 0; i < (len + 1) / 2; i++)
|
||||
sum += ((u16 *)packet)[i];
|
||||
while (sum >> 16)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
udp.uh_sum = (sum == 0xffff) ? sum : ~sum;
|
||||
|
||||
rc = gettimeofday(&time, NULL);
|
||||
pcap_header.ts_sec = time.tv_sec;
|
||||
pcap_header.ts_usec = time.tv_usec;
|
||||
pcap_header.incl_len = pcap_header.orig_len = ipsz + sizeof(udp) + len;
|
||||
|
||||
if (rc == -1 ||
|
||||
!read_write(daemon->dumpfd, (void *)&pcap_header, sizeof(pcap_header), 0) ||
|
||||
!read_write(daemon->dumpfd, iphdr, ipsz, 0) ||
|
||||
!read_write(daemon->dumpfd, (void *)&udp, sizeof(udp), 0) ||
|
||||
!read_write(daemon->dumpfd, (void *)packet, len, 0))
|
||||
my_syslog(LOG_ERR, _("failed to write packet dump"));
|
||||
else
|
||||
my_syslog(LOG_INFO, _("dumping UDP packet %u mask 0x%04x"), ++packet_count, mask);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -508,6 +508,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||
|
||||
if (errno == 0)
|
||||
{
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_UP_QUERY, (void *)header, plen, NULL, &start->addr);
|
||||
#endif
|
||||
|
||||
/* Keep info in case we want to re-send this packet */
|
||||
daemon->srv_save = start;
|
||||
daemon->packet_len = plen;
|
||||
@ -769,7 +773,7 @@ void reply_query(int fd, int family, time_t now)
|
||||
#endif
|
||||
|
||||
header = (struct dns_header *)daemon->packet;
|
||||
|
||||
|
||||
if (n < (int)sizeof(struct dns_header) || !(header->hb3 & HB3_QR))
|
||||
return;
|
||||
|
||||
@ -796,6 +800,12 @@ void reply_query(int fd, int family, time_t now)
|
||||
if (!(forward = lookup_frec(ntohs(header->id), hash)))
|
||||
return;
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_REPLY : DUMP_UP_REPLY,
|
||||
(void *)header, n, &serveraddr, NULL);
|
||||
#endif
|
||||
|
||||
|
||||
/* log_query gets called indirectly all over the place, so
|
||||
pass these in global variables - sorry. */
|
||||
daemon->log_display_id = forward->log_id;
|
||||
@ -934,6 +944,11 @@ void reply_query(int fd, int family, time_t now)
|
||||
status = dnssec_validate_reply(now, header, n, daemon->namebuff, daemon->keyname, &forward->class,
|
||||
!option_bool(OPT_DNSSEC_IGN_NS) && (server->flags & SERV_DO_DNSSEC),
|
||||
NULL, NULL);
|
||||
#ifdef HAVE_DUMPFILE
|
||||
if (status == STAT_BOGUS)
|
||||
dump_packet((forward->flags & (FREC_DNSKEY_QUERY | FREC_DS_QUERY)) ? DUMP_SEC_BOGUS : DUMP_BOGUS,
|
||||
header, (size_t)n, &serveraddr, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Can't validate, as we're missing key data. Put this
|
||||
@ -1060,6 +1075,11 @@ void reply_query(int fd, int family, time_t now)
|
||||
setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(unsigned int));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_SEC_QUERY, (void *)header, (size_t)nn, NULL, &server->addr);
|
||||
#endif
|
||||
|
||||
while (retry_send(sendto(fd, (char *)header, nn, 0,
|
||||
&server->addr.sa,
|
||||
sa_len(&server->addr))));
|
||||
@ -1114,8 +1134,8 @@ void reply_query(int fd, int family, time_t now)
|
||||
bogusanswer = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* restore CD bit to the value in the query */
|
||||
if (forward->flags & FREC_CHECKING_DISABLED)
|
||||
header->hb4 |= HB4_CD;
|
||||
@ -1141,6 +1161,11 @@ void reply_query(int fd, int family, time_t now)
|
||||
nn = resize_packet(header, nn, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_REPLY, daemon->packet, (size_t)nn, NULL, &forward->source);
|
||||
#endif
|
||||
|
||||
send_from(forward->fd, option_bool(OPT_NOWILD) || option_bool (OPT_CLEVERBIND), daemon->packet, nn,
|
||||
&forward->source, &forward->dest, forward->iface);
|
||||
}
|
||||
@ -1394,7 +1419,11 @@ void receive_query(struct listener *listen, time_t now)
|
||||
pass these in global variables - sorry. */
|
||||
daemon->log_display_id = ++daemon->log_id;
|
||||
daemon->log_source_addr = &source_addr;
|
||||
|
||||
|
||||
#ifdef HAVE_DUMPFILE
|
||||
dump_packet(DUMP_QUERY, daemon->packet, (size_t)n, &source_addr, NULL);
|
||||
#endif
|
||||
|
||||
if (extract_request(header, (size_t)n, daemon->namebuff, &type))
|
||||
{
|
||||
#ifdef HAVE_AUTH
|
||||
|
14
src/option.c
14
src/option.c
@ -161,6 +161,8 @@ struct myoption {
|
||||
#define LOPT_TFTP_MTU 349
|
||||
#define LOPT_REPLY_DELAY 350
|
||||
#define LOPT_RAPID_COMMIT 351
|
||||
#define LOPT_DUMPFILE 352
|
||||
#define LOPT_DUMPMASK 353
|
||||
|
||||
#ifdef HAVE_GETOPT_LONG
|
||||
static const struct option opts[] =
|
||||
@ -327,6 +329,8 @@ static const struct myoption opts[] =
|
||||
{ "dhcp-ttl", 1, 0 , LOPT_DHCPTTL },
|
||||
{ "dhcp-reply-delay", 1, 0, LOPT_REPLY_DELAY },
|
||||
{ "dhcp-rapid-commit", 0, 0, LOPT_RAPID_COMMIT },
|
||||
{ "dumpfile", 1, 0, LOPT_DUMPFILE },
|
||||
{ "dumpmask", 1, 0, LOPT_DUMPMASK },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@ -500,6 +504,8 @@ static struct {
|
||||
{ LOPT_DHCPTTL, ARG_ONE, "<ttl>", gettext_noop("Set TTL in DNS responses with DHCP-derived addresses."), NULL },
|
||||
{ LOPT_REPLY_DELAY, ARG_ONE, "<integer>", gettext_noop("Delay DHCP replies for at least number of seconds."), NULL },
|
||||
{ LOPT_RAPID_COMMIT, OPT_RAPID_COMMIT, NULL, gettext_noop("Enables DHCPv4 Rapid Commit option."), NULL },
|
||||
{ LOPT_DUMPFILE, ARG_ONE, "<path>", gettext_noop("Path to debug packet dump file"), NULL },
|
||||
{ LOPT_DUMPMASK, ARG_ONE, "<hex>", gettext_noop("Mask which packets to dump"), NULL },
|
||||
{ 0, 0, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@ -1811,6 +1817,14 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
ret_err(_("bad MX target"));
|
||||
break;
|
||||
|
||||
case LOPT_DUMPFILE: /* --dumpfile */
|
||||
daemon->dump_file = opt_string_alloc(arg);
|
||||
break;
|
||||
|
||||
case LOPT_DUMPMASK: /* --dumpmask */
|
||||
daemon->dump_mask = strtol(arg, NULL, 0);
|
||||
break;
|
||||
|
||||
#ifdef HAVE_DHCP
|
||||
case 'l': /* --dhcp-leasefile */
|
||||
daemon->lease_file = opt_string_alloc(arg);
|
||||
|
Loading…
x
Reference in New Issue
Block a user