diff options
author | Zoltan Herpai <wigyori@uid0.hu> | 2016-06-28 10:08:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-06-28 10:08:04 +0200 |
commit | eaeb4e48938014039899b0312e8e87da1073e348 (patch) | |
tree | 58519cde29158a1611b398c0e75b576125e5aa61 /package | |
parent | debeac0f833c2de3f15fe14135e365b6d8f54908 (diff) | |
parent | 3b0bfeac5cbb3df53755859299e9188981175b66 (diff) | |
download | master-187ad058-eaeb4e48938014039899b0312e8e87da1073e348.tar.gz master-187ad058-eaeb4e48938014039899b0312e8e87da1073e348.tar.bz2 master-187ad058-eaeb4e48938014039899b0312e8e87da1073e348.zip |
Merge pull request #16 from wigyori/master
Update bcm53xx, brcm63xx, octeon, and smaller patches
Diffstat (limited to 'package')
-rw-r--r-- | package/libs/libnetfilter-queue/patches/100-checksum_computation.patch | 113 | ||||
-rw-r--r-- | package/system/mtd/src/mtd.c | 8 | ||||
-rw-r--r-- | package/system/mtd/src/mtd.h | 2 | ||||
-rw-r--r-- | package/system/mtd/src/seama.c | 6 | ||||
-rw-r--r-- | package/utils/oseama/src/oseama.c | 134 |
5 files changed, 256 insertions, 7 deletions
diff --git a/package/libs/libnetfilter-queue/patches/100-checksum_computation.patch b/package/libs/libnetfilter-queue/patches/100-checksum_computation.patch new file mode 100644 index 0000000000..cbbff827dd --- /dev/null +++ b/package/libs/libnetfilter-queue/patches/100-checksum_computation.patch @@ -0,0 +1,113 @@ +--- a/src/extra/checksum.c ++++ b/src/extra/checksum.c +@@ -11,6 +11,7 @@ + + #include <stdio.h> + #include <stdbool.h> ++#include <endian.h> + #include <arpa/inet.h> + #include <netinet/ip.h> + #include <netinet/ip6.h> +@@ -26,8 +27,13 @@ uint16_t checksum(uint32_t sum, uint16_t + sum += *buf++; + size -= sizeof(uint16_t); + } +- if (size) +- sum += *(uint8_t *)buf; ++ if (size) { ++#if __BYTE_ORDER == __BIG_ENDIAN ++ sum += (uint16_t)*(uint8_t *)buf << 8; ++#else ++ sum += (uint16_t)*(uint8_t *)buf; ++#endif ++ } + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >>16); +@@ -35,7 +41,7 @@ uint16_t checksum(uint32_t sum, uint16_t + return (uint16_t)(~sum); + } + +-uint16_t checksum_tcpudp_ipv4(struct iphdr *iph) ++uint16_t checksum_tcpudp_ipv4(struct iphdr *iph, uint16_t protocol_id) + { + uint32_t sum = 0; + uint32_t iph_len = iph->ihl*4; +@@ -46,13 +52,13 @@ uint16_t checksum_tcpudp_ipv4(struct iph + sum += (iph->saddr) & 0xFFFF; + sum += (iph->daddr >> 16) & 0xFFFF; + sum += (iph->daddr) & 0xFFFF; +- sum += htons(IPPROTO_TCP); ++ sum += htons(protocol_id); + sum += htons(len); + + return checksum(sum, (uint16_t *)payload, len); + } + +-uint16_t checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr) ++uint16_t checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr, uint16_t protocol_id) + { + uint32_t sum = 0; + uint32_t hdr_len = (uint32_t *)transport_hdr - (uint32_t *)ip6h; +@@ -68,7 +74,7 @@ uint16_t checksum_tcpudp_ipv6(struct ip6 + sum += (ip6h->ip6_dst.s6_addr16[i] >> 16) & 0xFFFF; + sum += (ip6h->ip6_dst.s6_addr16[i]) & 0xFFFF; + } +- sum += htons(IPPROTO_TCP); ++ sum += htons(protocol_id); + sum += htons(ip6h->ip6_plen); + + return checksum(sum, (uint16_t *)payload, len); +--- a/src/extra/tcp.c ++++ b/src/extra/tcp.c +@@ -91,7 +91,7 @@ nfq_tcp_compute_checksum_ipv4(struct tcp + { + /* checksum field in header needs to be zero for calculation. */ + tcph->check = 0; +- tcph->check = checksum_tcpudp_ipv4(iph); ++ tcph->check = checksum_tcpudp_ipv4(iph, IPPROTO_TCP); + } + EXPORT_SYMBOL(nfq_tcp_compute_checksum_ipv4); + +@@ -105,7 +105,7 @@ nfq_tcp_compute_checksum_ipv6(struct tcp + { + /* checksum field in header needs to be zero for calculation. */ + tcph->check = 0; +- tcph->check = checksum_tcpudp_ipv6(ip6h, tcph); ++ tcph->check = checksum_tcpudp_ipv6(ip6h, tcph, IPPROTO_TCP); + } + EXPORT_SYMBOL(nfq_tcp_compute_checksum_ipv6); + +--- a/src/extra/udp.c ++++ b/src/extra/udp.c +@@ -91,7 +91,7 @@ nfq_udp_compute_checksum_ipv4(struct udp + { + /* checksum field in header needs to be zero for calculation. */ + udph->check = 0; +- udph->check = checksum_tcpudp_ipv4(iph); ++ udph->check = checksum_tcpudp_ipv4(iph, IPPROTO_UDP); + } + EXPORT_SYMBOL(nfq_udp_compute_checksum_ipv4); + +@@ -110,7 +110,7 @@ nfq_udp_compute_checksum_ipv6(struct udp + { + /* checksum field in header needs to be zero for calculation. */ + udph->check = 0; +- udph->check = checksum_tcpudp_ipv6(ip6h, udph); ++ udph->check = checksum_tcpudp_ipv6(ip6h, udph, IPPROTO_UDP); + } + EXPORT_SYMBOL(nfq_udp_compute_checksum_ipv6); + +--- a/src/internal.h ++++ b/src/internal.h +@@ -13,8 +13,8 @@ struct iphdr; + struct ip6_hdr; + + uint16_t checksum(uint32_t sum, uint16_t *buf, int size); +-uint16_t checksum_tcpudp_ipv4(struct iphdr *iph); +-uint16_t checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr); ++uint16_t checksum_tcpudp_ipv4(struct iphdr *iph, uint16_t protocol_id); ++uint16_t checksum_tcpudp_ipv6(struct ip6_hdr *ip6h, void *transport_hdr, uint16_t protocol_id); + + struct pkt_buff { + uint8_t *mac_header; diff --git a/package/system/mtd/src/mtd.c b/package/system/mtd/src/mtd.c index af544198cb..7d1fc8df72 100644 --- a/package/system/mtd/src/mtd.c +++ b/package/system/mtd/src/mtd.c @@ -674,7 +674,7 @@ resume: break; case MTD_IMAGE_FORMAT_SEAMA: if (mtd_fixseama) - mtd_fixseama(mtd, 0); + mtd_fixseama(mtd, 0, 0); break; default: break; @@ -737,8 +737,10 @@ static void usage(void) if (mtd_fixtrx) { fprintf(stderr, " -o offset offset of the image header in the partition(for fixtrx)\n"); + } + if (mtd_fixtrx || mtd_fixseama) { fprintf(stderr, - " -c datasize amount of data to be used for checksum calculation (for fixtrx)\n"); + " -c datasize amount of data to be used for checksum calculation (for fixtrx / fixseama)\n"); } fprintf(stderr, #ifdef FIS_SUPPORT @@ -987,7 +989,7 @@ int main (int argc, char **argv) break; case CMD_FIXSEAMA: if (mtd_fixseama) - mtd_fixseama(device, 0); + mtd_fixseama(device, 0, data_size); break; } diff --git a/package/system/mtd/src/mtd.h b/package/system/mtd/src/mtd.h index 0a8b1ae0fd..9b2e32ffd4 100644 --- a/package/system/mtd/src/mtd.h +++ b/package/system/mtd/src/mtd.h @@ -26,6 +26,6 @@ extern void mtd_parse_jffs2data(const char *buf, const char *dir); extern int trx_fixup(int fd, const char *name) __attribute__ ((weak)); extern int trx_check(int imagefd, const char *mtd, char *buf, int *len) __attribute__ ((weak)); extern int mtd_fixtrx(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak)); -extern int mtd_fixseama(const char *mtd, size_t offset) __attribute__ ((weak)); +extern int mtd_fixseama(const char *mtd, size_t offset, size_t data_size) __attribute__ ((weak)); extern int mtd_resetbc(const char *mtd) __attribute__ ((weak)); #endif /* __mtd_h */ diff --git a/package/system/mtd/src/seama.c b/package/system/mtd/src/seama.c index f8b677b189..bcda321918 100644 --- a/package/system/mtd/src/seama.c +++ b/package/system/mtd/src/seama.c @@ -104,14 +104,13 @@ err_out: } int -mtd_fixseama(const char *mtd, size_t offset) +mtd_fixseama(const char *mtd, size_t offset, size_t data_size) { int fd; char *first_block; ssize_t res; size_t block_offset; size_t data_offset; - size_t data_size; struct seama_entity_header *shdr; if (quiet < 2) @@ -155,7 +154,8 @@ mtd_fixseama(const char *mtd, size_t offset) } data_offset = offset + sizeof(struct seama_entity_header) + ntohs(shdr->metasize); - data_size = mtdsize - data_offset; + if (!data_size) + data_size = mtdsize - data_offset; if (data_size > ntohl(shdr->size)) data_size = ntohl(shdr->size); if (seama_fix_md5(shdr, fd, data_offset, data_size)) diff --git a/package/utils/oseama/src/oseama.c b/package/utils/oseama/src/oseama.c index 37a2171574..4434b11162 100644 --- a/package/utils/oseama/src/oseama.c +++ b/package/utils/oseama/src/oseama.c @@ -57,6 +57,7 @@ struct seama_entity_header { char *seama_path; int entity_idx = -1; +char *out_path; static inline size_t oseama_min(size_t x, size_t y) { return x < y ? x : y; @@ -392,6 +393,132 @@ out: } /************************************************** + * Extract + **************************************************/ + +static void oseama_extract_parse_options(int argc, char **argv) { + int c; + + while ((c = getopt(argc, argv, "e:o:")) != -1) { + switch (c) { + case 'e': + entity_idx = atoi(optarg); + break; + case 'o': + out_path = optarg; + break; + } + } +} + +static int oseama_extract_entity(FILE *seama, FILE *out) { + struct seama_entity_header hdr; + size_t bytes, metasize, imagesize, length; + uint8_t buf[1024]; + int i = 0; + int err = 0; + + while ((bytes = fread(&hdr, 1, sizeof(hdr), seama)) == sizeof(hdr)) { + if (be32_to_cpu(hdr.magic) != SEAMA_MAGIC) { + fprintf(stderr, "Invalid Seama magic: 0x%08x\n", be32_to_cpu(hdr.magic)); + err = -EINVAL; + break; + } + metasize = be16_to_cpu(hdr.metasize); + imagesize = be32_to_cpu(hdr.imagesize); + + if (i != entity_idx) { + fseek(seama, metasize + imagesize, SEEK_CUR); + i++; + continue; + } + + fseek(seama, -sizeof(hdr), SEEK_CUR); + + length = sizeof(hdr) + metasize + imagesize; + while ((bytes = fread(buf, 1, oseama_min(sizeof(buf), length), seama)) > 0) { + if (fwrite(buf, 1, bytes, out) != bytes) { + fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, out_path); + err = -EIO; + break; + } + length -= bytes; + } + + if (length) { + fprintf(stderr, "Couldn't extract whole entity %d from %s (%zu B left)\n", entity_idx, seama_path, length); + err = -EIO; + break; + } + + break; + } + + return err; +} + +static int oseama_extract(int argc, char **argv) { + FILE *seama; + FILE *out; + struct seama_seal_header hdr; + size_t bytes; + uint16_t metasize; + int err = 0; + + if (argc < 3) { + fprintf(stderr, "No Seama file passed\n"); + err = -EINVAL; + goto out; + } + seama_path = argv[2]; + + optind = 3; + oseama_extract_parse_options(argc, argv); + if (entity_idx < 0) { + fprintf(stderr, "No entity specified\n"); + err = -EINVAL; + goto out; + } else if (!out_path) { + fprintf(stderr, "No output file specified\n"); + err = -EINVAL; + goto out; + } + + seama = fopen(seama_path, "r"); + if (!seama) { + fprintf(stderr, "Couldn't open %s\n", seama_path); + err = -EACCES; + goto out; + } + + out = fopen(out_path, "w"); + if (!out) { + fprintf(stderr, "Couldn't open %s\n", out_path); + err = -EACCES; + goto err_close_seama; + } + + bytes = fread(&hdr, 1, sizeof(hdr), seama); + if (bytes != sizeof(hdr)) { + fprintf(stderr, "Couldn't read %s header\n", seama_path); + err = -EIO; + goto err_close_out; + } + metasize = be16_to_cpu(hdr.metasize); + + fseek(seama, metasize, SEEK_CUR); + + oseama_extract_entity(seama, out); + +err_close_out: + fclose(out); +err_close_seama: + fclose(seama); +out: + return err; +} + +/************************************************** * Start **************************************************/ @@ -407,6 +534,11 @@ static void usage() { printf("\t-m meta\t\t\t\tmeta into to put in header\n"); printf("\t-f file\t\t\t\tappend content from file\n"); printf("\t-b offset\t\t\tappend zeros till reaching absolute offset\n"); + printf("\n"); + printf("Extract from Seama seal (container):\n"); + printf("\toseama extract <file> [options]\n"); + printf("\t-e\t\t\t\tindex of entity to extract\n"); + printf("\t-o file\t\t\t\toutput file\n"); } int main(int argc, char **argv) { @@ -415,6 +547,8 @@ int main(int argc, char **argv) { return oseama_info(argc, argv); else if (!strcmp(argv[1], "entity")) return oseama_entity(argc, argv); + else if (!strcmp(argv[1], "extract")) + return oseama_extract(argc, argv); } usage(); |