File: 52_allow-specifying-a-custom-pcap-filter.patch

package info (click to toggle)
arpwatch 2.1a15-8
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 1,988 kB
  • sloc: sh: 3,047; ansic: 2,811; makefile: 90; awk: 90; perl: 15
file content (144 lines) | stat: -rw-r--r-- 3,384 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
Author: Stefan Voelkel <bd@bc-bd.org>
Description: allow specifying a custom pcap filter
Bug-Debian: https://bugs.debian.org/600886

Giving the user an option to specify a custom pcap filter is both very
versatile (can be used to satisfy the request from multiple wishlist bugs) and
little intrusive (the code is only run during startup) addition.

Slightly adjusted by Lukas Schwaighofer <lukas@schwaighofer.name> from the
patch submitted by Stefan Voelkel <bd@bc-bd.org> to the Debian BTS.
---
 arpwatch.8 | 15 +++++++++++++++
 arpwatch.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 62 insertions(+), 1 deletion(-)

--- a/arpwatch.8
+++ b/arpwatch.8
@@ -68,6 +68,14 @@
 .br
 .ti +8
 [
+.B -F
+.I filter
+]
+.\" **
+.\" **
+.br
+.ti +8
+[
 .B -s
 .I sendmail_path
 ]
@@ -182,6 +190,16 @@
 .\" **
 .\" **
 .LP
+(Debian) The
+.B -F
+option is used to specify a pcap filter, which provides a generic way of
+ignoring specific packets.  The applied pcap filter will be "(arp or rarp) and
+not vlan and (filter)".  See
+.BR pcap-filter (7)
+for the syntax of that string.
+.\" **
+.\" **
+.LP
 (Debian) The
 .B -s
 flag is used to specify the path to the sendmail program.
--- a/arpwatch.c
+++ b/arpwatch.c
@@ -166,6 +166,40 @@
       syslog(LOG_INFO, "Running as uid=%d gid=%d", getuid(), getgid());
 }
 
+int compile_filter(pcap_t *p, struct bpf_program *fp, const char *filter_user,
+	bpf_u_int32 netmask)
+{
+	int len, result;
+
+	char *filter = NULL;
+	static const char filter_default[] = "(arp or rarp) and not vlan";
+	// will get appended with " and ()" (7 characters), where the filter
+	// specified by the user will be added between the brackets
+
+	if (filter_user && strlen(filter_user)) {
+		/* calculate needed space for filter string. */
+		len = strlen(filter_user) + strlen(filter_default) + 7 + 1;
+		filter = malloc(len);
+		if (!filter) {
+			syslog(LOG_ERR, "compile_filter: out of memory");
+			return -1;
+		}
+		result = snprintf(filter, len, "%s and (%s)", filter_default, filter_user);
+		if (result != len - 1) {
+			syslog(LOG_ERR, "compile_filter: snprintf() error");
+			free(filter);
+			return -1;
+		}
+		syslog(LOG_INFO, "using pcap filter '%s'", filter);
+		result = pcap_compile(p, fp, filter, 1, netmask);
+		free(filter);
+	} else {
+		result = pcap_compile(p, fp, filter_default, 1, netmask);
+	}
+
+	return result;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -179,6 +213,7 @@
 	struct bpf_program code;
 	char errbuf[PCAP_ERRBUF_SIZE];
 	char* username = NULL;
+	char *filter_user = NULL;
 	char options[] =
 		"d"
 		/**/
@@ -186,6 +221,9 @@
 		"f:"
 		/**/
 		/**/
+		"F:"
+		/**/
+		/**/
 		"i:"
 		/**/
 		/**/
@@ -260,6 +298,10 @@
 			arpfile = optarg;
 			break;
 
+		case 'F':
+			filter_user = strdup(optarg);
+			break;
+
 		case 'i':
 			interface = optarg;
 			break;
@@ -443,10 +485,11 @@
 	}
 
 	/* Compile and install filter */
-	if (pcap_compile(pd, &code, "(arp or rarp) and not vlan", 1, netmask) < 0) {
+	if (compile_filter(pd, &code, filter_user, netmask) < 0) {
 		syslog(LOG_ERR, "pcap_compile: %s", pcap_geterr(pd));
 		exit(1);
 	}
+	free(filter_user);
 	if (pcap_setfilter(pd, &code) < 0) {
 		syslog(LOG_ERR, "pcap_setfilter: %s", pcap_geterr(pd));
 		exit(1);
@@ -915,6 +958,9 @@
 		"[-f datafile] "
 		/**/
 		/**/
+		"[-F \"filter\" ]"
+		/**/
+		/**/
 		"[-i interface] "
 		/**/
 		/**/