diff --git a/src/icmp/dune b/src/icmp/dune index 96ef347cb..f6207dfa9 100644 --- a/src/icmp/dune +++ b/src/icmp/dune @@ -4,6 +4,4 @@ (instrumentation (backend bisect_ppx)) (libraries logs tcpip ipaddr tcpip.checksum) - (preprocess - (pps ppx_cstruct)) (wrapped false)) diff --git a/src/icmp/icmpv4.ml b/src/icmp/icmpv4.ml index 44e88dfb8..5fa9c77ae 100644 --- a/src/icmp/icmpv4.ml +++ b/src/icmp/icmpv4.ml @@ -48,7 +48,6 @@ module Make (IP : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t) = struct f "ICMP: error parsing message from %a: %s" Ipaddr.V4.pp src s); Lwt.return_unit | Ok (message, payload) -> - let open Icmpv4_wire in match message.ty, message.subheader with | Echo_reply, _ -> Log.info (fun f -> @@ -65,7 +64,7 @@ module Make (IP : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t) = struct if t.echo_reply then begin let icmp = { code = 0x00; - ty = Icmpv4_wire.Echo_reply; + ty = Echo_reply; subheader = Id_and_seq (id, seq); } in writev t ~dst:src [ Marshal.make_cstruct icmp ~payload; payload ] @@ -77,7 +76,7 @@ module Make (IP : Tcpip.Ip.S with type ipaddr = Ipaddr.V4.t) = struct | ty, _ -> Log.info (fun f -> f "ICMP unknown ty %s from %a" - (ty_to_string ty) Ipaddr.V4.pp src); + (Icmpv4_wire.ty_to_string ty) Ipaddr.V4.pp src); Lwt.return_unit end diff --git a/src/icmp/icmpv4_packet.ml b/src/icmp/icmpv4_packet.ml index 12cf9da50..02d254e27 100644 --- a/src/icmp/icmpv4_packet.ml +++ b/src/icmp/icmpv4_packet.ml @@ -23,7 +23,7 @@ let pp fmt t = | Address addr -> say fmt "subheader: ip %a" Ipaddr.V4.pp addr | Unused -> () in - say fmt "ICMP type %s, code %d, subheader [%a]" (Icmpv4_wire.ty_to_string t.ty) + say fmt "ICMP type %s, code %d, subheader [%a]" (ty_to_string t.ty) t.code pp_subheader t.subheader let subheader_eq = function @@ -64,14 +64,14 @@ module Unmarshal = struct Error "packet too short for ICMPv4 header" else Ok () in let check_ty () = - match int_to_ty (get_icmpv4_ty buf) with + match int_to_ty (get_ty buf) with | None -> Error "unrecognized ICMPv4 type" | Some ty -> Ok ty in (* TODO: check checksum as well, and return an error if it's invalid *) let* () = check_len () in let* ty = check_ty () in - let code = get_icmpv4_code buf in + let code = get_code buf in let subheader = subheader_of_cstruct ty (Cstruct.shift buf 4) in let payload = Cstruct.shift buf sizeof_icmpv4 in Ok ({ code; ty; subheader}, payload) @@ -91,15 +91,15 @@ module Marshal = struct | Unused -> set_uint32 buf 0 Int32.zero let unsafe_fill {ty; code; subheader} buf ~payload = - set_icmpv4_ty buf (ty_to_int ty); - set_icmpv4_code buf code; - set_icmpv4_csum buf 0x0000; + set_ty buf (ty_to_int ty); + set_code buf code; + set_checksum buf 0x0000; subheader_into_cstruct ~buf:(Cstruct.shift buf 4) subheader; - let packets = [(Cstruct.sub buf 0 Icmpv4_wire.sizeof_icmpv4); payload] in - set_icmpv4_csum buf (Tcpip_checksum.ones_complement_list packets) + let packets = [(Cstruct.sub buf 0 sizeof_icmpv4); payload] in + set_checksum buf (Tcpip_checksum.ones_complement_list packets) let check_len buf = - if Cstruct.length buf < Icmpv4_wire.sizeof_icmpv4 then + if Cstruct.length buf < sizeof_icmpv4 then Error "Not enough space for ICMP header" else Ok () @@ -109,7 +109,7 @@ module Marshal = struct Ok () let make_cstruct t ~payload = - let buf = Cstruct.create Icmpv4_wire.sizeof_icmpv4 in + let buf = Cstruct.create sizeof_icmpv4 in unsafe_fill t buf ~payload; buf end diff --git a/src/icmp/icmpv4_wire.ml b/src/icmp/icmpv4_wire.ml index 8954990a7..4092696b8 100644 --- a/src/icmp/icmpv4_wire.ml +++ b/src/icmp/icmpv4_wire.ml @@ -1,32 +1,58 @@ -[%%cstruct - type icmpv4 = { - ty: uint8_t; - code: uint8_t; - csum: uint16_t; - id: uint16_t; - seq: uint16_t; - } [@@big_endian] -] - -[%%cenum type ty = - | Echo_reply [@id 0] - | Destination_unreachable [@id 3] + | Echo_reply + | Destination_unreachable | Source_quench | Redirect - | Echo_request [@id 8] - | Time_exceeded [@id 11] + | Echo_request + | Time_exceeded | Parameter_problem | Timestamp_request | Timestamp_reply | Information_request | Information_reply - [@@uint8_t] -] -[%%cenum +let ty_to_string = function + | Echo_reply -> "echo reply" + | Destination_unreachable -> "destination unreachable" + | Source_quench -> "source quench" + | Redirect -> "redirect" + | Echo_request -> "echo request" + | Time_exceeded -> "time exceeded" + | Parameter_problem -> "parameter problem" + | Timestamp_request -> "timestamp request" + | Timestamp_reply -> "timestamp reply" + | Information_request -> "information request" + | Information_reply -> "information reply" + +let int_to_ty = function + | 0 -> Some Echo_reply + | 3 -> Some Destination_unreachable + | 4 -> Some Source_quench + | 5 -> Some Redirect + | 8 -> Some Echo_request + | 11 -> Some Time_exceeded + | 12 -> Some Parameter_problem + | 13 -> Some Timestamp_request + | 14 -> Some Timestamp_reply + | 15 -> Some Information_request + | 16 -> Some Information_reply + | _ -> None + +let ty_to_int = function + | Echo_reply -> 0 + | Destination_unreachable -> 3 + | Source_quench -> 4 + | Redirect -> 5 + | Echo_request -> 8 + | Time_exceeded -> 11 + | Parameter_problem -> 12 + | Timestamp_request -> 13 + | Timestamp_reply -> 14 + | Information_request -> 15 + | Information_reply -> 16 + type unreachable_reason = - | Network_unreachable [@id 0] + | Network_unreachable | Host_unreachable | Protocol_unreachable | Port_unreachable @@ -41,6 +67,37 @@ type unreachable_reason = | TOS_host_unreachable | Communication_prohibited | Host_precedence_violation - | Precedence_insufficient [@id 15] - [@@uint8_t] -] + | Precedence_insufficient + +let unreachable_reason_to_int = function + | Network_unreachable -> 0 + | Host_unreachable -> 1 + | Protocol_unreachable -> 2 + | Port_unreachable -> 3 + | Would_fragment -> 4 + | Source_route_failed -> 5 + | Destination_network_unknown -> 6 + | Destination_host_unknown -> 7 + | Source_host_isolated -> 8 + | Destination_net_prohibited -> 9 + | Destination_host_prohibited -> 10 + | TOS_network_unreachable -> 11 + | TOS_host_unreachable -> 12 + | Communication_prohibited -> 13 + | Host_precedence_violation -> 14 + | Precedence_insufficient -> 15 + +let sizeof_icmpv4 = 8 + +let ty_off = 0 +let code_off = 1 +let csum_off = 2 + +let get_ty buf = Cstruct.get_uint8 buf ty_off +let set_ty buf value = Cstruct.set_uint8 buf ty_off value + +let get_code buf = Cstruct.get_uint8 buf code_off +let set_code buf value = Cstruct.set_uint8 buf code_off value + +let get_checksum buf = Cstruct.BE.get_uint16 buf csum_off +let set_checksum buf value = Cstruct.BE.set_uint16 buf csum_off value diff --git a/src/icmp/icmpv4_wire.mli b/src/icmp/icmpv4_wire.mli new file mode 100644 index 000000000..fb4f34a4c --- /dev/null +++ b/src/icmp/icmpv4_wire.mli @@ -0,0 +1,47 @@ +type ty = + | Echo_reply + | Destination_unreachable + | Source_quench + | Redirect + | Echo_request + | Time_exceeded + | Parameter_problem + | Timestamp_request + | Timestamp_reply + | Information_request + | Information_reply + +val ty_to_string : ty -> string +val int_to_ty : int -> ty option +val ty_to_int : ty -> int + +type unreachable_reason = + | Network_unreachable + | Host_unreachable + | Protocol_unreachable + | Port_unreachable + | Would_fragment + | Source_route_failed + | Destination_network_unknown + | Destination_host_unknown + | Source_host_isolated + | Destination_net_prohibited + | Destination_host_prohibited + | TOS_network_unreachable + | TOS_host_unreachable + | Communication_prohibited + | Host_precedence_violation + | Precedence_insufficient + +val unreachable_reason_to_int : unreachable_reason -> int + +val sizeof_icmpv4 : int + +val get_ty : Cstruct.t -> int +val set_ty : Cstruct.t -> int -> unit + +val get_code : Cstruct.t -> int +val set_code : Cstruct.t -> int -> unit + +val get_checksum : Cstruct.t -> int +val set_checksum : Cstruct.t -> int -> unit diff --git a/src/ipv4/dune b/src/ipv4/dune index a9e0da5b8..2a70bb3f2 100644 --- a/src/ipv4/dune +++ b/src/ipv4/dune @@ -5,6 +5,4 @@ (backend bisect_ppx)) (libraries logs ipaddr cstruct tcpip tcpip.udp tcpip.checksum mirage-random mirage-clock randomconv lru arp.mirage ethernet) - (preprocess - (pps ppx_cstruct)) (wrapped false)) diff --git a/src/ipv4/fragments.ml b/src/ipv4/fragments.ml index 29250b7c3..0477a6a85 100644 --- a/src/ipv4/fragments.ml +++ b/src/ipv4/fragments.ml @@ -196,7 +196,7 @@ let fragment ~mtu hdr payload = if more then Cstruct.split payload data_size else payload, Cstruct.empty in let payload_len = Cstruct.length this_payload in - Ipv4_wire.set_ipv4_csum hdr_buf 0; + Ipv4_wire.set_checksum hdr_buf 0; (match Ipv4_packet.Marshal.into_cstruct ~payload_len hdr' hdr_buf with (* hdr_buf is allocated with hdr_size (computed below) bytes, thus into_cstruct will never return an error! *) diff --git a/src/ipv4/ipv4_common.ml b/src/ipv4/ipv4_common.ml deleted file mode 100644 index a2a90a1bf..000000000 --- a/src/ipv4/ipv4_common.ml +++ /dev/null @@ -1,6 +0,0 @@ -let set_checksum buf = - let open Ipv4_wire in - (* Set the mutable values in the ipv4 header *) - set_ipv4_csum buf 0; - let checksum = Tcpip_checksum.ones_complement buf in - set_ipv4_csum buf checksum diff --git a/src/ipv4/ipv4_packet.ml b/src/ipv4/ipv4_packet.ml index ff3ccc313..6911df9fd 100644 --- a/src/ipv4/ipv4_packet.ml +++ b/src/ipv4/ipv4_packet.ml @@ -54,17 +54,17 @@ module Marshal = struct | k -> (4 - k) + n in let options_len = nearest_4 @@ Cstruct.length t.options in - set_ipv4_hlen_version buf ((4 lsl 4) + 5 + (options_len / 4)); - set_ipv4_id buf t.id; - set_ipv4_off buf t.off; - set_ipv4_ttl buf t.ttl; - set_ipv4_proto buf t.proto; - set_ipv4_src buf (Ipaddr.V4.to_int32 t.src); - set_ipv4_dst buf (Ipaddr.V4.to_int32 t.dst); + set_hlen_version buf ((4 lsl 4) + 5 + (options_len / 4)); + set_id buf t.id; + set_off buf t.off; + set_ttl buf t.ttl; + set_proto buf t.proto; + set_src buf t.src; + set_dst buf t.dst; Cstruct.blit t.options 0 buf sizeof_ipv4 (Cstruct.length t.options); - set_ipv4_len buf (sizeof_ipv4 + options_len + payload_len); + set_len buf (sizeof_ipv4 + options_len + payload_len); let checksum = Tcpip_checksum.ones_complement @@ Cstruct.sub buf 0 (20 + options_len) in - set_ipv4_csum buf checksum + set_checksum buf checksum let into_cstruct ~payload_len t buf = @@ -99,7 +99,7 @@ module Unmarshal = struct let open Ipv4_wire in let check_version buf = let version n = (n land 0xf0) in - match get_ipv4_hlen_version buf |> version with + match get_hlen_version buf |> version with | 0x40 -> Ok () | n -> Error (Printf.sprintf "IPv4 presented with a packet that claims a different IP version: %x" n) in @@ -109,28 +109,29 @@ module Unmarshal = struct in let get_header_length buf = let length_of_hlen_version n = (n land 0x0f) * 4 in - let hlen = get_ipv4_hlen_version buf |> length_of_hlen_version in - if (get_ipv4_len buf) < sizeof_ipv4 then - Error (Printf.sprintf - "total length %d is smaller than minimum header length" - (get_ipv4_len buf)) - else if get_ipv4_len buf < hlen then - Error (Printf.sprintf - "total length %d is smaller than stated header length %d" - (get_ipv4_len buf) hlen) - else if hlen < sizeof_ipv4 then - Error (Printf.sprintf "IPv4 header claimed to have size < 20: %d" hlen) - else if Cstruct.length buf < hlen then - Error (Printf.sprintf "IPv4 packet w/length %d claimed to have header of size %d" (Cstruct.length buf) hlen) - else Ok hlen + let hlen = get_hlen_version buf |> length_of_hlen_version in + let len = get_len buf in + if len < sizeof_ipv4 then + Error (Printf.sprintf + "total length %d is smaller than minimum header length" len) + else if len < hlen then + Error (Printf.sprintf + "total length %d is smaller than stated header length %d" + len hlen) + else if hlen < sizeof_ipv4 then + Error (Printf.sprintf "IPv4 header claimed to have size < 20: %d" hlen) + else if Cstruct.length buf < hlen then + Error (Printf.sprintf "IPv4 packet w/length %d claimed to have header of size %d" (Cstruct.length buf) hlen) + else Ok hlen in let parse buf options_end = - let src = Ipaddr.V4.of_int32 (get_ipv4_src buf) in - let dst = Ipaddr.V4.of_int32 (get_ipv4_dst buf) in - let id = get_ipv4_id buf in - let off = get_ipv4_off buf in - let ttl = get_ipv4_ttl buf in - let proto = get_ipv4_proto buf in + let src = get_src buf + and dst = get_dst buf + and id = get_id buf + and off = get_off buf + and ttl = get_ttl buf + and proto = get_proto buf + in let options = if options_end > sizeof_ipv4 then (Cstruct.sub buf sizeof_ipv4 (options_end - sizeof_ipv4)) else (Cstruct.create 0) @@ -143,9 +144,8 @@ module Unmarshal = struct parse buf hl let of_cstruct buf = - let open Ipv4_wire in let parse buf options_end = - let payload_len = (get_ipv4_len buf) - options_end in + let payload_len = Ipv4_wire.get_len buf - options_end in let payload_available = Cstruct.length buf - options_end in if payload_available < payload_len then ( Error (Printf.sprintf "Payload buffer (%d bytes) too small to contain payload (of size %d from header)" payload_available payload_len) @@ -172,7 +172,7 @@ module Unmarshal = struct | `TCP -> (* checksum isn't optional in tcp, but pkt must be long enough *) check ipv4_header ~proto (Cstruct.length transport_packet) | `UDP -> - match Udp_wire.get_udp_checksum transport_packet with + match Udp_wire.get_checksum transport_packet with | n when (=) 0 @@ compare n 0x0000 -> true (* no checksum supplied, so the check trivially passes *) | _ -> check ipv4_header ~proto (Cstruct.length transport_packet) diff --git a/src/ipv4/ipv4_wire.ml b/src/ipv4/ipv4_wire.ml index e0621e278..495505b85 100644 --- a/src/ipv4/ipv4_wire.ml +++ b/src/ipv4/ipv4_wire.ml @@ -1,14 +1,39 @@ -[%%cstruct -type 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: uint32_t; - dst: uint32_t; - } [@@big_endian] -] +let sizeof_ipv4 = 20 + +let hlen_version_off = 0 +let _tos_off = 1 +let len_off = 2 +let id_off = 4 +let off_off = 6 +let ttl_off = 8 +let proto_off = 9 +let csum_off = 10 +let src_off = 12 +let dst_off = 16 + +let get_hlen_version buf = Cstruct.get_uint8 buf hlen_version_off +let set_hlen_version buf v = Cstruct.set_uint8 buf hlen_version_off v + +let get_len buf = Cstruct.BE.get_uint16 buf len_off +let set_len buf v = Cstruct.BE.set_uint16 buf len_off v + +let get_id buf = Cstruct.BE.get_uint16 buf id_off +let set_id buf v = Cstruct.BE.set_uint16 buf id_off v + +let get_off buf = Cstruct.BE.get_uint16 buf off_off +let set_off buf v = Cstruct.BE.set_uint16 buf off_off v + +let get_ttl buf = Cstruct.get_uint8 buf ttl_off +let set_ttl buf v = Cstruct.set_uint8 buf ttl_off v + +let get_proto buf = Cstruct.get_uint8 buf proto_off +let set_proto buf v = Cstruct.set_uint8 buf proto_off v + +let get_checksum buf = Cstruct.BE.get_uint16 buf csum_off +let set_checksum buf value = Cstruct.BE.set_uint16 buf csum_off value + +let get_src buf = Ipaddr.V4.of_int32 (Cstruct.BE.get_uint32 buf src_off) +let set_src buf v = Cstruct.BE.set_uint32 buf src_off (Ipaddr.V4.to_int32 v) + +let get_dst buf = Ipaddr.V4.of_int32 (Cstruct.BE.get_uint32 buf dst_off) +let set_dst buf v = Cstruct.BE.set_uint32 buf dst_off (Ipaddr.V4.to_int32 v) diff --git a/src/ipv4/ipv4_wire.mli b/src/ipv4/ipv4_wire.mli new file mode 100644 index 000000000..df055d7f8 --- /dev/null +++ b/src/ipv4/ipv4_wire.mli @@ -0,0 +1,28 @@ +val sizeof_ipv4 : int + +val get_hlen_version : Cstruct.t -> int +val set_hlen_version : Cstruct.t -> int -> unit + +val get_len : Cstruct.t -> int +val set_len : Cstruct.t -> int -> unit + +val get_id : Cstruct.t -> int +val set_id : Cstruct.t -> int -> unit + +val get_off : Cstruct.t -> int +val set_off : Cstruct.t -> int -> unit + +val get_ttl : Cstruct.t -> int +val set_ttl : Cstruct.t -> int -> unit + +val get_proto : Cstruct.t -> int +val set_proto : Cstruct.t -> int -> unit + +val get_checksum : Cstruct.t -> int +val set_checksum : Cstruct.t -> int -> unit + +val get_src : Cstruct.t -> Ipaddr.V4.t +val set_src : Cstruct.t -> Ipaddr.V4.t -> unit + +val get_dst : Cstruct.t -> Ipaddr.V4.t +val set_dst : Cstruct.t -> Ipaddr.V4.t -> unit diff --git a/src/ipv6/dune b/src/ipv6/dune index 07ac59394..792cc2149 100644 --- a/src/ipv6/dune +++ b/src/ipv6/dune @@ -5,7 +5,5 @@ (backend bisect_ppx)) (libraries logs mirage-time mirage-net macaddr-cstruct tcpip.checksum mirage-clock duration ipaddr cstruct mirage-random tcpip randomconv - ethernet) - (preprocess - (pps ppx_cstruct)) + ethernet ipaddr-cstruct) (wrapped false)) diff --git a/src/ipv6/ipv6.ml b/src/ipv6/ipv6.ml index 2887a8c8b..c05a95a3b 100644 --- a/src/ipv6/ipv6.ml +++ b/src/ipv6/ipv6.ml @@ -117,8 +117,8 @@ module Make (N : Mirage_net.S) let pseudoheader t ?src:source dst proto len = let ph = Cstruct.create (16 + 16 + 8) in let src = match source with None -> src t ~dst | Some x -> x in - Ndpv6.ipaddr_to_cstruct_raw src ph 0; - Ndpv6.ipaddr_to_cstruct_raw dst ph 16; + Ipv6_wire.set_ip ph 0 src; + Ipv6_wire.set_ip ph 16 dst; Cstruct.BE.set_uint32 ph 32 (Int32.of_int len); Cstruct.set_uint8 ph 36 0; Cstruct.set_uint8 ph 37 0; diff --git a/src/ipv6/ipv6_wire.ml b/src/ipv6/ipv6_wire.ml index 6624611c9..b3d9ad013 100644 --- a/src/ipv6/ipv6_wire.ml +++ b/src/ipv6/ipv6_wire.ml @@ -1,14 +1,4 @@ - -[%%cstruct -type ipv6 = { - version_flow: uint32_t; - len: uint16_t; (* payload length (includes extensions) *) - nhdr: uint8_t; (* next header *) - hlim: uint8_t; (* hop limit *) - src: uint8_t [@len 16]; - dst: uint8_t [@len 16]; - } [@@big_endian] -] +let sizeof_ipv6 = 40 let int_to_protocol = function | 58 -> Some `ICMP @@ -21,112 +11,197 @@ let protocol_to_int = function | `TCP -> 6 | `UDP -> 17 -[%%cstruct -type icmpv6 = { - ty: uint8_t; - code: uint8_t; - csum: uint16_t; - reserved: uint32_t; - } [@@big_endian] -] - -[%%cstruct -type pingv6 = { - ty: uint8_t; - code: uint8_t; - csum: uint16_t; - id: uint16_t; - seq: uint16_t; - } [@@big_endian] -] -[%%cstruct -type ns = { - ty: uint8_t; - code: uint8_t; - csum: uint16_t; - reserved: uint32_t; - target: uint8_t [@len 16]; - } [@@big_endian] -] -[%%cstruct -type na = { - ty: uint8_t; - code: uint8_t; - csum: uint16_t; - reserved: uint32_t; - target: uint8_t [@len 16]; - } [@@big_endian] -] -let get_na_router buf = - (Cstruct.get_uint8 buf 4 land 0x80) <> 0 - -let get_na_solicited buf = - (Cstruct.get_uint8 buf 4 land 0x40) <> 0 - -let get_na_override buf = - (Cstruct.get_uint8 buf 4 land 0x20) <> 0 - -[%%cstruct -type redirect = { - ty : uint8_t; - code : uint8_t; - csum : uint16_t; - reserved : uint32_t; - target : uint8_t [@len 16]; - destination : uint8_t [@len 16]; - } [@@big_endian] -] - -[%%cstruct -type rs = { - ty: uint8_t; - code: uint8_t; - csum: uint16_t; - reserved: uint32_t; - } [@@big_endian] -] -[%%cstruct -type opt_prefix = { - ty: uint8_t; - len: uint8_t; - prefix_len: uint8_t; - reserved1: uint8_t; - valid_lifetime: uint32_t; - preferred_lifetime: uint32_t; - reserved2: uint32_t; - prefix: uint8_t [@len 16]; - } [@@big_endian] -] -let get_opt_prefix_on_link buf = - get_opt_prefix_reserved1 buf land 0x80 <> 0 - -let get_opt_prefix_autonomous buf = - get_opt_prefix_reserved1 buf land 0x40 <> 0 - -[%%cstruct -type opt = { - ty: uint8_t; - len: uint8_t; - } [@@big_endian] -] -[%%cstruct -type llopt = { - ty: uint8_t; - len: uint8_t; - addr: uint8_t [@len 6]; - } [@@big_endian] -] - -[%%cstruct -type ra = { - ty: uint8_t; - code: uint8_t; - csum: uint16_t; - cur_hop_limit: uint8_t; - reserved: uint8_t; - router_lifetime: uint16_t; - reachable_time: uint32_t; - retrans_timer: uint32_t; - } [@@big_endian] -] -let sizeof_ipv6_pseudo_header = 16 + 16 + 4 + 4 +let set_ip buf off v = + Ipaddr_cstruct.V6.write_cstruct_exn v (Cstruct.shift buf off) +let get_ip buf off = + Ipaddr_cstruct.V6.of_cstruct_exn (Cstruct.shift buf off) + +let version_flow_off = 0 +let len_off = 4 +let nhdr_off = 6 +let hlim_off = 7 +let src_off = 8 +let dst_off = 24 + +let get_version_flow buf = Cstruct.BE.get_uint32 buf version_flow_off +let set_version_flow buf v = Cstruct.BE.set_uint32 buf version_flow_off v + +let get_nhdr buf = Cstruct.get_uint8 buf nhdr_off +let set_nhdr buf v = Cstruct.set_uint8 buf nhdr_off v + +let get_len buf = Cstruct.BE.get_uint16 buf len_off +let set_len buf v = Cstruct.BE.set_uint16 buf len_off v + +let get_hlim buf = Cstruct.get_uint8 buf hlim_off +let set_hlim buf v = Cstruct.set_uint8 buf hlim_off v + +let get_src buf = get_ip buf src_off +let set_src buf v = set_ip buf src_off v + +let get_dst buf = get_ip buf dst_off +let set_dst buf v = set_ip buf dst_off v + +let ty_off = 0 +let get_ty buf = Cstruct.get_uint8 buf ty_off +let set_ty buf v = Cstruct.set_uint8 buf ty_off v + +let code_off = 1 +let get_code buf = Cstruct.get_uint8 buf code_off +let set_code buf v = Cstruct.set_uint8 buf code_off v + +module Ns = struct + let sizeof_ns = 24 + + let csum_off = 2 + let reserved_off = 4 + let target_off = 8 + + let get_checksum buf = Cstruct.BE.get_uint16 buf csum_off + let set_checksum buf v = Cstruct.BE.set_uint16 buf csum_off v + let get_reserved buf = Cstruct.BE.get_uint32 buf reserved_off + let set_reserved buf v = Cstruct.BE.set_uint32 buf reserved_off v + let get_target buf = get_ip buf target_off + let set_target buf v = set_ip buf target_off v +end + +module Llopt = struct + let sizeof_llopt = 8 + + let len_off = 1 + let addr_off = 2 + + let get_len buf = Cstruct.get_uint8 buf len_off + let set_len buf v = Cstruct.set_uint8 buf len_off v + + let get_addr buf = Macaddr_cstruct.of_cstruct_exn (Cstruct.shift buf addr_off) + let set_addr buf v = + Macaddr_cstruct.write_cstruct_exn v (Cstruct.shift buf addr_off) +end + +module Icmpv6 = struct + let sizeof_icmpv6 = 8 + + let _reserved_off = 4 + + let set_checksum = Ns.set_checksum +end + +module Na = struct + let sizeof_na = 24 + + let get_reserved = Ns.get_reserved + let set_reserved = Ns.set_reserved + let get_target = Ns.get_target + let set_target = Ns.set_target + + let get_first_reserved_byte buf = + Cstruct.get_uint8 buf Ns.reserved_off + + let get_router buf = (get_first_reserved_byte buf land 0x80) <> 0 + let get_solicited buf = (get_first_reserved_byte buf land 0x40) <> 0 + let get_override buf = (get_first_reserved_byte buf land 0x20) <> 0 +end + +module Rs = struct + let sizeof_rs = 8 + + let set_checksum = Ns.set_checksum + let set_reserved = Ns.set_reserved +end + +module Pingv6 = struct + let sizeof_pingv6 = 8 + + let id_off = 4 + let seq_off = 6 + + let get_checksum = Ns.get_checksum + let set_checksum = Ns.set_checksum + + let get_id buf = Cstruct.BE.get_uint16 buf id_off + let set_id buf v = Cstruct.BE.set_uint16 buf id_off v + + let get_seq buf = Cstruct.BE.set_uint16 buf seq_off + let set_seq buf v = Cstruct.BE.set_uint16 buf seq_off v +end + +module Opt = struct + let sizeof_opt = 2 + + let get_len = Llopt.get_len + let set_len = Llopt.set_len +end + +module Opt_prefix = struct + let sizeof_opt_prefix = 32 + + let get_len = Llopt.get_len + let set_len = Llopt.set_len + + let prefix_len_off = 2 + let get_prefix_len buf = Cstruct.get_uint8 buf prefix_len_off + let set_prefix_len buf v = Cstruct.set_uint8 buf prefix_len_off v + + let reserved1_off = 3 + let get_reserved1 buf = Cstruct.get_uint8 buf reserved1_off + let set_reserved1 buf v = Cstruct.set_uint8 buf reserved1_off v + + let valid_lifetime_off = 4 + let get_valid_lifetime buf = Cstruct.BE.get_uint32 buf valid_lifetime_off + let set_valid_lifetime buf v = Cstruct.BE.set_uint32 buf valid_lifetime_off v + + let preferred_lifetime_off = 8 + let get_preferred_lifetime buf = Cstruct.BE.get_uint32 buf preferred_lifetime_off + let set_preferred_lifetime buf v = Cstruct.BE.set_uint32 buf preferred_lifetime_off v + + let reserved2_off = 12 + + let prefix_off = 16 + let get_prefix buf = get_ip buf prefix_off + let set_prefix buf v = set_ip buf prefix_off v + + let on_link buf = get_reserved1 buf land 0x80 <> 0 + + let autonomous buf = get_reserved1 buf land 0x40 <> 0 + +end + +module Ra = struct + let sizeof_ra = 16 + + let get_checksum = Ns.get_checksum + let set_checksum = Ns.set_checksum + + let cur_hop_limit_off = 4 + let get_cur_hop_limit buf = Cstruct.get_uint8 buf cur_hop_limit_off + + let reserved_off = 5 + + let router_lifetime_off = 6 + let get_router_lifetime buf = Cstruct.BE.get_uint16 buf router_lifetime_off + + let reachable_time_off = 8 + let get_reachable_time buf = Cstruct.BE.get_uint32 buf reachable_time_off + + let retrans_timer_off = 12 + let get_retrans_timer buf = Cstruct.BE.get_uint32 buf retrans_timer_off +end + +module Redirect = struct + let sizeof_redirect = 40 + + let get_checksum = Ns.get_checksum + let set_checksum = Ns.set_checksum + + let get_reserved = Ns.get_reserved + let set_reserved = Ns.set_reserved + + let get_target = Ns.get_target + let set_target = Ns.set_target + + let destination_off = 24 + let get_destination buf = get_ip buf destination_off + let set_destination buf v = set_ip buf destination_off v +end + +(* let sizeof_ipv6_pseudo_header = 16 + 16 + 4 + 4 *) diff --git a/src/ipv6/ndpv6.ml b/src/ipv6/ndpv6.ml index ad5b5152e..72608a0a4 100644 --- a/src/ipv6/ndpv6.ml +++ b/src/ipv6/ndpv6.ml @@ -95,23 +95,6 @@ module Defaults = struct let retrans_timer = Duration.of_sec 1 end -let ipaddr_of_cstruct cs = - let hihi = Cstruct.BE.get_uint32 cs 0 in - let hilo = Cstruct.BE.get_uint32 cs 4 in - let lohi = Cstruct.BE.get_uint32 cs 8 in - let lolo = Cstruct.BE.get_uint32 cs 12 in - Ipaddr.of_int32 (hihi, hilo, lohi, lolo) - -let ipaddr_to_cstruct_raw i cs off = - let a, b, c, d = Ipaddr.to_int32 i in - Cstruct.BE.set_uint32 cs (0 + off) a; - Cstruct.BE.set_uint32 cs (4 + off) b; - Cstruct.BE.set_uint32 cs (8 + off) c; - Cstruct.BE.set_uint32 cs (12 + off) d - -let macaddr_to_cstruct_raw x cs off = - Cstruct.blit_from_string (Macaddr.to_octets x) 0 cs off 6 - let interface_addr mac = let bmac = Macaddr.to_octets mac in let c i = Char.code (String.get bmac i) in @@ -150,19 +133,19 @@ let checksum' ~proto frame bufs = Tcpip_checksum.ones_complement_list (src_dst :: cksum_buf :: bufs) let checksum frame bufs = - let proto = Ipv6_wire.get_ipv6_nhdr frame in + let proto = Ipv6_wire.get_nhdr frame in checksum' ~proto frame bufs module Allocate = struct let hdr ~hlim ~src ~dst ~proto ~size fillf = let size' = size + Ipv6_wire.sizeof_ipv6 in let fill ipbuf = - Ipv6_wire.set_ipv6_version_flow ipbuf 0x60000000l; (* IPv6 *) - Ipv6_wire.set_ipv6_len ipbuf size; - ipaddr_to_cstruct_raw src (Ipv6_wire.get_ipv6_src ipbuf) 0; - ipaddr_to_cstruct_raw dst (Ipv6_wire.get_ipv6_dst ipbuf) 0; - Ipv6_wire.set_ipv6_hlim ipbuf hlim; - Ipv6_wire.set_ipv6_nhdr ipbuf (Ipv6_wire.protocol_to_int proto); + Ipv6_wire.set_version_flow ipbuf 0x60000000l; (* IPv6 *) + Ipv6_wire.set_len ipbuf size; + Ipv6_wire.set_src ipbuf src; + Ipv6_wire.set_dst ipbuf dst; + Ipv6_wire.set_hlim ipbuf hlim; + Ipv6_wire.set_nhdr ipbuf (Ipv6_wire.protocol_to_int proto); let hdr, payload = Cstruct.split ipbuf Ipv6_wire.sizeof_ipv6 in let len' = fillf hdr payload in len' + Ipv6_wire.sizeof_ipv6 @@ -170,37 +153,37 @@ module Allocate = struct (size', fill) let ns ~specified ~mac ~src ~dst ~tgt = - let size = Ipv6_wire.sizeof_ns + if specified then Ipv6_wire.sizeof_llopt else 0 in + let size = Ipv6_wire.Ns.sizeof_ns + if specified then Ipv6_wire.Llopt.sizeof_llopt else 0 in let fillf hdr icmpbuf = - let optbuf = Cstruct.shift icmpbuf Ipv6_wire.sizeof_ns in - Ipv6_wire.set_ns_ty icmpbuf 135; (* NS *) - Ipv6_wire.set_ns_code icmpbuf 0; - Ipv6_wire.set_ns_reserved icmpbuf 0l; - ipaddr_to_cstruct_raw tgt (Ipv6_wire.get_ns_target icmpbuf) 0; + let optbuf = Cstruct.shift icmpbuf Ipv6_wire.Ns.sizeof_ns in + Ipv6_wire.set_ty icmpbuf 135; (* NS *) + Ipv6_wire.set_code icmpbuf 0; + Ipv6_wire.Ns.set_reserved icmpbuf 0l; + Ipv6_wire.Ns.set_target icmpbuf tgt; if specified then begin - Ipv6_wire.set_llopt_ty optbuf 1; - Ipv6_wire.set_llopt_len optbuf 1; - macaddr_to_cstruct_raw mac optbuf 2; + Ipv6_wire.set_ty optbuf 1; + Ipv6_wire.Llopt.set_len optbuf 1; + Ipv6_wire.Llopt.set_addr optbuf mac; end; - Ipv6_wire.set_icmpv6_csum icmpbuf 0; - Ipv6_wire.set_icmpv6_csum icmpbuf @@ checksum hdr [ icmpbuf ]; + Ipv6_wire.Icmpv6.set_checksum icmpbuf 0; + Ipv6_wire.Icmpv6.set_checksum icmpbuf @@ checksum hdr [ icmpbuf ]; size in hdr ~src ~dst ~hlim:255 ~proto:`ICMP ~size fillf let na ~mac ~src ~dst ~tgt ~sol = - let size = Ipv6_wire.sizeof_na + Ipv6_wire.sizeof_llopt in + let size = Ipv6_wire.Na.sizeof_na + Ipv6_wire.Llopt.sizeof_llopt in let fillf hdr icmpbuf = - let optbuf = Cstruct.shift icmpbuf Ipv6_wire.sizeof_na in - Ipv6_wire.set_na_ty icmpbuf 136; (* NA *) - Ipv6_wire.set_na_code icmpbuf 0; - Ipv6_wire.set_na_reserved icmpbuf (if sol then 0x60000000l else 0x20000000l); - ipaddr_to_cstruct_raw tgt (Ipv6_wire.get_na_target icmpbuf) 0; - Ipv6_wire.set_llopt_ty optbuf 2; - Ipv6_wire.set_llopt_len optbuf 1; - macaddr_to_cstruct_raw mac optbuf 2; - Ipv6_wire.set_icmpv6_csum icmpbuf 0; - Ipv6_wire.set_icmpv6_csum icmpbuf @@ checksum hdr [ icmpbuf ]; + let optbuf = Cstruct.shift icmpbuf Ipv6_wire.Na.sizeof_na in + Ipv6_wire.set_ty icmpbuf 136; (* NA *) + Ipv6_wire.set_code icmpbuf 0; + Ipv6_wire.Na.set_reserved icmpbuf (if sol then 0x60000000l else 0x20000000l); + Ipv6_wire.Na.set_target icmpbuf tgt; + Ipv6_wire.set_ty optbuf 2; + Ipv6_wire.Llopt.set_len optbuf 1; + Ipv6_wire.Llopt.set_addr optbuf mac; + Ipv6_wire.Icmpv6.set_checksum icmpbuf 0; + Ipv6_wire.Icmpv6.set_checksum icmpbuf @@ checksum hdr [ icmpbuf ]; size in hdr ~src ~dst ~hlim:255 ~proto:`ICMP ~size fillf @@ -210,35 +193,35 @@ module Allocate = struct let src = select_source ~dst in let cmp = Ipaddr.compare in let include_slla = (cmp src Ipaddr.unspecified) != 0 in - let slla_len = if include_slla then Ipv6_wire.sizeof_llopt else 0 in - let size = Ipv6_wire.sizeof_rs + slla_len in + let slla_len = if include_slla then Ipv6_wire.Llopt.sizeof_llopt else 0 in + let size = Ipv6_wire.Rs.sizeof_rs + slla_len in let fillf hdr icmpbuf = - Ipv6_wire.set_rs_ty icmpbuf 133; - Ipv6_wire.set_rs_code icmpbuf 0; - Ipv6_wire.set_rs_reserved icmpbuf 0l; + Ipv6_wire.set_ty icmpbuf 133; + Ipv6_wire.set_code icmpbuf 0; + Ipv6_wire.Rs.set_reserved icmpbuf 0l; if include_slla then begin - let optbuf = Cstruct.shift icmpbuf Ipv6_wire.sizeof_rs in - Ipv6_wire.set_llopt_ty optbuf 1; - Ipv6_wire.set_llopt_len optbuf 1; - macaddr_to_cstruct_raw mac optbuf 2 + let optbuf = Cstruct.shift icmpbuf Ipv6_wire.Rs.sizeof_rs in + Ipv6_wire.set_ty optbuf 1; + Ipv6_wire.Llopt.set_len optbuf 1; + Ipv6_wire.Llopt.set_addr optbuf mac end; - Ipv6_wire.set_icmpv6_csum icmpbuf 0; - Ipv6_wire.set_icmpv6_csum icmpbuf @@ checksum hdr [ icmpbuf ]; + Ipv6_wire.Icmpv6.set_checksum icmpbuf 0; + Ipv6_wire.Icmpv6.set_checksum icmpbuf @@ checksum hdr [ icmpbuf ]; size in hdr ~src ~dst ~hlim:255 ~proto:`ICMP ~size fillf let pong ~src ~dst ~hlim ~id ~seq ~data = (* TODO data may exceed size, fragment? *) - let size = Ipv6_wire.sizeof_pingv6 + Cstruct.length data in + let size = Ipv6_wire.Pingv6.sizeof_pingv6 + Cstruct.length data in let fillf hdr icmpbuf = - Ipv6_wire.set_pingv6_ty icmpbuf 129; (* ECHO REPLY *) - Ipv6_wire.set_pingv6_code icmpbuf 0; - Ipv6_wire.set_pingv6_id icmpbuf id; - Ipv6_wire.set_pingv6_seq icmpbuf seq; - Ipv6_wire.set_pingv6_csum icmpbuf 0; - Cstruct.blit data 0 icmpbuf Ipv6_wire.sizeof_pingv6 (Cstruct.length data); - Ipv6_wire.set_pingv6_csum icmpbuf @@ checksum hdr [ icmpbuf ]; + Ipv6_wire.set_ty icmpbuf 129; (* ECHO REPLY *) + Ipv6_wire.set_code icmpbuf 0; + Ipv6_wire.Pingv6.set_id icmpbuf id; + Ipv6_wire.Pingv6.set_seq icmpbuf seq; + Ipv6_wire.Pingv6.set_checksum icmpbuf 0; + Cstruct.blit data 0 icmpbuf Ipv6_wire.Pingv6.sizeof_pingv6 (Cstruct.length data); + Ipv6_wire.Pingv6.set_checksum icmpbuf @@ checksum hdr [ icmpbuf ]; size in hdr ~src ~dst ~hlim ~proto:`ICMP ~size fillf @@ -743,32 +726,32 @@ module Parser = struct | PREFIX of pfx let rec parse_options1 opts = - if Cstruct.length opts >= Ipv6_wire.sizeof_opt then + if Cstruct.length opts >= Ipv6_wire.Opt.sizeof_opt then (* TODO check for invalid len == 0 *) - let opt, opts = Cstruct.split opts (Ipv6_wire.get_opt_len opts * 8) in - match Ipv6_wire.get_opt_ty opt, Ipv6_wire.get_opt_len opt with + let opt, opts = Cstruct.split opts (Ipv6_wire.Opt.get_len opts * 8) in + match Ipv6_wire.get_ty opt, Ipv6_wire.Opt.get_len opt with | 1, 1 -> - SLLA (Macaddr_cstruct.of_cstruct_exn (Ipv6_wire.get_llopt_addr opt)) :: parse_options1 opts + SLLA (Ipv6_wire.Llopt.get_addr opt) :: parse_options1 opts | 2, 1 -> - TLLA (Macaddr_cstruct.of_cstruct_exn (Ipv6_wire.get_llopt_addr opt)) :: parse_options1 opts + TLLA (Ipv6_wire.Llopt.get_addr opt) :: parse_options1 opts | 5, 1 -> MTU (Int32.to_int (Cstruct.BE.get_uint32 opt 4)) :: parse_options1 opts | 3, 4 -> let pfx_prefix = Ipaddr.Prefix.make - (Ipv6_wire.get_opt_prefix_prefix_len opt) - (ipaddr_of_cstruct (Ipv6_wire.get_opt_prefix_prefix opt)) + (Ipv6_wire.Opt_prefix.get_len opt) + (Ipv6_wire.Opt_prefix.get_prefix opt) in - let pfx_on_link = Ipv6_wire.get_opt_prefix_on_link opt in - let pfx_autonomous = Ipv6_wire.get_opt_prefix_autonomous opt in + let pfx_on_link = Ipv6_wire.Opt_prefix.on_link opt in + let pfx_autonomous = Ipv6_wire.Opt_prefix.autonomous opt in let pfx_valid_lifetime = - let n = Ipv6_wire.get_opt_prefix_valid_lifetime opt in + let n = Ipv6_wire.Opt_prefix.get_valid_lifetime opt in match n with | 0xffffffffl -> None | n -> Some (Int64.of_int32 n) in let pfx_preferred_lifetime = - let n = Ipv6_wire.get_opt_prefix_preferred_lifetime opt in + let n = Ipv6_wire.Opt_prefix.get_preferred_lifetime opt in match n with | 0xffffffffl -> None | n -> Some (Int64.of_int32 n) @@ -784,25 +767,25 @@ module Parser = struct [] let parse_ra buf = - let ra_cur_hop_limit = Ipv6_wire.get_ra_cur_hop_limit buf in + let ra_cur_hop_limit = Ipv6_wire.Ra.get_cur_hop_limit buf in let ra_router_lifetime = - Int64.of_int (Ipv6_wire.get_ra_router_lifetime buf) + Int64.of_int (Ipv6_wire.Ra.get_router_lifetime buf) in let ra_reachable_time = - let n = Ipv6_wire.get_ra_reachable_time buf in + let n = Ipv6_wire.Ra.get_reachable_time buf in if n = 0l then None else let dt = Int64.of_int32 @@ Int32.div n 1000l in Some dt in let ra_retrans_timer = - let n = Ipv6_wire.get_ra_retrans_timer buf in + let n = Ipv6_wire.Ra.get_retrans_timer buf in if n = 0l then None else let dt = Int64.of_int32 @@ Int32.div n 1000l in Some dt in - let opts = Cstruct.shift buf Ipv6_wire.sizeof_ra in + let opts = Cstruct.shift buf Ipv6_wire.Ra.sizeof_ra in let ra_slla, ra_prefix = let opts = parse_options1 opts in List.fold_left (fun ra opt -> @@ -816,8 +799,8 @@ module Parser = struct let parse_ns buf = (* FIXME check code = 0 or drop *) - let ns_target = ipaddr_of_cstruct (Ipv6_wire.get_ns_target buf) in - let opts = Cstruct.shift buf Ipv6_wire.sizeof_ns in + let ns_target = Ipv6_wire.Ns.get_target buf in + let opts = Cstruct.shift buf Ipv6_wire.Ns.sizeof_ns in let ns_slla = let opts = parse_options1 opts in List.fold_left (fun ns opt -> @@ -830,12 +813,12 @@ module Parser = struct let parse_na buf = (* FIXME check code = 0 or drop *) - let na_router = Ipv6_wire.get_na_router buf in - let na_solicited = Ipv6_wire.get_na_solicited buf in - let na_override = Ipv6_wire.get_na_override buf in - let na_target = ipaddr_of_cstruct (Ipv6_wire.get_na_target buf) in + let na_router = Ipv6_wire.Na.get_router buf in + let na_solicited = Ipv6_wire.Na.get_solicited buf in + let na_override = Ipv6_wire.Na.get_override buf in + let na_target = Ipv6_wire.Na.get_target buf in let na_tlla = - let opts = Cstruct.shift buf Ipv6_wire.sizeof_na in + let opts = Cstruct.shift buf Ipv6_wire.Na.sizeof_na in let opts = parse_options1 opts in List.fold_left (fun na opt -> match opt with @@ -846,12 +829,12 @@ module Parser = struct {na_router; na_solicited; na_override; na_target; na_tlla} let parse_redirect buf = - let destination = ipaddr_of_cstruct (Ipv6_wire.get_redirect_destination buf) in - let target = ipaddr_of_cstruct (Ipv6_wire.get_redirect_target buf) in + let destination = Ipv6_wire.Redirect.get_destination buf in + let target = Ipv6_wire.Redirect.get_target buf in { target; destination } let dst_unreachable icmpbuf = - match Ipv6_wire.get_icmpv6_code icmpbuf with + match Ipv6_wire.get_code icmpbuf with | 0 -> "No route to destination" | 1 -> "Communication with destination administratively prohibited" | 2 -> "Beyond scope of source address" @@ -863,13 +846,13 @@ module Parser = struct | c -> "Unknown code: " ^ string_of_int c let time_exceeded icmpbuf = - match Ipv6_wire.get_icmpv6_code icmpbuf with + match Ipv6_wire.get_code icmpbuf with | 0 -> "Hop limit exceeded in transit" | 1 -> "Fragment reassembly time exceeded" | c -> "Unknown code: " ^ string_of_int c let parameter_problem icmpbuf = - match Ipv6_wire.get_icmpv6_code icmpbuf with + match Ipv6_wire.get_code icmpbuf with | 0 -> "Erroneous header field encountered" | 1 -> "Unrecognized Next Header type encountered" | 2 -> "Unrocognized IPv6 option encountered" @@ -883,7 +866,7 @@ module Parser = struct Log.info (fun f -> f "ICMP6: Checksum error, dropping packet: csum=0x%x" csum); Drop end else begin - match Ipv6_wire.get_icmpv6_ty icmpbuf with + match Ipv6_wire.get_ty icmpbuf with | 128 -> (* Echo request *) let id = Cstruct.BE.get_uint16 icmpbuf 4 in let seq = Cstruct.BE.get_uint16 icmpbuf 6 in @@ -894,12 +877,12 @@ module Parser = struct (* RFC 4861, 2.6.2 *) Drop | 134 (* RA *) -> - if Ipv6_wire.get_ipv6_hlim buf <> 255 then + if Ipv6_wire.get_hlim buf <> 255 then Drop else RA (src, dst, parse_ra icmpbuf) | 135 (* NS *) -> - if Ipv6_wire.get_ipv6_hlim buf <> 255 then + if Ipv6_wire.get_hlim buf <> 255 then Drop else let ns = parse_ns icmpbuf in @@ -908,7 +891,7 @@ module Parser = struct else NS (src, dst, ns) | 136 (* NA *) -> - if Ipv6_wire.get_ipv6_hlim buf <> 255 then + if Ipv6_wire.get_hlim buf <> 255 then Drop else let na = parse_na icmpbuf in @@ -918,7 +901,7 @@ module Parser = struct else NA (src, dst, na) | 137 (* Redirect *) -> - if Ipv6_wire.get_ipv6_hlim buf <> 255 then + if Ipv6_wire.get_hlim buf <> 255 then Drop else let redirect = parse_redirect icmpbuf in @@ -974,23 +957,23 @@ module Parser = struct and parse_options ~src ~dst buf poff = let pbuf = Cstruct.shift buf poff in - let nhdr = Ipv6_wire.get_opt_ty pbuf in - let olen = Ipv6_wire.get_opt_len pbuf * 8 + 8 in + let nhdr = Ipv6_wire.get_ty pbuf in + let olen = Ipv6_wire.Opt.get_len pbuf * 8 + 8 in let oend = olen + poff in let rec loop ooff = if ooff < oend then begin let obuf = Cstruct.shift buf ooff in - match Ipv6_wire.get_opt_ty obuf with + match Ipv6_wire.get_ty obuf with | 0 -> Log.debug (fun f -> f "IP6: Processing PAD1 option"); loop (ooff+1) | 1 -> Log.debug (fun f -> f "IP6: Processing PADN option"); - let len = Ipv6_wire.get_opt_len obuf in + let len = Ipv6_wire.Opt.get_len obuf in loop (ooff+len+2) | _ as n -> Log.info (fun f -> f "IP6: Processing unknown option, MSB %x" n); - let len = Ipv6_wire.get_opt_len obuf in + let len = Ipv6_wire.Opt.get_len obuf in match n land 0xc0 with | 0x00 -> loop (ooff+len+2) @@ -1014,16 +997,16 @@ module Parser = struct loop (poff+2) let packet is_my_addr buf = - if Cstruct.length buf < Ipv6_wire.sizeof_ipv6 || Cstruct.length buf < Ipv6_wire.sizeof_ipv6 + Ipv6_wire.get_ipv6_len buf then begin + if Cstruct.length buf < Ipv6_wire.sizeof_ipv6 || Cstruct.length buf < Ipv6_wire.sizeof_ipv6 + Ipv6_wire.get_len buf then begin Log.debug (fun m -> m "short IPv6 packet received, dropping"); Drop - end else if Int32.logand (Ipv6_wire.get_ipv6_version_flow buf) 0xF0000000l <> 0x60000000l then begin + end else if Int32.logand (Ipv6_wire.get_version_flow buf) 0xF0000000l <> 0x60000000l then begin Log.debug (fun m -> m "version in IPv6 packet not 6"); Drop end else begin - let buf = Cstruct.sub buf 0 (Ipv6_wire.sizeof_ipv6 + Ipv6_wire.get_ipv6_len buf) in - let src = ipaddr_of_cstruct (Ipv6_wire.get_ipv6_src buf) in - let dst = ipaddr_of_cstruct (Ipv6_wire.get_ipv6_dst buf) in + let buf = Cstruct.sub buf 0 (Ipv6_wire.sizeof_ipv6 + Ipv6_wire.get_len buf) in + let src = Ipv6_wire.get_src buf in + let dst = Ipv6_wire.get_dst buf in if Ipaddr.Prefix.(mem src multicast) then begin Log.debug (fun f -> f "IP6: Dropping packet, src is mcast"); Drop @@ -1033,7 +1016,7 @@ module Parser = struct Drop end else - parse_extension ~src ~dst buf true (Ipv6_wire.get_ipv6_nhdr buf) Ipv6_wire.sizeof_ipv6 + parse_extension ~src ~dst buf true (Ipv6_wire.get_nhdr buf) Ipv6_wire.sizeof_ipv6 end end diff --git a/src/ipv6/ndpv6.mli b/src/ipv6/ndpv6.mli index 8fe3d8fdf..ff40cd174 100644 --- a/src/ipv6/ndpv6.mli +++ b/src/ipv6/ndpv6.mli @@ -19,8 +19,6 @@ type ipaddr = Ipaddr.V6.t type prefix = Ipaddr.V6.Prefix.t type time = int64 -val ipaddr_of_cstruct : buffer -> ipaddr -val ipaddr_to_cstruct_raw : ipaddr -> buffer -> int -> unit val checksum : buffer -> buffer list -> int type event = diff --git a/src/stack-unix/icmpv4_socket.ml b/src/stack-unix/icmpv4_socket.ml index 527edcd11..fada21b37 100644 --- a/src/stack-unix/icmpv4_socket.ml +++ b/src/stack-unix/icmpv4_socket.ml @@ -101,8 +101,8 @@ let listen t addr fn = probably reflects some kernel datastructure size rather than the real on-the-wire size. This confuses our IPv4 parser so we correct the size here. *) - let len = Ipv4_wire.get_ipv4_len receive_buffer in - Ipv4_wire.set_ipv4_len receive_buffer (min len (Cstruct.length receive_buffer)); + let len = Ipv4_wire.get_len receive_buffer in + Ipv4_wire.set_len receive_buffer (min len (Cstruct.length receive_buffer)); Lwt.async (fun () -> fn receive_buffer); loop () in diff --git a/src/tcp/dune b/src/tcp/dune index 4ebec055c..8bf6ad9d1 100644 --- a/src/tcp/dune +++ b/src/tcp/dune @@ -5,6 +5,4 @@ (backend bisect_ppx)) (libraries logs ipaddr cstruct lwt-dllist tcpip.checksum tcpip duration randomconv fmt mirage-time mirage-clock mirage-random - mirage-flow metrics) - (preprocess - (pps ppx_cstruct))) + mirage-flow metrics)) diff --git a/src/tcp/tcp_packet.ml b/src/tcp/tcp_packet.ml index 18e159881..b5a1cda27 100644 --- a/src/tcp/tcp_packet.ml +++ b/src/tcp/tcp_packet.ml @@ -40,7 +40,7 @@ module Unmarshal = struct if Cstruct.length pkt < sizeof_tcp then Error "packet too short to contain a TCP packet of any size" else - Ok (Tcp_wire.get_data_offset pkt) + Ok (get_data_offset pkt) in let long_enough data_offset = if Cstruct.length pkt < data_offset then Error "packet too short to contain a TCP packet of the size claimed" @@ -57,17 +57,17 @@ module Unmarshal = struct let* data_offset = check_len pkt in let* () = long_enough data_offset in let* options = options data_offset pkt in - let sequence = get_tcp_sequence pkt |> Sequence.of_int32 in - let ack_number = get_tcp_ack_number pkt |> Sequence.of_int32 in + let sequence = get_sequence pkt |> Sequence.of_int32 in + let ack_number = get_ack_number pkt |> Sequence.of_int32 in let urg = get_urg pkt in let ack = get_ack pkt in let psh = get_psh pkt in let rst = get_rst pkt in let syn = get_syn pkt in let fin = get_fin pkt in - let window = get_tcp_window pkt in - let src_port = get_tcp_src_port pkt in - let dst_port = get_tcp_dst_port pkt in + let window = get_window pkt in + let src_port = get_src_port pkt in + let dst_port = get_dst_port pkt in let data = Cstruct.shift pkt data_offset in Ok ({ urg; ack; psh; rst; syn; fin; window; options; sequence; ack_number; src_port; dst_port }, data) @@ -80,27 +80,27 @@ module Marshal = struct let unsafe_fill ~pseudoheader ~payload t buf options_len = let data_off = sizeof_tcp + options_len in let buf = Cstruct.sub buf 0 data_off in - set_tcp_src_port buf t.src_port; - set_tcp_dst_port buf t.dst_port; - set_tcp_sequence buf (Sequence.to_int32 t.sequence); - set_tcp_ack_number buf (Sequence.to_int32 t.ack_number); + set_src_port buf t.src_port; + set_dst_port buf t.dst_port; + set_sequence buf (Sequence.to_int32 t.sequence); + set_ack_number buf (Sequence.to_int32 t.ack_number); set_data_offset buf (data_off / 4); - set_tcp_flags buf 0; + set_flags buf 0; if t.urg then set_urg buf; if t.ack then set_ack buf; if t.rst then set_rst buf; if t.syn then set_syn buf; if t.fin then set_fin buf; if t.psh then set_psh buf; - set_tcp_window buf t.window; - set_tcp_checksum buf 0; - set_tcp_urg_ptr buf 0; + set_window buf t.window; + set_checksum buf 0; + set_urg_ptr buf 0; (* it's possible we've been passed a buffer larger than the size of the header, * which contains some data after the end of the header we'll write; * in this case, make sure we compute the checksum properly *) let checksum = Tcpip_checksum.ones_complement_list [pseudoheader ; buf ; payload] in - set_tcp_checksum buf checksum; + set_checksum buf checksum; () let into_cstruct ~pseudoheader ~payload t buf = diff --git a/src/tcp/tcp_wire.ml b/src/tcp/tcp_wire.ml index ac9d6d811..8ef050b18 100644 --- a/src/tcp/tcp_wire.ml +++ b/src/tcp/tcp_wire.ml @@ -1,55 +1,67 @@ -[%%cstruct -type tcp = { - src_port: uint16_t; - dst_port: uint16_t; - sequence: uint32_t; - ack_number: uint32_t; - dataoff: uint8_t; - flags: uint8_t; - window: uint16_t; - checksum: uint16_t; - urg_ptr: uint16_t; - } [@@big_endian] -] - -[%%cstruct -type tcpv4_pseudo_header = { - src: uint32_t; - dst: uint32_t; - res: uint8_t; - proto: uint8_t; - len: uint16_t; - } [@@big_endian] -] +let sizeof_tcp = 20 + +let src_port_off = 0 +let dst_port_off = 2 +let sequence_off = 4 +let ack_off = 8 +let dataoff_off = 12 +let flags_off = 13 +let window_off = 14 +let checksum_off = 16 +let urg_ptr_off = 18 + +let get_src_port buf = Cstruct.BE.get_uint16 buf src_port_off +let set_src_port buf v = Cstruct.BE.set_uint16 buf src_port_off v + +let get_dst_port buf = Cstruct.BE.get_uint16 buf dst_port_off +let set_dst_port buf v = Cstruct.BE.set_uint16 buf dst_port_off v + +let get_sequence buf = Cstruct.BE.get_uint32 buf sequence_off +let set_sequence buf v = Cstruct.BE.set_uint32 buf sequence_off v + +let get_ack_number buf = Cstruct.BE.get_uint32 buf ack_off +let set_ack_number buf v = Cstruct.BE.set_uint32 buf ack_off v + +let get_flags buf = Cstruct.get_uint8 buf flags_off +let set_flags buf v = Cstruct.set_uint8 buf flags_off v + +let get_window buf = Cstruct.BE.get_uint16 buf window_off +let set_window buf v = Cstruct.BE.set_uint16 buf window_off v + +let get_checksum buf = Cstruct.BE.get_uint16 buf checksum_off +let set_checksum buf value = Cstruct.BE.set_uint16 buf checksum_off value + +let get_urg_ptr buf = Cstruct.BE.get_uint16 buf urg_ptr_off +let set_urg_ptr buf value = Cstruct.BE.set_uint16 buf urg_ptr_off value (* XXX note that we overwrite the lower half of dataoff * with 0, so be careful when implemented CWE flag which * sits there *) -let get_data_offset buf = ((get_tcp_dataoff buf) lsr 4) * 4 -let set_data_offset buf v = set_tcp_dataoff buf (v lsl 4) - -let get_fin buf = ((Cstruct.get_uint8 buf 13) land (1 lsl 0)) > 0 -let get_syn buf = ((Cstruct.get_uint8 buf 13) land (1 lsl 1)) > 0 -let get_rst buf = ((Cstruct.get_uint8 buf 13) land (1 lsl 2)) > 0 -let get_psh buf = ((Cstruct.get_uint8 buf 13) land (1 lsl 3)) > 0 -let get_ack buf = ((Cstruct.get_uint8 buf 13) land (1 lsl 4)) > 0 -let get_urg buf = ((Cstruct.get_uint8 buf 13) land (1 lsl 5)) > 0 -let get_ece buf = ((Cstruct.get_uint8 buf 13) land (1 lsl 6)) > 0 -let get_cwr buf = ((Cstruct.get_uint8 buf 13) land (1 lsl 7)) > 0 +let get_data_offset buf = ((Cstruct.get_uint8 buf dataoff_off) lsr 4) * 4 +let set_data_offset buf v = Cstruct.set_uint8 buf dataoff_off (v lsl 4) + +let get_fin buf = ((Cstruct.get_uint8 buf flags_off) land (1 lsl 0)) > 0 +let get_syn buf = ((Cstruct.get_uint8 buf flags_off) land (1 lsl 1)) > 0 +let get_rst buf = ((Cstruct.get_uint8 buf flags_off) land (1 lsl 2)) > 0 +let get_psh buf = ((Cstruct.get_uint8 buf flags_off) land (1 lsl 3)) > 0 +let get_ack buf = ((Cstruct.get_uint8 buf flags_off) land (1 lsl 4)) > 0 +let get_urg buf = ((Cstruct.get_uint8 buf flags_off) land (1 lsl 5)) > 0 +let _get_ece buf = ((Cstruct.get_uint8 buf flags_off) land (1 lsl 6)) > 0 +let _get_cwr buf = ((Cstruct.get_uint8 buf flags_off) land (1 lsl 7)) > 0 let set_fin buf = - Cstruct.set_uint8 buf 13 ((Cstruct.get_uint8 buf 13) lor (1 lsl 0)) + Cstruct.set_uint8 buf flags_off ((Cstruct.get_uint8 buf flags_off) lor (1 lsl 0)) let set_syn buf = - Cstruct.set_uint8 buf 13 ((Cstruct.get_uint8 buf 13) lor (1 lsl 1)) + Cstruct.set_uint8 buf flags_off ((Cstruct.get_uint8 buf flags_off) lor (1 lsl 1)) let set_rst buf = - Cstruct.set_uint8 buf 13 ((Cstruct.get_uint8 buf 13) lor (1 lsl 2)) + Cstruct.set_uint8 buf flags_off ((Cstruct.get_uint8 buf flags_off) lor (1 lsl 2)) let set_psh buf = - Cstruct.set_uint8 buf 13 ((Cstruct.get_uint8 buf 13) lor (1 lsl 3)) + Cstruct.set_uint8 buf flags_off ((Cstruct.get_uint8 buf flags_off) lor (1 lsl 3)) let set_ack buf = - Cstruct.set_uint8 buf 13 ((Cstruct.get_uint8 buf 13) lor (1 lsl 4)) + Cstruct.set_uint8 buf flags_off ((Cstruct.get_uint8 buf flags_off) lor (1 lsl 4)) let set_urg buf = - Cstruct.set_uint8 buf 13 ((Cstruct.get_uint8 buf 13) lor (1 lsl 5)) -let set_ece buf = - Cstruct.set_uint8 buf 13 ((Cstruct.get_uint8 buf 13) lor (1 lsl 6)) -let set_cwr buf = - Cstruct.set_uint8 buf 13 ((Cstruct.get_uint8 buf 13) lor (1 lsl 7)) + Cstruct.set_uint8 buf flags_off ((Cstruct.get_uint8 buf flags_off) lor (1 lsl 5)) +let _set_ece buf = + Cstruct.set_uint8 buf flags_off ((Cstruct.get_uint8 buf flags_off) lor (1 lsl 6)) +let _set_cwr buf = + Cstruct.set_uint8 buf flags_off ((Cstruct.get_uint8 buf flags_off) lor (1 lsl 7)) diff --git a/src/tcp/tcp_wire.mli b/src/tcp/tcp_wire.mli new file mode 100644 index 000000000..4ce241a67 --- /dev/null +++ b/src/tcp/tcp_wire.mli @@ -0,0 +1,42 @@ +val sizeof_tcp : int + +val get_src_port : Cstruct.t -> int +val set_src_port : Cstruct.t -> int -> unit + +val get_dst_port : Cstruct.t -> int +val set_dst_port : Cstruct.t -> int -> unit + +val get_sequence : Cstruct.t -> int32 +val set_sequence : Cstruct.t -> int32 -> unit + +val get_ack_number : Cstruct.t -> int32 +val set_ack_number : Cstruct.t -> int32 -> unit + +val get_flags : Cstruct.t -> int +val set_flags : Cstruct.t -> int -> unit + +val get_window : Cstruct.t -> int +val set_window : Cstruct.t -> int -> unit + +val get_checksum : Cstruct.t -> int +val set_checksum : Cstruct.t -> int -> unit + +val get_urg_ptr : Cstruct.t -> int +val set_urg_ptr : Cstruct.t -> int -> unit + +val get_data_offset : Cstruct.t -> int +val set_data_offset : Cstruct.t -> int -> unit + +val get_fin : Cstruct.t -> bool +val get_syn : Cstruct.t -> bool +val get_rst : Cstruct.t -> bool +val get_psh : Cstruct.t -> bool +val get_ack : Cstruct.t -> bool +val get_urg : Cstruct.t -> bool + +val set_fin : Cstruct.t -> unit +val set_syn : Cstruct.t -> unit +val set_rst : Cstruct.t -> unit +val set_psh : Cstruct.t -> unit +val set_ack : Cstruct.t -> unit +val set_urg : Cstruct.t -> unit diff --git a/src/udp/dune b/src/udp/dune index 087bee092..e28d9d1cc 100644 --- a/src/udp/dune +++ b/src/udp/dune @@ -4,6 +4,4 @@ (instrumentation (backend bisect_ppx)) (libraries mirage-random logs tcpip randomconv tcpip.checksum) - (preprocess - (pps ppx_cstruct)) (wrapped false)) diff --git a/src/udp/udp_packet.ml b/src/udp/udp_packet.ml index f75b7e5f8..6c6ab4264 100644 --- a/src/udp/udp_packet.ml +++ b/src/udp/udp_packet.ml @@ -34,11 +34,11 @@ module Unmarshal = struct end in let* () = check_header_length () in - let total_length_from_header = get_udp_length buf in + let total_length_from_header = get_length buf in let* payload_len = check_payload_length total_length_from_header (Cstruct.length buf) in - let src_port = Udp_wire.get_udp_source_port buf in - let dst_port = Udp_wire.get_udp_dest_port buf in - let payload = Cstruct.sub buf Udp_wire.sizeof_udp payload_len in + let src_port = get_src_port buf in + let dst_port = get_dst_port buf in + let payload = Cstruct.sub buf sizeof_udp payload_len in Ok ({ src_port; dst_port; }, payload) end module Marshal = struct @@ -47,10 +47,10 @@ module Marshal = struct let unsafe_fill ~pseudoheader ~payload {src_port; dst_port} udp_buf len = let open Udp_wire in let udp_buf = Cstruct.sub udp_buf 0 sizeof_udp in - set_udp_source_port udp_buf src_port; - set_udp_dest_port udp_buf dst_port; - set_udp_length udp_buf len; - set_udp_checksum udp_buf 0; + set_src_port udp_buf src_port; + set_dst_port udp_buf dst_port; + set_length udp_buf len; + set_checksum udp_buf 0; (* if we've been passed a buffer larger than sizeof_udp, make sure we * consider only the portion which will actually contain the header * when calculating this bit of the checksum *) @@ -60,7 +60,7 @@ module Marshal = struct * checksum is zero, it is transmitted as all ones (the equivalent * in one's complement arithmetic)." *) let csum = if csum = 0 then 0xffff else csum in - set_udp_checksum udp_buf csum + set_checksum udp_buf csum let into_cstruct ~pseudoheader ~payload t udp_buf = let open Udp_wire in @@ -73,7 +73,7 @@ module Marshal = struct Result.bind (check_header_len ()) (fun () -> let len = Cstruct.length payload + sizeof_udp in - let buf = Cstruct.sub udp_buf 0 Udp_wire.sizeof_udp in + let buf = Cstruct.sub udp_buf 0 sizeof_udp in unsafe_fill ~pseudoheader ~payload t buf len; Ok ()) diff --git a/src/udp/udp_packet.mli b/src/udp/udp_packet.mli index f34be0e18..865a342f2 100644 --- a/src/udp/udp_packet.mli +++ b/src/udp/udp_packet.mli @@ -8,7 +8,7 @@ val equal : t -> t -> bool module Unmarshal : sig - type error = string + type error = string (** [of_cstruct buf] attempts to interpret [buf] as a UDP header. If successful, it returns [Ok (header, payload)], although [payload] may be an diff --git a/src/udp/udp_wire.ml b/src/udp/udp_wire.ml index 46861da4c..9af833cec 100644 --- a/src/udp/udp_wire.ml +++ b/src/udp/udp_wire.ml @@ -1,9 +1,18 @@ -[%%cstruct -type udp = { - source_port: uint16_t; - dest_port: uint16_t; - length: uint16_t; - checksum: uint16_t; - } [@@big_endian] -] +let sizeof_udp = 8 +let src_port_offset = 0 +let dst_port_offset = 2 +let length_offset = 4 +let checksum_offset = 6 + +let get_src_port buf = Cstruct.BE.get_uint16 buf src_port_offset +let set_src_port buf v = Cstruct.BE.set_uint16 buf src_port_offset v + +let get_dst_port buf = Cstruct.BE.get_uint16 buf dst_port_offset +let set_dst_port buf v = Cstruct.BE.set_uint16 buf dst_port_offset v + +let get_length buf = Cstruct.BE.get_uint16 buf length_offset +let set_length buf v = Cstruct.BE.set_uint16 buf length_offset v + +let get_checksum buf = Cstruct.BE.get_uint16 buf checksum_offset +let set_checksum buf value = Cstruct.BE.set_uint16 buf checksum_offset value diff --git a/src/udp/udp_wire.mli b/src/udp/udp_wire.mli new file mode 100644 index 000000000..c3563ab3d --- /dev/null +++ b/src/udp/udp_wire.mli @@ -0,0 +1,13 @@ +val sizeof_udp : int + +val get_src_port : Cstruct.t -> int +val set_src_port : Cstruct.t -> int -> unit + +val get_dst_port : Cstruct.t -> int +val set_dst_port : Cstruct.t -> int -> unit + +val get_length : Cstruct.t -> int +val set_length : Cstruct.t -> int -> unit + +val get_checksum : Cstruct.t -> int +val set_checksum : Cstruct.t -> int -> unit diff --git a/tcpip.opam b/tcpip.opam index dd94c69a3..ac97bb053 100644 --- a/tcpip.opam +++ b/tcpip.opam @@ -28,7 +28,6 @@ depends: [ "ocaml" {>= "4.08.0"} "cstruct" {>= "6.0.0"} "cstruct-lwt" - "ppx_cstruct" "mirage-net" {>= "3.0.0"} "mirage-clock" {>= "3.0.0"} "mirage-random" {>= "2.0.0"} @@ -50,7 +49,8 @@ depends: [ "pcap-format" {with-test} "mirage-clock-unix" {with-test & >= "3.0.0"} "mirage-random-test" {with-test & >= "0.1.0"} - "ipaddr-cstruct" {with-test} + "ipaddr-cstruct" + "macaddr-cstruct" "lru" {>= "0.3.0"} "metrics" "cmdliner" {>= "1.1.0"} diff --git a/test/low_level.ml b/test/low_level.ml index 0a0688709..204bac1d1 100644 --- a/test/low_level.ml +++ b/test/low_level.ml @@ -34,8 +34,8 @@ let window = 5120 (* Helper functions *) let reply_id_from ~src ~dst data = - let sport = Tcp_wire.get_tcp_src_port data in - let dport = Tcp_wire.get_tcp_dst_port data in + let sport = Tcp_wire.get_src_port data in + let dport = Tcp_wire.get_dst_port data in WIRE.v ~dst_port:sport ~dst:src ~src_port:dport ~src:dst let ack_for data = diff --git a/test/test_checksums.ml b/test/test_checksums.ml index 915d29471..cadb83427 100644 --- a/test/test_checksums.ml +++ b/test/test_checksums.ml @@ -33,7 +33,7 @@ let udp_ipv4_correct_negative () = let udp_ipv4_allows_zero () = let buf = Cstruct.of_string example_ipv4_udp in let (ipv4_header, transport_packet) = unwrap_ipv4 buf in - Udp_wire.set_udp_checksum transport_packet 0x0000; + Udp_wire.set_checksum transport_packet 0x0000; Alcotest.(check bool) "0x0000 checksum is OK for UDP" true @@ verify_ipv4_udp ~ipv4_header ~transport_packet; Lwt.return_unit diff --git a/test/test_ipv6.ml b/test/test_ipv6.ml index 3ee05e506..7e5ea5bfe 100644 --- a/test/test_ipv6.ml +++ b/test/test_ipv6.ml @@ -102,35 +102,35 @@ let dad_na_is_sent () = get_stack backend address >>= fun stack -> create_ethernet backend >>= fun (listen_raw, write_raw, _) -> let received_one, on_received_one = Lwt.task () in - let nd_size = Ipv6_wire.sizeof_ipv6 + Ipv6_wire.sizeof_ns in + let nd_size = Ipv6_wire.sizeof_ipv6 + Ipv6_wire.Ns.sizeof_ns in let nd buf = - Ipv6_wire.set_ipv6_version_flow buf 0x60000000l; (* IPv6 *) - Ipv6_wire.set_ipv6_len buf Ipv6_wire.sizeof_ns; + Ipv6_wire.set_version_flow buf 0x60000000l; (* IPv6 *) + Ipv6_wire.set_len buf Ipv6_wire.Ns.sizeof_ns; Ipaddr_cstruct.V6.write_cstruct_exn Ipaddr.V6.unspecified (Cstruct.shift buf 8); Ipaddr_cstruct.V6.write_cstruct_exn (Ipaddr.V6.Prefix.network_address solicited_node_prefix address) (Cstruct.shift buf 24); - Ipv6_wire.set_ipv6_hlim buf 255; - Ipv6_wire.set_ipv6_nhdr buf (Ipv6_wire.protocol_to_int `ICMP); + Ipv6_wire.set_hlim buf 255; + Ipv6_wire.set_nhdr buf (Ipv6_wire.protocol_to_int `ICMP); let hdr, icmpbuf = Cstruct.split buf Ipv6_wire.sizeof_ipv6 in - Ipv6_wire.set_ns_ty icmpbuf 135; (* NS *) - Ipv6_wire.set_ns_code icmpbuf 0; - Ipv6_wire.set_ns_reserved icmpbuf 0l; + Ipv6_wire.set_ty icmpbuf 135; (* NS *) + Ipv6_wire.set_code icmpbuf 0; + Ipv6_wire.Ns.set_reserved icmpbuf 0l; Ipaddr_cstruct.V6.write_cstruct_exn address (Cstruct.shift icmpbuf 8); - Ipv6_wire.set_icmpv6_csum icmpbuf 0; - Ipv6_wire.set_icmpv6_csum icmpbuf @@ Ndpv6.checksum hdr [icmpbuf]; + Ipv6_wire.Icmpv6.set_checksum icmpbuf 0; + Ipv6_wire.Icmpv6.set_checksum icmpbuf @@ Ndpv6.checksum hdr [icmpbuf]; nd_size and is_na buf = let icmpbuf = Cstruct.shift buf Ipv6_wire.sizeof_ipv6 in - Ipv6_wire.get_ipv6_version_flow buf = 0x60000000l && (* IPv6 *) + Ipv6_wire.get_version_flow buf = 0x60000000l && (* IPv6 *) Ipaddr.V6.compare (Ipaddr_cstruct.V6.of_cstruct_exn (Cstruct.shift buf 8)) address = 0 && Ipaddr.V6.compare (Ipaddr_cstruct.V6.of_cstruct_exn (Cstruct.shift buf 24)) Ipaddr.V6.link_nodes = 0 && - Ipv6_wire.get_ipv6_hlim buf = 255 && - Ipv6_wire.get_ipv6_nhdr buf = Ipv6_wire.protocol_to_int `ICMP && - Ipv6_wire.get_na_ty icmpbuf = 136 && - Ipv6_wire.get_na_code icmpbuf = 0 && + Ipv6_wire.get_hlim buf = 255 && + Ipv6_wire.get_nhdr buf = Ipv6_wire.protocol_to_int `ICMP && + Ipv6_wire.get_ty icmpbuf = 136 && + Ipv6_wire.get_code icmpbuf = 0 && Ipaddr.V6.compare (Ipaddr_cstruct.V6.of_cstruct_exn (Cstruct.shift icmpbuf 8)) address = 0 @@ -159,44 +159,44 @@ let dad_na_is_received () = let address = Ipaddr.V6.of_string_exn "fc00::23" in let backend = B.create () in create_ethernet backend >>= fun (listen_raw, write_raw, mac) -> - let na_size = Ipv6_wire.sizeof_ipv6 + Ipv6_wire.sizeof_na + Ipv6_wire.sizeof_llopt in + let na_size = Ipv6_wire.sizeof_ipv6 + Ipv6_wire.Na.sizeof_na + Ipv6_wire.Llopt.sizeof_llopt in let is_ns buf = let icmpbuf = Cstruct.shift buf Ipv6_wire.sizeof_ipv6 in if - Ipv6_wire.get_ipv6_version_flow buf = 0x60000000l && (* IPv6 *) + Ipv6_wire.get_version_flow buf = 0x60000000l && (* IPv6 *) Ipaddr.V6.compare (Ipaddr_cstruct.V6.of_cstruct_exn (Cstruct.shift buf 8)) Ipaddr.V6.unspecified = 0 && Ipaddr.V6.Prefix.mem (Ipaddr_cstruct.V6.of_cstruct_exn (Cstruct.shift buf 24)) solicited_node_prefix && - Ipv6_wire.get_ipv6_hlim buf = 255 && - Ipv6_wire.get_ipv6_nhdr buf = Ipv6_wire.protocol_to_int `ICMP && - Ipv6_wire.get_ns_ty icmpbuf = 135 && - Ipv6_wire.get_ns_code icmpbuf = 0 + Ipv6_wire.get_hlim buf = 255 && + Ipv6_wire.get_nhdr buf = Ipv6_wire.protocol_to_int `ICMP && + Ipv6_wire.get_ty icmpbuf = 135 && + Ipv6_wire.get_code icmpbuf = 0 then Some (Ipaddr_cstruct.V6.of_cstruct_exn (Cstruct.shift icmpbuf 8)) else None in let na addr buf = - Ipv6_wire.set_ipv6_version_flow buf 0x60000000l; (* IPv6 *) - Ipv6_wire.set_ipv6_len buf (Ipv6_wire.sizeof_na + Ipv6_wire.sizeof_llopt); + Ipv6_wire.set_version_flow buf 0x60000000l; (* IPv6 *) + Ipv6_wire.set_len buf (Ipv6_wire.Na.sizeof_na + Ipv6_wire.Llopt.sizeof_llopt); Ipaddr_cstruct.V6.write_cstruct_exn addr (Cstruct.shift buf 8); Ipaddr_cstruct.V6.write_cstruct_exn Ipaddr.V6.link_nodes (Cstruct.shift buf 24); - Ipv6_wire.set_ipv6_hlim buf 255; - Ipv6_wire.set_ipv6_nhdr buf (Ipv6_wire.protocol_to_int `ICMP); + Ipv6_wire.set_hlim buf 255; + Ipv6_wire.set_nhdr buf (Ipv6_wire.protocol_to_int `ICMP); let hdr, icmpbuf = Cstruct.split buf Ipv6_wire.sizeof_ipv6 in - Ipv6_wire.set_na_ty icmpbuf 136; (* NA *) - Ipv6_wire.set_na_code icmpbuf 0; - Ipv6_wire.set_na_reserved icmpbuf 0x20000000l; + Ipv6_wire.set_ty icmpbuf 136; (* NA *) + Ipv6_wire.set_code icmpbuf 0; + Ipv6_wire.Na.set_reserved icmpbuf 0x20000000l; Ipaddr_cstruct.V6.write_cstruct_exn addr (Cstruct.shift icmpbuf 8); - let optbuf = Cstruct.shift icmpbuf Ipv6_wire.sizeof_na in - Ipv6_wire.set_llopt_ty optbuf 2; - Ipv6_wire.set_llopt_len optbuf 1; + let optbuf = Cstruct.shift icmpbuf Ipv6_wire.Na.sizeof_na in + Ipv6_wire.set_ty optbuf 2; + Ipv6_wire.Llopt.set_len optbuf 1; Macaddr_cstruct.write_cstruct_exn mac (Cstruct.shift optbuf 2); - Ipv6_wire.set_icmpv6_csum icmpbuf 0; - Ipv6_wire.set_icmpv6_csum icmpbuf @@ Ndpv6.checksum hdr [icmpbuf]; + Ipv6_wire.Icmpv6.set_checksum icmpbuf 0; + Ipv6_wire.Icmpv6.set_checksum icmpbuf @@ Ndpv6.checksum hdr [icmpbuf]; na_size in Lwt.pick [ diff --git a/test/test_rfc5961.ml b/test/test_rfc5961.ml index 8a01f30cd..ba772be68 100644 --- a/test/test_rfc5961.ml +++ b/test/test_rfc5961.ml @@ -105,7 +105,7 @@ let blind_rst_on_established_scenario = ) else Lwt.return (Fsm_error "Expected final ack of three way handshake") | `WAIT_FOR_CHALLENGE -> - if (Tcp_wire.get_ack data) && (Tcp_wire.get_tcp_ack_number data = 1l) then + if (Tcp_wire.get_ack data) && (Tcp_wire.get_ack_number data = 1l) then Lwt.return Fsm_done else Lwt.return (Fsm_error "Challenge ack expected") in @@ -174,7 +174,7 @@ let blind_syn_on_established_scenario = ) else Lwt.return (Fsm_error "Expected final ack of three step dance") | `WAIT_FOR_CHALLENGE -> - if (Tcp_wire.get_ack data) && (Tcp_wire.get_tcp_ack_number data = 1l) then ( + if (Tcp_wire.get_ack data) && (Tcp_wire.get_ack_number data = 1l) then ( Lwt.return Fsm_done ) else Lwt.return (Fsm_error "Challenge ack expected") in @@ -208,8 +208,7 @@ let blind_data_injection_scenario = ) else Lwt.return (Fsm_error "Expected final ack of three step dance") | `WAIT_FOR_CHALLENGE -> - if (Tcp_wire.get_ack data) && (Tcp_wire.get_tcp_ack_number data = - 1000001l) then + if (Tcp_wire.get_ack data) && (Tcp_wire.get_ack_number data = 1000001l) then Lwt.return Fsm_done else Lwt.return (Fsm_error "Challenge ack expected") @@ -244,7 +243,7 @@ let data_repeated_ack_scenario = ) else Lwt.return (Fsm_error "Expected final ack of three step dance") | `WAIT_FOR_DATA_ACK -> - if (Tcp_wire.get_ack data) && (Tcp_wire.get_tcp_ack_number data = Int32.(add 1000001l (of_int (Cstruct.length page)))) then + if (Tcp_wire.get_ack data) && (Tcp_wire.get_ack_number data = Int32.(add 1000001l (of_int (Cstruct.length page)))) then Lwt.return Fsm_done else Lwt.return (Fsm_error "Ack for data expected") in diff --git a/test/test_udp.ml b/test/test_udp.ml index 783f5f11a..2f7d8bb51 100644 --- a/test/test_udp.ml +++ b/test/test_udp.ml @@ -39,9 +39,9 @@ let marshal_unmarshal () = fails "unmarshal a too-short packet" parse (Cstruct.create 2); let with_data = Cstruct.create 8 in Cstruct.memset with_data 0; - Udp_wire.set_udp_source_port with_data 2000; - Udp_wire.set_udp_dest_port with_data 21; - Udp_wire.set_udp_length with_data 20; + Udp_wire.set_src_port with_data 2000; + Udp_wire.set_dst_port with_data 21; + Udp_wire.set_length with_data 20; let payload = Cstruct.of_string "abcdefgh1234" in let with_data = Cstruct.concat [with_data; payload] in match Udp_packet.Unmarshal.of_cstruct with_data with