From 45b200eb18910ceb3acd50c1bf4cbbae3766d3b9 Mon Sep 17 00:00:00 2001 From: Neale Pickett Date: Fri, 8 Aug 2014 13:57:50 -0600 Subject: [PATCH] Working Gapstr --- Makefile | 29 ++---- dumbdecode | 16 --- hd.c | 98 ------------------ p4split.c | 149 -------------------------- pcap.c | 101 ------------------ pcap.h | 76 -------------- pcat.c | 207 ------------------------------------- pmerge.c | 142 ------------------------- printfesc.c | 40 ------- puniq.c | 68 ------------ pyesc.c | 26 ----- src/fred/gaptest.go | 10 +- hd.go => src/hd/hd.go | 0 src/netarch/gapstr.go | 119 +++++++++++++++++++-- src/netarch/gapstr_test.go | 43 ++++++++ src/pcap/pcap.go | 3 - stream.c | 118 --------------------- stream.h | 30 ------ unhex.c | 50 --------- xor.c | 47 --------- 20 files changed, 169 insertions(+), 1203 deletions(-) delete mode 100755 dumbdecode delete mode 100644 hd.c delete mode 100644 p4split.c delete mode 100644 pcap.c delete mode 100644 pcap.h delete mode 100644 pcat.c delete mode 100644 pmerge.c delete mode 100644 printfesc.c delete mode 100644 puniq.c delete mode 100644 pyesc.c rename hd.go => src/hd/hd.go (100%) create mode 100644 src/netarch/gapstr_test.go delete mode 100644 stream.c delete mode 100644 stream.h delete mode 100644 unhex.c delete mode 100644 xor.c diff --git a/Makefile b/Makefile index e4e4162..e2549f8 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,13 @@ -CFLAGS = -Wall -Werror -TARGETS += puniq -TARGETS += hd +TARGETS += netarch GOPATH = $(CURDIR) export GOPATH -all: $(TARGETS) +all: + go build $(TARGETS) -%: src/%.go - go build $@ - -%: %.go - go build $< - -install: $(TARGETS) - install -d $(DESTDIR)$(PREFIX) - install $(TARGETS) $(DESTDIR)$(PREFIX)/bin - -pmerge: pmerge.o pcap.o - -puniq: puniq.o pcap.o - -p4split: p4split.o pcap.o - -pcat: pcat.o pcap.o stream.o -pcat.o: CFLAGS += -Wno-unused-variable +test: + go test $(TARGETS) clean: - rm -f $(TARGETS) *.o + go clean diff --git a/dumbdecode b/dumbdecode deleted file mode 100755 index a0559b4..0000000 --- a/dumbdecode +++ /dev/null @@ -1,16 +0,0 @@ -#! /bin/sh - -# Emulate dumbdecode.py from python netarch - -# The advantage here is, after the pcat step, you're dealing with text files. -# * cache the output of pcat to speed things up a little. -# * tail -n +5000 to ignore the first 5000 lines of your cache. -# * grep the cache, use sed, awk, whatever - -./pmerge "$@" | ./pcat | while read ts proto src dst payload; do - #when=$(TZ=Z date --rfc-3339=ns -d @$ts) - printf "Packet %s None: None\n" $proto - printf " %s -> %s (%s)\n" ${src%,*} ${dst%,*} "$ts" - echo $payload | ./unhex | ./hd - echo -done \ No newline at end of file diff --git a/hd.c b/hd.c deleted file mode 100644 index 9a9e37e..0000000 --- a/hd.c +++ /dev/null @@ -1,98 +0,0 @@ -#include -#include -#include - -const char *charset[] = { - "·", "☺", "☻", "♥", "♦", "♣", "♠", "•", "◘", "○", "◙", "♂", "♀", "♪", "♫", "☼", - "►", "◄", "↕", "‼", "¶", "§", "▬", "↨", "↑", "↓", "→", "←", "∟", "↔", "▲", "▼", - " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", - "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">", "?", - "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", - "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", - "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", - "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "⌂", - - "Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å", - "É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "€", "ƒ", - "á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "½", "⅓", "¼", "⅕", "⅙", "⅛", "«", "»", - "░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐", - "└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "╧", - "╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀", - "α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩", - "⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹", "ⁱ", "ⁿ", "⁽", "⁼", "⁾", "¤", -}; - -int -dump(FILE * f) -{ - uint64_t p = 0; - uint8_t buf[32]; - int offset = 0; - int skipping = 0; - - while (!feof(f)) { - uint8_t *bytes = buf + offset; - size_t len; - int i; - - offset = 16 - offset; - - len = fread(bytes, 1, 16, f); - if (0 == len) - break; - - if (p && (0 == memcmp(buf, buf + 16, 16))) { - if (!skipping) { - printf("*\n"); - skipping = 1; - } - p += 16; - continue; - } else { - skipping = 0; - } - - printf("%08lx ", (long unsigned int) p); - for (i = 0; i < 16; i += 1) { - if (i < len) { - printf("%02x ", bytes[i]); - } else { - printf(" "); - } - if (7 == i) { - printf(" "); - } - } - printf(" ┆"); - for (i = 0; i < len; i += 1) { - printf("%s", charset[bytes[i]]); - } - if (-1 == printf("┆\n")) { - perror("printf"); - return 1; - } - p += len; - } - printf("%08lx\n", (long unsigned int) p); - - return 0; -} - -int -main(int argc, char *argv[]) -{ - if (1 == argc) { - dump(stdin); - } else { - FILE *f = fopen(argv[1], "rb"); - - if (!f) { - perror("open"); - return 1; - } - - dump(f); - } - - return 0; -} diff --git a/p4split.c b/p4split.c deleted file mode 100644 index 35d0086..0000000 --- a/p4split.c +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include -#include -#include -#include -#include "pcap.h" - -/* - * Gaah so much crap - */ -#include -#include -#include -#include -#include - - -int -usage(int ret) -{ - fprintf(stderr, "Usage: p4split CIDR\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Splits pcap on stdin into up to 256 files, based on CIDR.\n"); - return ret; -} - - -int -parse_cidr(char *s, uint32_t * addr, uint8_t * bits) -{ - char *slash = index(s, '/'); - struct in_addr inp; - - if (slash) { - *slash = 0; - *bits = atoi(slash + 1); - } else { - *bits = 0; - } - - if (0 == inet_aton(s, &inp)) - return -1; - *addr = ntohl(inp.s_addr); - - return 0; -} - - -int -main(int argc, char *argv[]) -{ - struct pcap_file p; - struct pcap_file out[256]; - int ok = 0; - uint32_t addr; - uint32_t mask; - uint8_t bits; - uint8_t shr; - int i; - - if (argc != 2) - return usage(0); - if (-1 == parse_cidr(argv[1], &addr, &bits)) - return usage(0); - if (bits > 24) - return usage(0); - if (bits % 8) { - fprintf(stderr, "Warning: routing prefix is not a multiple of 8.\n"); - } - - mask = ~((1 << (32 - bits)) - 1); - addr &= mask; - shr = (32 - bits) - 8; - - for (i = 0; i < 256; i += 1) { - out[i].f = NULL; - } - - if (-1 == pcap_open_in(&p, stdin)) - return usage(0); - - while (1) { - struct pcap_pkthdr hdr; - uint8_t octet; - char frame[MAXFRAME]; - - ok = 1; - if (-1 == pcap_read_pkthdr(&p, &hdr)) - break; - if (1 != fread(frame, hdr.caplen, 1, p.f)) - break; - - - { - struct ether_header *eh = (struct ether_header *) frame; - struct iphdr *ih = (struct iphdr *) (frame + sizeof(struct ether_header)); - uint32_t a; - - /* - * VLAN tag - */ - if (ntohs(eh->ether_type) == 0x8100) { - ih = (struct iphdr *) ((char *) ih + 4); - } - - a = ntohl(ih->saddr); - if ((a & mask) != addr) { - a = ntohl(ih->daddr); - if ((a & mask) != addr) { - fprintf(stderr, "Warning: dropping unmatched packet %08x -> %08x\n", - ntohl(ih->saddr), ntohl(ih->daddr)); - continue; - } - } - octet = (a & ~mask) >> shr; - } - - ok = 0; - if (!out[octet].f) { - char fn[9]; - FILE *f; - - sprintf(fn, "%d.pcap", octet); - - if (NULL == (f = fopen(fn, "wb"))) - break; - if (-1 == pcap_open_out(&out[octet], f)) - break; - } - - if (-1 == pcap_write_pkthdr(&out[octet], &hdr)) - break; - if (1 != fwrite(frame, hdr.caplen, 1, out[octet].f)) - break; - } - - if (!ok) { - perror("Error"); - return 1; - } - - for (i = 0; i < 256; i += 1) { - if (out[i].f) { - pcap_close(&p); - } - } - - return 0; -} diff --git a/pcap.c b/pcap.c deleted file mode 100644 index 2c8d8b9..0000000 --- a/pcap.c +++ /dev/null @@ -1,101 +0,0 @@ -#include -#include -#include -#include "pcap.h" - -int -pcap_open_in(struct pcap_file *ctx, FILE * f) -{ - struct pcap_file_header h; - - if (1 != fread(&h, sizeof(h), 1, f)) { - h.magic = 0; - } - - if (MAGIC == h.magic) { - ctx->swap = 0; - } else if (bswap32(MAGIC) == h.magic) { - ctx->swap = 1; - } else { - return -1; - } - if ((h.version_major != 2) || (h.version_minor != 4)) { - return -1; - } - - if (ctx->swap) { - h.snaplen = bswap32(h.snaplen); - } - if (h.snaplen > MAXFRAME) { - return -1; - } - ctx->linktype = h.linktype; - - ctx->f = f; - return 0; -} - -int -pcap_open_out(struct pcap_file *ctx, FILE * f) -{ - struct pcap_file_header h = { MAGIC, 2, 4, 0, 0, MAXFRAME, 1 }; - - if (1 != fwrite(&h, sizeof(h), 1, f)) { - return -1; - } - ctx->f = f; - ctx->swap = 0; - - return 0; -} - -int -pcap_read_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr) -{ - if (1 != fread(hdr, sizeof(*hdr), 1, ctx->f)) { - return -1; - } - - if (ctx->swap) { - hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec); - hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec); - hdr->caplen = bswap32(hdr->caplen); - hdr->len = bswap32(hdr->len); - } - - if (hdr->caplen > MAXFRAME) { - return -1; - } - - return 0; -} - -int -pcap_write_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr) -{ - if (ctx->swap) { - struct pcap_pkthdr ohdr; - - memcpy(&ohdr, hdr, sizeof(ohdr)); - hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec); - hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec); - hdr->caplen = bswap32(hdr->caplen); - hdr->len = bswap32(hdr->len); - - if (1 != fwrite(&ohdr, sizeof(ohdr), 1, ctx->f)) { - return -1; - } - } else { - if (1 != fwrite(hdr, sizeof(*hdr), 1, ctx->f)) { - return -1; - } - } - - return 0; -} - -void -pcap_close(struct pcap_file *ctx) -{ - fclose(ctx->f); -} diff --git a/pcap.h b/pcap.h deleted file mode 100644 index 27b01ee..0000000 --- a/pcap.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef __PCAP_H__ -#define __PCAP_H__ - -#include -#include -#include - -#define MAGIC 0xa1b2c3d4 -#define MAXFRAME 9000 - -/* - * Described at http://www.tcpdump.org/linktypes.html - */ -#define LINKTYPE_ETHERNET 1 -#define LINKTYPE_RAW 101 - -struct pcap_file { - FILE *f; - uint32_t linktype; - bool swap; -}; - -struct pcap_file_header { - uint32_t magic; - uint16_t version_major; - uint16_t version_minor; - int32_t thiszone; /* gmt to local correction */ - uint32_t sigfigs; /* accuracy of timestamps */ - int32_t snaplen; /* max length saved portion of each pkt */ - int32_t linktype; /* data link type (LINKTYPE_*) */ -}; - -struct pcap_pkthdr { - struct pcap_timeval { - uint32_t tv_sec; - uint32_t tv_usec; - } ts; /* time stamp */ - uint32_t caplen; /* length of portion present */ - uint32_t len; /* length this packet (off wire) */ -}; - -#ifndef max -#define max(a, b) ((a)>(b)?(a):(b)) -#endif - -#ifndef min -#define min(a, b) ((a)<(b)?(a):(b)) -#endif - -#define bswap32(i) (((i & 0xff000000) >> 030) | \ - ((i & 0x00ff0000) >> 010) | \ - ((i & 0x0000ff00) << 010) | \ - ((i & 0x000000ff) << 030)) -#define bswap16(i) (((i & 0xff00) >> 010) | \ - ((i & 0x00ff) << 010)) - - -/* - * Debugging help - */ -#define DUMPf(fmt, args...) fprintf(stderr, "%s:%s:%d " fmt "\n", __FILE__, __FUNCTION__, __LINE__, ##args) -#define DUMP() DUMPf("") -#define DUMP_d(v) DUMPf("%s = %d", #v, v) -#define DUMP_u(v) DUMPf("%s = %u", #v, v) -#define DUMP_x(v) DUMPf("%s = 0x%x", #v, v) -#define DUMP_s(v) DUMPf("%s = %s", #v, v) -#define DUMP_c(v) DUMPf("%s = %c", #v, v) -#define DUMP_p(v) DUMPf("%s = %p", #v, v) - -int pcap_open_in(struct pcap_file *ctx, FILE * f); -int pcap_open_out(struct pcap_file *ctx, FILE * f); -int pcap_read_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr); -int pcap_write_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr); -void pcap_close(struct pcap_file *ctx); - -#endif /* __PCAP_H__ */ diff --git a/pcat.c b/pcat.c deleted file mode 100644 index aa3c9f5..0000000 --- a/pcat.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * pcat.c -- pcap to text - * - * Reads pcap on stdin, dumps text representation to stdout. - * This discards or ignores some parts of packets. If fidelity is a concern, - * deal directly with the original pcap. - * - * Output lines are of the form: - * - * PROTO SRC DST OPTS PAYLOAD - * - - */ - -#include -#include -#include "pcap.h" -#include "stream.h" - -#define IPPROTO_TCP 6 -#define IPPROTO_UDP 17 -#define IPPROTO_ICMP 1 - -#define TH_FIN 0x01 -#define TH_SYN 0x02 -#define TH_RST 0x04 -#define TH_PSH 0x08 -#define TH_ACK 0x10 -#define TH_URG 0x20 - -void -ip4_addr(char *addr_s, uint32_t addr) -{ - snprintf(addr_s, 16, "%u.%u.%u.%u", (addr >> 24) & 0xff, (addr >> 16) & 0xff, (addr >> 8) & 0xff, (addr >> 0) & 0xff); -} - -void -print_payload(struct stream *s) -{ - while (s->len) { - printf("%02x", read_uint8(s)); - } -} - -void -process_tcp(struct stream *s, char *saddr_s, char *daddr_s) -{ - uint16_t sport = read_uint16(s); - uint16_t dport = read_uint16(s); - uint32_t seq = read_uint32(s); - uint32_t ack = read_uint32(s); - uint8_t off = read_uint8(s); - uint8_t hlen = (off >> 4) * 4; - uint8_t flags = read_uint8(s); - uint16_t window = read_uint16(s); - uint16_t chksum = read_uint16(s); - uint16_t urgent = read_uint16(s); - - if (hlen < 20) { - printf("!"); - } - - printf("TCP %s,%u %s,%u %u,%u,%d ", saddr_s, sport, daddr_s, dport, seq, ack, flags); -} - -void -process_udp(struct stream *s, char *saddr_s, char *daddr_s) -{ - uint16_t sport = read_uint16(s); - uint16_t dport = read_uint16(s); - uint16_t len = read_uint16(s); - uint16_t chksum = read_uint16(s); - - printf("UDP %s,%u %s,%u 0 ", saddr_s, sport, daddr_s, dport); -} - -void -process_icmp(struct stream *s, char *saddr_s, char *daddr_s) -{ - uint8_t type = read_uint8(s); - uint8_t code = read_uint8(s); - uint16_t checksum = read_uint16(s); - - printf("ICMP %d,%d %s %s ", type, code, saddr_s, daddr_s); -} - -void -process_ip4(struct stream *s) -{ - uint8_t vhl = read_uint8(s); - uint8_t ihl = (vhl & 0x0f) * 4; - uint8_t tos = read_uint8(s); - uint16_t length = read_uint16(s); - uint16_t id = read_uint16(s); - uint16_t off = read_uint16(s); - uint8_t ttl = read_uint8(s); - uint8_t proto = read_uint8(s); - uint16_t chksum = read_uint16(s); - uint32_t saddr = read_uint32(s); - uint32_t daddr = read_uint32(s); - - char saddr_s[20]; - char daddr_s[20]; - - ip4_addr(saddr_s, saddr); - ip4_addr(daddr_s, daddr); - - // Ignore options - sskip(s, 20 - ihl); - - // Force stream length to IP payload length - s->len = length - ihl; - - switch (proto) { - case IPPROTO_TCP: - process_tcp(s, saddr_s, daddr_s); - break; - case IPPROTO_UDP: - process_udp(s, saddr_s, daddr_s); - break; - case IPPROTO_ICMP: - process_icmp(s, saddr_s, daddr_s); - break; - default: - printf("P%d %s %s ", proto, saddr_s, daddr_s); - break; - } - - print_payload(s); -} - - -void -print_ethernet(struct stream *s) -{ - uint8_t saddr[6]; - uint8_t daddr[6]; - uint16_t ethertype; - - sread(s, &saddr, sizeof(saddr)); - sread(s, &daddr, sizeof(daddr)); - ethertype = read_uint16(s); - - if (ethertype == 0x8100) { - // VLAN - read_uint16(s); - ethertype = read_uint16(s); - } - - switch (ethertype) { - case 0x0800: // IPv4 - process_ip4(s); - break; - } -} - -void -print_frame(struct pcap_file *p, struct pcap_pkthdr *hdr, char const *frame) -{ - struct stream streambuf; - struct stream *s = &streambuf; - - sinit(s, frame, hdr->caplen); - printf("%u.%u ", hdr->ts.tv_sec, hdr->ts.tv_usec); - switch (p->linktype) { - case LINKTYPE_ETHERNET: - print_ethernet(s); - break; - case LINKTYPE_RAW: - process_ip4(s); - break; - } - printf("\n"); -} - -void -pcat(FILE * f) -{ - struct pcap_file p; - - if (-1 == pcap_open_in(&p, f)) - return; - - for (;;) { - struct pcap_pkthdr hdr; - char frame[MAXFRAME]; - - if (-1 == pcap_read_pkthdr(&p, &hdr)) { - break; - } - - if (1 != fread(frame, hdr.caplen, 1, f)) { - break; - } - - print_frame(&p, &hdr, frame); - } -} - - -int -main(int argc, char *argv[]) -{ - pcat(stdin); - - return 0; -} diff --git a/pmerge.c b/pmerge.c deleted file mode 100644 index d991774..0000000 --- a/pmerge.c +++ /dev/null @@ -1,142 +0,0 @@ -#include -#include -#include -#include "pcap.h" - -struct input_file { - int active; - struct pcap_file p; - struct pcap_pkthdr next; -}; - -int -usage(int ret) -{ - fprintf(stderr, "Usage: pmerge FILE ...\n"); - fprintf(stderr, "\n"); - fprintf(stderr, "Merges pcap files, outputting time-ordered pcap stream\n"); - return ret; -} - -int -read_next(struct input_file *file) -{ - if (!file->active) - return -1; - - if (-1 == pcap_read_pkthdr(&file->p, &file->next)) { - pcap_close(&file->p); - file->active = 0; - file->next.ts.tv_sec = 0xffffffff; - file->next.ts.tv_usec = 0xffffffff; - return -1; - } - - return 0; -} - -int -main(int argc, char *argv[]) -{ - struct input_file files[argc - 1]; - int nfiles = 0; - int nopen; - int i; - struct pcap_file out; - - if (1 == argc) - return usage(0); - - /* - * Open input files - */ - for (i = 0; i < argc - 1; i += 1) { - char *fn = argv[i + 1]; - struct input_file *cur = &files[nfiles]; - FILE *f; - - if ('-' == fn[0]) - return usage(0); - - f = fopen(fn, "rb"); - if (NULL == f) { - perror(fn); - return EX_NOINPUT; - } - - if (-1 == pcap_open_in(&cur->p, f)) { - fprintf(stderr, "%s: unable to process\n", fn); - return EX_IOERR; - } - cur->active = 1; - - if (0 == read_next(cur)) { - nfiles += 1; - } - } - - if (-1 == pcap_open_out(&out, stdout)) { - perror("writing header"); - return EX_IOERR; - } - - nopen = nfiles; - while (nopen) { - struct input_file *cur = &files[0]; - char frame[MAXFRAME]; - size_t len; - - /* - * Find next oldest frame - */ - for (i = 0; i < nfiles; i += 1) { - if (files[i].active && - ((files[i].next.ts.tv_sec < cur->next.ts.tv_sec) || - ((files[i].next.ts.tv_sec == cur->next.ts.tv_sec) && - (files[i].next.ts.tv_usec < cur->next.ts.tv_usec)))) { - cur = &files[i]; - } - } - - /* - * Make sure it'll fit - */ - if (cur->next.caplen > sizeof(frame)) { - fprintf(stderr, "error: huge frame (size %u)\n", (unsigned int) len); - return EX_SOFTWARE; - } - - /* - * Read it - */ - len = fread(frame, 1, cur->next.caplen, cur->p.f); - if (len < cur->next.caplen) { - /* - * Short read - */ - cur->next.caplen = len; - pcap_close(&cur->p); - cur->active = 0; - } - - /* - * Write header + frame - */ - if (len) { - if (1 != fwrite(&cur->next, sizeof(cur->next), 1, stdout)) { - perror("error"); - return EX_IOERR; - } - if (len != fwrite(frame, 1, len, stdout)) { - perror("error"); - return EX_IOERR; - } - } - - if (-1 == read_next(cur)) { - nopen -= 1; - } - } - - return 0; -} diff --git a/printfesc.c b/printfesc.c deleted file mode 100644 index aae7904..0000000 --- a/printfesc.c +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include - -int -main(int argc, char *argv[]) -{ - printf("printf "); - - while (!feof(stdin)) { - int c = getchar(); - - switch (c) { - case EOF: - break; - case '\n': - printf("\\n"); - break; - case '\r': - printf("\\r"); - break; - case '\t': - printf("\\t"); - break; - case '"': - printf("\\\""); - break; - default: - if (isprint(c)) { - putchar(c); - } else { - printf("\\%03o", c); - } - break; - } - } - - putchar('\n'); - - return 0; -} diff --git a/puniq.c b/puniq.c deleted file mode 100644 index b5ac07a..0000000 --- a/puniq.c +++ /dev/null @@ -1,68 +0,0 @@ -#include -#include -#include -#include "pcap.h" - -int -main(int argc, char *argv[]) -{ - int i; - struct pcap_pkthdr hdr[2]; - char frame[2][MAXFRAME]; - int cur = 0; - struct pcap_file out; - - memset(&hdr, 0, sizeof(hdr)); - memset(frame, 0, 2 * MAXFRAME); - - if (-1 == pcap_open_out(&out, stdout)) { - perror("writing header"); - return EX_IOERR; - } - - i = 1; - do { - char *fn = argv[i]; - FILE *f; - struct pcap_file p; - - if ((!fn) || (0 == strcmp("-", fn))) { - f = stdin; - } else { - f = fopen(fn, "rb"); - if (NULL == f) { - perror(fn); - return EX_IOERR; - } - } - - if (-1 == pcap_open_in(&p, f)) { - fprintf(stderr, "%s: unable to process\n", fn); - return EX_IOERR; - } - - while (1) { - if (-1 == pcap_read_pkthdr(&p, &hdr[cur])) - break; - if (1 != fread(frame[cur], hdr[cur].caplen, 1, p.f)) - break; - - if ((0 == memcmp(&hdr[0], &hdr[1], sizeof(hdr[0]))) && (0 == memcmp(frame[0], frame[1], hdr[cur].caplen))) { - /* - * Skip this duplicate - */ - } else { - if (-1 == pcap_write_pkthdr(&out, &hdr[cur])) - break; - if (1 != fwrite(frame[cur], hdr[cur].caplen, 1, out.f)) - break; - } - cur = (1 - cur); - } - pcap_close(&p); - - i += 1; - } while (i < argc); - - return 0; -} diff --git a/pyesc.c b/pyesc.c deleted file mode 100644 index a67e709..0000000 --- a/pyesc.c +++ /dev/null @@ -1,26 +0,0 @@ -#include - -int -main(int argc, char *argv[]) -{ - while (1) { - int c = getchar(); - - switch (c) { - case EOF: - return 0; - case 134: - printf("\\\\"); - break; - case 32 ... 91: - case 93 ... 126: - putchar(c); - break; - default: - printf("\\x%02x", c); - break; - } - } - - return 0; -} diff --git a/src/fred/gaptest.go b/src/fred/gaptest.go index 7797da6..b76e8ae 100644 --- a/src/fred/gaptest.go +++ b/src/fred/gaptest.go @@ -8,7 +8,13 @@ import ( func main() { g := new(netarch.Gapstr) g = g.AppendString("hello") - g = g.AppendGap(12) - g = g.AppendString("world") + g = g.AppendGap(10) + g = g.AppendString(" world") + fmt.Println("hi", g.String()) + fmt.Printf("%v\n", g) + fmt.Printf("%#v\n", g.Slice(0, 4)) + fmt.Printf("%#v\n", g.Slice(4, 8)) + fmt.Printf("%#v\n", g.Slice(8, 12)) + fmt.Printf("%#v\n", g.Slice(12, 16)) } diff --git a/hd.go b/src/hd/hd.go similarity index 100% rename from hd.go rename to src/hd/hd.go diff --git a/src/netarch/gapstr.go b/src/netarch/gapstr.go index 9ecc54e..f2f1d17 100644 --- a/src/netarch/gapstr.go +++ b/src/netarch/gapstr.go @@ -4,26 +4,80 @@ import ( "bytes" ) +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + type chunk interface{} +func chunkLen(c chunk) int { + switch c.(type) { + case int: + return c.(int) + case string: + return len(c.(string)) + } + return 0 +} + +func chunkSlice(c chunk, beg, end int) chunk { + switch c.(type) { + case int: + return end - beg + case string: + return c.(string)[beg:end] + } + return 0 +} + +// The type of a function to be passed to Map +type Processor func(int, string) string + type Gapstr struct { chunks []chunk } -func GapstrOfString(s string) *Gapstr { - return &Gapstr{[]chunk{s}} +func (g *Gapstr) Length() int { + ret := 0 + + for _, c := range g.chunks { + ret += chunkLen(c) + } + return ret } -func (g *Gapstr) appendChunk(c chunk) *Gapstr { - return &Gapstr{append(g.chunks, c)} +func (g *Gapstr) HasGaps() bool { + for _, c := range g.chunks { + switch c.(type) { + case int: + return true + } + } + return false +} + +func (g *Gapstr) Copy() *Gapstr { + chunks := make([]chunk, len(g.chunks)) + copy(chunks, g.chunks) + return &Gapstr{chunks} } func (g *Gapstr) AppendString(s string) *Gapstr { - return g.appendChunk(s) + return &Gapstr{append(g.chunks, s)} } func (g *Gapstr) AppendGap(len int) *Gapstr { - return g.appendChunk(len) + return &Gapstr{append(g.chunks, len)} } func (g *Gapstr) String() string { @@ -37,4 +91,55 @@ func (g *Gapstr) String() string { } } return b.String() -} \ No newline at end of file +} + +// Apply proc to everything in g +func (g *Gapstr) Map(proc Processor) *Gapstr { + chunks := make([]chunk, 0, len(g.chunks)) + pos := 0 + + for _, c := range g.chunks { + switch c.(type) { + case int: + chunks = append(chunks, c) + case string: + chunks = append(chunks, proc(pos, c.(string))) + } + pos += chunkLen(c) + } + + return &Gapstr{chunks} +} + +func (g *Gapstr) Xor(mask []byte) *Gapstr { + xorproc := func(pos int, s string) string { + var b bytes.Buffer + + for i := 0; i < len(s); i += 1 { + p := (pos + i) % len(mask) + b.WriteByte(s[i] ^ mask[p]) + } + return b.String() + } + return g.Map(xorproc) +} + +func (g *Gapstr) Slice(beg, end int) *Gapstr { + pos := 0 + chunks := make([]chunk, 0) + + for _, c := range g.chunks { + cl := chunkLen(c) + + if (pos + cl > beg) && (pos <= end) { + cb := max(beg - pos, 0) + ce := min(end - pos, cl) + + chunks = append(chunks, chunkSlice(c, cb, ce)) + } + + pos += cl + } + + return &Gapstr{chunks} +} diff --git a/src/netarch/gapstr_test.go b/src/netarch/gapstr_test.go new file mode 100644 index 0000000..feb422f --- /dev/null +++ b/src/netarch/gapstr_test.go @@ -0,0 +1,43 @@ +package netarch + +import ( + "testing" +) + +func AssertEqual(t *testing.T, a, b interface{}) { + if a != b { + t.Errorf("Not equal: %#v, %#v", a, b) + } +} + +func TestChunk(t *testing.T) { + c := chunk("hello") + AssertEqual(t, chunkLen(c), 5) + AssertEqual(t, chunkSlice(c, 0, 3), "hel") + AssertEqual(t, chunkSlice(c, 3, 5), "lo") + + c = chunk(5) + AssertEqual(t, chunkLen(c), 5) + AssertEqual(t, chunkSlice(c, 0, 3), 3) + AssertEqual(t, chunkSlice(c, 3, 5), 2) +} + +func TestGapstr(t *testing.T) { + g := new(Gapstr) + g = g.AppendString("hello") + g = g.AppendGap(10) + g = g.AppendString(" world") + + gs := g.String() + AssertEqual(t, gs, "hello\000\000\000\000\000\000\000\000\000\000 world") + + for i := 0; i <= 20; i += 4 { + j := i+4 + if j > len(gs) { + j = len(gs) + } + AssertEqual(t, g.Slice(i, i+4).String(), gs[i:j]) + } + + AssertEqual(t, g.Slice(0, 12).String(), gs[0:12]) +} diff --git a/src/pcap/pcap.go b/src/pcap/pcap.go index 823bf1c..6078039 100644 --- a/src/pcap/pcap.go +++ b/src/pcap/pcap.go @@ -99,9 +99,6 @@ func (r *Reader) Read() (*Frame, error) { var h FrameHeader err := binary.Read(r.r, r.order, &h) - if err == EOF { - return nil, nil - } if err != nil { return nil, err } diff --git a/stream.c b/stream.c deleted file mode 100644 index 48b83ef..0000000 --- a/stream.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include -#include -#include -#include "stream.h" - -void -sinit(struct stream *s, char const *buf, size_t buflen, enum endianness endian) -{ - s->buf = buf; - s->len = buflen; - s->endian = endian; -} - -bool -sskip(struct stream *s, size_t count) -{ - if (count > s->len) { - s->len = 0; - return false; - } - - s->buf += count; - s->len -= count; - return true; -} - -bool -sread(struct stream *s, void *buf, size_t count) -{ - void const *d = s->buf; - - if (!sskip(s, count)) { - return false; - } - memcpy(buf, d, count); - - return true; -} - - - -uint8_t -read_uint8(struct stream *s) -{ - uint8_t *d = (uint8_t *) s->buf; - - if (!sskip(s, 1)) { - return 0; - } - return d[0]; -} - - - -uint16_t -read_uint16be(struct stream *s) -{ - uint8_t *d = (uint8_t *) s->buf; - - if (!sskip(s, 2)) { - return 0; - } - return ((d[0] << 8) | (d[1] << 0)); -} - - -uint16_t -read_uint16le(struct stream *s) -{ - uint8_t *d = (uint8_t *) s->buf; - - if (!sskip(s, 2)) { - return 0; - } - return ((d[0] << 0) | (d[1] << 8)); -} - -uint16_t -read_uint16(struct stream *s) -{ - if (s->endian == ENDIAN_BIG) { - return read_uint16be(s); - } else { - return read_uint16le(s); - } -} - - -uint32_t -read_uint32be(struct stream *s) -{ - uint8_t *d = (uint8_t *) s->buf; - if (!sskip(s, 4)) { - return 0; - } - return ((d[0] << 24) | (d[1] << 16) | (d[2] << 8) | (d[3] << 0)); -} - -uint32_t -read_uint32le(struct stream *s) -{ - uint8_t *d = (uint8_t *) s->buf; - if (!sskip(s, 4)) { - return 0; - } - return ((d[0] << 0) | (d[1] << 8) | (d[2] << 16) | (d[3] << 24)); -} - -uint32_t -read_uint32(struct stream *s) -{ - if (s->endian == ENDIAN_BIG) { - return read_uint32be(s); - } else { - return read_uint32le(s); - } -} diff --git a/stream.h b/stream.h deleted file mode 100644 index 03de2a5..0000000 --- a/stream.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _STREAM_H -#define _STREAM_H - -#include -#include -#include - -enum endianness { - ENDIAN_BIG, - ENDIAN_LITTLE -}; - -struct stream { - char const *buf; - size_t len; - enum endianness endian; -}; - -void sinit(struct stream *s, char const *buf, size_t len, enum endianness endian); -bool sskip(struct stream *s, size_t count); -bool sread(struct stream *s, void *buf, size_t count); -uint8_t read_uint8(struct stream *s); -uint16_t read_uint16be(struct stream *s); -uint16_t read_uint16le(struct stream *s); -uint16_t read_uint16(struct stream *s); -uint32_t read_uint32be(struct stream *s); -uint32_t read_uint32le(struct stream *s); -uint32_t read_uint32(struct stream *s); - -#endif diff --git a/unhex.c b/unhex.c deleted file mode 100644 index 72e4a44..0000000 --- a/unhex.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Hex Decoder -- 2012 Zephyr This file is in the public domain. I make no promises about the functionality - * of this program. - */ - -#include - -int -main(int argc, char *argv[]) -{ - unsigned char acc = 0; - unsigned char nybble = 0; - unsigned long int count = 0; - - while (1) { - int c = getchar(); - - count += 1; - - switch (c) { - case EOF: - return 0; - case '0' ... '9': - acc = (acc << 4) + c - '0'; - nybble += 1; - break; - case 'a' ... 'f': - acc = (acc << 4) + c - 'a' + 10; - nybble += 1; - break; - case 'A' ... 'F': - acc = (acc << 4) + c - 'A' + 10; - nybble += 1; - break; - default: - if (nybble != 0) { - fprintf(stderr, "Warning: non-hex character mid-octet at offset %lu\n", count); - } - break; - } - - if (nybble == 2) { - putchar(acc); - acc = 0; - nybble = 0; - } - } - - return 0; -} diff --git a/xor.c b/xor.c deleted file mode 100644 index 9ac7fd3..0000000 --- a/xor.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * xor filter -- 2012 Zephyr This file is in the public domain. I make no promises about the functionality - * of this program. - */ - -#include -#include -#include - -int -main(int argc, char *argv[]) -{ - int start = 1; - int base = 0; - int arg; - - if (argc < 2) { - fprintf(stderr, "Usage: %s [-x] m1 [m2 ...]\n", argv[0]); - return 1; - } - - if (0 == strcmp(argv[1], "-x")) { - base = 16; - start += 1; - } - - arg = start; - - while (1) { - int c = getchar(); - unsigned char mask; - - if (!argv[arg]) { - arg = start; - } - mask = strtol(argv[arg++], NULL, base); - - if (EOF == c) { - break; - } - - c ^= mask; - putchar(c); - } - - return 0; -}