dgn3500sum.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* **************************************************************************
  2. This program creates a modified 16bit checksum used for the Netgear
  3. DGN3500 series routers. The difference between this and a standard
  4. checksum is that every 0x100 bytes added 0x100 have to be subtracted
  5. from the sum.
  6. (C) 2013 Marco Antonio Mauro <marcus90 at gmail.com>
  7. Based on previous unattributed work.
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. ************************************************************************* */
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <sys/stat.h>
  24. unsigned char PidDataWW[70] =
  25. {
  26. 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
  27. 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  28. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
  29. 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
  30. 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
  31. } ;
  32. unsigned char PidDataDE[70] =
  33. {
  34. 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
  35. 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  36. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x37,
  37. 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
  38. 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
  39. } ;
  40. unsigned char PidDataNA[70] =
  41. {
  42. 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
  43. 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  44. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
  45. 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
  46. 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
  47. } ;
  48. /* *******************************************************************
  49. Reads the file into memory and returns pointer to the buffer. */
  50. static char *readfile(char *filename, int *size)
  51. {
  52. FILE *fp;
  53. char *buffer;
  54. struct stat info;
  55. if (stat(filename,&info)!=0)
  56. return NULL;
  57. if ((fp=fopen(filename,"r"))==NULL)
  58. return NULL;
  59. buffer=NULL;
  60. for (;;)
  61. {
  62. if ((buffer=(char *)malloc(info.st_size+1))==NULL)
  63. break;
  64. if (fread(buffer,1,info.st_size,fp)!=info.st_size)
  65. {
  66. free(buffer);
  67. buffer=NULL;
  68. break;
  69. }
  70. buffer[info.st_size]='\0';
  71. if(size) *size = info.st_size;
  72. break;
  73. }
  74. (void)fclose(fp);
  75. return buffer;
  76. }
  77. /* ******************************************************************* */
  78. int main(int argc, char** argv)
  79. {
  80. unsigned long start, i;
  81. char *endptr, *buffer, *p;
  82. int count; // size of file in bytes
  83. unsigned short sum = 0, sum1 = 0;
  84. char sumbuf[9];
  85. if(argc < 3) {
  86. printf("ERROR: Argument missing!\n\nUsage %s filename starting offset in hex [PID code]\n\n", argv[0]);
  87. return 1;
  88. }
  89. FILE *fp = fopen(argv[1], "a");
  90. if(!fp) {
  91. printf("ERROR: File not writeable!\n");
  92. return 1;
  93. }
  94. if(argc == 4)
  95. {
  96. printf("%s: PID type: %s\n", argv[0], argv[3]);
  97. if(strcmp(argv[3], "DE")==0)
  98. fwrite(PidDataDE, sizeof(PidDataDE), sizeof(char), fp); /* write DE pid */
  99. else if(strcmp(argv[3], "NA")==0)
  100. fwrite(PidDataNA, sizeof(PidDataNA), sizeof(char), fp); /* write NA pid */
  101. else /* if(strcmp(argv[3], "WW")) */
  102. fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid */
  103. }
  104. else
  105. fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid if unspecified */
  106. fclose(fp);
  107. /* Read the file to calculate the checksums */
  108. buffer = readfile(argv[1], &count);
  109. if(!buffer) {
  110. printf("ERROR: File %s not found!\n", argv[1]);
  111. return 1;
  112. }
  113. p = buffer;
  114. for(i = 0; i < count; i++)
  115. {
  116. sum += p[i];
  117. }
  118. start = strtol(argv[2], &endptr, 16);
  119. p = buffer+start;
  120. for(i = 0; i < count - start; i++)
  121. {
  122. sum1 += p[i];
  123. }
  124. sprintf(sumbuf,"%04X%04X",sum1,sum);
  125. /* Append the 2 checksums to end of file */
  126. fp = fopen(argv[1], "a");
  127. if(!fp) {
  128. printf("ERROR: File not writeable!\n");
  129. return 1;
  130. }
  131. fwrite(sumbuf, 8, sizeof(char), fp);
  132. fclose(fp);
  133. free(buffer);
  134. return 0;
  135. }