• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/firmware-utils/src/avm-wasp-checksum.c

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  * Copyright (C) 2020 Andreas Boehler <dev@aboehler.at>
  4  *
  5  * This tool was based on:
  6  *      firmware-crc.pl by Atheros Communications
  7  *
  8  * This program is free software; you can redistribute it and/or modify it
  9  * under the terms of the GNU General Public License version 2 as published
 10  * by the Free Software Foundation.
 11  *
 12  */
 13 
 14 #include <stdlib.h>
 15 #include <stdio.h>
 16 #include <stdint.h>
 17 #include <string.h>
 18 #include <getopt.h>     /* for getopt() */
 19 #include <byteswap.h>
 20 
 21 char *infile;
 22 char *outfile;
 23 char *progname;
 24 enum {
 25         MODEL_3390,
 26         MODEL_X490
 27 } model;
 28 
 29 #define CHUNK_SIZE 256
 30 
 31 uint32_t crc32_for_byte(uint32_t r)
 32 {
 33         for (int j = 0; j < 8; ++j)
 34                 r = (r & 1 ? 0 : (uint32_t)0xEDB88320L) ^ r >> 1;
 35         return r ^ (uint32_t)0xFF000000L;
 36 }
 37 
 38 void crc32(const void *data, size_t n_bytes, uint32_t *crc)
 39 {
 40         static uint32_t table[0x100];
 41 
 42         if (!*table)
 43                 for (size_t i = 0; i < 0x100; ++i)
 44                         table[i] = crc32_for_byte(i);
 45         for (size_t i = 0; i < n_bytes; ++i)
 46                 *crc = table[(uint8_t)*crc ^ ((uint8_t *)data)[i]] ^ *crc >> 8;
 47 }
 48 
 49 static void usage(int status)
 50 {
 51         fprintf(stderr, "Usage: %s [OPTIONS...]\n", progname);
 52         fprintf(stderr,
 53                 "\n"
 54                 "Options:\n"
 55                 "  -i              input file name\n"
 56                 "  -o              output file name\n"
 57                 "  -m              model (3390, x490 for 3490/5490/7490)\n"
 58                 "  -h              show this screen\n"
 59         );
 60 
 61         exit(status);
 62 }
 63 
 64 int main(int argc, char *argv[])
 65 {
 66         uint32_t crc = 0;
 67         FILE *in_fp;
 68         FILE *out_fp;
 69         uint32_t buf[CHUNK_SIZE];
 70         size_t read;
 71 
 72         progname = argv[0];
 73 
 74         while (1) {
 75                 int c;
 76 
 77                 c = getopt(argc, argv, "i:o:m:h");
 78                 if (c == -1)
 79                         break;
 80 
 81                 switch (c) {
 82                 case 'i':
 83                         infile = optarg;
 84                         break;
 85                 case 'o':
 86                         outfile = optarg;
 87                         break;
 88                 case 'm':
 89                         if (strcmp(optarg, "3390") == 0)
 90                                 model = MODEL_3390;
 91                         else if (strcmp(optarg, "x490") == 0)
 92                                 model = MODEL_X490;
 93                         else
 94                                 usage(EXIT_FAILURE);
 95                         break;
 96                 case 'h':
 97                         usage(EXIT_SUCCESS);
 98                 default:
 99                         usage(EXIT_FAILURE);
100                         break;
101                 }
102         }
103 
104         if (!infile || !outfile)
105                 usage(EXIT_FAILURE);
106 
107         in_fp = fopen(infile, "r");
108         if (!in_fp) {
109                 fprintf(stderr, "Error opening input file: %s\n", infile);
110                 return EXIT_FAILURE;
111         }
112         out_fp = fopen(outfile, "w");
113         if (!out_fp) {
114                 fprintf(stderr, "Error opening output file: %s\n", outfile);
115                 fclose(in_fp);
116                 return EXIT_FAILURE;
117         }
118 
119         while (!feof(in_fp)) {
120                 switch (model) {
121                 case MODEL_3390:
122                         read = fread(buf, sizeof(uint32_t), CHUNK_SIZE, in_fp);
123                         if (ferror(in_fp)) {
124                                 fprintf(stderr, "Error reading input file: %s\n", infile);
125                                 fclose(in_fp);
126                                 fclose(out_fp);
127                                 return EXIT_FAILURE;
128                         }
129                         for (int i = 0; i < read; i++)
130                                 crc = crc ^ buf[i];
131                         fwrite(buf, sizeof(uint32_t), read, out_fp);
132                         if (ferror(out_fp)) {
133                                 fprintf(stderr, "Error writing output file: %s\n", outfile);
134                                 fclose(in_fp);
135                                 fclose(out_fp);
136                                 return EXIT_FAILURE;
137                         }
138                         break;
139                 case MODEL_X490:
140                         read = fread(buf, 1, sizeof(uint32_t) * CHUNK_SIZE, in_fp);
141                         if (ferror(in_fp)) {
142                                 fprintf(stderr, "Error reading input file: %s\n", infile);
143                                 fclose(in_fp);
144                                 fclose(out_fp);
145                                 return EXIT_FAILURE;
146                         }
147                         crc32(buf, read, &crc);
148                         fwrite(buf, 1, read, out_fp);
149                         if (ferror(out_fp)) {
150                                 fprintf(stderr, "Error writing output file: %s\n", outfile);
151                                 fclose(in_fp);
152                                 fclose(out_fp);
153                                 return EXIT_FAILURE;
154                         }
155                         break;
156                 }
157         }
158         if (model == MODEL_X490)
159                 crc = bswap_32(crc);
160         fwrite(&crc, sizeof(uint32_t), 1, out_fp);
161         if (ferror(out_fp)) {
162                 fprintf(stderr, "Error writing checksum to output file: %s\n", outfile);
163                 fclose(in_fp);
164                 fclose(out_fp);
165                 return EXIT_FAILURE;
166         }
167         fclose(in_fp);
168         fclose(out_fp);
169         printf("Done.\n");
170         return EXIT_SUCCESS;
171 }
172 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt