aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware-utils/src/dgn3500sum.c
blob: 6c2937ed51a279e340d67f2c7e3ba68d7b66d3f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// SPDX-License-Identifier: GPL-2.0-or-later
/* **************************************************************************

   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.

 ************************************************************************* */


#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[8 + 8 + 1];

  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;
}