diff options
-rw-r--r-- | bpf-assembler.scm | 12 | ||||
-rw-r--r-- | tests/run.scm | 187 |
2 files changed, 192 insertions, 7 deletions
diff --git a/bpf-assembler.scm b/bpf-assembler.scm index 9614fac..c626bee 100644 --- a/bpf-assembler.scm +++ b/bpf-assembler.scm @@ -43,7 +43,7 @@ ;; XXX TODO: Use the constants from net/bpf.h? ;; Ordered by complexity - (defaddrmode no-operands #x80 (() => 0) (_ => ())) + (defaddrmode no-operands #x00 (() => 0) (_ => ())) (defaddrmode packet-length #x80 (('len) => 0) (_ => (len))) (defaddrmode index-register #x08 (('x) => 0) (_ => (x))) (defaddrmode accumulator-register #x10 (('a) => 0) (_ => (a))) @@ -53,6 +53,9 @@ (defaddrmode memory-ref #x60 ((('mem (and k (? uint?)))) => k) (k => ((mem ,k)))) + (defaddrmode memory-set! #x00 ; No corresponding definition in bpf.h + ((('mem (and k (? uint?)))) => k) + (k => ((mem ,k)))) (defaddrmode packet-ref #x20 ((('pkt (and k (? uint?)))) => k) (k => ((pkt ,k)))) @@ -81,9 +84,10 @@ packet-length immediate memory-ref packet-ref packet-ref/index-register) (defop ldh #x08 packet-ref packet-ref/index-register) (defop ldb #x10 packet-ref packet-ref/index-register) - (defop ldx #x01 packet-length immediate memory-ref packet-ref/hack) - (defop st #x02 memory-ref) - (defop stx #x03 memory-ref) + (defop ldx #x01 packet-length immediate memory-ref) + (defop ldxb #x11 packet-ref/hack) ; This is how tcpdump prints ldx/msh + (defop st #x02 memory-set!) + (defop stx #x03 memory-set!) (defop jmp #x05 immediate) ; aka JA (defop jeq #x15 conditional-jump-immediate conditional-jump-index-register) (defop jgt #x25 conditional-jump-immediate conditional-jump-index-register) diff --git a/tests/run.scm b/tests/run.scm index b0e8e46..880c105 100644 --- a/tests/run.scm +++ b/tests/run.scm @@ -17,7 +17,9 @@ ;; load byte/halfword into accumulator register (ldb (pkt 1)) (ldb (pkt x 1)) (ldh (pkt 1)) (ldh (pkt x 1)) ;; load index register - (ldx len) (ldx 1) (ldx (mem 1)) (ldx (pkt 4* 1)) + (ldx len) (ldx 1) (ldx (mem 1)) + ;; load index register w/ byte, with packet 4*-index hack + (ldxb (pkt 4* 1)) ;; store accumulator/index register (st (mem 1)) (stx (mem 1)) ;; jump unconditionally (sometimes called JA instead of JMP) @@ -56,6 +58,8 @@ (ldb len) (ldb x) (ldb a) (ldb (pkt 4* 1))) ("load of word into index from invalid types" (ldx (pkt 1)) (ldx a) (ldx x) (ldx (pkt 1)) (ldx (pkt x 1))) + ("load of byte into index from invalid types" + (ldxb len) (ldxb 1) (ldxb (mem 1)) (ldxb (pkt 1)) (ldxb (pkt x 1))) ("store of accumulator into memory must be immediate memory index" (st 1) (st len) (st a) (st x) (st (mem x 1)) @@ -136,6 +140,94 @@ "6 0 0 65535" "6 0 0 0") "\n" 'suffix) + (lambda () (read-decimal-bpf-bytecode))))) + (test "unoptimised data-only dump of port 80" + `((ldh (pkt 12)) + (jeq #x0800 0 37) + (ldh (pkt 12)) + (jeq #x86dd 0 2) + (ldb (pkt 20)) + (jeq #x06 4 0) + (ldh (pkt 12)) + (jeq #x0800 0 31) + (ldb (pkt 23)) + (jeq #x06 0 29) + (ldh (pkt 20)) + (jset #x1fff 27 0) + (ld #x0d) + (st (mem 0)) + (ldxb (pkt 4* 14)) + (ld (mem 0)) + (add x) + (tax) + (ldb (pkt x 14)) + (st (mem 1)) + (ld #x02) + (st (mem 2)) + (ld #x01) + (st (mem 3)) + (ldx (mem 3)) + (ld (mem 2)) + (or x) + (st (mem 3)) + (ldx (mem 3)) + (ld (mem 1)) + (and x) + (st (mem 3)) + (ld #x00) + (st (mem 4)) + (ldx (mem 4)) + (ld (mem 3)) + (sub x) + (jeq #x00 1 0) + (ret 65535) + (ret 0)) + ;; tcpdump -Oddd tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 + (bpf-bytecode->exprs + (with-input-from-string + (string-join + `("40" + "40 0 0 12" + "21 0 37 2048" + "40 0 0 12" + "21 0 2 34525" + "48 0 0 20" + "21 4 0 6" + "40 0 0 12" + "21 0 31 2048" + "48 0 0 23" + "21 0 29 6" + "40 0 0 20" + "69 27 0 8191" + "0 0 0 13" + "2 0 0 0" + "177 0 0 14" + "96 0 0 0" + "12 0 0 0" + "7 0 0 0" + "80 0 0 14" + "2 0 0 1" + "0 0 0 2" + "2 0 0 2" + "0 0 0 1" + "2 0 0 3" + "97 0 0 3" + "96 0 0 2" + "76 0 0 0" + "2 0 0 3" + "97 0 0 3" + "96 0 0 1" + "92 0 0 0" + "2 0 0 3" + "0 0 0 0" + "2 0 0 4" + "97 0 0 4" + "96 0 0 3" + "28 0 0 0" + "21 1 0 0" + "6 0 0 65535" + "6 0 0 0") + "\n" 'suffix) (lambda () (read-decimal-bpf-bytecode)))))) (test-group "decimal bytecode writer" @@ -167,8 +259,97 @@ (ld (pkt 28)) (jeq #x7f000001 0 1) (ret 65535) - (ret 0)))))) -)) + (ret 0))))))) + + (test "unoptimised data-only dump of port 80" + (string-join + `("40" + "40 0 0 12" + "21 0 37 2048" + "40 0 0 12" + "21 0 2 34525" + "48 0 0 20" + "21 4 0 6" + "40 0 0 12" + "21 0 31 2048" + "48 0 0 23" + "21 0 29 6" + "40 0 0 20" + "69 27 0 8191" + "0 0 0 13" + "2 0 0 0" + "177 0 0 14" + "96 0 0 0" + "12 0 0 0" + "7 0 0 0" + "80 0 0 14" + "2 0 0 1" + "0 0 0 2" + "2 0 0 2" + "0 0 0 1" + "2 0 0 3" + "97 0 0 3" + "96 0 0 2" + "76 0 0 0" + "2 0 0 3" + "97 0 0 3" + "96 0 0 1" + "92 0 0 0" + "2 0 0 3" + "0 0 0 0" + "2 0 0 4" + "97 0 0 4" + "96 0 0 3" + "28 0 0 0" + "21 1 0 0" + "6 0 0 65535" + "6 0 0 0") + "\n" 'suffix) + ;; tcpdump -Oddd tcp[tcpflags] & (tcp-syn|tcp-fin) != 0 + (with-output-to-string + (lambda () + (write-decimal-bpf-bytecode + (exprs->bpf-bytecode + `((ldh (pkt 12)) + (jeq #x0800 0 37) + (ldh (pkt 12)) + (jeq #x86dd 0 2) + (ldb (pkt 20)) + (jeq #x06 4 0) + (ldh (pkt 12)) + (jeq #x0800 0 31) + (ldb (pkt 23)) + (jeq #x06 0 29) + (ldh (pkt 20)) + (jset #x1fff 27 0) + (ld #x0d) + (st (mem 0)) + (ldxb (pkt 4* 14)) + (ld (mem 0)) + (add x) + (tax) + (ldb (pkt x 14)) + (st (mem 1)) + (ld #x02) + (st (mem 2)) + (ld #x01) + (st (mem 3)) + (ldx (mem 3)) + (ld (mem 2)) + (or x) + (st (mem 3)) + (ldx (mem 3)) + (ld (mem 1)) + (and x) + (st (mem 3)) + (ld #x00) + (st (mem 4)) + (ldx (mem 4)) + (ld (mem 3)) + (sub x) + (jeq #x00 1 0) + (ret 65535) + (ret 0)))))))) (test-end "BPF assembler") |