mirror of https://github.com/dirtbags/fluffy.git
Merge remote-tracking branch 'origin/master'
Conflicts: pcat.c
This commit is contained in:
commit
17d9297388
13
Makefile
13
Makefile
|
@ -1,13 +1,20 @@
|
|||
CFLAGS = -Wall -Werror -Wno-unused-variable
|
||||
CFLAGS = -Wall -Werror
|
||||
TARGETS = pmerge puniq p4split pcat
|
||||
TARGETS += hd pyesc printfesc xor unhex
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
%: %.go
|
||||
go build $<
|
||||
|
||||
pmerge: pmerge.o pcap.o
|
||||
|
||||
puniq: puniq.o pcap.o
|
||||
p4split: p4split.c pcap.o
|
||||
pcat: pcat.c pcap.o stream.o
|
||||
|
||||
p4split: p4split.o pcap.o
|
||||
|
||||
pcat: pcat.o pcap.o stream.o
|
||||
pcat.o: CFLAGS += -Wno-unused-variable
|
||||
|
||||
clean:
|
||||
rm -f $(TARGETS) *.o
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
The Fluffy Suite
|
||||
============
|
||||
|
||||
Fluffy was begun in April 2011 in Tennessee,
|
||||
as a replacement for the aging "dirtbags.ip" codebase.
|
||||
It is comprised of multiple small standalone binaries,
|
||||
which are meant to be chained together,
|
||||
either on the command-line or from a shell script,
|
||||
to create a more powerful (and specific) piece of software.
|
||||
|
||||
Usually, a program expects input on stdin,
|
||||
and produces output on stdout.
|
||||
Flags are sparse by design.
|
||||
|
||||
|
||||
hd -- Hex Dump
|
||||
--------------
|
||||
|
||||
Like the normal hd,
|
||||
but with unicode characters to represent all 256 octets,
|
||||
instead of using "." for unprintable characters.
|
||||
|
||||
|
||||
p4split -- split a pcap file by IPv4 address CIDR
|
||||
---------------------------
|
||||
|
||||
Splits a pcap file up ito 256 files, based on a CIDR. For example:
|
||||
|
||||
p4split 32 < foo.pcap
|
||||
|
||||
Will create [0-255].pcap
|
||||
|
||||
|
||||
pcat -- print text representation of pcap file
|
||||
------------------------------
|
||||
|
||||
Prints a (lossy) text representation of a pcap file to stdout.
|
||||
This program is the keystone of the Fluffy Suite.
|
||||
By representing everything as text,
|
||||
programmers can use any number of standard Unix text processing tools,
|
||||
such as sed, awk, cut, grep, or head.
|
||||
|
||||
|
||||
pmerge -- merge pcap files
|
||||
-------------------------------------------
|
||||
|
||||
Takes a list of pcap files, assuming they are sorted by time
|
||||
(you would have to work hard to create any other kind),
|
||||
and merges them into a single sorted output.
|
||||
|
||||
|
||||
printfesc -- printf escape input
|
||||
--------------------------------
|
||||
|
||||
Reads octets,
|
||||
writes a string suitable for copy-paste into printf.
|
||||
|
||||
|
||||
puniq -- omit repeated frames
|
||||
--------------------------------
|
||||
|
||||
Removes duplicate frames from input,
|
||||
writing to output.
|
||||
|
||||
|
||||
pyesc -- python escape input
|
||||
---------------------------------
|
||||
|
||||
Escapes input octets for pasting into a python "print" statement.
|
||||
|
||||
|
||||
|
||||
unhex -- unescape hex
|
||||
---------------------------------
|
||||
|
||||
Reads ASCII hex codes on stdin,
|
||||
writes those octets to stdout.
|
||||
|
||||
The following pipe is equivalent to "cat":
|
||||
|
||||
./hd | cut -b 11-58 | ./unhex
|
||||
|
||||
|
||||
xor -- xor mask octets
|
||||
--------------------------------
|
||||
|
||||
Applies the given mask as an xor to input.
|
||||
The mask will be repeated,
|
||||
so for a 1-value mask, every octet is xored against that value.
|
||||
For a 16-value mask, the mask is applied to 16-octet chunks at a time.
|
||||
|
||||
The "-x" option treats values as hex.
|
||||
|
||||
The following pipe is equivalent to "cat":
|
||||
|
||||
./xor 42 | ./xor -x 2A
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"io"
|
||||
)
|
||||
|
||||
const charset = "" +
|
||||
"·☺☻♥♦♣♠•◘○◙♂♀♪♫☼" +
|
||||
"►◄↕‼¶§▬↨↑↓→←∟↔▲▼" +
|
||||
" !\"#$%&'()*+,-./" +
|
||||
"0123456789:;<=>?" +
|
||||
"@ABCDEFGHIJKLMNO" +
|
||||
"PQRSTUVWXYZ[\\]^_" +
|
||||
"`abcdefghijklmno" +
|
||||
"pqrstuvwxyz{|}~⌂" +
|
||||
|
||||
"ÇüéâäàåçêëèïîìÄÅ" +
|
||||
"ÉæÆôöòûùÿÖÜ¢£¥€ƒ" +
|
||||
"áíóúñѪº½⅓¼⅕⅙⅛«»" +
|
||||
"░▒▓│┤╡╢╖╕╣║╗╝╜╛┐" +
|
||||
"└┴┬├─┼╞╟╚╔╩╦╠═╬╧" +
|
||||
"╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀" +
|
||||
"αßΓπΣσµτΦΘΩδ∞φε∩" +
|
||||
"⁰¹²³⁴⁵⁶⁷⁸⁹ⁱⁿ⁽⁼⁾¤"
|
||||
|
||||
func main() {
|
||||
offset := 0
|
||||
b := make([]byte, 16)
|
||||
lb := make([]byte, 16)
|
||||
chars := []rune(charset)
|
||||
skipping := false
|
||||
|
||||
for ;; {
|
||||
n, err := os.Stdin.Read(b)
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
fmt.Println("read failed:", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if (offset > 0) && (bytes.Equal(lb, b)) {
|
||||
if ! skipping {
|
||||
fmt.Println("*")
|
||||
}
|
||||
offset += n
|
||||
skipping = true
|
||||
continue
|
||||
}
|
||||
copy(lb, b)
|
||||
skipping = false
|
||||
|
||||
fmt.Printf("%08x ", offset)
|
||||
offset += n
|
||||
|
||||
for i := 0; i < 16; i += 1 {
|
||||
if i % 8 == 0 {
|
||||
fmt.Printf(" ")
|
||||
}
|
||||
if i < n {
|
||||
fmt.Printf("%02x ", b[i])
|
||||
} else {
|
||||
fmt.Printf(" ")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("ǀ")
|
||||
for i := 0; i < n; i += 1 {
|
||||
fmt.Printf("%c", chars[b[i]])
|
||||
}
|
||||
fmt.Printf("ǀ\n")
|
||||
}
|
||||
|
||||
fmt.Printf("%08x\n", offset)
|
||||
}
|
62
pcat.c
62
pcat.c
|
@ -1,3 +1,17 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include "pcap.h"
|
||||
|
@ -31,33 +45,33 @@ print_payload(struct stream *s)
|
|||
void
|
||||
process_tcp(struct stream *s, char *saddr_s, char *daddr_s)
|
||||
{
|
||||
uint16_t sport = read_uint16be(s);
|
||||
uint16_t dport = read_uint16be(s);
|
||||
uint32_t seq = read_uint32be(s);
|
||||
uint32_t ack = read_uint32be(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_uint16be(s);
|
||||
uint16_t chksum = read_uint16be(s);
|
||||
uint16_t urgent = read_uint16be(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,%u %s,%u,%u ", saddr_s, sport, seq, daddr_s, dport, ack);
|
||||
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_uint16be(s);
|
||||
uint16_t dport = read_uint16be(s);
|
||||
uint16_t len = read_uint16be(s);
|
||||
uint16_t chksum = read_uint16be(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 ", saddr_s, sport, daddr_s, dport);
|
||||
printf("UDP %s,%u %s,%u 0 ", saddr_s, sport, daddr_s, dport);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -65,7 +79,7 @@ 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_uint16be(s);
|
||||
uint16_t checksum = read_uint16(s);
|
||||
|
||||
printf("ICMP %d,%d %s %s ", type, code, saddr_s, daddr_s);
|
||||
}
|
||||
|
@ -76,14 +90,14 @@ 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_uint16be(s);
|
||||
uint16_t id = read_uint16be(s);
|
||||
uint16_t off = read_uint16be(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_uint16be(s);
|
||||
uint32_t saddr = read_uint32be(s);
|
||||
uint32_t daddr = read_uint32be(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];
|
||||
|
@ -125,12 +139,12 @@ print_ethernet(struct stream *s)
|
|||
|
||||
sread(s, &saddr, sizeof(saddr));
|
||||
sread(s, &daddr, sizeof(daddr));
|
||||
ethertype = read_uint16be(s);
|
||||
ethertype = read_uint16(s);
|
||||
|
||||
if (ethertype == 0x8100) {
|
||||
// VLAN
|
||||
read_uint16be(s);
|
||||
ethertype = read_uint16be(s);
|
||||
read_uint16(s);
|
||||
ethertype = read_uint16(s);
|
||||
}
|
||||
|
||||
switch (ethertype) {
|
||||
|
@ -147,7 +161,7 @@ print_frame(struct pcap_file *p, struct pcap_pkthdr *hdr, char const *frame)
|
|||
struct stream *s = &streambuf;
|
||||
|
||||
sinit(s, frame, hdr->caplen);
|
||||
printf("%u.%06u ", hdr->ts.tv_sec, hdr->ts.tv_usec);
|
||||
printf("%u.%u ", hdr->ts.tv_sec, hdr->ts.tv_usec);
|
||||
switch (p->linktype) {
|
||||
case LINKTYPE_ETHERNET:
|
||||
print_ethernet(s);
|
||||
|
|
22
printfesc.c
22
printfesc.c
|
@ -1,4 +1,5 @@
|
|||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
|
@ -11,13 +12,24 @@ main(int argc, char *argv[])
|
|||
switch (c) {
|
||||
case EOF:
|
||||
break;
|
||||
case '0' ... '9':
|
||||
case 'A' ... 'Z':
|
||||
case 'a' ... 'z':
|
||||
putchar(c);
|
||||
case '\n':
|
||||
printf("\\n");
|
||||
break;
|
||||
case '\r':
|
||||
printf("\\r");
|
||||
break;
|
||||
case '\t':
|
||||
printf("\\t");
|
||||
break;
|
||||
case '"':
|
||||
printf("\\\"");
|
||||
break;
|
||||
default:
|
||||
printf("\\\\%03o", c);
|
||||
if (isprint(c)) {
|
||||
putchar(c);
|
||||
} else {
|
||||
printf("\\%03o", c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
43
stream.c
43
stream.c
|
@ -5,10 +5,11 @@
|
|||
#include "stream.h"
|
||||
|
||||
void
|
||||
sinit(struct stream *s, char const *buf, size_t buflen)
|
||||
sinit(struct stream *s, char const *buf, size_t buflen, enum endianness endian)
|
||||
{
|
||||
s->buf = buf;
|
||||
s->len = buflen;
|
||||
s->endian = endian;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -25,7 +26,7 @@ sskip(struct stream *s, size_t count)
|
|||
}
|
||||
|
||||
bool
|
||||
sread(struct stream * s, void *buf, size_t count)
|
||||
sread(struct stream *s, void *buf, size_t count)
|
||||
{
|
||||
void const *d = s->buf;
|
||||
|
||||
|
@ -37,8 +38,10 @@ sread(struct stream * s, void *buf, size_t count)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t
|
||||
read_uint8(struct stream * s)
|
||||
read_uint8(struct stream *s)
|
||||
{
|
||||
uint8_t *d = (uint8_t *) s->buf;
|
||||
|
||||
|
@ -48,8 +51,10 @@ read_uint8(struct stream * s)
|
|||
return d[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint16_t
|
||||
read_uint16be(struct stream * s)
|
||||
read_uint16be(struct stream *s)
|
||||
{
|
||||
uint8_t *d = (uint8_t *) s->buf;
|
||||
|
||||
|
@ -59,8 +64,9 @@ read_uint16be(struct stream * s)
|
|||
return ((d[0] << 8) | (d[1] << 0));
|
||||
}
|
||||
|
||||
|
||||
uint16_t
|
||||
read_uint16le(struct stream * s)
|
||||
read_uint16le(struct stream *s)
|
||||
{
|
||||
uint8_t *d = (uint8_t *) s->buf;
|
||||
|
||||
|
@ -70,11 +76,21 @@ read_uint16le(struct stream * s)
|
|||
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)
|
||||
read_uint32be(struct stream *s)
|
||||
{
|
||||
uint8_t *d = (uint8_t *) s->buf;
|
||||
|
||||
if (!sskip(s, 4)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -82,12 +98,21 @@ read_uint32be(struct stream * s)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
read_uint32le(struct stream * s)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
10
stream.h
10
stream.h
|
@ -5,18 +5,26 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
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);
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue