Open guyharris opened 11 years ago
The suggested patch:
From d1a300b24ffff269ef012b03a6018a0be6611555 Mon Sep 17 00:00:00 2001
From: Felix Obenhuber <felix@obenhuber.de>
Date: Sun, 11 Oct 2009 23:11:15 +0200
Subject: [PATCH] Support for SocketCAN
Print struct can_frame for the Linux SocketCAN implementation almost the same
way candump does. Uses libpcap SocketCAN patch.
---
CREDITS | 1 +
INSTALL.txt | 1 +
Makefile.in | 15 ++++----
interface.h | 1 +
print-socketcan.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++
tcpdump.c | 3 ++
6 files changed, 111 insertions(+), 7 deletions(-)
create mode 100644 print-socketcan.c
diff --git a/CREDITS b/CREDITS
index 3579d73..db7223e 100644
--- a/CREDITS
+++ b/CREDITS
@@ -51,6 +51,7 @@ Additional people who have contributed patches:
Eddie Kohler <xexd at sourceforge dot net>
Elmar Kirchner <elmar at juniper dot net>
Fang Wang <fangwang at sourceforge dot net>
+ Felix Obenhuber <felix at obenhuber dot de>
Florent Drouin <Florent dot Drouin at alcatel-lucent dot fr>
Florian Forster <octo at verplant dot org>
Francis Dupont <Francis dot Dupont at enst-bretagne dot fr>
diff --git a/INSTALL.txt b/INSTALL.txt
index a03e2c0..0d0bed5 100644
--- a/INSTALL.txt
+++ b/INSTALL.txt
@@ -211,6 +211,7 @@ print-sll.c - Linux "cooked" capture printer routines
print-slow.c - IEEE "slow protocol" (802.3ad) printer routines
print-smb.c - SMB/CIFS printer routines
print-snmp.c - Simple Network Management Protocol printer routines
+print-socketcan.c - SocketCAN printer routines
print-stp.c - IEEE 802.1d spanning tree protocol printer routines
print-sunatm.c - SunATM DLPI capture printer routines
print-sunrpc.c - Sun Remote Procedure Call printer routines
diff --git a/Makefile.in b/Makefile.in
index 633c59d..e95bade 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,17 +80,18 @@ CSRC = addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c
print-igrp.c print-ip.c print-ipcomp.c print-ipfc.c \
print-ipx.c print-isoclns.c print-juniper.c print-krb.c \
print-l2tp.c print-lane.c print-ldp.c print-lldp.c print-llc.c \
- print-lmp.c print-lspping.c print-lwapp.c \
+ print-lmp.c print-lspping.c print-lwapp.c \
print-lwres.c print-mobile.c print-mpcp.c print-mpls.c print-msdp.c \
print-nfs.c print-ntp.c print-null.c print-olsr.c print-ospf.c \
print-pgm.c print-pim.c print-ppp.c print-pppoe.c print-pptp.c \
print-radius.c print-raw.c print-rip.c print-rrcp.c print-rsvp.c \
- print-rx.c print-sctp.c print-sflow.c print-sip.c print-sl.c print-sll.c \
- print-slow.c print-snmp.c print-stp.c print-sunatm.c print-sunrpc.c \
- print-symantec.c print-syslog.c print-tcp.c print-telnet.c print-tftp.c \
- print-timed.c print-token.c print-udld.c print-udp.c print-usb.c \
- print-vjc.c print-vqp.c print-vrrp.c print-vtp.c \
- print-wb.c print-zephyr.c signature.c setsignal.c tcpdump.c util.c
+ print-rx.c print-sctp.c print-sflow.c print-socketcan.c print-sip.c \
+ print-sl.c print-sll.c print-slow.c print-snmp.c print-stp.c \
+ print-sunatm.c print-sunrpc.c print-symantec.c print-syslog.c \
+ print-tcp.c print-telnet.c print-tftp.c print-timed.c print-token.c \
+ print-udld.c print-udp.c print-usb.c print-vjc.c print-vqp.c \
+ print-vrrp.c print-vtp.c print-wb.c print-zephyr.c signature.c \
+ setsignal.c tcpdump.c util.c
LIBNETDISSECT_SRC=print-isakmp.c
LIBNETDISSECT_OBJ=$(LIBNETDISSECT_SRC:.c=.o)
diff --git a/interface.h b/interface.h
index afeaee9..6c62b3b 100644
--- a/interface.h
+++ b/interface.h
@@ -323,6 +323,7 @@ extern void sip_print(const u_char *, u_int);
extern void syslog_print(const u_char *, u_int);
extern u_int bt_if_print(const struct pcap_pkthdr *, const u_char *);
extern u_int usb_linux_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int socketcan_print(const struct pcap_pkthdr *, const u_char *);
#ifdef INET6
extern void ip6_print(const u_char *, u_int);
diff --git a/print-socketcan.c b/print-socketcan.c
new file mode 100644
index 0000000..93f0283
--- /dev/null
+++ b/print-socketcan.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2009 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Support for the SocketCAN
+ *
+ * Original code taken from can-utils in SocketCAN
+ * http://developer.berlios.de/projects/socketcan/
+ *
+ * Modified Felix Obenhuber <felix@obenhuber.de>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+
+#include <linux/can.h>
+
+u_int
+socketcan_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ int i, j, dlen, offset;
+ struct can_frame *cf = (struct can_frame*)p;
+ int dlc = (cf->can_dlc > 8)? 8 : cf->can_dlc;
+ char buf[45]; /* max length */
+
+ sprintf(buf, "%s ", "CAN");
+ offset = 4;
+
+ if (cf->can_id & CAN_ERR_FLAG)
+ {
+ sprintf(buf+offset, "%8X ", cf->can_id & (CAN_ERR_MASK|CAN_ERR_FLAG));
+ offset += 10;
+ }
+ else if (cf->can_id & CAN_EFF_FLAG)
+ {
+ sprintf(buf+offset, "%8X ", cf->can_id & CAN_EFF_MASK);
+ offset += 10;
+ }
+ else
+ {
+ sprintf(buf+offset, "%3X ", cf->can_id & CAN_SFF_MASK);
+ offset += 5;
+ }
+
+ sprintf(buf+offset, "[%d]", dlc);
+ offset += 3;
+
+
+ if (cf->can_id & CAN_RTR_FLAG) /* there are no ERR frames with RTR */
+ {
+ sprintf(buf+offset, " remote request");
+ printf("%s", buf );
+ return;
+ }
+
+ dlen = 3; /* _AA */
+ for (i = 0; i < dlc; i++)
+ {
+ sprintf(buf+offset, " %02X", cf->data[i]);
+ offset += dlen;
+ }
+
+ if (cf->can_id & CAN_ERR_FLAG)
+ sprintf(buf+offset, "%*s", dlen*(8-dlc)+13, "ERRORFRAME");
+ else
+ {
+ j = dlen*(8-dlc)+4;
+ sprintf(buf+offset, "%*s", j, "'");
+ offset += j;
+ for (i = 0; i < dlc; i++)
+ if ((cf->data[i] > 0x1F) && (cf->data[i] < 0x7F))
+ buf[offset++] = cf->data[i];
+ else
+ buf[offset++] = '.';
+
+ sprintf(buf+offset, "'");
+ }
+
+ printf("%s", buf );
+ return (sizeof(struct can_frame));
+}
diff --git a/tcpdump.c b/tcpdump.c
index 18c7af4..b3cc2c6 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -282,6 +282,9 @@ static struct printer printers[] = {
#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX_MMAPPED)
{ usb_linux_print, DLT_USB_LINUX_MMAPPED},
#endif
+#ifdef DLT_CAN_SOCKETCAN
+ { socketcan_print, DLT_CAN_SOCKETCAN},
+#endif
{ NULL, 0 },
};
--
1.6.3.3
+1! Does it just output the same thing as the "candump" socketCAN library? I was disappointed when i tried to pipe through SSH SocketCAN frames to Wireshark (just the same as you can do with Ethernet frames), and tcpdump told me it wasn't possible. It is really useful when you try to debug embedded systems. I scripted something that works with python but i can help to migrate it :) It could be a great feature for a future version.
EDIT: it's possible using the -w flag: tcpdump: packet printing is not supported for link type CAN_SOCKETCAN: use -w
for example, you just have to do a ssh tunnel with this and it works
tcpdump -s0 -U -n -w - -i vcan0 | wireshark -k -i -
@Adraub, do you have a packet capture of this type?
On ubuntu using socketcan you can easily create a capture @infrastation
$ modprobe vcan $ sudo ip link add dev vcan0 type vcan $ sudo ip link set up vcan0
let this run in a terminal: cangen vcan0
in another launch: tcpdump -s0 -U -n -w - -i vcan0 | wireshark -k -i -
Here you are, you can save your can file as pcap.
Please note that sadly, i see on my device can frame send twice, one as a "kernel" request, and another as a received frame. This is linux cooked capture and it doesnt seem possible to filter it directly with tcpdump.
it's possible using the -w flag
Yes, for all link-layer header types, even Ethernet, if you want to run tcpdump and pipe its output to Wireshark, you need -w
.
Converted from SourceForge issue 2876645, submitted by asu_fo
Libpcap gets extended to capture CAN frames via the SocketCAN interface.
This patch enabled tcpdump to print that captured frames for testing purposes and convenience. The printing routine is taken from the can-utlis of SocketCAN.