# HG changeset patch # User Michael Spacefalcon # Date 1420613733 0 # Node ID 0c631396b8ce3f15245316882a4fbe1bf5a046d0 # Parent 6b966854196508a0aff40394c00fe7117e682942 started grokdsn utility, parses header successfully diff -r 6b9668541965 -r 0c631396b8ce .hgignore --- a/.hgignore Thu Dec 04 07:25:12 2014 +0000 +++ b/.hgignore Wed Jan 07 06:55:33 2015 +0000 @@ -21,6 +21,7 @@ ^miscprog/atsc$ ^miscprog/calextract$ ^miscprog/factdiff$ +^miscprog/grokdsn$ ^miscprog/imeibrute$ ^miscprog/mokosrec2bin$ ^miscprog/pircksum$ diff -r 6b9668541965 -r 0c631396b8ce miscprog/Makefile --- a/miscprog/Makefile Thu Dec 04 07:25:12 2014 +0000 +++ b/miscprog/Makefile Wed Jan 07 06:55:33 2015 +0000 @@ -1,6 +1,6 @@ CC= gcc CFLAGS= -O2 -STD= atsc calextract factdiff mokosrec2bin pircksum rfcap-grep +STD= atsc calextract factdiff grokdsn mokosrec2bin pircksum rfcap-grep CRYPTO= imeibrute pirimei PROGS= ${STD} ${CRYPTO} @@ -15,6 +15,7 @@ atsc: atsc.c calextract: calextract.c factdiff: factdiff.c +grokdsn: grokdsn.c imeibrute: imeibrute.c mokosrec2bin: mokosrec2bin.c pircksum: pircksum.c diff -r 6b9668541965 -r 0c631396b8ce miscprog/grokdsn.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/miscprog/grokdsn.c Wed Jan 07 06:55:33 2015 +0000 @@ -0,0 +1,128 @@ +/* + * We have TI's Leonardo reference schematics in the form of 3 different PDF + * versions and an OrCAD DSN file corresponding to one of them. The latter + * appears (based on a cursory strings(1) inspection) to contain more + * juicy information than is present in the PDF prints. We need to extract + * as much of this information as we can in order to replicate the lost + * Leonardo board as closely as possible. + * + * The top level structure of this DSN file appears to be Microsoft CDF. + * Therefore, I shall begin by parsing this "archive" structure and + * extracting the individual files contained therein, in an effort to gain + * more insight as to what goes with what than can be gleaned from strings(1) + * on the raw DSN file. This hack-utility is my CDF parser written for + * this specific purpose. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HEADER_MFAT_ENTRIES 109 +struct cdf_header { + u_char magic[8]; + u_char uid[16]; + uint16_t fmt_minor; + uint16_t fmt_major; + uint16_t byte_order; + uint16_t sector_size; + uint16_t subsec_size; + u_char rsvd1[10]; + uint32_t fat_sectors; + uint32_t dir_start; + u_char rsvd2[4]; + uint32_t min_large_file; + uint32_t subfat_start; + uint32_t subfat_sectors; + uint32_t mfat_start; + uint32_t mfat_sectors; + uint32_t fat_secids[HEADER_MFAT_ENTRIES]; +}; + +char *dsnfilename; +u_char *filemapping; +struct cdf_header *cdf_header; +unsigned total_sectors; + +open_and_mmap_file() +{ + int fd; + struct stat st; + + fd = open(dsnfilename, O_RDONLY); + if (fd < 0) { + perror(dsnfilename); + exit(1); + } + fstat(fd, &st); + if (!S_ISREG(st.st_mode)) { + fprintf(stderr, "error: %s is not a regular file\n", + dsnfilename); + exit(1); + } + if (st.st_size < 512) { + fprintf(stderr, "error: %s is shorter than 512 bytes\n", + dsnfilename); + exit(1); + } + if (st.st_size % 512) { + fprintf(stderr, "error: %s is not a multiple of 512 bytes\n", + dsnfilename); + exit(1); + } + filemapping = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (filemapping == MAP_FAILED) { + perror("mmap"); + exit(1); + } + close(fd); + cdf_header = (struct cdf_header *) filemapping; + total_sectors = st.st_size / 512 - 1; + return(0); +} + +dump_cdf_header() +{ + printf("Magic: %02X %02X %02X %02X %02X %02X %02X %02X\n", + cdf_header->magic[0], cdf_header->magic[1], + cdf_header->magic[2], cdf_header->magic[3], + cdf_header->magic[4], cdf_header->magic[5], + cdf_header->magic[6], cdf_header->magic[7]); + printf("Format version: %04X.%04X\n", le16toh(cdf_header->fmt_major), + le16toh(cdf_header->fmt_minor)); + printf("Sector / subsector shift: %u / %u\n", + le16toh(cdf_header->sector_size), + le16toh(cdf_header->subsec_size)); + printf("Total FAT sectors: %u\n", le32toh(cdf_header->fat_sectors)); + printf("Directory start sector: %u\n", le32toh(cdf_header->dir_start)); + printf("File size threshold: %u\n", + le32toh(cdf_header->min_large_file)); + return(0); +} + +main(argc, argv) + char **argv; +{ + if (sizeof(struct cdf_header) != 512) { + fprintf(stderr, "error: struct cdf_header is misdefined\n"); + exit(1); + } + if (argc != 3) { + fprintf(stderr, "usage: %s binfile.dsn \n", argv[0]); + exit(1); + } + dsnfilename = argv[1]; + open_and_mmap_file(); + if (!strcmp(argv[2], "hdr")) + return dump_cdf_header(); + fprintf(stderr, "error: \"%s\" is not a recognized command\n", argv[2]); + exit(1); +}