IPv4IPv4 protocol layer.
This module handles IPv4 packet encoding, decoding, fragmentation, and reassembly. It maintains a routing table (via ARPv4) to resolve destination IPv4 addresses to MAC addresses.
When an IPv4 packet arrives, it may or may not have been fragmented in transit. The payload type reflects this:
Slice: the packet was not fragmented. The payload is a zero-copy slice pointing directly into the original Ethernet frame buffer. This is the "happy path" and avoids any allocation.String: the packet was reassembled from multiple fragments. Reassembly requires copying, so the result is an OCaml string.Upper layers (TCP, UDP) handle both cases transparently.
write may need to resolve the destination's MAC address via ARPv4. This involves sending an ARP request and waiting for a reply, which constitutes an "interruption" (the current Miou task may be suspended). An internal cache avoids repeated lookups. If you already know the MAC address, use write_directly which never interrupts.
module Flag : sig ... endmodule Packet : sig ... endThe IPv4 protocol state. Maintains the routing/ARP cache, fragmentation reassembly state, and configured addresses.
val tags : t -> Logs.Tag.setWhen IPv4 sends logs, it can attach information such as the source IPv4 and the destination to which the logs relate. The user can obtain this information through the Logs API (and tags) and display it in order to better characterize the information that IPv4 can send (especially with regard to debugging).
Metadata about a received IPv4 packet, passed to upper-layer handlers.
protocol: the upper-layer protocol (6 = TCP, 17 = UDP, 1 = ICMP).uid: the IP identification field.val create :
?to_expire:int ->
Ethernet.t ->
ARPv4.t ->
?gateway:Ipaddr.V4.t ->
?handler:((packet * payload) -> unit) ->
Ipaddr.V4.Prefix.t ->
(t, [> `MTU_too_small ]) resultcreate ?to_expire eth arpv4 ?gateway ?handler cidr creates a new IPv4 protocol handler.
to_expire (nanoseconds): how long to keep fragments in the reassembly cache before discarding them (defaults to 10 seconds).eth: the Ethernet layer used for frame I/O.arpv4: the ARPv4 state for address resolution.gateway: the default IPv4 gateway. If absent, only On-Link destinations can be reached.handler: the function called when a complete IPv4 packet is received (and reassembled if fragmented). Typically installed later via set_handler.cidr: the local IPv4 address and prefix (e.g. 10.0.0.2/24).Returns `MTU_too_small if the Ethernet MTU is too small for IPv4.
val src : t -> dst:Ipaddr.V4.t -> Ipaddr.V4.tIt is morally possible for a unikernel to have several IPv4 addresses, each of which can communicate with certain destinations (depending on the routes discovered). In this case, the user is able to determine the source IPv4 address required to communicate with the given destination.
In practice, the implementation is configured to have only one IPv4 address. This assertion is therefore true:
let open Ipaddr in
let dst0 = V4.of_octets (Mirage_crypto_rng.generate 4) |> Result.get_ok in
let src0 = Mnet.IPv4.src ipv4 ~dst:dst0 in
let dst1 = V4.of_octets (Mirage_crypto_rng.generate 4) |> Result.get_ok in
let src1 = Mnet.IPv4.src ipv4 ~dst:dst1 in
assert (V4.compare src0 src1 = 0)val addresses : t -> Ipaddr.V4.Prefix.t listaddresses t returns the addresses on which the given state t is mounted.
module Writer : sig ... endEfficient IPv4 payload composition.
val write_directly :
t ->
?ttl:int ->
Ipaddr.V4.t ->
(Ipaddr.V4.t * Macaddr.t) ->
protocol:int ->
Writer.t ->
unitwrite_directly ipv4 ?ttl src (dst, macaddr) ~protocol w writes a new IPv4 packet w effectively (without interruption) (fragmented or not) to the specified destination macaddr.
val write :
t ->
?ttl:int ->
?src:Ipaddr.V4.t ->
Ipaddr.V4.t ->
protocol:int ->
Writer.t ->
(unit, [> `Route_not_found ]) resultwrite ipv4 ?ttl ?src dst ~protocol w writes a new IPv4 packet w (fragmented or not) to the specified destination dst. This function may have an interruption to discover the route to send the given packet to dst (an underlying cache exists for such discovery).
val attempt_to_discover_destination : t -> Ipaddr.V4.t -> Macaddr.t optionattempt_to_discover_destination ipv4 dst attempts to return the MAC address to which we would like to send a packet if we wish to send it to dst.
val input : t -> Slice_bstr.t Ethernet.packet -> unitinput ipv4 pkt is the function to install as an IPv4 handler for an Ethernet daemon. It analyze incoming IPv4 packets and update the given state ipv4.
When a packet is received (and reassembled if it has been fragmented), the handler is called with the IPv4 information (source, destination and protocol, see packet) so that the upper layer (such as TCP) can process it. set_handler allows you to modify this handler in order to direct incoming packets to a specific process.