Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .ocamlformat
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
profile = janestreet
version = 0.28.1
18 changes: 8 additions & 10 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,17 @@ let () =
## Simple binary message parser

```ocaml
(*
+---------------+---------------+--------------------------+
| type | subtype | parameter |
+---------------+---------------+--------------------------+
<-- 16 bits --> <-- 16 bits --> <------- 32 bits -------->
(* +---------------+---------------+--------------------------+
| type | subtype | parameter |
+---------------+---------------+--------------------------+
<-- 16 bits --> <-- 16 bits --> <------- 32 bits -------->

All fields are in network byte order.
*)
All fields are in network byte order. *)

let%bitstring make_message typ subtype param = {|
typ : 16;
subtype : 16;
param : 32
typ : 16;
subtype : 16;
param : 32
|};;
```

Expand Down
5 changes: 3 additions & 2 deletions dune
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
(env
(dev
(flags (:standard -w -27-32-33-35))))
(dev
(flags
(:standard -w -27-32-33-35))))
23 changes: 10 additions & 13 deletions examples/elf.ml
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
(* Read an ELF (Linux binary) header.
* $Id$
*)
(* Read an ELF (Linux binary) header. *)

open Printf

let () =
let filename = "/bin/ls" in
let bits = Bitstring.bitstring_of_file filename in

match%bitstring bits with
| {| 0x7f : 8; "ELF" : 24 : string; (* ELF magic number *)
_ : 12*8 : bitstring; (* ELF identifier *)
e_type : 16 : littleendian; (* object file type *)
e_machine : 16 : littleendian (* architecture *)
|} ->
printf "%s: ELF binary, type %d, arch %d\n" filename e_type e_machine

| {| _ |} ->
eprintf "%s: Not an ELF binary\n" filename
| {| 0x7f : 8
; "ELF" : 24 : string (* ELF magic number *)
; _ : 12*8 : bitstring (* ELF identifier *)
; e_type : 16 : littleendian (* object file type *)
; e_machine : 16 : littleendian (* architecture *)
|}
-> printf "%s: ELF binary, type %d, arch %d\n" filename e_type e_machine
| {| _ |} -> eprintf "%s: Not an ELF binary\n" filename
;;
113 changes: 56 additions & 57 deletions examples/ext3_superblock.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
(* Parse an ext3 superblock.
* $Id$
*)
(* Parse an ext3 superblock. *)

open Printf

Expand All @@ -12,59 +10,60 @@ let bits = Bitstring.bitstring_of_file "ext3_sb"

let () =
match%bitstring 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 : string; (* 128-bit uuid for volume *)
s_volume_name : 128 : string; (* volume name *)
s_last_mounted : 512 : string; (* directory where last mounted *)
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 : string; (* 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 *)
_ : 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 : string (* 128-bit uuid for volume *)
; s_volume_name : 128 : string (* volume name *)
; s_last_mounted : 512 : string (* directory where last mounted *)
; 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 : string (* 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 *)
; _ : 6080 : bitstring |}
->
(* Padding to the end of the block *)
printf "ext3 superblock:\n";
printf " s_inodes_count = %ld\n" s_inodes_count;
printf " s_blocks_count = %ld\n" s_blocks_count;
Expand All @@ -73,7 +72,7 @@ let () =
printf " s_uuid = %S\n" s_uuid;
printf " s_volume_name = %S\n" s_volume_name;
printf " s_last_mounted = %S\n" s_last_mounted

| {| _ |} ->
eprintf "not an ext3 superblock!\n%!";
exit 2
;;
49 changes: 23 additions & 26 deletions examples/gif.ml
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
(* GIF header parser.
* $Id$
*)
(* GIF header parser. *)

open Printf

let () =
if Array.length Sys.argv <= 1 then
failwith "usage: gif input.gif";
if Array.length Sys.argv <= 1 then failwith "usage: gif input.gif";
let filename = Sys.argv.(1) in
let bits = Bitstring.bitstring_of_file filename in

match%bitstring bits with
| {|("GIF87a"|"GIF89a") : 6*8 : string; (* GIF magic. *)
width : 16 : littleendian;
height : 16 : littleendian;
colormap : 1; (* Has colormap? *)
colorbits : 3; (* Color res = colorbits+1 *)
sortflag : 1;
bps : 3; (* Bits/pixel = bps+1 *)
bg : 8; (* Background colour. *)
aspectratio : 8|} ->
printf "%s: GIF image:\n" filename;
printf " size %d %d\n" width height;
printf " has global colormap? %b\n" colormap;
printf " colorbits %d\n" (colorbits+1);
printf " global colormap is sorted? %b\n" sortflag;
printf " bits/pixel %d\n" (bps+1);
printf " background color index %d\n" bg;
printf " aspect ratio %d\n" aspectratio

| {|_|} ->
eprintf "%s: Not a GIF image\n" filename
| {| ("GIF87a"|"GIF89a") : 6*8 : string (* GIF magic. *)
; width : 16 : littleendian
; height : 16 : littleendian
; colormap : 1 (* Has colormap? *)
; colorbits : 3 (* Color res = colorbits+1 *)
; sortflag : 1
; bps : 3 (* Bits/pixel = bps+1 *)
; bg : 8 (* Background colour. *)
; aspectratio : 8
|}
->
printf "%s: GIF image:\n" filename;
printf " size %d %d\n" width height;
printf " has global colormap? %b\n" colormap;
printf " colorbits %d\n" (colorbits + 1);
printf " global colormap is sorted? %b\n" sortflag;
printf " bits/pixel %d\n" (bps + 1);
printf " background color index %d\n" bg;
printf " aspect ratio %d\n" aspectratio
| {|_|} -> eprintf "%s: Not a GIF image\n" filename
;;
36 changes: 19 additions & 17 deletions examples/ipv4_header.ml
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
(* Parse and display an IPv4 header from a file.
* $Id$
*)
(* Parse and display an IPv4 header from a file. *)

open Printf

let header = Bitstring.bitstring_of_file "ipv4_header.dat"

let () =
match%bitstring header with
| {|version : 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|}
when version = 4 ->

printf "IPv%d:\n" version;
| {| 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 " type of service: %d\n" tos;
printf " packet length: %d bytes\n" length;
Expand All @@ -32,10 +36,8 @@ let () =
Bitstring.hexdump_bitstring stdout options;
printf " packet payload:\n";
Bitstring.hexdump_bitstring stdout payload

| {|version : 4|} ->
eprintf "cannot parse IP version %d\n" version

| {|version : 4|} -> eprintf "cannot parse IP version %d\n" version
| {|_|} as header ->
eprintf "data is smaller than one nibble:\n";
Bitstring.hexdump_bitstring stderr header
;;
Loading