Configuration Record Checksum

Discussion to talk about software related topics only.
Post Reply
mjacobs
Posts: 2
Joined: Wed Jan 23, 2013 10:22 am

Configuration Record Checksum

Post by mjacobs »

I'm trying to write a Python module that can find and update the IP address for NetBurners. This post by tod was invaluable in working out the packet structure, how to make a broadcast, and listen for responses. One problem remains: calculating the checksum. All documentation and sample code I've seen says that UpdateConfigRecord does that itself. What is the algorithm it uses?
User avatar
dciliske
Posts: 624
Joined: Mon Feb 06, 2012 9:37 am
Location: San Diego, CA
Contact:

Re: Configuration Record Checksum

Post by dciliske »

You'll find the process in the 'system.c' file of the main system library.

The part that actually computes the checksum is

Code: Select all

ConfigRecord cr;
   cr.checksum = 0;
   cr.recordsize = sizeof( cr );

   pTo = ( unsigned short * ) &cr;

   for ( i = 0; i < sizeof( cr ); i += 2 )
   {
      csum += *pTo++;
   }

   cr.checksum = ( 0xAAAA - csum );

Dan Ciliske
Project Engineer
Netburner, Inc
User avatar
pbreed
Posts: 1091
Joined: Thu Apr 24, 2008 3:58 pm

Re: Configuration Record Checksum

Post by pbreed »

Note that in python on a PC you will likely have big endian vs little endian issues with this computation...

When sending a new config record via the ipsetup protocol you don't need to do the checksum, just set it to zero, the device will checksum it before it saves it.
mjacobs
Posts: 2
Joined: Wed Jan 23, 2013 10:22 am

Re: Configuration Record Checksum

Post by mjacobs »

Thanks so far but I think I may be running into endianness problems. The code I'm using right now is this:

Code: Select all

ints = [ord(x) for x in config_record]
running_total = 0
for i in range(0, len(ints), 2):
    running_total += int((ints[i] << 8) | ints[i + 1])
checksum = (0xAAAA - (running_total & 0xFFFF)) % 0x10000
The general flow of the code:
  1. It takes the config record as a string and converts each character to the integer equivalent.
  2. By steps of two, two ints are taken and combined into a 16 bit value. This is then added to the running total.
  3. Since Python supports arbitrarily large integers, all but the bottom 2 bytes need to be ignored (emulating the integer overflow in C).
  4. It is subtracted from 0xAAAA.
  5. To get it back to a positive number (since it needs to be unsigned), modulus 0x10000 is used.
The first two values of the configuration record are the size of the record itself and the IP address. If these are 148 (0x00000094) and 192.168.1.100 (0xC0A80164), my code would do as follows:
  1. config_record = "\x00\x00\x00\x94\xC0\xA8\x01\x64..."
    {0x00, 0x00, 0x00, 0x94, 0xC0, 0xA8, 0x01, 0x64}
  2. 0x0000 + 0x0094 + 0xC0A8 + 0x0164 = 0xC2A0
  3. 0xC2A0 & 0xFFFF = 0xC2A0
  4. 0xAAAA - 0xC2A0 = -0x17F6
  5. -0x17F6 % 0x10000 = 0xE80A
For that (small) piece of data, is my algorithm correct? Are the numbers stored correctly?
User avatar
pbreed
Posts: 1091
Joined: Thu Apr 24, 2008 3:58 pm

Re: Configuration Record Checksum

Post by pbreed »

I have no quick way to test your code, it looks correct....
You big endian conversion scheme looks correct....

however the step in the code Dan posted

cr.checksum = 0;

is important, IE you must pput a 0 value in the cehcksum part of the config record before you do the csum...


Here is a way to cheat... a bit and get a know good example...
You can load an app in the unit and do the following...

#include <utils.h>

//Then in your code ...
ShowData((PBYTE)&gConfigRec,sizeof(gConfigRec));
iprintf("gConfigRec.csum = %04X\r\n",gConfigRec.checksum;

This should give you a known good config record to calculate against....
Post Reply