Skip to content

Commit

Permalink
VLAN 4095 now means "all VLANs" for -l / -L command line options.
Browse files Browse the repository at this point in the history
Previously VLAN 0 was taken to mean all VLANs, but it seems that 0
is a valid ID that might appear on the wire.  4095 is also reserved
and less likely to appear on the wire.  Thanks Daniel Stirnimann
for the bug report.
  • Loading branch information
wessels committed Aug 26, 2015
1 parent d335378 commit 727d0a3
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 14 deletions.
4 changes: 2 additions & 2 deletions dnscap.1
Expand Up @@ -124,13 +124,13 @@ as the input packet source. Can be given as "-" to indicate standard input.
.It Fl l Ar vlan
Captures only 802.1Q encapsulated packets, and selects specific vlans to be
monitored. Can be specified more than once to select multiple vlans.
.Fl l Ar 0
.Fl l Ar 4095
means "all vlans".
.It Fl L Ar vlan
Captures 802.1Q encapsulated packets matching the specified vlans AND
packets without VLAN tags. Can be specified more than one to select
multiple vlans.
.Fl L Ar 0
.Fl L Ar 4095
means "all vlans".
.It Fl u Ar port
Capture only packets on this UDP port, and treat as DNS traffic. The default
Expand Down
32 changes: 20 additions & 12 deletions dnscap.c
Expand Up @@ -533,8 +533,8 @@ help_2(void) {
"\t-I include ICMP and ICMPv6 packets\n"
"\t-i <if> select this live interface(s)\n"
"\t-r <file> read this pcap file\n"
"\t-l <vlan> select only these vlan(s)\n"
"\t-L <vlan> select these vlan(s) and non-VLAN frames\n"
"\t-l <vlan> select only these vlan(s) (4095 for all)\n"
"\t-L <vlan> select these vlan(s) and non-VLAN frames (4095 for all)\n"
"\t-u <port> dns port (default: 53)\n"
"\t-m [qun] select messages: query, update, notify\n"
"\t-s [ir] select sides: initiations, responses\n"
Expand Down Expand Up @@ -648,22 +648,32 @@ parse_args(int argc, char *argv[]) {
case 'l':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul > MAX_VLAN)
usage("vlan must be 0 or an integer 1..4095");
usage("vlan must be an integer 0..4095");
vlan = malloc(sizeof *vlan);
assert(vlan != NULL);
INIT_LINK(vlan, link);
vlan->vlan = (unsigned) ul;
APPEND(vlans_excl, vlan, link);
if (0 == ul)
fprintf(stderr, "Warning: previous versions of %s "
"interpreted 0 as all VLANs. "
"If you want all VLANs now you must "
"specify %u.\n", ProgramName, MAX_VLAN);
break;
case 'L':
ul = strtoul(optarg, &p, 0);
if (*p != '\0' || ul > MAX_VLAN)
usage("vlan must be 0 or an integer 1..4095");
usage("vlan must be an integer 0..4095");
vlan = malloc(sizeof *vlan);
assert(vlan != NULL);
INIT_LINK(vlan, link);
vlan->vlan = (unsigned) ul;
APPEND(vlans_incl, vlan, link);
if (0 == ul)
fprintf(stderr, "Warning: previous versions of %s "
"interpreted 0 as all VLANs. "
"If you want all VLANs now you must "
"specify %u.\n", ProgramName, MAX_VLAN);
break;
case 'T':
wanttcp = TRUE;
Expand Down Expand Up @@ -1450,7 +1460,7 @@ dl_pkt(u_char *user, const struct pcap_pkthdr *hdr, const u_char *pkt) {
return;

/* Data link. */
vlan = 0;
vlan = MAX_VLAN; /* MAX_VLAN (0xFFF) is reserved and shouldn't appear on the wire */
switch (mypcap->dlt) {
case DLT_NULL: {
uint32_t x;
Expand Down Expand Up @@ -1510,11 +1520,9 @@ dl_pkt(u_char *user, const struct pcap_pkthdr *hdr, const u_char *pkt) {
if (etype == ETHERTYPE_VLAN) {
if (len < 4)
return;
vlan = ntohs(*(const uint16_t *) pkt);
vlan = ntohs(*(const uint16_t *) pkt) & 0xFFF;
pkt += 2;
len -= 2;
if (vlan < 1 || vlan > MAX_VLAN)
return;
etype = ntohs(*(const uint16_t *) pkt);
pkt += 2;
len -= 2;
Expand All @@ -1541,7 +1549,7 @@ dl_pkt(u_char *user, const struct pcap_pkthdr *hdr, const u_char *pkt) {
for (vl = HEAD(vlans_excl);
vl != NULL;
vl = NEXT(vl, link))
if (vl->vlan == vlan || vl->vlan == 0)
if (vl->vlan == vlan || vl->vlan == MAX_VLAN)
break;
// If there is no VLAN matching the packet, skip it
if (vl == NULL)
Expand All @@ -1553,11 +1561,11 @@ dl_pkt(u_char *user, const struct pcap_pkthdr *hdr, const u_char *pkt) {
for (vl = HEAD(vlans_incl);
vl != NULL;
vl = NEXT(vl, link))
if (vl->vlan == vlan || vl->vlan == 0)
if (vl->vlan == vlan || vl->vlan == MAX_VLAN)
break;
// If there is no VLAN matching the packet, and the packet is
// tagged, skip it
if (vl == NULL && vlan != 0)
if (vl == NULL && vlan != MAX_VLAN)
return;
}

Expand All @@ -1583,7 +1591,7 @@ dl_pkt(u_char *user, const struct pcap_pkthdr *hdr, const u_char *pkt) {
strcpy(via, (mypcap->name == NULL)
? "\"some interface\""
: mypcap->name);
if (vlan != 0)
if (vlan != MAX_VLAN)
sprintf(via + strlen(via), " (vlan %u)", vlan);
sprintf(descr, "[%lu] %s.%06lu [#%ld %s %u] \\\n",
(u_long)len, when, (u_long)hdr->ts.tv_usec,
Expand Down

0 comments on commit 727d0a3

Please sign in to comment.