diff --git a/CHANGES b/CHANGES index 19976358be..586ae2437e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,14 @@ +3.3.0-dev.403 | 2020-10-13 10:50:12 -0700 + + * Add new Pcap::findalldevs() BIF (Seth Hall, Corelight) + + * Remove superfluous RuleCondition destructors (Jon Siwek, Corelight) + + * Silence Clang's warning about ignoring GCC's maybe-uninitialized warning (Jon Siwek, Corelight) + + * Add reference to network_time_init from zeek_init docs (Jon Siwek, Corelight) + 3.3.0-dev.390 | 2020-10-12 17:43:15 -0700 * Improve documentation for zeek_init event scheduling pitfalls (Jon Siwek, Corelight) diff --git a/VERSION b/VERSION index ea0e8675c9..b61175c6d6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3.0-dev.390 +3.3.0-dev.403 diff --git a/scripts/base/init-bare.zeek b/scripts/base/init-bare.zeek index b7a2b1b80c..fe1419fa26 100644 --- a/scripts/base/init-bare.zeek +++ b/scripts/base/init-bare.zeek @@ -4976,6 +4976,26 @@ export { ## Number of Mbytes to provide as buffer space when capturing from live ## interfaces. const bufsize = 128 &redef; + + ## The definition of a "pcap interface". + type Interface: record { + ## The interface/device name. + name: string; + ## A human-readable description of the device. + description: string &optional; + ## The network addresses associated with the device. + addrs: set[addr]; + ## Whether the device is a loopback interface. E.g. addresses + ## of ``127.0.0.1`` or ``[::1]`` are used by loopback interfaces. + is_loopback: bool; + + ## Whether the device is up. Not set when that info is unavailable. + is_up: bool &optional; + ## Whether the device is running. Not set when that info is unavailable. + is_running: bool &optional; + }; + + type Interfaces: set[Pcap::Interface]; } # end export module DCE_RPC; diff --git a/src/iosource/pcap/pcap.bif b/src/iosource/pcap/pcap.bif index 5655a8fac9..c37416c968 100644 --- a/src/iosource/pcap/pcap.bif +++ b/src/iosource/pcap/pcap.bif @@ -1,10 +1,13 @@ module Pcap; + const snaplen: count; const bufsize: count; %%{ +#include "pcap.h" + #include "iosource/Manager.h" %%} @@ -102,3 +105,57 @@ function error%(%): string return zeek::make_intrusive("no error"); %} + +function findalldevs%(%): Pcap::Interfaces + %{ + pcap_if_t* alldevs; + char errbuf[PCAP_ERRBUF_SIZE]; + + static auto ifaces_type = id::find_type("Pcap::Interfaces"); + auto pcap_interfaces = make_intrusive(ifaces_type); + + int ret = pcap_findalldevs(&alldevs, errbuf); + if ( ret == PCAP_ERROR ) + { + emit_builtin_error(util::fmt("Error calling pcap_findalldevs: %s", errbuf)); + // Return an empty set in case of failure. + return pcap_interfaces; + } + + static auto iface_type = id::find_type("Pcap::Interface"); + for ( auto d = alldevs; d; d = d->next ) + { + auto r = make_intrusive(iface_type); + + r->Assign(0, make_intrusive(d->name)); + if ( d->description ) + r->Assign(1, make_intrusive(d->description)); + + auto addrs = make_intrusive(TYPE_ADDR); + for ( auto addr = d->addresses; addr != NULL; addr = addr->next ) + { + if ( addr->addr->sa_family == AF_INET ) + { + IPAddr a(reinterpret_cast(addr->addr)->sin_addr); + addrs->Append(make_intrusive(a)); + } + else if ( addr->addr->sa_family == AF_INET6 ) + { + IPAddr a(reinterpret_cast(addr->addr)->sin6_addr); + addrs->Append(make_intrusive(a)); + } + } + r->Assign(2, addrs->ToSetVal()); + r->Assign(3, val_mgr->Bool(d->flags & PCAP_IF_LOOPBACK)); +#ifdef PCAP_IF_UP + // These didn't become available until libpcap 1.6.1 + r->Assign(4, val_mgr->Bool(d->flags & PCAP_IF_UP)); + r->Assign(5, val_mgr->Bool(d->flags & PCAP_IF_RUNNING)); +#endif + + pcap_interfaces->Assign(std::move(r), nullptr); + } + + pcap_freealldevs(alldevs); + return pcap_interfaces; + %}