diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index e56bcb7..b70ecdb 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -781,7 +781,7 @@ The address range can be of the form must fall in the same /64 network, or prefix-length must be greater than or equal to 64 except that shorter prefix lengths than 64 are allowed only if non-sequential names are in use. .TP .B --dumpfile= -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. +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. The file may be a named-pipe which Wireshark is listening to. .TP .B --dumpmask= 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 diff --git a/src/dump.c b/src/dump.c index 38dca7e..2920035 100644 --- a/src/dump.c +++ b/src/dump.c @@ -51,22 +51,30 @@ void dump_init(void) packet_count = 0; + 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 (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), RW_WRITE)) die(_("cannot create %s: %s"), daemon->dump_file, EC_FILE); } + else if (S_ISFIFO(buf.st_mode)) + { + /* File is named pipe (with wireshark on the other end, probably.) + Send header. */ + if ((daemon->dumpfd = open(daemon->dump_file, O_APPEND | O_RDWR)) == -1 || + !read_write(daemon->dumpfd, (void *)&header, sizeof(header), RW_WRITE)) + die(_("cannot open pipe %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), RW_READ)) die(_("cannot access %s: %s"), daemon->dump_file, EC_FILE);