/* ************************************************************************** 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 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 #include #include #include 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; }