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; -}