123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051typeport=Cstruct.uint16typeendpoint=(Ipaddr.V4.t*port)typeerror=[`Overlap|`Cannot_NAT|`Untranslated|`TTL_exceeded]letpp_errorf=function|`Overlap->Fmt.stringf"Overlapping NAT entry"|`Cannot_NAT->Fmt.stringf"Cannot add rule for this packet type"|`Untranslated->Fmt.stringf"Packet not translated"|`TTL_exceeded->Fmt.stringf"TTL exceeded"typeports={tcp:portlist;udp:portlist;icmp:portlist;}moduletypeS=sigtypetvalremove_connections:t->Ipaddr.V4.t->portsvaltranslate:t->Nat_packet.t->(Nat_packet.t,[>`Untranslated|`TTL_exceeded])resultvalis_port_free:t->[`Udp|`Tcp|`Icmp]->src:Ipaddr.V4.t->dst:Ipaddr.V4.t->src_port:int->dst_port:int->boolvaladd:t->Nat_packet.t->Ipaddr.V4.t->(unit->intoption)->[`NAT|`Redirectofendpoint]->(unit,[>`Overlap|`Cannot_NAT])resultvalreset:t->unitendmoduletypeSUBTABLE=sigtypettypetransport_channeltypechannel=Ipaddr.V4.t*Ipaddr.V4.t*transport_channelvallookup:t->channel->channeloptionvalinsert:t->(channel*channel)list->(unit,[>`Overlap])resultvaldelete:t->channellist->unitendmoduletypeTABLE=sigtypetmoduleTCP:SUBTABLEwithtypet:=tandtypetransport_channel=port*portmoduleUDP:SUBTABLEwithtypet:=tandtypetransport_channel=port*portmoduleICMP:SUBTABLEwithtypet:=tandtypetransport_channel=Cstruct.uint16valreset:t->unit(** Remove all entries from the table. *)valremove_connections:t->Ipaddr.V4.t->portsvalis_port_free:t->[`Udp|`Tcp|`Icmp]->src:Ipaddr.V4.t->dst:Ipaddr.V4.t->src_port:int->dst_port:int->boolend