Add linux netfilter NFLOG capture functionality initial commit

modified GetLinkHeaderSize to support link type
   modified ProcessLayer2 to support NFLOG packets
   expecting out of the box support from libpcap

hacking my way around bpf, bpf is not supported in libpcap (would be easy to implement) but at the moment, throw a warn if applying a filter and short circuit bpf code.

want to ensure this works... commenting out error states.

Fixed SetFilter to properly detect m_matches_anything, which is used by the DLT_NFLOG type to short circuit bpf filters.

Added NFLOG parsing to zeek source, added m_matches_anything flag check for bpf functionality (NFLOG is bpf incompatible, but shouldn't be)
This commit is contained in:
Ryan Denniston 2019-01-18 13:50:22 -08:00
parent 5618b21cca
commit 5262237c3b
3 changed files with 56 additions and 0 deletions

View file

@ -104,6 +104,13 @@ bool BPF_Program::Compile(int snaplen, int linktype, const char* filter,
{ {
FreeCode(); FreeCode();
if ( linktype == DLT_NFLOG ) //hacky way to support nflog but not bpf
{
m_compiled = true;
m_matches_anything = true;
return true;
}
#ifdef LIBPCAP_PCAP_COMPILE_NOPCAP_HAS_ERROR_PARAMETER #ifdef LIBPCAP_PCAP_COMPILE_NOPCAP_HAS_ERROR_PARAMETER
char my_error[PCAP_ERRBUF_SIZE]; char my_error[PCAP_ERRBUF_SIZE];

View file

@ -92,6 +92,9 @@ int Packet::GetLinkHeaderSize(int link_type)
case DLT_IEEE802_11_RADIO: // 802.11 plus RadioTap case DLT_IEEE802_11_RADIO: // 802.11 plus RadioTap
return 59; return 59;
case DLT_NFLOG: //Linux netlink NETLINK NFLOG socket log messages
return 8; //base l2 header up to TLV values
case DLT_RAW: case DLT_RAW:
return 0; return 0;
} }
@ -395,6 +398,47 @@ void Packet::ProcessLayer2()
break; break;
} }
case DLT_NFLOG:
{
int protocol = pdata[0]; //https://www.tcpdump.org/linktypes/LINKTYPE_NFLOG.html
if ( protocol == AF_INET )
l3_proto = L3_IPV4;
else if ( protocol == AF_INET6 )
l3_proto = L3_IPV6;
//skip header to tlv structs
pdata += 4;
int tlv_len;
int tlv_type;
while(1){
if ( pdata >= end_of_data )
{
Weird("nflog_no_pcap_payload");
return;
}
tlv_len = (pdata[1] << 8 )+ pdata[0]; //lil' endian
tlv_type = (pdata[3] << 8) + pdata[2];
//tlv's are in groups of 8 bytes min padding apparently
if (tlv_len < 8){
tlv_len = 8;
}
//if 9, then raw packet is straight away after.
if (tlv_type == 9){ //type nflog payload
pdata += 4; //skip the tlv type and length to put the payload at the front of the buffer.
break;
}else{
pdata += tlv_len;
}
}
break;
}
default: default:
{ {
// Assume we're pointing at IP. Just figure out which version. // Assume we're pointing at IP. Just figure out which version.

View file

@ -247,6 +247,11 @@ bool PcapSource::SetFilter(int index)
return false; return false;
} }
//if the filter matches anything, return true
if ( code->MatchesAnything() )
{
return true;
}
if ( pcap_setfilter(pd, code->GetProgram()) < 0 ) if ( pcap_setfilter(pd, code->GetProgram()) < 0 )
{ {
PcapError(); PcapError();