CDP Sniffing with an Arduino

Firstly full credit to Chris van Marle for his work on his CDPSniffino code, of which I have butchered (to be honest) to get it to work with ENC28J60 ethernet controllers. The packet info that is captured is slightly different, so it took a while debugging. This is also my first Arduino project (not including 3D printers). It has  been a while since I have written C code… Enough excuses…

Anyway, I use a lot of Cisco equipment and I have found on many occasion that network wall ports are either not labeled or the labels have worn off. When that port needs to be reconfigured it can take time to work out which network cabinet it goes back too, then which switch, and then which switch port. Most of the information can be obtained from CDP (Cisco Discovery Protocol):

  • The switch name gives a good indication of which cabinet and switch.
  • Model: Helps when the hostname has no indications of what the device is.
  • IP address: You can try to remotely access the switch (SSH/Telnet/Web interface).
  • The switch port is given (E.g; FastEthernet0/1).
  • VLAN: Good to know because it often determines what DHCP range is offered – I’m still working out if it’s the VLAN of the port or the “switch”.

The original code for CDPSniffino compiled fine on an Uno with a W5100 network shield (kudos again to Chris). I had always planned to make a few network enabled devices, and cost cuts are in effect. The ENC28J60 is significantly cheaper than the W5100, and the Arduino Mini Pro compatible boards have enough capacity to be a good substitute. Arduino Uno R3 + Wiznet W5100 shield >$20. Arduino Mini Pro + ENC28J60 = can be < $5 (shop around).

The ENC28J60 works with the Ethercard library. It took a while to find now to get the NIC to switch to promiscuous mode. When enabled the controller will process all packets it sees, and not filter multicast and broadcast packets.

To make it faster and easier to obtain the info, it needs a screen. The alternative is plugging it in and dragging out a laptop to read the info through a serial port. I tried a few no name LCD’s, but found (as many others have), that without correct information (datasheets or a driver name) it’s a huge time waster. Also most had 3.3v VCC and data lines (not 5v). Luckily I found a cheap supplier that did (after 3 failures). These have been pretty good, they can output text with basic commands using the Adafruit_ST7735 library. I mistakenly had 5V running to the LED line for a while (should be 3.3V) , after the LEDs cooled down, the blue tinge disappeared and all was fine.

The two test rigs shown below are both using ENC28J60 controllers, the larger on has a character LCD and Arduino Uno R3 board. The smaller one has an Arduino Mini Pro (compatible), and an ST7735 based color graphical LCD. During testing the larger one drained a 9V battery after about an hour of use. A goal was to make it small enough to  join to this and use the phone charger battery for power.

What I found when testing:

  • CDP is enabled by default on most Cisco devices.
  • The default schedule for sending CDP packets is every 60 seconds – Although this can be changed or disabled.
  • Wireless Access Points also have CDP enabled by default, which is good when tracing which WAP connects to which power injector (what out for POE!).
  • Un-managed consumer grade switches will pass CDP packets, so the switch you see may not be the one that is connected directly to the port. Also the heavier the traffic on an un-managed switch, the longer it takes to detect the packets. I believe this is because the ENC28J60 doesn’t not have a lot of processing power, and the Arduino Mini can’t keep up, so it drops packets when under heavy load.

All code and STL’s for the case will be published when I’m happy with the smaller test unit.

UPDATE: Reprinted case in green and crudely added it too the wireless serial device. Time for a field test.

UPDATE [24-06-14]: I’ve reduced the overall size of the case by about 10% by using a smaller ENC28J60 PCB, and started working on extra features. One of the features I’m working on is getting it to check for open ports (80, 22, and 23) on the detected equipment (if it’s IP can be obtained). If the switch accepts a connection on any of those ports you can gain access to the remote switch using network rather than using a serial cable.

UPDATE [9-1-2015]

As requested below: Source Code (needs clean up)

Edited Ethercard Library  ethercard_edited

Cheers.

23 thoughts on “CDP Sniffing with an Arduino

  1. Greetings! I would love to do this. You mentioned you would publish the final code. Do you have that available somewhere? Thanks!

  2. I get compile errors with your code attached. Can you please fix it?
    most probably here:
    ip=ip.substring(ip.length()-1)=”;

    Error:

    This report would have more information with
    “Show verbose output during compilation”
    enabled in File > Preferences.
    Arduino: 1.0.6 (Mac OS X), Board: “Arduino Pro or Pro Mini (5V, 16 MHz) w/ ATmega328″
    LCD_Listener_Nano.ino: In function ‘String print_ip(const byte*, unsigned int, unsigned int)’:
    LCD_Listener_Nano:320: error: ambiguous overload for ‘operator=’ in ‘String::substring(unsigned int) const((ip.String::length() + 65535u)) = ’00”
    /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WString.h:86: note: candidates are: String& String::operator=(const String&)
    /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WString.h:87: note: String& String::operator=(const char*)
    /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/cores/arduino/WString.h:88: note: String& String::operator=(const __FlashStringHelper*)

  3. Got the code fixed and all good but one minor issue.
    Sometimes DHCP gives 0.0.0.0 as the DHCP IP address.
    Have you seen this? Any fix?

    Thanks

    • Hi, unless you’ve changed it, the code waits 20 seconds for a DHCP reply. I have also gotten 0.0.0.0 on the odd occasion, when I’ve turned it on and not plugged the network cable in fast enough, I originally wanted to have a loop that keeps going until it detects line sync on the NIC, but I wasn’t able to get it to work. You’ll also get “0.0.0.0” when plugged into a trunked port where you shouldn’t receive DHCP requests, but you’ll still see CDP packets.

      Cheers.

      • Access port not a trunk port.

        Sometimes if I turn it off and turned it back on with the same cable connected, occasionally gets 0.0.0.0 but it gives switch information correctly.
        I get;
        1) DHCP Failed message
        2) Then I unplug the network cable and plug it back on.
        3) DHCP IP: 0.0.0.0 but Correct device information displayed except DHCP

  4. Hi there! I am a C++ developer with a side hobby in hardware hacking and arduinos. I had this unoriginal idea the other day LOL that I should be able to create an in-line packet sniffer using an arduino and Ethernet shield, but it seems you’ve already done this. What I would like to do however is be able to modify the packet data based on some custom filter before the packet goes out the door. I wanted to ask you, do you think your device could be easily modified in that respect? I want to situate this between my router and a PlayStation 3. It will need to work transparently to the PS3 during online play. Any ideas? I really want to learn how to do this and don’t mind paying for the tutoring. Everyone is telling me the device would be SLOW, but gameplay packets generally have a tiny footprint. I won’t be streaming movies or downloading files over this thing. Email me please, Thanks!

  5. I’m intending to use this as a little Network tester fot work. I’m always having to borrow my boss’s fluke just to pull port info. So I’m going to throw my own version of this together and I’ll publish my work as well.

    However, a question I had, I’m trying to determine whether the NIC will survive POE. All the jacks usually have it enabled. Its type B terminations and all thr jacks are gigabit. So it’s a super imposed signal on some of the lines. As far as I understand, I shouldn’t have to worry about it. I don’t intend to utilize the power or measure it. Just don’t want to burn it up. Have you ever plugged this into a POE jack?

    • Hi Gary, Ive used it with many current Cisco switches that have POE capabilites and it was ok. I have also had it plugged into the seperate power injectors and its been fine. What I cant confirm is if it will survive a passive power injector – one that has the voltage running all the time.

      Please let me know how you go with your project.

      Cheers

Leave a Reply

Your email address will not be published. Required fields are marked *

*