Support for (mixed) MPLS and VLAN traffic, and a new default BPF

filter. (Seth Hall and Robin Sommer)

- Merging in the patch from #264, which provides support for mixed
  VLAN and MPLS traffic.

- Changing Bro's default filter from being built dynamically to being
  a static "ip or not ip". To get the old behaviour back (i.e., the
  dynamically built filter), redef "all_packets" to false.

- print-filter.bro now always prints the filter that Bro is actually
  using, even if overriden from the command line.
This commit is contained in:
Robin Sommer 2011-04-28 21:14:52 -07:00
parent b01aa66fe6
commit 9ddc26328d
18 changed files with 170 additions and 35 deletions

View file

@ -181,16 +181,98 @@ void PktSrc::Process()
current_timestamp = next_timestamp;
int pkt_hdr_size = hdr_size;
// Unfortunately some packets on the link might have MPLS labels
// while others don't. That means we need to ask the link-layer if
// labels are in place.
bool have_mpls = false;
int protocol = 0;
switch ( datalink ) {
case DLT_NULL:
{
protocol = (data[3] << 24) + (data[2] << 16) + (data[1] << 8) + data[0];
if ( protocol != AF_INET && protocol != AF_INET6 )
{
sessions->Weird("non_ip_packet_in_null_transport", &hdr, data);
data = 0;
return;
}
break;
}
case DLT_EN10MB:
{
// Get protocol being carried from the ethernet frame.
protocol = (data[12] << 8) + data[13];
// MPLS carried over the ethernet frame.
if ( protocol == 0x8847 )
have_mpls = true;
// VLAN carried over ethernet frame.
else if ( protocol == 0x8100 )
{
data += get_link_header_size(datalink);
data += 4; // Skip the vlan header
pkt_hdr_size = 0;
}
break;
}
case DLT_PPP_SERIAL:
{
// Get PPP protocol.
protocol = (data[2] << 8) + data[3];
if ( protocol == 0x0281 )
// MPLS Unicast
have_mpls = true;
else if ( protocol != 0x0021 && protocol != 0x0057 )
{
// Neither IPv4 nor IPv6.
sessions->Weird("non_ip_packet_in_ppp_encapsulation", &hdr, data);
data = 0;
return;
}
break;
}
}
if ( have_mpls )
{
// Remove the data link layer
data += get_link_header_size(datalink);
// Denote a header size of zero before the IP header
pkt_hdr_size = 0;
// Skip the MPLS label stack.
bool end_of_stack = false;
while ( ! end_of_stack )
{
end_of_stack = *(data + 2) & 0x01;
data += 4;
}
}
if ( pseudo_realtime )
{
current_pseudo = CheckPseudoTime();
net_packet_arrival(current_pseudo, &hdr, data, hdr_size, this);
net_packet_arrival(current_pseudo, &hdr, data, pkt_hdr_size, this);
if ( ! first_wallclock )
first_wallclock = current_time(true);
}
else
net_packet_arrival(current_timestamp, &hdr, data, hdr_size, this);
net_packet_arrival(current_timestamp, &hdr, data, pkt_hdr_size, this);
data = 0;
}
@ -399,6 +481,11 @@ PktInterfaceSrc::PktInterfaceSrc(const char* arg_interface, const char* filter,
if ( PrecompileFilter(0, filter) && SetFilter(0) )
{
SetHdrSize();
if ( closed )
// Couldn't get header size.
return;
fprintf(stderr, "listening on %s\n", interface);
}
else
@ -647,6 +734,9 @@ int get_link_header_size(int dl)
return 16;
#endif
case DLT_PPP_SERIAL: // PPP_SERIAL
return 4;
case DLT_RAW:
return 0;
}