aboutsummaryrefslogtreecommitdiffstats
path: root/tools/firmware-utils/src/mktplinkfw-lib.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/firmware-utils/src/mktplinkfw-lib.c')
-rw-r--r--tools/firmware-utils/src/mktplinkfw-lib.c195
1 files changed, 195 insertions, 0 deletions
diff --git a/tools/firmware-utils/src/mktplinkfw-lib.c b/tools/firmware-utils/src/mktplinkfw-lib.c
new file mode 100644
index 0000000000..838b1792ff
--- /dev/null
+++ b/tools/firmware-utils/src/mktplinkfw-lib.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This tool was based on:
+ * TP-Link WR941 V2 firmware checksum fixing tool.
+ * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h> /* for unlink() */
+#include <libgen.h>
+#include <getopt.h> /* for getopt() */
+#include <stdarg.h>
+#include <stdbool.h>
+#include <endian.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include "mktplinkfw-lib.h"
+#include "md5.h"
+
+extern char *progname;
+static unsigned char jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
+
+struct flash_layout *find_layout(struct flash_layout *layouts, const char *id)
+{
+ struct flash_layout *ret;
+ struct flash_layout *l;
+
+ ret = NULL;
+ for (l = layouts; l->id != NULL; l++){
+ if (strcasecmp(id, l->id) == 0) {
+ ret = l;
+ break;
+ }
+ };
+
+ return ret;
+}
+
+void get_md5(const char *data, int size, uint8_t *md5)
+{
+ MD5_CTX ctx;
+
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, data, size);
+ MD5_Final(md5, &ctx);
+}
+
+int get_file_stat(struct file_info *fdata)
+{
+ struct stat st;
+ int res;
+
+ if (fdata->file_name == NULL)
+ return 0;
+
+ res = stat(fdata->file_name, &st);
+ if (res){
+ ERRS("stat failed on %s", fdata->file_name);
+ return res;
+ }
+
+ fdata->file_size = st.st_size;
+ return 0;
+}
+
+int read_to_buf(const struct file_info *fdata, char *buf)
+{
+ FILE *f;
+ int ret = EXIT_FAILURE;
+
+ f = fopen(fdata->file_name, "r");
+ if (f == NULL) {
+ ERRS("could not open \"%s\" for reading", fdata->file_name);
+ goto out;
+ }
+
+ errno = 0;
+ fread(buf, fdata->file_size, 1, f);
+ if (errno != 0) {
+ ERRS("unable to read from file \"%s\"", fdata->file_name);
+ goto out_close;
+ }
+
+ ret = EXIT_SUCCESS;
+
+out_close:
+ fclose(f);
+out:
+ return ret;
+}
+
+int pad_jffs2(char *buf, int currlen, int maxlen)
+{
+ int len;
+ uint32_t pad_mask;
+
+ len = currlen;
+ pad_mask = (64 * 1024);
+ while ((len < maxlen) && (pad_mask != 0)) {
+ uint32_t mask;
+ int i;
+
+ for (i = 10; i < 32; i++) {
+ mask = 1 << i;
+ if (pad_mask & mask)
+ break;
+ }
+
+ len = ALIGN(len, mask);
+
+ for (i = 10; i < 32; i++) {
+ mask = 1 << i;
+ if ((len & (mask - 1)) == 0)
+ pad_mask &= ~mask;
+ }
+
+ for (i = 0; i < sizeof(jffs2_eof_mark); i++)
+ buf[len + i] = jffs2_eof_mark[i];
+
+ len += sizeof(jffs2_eof_mark);
+ }
+
+ return len;
+}
+
+int write_fw(const char *ofname, const char *data, int len)
+{
+ FILE *f;
+ int ret = EXIT_FAILURE;
+
+ f = fopen(ofname, "w");
+ if (f == NULL) {
+ ERRS("could not open \"%s\" for writing", ofname);
+ goto out;
+ }
+
+ errno = 0;
+ fwrite(data, len, 1, f);
+ if (errno) {
+ ERRS("unable to write output file");
+ goto out_flush;
+ }
+
+ DBG("firmware file \"%s\" completed", ofname);
+
+ ret = EXIT_SUCCESS;
+
+out_flush:
+ fflush(f);
+ fclose(f);
+ if (ret != EXIT_SUCCESS) {
+ unlink(ofname);
+ }
+out:
+ return ret;
+}
+
+/* Helper functions to inspect_fw() representing different output formats */
+inline void inspect_fw_pstr(const char *label, const char *str)
+{
+ printf("%-23s: %s\n", label, str);
+}
+
+inline void inspect_fw_phex(const char *label, uint32_t val)
+{
+ printf("%-23s: 0x%08x\n", label, val);
+}
+
+inline void inspect_fw_phexdec(const char *label, uint32_t val)
+{
+ printf("%-23s: 0x%08x / %8u bytes\n", label, val, val);
+}
+
+inline void inspect_fw_pmd5sum(const char *label, const uint8_t *val, const char *text)
+{
+ int i;
+
+ printf("%-23s:", label);
+ for (i=0; i<MD5SUM_LEN; i++)
+ printf(" %02x", val[i]);
+ printf(" %s\n", text);
+}