1511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
2511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copyright (c) 2012 Jakub Zawadzki
3511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * All rights reserved.
4511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *
5511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Redistribution and use in source and binary forms, with or without
6511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * modification, are permitted provided that the following conditions
7511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * are met:
8511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *
9511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 1. Redistributions of source code must retain the above copyright
10511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * notice, this list of conditions and the following disclaimer.
11511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 2. Redistributions in binary form must reproduce the above copyright
12511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * notice, this list of conditions and the following disclaimer in the
13511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * documentation and/or other materials provided with the distribution.
14511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * 3. The name of the author may not be used to endorse or promote
15511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * products derived from this software without specific prior written
16511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * permission.
17511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *
18511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
30511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
31511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_CONFIG_H
32511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "config.h"
33511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <string.h>
36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <time.h>
38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <sys/time.h>
39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <dbus/dbus.h>
41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap-int.h"
43511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap-dbus.h"
44511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
45511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Private data for capturing on D-Bus.
47511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
48511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct pcap_dbus {
49511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	DBusConnection *conn;
50511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	u_int	packets_read;	/* count of packets read */
51511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
52511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
53511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
54511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldbus_read(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
55511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
56511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_dbus *handlep = handle->priv;
57511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
58511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_pkthdr pkth;
59511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	DBusMessage *message;
60511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
61511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	char *raw_msg;
62511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int raw_msg_len;
63511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
64511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int count = 0;
65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	message = dbus_connection_pop_message(handlep->conn);
67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	while (!message) {
69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		// XXX handle->opt.timeout = timeout_ms;
70511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (!dbus_connection_read_write(handlep->conn, 100)) {
71511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Connection closed");
72511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return -1;
73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (handle->break_loop) {
76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			handle->break_loop = 0;
77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return -2;
78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		message = dbus_connection_pop_message(handlep->conn);
81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Disconnected");
85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return -1;
86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (dbus_message_marshal(message, &raw_msg, &raw_msg_len)) {
89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		pkth.caplen = pkth.len = raw_msg_len;
90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/* pkth.caplen = min (payload_len, handle->snapshot); */
91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		gettimeofday(&pkth.ts, NULL);
93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (handle->fcode.bf_insns == NULL ||
94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		    bpf_filter(handle->fcode.bf_insns, (u_char *)raw_msg, pkth.len, pkth.caplen)) {
95511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			handlep->packets_read++;
96511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			callback(user, &pkth, (u_char *)raw_msg);
97511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			count++;
98511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
99511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		dbus_free(raw_msg);
101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return count;
103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldbus_write(pcap_t *handle, const void *buf, size_t size)
107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* XXX, not tested */
109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_dbus *handlep = handle->priv;
110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	DBusError error = DBUS_ERROR_INIT;
112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	DBusMessage *msg;
113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (!(msg = dbus_message_demarshal(buf, size, &error))) {
115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dbus_message_demarshal() failed: %s", error.message);
116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		dbus_error_free(&error);
117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return -1;
118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dbus_connection_send(handlep->conn, msg, NULL);
121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dbus_connection_flush(handlep->conn);
122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dbus_message_unref(msg);
124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return 0;
125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldbus_stats(pcap_t *handle, struct pcap_stat *stats)
129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_dbus *handlep = handle->priv;
131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	stats->ps_recv = handlep->packets_read;
133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	stats->ps_drop = 0;
134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	stats->ps_ifdrop = 0;
135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return 0;
136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void
139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldbus_cleanup(pcap_t *handle)
140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_dbus *handlep = handle->priv;
142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	dbus_connection_unref(handlep->conn);
144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pcap_cleanup_live_common(handle);
146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldbus_activate(pcap_t *handle)
150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define EAVESDROPPING_RULE "eavesdrop=true,"
152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	static const char *rules[] = {
154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		EAVESDROPPING_RULE "type='signal'",
155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		EAVESDROPPING_RULE "type='method_call'",
156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		EAVESDROPPING_RULE "type='method_return'",
157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		EAVESDROPPING_RULE "type='error'",
158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	};
159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	#define N_RULES sizeof(rules)/sizeof(rules[0])
161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	struct pcap_dbus *handlep = handle->priv;
163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	const char *dev = handle->opt.source;
164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	DBusError error = DBUS_ERROR_INIT;
166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	int i;
167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (strcmp(dev, "dbus-system") == 0) {
169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) {
170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get system bus: %s", error.message);
171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			dbus_error_free(&error);
172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return PCAP_ERROR;
173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else if (strcmp(dev, "dbus-session") == 0) {
176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (!(handlep->conn = dbus_bus_get(DBUS_BUS_SESSION, &error))) {
177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to get session bus: %s", error.message);
178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			dbus_error_free(&error);
179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return PCAP_ERROR;
180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else if (strncmp(dev, "dbus://", 7) == 0) {
183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		const char *addr = dev + 7;
184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (!(handlep->conn = dbus_connection_open(addr, &error))) {
186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to open connection to: %s: %s", addr, error.message);
187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			dbus_error_free(&error);
188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return PCAP_ERROR;
189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (!dbus_bus_register(handlep->conn, &error)) {
192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to register bus %s: %s\n", addr, error.message);
193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			dbus_error_free(&error);
194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			return PCAP_ERROR;
195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	} else {
198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get bus address from %s", handle->opt.source);
199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return PCAP_ERROR;
200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* Initialize some components of the pcap structure. */
203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->bufsize = 0;
204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->offset = 0;
205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->linktype = DLT_DBUS;
206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->read_op = dbus_read;
207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->inject_op = dbus_write;
208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->setfilter_op = install_bpf_program; /* XXX, later add support for dbus_bus_add_match() */
209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->setdirection_op = NULL;
210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->set_datalink_op = NULL;      /* can't change data link type */
211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->getnonblock_op = pcap_getnonblock_fd;
212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->setnonblock_op = pcap_setnonblock_fd;
213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->stats_op = dbus_stats;
214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	handle->selectable_fd = handle->fd = -1;
216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (handle->opt.rfmon) {
218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		/*
219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 * Monitor mode doesn't apply to dbus connections.
220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		 */
221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		dbus_cleanup(handle);
222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return PCAP_ERROR_RFMON_NOTSUP;
223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	/* dbus_connection_set_max_message_size(handlep->conn, handle->snapshot); */
226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (handle->opt.buffer_size != 0)
227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		dbus_connection_set_max_received_size(handlep->conn, handle->opt.buffer_size);
228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	for (i = 0; i < N_RULES; i++) {
230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		dbus_bus_add_match(handlep->conn, rules[i], &error);
231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		if (dbus_error_is_set(&error)) {
232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			dbus_error_free(&error);
233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			/* try without eavesdrop */
235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			dbus_bus_add_match(handlep->conn, rules[i] + strlen(EAVESDROPPING_RULE), &error);
236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			if (dbus_error_is_set(&error)) {
237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Failed to add bus match: %s\n", error.message);
238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				dbus_error_free(&error);
239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				dbus_cleanup(handle);
240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall				return PCAP_ERROR;
241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall			}
242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		}
243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return 0;
246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_t *
249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldbus_create(const char *device, char *ebuf, int *is_ours)
250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	pcap_t *p;
252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (strcmp(device, "dbus-system") &&
254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		strcmp(device, "dbus-session") &&
255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		strncmp(device, "dbus://", 7))
256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	{
257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		*is_ours = 0;
258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return NULL;
259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	}
260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	*is_ours = 1;
262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p = pcap_create_common(device, ebuf, sizeof (struct pcap_dbus));
263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (p == NULL)
264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return (NULL);
265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	p->activate_op = dbus_activate;
267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return (p);
268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint
271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgralldbus_findalldevs(pcap_if_t **alldevsp, char *err_str)
272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_add_if(alldevsp, "dbus-system", 0, "D-Bus system bus", err_str) < 0)
274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return -1;
275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	if (pcap_add_if(alldevsp, "dbus-session", 0, "D-Bus session bus", err_str) < 0)
276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall		return -1;
277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall	return 0;
278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
280