1511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
2511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Copyright (c) 2009 Felix Obenhuber
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 * Sockettrace sniffing API implementation for Linux platform
31511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * By Felix Obenhuber <felix@obenhuber.de>
32511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall *
33511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
34511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
35511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#ifdef HAVE_CONFIG_H
36511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "config.h"
37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
38511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
39511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <libusb-1.0/libusb.h>
40511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
41511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <stdlib.h>
42511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <unistd.h>
43511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <fcntl.h>
44511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <string.h>
45511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <pthread.h>
46511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
47511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap-int.h"
48511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include "pcap-canusb-linux.h"
49511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
50511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define CANUSB_IFACE "canusb"
51511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
52511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define CANUSB_VID 0x0403
53511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define CANUSB_PID 0x8990
54511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
55511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#define USE_THREAD 1
56511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
57511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#if USE_THREAD == 0
58511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#include <signal.h>
59511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall#endif
60511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
61511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
62511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* forward declaration */
63511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int canusb_activate(pcap_t *);
64511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int canusb_read_linux(pcap_t *, int , pcap_handler , u_char *);
65511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int canusb_inject_linux(pcap_t *, const void *, size_t);
66511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int canusb_setfilter_linux(pcap_t *, struct bpf_program *);
67511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int canusb_setdirection_linux(pcap_t *, pcap_direction_t);
68511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int canusb_stats_linux(pcap_t *, struct pcap_stat *);
69511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
70511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct CAN_Msg
71511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
72511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    uint32_t timestamp;
73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    uint32_t id;
74511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    uint32_t length;
75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    uint8_t data[8];
76511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
77511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/*
79511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * Private data for capturing on Linux CANbus USB devices.
80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall */
81511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstruct pcap_canusb {
82511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    libusb_context *ctx;
83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    libusb_device_handle *dev;
84511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    pthread_t worker;
85511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    int rdpipe, wrpipe;
86511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    volatile int loop;
87511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall};
88511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
89511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallint canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
90511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
91511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    libusb_context *fdctx;
92511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    libusb_device** devs;
93511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    unsigned char sernum[65];
94511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    int cnt, i;
95511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
96511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (libusb_init(&fdctx) != 0) {
97511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        /*
98511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall         * XXX - if this doesn't just mean "no USB file system mounted",
99511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall         * perhaps we should report a real error rather than just
100511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall         * saying "no CANUSB devices".
101511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall         */
102511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return 0;
103511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
104511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
105511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    cnt = libusb_get_device_list(fdctx,&devs);
106511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
107511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    for(i=0;i<cnt;i++)
108511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    {
109511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        int ret;
110511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        // Check if this device is interesting.
111511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        struct libusb_device_descriptor desc;
112511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_get_device_descriptor(devs[i],&desc);
113511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
114511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
115511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            continue; //It is not, check next device
116511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
117511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        //It is!
118511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_device_handle *dh = NULL;
119511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
120511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if ((ret = libusb_open(devs[i],&dh)) == 0)
121511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        {
122511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            char dev_name[30];
123511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            char dev_descr[50];
124511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            int n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,sernum,64);
125511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            sernum[n] = 0;
126511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
127511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            snprintf(dev_name, 30, CANUSB_IFACE"%s", sernum);
128511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            snprintf(dev_descr, 50, "CanUSB [%s]", sernum);
129511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
130511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            libusb_close(dh);
131511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
132511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0)
133511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            {
134511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall                libusb_free_device_list(devs,1);
135511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall                libusb_exit(fdctx);
136511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall                return -1;
137511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            }
138511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        }
139511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
140511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
141511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    libusb_free_device_list(devs,1);
142511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    libusb_exit(fdctx);
143511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return 0;
144511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
145511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
146511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic libusb_device_handle* canusb_opendevice(struct libusb_context *ctx, char* devserial)
147511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
148511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    libusb_device** devs;
149511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    unsigned char serial[65];
150511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    int cnt,i,n;
151511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
152511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    cnt = libusb_get_device_list(ctx,&devs);
153511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
154511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    for(i=0;i<cnt;i++)
155511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    {
156511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        // Check if this device is interesting.
157511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        struct libusb_device_descriptor desc;
158511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_get_device_descriptor(devs[i],&desc);
159511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
160511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
161511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall          continue;
162511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
163511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        //Found one!
164511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_device_handle *dh = NULL;
165511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
166511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if (libusb_open(devs[i],&dh) != 0) continue;
167511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
168511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,serial,64);
169511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        serial[n] = 0;
170511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
171511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if ((devserial) && (strcmp((char *)serial,devserial) != 0))
172511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        {
173511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            libusb_close(dh);
174511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            continue;
175511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        }
176511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
177511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if ((libusb_kernel_driver_active(dh,0)) && (libusb_detach_kernel_driver(dh,0) != 0))
178511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        {
179511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            libusb_close(dh);
180511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            continue;
181511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        }
182511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
183511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if (libusb_set_configuration(dh,1) != 0)
184511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        {
185511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            libusb_close(dh);
186511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            continue;
187511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        }
188511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
189511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if (libusb_claim_interface(dh,0) != 0)
190511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        {
191511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            libusb_close(dh);
192511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            continue;
193511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        }
194511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
195511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        //Fount it!
196511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_free_device_list(devs,1);
197511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return dh;
198511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
199511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
200511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    libusb_free_device_list(devs,1);
201511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return NULL;
202511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
203511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
204511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
205511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_t *
206511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcanusb_create(const char *device, char *ebuf, int *is_ours)
207511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
208511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    const char *cp;
209511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    char *cpend;
210511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    long devnum;
211511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    pcap_t* p;
212511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    struct pcap_canusb *canusb;
213511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
214511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    /* Does this look like a DAG device? */
215511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    cp = strrchr(device, '/');
216511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (cp == NULL)
217511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        cp = device;
218511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    /* Does it begin with "canusb"? */
219511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (strncmp(cp, "canusb", 6) != 0) {
220511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        /* Nope, doesn't begin with "canusb" */
221511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        *is_ours = 0;
222511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return NULL;
223511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
224511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    /* Yes - is "canusb" followed by a number? */
225511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    cp += 6;
226511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    devnum = strtol(cp, &cpend, 10);
227511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (cpend == cp || *cpend != '\0') {
228511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        /* Not followed by a number. */
229511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        *is_ours = 0;
230511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return NULL;
231511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
232511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (devnum < 0) {
233511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        /* Followed by a non-valid number. */
234511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        *is_ours = 0;
235511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return NULL;
236511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
237511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
238511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    /* OK, it's probably ours. */
239511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    *is_ours = 1;
240511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
241511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    p = pcap_create_common(device, ebuf, sizeof (struct pcap_canusb));
242511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (p == NULL)
243511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return (NULL);
244511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
245511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    canusb = p->priv;
246511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    canusb->ctx = NULL;
247511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    canusb->dev = NULL;
248511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    canusb->rdpipe = -1;
249511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    canusb->wrpipe = -1;
250511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
251511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    p->activate_op = canusb_activate;
252511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
253511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return (p);
254511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
255511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
256511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
257511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void* canusb_capture_thread(void *arg)
258511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
259511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    struct pcap_canusb *canusb = arg;
260511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    int i;
261511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    struct
262511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    {
263511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall      uint8_t rxsz, txsz;
264511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    } status;
265511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
266511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    fcntl(canusb->wrpipe, F_SETFL, O_NONBLOCK);
267511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
268511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    while(canusb->loop)
269511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    {
270511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        int sz;
271511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        struct CAN_Msg msg;
272511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
273511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
274511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        //HACK!!!!! -> drop buffered data, read new one by reading twice.
275511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
276511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
277511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        for(i = 0; i<status.rxsz; i++)
278511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        {
279511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            libusb_bulk_transfer(canusb->dev, 0x85, (unsigned char*)&msg, sizeof(msg), &sz, 100);
280511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            write(canusb->wrpipe, &msg, sizeof(msg));
281511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        }
282511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
283511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
284511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
285511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return NULL;
286511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
287511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
288511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int canusb_startcapture(struct pcap_canusb* this)
289511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
290511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    int pipefd[2];
291511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
292511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (pipe(pipefd) == -1)
293511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return -1;
294511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
295511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    this->rdpipe = pipefd[0];
296511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    this->wrpipe = pipefd[1];
297511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
298511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    this->loop = 1;
299511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    pthread_create(&this->worker, NULL, canusb_capture_thread, this);
300511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
301511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return this->rdpipe;
302511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
303511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
304511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void canusb_clearbufs(struct pcap_canusb* this)
305511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
306511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    unsigned char cmd[16];
307511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    int al;
308511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
309511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    cmd[0] = 1;  //Empty incoming buffer
310511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    cmd[1] = 1;  //Empty outgoing buffer
311511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    cmd[3] = 0;  //Not a write to serial number
312511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    memset(&cmd[4],0,16-4);
313511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
314511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    libusb_interrupt_transfer(this->dev, 0x1,cmd,16,&al,100);
315511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
316511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
317511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
318511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic void canusb_close(pcap_t* handle)
319511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
320511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    struct pcap_canusb *canusb = handle->priv;
321511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
322511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    canusb->loop = 0;
323511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    pthread_join(canusb->worker, NULL);
324511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
325511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (canusb->dev)
326511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    {
327511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_close(canusb->dev);
328511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        canusb->dev = NULL;
329511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
330511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (canusb->ctx)
331511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    {
332511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_exit(canusb->ctx);
333511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        canusb->ctx = NULL;
334511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
335511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
336511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
337511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
338511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
339511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int canusb_activate(pcap_t* handle)
340511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
341511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    struct pcap_canusb *canusb = handle->priv;
342511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    char *serial;
343511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
344511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (libusb_init(&canusb->ctx) != 0) {
345511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        /*
346511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall         * XXX - what causes this to fail?
347511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall         */
348511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "libusb_init() failed");
349511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return PCAP_ERROR;
350511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
351511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
352511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->read_op = canusb_read_linux;
353511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
354511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->inject_op = canusb_inject_linux;
355511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->setfilter_op = canusb_setfilter_linux;
356511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->setdirection_op = canusb_setdirection_linux;
357511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->getnonblock_op = pcap_getnonblock_fd;
358511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->setnonblock_op = pcap_setnonblock_fd;
359511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->stats_op = canusb_stats_linux;
360511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->cleanup_op = canusb_close;
361511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
362511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    /* Initialize some components of the pcap structure. */
363511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->bufsize = 32;
364511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->offset = 8;
365511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->linktype = DLT_CAN_SOCKETCAN;
366511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->set_datalink_op = NULL;
367511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
368511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    serial = handle->opt.source + strlen(CANUSB_IFACE);
369511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
370511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    canusb->dev = canusb_opendevice(canusb->ctx, serial);
371511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (!canusb->dev)
372511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    {
373511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        libusb_exit(canusb->ctx);
374511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't open USB Device");
375511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return PCAP_ERROR;
376511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
377511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
378511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    canusb_clearbufs(canusb);
379511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
380511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->fd = canusb_startcapture(canusb);
381511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    handle->selectable_fd = handle->fd;
382511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
383511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return 0;
384511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
385511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
386511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
387511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
388511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
389511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
390511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcanusb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
391511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
392511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    static struct timeval firstpacket = { -1, -1};
393511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    int i = 0;
394511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    struct CAN_Msg msg;
395511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    struct pcap_pkthdr pkth;
396511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
397511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    while(i < max_packets)
398511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    {
399511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        int n;
400511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        usleep(10 * 1000);
401511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        n = read(handle->fd, &msg, sizeof(msg));
402511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if (n <= 0)
403511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            break;
404511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        pkth.caplen = pkth.len = n;
405511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        pkth.caplen -= 4;
406511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        pkth.caplen -= 8 - msg.length;
407511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
408511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if ((firstpacket.tv_sec == -1) && (firstpacket.tv_usec == -1))
409511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            gettimeofday(&firstpacket, NULL);
410511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
411511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        pkth.ts.tv_usec = firstpacket.tv_usec + (msg.timestamp % 100) * 10000;
412511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        pkth.ts.tv_sec = firstpacket.tv_usec + (msg.timestamp / 100);
413511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        if (pkth.ts.tv_usec > 1000000)
414511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        {
415511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            pkth.ts.tv_usec -= 1000000;
416511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            pkth.ts.tv_sec++;
417511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        }
418511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
419511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        callback(user, &pkth, (void*)&msg.id);
420511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        i++;
421511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
422511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
423511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return i;
424511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
425511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
426511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
427511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
428511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcanusb_inject_linux(pcap_t *handle, const void *buf, size_t size)
429511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
430511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    /* not yet implemented */
431511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on canusb devices");
432511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return (-1);
433511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
434511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
435511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
436511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
437511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcanusb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
438511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
439511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    /* not yet implemented */
440511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    stats->ps_recv = 0;     /* number of packets received */
441511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    stats->ps_drop = 0;     /* number of packets dropped */
442511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    stats->ps_ifdrop = 0;   /* drops by interface -- only supported on some platforms */
443511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return 0;
444511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
445511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
446511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
447511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
448511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcanusb_setfilter_linux(pcap_t *p, struct bpf_program *fp)
449511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
450511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    /* not yet implemented */
451511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return 0;
452511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
453511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
454511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
455511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallstatic int
456511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallcanusb_setdirection_linux(pcap_t *p, pcap_direction_t d)
457511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall{
458511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    /* no support for PCAP_D_OUT */
459511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    if (d == PCAP_D_OUT)
460511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    {
461511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        snprintf(p->errbuf, sizeof(p->errbuf),
462511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall            "Setting direction to PCAP_D_OUT is not supported on this interface");
463511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall        return -1;
464511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    }
465511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
466511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    p->direction = d;
467511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
468511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    return 0;
469511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall}
470511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
471511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall
472511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall/* eof */
473