mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-29 01:59:02 +00:00
168 lines
4.9 KiB
C
168 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, sum1;
|
||
|
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;
|
||
|
sum1 = 0;
|
||
|
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;
|
||
|
}
|