Configuration Record Checksum
Configuration Record Checksum
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?
Re: Configuration Record Checksum
You'll find the process in the 'system.c' file of the main system library.
The part that actually computes the checksum is
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
Project Engineer
Netburner, Inc
Re: Configuration Record Checksum
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.
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.
Re: Configuration Record Checksum
Thanks so far but I think I may be running into endianness problems. The code I'm using right now is this:
The general flow of the code:
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
- It takes the config record as a string and converts each character to the integer equivalent.
- By steps of two, two ints are taken and combined into a 16 bit value. This is then added to the running total.
- Since Python supports arbitrarily large integers, all but the bottom 2 bytes need to be ignored (emulating the integer overflow in C).
- It is subtracted from 0xAAAA.
- To get it back to a positive number (since it needs to be unsigned), modulus 0x10000 is used.
- config_record = "\x00\x00\x00\x94\xC0\xA8\x01\x64..."
{0x00, 0x00, 0x00, 0x94, 0xC0, 0xA8, 0x01, 0x64} - 0x0000 + 0x0094 + 0xC0A8 + 0x0164 = 0xC2A0
- 0xC2A0 & 0xFFFF = 0xC2A0
- 0xAAAA - 0xC2A0 = -0x17F6
- -0x17F6 % 0x10000 = 0xE80A
Re: Configuration Record Checksum
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....
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....