When Wireshark first appeared, it was called Ethereal… and its motto was:
“Sniffing the glue that holds the internet together”
Wireshark sniffs the packet-glue that holds the internet together and is one of the most influential pieces of open source software there is.
That’s a pretty bold statement and I even count projects like Linux itself in that comparison. It’s certainly up there.
Wireshark takes packets of data sent on a Network and converts the binary transmission into something us humans can understand.
It can take something like this data on a CAN bus:
3031363744454c4d4e4f50515a5b5c5d646a6b7c7d9e9fa0a1d8d9dadb
… and turn it into something like this that we can understand:
RT_COOLANTTEMP1(LIM) ( Coolant Temp ) = 23.048 C
Wireshark, and its sister tools, have facilitated the democratisation of internet development. Without it, and in the early days of the internet, people would have to write their own test and development software or pay large sums of money for specialist software. Wireshark has allowed anybody, whether privately or commercially, to peek, ponder and pontificate about how all sorts of devices and software communicate with each other.
These days it is also relatively simple to add new functionality to Wireshark and allow it to decode and dissect any new protocol that you care to dream up.
The only caveat is that the communication protocol in question needs to be packet based. i.e. it needs to happen in chunks of data. But, as it happens, that’s ok… Even the streams of data that we, as humans, perceive as being continuous are transmitted in chunks (packets) over the internet. Speech, Music, Video, Financial Transactions and plain old web-browsing are all transmitted over the internet in packets. And until recently they couldn’t hide from Wireshark.
However, more recently, much of the internet has moved to using encrypted communications. This is a lot more difficult for Wireshark to peer into, but for software developers (and for that matter hackers) that have the appropriate encryption keys, Wireshark is still an invaluable tool to write, debug and help deliver their software.
Dissectors
Wireshark is essentially a “frame-work”. By which we mean it provides a skeleton that support the real work of the software. Just like a human skeleton (frame work) it provides support for the rest our body’s organs. The frame-work provides all the housekeeping functions, like accessing the network, opening and closing files and displaying packets to a user.
That leaves the bulk of the “real work” inside Wireshark to software modules called “packet dissectors”. There is one or more packet dissector modules (a chunk of software) for each of the communications protocols that Wireshark can decode.
Remember that internet communications protocols are like different spoken languages. And each Wireshark dissector is like a translator for each of those different languages – turning binary data into human readable text.
I just checked the Wireshark source code , and as I write this post in September of 2019, Wireshark has 1450 dissectors that ship with the software download. Each of those dissectors can turn a “machine readable” communications protocol into something that is “human readable” (see below for an example of that). And, of course, that doesn’t include the thousands of dissectors that people have written for themselves or their companies and that don’t get shipped with Wireshark as standard. I think that’s amazing.
So how does an internet packet sniffing application like Wireshark help with the poking around in the world of automotive communications?
SocketCAN
Each CAN bus “frame” of data (see ECU Diagnostics – part 2 : ECU, OBD and CAN for an explanation of CAN bus) can also be thought of as a “packet” of data. And it looks very much like any other internet packet based protocol. It has a start to the packet, a data section, flags (information) that tell us about the packet and error checking – all features of internet packets. The only real difference between a CAN bus frame/packet and internet packets is that it has an ID (identifier) that looks sort-of… but-not-quite like the source and destination addresses of an internet packet. But its a reasonable analogy and allows Wireshark to be able to work with CAN bus packets.
Enter SocketCAN.
Because CAN bus frames are so much like an internet packet, we can convert them into something that Wireshark thinks is an internet packet and then let all the tools and software Inside Wireshark, that are able work with internet packets, do the hard work of dissecting CAN bus packets and displaying them for us.
SocketCAN takes a stream of CANbus frames and puts them into an internet packet format and then makes that packet stream available through a “socket”. It should perhaps be called Can-to-Socket instead of SocketCAN, but that’s quite a common trope for the internet… just to confuse everyone who are not in the know!
The internet runs on sockets… perhaps just like the power grids of the world. When a software application wants to access the internet, it plugs into a socket, just like you would if you want power for your electrical devices.. These are of course software sockets but the analogy is quite similar. In this example, the CAN bus frames are like the electricity that is fed to you through a power socket.
Internet sockets connect software running on a computer, or server, to another computer’s software that also use internet sockets to receive the data.
Now we have a way of taking the 1’s and 0’s on the CAN bus and turning them into a stream of packets that our computers can access through a socket interface!
SocketCAN is a Linux thing. It is actually a “kernel module”, which means it can run fast and with extra privileges that regular software doesn’t have. The real world upshot of this is that SocketCAN creates another network interface on the computer, just like a Wifi or Ethernet network connection… and means that CANbus frames drop into the computer just like they are coming from a Wifi of Ethernet connection.
Phew! We’re finally going to talk about looking at the data…
Capture Files
Wireshark works with “captures”… it captures packets from a network and then displays them like in the picture above of a CAN bus capture. And just like Wireshark can capture packets from a Wifi or Ethernet connection to the internet, it can also now capture packets from our CAN bus, because we have SocketCAN turning the CAN bus frames into an internet packet for us.
An important point for us here is that Wireshark accesses these packets using an internet socket… just the sort of socket that SocetCAN will take CAN bus frames and convert them into internet sockets.
It can either view the packets “live”, meaning they appear on the Wireshark display as they are transmitted on the CAN bus, or it can show packets that have been “captured” to a file and then display them later by loading the file into Wireshark again. The computer file that this creates is called a “capture file” and it contains the digital frames taken from the CAN bus that SocketCAN turned into packets for us.
So what do we do with all of this?
First Captures of What our Cars are Talking About
So, after connecting our test rig up as in the previous post, we needed to see what the car was talking about on it’s CAN bus. We knew very little about how the car could communicate with us at this stage, so I broke out an OBD Scanner…
AutoLink OBD Scanner
At this point in the proceedings I remembered that in my box of tricks I had bought an OBD scanner. These scanners plug into the OBD port under the car’s dash and show whatever standard data requests the car can support.
I have the Autolink AL319 that I’d used when I built the car to see that everything looked ok with the engine management side of things. The AL 319 can decode a number of different, common, protocols. It turned out that all it could talk to the Caterham with was the standard-fast OBD-II protocol.
So I hooked up the Scanner to the car where the Easimap software had been and set it to check on the data from the car while I captured the packets on the Raspberry Pi.
The main reason behind using the scanner was to see if it could probe the car in any ways similar to Easimap. Perhaps it would give us a clue about what other protocols the car could support.
The scanner was able to extract something like 15 data points (see the end of this post for a full list) and looked like this:
in the picture above each line on the display corresponds to a data element from the car. For instance, ECT stands for Engine Coolant Temperature and is reading 21C.
To get the data captures you’ll see below I followed the test setup I had in the previous post… namely… Raspberry Pi was connected in parallel with the scanner and car and was running a tshark capture to a file.
Once I had powered on the car, the scanner comes to life (powered by the OBD port of the car) and starts to talk to the car. After it had “discovered” the car talking fast, extended, OBD-II then I was able to scroll through the various data screens while the Raspberry Pi captured the conversation to a packet capture file.
So I opened the packet capture up in Wireshark expecting to see lots of data, but nothing really appeared.
It’s not particularly unusual for Wireshark to have problems dissecting packets. It can be a bit buggy sometimes. But I had hoped it would do better. In theory Wireshark has an OBD-II dissector. But all I could see was the “raw” CAN packets, as shown in the picture below.
Something’s Not Working with the Wireshark OBD-II Dissector
If you look at the screen capture of Wireshark above, you’ll see that the first line (packet 142) shows the Protocol as OBD-II. But the remaining packets are not decoded correctly. From packets 200 to 219 we can see the Scanner trying different protocols on the car to see if it will respond… it finally does in packet 269, but Wireshark should be doing a better job of decoding from 269 onwards and displaying the OBD-II data, not just the hexadecimal format you can see above.
On further investigation, over a few hours and after eventually getting into the Wireshark source code… I found the problem was that the Wireshark OBD-II dissector was only able to decode packets with 11bit CAN ID’s (which is why it can decode packet 142 – it’s an 11bit ID the scanner first sends to the car). But our cars are using 29bit CAN ID’s, which it turns out Wireshark couldn’t decode.
Bummer!
Fixing the Dissector
So, I rolled up my sleeves and set about fixing Wireshark’s OBD-II dissector.
That’s the beauty of open-source software. You download the code, fix what needs to be fixed… and if you’re lucky you can submit your fix back to the project and everyone else gets to benefit from your fix.
In the end I changed, or added, 95 lines of code to packet-obd-ii.c file in the Wireshark source code. Over the course of a few days the patch was reviewed, tested and eventually accepted by the project co-ordinators. So, hopefully as of the next public release (version 3.0.4) of Wireshark it should be able to dissect 29bit OBD-II communications to and from a MBE 9A4 ECU.
Woot woot!
The patch and all its gory details can be found here:
https://code.wireshark.org/review/#/c/34297/
With the patch installed the same capture file shown below…
… now looks like this one below…
All the CAN bus byte data has been turned into something we can read more easily. You can see commands are sent from the scanner to the car and a response comes back. So, for instance in packet number 1948 the scanner sends the “calculated engine load” command and the car responds in packet 1949 with 0.00% (i.e. the car isn’t running).
But not only that… because the Wireshark application and the Tshark command line tool both share the same code base, it means I can run a command like this..
tshark -i can0 -Y “(can.id != 0x0cbb0001)” -d can.subdissector=obd-ii
and get a simple text output of what the Scanner was doing:
# Time ID Info 1891 18.384234117 [18db33f1] Freeze DTC 1892 18.386480284 [18daf101] Freeze DTC: < 22 26 > 1948 18.932752338 [18db33f1] Calculated engine load 1949 18.933708266 [18daf101] Calculated engine load: 0.00 % 2004 19.480255834 [18db33f1] Engine coolant temperature 2006 19.482689349 [18daf101] Engine coolant temperature: 21 °C 2061 20.029324990 [18db33f1] Intake manifold absolute pressure 2062 20.031880206 [18daf101] Intake manifold absolute pressure: 200 kPa 2118 20.578419385 [18db33f1] Engine RPM 2119 20.581109100 [18daf101] Engine RPM: 0.00 rpm 2175 21.127303969 [18db33f1] Timing advance 2176 21.128371192 [18daf101] Timing advance: 0.00 °BTDC 2231 21.674841186 [18db33f1] Intake air temperature 2233 21.676107628 [18daf101] Intake air temperature: 16 °C 2288 22.222260164 [18db33f1] Throttle position 2289 22.224313834 [18daf101] Throttle position: 22.35 % 2345 22.771129266 [18db33f1] OBD standards 2346 22.773691168 [18daf101] OBD standards: EOBD 2402 23.320629505 [18db33f1] Oxygen sensors present (4 banks) 2403 23.323019928 [18daf101] Oxygen sensors present (4 banks): Bank1 sensors: 1 , Bank2 sensors: None, Bank3 sensors: None, Bank4 sensors: None 2459 23.869724288 [18db33f1] Fuel Rail Gauge Pressure 2460 23.872168914 [18daf101] Fuel Rail Gauge Pressure: 2400 kPa 2515 24.419230119 [18db33f1] Absolute Barometric Pressure 2517 24.421439008 [18daf101] Absolute Barometric Pressure: 0 kPa 2572 24.968236310 [18db33f1] Control module voltage 2573 24.969567270 [18daf101] Control module voltage: 11.693 V 2629 25.516453162 [18db33f1] Commanded throttle actuator 2630 25.518540406 [18daf101] Commanded throttle actuator: 00
If you want to see how I came up with that tshark command line options then you can find more in the tshark man pages. But simply put the options translate as:
- -i tells tshark to use the can0, SocketCAN network interface
- -Y option restricts the displayed packets so we don’t see the MBE-Broadcast frames that use the CAN bus ID of 0x0cbb0001
- -d is the important one that tells tshark to take any CAN packets (using the can.subdissector) and decodes them as OBD-II
For those of you that like your graphical user interfaces, that last dump of text may seem like a step backwards. But the advantage of getting a text output from a packet capture is that you can search and analyse the capture more easily. Wireshark allows you to do some simple captures and filters, but once I have a textual version of the capture I can more easily just look for things like engine RPM, or coolant temperature. It would be nice if Wireshark could do more of that, but that’s not something I want to fix at the moment.
And here’s the full list of what data an MBE 9A4 Caterham stock ECU can report via the OBD-II protocol:
- Monitor status
- Freeze DTC
- Calculated engine load
- Engine coolant temperature
- Intake manifold absolute pressure
- Engine RPM
- Timing advance
- Intake air temperature
- Throttle position
- OBD standards
- Oxygen sensors present (4 banks)
- Fuel Rail Gauge Pressure
- Absolute Barometric Pressure
- Control module voltage
- Commanded throttle actuator
So there we are. I started off thinking that pulling the scanner out of my toy box would be a 5 minute investigation. A week later I had the analysis I wanted but I also got to make my first patch of Wireshark and, after using the software for 20 years, I’d got a better understanding how it really works.
Now we’ve seen what the car can do when it talks OBD-II, we can get back to understanding the Easimap protocol some more.
Leave a Comment