xref: /aosp_15_r20/external/libpcap/pcap-dbus.c (revision 8b26181f966a6af5cf6981a6f474313de533bb28)
1*8b26181fSAndroid Build Coastguard Worker /*
2*8b26181fSAndroid Build Coastguard Worker  * Copyright (c) 2012 Jakub Zawadzki
3*8b26181fSAndroid Build Coastguard Worker  * All rights reserved.
4*8b26181fSAndroid Build Coastguard Worker  *
5*8b26181fSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without
6*8b26181fSAndroid Build Coastguard Worker  * modification, are permitted provided that the following conditions
7*8b26181fSAndroid Build Coastguard Worker  * are met:
8*8b26181fSAndroid Build Coastguard Worker  *
9*8b26181fSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright
10*8b26181fSAndroid Build Coastguard Worker  * notice, this list of conditions and the following disclaimer.
11*8b26181fSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright
12*8b26181fSAndroid Build Coastguard Worker  * notice, this list of conditions and the following disclaimer in the
13*8b26181fSAndroid Build Coastguard Worker  * documentation and/or other materials provided with the distribution.
14*8b26181fSAndroid Build Coastguard Worker  * 3. The name of the author may not be used to endorse or promote
15*8b26181fSAndroid Build Coastguard Worker  * products derived from this software without specific prior written
16*8b26181fSAndroid Build Coastguard Worker  * permission.
17*8b26181fSAndroid Build Coastguard Worker  *
18*8b26181fSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19*8b26181fSAndroid Build Coastguard Worker  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20*8b26181fSAndroid Build Coastguard Worker  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21*8b26181fSAndroid Build Coastguard Worker  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22*8b26181fSAndroid Build Coastguard Worker  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23*8b26181fSAndroid Build Coastguard Worker  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24*8b26181fSAndroid Build Coastguard Worker  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25*8b26181fSAndroid Build Coastguard Worker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26*8b26181fSAndroid Build Coastguard Worker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*8b26181fSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28*8b26181fSAndroid Build Coastguard Worker  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*8b26181fSAndroid Build Coastguard Worker  */
30*8b26181fSAndroid Build Coastguard Worker 
31*8b26181fSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
32*8b26181fSAndroid Build Coastguard Worker #include <config.h>
33*8b26181fSAndroid Build Coastguard Worker #endif
34*8b26181fSAndroid Build Coastguard Worker 
35*8b26181fSAndroid Build Coastguard Worker #include <string.h>
36*8b26181fSAndroid Build Coastguard Worker 
37*8b26181fSAndroid Build Coastguard Worker #include <time.h>
38*8b26181fSAndroid Build Coastguard Worker #include <sys/time.h>
39*8b26181fSAndroid Build Coastguard Worker 
40*8b26181fSAndroid Build Coastguard Worker #include <dbus/dbus.h>
41*8b26181fSAndroid Build Coastguard Worker 
42*8b26181fSAndroid Build Coastguard Worker #include "pcap-int.h"
43*8b26181fSAndroid Build Coastguard Worker #include "pcap-dbus.h"
44*8b26181fSAndroid Build Coastguard Worker 
45*8b26181fSAndroid Build Coastguard Worker /*
46*8b26181fSAndroid Build Coastguard Worker  * Private data for capturing on D-Bus.
47*8b26181fSAndroid Build Coastguard Worker  */
48*8b26181fSAndroid Build Coastguard Worker struct pcap_dbus {
49*8b26181fSAndroid Build Coastguard Worker 	DBusConnection *conn;
50*8b26181fSAndroid Build Coastguard Worker 	u_int	packets_read;	/* count of packets read */
51*8b26181fSAndroid Build Coastguard Worker };
52*8b26181fSAndroid Build Coastguard Worker 
53*8b26181fSAndroid Build Coastguard Worker static int
dbus_read(pcap_t * handle,int max_packets _U_,pcap_handler callback,u_char * user)54*8b26181fSAndroid Build Coastguard Worker dbus_read(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user)
55*8b26181fSAndroid Build Coastguard Worker {
56*8b26181fSAndroid Build Coastguard Worker 	struct pcap_dbus *handlep = handle->priv;
57*8b26181fSAndroid Build Coastguard Worker 
58*8b26181fSAndroid Build Coastguard Worker 	struct pcap_pkthdr pkth;
59*8b26181fSAndroid Build Coastguard Worker 	DBusMessage *message;
60*8b26181fSAndroid Build Coastguard Worker 
61*8b26181fSAndroid Build Coastguard Worker 	char *raw_msg;
62*8b26181fSAndroid Build Coastguard Worker 	int raw_msg_len;
63*8b26181fSAndroid Build Coastguard Worker 
64*8b26181fSAndroid Build Coastguard Worker 	int count = 0;
65*8b26181fSAndroid Build Coastguard Worker 
66*8b26181fSAndroid Build Coastguard Worker 	message = dbus_connection_pop_message(handlep->conn);
67*8b26181fSAndroid Build Coastguard Worker 
68*8b26181fSAndroid Build Coastguard Worker 	while (!message) {
69*8b26181fSAndroid Build Coastguard Worker 		/* XXX handle->opt.timeout = timeout_ms; */
70*8b26181fSAndroid Build Coastguard Worker 		if (!dbus_connection_read_write(handlep->conn, 100)) {
71*8b26181fSAndroid Build Coastguard Worker 			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed");
72*8b26181fSAndroid Build Coastguard Worker 			return -1;
73*8b26181fSAndroid Build Coastguard Worker 		}
74*8b26181fSAndroid Build Coastguard Worker 
75*8b26181fSAndroid Build Coastguard Worker 		if (handle->break_loop) {
76*8b26181fSAndroid Build Coastguard Worker 			handle->break_loop = 0;
77*8b26181fSAndroid Build Coastguard Worker 			return -2;
78*8b26181fSAndroid Build Coastguard Worker 		}
79*8b26181fSAndroid Build Coastguard Worker 
80*8b26181fSAndroid Build Coastguard Worker 		message = dbus_connection_pop_message(handlep->conn);
81*8b26181fSAndroid Build Coastguard Worker 	}
82*8b26181fSAndroid Build Coastguard Worker 
83*8b26181fSAndroid Build Coastguard Worker 	if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
84*8b26181fSAndroid Build Coastguard Worker 		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected");
85*8b26181fSAndroid Build Coastguard Worker 		return -1;
86*8b26181fSAndroid Build Coastguard Worker 	}
87*8b26181fSAndroid Build Coastguard Worker 
88*8b26181fSAndroid Build Coastguard Worker 	if (dbus_message_marshal(message, &raw_msg, &raw_msg_len)) {
89*8b26181fSAndroid Build Coastguard Worker 		pkth.caplen = pkth.len = raw_msg_len;
90*8b26181fSAndroid Build Coastguard Worker 		/* pkth.caplen = min (payload_len, handle->snapshot); */
91*8b26181fSAndroid Build Coastguard Worker 
92*8b26181fSAndroid Build Coastguard Worker 		gettimeofday(&pkth.ts, NULL);
93*8b26181fSAndroid Build Coastguard Worker 		if (handle->fcode.bf_insns == NULL ||
94*8b26181fSAndroid Build Coastguard Worker 		    pcap_filter(handle->fcode.bf_insns, (u_char *)raw_msg, pkth.len, pkth.caplen)) {
95*8b26181fSAndroid Build Coastguard Worker 			handlep->packets_read++;
96*8b26181fSAndroid Build Coastguard Worker 			callback(user, &pkth, (u_char *)raw_msg);
97*8b26181fSAndroid Build Coastguard Worker 			count++;
98*8b26181fSAndroid Build Coastguard Worker 		}
99*8b26181fSAndroid Build Coastguard Worker 
100*8b26181fSAndroid Build Coastguard Worker 		dbus_free(raw_msg);
101*8b26181fSAndroid Build Coastguard Worker 	}
102*8b26181fSAndroid Build Coastguard Worker 	return count;
103*8b26181fSAndroid Build Coastguard Worker }
104*8b26181fSAndroid Build Coastguard Worker 
105*8b26181fSAndroid Build Coastguard Worker static int
dbus_write(pcap_t * handle,const void * buf,int size)106*8b26181fSAndroid Build Coastguard Worker dbus_write(pcap_t *handle, const void *buf, int size)
107*8b26181fSAndroid Build Coastguard Worker {
108*8b26181fSAndroid Build Coastguard Worker 	/* XXX, not tested */
109*8b26181fSAndroid Build Coastguard Worker 	struct pcap_dbus *handlep = handle->priv;
110*8b26181fSAndroid Build Coastguard Worker 
111*8b26181fSAndroid Build Coastguard Worker 	DBusError error = DBUS_ERROR_INIT;
112*8b26181fSAndroid Build Coastguard Worker 	DBusMessage *msg;
113*8b26181fSAndroid Build Coastguard Worker 
114*8b26181fSAndroid Build Coastguard Worker 	if (!(msg = dbus_message_demarshal(buf, size, &error))) {
115*8b26181fSAndroid Build Coastguard Worker 		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dbus_message_demarshal() failed: %s", error.message);
116*8b26181fSAndroid Build Coastguard Worker 		dbus_error_free(&error);
117*8b26181fSAndroid Build Coastguard Worker 		return -1;
118*8b26181fSAndroid Build Coastguard Worker 	}
119*8b26181fSAndroid Build Coastguard Worker 
120*8b26181fSAndroid Build Coastguard Worker 	dbus_connection_send(handlep->conn, msg, NULL);
121*8b26181fSAndroid Build Coastguard Worker 	dbus_connection_flush(handlep->conn);
122*8b26181fSAndroid Build Coastguard Worker 
123*8b26181fSAndroid Build Coastguard Worker 	dbus_message_unref(msg);
124*8b26181fSAndroid Build Coastguard Worker 	return 0;
125*8b26181fSAndroid Build Coastguard Worker }
126*8b26181fSAndroid Build Coastguard Worker 
127*8b26181fSAndroid Build Coastguard Worker static int
dbus_stats(pcap_t * handle,struct pcap_stat * stats)128*8b26181fSAndroid Build Coastguard Worker dbus_stats(pcap_t *handle, struct pcap_stat *stats)
129*8b26181fSAndroid Build Coastguard Worker {
130*8b26181fSAndroid Build Coastguard Worker 	struct pcap_dbus *handlep = handle->priv;
131*8b26181fSAndroid Build Coastguard Worker 
132*8b26181fSAndroid Build Coastguard Worker 	stats->ps_recv = handlep->packets_read;
133*8b26181fSAndroid Build Coastguard Worker 	stats->ps_drop = 0;
134*8b26181fSAndroid Build Coastguard Worker 	stats->ps_ifdrop = 0;
135*8b26181fSAndroid Build Coastguard Worker 	return 0;
136*8b26181fSAndroid Build Coastguard Worker }
137*8b26181fSAndroid Build Coastguard Worker 
138*8b26181fSAndroid Build Coastguard Worker static void
dbus_cleanup(pcap_t * handle)139*8b26181fSAndroid Build Coastguard Worker dbus_cleanup(pcap_t *handle)
140*8b26181fSAndroid Build Coastguard Worker {
141*8b26181fSAndroid Build Coastguard Worker 	struct pcap_dbus *handlep = handle->priv;
142*8b26181fSAndroid Build Coastguard Worker 
143*8b26181fSAndroid Build Coastguard Worker 	dbus_connection_unref(handlep->conn);
144*8b26181fSAndroid Build Coastguard Worker 
145*8b26181fSAndroid Build Coastguard Worker 	pcap_cleanup_live_common(handle);
146*8b26181fSAndroid Build Coastguard Worker }
147*8b26181fSAndroid Build Coastguard Worker 
148*8b26181fSAndroid Build Coastguard Worker /*
149*8b26181fSAndroid Build Coastguard Worker  * We don't support non-blocking mode.  I'm not sure what we'd
150*8b26181fSAndroid Build Coastguard Worker  * do to support it and, given that we don't support select()/
151*8b26181fSAndroid Build Coastguard Worker  * poll()/epoll_wait()/kevent() etc., it probably doesn't
152*8b26181fSAndroid Build Coastguard Worker  * matter.
153*8b26181fSAndroid Build Coastguard Worker  */
154*8b26181fSAndroid Build Coastguard Worker static int
dbus_getnonblock(pcap_t * p)155*8b26181fSAndroid Build Coastguard Worker dbus_getnonblock(pcap_t *p)
156*8b26181fSAndroid Build Coastguard Worker {
157*8b26181fSAndroid Build Coastguard Worker 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
158*8b26181fSAndroid Build Coastguard Worker 	    "Non-blocking mode isn't supported for capturing on D-Bus");
159*8b26181fSAndroid Build Coastguard Worker 	return (-1);
160*8b26181fSAndroid Build Coastguard Worker }
161*8b26181fSAndroid Build Coastguard Worker 
162*8b26181fSAndroid Build Coastguard Worker static int
dbus_setnonblock(pcap_t * p,int nonblock _U_)163*8b26181fSAndroid Build Coastguard Worker dbus_setnonblock(pcap_t *p, int nonblock _U_)
164*8b26181fSAndroid Build Coastguard Worker {
165*8b26181fSAndroid Build Coastguard Worker 	snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
166*8b26181fSAndroid Build Coastguard Worker 	    "Non-blocking mode isn't supported for capturing on D-Bus");
167*8b26181fSAndroid Build Coastguard Worker 	return (-1);
168*8b26181fSAndroid Build Coastguard Worker }
169*8b26181fSAndroid Build Coastguard Worker 
170*8b26181fSAndroid Build Coastguard Worker static int
dbus_activate(pcap_t * handle)171*8b26181fSAndroid Build Coastguard Worker dbus_activate(pcap_t *handle)
172*8b26181fSAndroid Build Coastguard Worker {
173*8b26181fSAndroid Build Coastguard Worker #define EAVESDROPPING_RULE "eavesdrop=true,"
174*8b26181fSAndroid Build Coastguard Worker 
175*8b26181fSAndroid Build Coastguard Worker 	static const char *rules[] = {
176*8b26181fSAndroid Build Coastguard Worker 		EAVESDROPPING_RULE "type='signal'",
177*8b26181fSAndroid Build Coastguard Worker 		EAVESDROPPING_RULE "type='method_call'",
178*8b26181fSAndroid Build Coastguard Worker 		EAVESDROPPING_RULE "type='method_return'",
179*8b26181fSAndroid Build Coastguard Worker 		EAVESDROPPING_RULE "type='error'",
180*8b26181fSAndroid Build Coastguard Worker 	};
181*8b26181fSAndroid Build Coastguard Worker 
182*8b26181fSAndroid Build Coastguard Worker 	#define N_RULES sizeof(rules)/sizeof(rules[0])
183*8b26181fSAndroid Build Coastguard Worker 
184*8b26181fSAndroid Build Coastguard Worker 	struct pcap_dbus *handlep = handle->priv;
185*8b26181fSAndroid Build Coastguard Worker 	const char *dev = handle->opt.device;
186*8b26181fSAndroid Build Coastguard Worker 
187*8b26181fSAndroid Build Coastguard Worker 	DBusError error = DBUS_ERROR_INIT;
188*8b26181fSAndroid Build Coastguard Worker 	u_int i;
189*8b26181fSAndroid Build Coastguard Worker 
190*8b26181fSAndroid Build Coastguard Worker 	if (strcmp(dev, "dbus-system") == 0) {
191*8b26181fSAndroid Build Coastguard Worker 		if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
192*8b26181fSAndroid Build Coastguard Worker 			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get system bus: %s", error.message);
193*8b26181fSAndroid Build Coastguard Worker 			dbus_error_free(&error);
194*8b26181fSAndroid Build Coastguard Worker 			return PCAP_ERROR;
195*8b26181fSAndroid Build Coastguard Worker 		}
196*8b26181fSAndroid Build Coastguard Worker 
197*8b26181fSAndroid Build Coastguard Worker 	} else if (strcmp(dev, "dbus-session") == 0) {
198*8b26181fSAndroid Build Coastguard Worker 		if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SESSION, &error))) {
199*8b26181fSAndroid Build Coastguard Worker 			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get session bus: %s", error.message);
200*8b26181fSAndroid Build Coastguard Worker 			dbus_error_free(&error);
201*8b26181fSAndroid Build Coastguard Worker 			return PCAP_ERROR;
202*8b26181fSAndroid Build Coastguard Worker 		}
203*8b26181fSAndroid Build Coastguard Worker 
204*8b26181fSAndroid Build Coastguard Worker 	} else if (strncmp(dev, "dbus://", 7) == 0) {
205*8b26181fSAndroid Build Coastguard Worker 		const char *addr = dev + 7;
206*8b26181fSAndroid Build Coastguard Worker 
207*8b26181fSAndroid Build Coastguard Worker 		if (!(handlep->conn = dbus_connection_open(addr, &error))) {
208*8b26181fSAndroid Build Coastguard Worker 			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to open connection to: %s: %s", addr, error.message);
209*8b26181fSAndroid Build Coastguard Worker 			dbus_error_free(&error);
210*8b26181fSAndroid Build Coastguard Worker 			return PCAP_ERROR;
211*8b26181fSAndroid Build Coastguard Worker 		}
212*8b26181fSAndroid Build Coastguard Worker 
213*8b26181fSAndroid Build Coastguard Worker 		if (!dbus_bus_register(handlep->conn, &error)) {
214*8b26181fSAndroid Build Coastguard Worker 			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to register bus %s: %s\n", addr, error.message);
215*8b26181fSAndroid Build Coastguard Worker 			dbus_error_free(&error);
216*8b26181fSAndroid Build Coastguard Worker 			return PCAP_ERROR;
217*8b26181fSAndroid Build Coastguard Worker 		}
218*8b26181fSAndroid Build Coastguard Worker 
219*8b26181fSAndroid Build Coastguard Worker 	} else {
220*8b26181fSAndroid Build Coastguard Worker 		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get bus address from %s", handle->opt.device);
221*8b26181fSAndroid Build Coastguard Worker 		return PCAP_ERROR;
222*8b26181fSAndroid Build Coastguard Worker 	}
223*8b26181fSAndroid Build Coastguard Worker 
224*8b26181fSAndroid Build Coastguard Worker 	/* Initialize some components of the pcap structure. */
225*8b26181fSAndroid Build Coastguard Worker 	handle->bufsize = 0;
226*8b26181fSAndroid Build Coastguard Worker 	handle->offset = 0;
227*8b26181fSAndroid Build Coastguard Worker 	handle->linktype = DLT_DBUS;
228*8b26181fSAndroid Build Coastguard Worker 	handle->read_op = dbus_read;
229*8b26181fSAndroid Build Coastguard Worker 	handle->inject_op = dbus_write;
230*8b26181fSAndroid Build Coastguard Worker 	handle->setfilter_op = install_bpf_program; /* XXX, later add support for dbus_bus_add_match() */
231*8b26181fSAndroid Build Coastguard Worker 	handle->setdirection_op = NULL;
232*8b26181fSAndroid Build Coastguard Worker 	handle->set_datalink_op = NULL;      /* can't change data link type */
233*8b26181fSAndroid Build Coastguard Worker 	handle->getnonblock_op = dbus_getnonblock;
234*8b26181fSAndroid Build Coastguard Worker 	handle->setnonblock_op = dbus_setnonblock;
235*8b26181fSAndroid Build Coastguard Worker 	handle->stats_op = dbus_stats;
236*8b26181fSAndroid Build Coastguard Worker 	handle->cleanup_op = dbus_cleanup;
237*8b26181fSAndroid Build Coastguard Worker 
238*8b26181fSAndroid Build Coastguard Worker #ifndef _WIN32
239*8b26181fSAndroid Build Coastguard Worker 	/*
240*8b26181fSAndroid Build Coastguard Worker 	 * Unfortunately, trying to do a select()/poll()/epoll_wait()/
241*8b26181fSAndroid Build Coastguard Worker 	 * kevent()/etc. on a D-Bus connection isn't a simple
242*8b26181fSAndroid Build Coastguard Worker 	 * case of "give me an FD on which to wait".
243*8b26181fSAndroid Build Coastguard Worker 	 *
244*8b26181fSAndroid Build Coastguard Worker 	 * Apparently, you have to register "add watch", "remove watch",
245*8b26181fSAndroid Build Coastguard Worker 	 * and "toggle watch" functions with
246*8b26181fSAndroid Build Coastguard Worker 	 * dbus_connection_set_watch_functions(),
247*8b26181fSAndroid Build Coastguard Worker 	 * keep a *set* of FDs, add to that set in the "add watch"
248*8b26181fSAndroid Build Coastguard Worker 	 * function, subtract from it in the "remove watch" function,
249*8b26181fSAndroid Build Coastguard Worker 	 * and either add to or subtract from that set in the "toggle
250*8b26181fSAndroid Build Coastguard Worker 	 * watch" function, and do the wait on *all* of the FDs in the
251*8b26181fSAndroid Build Coastguard Worker 	 * set.  (Yes, you need the "toggle watch" function, so that
252*8b26181fSAndroid Build Coastguard Worker 	 * the main loop doesn't itself need to check for whether
253*8b26181fSAndroid Build Coastguard Worker 	 * a given watch is enabled or disabled - most libpcap programs
254*8b26181fSAndroid Build Coastguard Worker 	 * know nothing about D-Bus and shouldn't *have* to know anything
255*8b26181fSAndroid Build Coastguard Worker 	 * about D-Bus other than how to decode D-Bus messages.)
256*8b26181fSAndroid Build Coastguard Worker 	 *
257*8b26181fSAndroid Build Coastguard Worker 	 * Implementing that would require considerable changes in
258*8b26181fSAndroid Build Coastguard Worker 	 * the way libpcap exports "selectable FDs" to its client.
259*8b26181fSAndroid Build Coastguard Worker 	 * Until that's done, we just say "you can't do that".
260*8b26181fSAndroid Build Coastguard Worker 	 */
261*8b26181fSAndroid Build Coastguard Worker 	handle->selectable_fd = handle->fd = -1;
262*8b26181fSAndroid Build Coastguard Worker #endif
263*8b26181fSAndroid Build Coastguard Worker 
264*8b26181fSAndroid Build Coastguard Worker 	if (handle->opt.rfmon) {
265*8b26181fSAndroid Build Coastguard Worker 		/*
266*8b26181fSAndroid Build Coastguard Worker 		 * Monitor mode doesn't apply to dbus connections.
267*8b26181fSAndroid Build Coastguard Worker 		 */
268*8b26181fSAndroid Build Coastguard Worker 		dbus_cleanup(handle);
269*8b26181fSAndroid Build Coastguard Worker 		return PCAP_ERROR_RFMON_NOTSUP;
270*8b26181fSAndroid Build Coastguard Worker 	}
271*8b26181fSAndroid Build Coastguard Worker 
272*8b26181fSAndroid Build Coastguard Worker 	/*
273*8b26181fSAndroid Build Coastguard Worker 	 * Turn a negative snapshot value (invalid), a snapshot value of
274*8b26181fSAndroid Build Coastguard Worker 	 * 0 (unspecified), or a value bigger than the normal maximum
275*8b26181fSAndroid Build Coastguard Worker 	 * value, into the maximum message length for D-Bus (128MB).
276*8b26181fSAndroid Build Coastguard Worker 	 */
277*8b26181fSAndroid Build Coastguard Worker 	if (handle->snapshot <= 0 || handle->snapshot > 134217728)
278*8b26181fSAndroid Build Coastguard Worker 		handle->snapshot = 134217728;
279*8b26181fSAndroid Build Coastguard Worker 
280*8b26181fSAndroid Build Coastguard Worker 	/* dbus_connection_set_max_message_size(handlep->conn, handle->snapshot); */
281*8b26181fSAndroid Build Coastguard Worker 	if (handle->opt.buffer_size != 0)
282*8b26181fSAndroid Build Coastguard Worker 		dbus_connection_set_max_received_size(handlep->conn, handle->opt.buffer_size);
283*8b26181fSAndroid Build Coastguard Worker 
284*8b26181fSAndroid Build Coastguard Worker 	for (i = 0; i < N_RULES; i++) {
285*8b26181fSAndroid Build Coastguard Worker 		dbus_bus_add_match(handlep->conn, rules[i], &error);
286*8b26181fSAndroid Build Coastguard Worker 		if (dbus_error_is_set(&error)) {
287*8b26181fSAndroid Build Coastguard Worker 			dbus_error_free(&error);
288*8b26181fSAndroid Build Coastguard Worker 
289*8b26181fSAndroid Build Coastguard Worker 			/* try without eavesdrop */
290*8b26181fSAndroid Build Coastguard Worker 			dbus_bus_add_match(handlep->conn, rules[i] + strlen(EAVESDROPPING_RULE), &error);
291*8b26181fSAndroid Build Coastguard Worker 			if (dbus_error_is_set(&error)) {
292*8b26181fSAndroid Build Coastguard Worker 				snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to add bus match: %s\n", error.message);
293*8b26181fSAndroid Build Coastguard Worker 				dbus_error_free(&error);
294*8b26181fSAndroid Build Coastguard Worker 				dbus_cleanup(handle);
295*8b26181fSAndroid Build Coastguard Worker 				return PCAP_ERROR;
296*8b26181fSAndroid Build Coastguard Worker 			}
297*8b26181fSAndroid Build Coastguard Worker 		}
298*8b26181fSAndroid Build Coastguard Worker 	}
299*8b26181fSAndroid Build Coastguard Worker 
300*8b26181fSAndroid Build Coastguard Worker 	return 0;
301*8b26181fSAndroid Build Coastguard Worker }
302*8b26181fSAndroid Build Coastguard Worker 
303*8b26181fSAndroid Build Coastguard Worker pcap_t *
dbus_create(const char * device,char * ebuf,int * is_ours)304*8b26181fSAndroid Build Coastguard Worker dbus_create(const char *device, char *ebuf, int *is_ours)
305*8b26181fSAndroid Build Coastguard Worker {
306*8b26181fSAndroid Build Coastguard Worker 	pcap_t *p;
307*8b26181fSAndroid Build Coastguard Worker 
308*8b26181fSAndroid Build Coastguard Worker 	if (strcmp(device, "dbus-system") &&
309*8b26181fSAndroid Build Coastguard Worker 		strcmp(device, "dbus-session") &&
310*8b26181fSAndroid Build Coastguard Worker 		strncmp(device, "dbus://", 7))
311*8b26181fSAndroid Build Coastguard Worker 	{
312*8b26181fSAndroid Build Coastguard Worker 		*is_ours = 0;
313*8b26181fSAndroid Build Coastguard Worker 		return NULL;
314*8b26181fSAndroid Build Coastguard Worker 	}
315*8b26181fSAndroid Build Coastguard Worker 
316*8b26181fSAndroid Build Coastguard Worker 	*is_ours = 1;
317*8b26181fSAndroid Build Coastguard Worker 	p = PCAP_CREATE_COMMON(ebuf, struct pcap_dbus);
318*8b26181fSAndroid Build Coastguard Worker 	if (p == NULL)
319*8b26181fSAndroid Build Coastguard Worker 		return (NULL);
320*8b26181fSAndroid Build Coastguard Worker 
321*8b26181fSAndroid Build Coastguard Worker 	p->activate_op = dbus_activate;
322*8b26181fSAndroid Build Coastguard Worker 	/*
323*8b26181fSAndroid Build Coastguard Worker 	 * Set these up front, so that, even if our client tries
324*8b26181fSAndroid Build Coastguard Worker 	 * to set non-blocking mode before we're activated, or
325*8b26181fSAndroid Build Coastguard Worker 	 * query the state of non-blocking mode, they get an error,
326*8b26181fSAndroid Build Coastguard Worker 	 * rather than having the non-blocking mode option set
327*8b26181fSAndroid Build Coastguard Worker 	 * for use later.
328*8b26181fSAndroid Build Coastguard Worker 	 */
329*8b26181fSAndroid Build Coastguard Worker 	p->getnonblock_op = dbus_getnonblock;
330*8b26181fSAndroid Build Coastguard Worker 	p->setnonblock_op = dbus_setnonblock;
331*8b26181fSAndroid Build Coastguard Worker 	return (p);
332*8b26181fSAndroid Build Coastguard Worker }
333*8b26181fSAndroid Build Coastguard Worker 
334*8b26181fSAndroid Build Coastguard Worker int
dbus_findalldevs(pcap_if_list_t * devlistp,char * err_str)335*8b26181fSAndroid Build Coastguard Worker dbus_findalldevs(pcap_if_list_t *devlistp, char *err_str)
336*8b26181fSAndroid Build Coastguard Worker {
337*8b26181fSAndroid Build Coastguard Worker 	/*
338*8b26181fSAndroid Build Coastguard Worker 	 * The notion of "connected" vs. "disconnected" doesn't apply.
339*8b26181fSAndroid Build Coastguard Worker 	 * XXX - what about the notions of "up" and "running"?
340*8b26181fSAndroid Build Coastguard Worker 	 */
341*8b26181fSAndroid Build Coastguard Worker 	if (add_dev(devlistp, "dbus-system",
342*8b26181fSAndroid Build Coastguard Worker 	    PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE, "D-Bus system bus",
343*8b26181fSAndroid Build Coastguard Worker 	    err_str) == NULL)
344*8b26181fSAndroid Build Coastguard Worker 		return -1;
345*8b26181fSAndroid Build Coastguard Worker 	if (add_dev(devlistp, "dbus-session",
346*8b26181fSAndroid Build Coastguard Worker 	    PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE, "D-Bus session bus",
347*8b26181fSAndroid Build Coastguard Worker 	    err_str) == NULL)
348*8b26181fSAndroid Build Coastguard Worker 		return -1;
349*8b26181fSAndroid Build Coastguard Worker 	return 0;
350*8b26181fSAndroid Build Coastguard Worker }
351*8b26181fSAndroid Build Coastguard Worker 
352