packagecstruct-async
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=4a67bb8f042753453c59eabf0e47865631253ba694091ce6062aac05d47a9bed
sha512=3eeeb6ae0fd3b625cf1d308498f0a1e6951d16566561f3362fdf74e7158d92d8f6c6d9fa968ff15f8c19a1886dce99d0ef17b44dbb37b97cc68c9b088fdc2248
Description
Cstruct is a library and syntax extension to make it easier to access C-likestructures directly from OCaml. It supports both reading and writing to thesestructures, and they are accessed via theBigarray
module.
README
Cstruct -- access C-like structures directly from OCaml
v6.0.1
Cstruct is a library and syntax extension to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these structures, and they are accessed via theBigarray
module.
Installation
This repository provides several packages that can be installed via theopam package manager:
cstruct
: the core Cstruct librarycstruct-sexp
: serialisers into s-expression format of Cstructscstruct-unix
: provide Unix variations of the read/write functions using file descriptorscstruct-async
: provideAsync Pipe and Bigstring supportcstruct-lwt
: provideLwt variants of read/write functionsppx_cstruct
: aPPX syntax extension (see below)
The libraries depend on OCaml version 4.03.0 and later, since it provides appx extension point. The oldcamlp4 syntax extension is nolonger available; the last cstruct release which contained it was v1.9.0.
Local development
You can build the library viadune, usingmake
ordune build
directly. Since everything is built via dune, you can also place this repository within a wider dune workspace in order to make local modifications across repositories.
Usage
PPX
The PPX processor is used by passing the OCaml source code through theppx_cstruct
binary. An example pcap description is:
[%%cstructtype pcap_header = { magic_number: uint32_t; (* magic number *) version_major: uint16_t; (* major version number *) version_minor: uint16_t; (* minor version number *) thiszone: uint32_t; (* GMT to local correction *) sigfigs: uint32_t; (* accuracy of timestamps *) snaplen: uint32_t; (* max length of captured packets, in octets *) network: uint32_t; (* data link type *)} [@@little_endian]][%%cstructtype pcap_packet = { ts_sec: uint32_t; (* timestamp seconds *) ts_usec: uint32_t; (* timestamp microseconds *) incl_len: uint32_t; (* number of octets of packet saved in file *) orig_len: uint32_t; (* actual length of packet *)} [@@little_endian]][%%cstructtype ethernet = { dst: uint8_t [@len 6]; src: uint8_t [@len 6]; ethertype: uint16_t;} [@@big_endian]][%%cstructtype ipv4 = { hlen_version: uint8_t; tos: uint8_t; len: uint16_t; id: uint16_t; off: uint16_t; ttl: uint8_t; proto: uint8_t; csum: uint16_t; src: uint8_t [@len 4]; dst: uint8_t [@len 4];} [@@big_endian]]
This auto-generates generates functions of the form below in theml
file:
let sizeof_pcap_packet = 16let get_pcap_packet_ts_sec v = Cstruct.LE.get_uint32 v 0let set_pcap_packet_ts_sec v x = Cstruct.LE.set_uint32 v 0 xlet get_pcap_packet_ts_usec v = Cstruct.LE.get_uint32 v 4let set_pcap_packet_ts_usec v x = Cstruct.LE.set_uint32 v 4 xlet get_pcap_packet_incl_len v = Cstruct.LE.get_uint32 v 8let set_pcap_packet_incl_len v x = Cstruct.LE.set_uint32 v 8 xlet get_pcap_packet_orig_len v = Cstruct.LE.get_uint32 v 12let set_pcap_packet_orig_len v x = Cstruct.LE.set_uint32 v 12 xlet sizeof_ethernet = 14let get_ethernet_dst src = Cstruct.sub src 0 6let copy_ethernet_dst src = Cstruct.copy src 0 6let set_ethernet_dst src srcoff dst = Cstruct.blit_from_string src srcoff dst 0 6let blit_ethernet_dst src srcoff dst = Cstruct.blit src srcoff dst 0 6let get_ethernet_src src = Cstruct.sub src 6 6let copy_ethernet_src src = Cstruct.copy src 6 6let set_ethernet_src src srcoff dst = Cstruct.blit_from_string src srcoff dst 6 6let blit_ethernet_src src srcoff dst = Cstruct.blit src srcoff dst 6 6let get_ethernet_ethertype v = Cstruct.BE.get_uint16 v 12let set_ethernet_ethertype v x = Cstruct.BE.set_uint16 v 12 x
Themli
file will have signatures of this form:
val sizeof_pcap_packet : intval get_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32val set_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32 -> unitval get_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32val set_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32 -> unitval get_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32val set_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32 -> unitval get_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32val set_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32 -> unitval hexdump_pcap_packet_to_buffer : Buffer.t -> pcap_packet -> unitval hexdump_pcap_packet : Cstruct.t -> unitval sizeof_ethernet : intval get_ethernet_dst : Cstruct.t -> Cstruct.tval copy_ethernet_dst : Cstruct.t -> stringval set_ethernet_dst : string -> int -> Cstruct.t -> unitval blit_ethernet_dst : Cstruct.t -> int -> Cstruct.t -> unitval get_ethernet_src : Cstruct.t -> Cstruct.tval copy_ethernet_src : Cstruct.t -> stringval set_ethernet_src : string -> int -> Cstruct.t -> unitval blit_ethernet_src : Cstruct.t -> int -> Cstruct.t -> unitval get_ethernet_ethertype : Cstruct.t -> Cstruct.uint16val set_ethernet_ethertype : Cstruct.t -> Cstruct.uint16 -> unitval hexdump_ethernet_to_buffer : Buffer.t -> Cstruct.t -> unitval hexdump_ethernet : Cstruct.t -> unit
Thehexdump
functions above are convenient pretty-printing functions to help you debug, and aren't intended to be high performance.
You can also declare C-like enums:
[%%cenumtype foo32 = | ONE32 | TWO32 [@id 0xfffffffel] | THREE32 [@@uint32_t]][%%cenumtype bar16 = | ONE [@id 1] | TWO | FOUR [@id 4] | FIVE [@@uint16_t]]
This generates signatures of the form:
type foo32 = | ONE32 | TWO32 | THREE32val int_to_foo32 : int32 -> foo32 optionval foo32_to_int : foo32 -> int32val foo32_to_string : foo32 -> stringval string_to_foo32 : string -> foo32 optionval compare_foo32 : foo32 -> foo32 -> inttype bar16 = | ONE | TWO | FOUR | FIVEval int_to_bar16 : int -> bar16 optionval bar16_to_int : bar16 -> intval bar16_to_string : bar16 -> stringval string_to_bar16 : string -> bar16 optionval compare_bar16 : bar16 -> bar16 -> int
Comparisons will be done relatively to the constructor ids.
You can also add a(sexp)
decorator to output s-expression convertors for use with thesexplib
library.
[%%cenumtype foo64 = | ONE64 | TWO64 | THREE64 [@@uint64_t] [@@sexp]]
Andsexp_of_foo64
andfoo64_of_sexp
functions will also be available. The representation of the Sexp is the string representation of the enum.
If you do use the sexp decorator, then you will also need to addsexplib
to the dependency list for your package (both in thedune
file and theopam
file).
Please see theppx_test/
directory for more in-depth examples.
Dependencies (6)
- cstruct
= version
- core_kernel
>= "v0.9.0"
- async_unix
>= "v0.9.0"
- async_kernel
>= "v0.9.0"
- dune
>= "2.0.0"
- ocaml
>= "4.03.0"
Dev Dependencies
None
Used by (1)
Conflicts
None