aboutsummaryrefslogtreecommitdiffstats
path: root/package
diff options
context:
space:
mode:
Diffstat (limited to 'package')
-rw-r--r--package/libs/libnetfilter-queue/patches/100-checksum_computation.patch113
-rw-r--r--package/system/mtd/src/mtd.c8
-rw-r--r--package/system/mtd/src/mtd.h2
-rw-r--r--package/system/mtd/src/seama.c6
-rw-r--r--package/utils/oseama/src/oseama.c134
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();