Hi, tcpdump feels a bit laggy or slow some times when i use it for live debugging.
The following patch adds a new flag, '-b', to tcpdump. With this flag, tcpdump sets BIOCIMMEDIATE for the current bpf(4) interface. With BIOCIMMEDIATE set, the output is fluent. Index: usr.sbin/tcpdump/privsep.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/privsep.c,v retrieving revision 1.30 diff -u -p -r1.30 privsep.c --- usr.sbin/tcpdump/privsep.c 22 Sep 2011 09:12:30 -0000 1.30 +++ usr.sbin/tcpdump/privsep.c 14 Dec 2014 22:40:14 -0000 @@ -318,7 +318,7 @@ priv_init(int argc, char **argv) static void impl_open_bpf(int fd, int *bpfd) { - int snaplen, promisc, err; + int snaplen, promisc, immediate, err; u_int dlt, dirfilt; char device[IFNAMSIZ]; size_t iflen; @@ -327,12 +327,13 @@ impl_open_bpf(int fd, int *bpfd) must_read(fd, &snaplen, sizeof(int)); must_read(fd, &promisc, sizeof(int)); + must_read(fd, &immediate, sizeof(int)); must_read(fd, &dlt, sizeof(u_int)); must_read(fd, &dirfilt, sizeof(u_int)); iflen = read_string(fd, device, sizeof(device), __func__); if (iflen == 0) errx(1, "Invalid interface size specified"); - *bpfd = pcap_live(device, snaplen, promisc, dlt, dirfilt); + *bpfd = pcap_live(device, snaplen, promisc, immediate, dlt, dirfilt); err = errno; if (*bpfd < 0) logmsg(LOG_DEBUG, Index: usr.sbin/tcpdump/privsep.h =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/privsep.h,v retrieving revision 1.7 diff -u -p -r1.7 privsep.h --- usr.sbin/tcpdump/privsep.h 25 Aug 2009 06:59:17 -0000 1.7 +++ usr.sbin/tcpdump/privsep.h 14 Dec 2014 22:40:14 -0000 @@ -47,10 +47,10 @@ int priv_init(int, char **); void priv_init_done(void); int setfilter(int, int, char *); -int pcap_live(const char *, int, int, u_int, u_int); +int pcap_live(const char *, int, int, int, u_int, u_int); struct bpf_program *priv_pcap_setfilter(pcap_t *, int, u_int32_t); -pcap_t *priv_pcap_live(const char *, int, int, int, char *, u_int, +pcap_t *priv_pcap_live(const char *, int, int, int, int, char *, u_int, u_int); pcap_t *priv_pcap_offline(const char *, char *); Index: usr.sbin/tcpdump/privsep_pcap.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/privsep_pcap.c,v retrieving revision 1.17 diff -u -p -r1.17 privsep_pcap.c --- usr.sbin/tcpdump/privsep_pcap.c 14 Nov 2012 03:33:04 -0000 1.17 +++ usr.sbin/tcpdump/privsep_pcap.c 14 Dec 2014 22:40:14 -0000 @@ -172,8 +172,8 @@ priv_pcap_setfilter(pcap_t *hpcap, int o /* privileged part of priv_pcap_live */ int -pcap_live(const char *device, int snaplen, int promisc, u_int dlt, - u_int dirfilt) +pcap_live(const char *device, int snaplen, int promisc, int immediate, + u_int dlt, u_int dirfilt) { char bpf[sizeof "/dev/bpf0000000000"]; int fd, n = 0; @@ -204,6 +204,10 @@ pcap_live(const char *device, int snaple if (promisc) /* this is allowed to fail */ ioctl(fd, BIOCPROMISC, NULL); + + if (immediate && ioctl(fd, BIOCIMMEDIATE, &immediate) < 0) + goto error; + if (ioctl(fd, BIOCSDIRFILT, &dirfilt) < 0) goto error; @@ -223,7 +227,7 @@ pcap_live(const char *device, int snaple * unprivileged part. */ pcap_t * -priv_pcap_live(const char *dev, int slen, int prom, int to_ms, +priv_pcap_live(const char *dev, int slen, int prom, int imme, int to_ms, char *ebuf, u_int dlt, u_int dirfilt) { int fd, err; @@ -251,6 +255,7 @@ priv_pcap_live(const char *dev, int slen write_command(priv_fd, PRIV_OPEN_BPF); must_write(priv_fd, &slen, sizeof(int)); must_write(priv_fd, &prom, sizeof(int)); + must_write(priv_fd, &imme, sizeof(int)); must_write(priv_fd, &dlt, sizeof(u_int)); must_write(priv_fd, &dirfilt, sizeof(u_int)); write_string(priv_fd, dev); Index: usr.sbin/tcpdump/tcpdump.8 =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/tcpdump.8,v retrieving revision 1.83 diff -u -p -r1.83 tcpdump.8 --- usr.sbin/tcpdump/tcpdump.8 3 Jun 2014 02:57:29 -0000 1.83 +++ usr.sbin/tcpdump/tcpdump.8 14 Dec 2014 22:40:15 -0000 @@ -28,7 +28,7 @@ .Sh SYNOPSIS .Nm tcpdump .Bk -words -.Op Fl AadefILlNnOopqStvXx +.Op Fl AabdefILlNnOopqStvXx .Op Fl c Ar count .Op Fl D Ar direction .Oo Fl E Oo Ar espalg : Oc Ns @@ -61,6 +61,9 @@ The smaller of the entire packet or bytes will be printed. .It Fl a Attempt to convert network and broadcast addresses to names. +.It Fl b +Disables read blocking on the bpf(4) buffer. With this so called +``immediate mode'' reads return immediately upon packet reception. .It Fl c Ar count Exit after receiving .Ar count Index: usr.sbin/tcpdump/tcpdump.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/tcpdump.c,v retrieving revision 1.66 diff -u -p -r1.66 tcpdump.c --- usr.sbin/tcpdump/tcpdump.c 30 Jun 2014 04:25:11 -0000 1.66 +++ usr.sbin/tcpdump/tcpdump.c 14 Dec 2014 22:40:15 -0000 @@ -60,6 +60,7 @@ int Aflag; /* dump ascii */ int aflag; /* translate network and broadcast addresses */ +int bflag; /* set read on livesession to non-blocking */ int dflag; /* print filter code */ int eflag; /* print ethernet header */ int fflag; /* don't translate "foreign" IP address */ @@ -226,7 +227,7 @@ main(int argc, char **argv) opterr = 0; while ((op = getopt(argc, argv, - "Aac:D:deE:fF:i:IlLnNOopqr:s:StT:vw:xXy:Y")) != -1) + "Aabc:D:deE:fF:i:IlLnNOopqr:s:StT:vw:xXy:Y")) != -1) switch (op) { case 'A': @@ -238,6 +239,10 @@ main(int argc, char **argv) ++aflag; break; + case 'b': + ++bflag; + break; + case 'c': cnt = atoi(optarg); if (cnt <= 0) @@ -429,8 +434,8 @@ main(int argc, char **argv) if (device == NULL) error("%s", ebuf); } - pd = priv_pcap_live(device, snaplen, !pflag, 1000, ebuf, - dlt, dirfilt); + pd = priv_pcap_live(device, snaplen, !pflag, bflag, 1000, + ebuf, dlt, dirfilt); if (pd == NULL) error("%s", ebuf);