-$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.
{ 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".
* 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 $
*)
(**
| 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;
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
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;
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
]}
*)
let make_message typ subtype param =
- (BITSTRING
+ (BITSTRING {
typ : 16;
subtype : 16;
- param : 32) ;;
+ param : 32
+ }) ;;
]}
{2 Loading, creating bitstrings}
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}
[|] ...
{[
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
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
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. *)
but you can also match a constant, as in:
{[
-| 6 : 4 -> ...
+| { 6 : 4 } -> ...
(* Only matches if the first 4 bits contain the integer 6. *)
]}
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. *)
]}
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,
{[
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
{[
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
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
* 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
];
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)
(* '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
]
];
(* 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 *)
let _, off, len = rest in
assert (off = 24 && len = 0) (* no further data *)
- | _ ->
+ | { _ } ->
failwith "error: did not match\n"
(* 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);
let _, off, len = rest in
assert (off = 16 && len = 0) (* no further data *)
- | _ ->
+ | { _ } ->
failwith "error: did not match\n"
(* 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 *)
let _, off, len = rest in
assert (off = 16 && len = 0) (* no further data *)
- | _ ->
+ | { _ } ->
failwith "error: did not match\n"
(* 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);
let _, off, len = rest in
assert (off = 16 && len = 0) (* no further data *)
- | _ ->
+ | { _ } ->
failwith "error: did not match\n"
(* 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);
let _, off, len = rest in
assert (off = 16 && len = 0) (* no further data *)
- | _ ->
+ | { _ } ->
failwith "error: did not match\n"
(* 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 ;;
(* 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
(* 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;
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%!"
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
(* 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
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;
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;
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
(* 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
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;
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