From 18a624e4d05c8e6129cdd107d91222e2a2544a1e Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 25 Apr 2008 11:08:43 +0000 Subject: [PATCH] Change syntax so that { ... } surrounds match patterns. --- TODO | 12 +++++- bitmatch.mli | 99 ++++++++++++++++++++++++----------------------- configure.ac | 2 +- pa_bitmatch.ml | 16 +++++--- tests/05_bits.ml | 12 +++--- tests/06_ints1.ml | 8 ++-- tests/06_ints2.ml | 8 ++-- tests/06_ints3.ml | 8 ++-- tests/10_constr1.ml | 10 ++--- tests/10_constr2.ml | 6 +-- tests/20_varsize.ml | 17 +++++---- tests/60_ping.ml | 30 +++++++-------- tests/70_ext3_sb.ml | 108 ++++++++++++++++++++++++++-------------------------- 13 files changed, 176 insertions(+), 160 deletions(-) diff --git a/TODO b/TODO index 11e2d02..a895ee3 100644 --- a/TODO +++ b/TODO @@ -1,11 +1,11 @@ -$Id: TODO,v 1.1 2008-04-15 13:41:14 rjones Exp $ +$Id: TODO,v 1.2 2008-04-25 11:08:43 rjones Exp $ Major to-do items. (1) In bitmatch operator, use patterns not expressions. (2) Allow matching against strings. -(3) Change the syntax so { ... } surrounds match patterns. +(3) DONE - Change the syntax so { ... } surrounds match patterns. (4) Provide UInt32 and UInt64 types. @@ -20,3 +20,11 @@ Major to-do items. { start : 16; another : 16 : align(32); (* implicit 16 bit gap before this *) } + +(7) Assertions: + + { start : 16 : assert (offset = 0); } + + (Q: Are these evaluated at compile time or at run time or selectable?) + +(8) Named but unbound patterns to avoid "Warning Y: unused variable". diff --git a/bitmatch.mli b/bitmatch.mli index b700f2b..b901ac0 100644 --- a/bitmatch.mli +++ b/bitmatch.mli @@ -15,7 +15,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * $Id: bitmatch.mli,v 1.13 2008-04-15 13:40:51 rjones Exp $ + * $Id: bitmatch.mli,v 1.14 2008-04-25 11:08:43 rjones Exp $ *) (** @@ -55,13 +55,13 @@ let display pkt = | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ *) - | 4 : 4; hdrlen : 4; tos : 8; length : 16; - identification : 16; flags : 3; fragoffset : 13; - ttl : 8; protocol : 8; checksum : 16; - source : 32; - dest : 32; - options : (hdrlen-5)*32 : bitstring; - payload : -1 : bitstring -> + | { 4 : 4; hdrlen : 4; tos : 8; length : 16; + identification : 16; flags : 3; fragoffset : 13; + ttl : 8; protocol : 8; checksum : 16; + source : 32; + dest : 32; + options : (hdrlen-5)*32 : bitstring; + payload : -1 : bitstring } -> printf "IPv4:\n"; printf " header length: %d * 32 bit words\n" hdrlen; @@ -79,11 +79,11 @@ let display pkt = printf " packet payload:\n"; Bitmatch.hexdump_bitstring stdout payload - | version : 4 -> + | { version : 4 } -> eprintf "unknown IP version %d\n" version; exit 1 - | _ as pkt -> + | { _ } as pkt -> eprintf "data is smaller than one nibble:\n"; Bitmatch.hexdump_bitstring stderr pkt; exit 1 @@ -97,22 +97,22 @@ let bits = Bitmatch.bitstring_of_file "tests/ext3_sb" let () = bitmatch bits with - | s_inodes_count : 32 : littleendian; (* Inodes count *) - s_blocks_count : 32 : littleendian; (* Blocks count *) - s_r_blocks_count : 32 : littleendian; (* Reserved blocks count *) - s_free_blocks_count : 32 : littleendian; (* Free blocks count *) - s_free_inodes_count : 32 : littleendian; (* Free inodes count *) - s_first_data_block : 32 : littleendian; (* First Data Block *) - s_log_block_size : 32 : littleendian; (* Block size *) - s_log_frag_size : 32 : littleendian; (* Fragment size *) - s_blocks_per_group : 32 : littleendian; (* # Blocks per group *) - s_frags_per_group : 32 : littleendian; (* # Fragments per group *) - s_inodes_per_group : 32 : littleendian; (* # Inodes per group *) - s_mtime : 32 : littleendian; (* Mount time *) - s_wtime : 32 : littleendian; (* Write time *) - s_mnt_count : 16 : littleendian; (* Mount count *) - s_max_mnt_count : 16 : littleendian; (* Maximal mount count *) - 0xef53 : 16 : littleendian -> (* Magic signature *) + | { s_inodes_count : 32 : littleendian; (* Inodes count *) + s_blocks_count : 32 : littleendian; (* Blocks count *) + s_r_blocks_count : 32 : littleendian; (* Reserved blocks count *) + s_free_blocks_count : 32 : littleendian; (* Free blocks count *) + s_free_inodes_count : 32 : littleendian; (* Free inodes count *) + s_first_data_block : 32 : littleendian; (* First Data Block *) + s_log_block_size : 32 : littleendian; (* Block size *) + s_log_frag_size : 32 : littleendian; (* Fragment size *) + s_blocks_per_group : 32 : littleendian; (* # Blocks per group *) + s_frags_per_group : 32 : littleendian; (* # Fragments per group *) + s_inodes_per_group : 32 : littleendian; (* # Inodes per group *) + s_mtime : 32 : littleendian; (* Mount time *) + s_wtime : 32 : littleendian; (* Write time *) + s_mnt_count : 16 : littleendian; (* Mount count *) + s_max_mnt_count : 16 : littleendian; (* Maximal mount count *) + 0xef53 : 16 : littleendian } -> (* Magic signature *) printf "ext3 superblock:\n"; printf " s_inodes_count = %ld\n" s_inodes_count; @@ -120,7 +120,7 @@ let () = printf " s_free_inodes_count = %ld\n" s_free_inodes_count; printf " s_free_blocks_count = %ld\n" s_free_blocks_count - | _ -> + | { _ } -> eprintf "not an ext3 superblock!\n%!"; exit 2 ]} @@ -139,10 +139,11 @@ let () = *) let make_message typ subtype param = - (BITSTRING + (BITSTRING { typ : 16; subtype : 16; - param : 32) ;; + param : 32 + }) ;; ]} {2 Loading, creating bitstrings} @@ -172,11 +173,11 @@ let make_message typ subtype param = The general form of [bitmatch] is: - [bitmatch] {i bitstring-expression} [with] + [bitmatch {] {i bitstring-expression} [} with] - [|] {i pattern} [->] {i code} + [| {] {i pattern} [} ->] {i code} - [|] {i pattern} [->] {i code} + [| {] {i pattern} [} ->] {i code} [|] ... @@ -193,25 +194,25 @@ let make_message typ subtype param = {[ bitmatch bits with -| version : 8; name : 8; param : 8 -> ... +| { version : 8; name : 8; param : 8 } -> ... (* Bitstring of at least 3 bytes. First byte is the version number, second byte is a field called name, third byte is a field called parameter. *) -| flag : 1 -> +| { flag : 1 } -> printf "flag is %b\n" flag (* A single flag bit (mapped into an OCaml boolean). *) -| len : 4; data : 1+len -> +| { len : 4; data : 1+len } -> printf "len = %d, data = 0x%Lx\n" len data (* A 4-bit length, followed by 1-16 bits of data, where the length of the data is computed from len. *) -| ipv6_source : 128 : bitstring; - ipv6_dest : 128 : bitstring -> ... +| { ipv6_source : 128 : bitstring; + ipv6_dest : 128 : bitstring } -> ... (* IPv6 source and destination addresses. Each is 128 bits and is mapped into a bitstring type which will be a substring @@ -221,7 +222,7 @@ bitmatch bits with You can also add conditional when-clauses: {[ -| version : 4 +| { version : 4 } when version = 4 || version = 6 -> ... (* Only match and run the code when version is 4 or 6. If @@ -237,8 +238,8 @@ bitmatch bits with length is zero in the when-clause: {[ -| n : 4; - rest : -1 : bitstring +| { n : 4; + rest : -1 : bitstring } when Bitmatch.bitstring_length rest = 0 -> ... (* Only matches exactly 4 bits. *) @@ -248,7 +249,7 @@ bitmatch bits with but you can also match a constant, as in: {[ -| 6 : 4 -> ... +| { 6 : 4 } -> ... (* Only matches if the first 4 bits contain the integer 6. *) ]} @@ -302,11 +303,11 @@ bitmatch bits with bitstring and/or have a default match case: {[ -| _ -> ... +| { _ } -> ... (* Default match case. *) -| _ as pkt -> ... +| { _ } as pkt -> ... (* Default match case, with 'pkt' bound to the whole bitstring. *) ]} @@ -321,9 +322,10 @@ bitmatch bits with let version = 1 ;; let data = 10 ;; let bits = - BITSTRING + BITSTRING { version : 4; - data : 12 ;; + data : 12 + } ;; (* Constructs a 16-bit bitstring with the first four bits containing the integer 1, and the following 12 bits containing the integer 10, @@ -437,8 +439,8 @@ Bitmatch.hexdump_bitstring stdout bits ;; {[ bitmatch bits with -| len : 64; - buffer : Int64.to_int len : bitstring -> +| { len : 64; + buffer : Int64.to_int len : bitstring } -> ]} The [len] field can be set arbitrarily large by an attacker, but @@ -460,8 +462,9 @@ bitmatch bits with {[ let len = read_untrusted_source () in let buffer = allocate_bitstring () in -BITSTRING +BITSTRING { buffer : len : bitstring +} ]} This code merely causes a check that buffer's length is the same as diff --git a/configure.ac b/configure.ac index 3f6a9e4..2ba7e97 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(ocaml-bitmatch,0.4) +AC_INIT(ocaml-bitmatch,0.5) dnl Check for basic C environment. AC_PROG_CC diff --git a/pa_bitmatch.ml b/pa_bitmatch.ml index b5e9758..d10ff6f 100644 --- a/pa_bitmatch.ml +++ b/pa_bitmatch.ml @@ -15,7 +15,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * $Id: pa_bitmatch.ml,v 1.7 2008-04-25 10:44:00 rjones Exp $ + * $Id: pa_bitmatch.ml,v 1.8 2008-04-25 11:08:43 rjones Exp $ *) open Printf @@ -688,13 +688,15 @@ EXTEND Gram ]; match_case: [ - [ "_"; + [ "{"; "_"; "}"; bind = OPT [ "as"; name = LIDENT -> name ]; w = OPT [ "when"; e = expr -> e ]; "->"; code = expr -> (Bind bind, w, code) ] - | [ fields = LIST0 field SEP ";"; + | [ "{"; + fields = LIST0 field SEP ";"; + "}"; w = OPT [ "when"; e = expr -> e ]; "->"; code = expr -> (Fields fields, w, code) @@ -703,14 +705,16 @@ EXTEND Gram (* 'bitmatch' expressions. *) expr: LEVEL ";" [ - [ "bitmatch"; bs = expr; "with"; OPT "|"; + [ "bitmatch"; + bs = expr; "with"; OPT "|"; cases = LIST1 match_case SEP "|" -> output_bitmatch _loc bs cases ] (* Constructor. *) - | [ "BITSTRING"; - fields = LIST0 field SEP ";" -> + | [ "BITSTRING"; "{"; + fields = LIST0 field SEP ";"; + "}" -> output_constructor _loc fields ] ]; diff --git a/tests/05_bits.ml b/tests/05_bits.ml index 7f78b46..829643c 100644 --- a/tests/05_bits.ml +++ b/tests/05_bits.ml @@ -1,15 +1,15 @@ (* Extract bits. - * $Id: 05_bits.ml,v 1.2 2008-04-01 08:56:43 rjones Exp $ + * $Id: 05_bits.ml,v 1.3 2008-04-25 11:08:43 rjones Exp $ *) let bits = Bitmatch.make_bitstring 24 '\x5a' (* makes the string 0x5a5a5a *) let () = bitmatch bits with - | b0 : 1; b1 : 1; b2 : 1; b3 : 1; b4 : 1; b5 : 1; b6 : 1; b7 : 1; - b8 : 1; b9 : 1; b10 : 1; b11 : 1; b12 : 1; b13 : 1; b14 : 1; b15 : 1; - b16 : 1; b17 : 1; b18 : 1; b19 : 1; b20 : 1; b21 : 1; b22 : 1; b23 : 1; - rest : -1 : bitstring -> + | { b0 : 1; b1 : 1; b2 : 1; b3 : 1; b4 : 1; b5 : 1; b6 : 1; b7 : 1; + b8 : 1; b9 : 1; b10 : 1; b11 : 1; b12 : 1; b13 : 1; b14 : 1; b15 : 1; + b16 : 1; b17 : 1; b18 : 1; b19 : 1; b20 : 1; b21 : 1; b22 : 1; b23 : 1; + rest : -1 : bitstring } -> assert (not b0 && b1 && not b2 && b3 && (* 0x5 *) b4 && not b5 && b6 && not b7); (* 0xA *) assert (not b8 && b9 && not b10 && b11 && (* 0x5 *) @@ -19,5 +19,5 @@ let () = let _, off, len = rest in assert (off = 24 && len = 0) (* no further data *) - | _ -> + | { _ } -> failwith "error: did not match\n" diff --git a/tests/06_ints1.ml b/tests/06_ints1.ml index 5a49bff..962f83e 100644 --- a/tests/06_ints1.ml +++ b/tests/06_ints1.ml @@ -1,13 +1,13 @@ (* Extract some simple integers. - * $Id: 06_ints1.ml,v 1.1 2008-04-01 08:56:43 rjones Exp $ + * $Id: 06_ints1.ml,v 1.2 2008-04-25 11:08:43 rjones Exp $ *) let bits = Bitmatch.make_bitstring 16 '\xcf' (* makes the string 0xcfcf *) let () = bitmatch bits with - | n0 : 4; n1 : 4; n2 : 4; n3 : 4; - rest : -1 : bitstring -> + | { n0 : 4; n1 : 4; n2 : 4; n3 : 4; + rest : -1 : bitstring } -> assert (n0 = 0xc); assert (n1 = 0xf); assert (n2 = 0xc); @@ -16,5 +16,5 @@ let () = let _, off, len = rest in assert (off = 16 && len = 0) (* no further data *) - | _ -> + | { _ } -> failwith "error: did not match\n" diff --git a/tests/06_ints2.ml b/tests/06_ints2.ml index c0bd76e..3587b4a 100644 --- a/tests/06_ints2.ml +++ b/tests/06_ints2.ml @@ -1,13 +1,13 @@ (* Extract some simple integers. - * $Id: 06_ints2.ml,v 1.1 2008-04-01 08:56:43 rjones Exp $ + * $Id: 06_ints2.ml,v 1.2 2008-04-25 11:08:43 rjones Exp $ *) let bits = Bitmatch.make_bitstring 16 '\xcf' (* makes the string 0xcfcf *) let () = bitmatch bits with - | n0 : 2; n1 : 2; n2 : 2; n3 : 2; n4 : 2; n5 : 2; n6 : 2; n7 : 2; - rest : -1 : bitstring -> + | { n0 : 2; n1 : 2; n2 : 2; n3 : 2; n4 : 2; n5 : 2; n6 : 2; n7 : 2; + rest : -1 : bitstring } -> assert (n0 = 0x3); (* 0xc *) assert (n1 = 0x0); assert (n2 = 0x3); (* 0xf *) @@ -20,5 +20,5 @@ let () = let _, off, len = rest in assert (off = 16 && len = 0) (* no further data *) - | _ -> + | { _ } -> failwith "error: did not match\n" diff --git a/tests/06_ints3.ml b/tests/06_ints3.ml index dc5b687..850dd04 100644 --- a/tests/06_ints3.ml +++ b/tests/06_ints3.ml @@ -1,13 +1,13 @@ (* Extract some simple integers. - * $Id: 06_ints3.ml,v 1.1 2008-04-01 08:56:43 rjones Exp $ + * $Id: 06_ints3.ml,v 1.2 2008-04-25 11:08:43 rjones Exp $ *) let bits = Bitmatch.make_bitstring 16 '\xcf' (* makes the string 0xcfcf *) let () = bitmatch bits with - | n0 : 3; n1 : 3; n2 : 3; n3 : 3; n4 : 3; n5 : 1; - rest : -1 : bitstring -> + | { n0 : 3; n1 : 3; n2 : 3; n3 : 3; n4 : 3; n5 : 1; + rest : -1 : bitstring } -> assert (n0 = 0b110); assert (n1 = 0b011); assert (n2 = 0b111); @@ -18,5 +18,5 @@ let () = let _, off, len = rest in assert (off = 16 && len = 0) (* no further data *) - | _ -> + | { _ } -> failwith "error: did not match\n" diff --git a/tests/10_constr1.ml b/tests/10_constr1.ml index ba7ccc8..0a14928 100644 --- a/tests/10_constr1.ml +++ b/tests/10_constr1.ml @@ -1,15 +1,15 @@ (* Test a simple constructor. - * $Id: 10_constr1.ml,v 1.1 2008-04-01 17:05:37 rjones Exp $ + * $Id: 10_constr1.ml,v 1.2 2008-04-25 11:08:43 rjones Exp $ *) -let bits = BITSTRING 0xc : 4; 0xf : 4; 0xc : 4; 0xf : 4 ;; +let bits = BITSTRING { 0xc : 4; 0xf : 4; 0xc : 4; 0xf : 4 } ;; assert (bits = Bitmatch.make_bitstring 16 '\xcf') ;; let () = bitmatch bits with - | n0 : 4; n1 : 4; n2 : 4; n3 : 4; - rest : -1 : bitstring -> + | { n0 : 4; n1 : 4; n2 : 4; n3 : 4; + rest : -1 : bitstring } -> assert (n0 = 0xc); assert (n1 = 0xf); assert (n2 = 0xc); @@ -18,5 +18,5 @@ let () = let _, off, len = rest in assert (off = 16 && len = 0) (* no further data *) - | _ -> + | { _ } -> failwith "error: did not match\n" diff --git a/tests/10_constr2.ml b/tests/10_constr2.ml index 31af87f..92b1470 100644 --- a/tests/10_constr2.ml +++ b/tests/10_constr2.ml @@ -1,12 +1,12 @@ (* Test a simple constructor. - * $Id: 10_constr2.ml,v 1.1 2008-04-02 11:06:07 rjones Exp $ + * $Id: 10_constr2.ml,v 1.2 2008-04-25 11:08:43 rjones Exp $ *) let version = 1 ;; let data = 10 ;; let bits = BITSTRING - version : 4; - data : 12 ;; + { version : 4; + data : 12 } ;; Bitmatch.hexdump_bitstring stdout bits ;; diff --git a/tests/20_varsize.ml b/tests/20_varsize.ml index 5222766..b90763c 100644 --- a/tests/20_varsize.ml +++ b/tests/20_varsize.ml @@ -1,5 +1,5 @@ (* Construct and match against random variable sized strings. - * $Id: 20_varsize.ml,v 1.1 2008-04-01 17:05:37 rjones Exp $ + * $Id: 20_varsize.ml,v 1.2 2008-04-25 11:08:43 rjones Exp $ *) open Printf @@ -56,11 +56,12 @@ let () = (* Construct the bitstring. *) let bits = try - (BITSTRING - n0 : n0sz; - n1 : n1sz; - n2 : n2sz; - n3 : n3sz) + (BITSTRING { + n0 : n0sz; + n1 : n1sz; + n2 : n2sz; + n3 : n3sz + }) with Bitmatch.Construct_failure (msg, _, _, _) -> eprintf "FAILED: Construct_failure %s\n%!" msg; @@ -70,7 +71,7 @@ let () = let r0, r1, r2, r3 = bitmatch bits with - | r0 : n0sz; r1 : n1sz; r2 : n2sz; r3 : n3sz; rest : -1 : bitstring -> + | { r0 : n0sz; r1 : n1sz; r2 : n2sz; r3 : n3sz; rest : -1 : bitstring } -> let rest_len = Bitmatch.bitstring_length rest in if rest_len <> 0 then ( eprintf "FAILED: rest is not zero length (length = %d)\n%!" @@ -79,7 +80,7 @@ let () = exit 2 ); r0, r1, r2, r3 - | _ -> + | { _ } -> eprintf "FAILED: bitmatch operator did not match\n%!"; dump n0 n0sz n1 n1sz n2 n2sz n3 n3sz bits 0L 0L 0L 0L; exit 2 in diff --git a/tests/60_ping.ml b/tests/60_ping.ml index 1954de1..7a274cb 100644 --- a/tests/60_ping.ml +++ b/tests/60_ping.ml @@ -1,5 +1,5 @@ (* Read in IPv4 and IPv6 ping packets and display them. - * $Id: 60_ping.ml,v 1.2 2008-04-01 15:22:46 rjones Exp $ + * $Id: 60_ping.ml,v 1.3 2008-04-25 11:08:43 rjones Exp $ *) open Printf @@ -7,13 +7,13 @@ open Printf let display pkt = bitmatch pkt with (* IPv4 packet header *) - | 4 : 4; hdrlen : 4; tos : 8; length : 16; - identification : 16; flags : 3; fragoffset : 13; - ttl : 8; protocol : 8; checksum : 16; - source : 32; - dest : 32; - options : (hdrlen-5)*32 : bitstring; - payload : -1 : bitstring -> + | { 4 : 4; hdrlen : 4; tos : 8; length : 16; + identification : 16; flags : 3; fragoffset : 13; + ttl : 8; protocol : 8; checksum : 16; + source : 32; + dest : 32; + options : (hdrlen-5)*32 : bitstring; + payload : -1 : bitstring } -> printf "IPv4:\n"; printf " header length: %d * 32 bit words\n" hdrlen; @@ -32,11 +32,11 @@ let display pkt = Bitmatch.hexdump_bitstring stdout payload (* IPv6 packet header *) - | 6 : 4; tclass : 8; flow : 20; - length : 16; nexthdr : 8; ttl : 8; - source : 128 : bitstring; - dest : 128 : bitstring; - payload : -1 : bitstring -> + | { 6 : 4; tclass : 8; flow : 20; + length : 16; nexthdr : 8; ttl : 8; + source : 128 : bitstring; + dest : 128 : bitstring; + payload : -1 : bitstring } -> printf "IPv6:\n"; printf " traffic class: %d\n" tclass; @@ -51,11 +51,11 @@ let display pkt = printf "packet payload:\n"; Bitmatch.hexdump_bitstring stdout payload - | version : 4 -> + | { version : 4 } -> eprintf "unknown IP version %d\n" version; exit 1 - | _ as pkt -> + | { _ } as pkt -> eprintf "data is smaller than one nibble:\n"; Bitmatch.hexdump_bitstring stderr pkt; exit 1 diff --git a/tests/70_ext3_sb.ml b/tests/70_ext3_sb.ml index e8cebb4..af5169a 100644 --- a/tests/70_ext3_sb.ml +++ b/tests/70_ext3_sb.ml @@ -1,5 +1,5 @@ (* Parse an ext3 superblock. - * $Id: 70_ext3_sb.ml,v 1.1 2008-04-01 19:10:45 rjones Exp $ + * $Id: 70_ext3_sb.ml,v 1.2 2008-04-25 11:08:43 rjones Exp $ *) open Printf @@ -12,58 +12,58 @@ let bits = Bitmatch.bitstring_of_file "tests/ext3_sb" let () = bitmatch bits with - | s_inodes_count : 32 : littleendian; (* Inodes count *) - s_blocks_count : 32 : littleendian; (* Blocks count *) - s_r_blocks_count : 32 : littleendian; (* Reserved blocks count *) - s_free_blocks_count : 32 : littleendian; (* Free blocks count *) - s_free_inodes_count : 32 : littleendian; (* Free inodes count *) - s_first_data_block : 32 : littleendian; (* First Data Block *) - s_log_block_size : 32 : littleendian; (* Block size *) - s_log_frag_size : 32 : littleendian; (* Fragment size *) - s_blocks_per_group : 32 : littleendian; (* # Blocks per group *) - s_frags_per_group : 32 : littleendian; (* # Fragments per group *) - s_inodes_per_group : 32 : littleendian; (* # Inodes per group *) - s_mtime : 32 : littleendian; (* Mount time *) - s_wtime : 32 : littleendian; (* Write time *) - s_mnt_count : 16 : littleendian; (* Mount count *) - s_max_mnt_count : 16 : littleendian; (* Maximal mount count *) - 0xef53 : 16 : littleendian; (* Magic signature *) - s_state : 16 : littleendian; (* File system state *) - s_errors : 16 : littleendian; (* Behaviour when detecting errors *) - s_minor_rev_level : 16 : littleendian; (* minor revision level *) - s_lastcheck : 32 : littleendian; (* time of last check *) - s_checkinterval : 32 : littleendian; (* max. time between checks *) - s_creator_os : 32 : littleendian; (* OS *) - s_rev_level : 32 : littleendian; (* Revision level *) - s_def_resuid : 16 : littleendian; (* Default uid for reserved blocks *) - s_def_resgid : 16 : littleendian; (* Default gid for reserved blocks *) - s_first_ino : 32 : littleendian; (* First non-reserved inode *) - s_inode_size : 16 : littleendian; (* size of inode structure *) - s_block_group_nr : 16 : littleendian; (* block group # of this superblock *) - s_feature_compat : 32 : littleendian; (* compatible feature set *) - s_feature_incompat : 32 : littleendian; (* incompatible feature set *) - s_feature_ro_compat : 32 : littleendian; (* readonly-compatible feature set *) - s_uuid : 128 : bitstring; (* 128-bit uuid for volume *) - s_volume_name : 128 : bitstring; (* volume name XXX string *) - s_last_mounted : 512 : bitstring; (* directory where last mounted XXX string *) - s_algorithm_usage_bitmap : 32 : littleendian; (* For compression *) - s_prealloc_blocks : 8; (* Nr of blocks to try to preallocate*) - s_prealloc_dir_blocks : 8; (* Nr to preallocate for dirs *) - s_reserved_gdt_blocks : 16 : littleendian; (* Per group desc for online growth *) - s_journal_uuid : 128 : bitstring; (* uuid of journal superblock *) - s_journal_inum : 32 : littleendian; (* inode number of journal file *) - s_journal_dev : 32 : littleendian; (* device number of journal file *) - s_last_orphan : 32 : littleendian; (* start of list of inodes to delete *) - s_hash_seed0 : 32 : littleendian; (* HTREE hash seed *) - s_hash_seed1 : 32 : littleendian; - s_hash_seed2 : 32 : littleendian; - s_hash_seed3 : 32 : littleendian; - s_def_hash_version : 8; (* Default hash version to use *) - s_reserved_char_pad : 8; - s_reserved_word_pad : 16 : littleendian; - s_default_mount_opts : 32 : littleendian; - s_first_meta_bg : 32 : littleendian; (* First metablock block group *) - s_reserved : 6080 : bitstring -> (* Padding to the end of the block *) + | { s_inodes_count : 32 : littleendian; (* Inodes count *) + s_blocks_count : 32 : littleendian; (* Blocks count *) + s_r_blocks_count : 32 : littleendian; (* Reserved blocks count *) + s_free_blocks_count : 32 : littleendian; (* Free blocks count *) + s_free_inodes_count : 32 : littleendian; (* Free inodes count *) + s_first_data_block : 32 : littleendian; (* First Data Block *) + s_log_block_size : 32 : littleendian; (* Block size *) + s_log_frag_size : 32 : littleendian; (* Fragment size *) + s_blocks_per_group : 32 : littleendian; (* # Blocks per group *) + s_frags_per_group : 32 : littleendian; (* # Fragments per group *) + s_inodes_per_group : 32 : littleendian; (* # Inodes per group *) + s_mtime : 32 : littleendian; (* Mount time *) + s_wtime : 32 : littleendian; (* Write time *) + s_mnt_count : 16 : littleendian; (* Mount count *) + s_max_mnt_count : 16 : littleendian; (* Maximal mount count *) + 0xef53 : 16 : littleendian; (* Magic signature *) + s_state : 16 : littleendian; (* File system state *) + s_errors : 16 : littleendian; (* Behaviour when detecting errors *) + s_minor_rev_level : 16 : littleendian; (* minor revision level *) + s_lastcheck : 32 : littleendian; (* time of last check *) + s_checkinterval : 32 : littleendian; (* max. time between checks *) + s_creator_os : 32 : littleendian; (* OS *) + s_rev_level : 32 : littleendian; (* Revision level *) + s_def_resuid : 16 : littleendian; (* Default uid for reserved blocks *) + s_def_resgid : 16 : littleendian; (* Default gid for reserved blocks *) + s_first_ino : 32 : littleendian; (* First non-reserved inode *) + s_inode_size : 16 : littleendian; (* size of inode structure *) + s_block_group_nr : 16 : littleendian; (* block group # of this superblock *) + s_feature_compat : 32 : littleendian; (* compatible feature set *) + s_feature_incompat : 32 : littleendian; (* incompatible feature set *) + s_feature_ro_compat : 32 : littleendian; (* readonly-compatible feature set *) + s_uuid : 128 : bitstring; (* 128-bit uuid for volume *) + s_volume_name : 128 : bitstring; (* volume name XXX string *) + s_last_mounted : 512 : bitstring; (* directory where last mounted XXX string *) + s_algorithm_usage_bitmap : 32 : littleendian; (* For compression *) + s_prealloc_blocks : 8; (* Nr of blocks to try to preallocate*) + s_prealloc_dir_blocks : 8; (* Nr to preallocate for dirs *) + s_reserved_gdt_blocks : 16 : littleendian;(* Per group desc for online growth *) + s_journal_uuid : 128 : bitstring; (* uuid of journal superblock *) + s_journal_inum : 32 : littleendian; (* inode number of journal file *) + s_journal_dev : 32 : littleendian; (* device number of journal file *) + s_last_orphan : 32 : littleendian; (* start of list of inodes to delete *) + s_hash_seed0 : 32 : littleendian; (* HTREE hash seed *) + s_hash_seed1 : 32 : littleendian; + s_hash_seed2 : 32 : littleendian; + s_hash_seed3 : 32 : littleendian; + s_def_hash_version : 8; (* Default hash version to use *) + s_reserved_char_pad : 8; + s_reserved_word_pad : 16 : littleendian; + s_default_mount_opts : 32 : littleendian; + s_first_meta_bg : 32 : littleendian; (* First metablock block group *) + s_reserved : 6080 : bitstring } -> (* Padding to the end of the block *) printf "ext3 superblock:\n"; printf " s_inodes_count = %ld\n" s_inodes_count; @@ -71,6 +71,6 @@ let () = printf " s_free_inodes_count = %ld\n" s_free_inodes_count; printf " s_free_blocks_count = %ld\n" s_free_blocks_count - | _ -> + | { _ } -> eprintf "not an ext3 superblock!\n%!"; exit 2 -- 1.8.3.1