deadbit is an attempt at an ICMP based memory test (memtest) for routers and network equipment. It works by sending carefully crafted ICMP packets designed to exhaust every input possible when handling ICMP. In theory this could find the issue in situations where network equipment appears to be failing for certain ICMP packets and not others. Hopefully (and this is experimental even for me) if there is a dead bit in the router memory somewhere this test should be able to fail reliably and flush it out.
Couple caveats: This utility is experimental, even for me. At the time of writing I don't actually have a broken piece of network gear to test it against. Second - this utility expects to have some control over the ICMP sequence numbers of outgoing packets. If you are running other pings/traceroutes/whatever at the same time that will likely muck with the results. Finally - in tests that *do* depend on the sequence number, deadbit can't actually tell you what the dead bits *are* (it knows that it sent a 1 one time and a 0 the other, but doesn't know which is which). If you get a positive result and need to figure out whats actually happening you will want to use something like Wireshark to examine the actual packets.
It runs pretty slow by default, waiting politely 1 second between tests. If you want to finish in a reasonable amount of time, use "-i whatever" to set a much smaller wait period.
Like I said, highly experimental! If you have any success with it, or have any suggestions/fixes/complaints/whatever please let me know!
Deadbit (purports to) perform the following tests:
- Testing all individual bits in the given payload (up to -m SIZE bytes). Deadbit will for instance try 11111111 (imagine 1472 1's). If there was a failure, it will try 11110000 and 00001111 and so on to narrow it down to an individual payload bit that fails if it is set to 1.
- The inverse of the individual bit test - for instance trying 00000000, then on failure trying 11110000 and 00001111 and so on to determine if any individual payload bits fail when they are set to 0.
- Testing each bit in the ICMP checksum field. We don't know the checksum - it is partially based on the ICMP sequence number however and we can influence that - it increments by one every time we send an ICMP packet. So we establish a baseline - just an arbitrary packet with 0x00's for data, and then send 16 packets with their data set to (2^i - 1). Each of these packets should have the bit in slot "i" toggled from its original state - either 0 to 1 or 1 to 0. Other bits may also have changed, but that can't be helped.
- Testing every possible addend that contributes to the checksum. This is relatively straightforward, we send a packet with the data 0x0000 0x0001 0x0002 0x0003... etc until we reach (-m SIZE). We then send a second packet, picking up where we left off. Then a third, etc, until we reach ... 0xFFFD 0xFFFE 0xFFFF. At this point we know that every possible 16 bit word has been fed through the adder.
- Testing all possible checksum carry values. When the checksum is calculated, the 16 bit words are added together and the carry values are stashed and/or calculated somewhere. We attempt to exhaust all possible carry values by starting with our arbitrary sequence number and sending a payload of 0xFFFE 0xFFFE 0xFFFE etc. This should result in first the sequence number being sent to the adder, then the sequence number - 1, then the sequence number - 2, etc. When we reach the end of our packet we grind-ping against localhost enough times to increment the sequence number past the area we have tested and repeat the cycle. Once we rolled the sequence number around 0-65536 to its original position we stop.
- Testing all possible single byte packets. This is straightforward, we send the 256 packets with data set to 0x00 0x00 0x00.. etc through 0xFF 0xFF 0xFF... etc
- Finally, we send 65536 arbitrary packets to test all possible checksums and sequence numbers. This takes the longest and comes complete with a suggestion to maybe press control-c and quit.
***************************************************************** deadbit.exe - written by Eli Fulkerson, Nov 2015 v0.2 - Nov 6 2015 - 20:21:04 http://www.elifulkerson.com/projects/deadbit.php for updates. ***************************************************************** Usage: deadbit [-f] [-m SIZE] host Flags: -f : Allow fragmentation of the packet. -w : Set the number of milliseconds to wait for a response (default 3000). -r : Set the maximum number of probe retries on timeout (default = 3). -i : Set the interval between two echo requests in ms (default 1000). -m : Sets a payload size to test. (Default is 1472) -v : Print version info and exit. -h,-? : Print usage information and exit.
C:\>deadbit -i 50 www.elifulkerson.com Testing: individual stuck data bits - 1 in a field of 0000...etc Will bisect if error found... passed: 0xFF in position(s) 0 through 1472 of 1472 bytes. (other bytes: 0x00) Testing: individual stuck data bits - 0 in a field of 1111...etc Will bisect if error found... passed: 0x00 in position(s) 0 through 1472 of 1472 bytes. (other bytes: 0xFF) Testing: each bit in the ICMP checksum passed: bit in position 0x8000 of checksum toggled. Testing: each possible 16 bit word addend that contributes to the checksum passed: checksum add register test starting at 0x102c0. Testing: all possible checksum carry values passed: chksum carry register test #89 of 90. Actual checksum unknown. Testing: each data packet consisting of one particular byte over and over passed: 0xFF repeating in position(s) 0 through 1472. ~ 0s left Testing: incrementing sequence numbers with same payload to test all possible 2 byte ICMP checksums... --- THIS TEST IS LAST AND TAKES FOREVER. --- --- FEEL FREE TO CTRL-C IF YOU DON'T CARE --- passed: ping #3815 of 65536. ~ 51m 26s left ctrl-c