From 38722cca48771a791c08bd4911c208520e4eb627 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Mon, 22 Mar 2010 11:22:54 +0100 Subject: ipa-firmware: Write the firmware parts to a file The first non working version to dump the content of the sdp to the terminal.. --- openbsc/include/openbsc/ipaccess.h | 1 + openbsc/src/ipaccess/ipaccess-config.c | 64 +++++++++++++++++++++++++++++--- openbsc/src/ipaccess/ipaccess-firmware.c | 1 + 3 files changed, 61 insertions(+), 5 deletions(-) (limited to 'openbsc') diff --git a/openbsc/include/openbsc/ipaccess.h b/openbsc/include/openbsc/ipaccess.h index f34cfbd79..86248aae5 100644 --- a/openbsc/include/openbsc/ipaccess.h +++ b/openbsc/include/openbsc/ipaccess.h @@ -89,6 +89,7 @@ struct sdp_header_entry { struct sdp_header_item { struct sdp_header_entry header_entry; struct llist_head entry; + off_t absolute_offset; }; struct sdp_header { diff --git a/openbsc/src/ipaccess/ipaccess-config.c b/openbsc/src/ipaccess/ipaccess-config.c index ad20e67c1..33dd82a4f 100644 --- a/openbsc/src/ipaccess/ipaccess-config.c +++ b/openbsc/src/ipaccess/ipaccess-config.c @@ -57,6 +57,7 @@ static u_int16_t nv_mask; static char *software = NULL; static int sw_load_state = 0; static int oml_state = 0; +static int dump_files = 0; struct sw_load { u_int8_t file_id[255]; @@ -475,6 +476,49 @@ static int find_sw_load_params(const char *filename) return 0; } +static void dump_entry(struct sdp_header_item *sub_entry, int part, int fd) +{ + int out_fd; + int copied; + char filename[4096]; + off_t target; + + if (!dump_files) + return; + + if (sub_entry->header_entry.something1 == 0) + return; + + snprintf(filename, sizeof(filename), "part.%d", part++); + out_fd = open(filename, O_WRONLY | O_CREAT, 0660); + if (out_fd < 0) { + perror("Can not dump firmware"); + return; + } + + target = sub_entry->absolute_offset; + if (lseek(fd, target, SEEK_SET) != target) { + perror("seek failed"); + close(out_fd); + return; + } + + for (copied = 0; copied < ntohl(sub_entry->header_entry.length); ++copied) { + char c; + if (read(fd, &c, sizeof(c)) != sizeof(c)) { + perror("copy failed"); + break; + } + + if (write(out_fd, &c, sizeof(c)) != sizeof(c)) { + perror("write failed"); + break; + } + } + + close(out_fd); +} + static void analyze_firmware(const char *filename) { struct stat stat; @@ -483,6 +527,7 @@ static void analyze_firmware(const char *filename) struct llist_head *entry; int fd; void *tall_firm_ctx = 0; + int part = 0; entry = talloc_zero(tall_firm_ctx, struct llist_head); INIT_LLIST_HEAD(entry); @@ -501,10 +546,6 @@ static void analyze_firmware(const char *filename) } ipaccess_analyze_file(fd, stat.st_size, 0, entry); - if (close(fd) != 0) { - perror("Close failed.\n"); - return; - } llist_for_each_entry(header, entry, entry) { printf("Printing header information:\n"); @@ -530,11 +571,19 @@ static void analyze_firmware(const char *filename) printf("\taddr1: 0x%x\n", ntohl(sub_entry->header_entry.addr1)); printf("\taddr2: 0x%x\n", ntohl(sub_entry->header_entry.addr2)); printf("\tstart: 0x%x\n", ntohl(sub_entry->header_entry.start)); + printf("\tabs. offset: 0x%lx\n", sub_entry->absolute_offset); printf("\n\n"); + + dump_entry(sub_entry, part++, fd); } printf("\n\n"); } + if (close(fd) != 0) { + perror("Close failed.\n"); + return; + } + talloc_free(tall_firm_ctx); } @@ -554,6 +603,7 @@ static void print_help(void) printf(" -s --stream-id ID\n"); printf(" -d --software firmware\n"); printf(" -f --firmware firmware Provide firmware information\n"); + printf(" -w --write-firmware. This will dump the firmware parts to the filesystem. Use with -f.\n"); } int main(int argc, char **argv) @@ -587,9 +637,10 @@ int main(int argc, char **argv) { "stream-id", 1, 0, 's' }, { "software", 1, 0, 'd' }, { "firmware", 1, 0, 'f' }, + { "write-firmware", 0, 0, 'w' }, }; - c = getopt_long(argc, argv, "u:o:rn:l:hs:d:f:", long_options, + c = getopt_long(argc, argv, "u:o:rn:l:hs:d:f:w", long_options, &option_index); if (c == -1) @@ -628,6 +679,9 @@ int main(int argc, char **argv) case 'f': analyze_firmware(optarg); exit(0); + case 'w': + dump_files = 1; + break; case 'h': print_usage(); print_help(); diff --git a/openbsc/src/ipaccess/ipaccess-firmware.c b/openbsc/src/ipaccess/ipaccess-firmware.c index 5f16a7d58..d1004ea9e 100644 --- a/openbsc/src/ipaccess/ipaccess-firmware.c +++ b/openbsc/src/ipaccess/ipaccess-firmware.c @@ -117,6 +117,7 @@ int ipaccess_analyze_file(int fd, const unsigned int st_size, const unsigned int header_entry = talloc_zero(header, struct sdp_header_item); header_entry->header_entry = entry; + header_entry->absolute_offset = lseek(fd, 0, SEEK_CUR); llist_add(&header_entry->entry, &header->header_list); /* now we need to find the SDP file... */ -- cgit v1.2.3