/* * cansniffer.c * * Copyright (c) 2002-2007 Volkswagen Group Electronic Research * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Volkswagen nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * Alternatively, provided that this notice is retained in full, this * software may be distributed under the terms of the GNU General * Public License ("GPL") version 2, in which case the provisions of the * GPL apply INSTEAD OF those given above. * * The provided data structures and external interfaces from this code * are not restricted to be used by modules with a GPL compatible license. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * Send feedback to * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "terminal.h" #define SETFNAME "sniffset." #define ANYDEV "any" #define MAX_SLOTS 2048 /* flags */ #define ENABLE 1 /* by filter or user */ #define DISPLAY 2 /* is on the screen */ #define UPDATE 4 /* needs to be printed on the screen */ #define CLRSCR 8 /* clear screen in next loop */ /* flags testing & setting */ #define is_set(id, flag) (sniftab[id].flags & flag) #define is_clr(id, flag) (!(sniftab[id].flags & flag)) #define do_set(id, flag) (sniftab[id].flags |= flag) #define do_clr(id, flag) (sniftab[id].flags &= ~flag) /* time defaults */ #define TIMEOUT 500 /* in 10ms */ #define HOLD 100 /* in 10ms */ #define LOOP 20 /* in 10ms */ #define ATTCOLOR ATTBOLD FGRED #define STARTLINESTR "XX delta ID data ... " struct snif { int flags; long hold; long timeout; struct timeval laststamp; struct timeval currstamp; struct can_frame last; struct can_frame current; struct can_frame marker; struct can_frame notch; } sniftab[MAX_SLOTS]; extern int optind, opterr, optopt; static int running = 1; static int clearscreen = 1; static int notch; static long timeout = TIMEOUT; static long hold = HOLD; static long loop = LOOP; static unsigned char binary; static unsigned char binary_gap; static unsigned char color; static char *interface; void print_snifline(int slot); int handle_keyb(int fd); int handle_frame(int fd, long currcms); int handle_timeo(int fd, long currcms); int sniftab_index(canid_t id); void writesettings(char* name); void readsettings(char* name, int sockfd); int idx = 0; int comp (const void * elem1, const void * elem2) { unsigned long f = ((struct snif*)elem1)->current.can_id; unsigned long s = ((struct snif*)elem2)->current.can_id; if (f > s) return 1; if (f < s) return -1; return 0; } void print_usage(char *prg) { const char manual [] = { "commands that can be entered at runtime:\n" "\n" "q - quit\n" "b - toggle binary / HEX-ASCII output\n" "B - toggle binary with gap / HEX-ASCII output (exceeds 80 chars!)\n" "c - toggle color mode\n" "# - notch currently marked/changed bits (can be used repeatedly)\n" "* - clear notched marked\n" "rMYNAME - read settings file (filter/notch)\n" "wMYNAME - write settings file (filter/notch)\n" "+FILTER - add CAN-IDs to sniff\n" "-FILTER - remove CAN-IDs to sniff\n" "\n" "FILTER must be a single CAN-ID:\n"/* "or a CAN-ID/Bitmask:\n"*/ "+1F5 - add CAN-ID 0x1F5\n" "-42E - remove CAN-ID 0x42E\n" "\n" "29 bit IDs:\n" "+18FEDF55 - add CAN-ID 0x18FEDF55\n" "-00000090 - remove CAN-ID 0x00000090\n" /* "-42E7FF - remove CAN-ID 0x42E (using Bitmask)\N"*/ /* "-500700 - remove CAN-IDs 0x500 - 0x5FF\n"*/ /* "+400600 - add CAN-IDs 0x400 - 0x5FF\n"*/ /* "+000000 - add all CAN-IDs\n"*/ /* "-000000 - remove all CAN-IDs\n"*/ /* "\n"*/ /* "if (id & filter) == (sniff-id & filter) the action (+/-) IS PERFORMED,\N" */ /* "which is quite easy when the filter is 000\n"*/ "\n" }; fprintf(stderr, "\nUsage: %s [can-interface]\n", prg); // fprintf(stderr, "Options: -m (initial FILTER default 0x00000000)\n"); // fprintf(stderr, " -v (initial FILTER default 0x00000000)\n"); fprintf(stderr, "Options: -q (quiet - all slots are deactivated)\n"); fprintf(stderr, " -r (read %sname from file)\n", SETFNAME); fprintf(stderr, " -b (start with binary mode)\n"); fprintf(stderr, " -B (start with binary mode with gap - exceeds 80 chars!)\n"); fprintf(stderr, " -c (color changes)\n"); fprintf(stderr, " -t