openwrtv4/tools/firmware-utils/src/dgn3500sum.c
Mathias Kresin 06741411e0 firmware-utils: fix dgn3500sum compiler warnings
The sum variable need to be initialised, otherwise it will points to
random stack memory and a bogus image checksum might be calculated.

While at it, fix the segfault in case the product region code isn't
specified and enable compiler warnings which had revealed all the code
issues.

Signed-off-by: Mathias Kresin <dev@kresin.me>
2017-06-26 20:08:36 +02:00

166 lines
4.9 KiB
C

/* **************************************************************************
This program creates a modified 16bit checksum used for the Netgear
DGN3500 series routers. The difference between this and a standard
checksum is that every 0x100 bytes added 0x100 have to be subtracted
from the sum.
(C) 2013 Marco Antonio Mauro <marcus90 at gmail.com>
Based on previous unattributed work.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
************************************************************************* */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
unsigned char PidDataWW[70] =
{
0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
} ;
unsigned char PidDataDE[70] =
{
0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x37,
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
} ;
unsigned char PidDataNA[70] =
{
0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
} ;
/* *******************************************************************
Reads the file into memory and returns pointer to the buffer. */
static char *readfile(char *filename, int *size)
{
FILE *fp;
char *buffer;
struct stat info;
if (stat(filename,&info)!=0)
return NULL;
if ((fp=fopen(filename,"r"))==NULL)
return NULL;
buffer=NULL;
for (;;)
{
if ((buffer=(char *)malloc(info.st_size+1))==NULL)
break;
if (fread(buffer,1,info.st_size,fp)!=info.st_size)
{
free(buffer);
buffer=NULL;
break;
}
buffer[info.st_size]='\0';
if(size) *size = info.st_size;
break;
}
(void)fclose(fp);
return buffer;
}
/* ******************************************************************* */
int main(int argc, char** argv)
{
unsigned long start, i;
char *endptr, *buffer, *p;
int count; // size of file in bytes
unsigned short sum = 0, sum1 = 0;
char sumbuf[9];
if(argc < 3) {
printf("ERROR: Argument missing!\n\nUsage %s filename starting offset in hex [PID code]\n\n", argv[0]);
return 1;
}
FILE *fp = fopen(argv[1], "a");
if(!fp) {
printf("ERROR: File not writeable!\n");
return 1;
}
if(argc == 4)
{
printf("%s: PID type: %s\n", argv[0], argv[3]);
if(strcmp(argv[3], "DE")==0)
fwrite(PidDataDE, sizeof(PidDataDE), sizeof(char), fp); /* write DE pid */
else if(strcmp(argv[3], "NA")==0)
fwrite(PidDataNA, sizeof(PidDataNA), sizeof(char), fp); /* write NA pid */
else /* if(strcmp(argv[3], "WW")) */
fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid */
}
else
fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid if unspecified */
fclose(fp);
/* Read the file to calculate the checksums */
buffer = readfile(argv[1], &count);
if(!buffer) {
printf("ERROR: File %s not found!\n", argv[1]);
return 1;
}
p = buffer;
for(i = 0; i < count; i++)
{
sum += p[i];
}
start = strtol(argv[2], &endptr, 16);
p = buffer+start;
for(i = 0; i < count - start; i++)
{
sum1 += p[i];
}
sprintf(sumbuf,"%04X%04X",sum1,sum);
/* Append the 2 checksums to end of file */
fp = fopen(argv[1], "a");
if(!fp) {
printf("ERROR: File not writeable!\n");
return 1;
}
fwrite(sumbuf, 8, sizeof(char), fp);
fclose(fp);
free(buffer);
return 0;
}