12345678910111213141516171819202122232425262728293031323334letsrc=Logs.Src.create"dhcp_client_mirage"moduleLog=(valLogs.src_logsrc:Logs.LOG)letconfig_of_leaselease=letopenDhcp_wirein(* ipv4_config expects a single IP address and the information
needed to construct a prefix. It can optionally use one router. *)letaddress=lease.yiaddrinmatchDhcp_wire.find_subnet_masklease.optionswith|None->Log.info(funf->f"Lease obtained with no subnet mask; discarding it");Log.debug(funf->f"Unusable lease: %s"@@Dhcp_wire.pkt_to_stringlease);None|Somesubnet->matchIpaddr.V4.Prefix.of_netmask~netmask:subnet~addresswith|Error`Msgmsg->Log.info(funf->f"Invalid address and netmask combination %s, discarding"msg);None|Oknetwork->letvalid_routers=Dhcp_wire.collect_routerslease.optionsinmatchvalid_routerswith|[]->Some(network,None)|hd::_->Some(network,Somehd)moduleMake(Random:Mirage_random.S)(Time:Mirage_time.S)(Net:Mirage_net.S)=structopenLwt.Infixtypet=(Ipaddr.V4.Prefix.t*Ipaddr.V4.toption)Lwt_stream.tletconnect?(requests:Dhcp_wire.option_codelistoption)net=letmoduleLwt_client=Dhcp_client_lwt.Make(Random)(Time)(Net)inLwt_client.connect~renew:false?requestsnet>>=funlease_stream->Lwt.return@@Lwt_stream.filter_mapconfig_of_leaselease_streamend