> > +#define BIOCGQUEUE _IOR('B',126, u_int32_t)
> > +#define BIOCSQUEUE _IOW('B',127, u_int32_t)
>
> these ioctls can take u_int to be consistent with how you're using
> them.
Sorry everyone. I wanted to make it all the same type -- u_int32_t,
and obviously forgot it in the kernel part.
Do you think using u_int is better? I'll change it in the other diff.
OK now? Anything else? If you don't tell people what are they doing
wrong, they'll just keep doing it ;-)
--
Martin Pelikan
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 19 Mar 2013 16:10:42 -0000
@@ -18,6 +18,7 @@
*/
#include <sys/types.h>
+#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/wait.h>
@@ -125,6 +126,41 @@ static void impl_getlines(int);
static void test_state(int, int);
static void logmsg(int, const char *, ...);
+
+static u_int
+find_queue(const char *device, const char *queue)
+{
+ int fd;
+ u_int32_t q, total;
+ struct pfioc_altq pa;
+
+ if ((fd = open("/dev/pf", O_RDONLY)) == -1)
+ err(2, "can't open pf to get queue ID");
+
+ memset(&pa, 0, sizeof pa);
+ if (ioctl(fd, DIOCGETALTQS, &pa))
+ err(2, "DIOCGETALTQS");
+
+ total = pa.nr;
+ for (q = 0; q < total; ++q) {
+ pa.nr = q;
+ if (ioctl(fd, DIOCGETALTQ, &pa))
+ err(2, "DIOCGETALTQ, number %u", q);
+ if (pa.altq.qid == 0)
+ continue;
+ if (strncmp(pa.altq.ifname, device, sizeof pa.altq.ifname))
+ continue;
+ if (strncmp(pa.altq.qname, queue, sizeof pa.altq.qname))
+ continue;
+ break;
+ }
+ close(fd);
+ if (q == total)
+ warnx("WARNING: no queue %s on interface %s, choosing all",
+ queue, device);
+ return (q == total ? 0 : pa.altq.qid);
+}
+
int
priv_init(int argc, char **argv)
{
@@ -200,7 +236,7 @@ priv_init(int argc, char **argv)
/* parse the arguments for required options */
opterr = 0;
while ((i = getopt(argc, argv,
- "ac:D:deE:fF:i:lLnNOopqr:s:StT:vw:xXy:Y")) != -1) {
+ "ac:D:deE:fF:i:lLnNOopQ:qr:s:StT:vw:xXy:Y")) != -1) {
switch (i) {
case 'n':
nflag++;
@@ -319,9 +355,9 @@ static void
impl_open_bpf(int fd, int *bpfd)
{
int snaplen, promisc, err;
- u_int dlt, dirfilt;
- char device[IFNAMSIZ];
- size_t iflen;
+ u_int dlt, dirfilt, qid = 0;
+ char device[IFNAMSIZ], queue[PF_QNAME_SIZE];
+ size_t iflen, qlen;
logmsg(LOG_DEBUG, "[priv]: msg PRIV_OPEN_BPF received");
@@ -332,7 +368,10 @@ impl_open_bpf(int fd, int *bpfd)
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);
+ qlen = read_string(fd, queue, sizeof queue, __func__);
+ if (qlen > 1)
+ qid = find_queue(device, queue);
+ *bpfd = pcap_live(device, snaplen, promisc, dlt, dirfilt, qid);
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 19 Mar 2013 16:10:42 -0000
@@ -47,11 +47,11 @@ 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, u_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,
- u_int);
+ u_int, const char *);
pcap_t *priv_pcap_offline(const char *, char *);
size_t priv_gethostbyaddr(char *, size_t, int, char *, size_t);
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 19 Mar 2013 16:10:42 -0000
@@ -173,7 +173,7 @@ 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)
+ u_int dirfilt, u_int qid)
{
char bpf[sizeof "/dev/bpf0000000000"];
int fd, n = 0;
@@ -206,6 +206,8 @@ pcap_live(const char *device, int snaple
ioctl(fd, BIOCPROMISC, NULL);
if (ioctl(fd, BIOCSDIRFILT, &dirfilt) < 0)
goto error;
+ if (qid && ioctl(fd, BIOCSQUEUE, &qid) < 0)
+ goto error;
/* lock the descriptor */
if (ioctl(fd, BIOCLOCK, NULL) < 0)
@@ -224,7 +226,7 @@ pcap_live(const char *device, int snaple
*/
pcap_t *
priv_pcap_live(const char *dev, int slen, int prom, int to_ms,
- char *ebuf, u_int dlt, u_int dirfilt)
+ char *ebuf, u_int dlt, u_int dirfilt, const char *queue)
{
int fd, err;
struct bpf_version bv;
@@ -254,6 +256,7 @@ priv_pcap_live(const char *dev, int slen
must_write(priv_fd, &dlt, sizeof(u_int));
must_write(priv_fd, &dirfilt, sizeof(u_int));
write_string(priv_fd, dev);
+ write_string(priv_fd, queue);
fd = receive_fd(priv_fd);
must_read(priv_fd, &err, sizeof(int));
Index: usr.sbin/tcpdump/tcpdump.8
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/tcpdump.8,v
retrieving revision 1.79
diff -u -p -r1.79 tcpdump.8
--- usr.sbin/tcpdump/tcpdump.8 26 Sep 2012 16:19:45 -0000 1.79
+++ usr.sbin/tcpdump/tcpdump.8 19 Mar 2013 16:10:42 -0000
@@ -35,6 +35,7 @@
.Ar espkey Oc
.Op Fl F Ar file
.Op Fl i Ar interface
+.Op Fl Q Ar queue
.Op Fl r Ar file
.Op Fl s Ar snaplen
.Op Fl T Ar type
@@ -176,6 +177,14 @@ cannot be used as an abbreviation for
.Dq ether host \&"{local-hw-addr}\&"
or
.Dq ether broadcast .
+.It Fl Q Ar queue
+Display only traffic going out of this queue (see
+.Xr altq 9
+or
+.Xr pf 4
+for reference).
+If no such queue exists on the selected interface, a warning is displayed.
+Note that queueing applies only to outbound traffic.
.It Fl q
Quick
.Pq quiet?
Index: usr.sbin/tcpdump/tcpdump.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/tcpdump.c,v
retrieving revision 1.65
diff -u -p -r1.65 tcpdump.c
--- usr.sbin/tcpdump/tcpdump.c 11 Jul 2012 10:37:38 -0000 1.65
+++ usr.sbin/tcpdump/tcpdump.c 19 Mar 2013 16:10:42 -0000
@@ -82,6 +82,7 @@ int packettype;
char *program_name;
char *device = NULL;
+char *queue = NULL, noqueue[1] = "";
int32_t thiszone; /* seconds offset from gmt to local time */
@@ -229,7 +230,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)
+ "Aac:D:deE:fF:i:IlLnNOopQ:qr:s:StT:vw:xXy:Y")) != -1)
switch (op) {
case 'A':
@@ -309,6 +310,10 @@ main(int argc, char **argv)
++pflag;
break;
+ case 'Q':
+ queue = optarg;
+ break;
+
case 'q':
++qflag;
break;
@@ -432,8 +437,12 @@ main(int argc, char **argv)
if (device == NULL)
error("%s", ebuf);
}
+ if (queue == NULL)
+ queue = noqueue;
+ else if (dirfilt == BPF_DIRECTION_OUT)
+ error("queueing happens on -D way OUT!");
pd = priv_pcap_live(device, snaplen, !pflag, 1000, ebuf,
- dlt, dirfilt);
+ dlt, dirfilt, queue);
if (pd == NULL)
error("%s", ebuf);
@@ -487,10 +496,12 @@ main(int argc, char **argv)
/* state: STATE_RUN */
}
if (RFileName == NULL) {
- (void)fprintf(stderr, "%s: listening on %s, link-type ",
- program_name, device);
+ fprintf(stderr, "%s: listening on %s", program_name, device);
+ if (queue && queue != noqueue)
+ fprintf(stderr, ", queue %s", queue);
+ fprintf(stderr, ", link-type ");
pcap_print_linktype(pd->linktype);
- (void)fflush(stderr);
+ fflush(stderr);
}
if (oflag)