<commit_before>diff --git a/src/PktSrc.cc b/src/PktSrc.cc
index 9d6bce6..e8f59dd 100644
--- a/src/PktSrc.cc
+++ b/src/PktSrc.cc
@@ -11,6 +11,26 @@
 #include "Net.h"
 #include "Sessions.h"
 
+#define HAVE_NETMAP
+
+#ifdef HAVE_NETMAP
+
+// Compile in netmap support. If the interface name starts with
+// "netmap:" or "vale" we use a netmap fd instead of pcap, and bind
+// one or all rings depending on NETMAP_RING_ID environment variable.
+//
+// For a test run  you can use the vale switch,
+//	pkt-gen -i vale1:b -f tx -R ..rate_in_pps
+// and launch bro like this
+/*
+
+BROPATH=`./bro-path-dev` ./src/bro -i vale1:a -b -e 'global l=0; event p(){local s=net_stats(); local c=s$pkts_recvd;print c-l;l=c; schedule 1 sec {p()};} event bro_init(){event p();}'
+
+ */
+#define NETMAP_WITH_LIBS
+#include <net/netmap_user.h>
+
+#endif /* HAVE_NETMAP */
 
 // ### This needs auto-confing.
 #ifdef HAVE_PCAP_INT_H
@@ -75,7 +95,15 @@ int PktSrc::ExtractNextPacket()
 		return 0;
 		}
 
+#ifdef HAVE_NETMAP
+	// in netmap mode call netmap equivalent of pcap_next()
+	if (IS_NETMAP_DESC(pd))
+		data = last_data = nm_nextpkt((struct nm_desc_t *)pd,
+				(struct nm_hdr_t *)&hdr);
+	else
+#else /* !HAVE_NETMAP */
 	data = last_data = pcap_next(pd, &hdr);
+#endif /* !HAVE_NETMAP */
 
 	if ( data && (hdr.len == 0 || hdr.caplen == 0) )
 		{
@@ -407,6 +435,11 @@ void PktSrc::Close()
 	{
 	if ( pd )
 		{
+#ifdef HAVE_NETMAP
+		if (IS_NETMAP_DESC(pd))
+			nm_close((struct nm_desc_t *)pd);
+		else
+#endif /* HAVE_NETMAP */
 		pcap_close(pd);
 		pd = 0;
 		closed = true;
@@ -443,6 +476,14 @@ void PktSrc::Statistics(Stats* s)
 	else
 		{
 		struct pcap_stat pstat;
+#ifdef HAVE_NETMAP
+		if (IS_NETMAP_DESC(pd))
+			{
+			s->dropped = stats.dropped;
+			s->link = stats.received;
+			}
+		else
+#endif /* HAVE_NETMAP */
 		if ( pcap_stats(pd, &pstat) < 0 )
 			{
 			reporter->Error("problem getting packet filter statistics: %s",
@@ -482,6 +523,21 @@ PktInterfaceSrc::PktInterfaceSrc(const char* arg_interface, const char* filter,
 
 	interface = copy_string(arg_interface);
 
+#ifdef HAVE_NETMAP
+	pd = (pcap_t *)nm_open(interface, getenv("NETMAP_RING_ID"), 0, 0);
+	// netmap interfaces are named netmap:* or vale*
+	// If pd == 0 && errno == 0 "interface" is not a valid
+	// netmap interface name, so we fall through to pcap
+	if (pd || errno > 0)
+		{
+		if (pd)
+			selectable_fd = NETMAP_FD(pd);
+		else
+			closed = true;
+		return;
+		}
+#endif /* HAVE_NETMAP */
+
 	// Determine network and netmask.
 	uint32 net;
 	if ( pcap_lookupnet(interface, &net, &netmask, tmp_errbuf) < 0 )
<commit_msg>update bro header<commit_after>diff --git a/src/PktSrc.cc b/src/PktSrc.cc
index 9d6bce6..e8f59dd 100644
--- a/src/PktSrc.cc
+++ b/src/PktSrc.cc
@@ -11,6 +11,26 @@
 #include "Net.h"
 #include "Sessions.h"
 
+#define HAVE_NETMAP
+
+#ifdef HAVE_NETMAP
+
+// Compile in netmap support. If the interface name starts with
+// "netmap:" or "vale" we use a netmap fd instead of pcap, and bind
+// one or all rings depending on NETMAP_RING_ID environment variable.
+//
+// For a test run  you can use the vale switch,
+//	pkt-gen -i vale1:b -f tx -R ..rate_in_pps
+// and launch bro like this
+/*
+
+BROPATH=`./bro-path-dev` ./src/bro -i vale1:a -b -e 'global l=0; event p(){local s=net_stats(); local c=s$pkts_recvd;print c-l;l=c; schedule 1 sec {p()};} event bro_init(){event p();}'
+
+ */
+#define NETMAP_WITH_LIBS
+#include <net/netmap_user.h>
+
+#endif /* HAVE_NETMAP */
 
 // ### This needs auto-confing.
 #ifdef HAVE_PCAP_INT_H
@@ -75,7 +95,14 @@ int PktSrc::ExtractNextPacket()
 		return 0;
 		}
 
+#ifdef HAVE_NETMAP
+	// in netmap mode call netmap equivalent of pcap_next()
+	if (IS_NETMAP_DESC(pd))
+		data = last_data = nm_nextpkt((struct nm_desc_t *)pd,
+				(struct nm_hdr_t *)&hdr);
+	else
+#endif /* HAVE_NETMAP */
 	data = last_data = pcap_next(pd, &hdr);
 
 	if ( data && (hdr.len == 0 || hdr.caplen == 0) )
 		{
@@ -407,6 +435,11 @@ void PktSrc::Close()
 	{
 	if ( pd )
 		{
+#ifdef HAVE_NETMAP
+		if (IS_NETMAP_DESC(pd))
+			nm_close((struct nm_desc_t *)pd);
+		else
+#endif /* HAVE_NETMAP */
 		pcap_close(pd);
 		pd = 0;
 		closed = true;
@@ -443,6 +476,14 @@ void PktSrc::Statistics(Stats* s)
 	else
 		{
 		struct pcap_stat pstat;
+#ifdef HAVE_NETMAP
+		if (IS_NETMAP_DESC(pd))
+			{
+			s->dropped = stats.dropped;
+			s->link = stats.received;
+			}
+		else
+#endif /* HAVE_NETMAP */
 		if ( pcap_stats(pd, &pstat) < 0 )
 			{
 			reporter->Error("problem getting packet filter statistics: %s",
@@ -482,6 +523,21 @@ PktInterfaceSrc::PktInterfaceSrc(const char* arg_interface, const char* filter,
 
 	interface = copy_string(arg_interface);
 
+#ifdef HAVE_NETMAP
+	pd = (pcap_t *)nm_open(interface, getenv("NETMAP_RING_ID"), 0, 0);
+	// netmap interfaces are named netmap:* or vale*
+	// If pd == 0 && errno == 0 "interface" is not a valid
+	// netmap interface name, so we fall through to pcap
+	if (pd || errno > 0)
+		{
+		if (pd)
+			selectable_fd = NETMAP_FD(pd);
+		else
+			closed = true;
+		return;
+		}
+#endif /* HAVE_NETMAP */
+
 	// Determine network and netmask.
 	uint32 net;
 	if ( pcap_lookupnet(interface, &net, &netmask, tmp_errbuf) < 0 )

{'fraction_non_alphanumeric': 0.1710195395627781, 'fraction_numerical': 0.027084542464693363, 'mean_word_length': 3.4839549002601906, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1164312', 'n_tokens_mistral': 2337, 'n_tokens_neox': 2156, 'n_words': 534}