firmware-utils: replace GPL 2.0+ boilerplate/reference with SPDX
[openwrt/openwrt.git] / tools / firmware-utils / src / dgn3500sum.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* **************************************************************************
3
4 This program creates a modified 16bit checksum used for the Netgear
5 DGN3500 series routers. The difference between this and a standard
6 checksum is that every 0x100 bytes added 0x100 have to be subtracted
7 from the sum.
8
9 (C) 2013 Marco Antonio Mauro <marcus90 at gmail.com>
10
11 Based on previous unattributed work.
12
13 ************************************************************************* */
14
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/stat.h>
20
21 unsigned char PidDataWW[70] =
22 {
23 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
24 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
26 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
27 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
28 } ;
29
30 unsigned char PidDataDE[70] =
31 {
32 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
33 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x37,
35 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
36 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
37 } ;
38
39 unsigned char PidDataNA[70] =
40 {
41 0x73, 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D, 0x00, 0x00, 0x00, 0x00, 0x59, 0x50, 0x35, 0x37, 0x32,
42 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x37,
44 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73,
45 0x45, 0x72, 0x43, 0x6F, 0x4D, 0x6D,
46 } ;
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
56 if (stat(filename,&info)!=0)
57 return NULL;
58
59 if ((fp=fopen(filename,"r"))==NULL)
60 return NULL;
61
62 buffer=NULL;
63 for (;;)
64 {
65 if ((buffer=(char *)malloc(info.st_size+1))==NULL)
66 break;
67
68 if (fread(buffer,1,info.st_size,fp)!=info.st_size)
69 {
70 free(buffer);
71 buffer=NULL;
72 break;
73 }
74
75 buffer[info.st_size]='\0';
76 if(size) *size = info.st_size;
77
78 break;
79 }
80
81 (void)fclose(fp);
82
83 return buffer;
84 }
85
86
87 /* ******************************************************************* */
88 int main(int argc, char** argv)
89 {
90 unsigned long start, i;
91 char *endptr, *buffer, *p;
92 int count; // size of file in bytes
93 unsigned short sum = 0, sum1 = 0;
94 char sumbuf[8 + 8 + 1];
95
96 if(argc < 3) {
97 printf("ERROR: Argument missing!\n\nUsage %s filename starting offset in hex [PID code]\n\n", argv[0]);
98 return 1;
99 }
100
101
102 FILE *fp = fopen(argv[1], "a");
103 if(!fp) {
104 printf("ERROR: File not writeable!\n");
105 return 1;
106 }
107 if(argc == 4)
108 {
109 printf("%s: PID type: %s\n", argv[0], argv[3]);
110 if(strcmp(argv[3], "DE")==0)
111 fwrite(PidDataDE, sizeof(PidDataDE), sizeof(char), fp); /* write DE pid */
112 else if(strcmp(argv[3], "NA")==0)
113 fwrite(PidDataNA, sizeof(PidDataNA), sizeof(char), fp); /* write NA pid */
114 else /* if(strcmp(argv[3], "WW")) */
115 fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid */
116 }
117 else
118 fwrite(PidDataWW, sizeof(PidDataWW), sizeof(char), fp); /* write WW pid if unspecified */
119
120 fclose(fp);
121
122 /* Read the file to calculate the checksums */
123 buffer = readfile(argv[1], &count);
124 if(!buffer) {
125 printf("ERROR: File %s not found!\n", argv[1]);
126 return 1;
127 }
128
129 p = buffer;
130 for(i = 0; i < count; i++)
131 {
132 sum += p[i];
133 }
134
135 start = strtol(argv[2], &endptr, 16);
136 p = buffer+start;
137 for(i = 0; i < count - start; i++)
138 {
139 sum1 += p[i];
140 }
141
142 sprintf(sumbuf,"%04X%04X",sum1,sum);
143 /* Append the 2 checksums to end of file */
144 fp = fopen(argv[1], "a");
145 if(!fp) {
146 printf("ERROR: File not writeable!\n");
147 return 1;
148 }
149 fwrite(sumbuf, 8, sizeof(char), fp);
150 fclose(fp);
151 free(buffer);
152 return 0;
153 }