From d685147c52b189d5da22e00c48b7fb4ea8a22ea8 Mon Sep 17 00:00:00 2001 From: cheatfate Date: Mon, 15 Apr 2019 11:16:54 +0300 Subject: [PATCH] Move ipnet/iface functionality to nim-chronos. Adjust tests. --- libp2p/ipnet/iface.nim | 1164 ---------------------------------------- libp2p/ipnet/ipnet.nim | 700 ------------------------ tests/testiface.nim | 9 - tests/testipnet.nim | 219 -------- tests/testnative.nim | 1 - 5 files changed, 2093 deletions(-) delete mode 100644 libp2p/ipnet/iface.nim delete mode 100644 libp2p/ipnet/ipnet.nim delete mode 100644 tests/testiface.nim delete mode 100644 tests/testipnet.nim diff --git a/libp2p/ipnet/iface.nim b/libp2p/ipnet/iface.nim deleted file mode 100644 index d1b831c..0000000 --- a/libp2p/ipnet/iface.nim +++ /dev/null @@ -1,1164 +0,0 @@ -## Nim-LibP2P -## Copyright (c) 2018 Status Research & Development GmbH -## Licensed under either of -## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) -## * MIT license ([LICENSE-MIT](LICENSE-MIT)) -## at your option. -## This file may not be copied, modified, or distributed except according to -## those terms. - -## This module implements cross-platform network interfaces list. -## Currently supported OSes are Windows, Linux, MacOS, BSD(not tested). -import algorithm -from strutils import toHex -import ipnet - -const - MaxAdapterAddressLength* = 8 - -type - InterfaceType* = enum - IfError = 0, # This is workaround element for ProoveInit warnings. - IfOther = 1, - IfRegular1822 = 2, - IfHdh1822 = 3, - IfDdnX25 = 4, - IfRfc877X25 = 5, - IfEthernetCsmacd = 6, - IfIso88023Csmacd = 7, - IfIso88024TokenBus = 8, - IfIso88025TokenRing = 9, - IfIso88026MAN = 10, - IfStarlan = 11, - IfProteon10Mbit = 12, - IfProteon80Mbit = 13, - IfHyperChannel = 14, - IfFddi = 15, - IfLapB = 16, - IfSdlc = 17, - IfDs1 = 18, - IfE1 = 19, - IfBasicIsdn = 20, - IfPrimaryIsdn = 21, - IfPropPoint2PointSerial = 22, - IfPpp = 23, - IfSoftwareLoopback = 24, - IfEon = 25, - IfEthernet3Mbit = 26, - IfNsip = 27, - IfSlip = 28, - IfUltra = 29, - IfDs3 = 30, - IfSip = 31, - IfFrameRelay = 32, - IfRs232 = 33, - IfPara = 34, - IfArcNet = 35, - IfArcNetPlus = 36, - IfAtm = 37, - IfMioX25 = 38, - IfSonet = 39, - IfX25Ple = 40, - IfIso88022Llc = 41, - IfLocalTalk = 42, - IfSmdsDxi = 43, - IfFrameRelayService = 44, - IfV35 = 45, - IfHssi = 46, - IfHippi = 47, - IfModem = 48, - IfAal5 = 49, - IfSonetPath = 50, - IfSonetVt = 51, - IfSmdsIcip = 52, - IfPropVirtual = 53, - IfPropMultiplexor = 54, - IfIeee80212 = 55, - IfFibreChannel = 56, - IfHippiInterface = 57, - IfFrameRelayInterconnect = 58, - IfAflane8023 = 59, - IfAflane8025 = 60, - IfCctemul = 61, - IfFastEther = 62, - IfIsdn = 63, - IfV11 = 64, - IfV36 = 65, - IfG70364K = 66, - IfG7032MB = 67, - IfQllc = 68, - IfFastEtherFx = 69, - IfChannel = 70, - IfIeee80211 = 71, - IfIbm370Parchan = 72, - IfEscon = 73, - IfDlsw = 74, - IfIsdnS = 75, - IfIsdnU = 76, - IfLapD = 77, - IfIpSwitch = 78, - IfRsrb = 79, - IfAtmLogical = 80, - IfDs0 = 81, - IfDs0Bundle = 82, - IfBsc = 83, - IfAsync = 84, - IfCnr = 85, - IfIso88025rDtr = 86, - IfEplrs = 87, - IfArap = 88, - IfPropCnls = 89, - IfHostPad = 90, - IfTermPad = 91, - IfFrameRelayMpi = 92, - IfX213 = 93, - IfAdsl = 94, - IfRadsl = 95, - IfSdsl = 96, - IfVdsl = 97, - IfIso88025Crfprint = 98, - IfMyrInet = 99, - IfVoiceEm = 100, - IfVoiceFxo = 101, - IfVoiceFxs = 102, - IfVoiceEncap = 103, - IfVoiceOverip = 104, - IfAtmDxi = 105, - IfAtmFuni = 106, - IfAtmIma = 107, - IfPppMultilinkBundle = 108, - IfIpoverCdlc = 109, - IfIpoverClaw = 110, - IfStackToStack = 111, - IfVirtualIpAddress = 112, - IfMpc = 113, - IfIpoverAtm = 114, - IfIso88025Fiber = 115, - IfTdlc = 116, - IfGigabitEthernet = 117, - IfHdlc = 118, - IfLapF = 119, - IfV37 = 120, - IfX25Mlp = 121, - IfX25HuntGroup = 122, - IfTransPhdlc = 123, - IfInterleave = 124, - IfFast = 125, - IfIp = 126, - IfDocScableMaclayer = 127, - IfDocScableDownstream = 128, - IfDocScableUpstream = 129, - IfA12MppSwitch = 130, - IfTunnel = 131, - IfCoffee = 132, - IfCes = 133, - IfAtmSubInterface = 134, - IfL2Vlan = 135, - IfL3IpVlan = 136, - IfL3IpxVlan = 137, - IfDigitalPowerline = 138, - IfMediaMailOverIp = 139, - IfDtm = 140, - IfDcn = 141, - IfIpForward = 142, - IfMsdsl = 143, - IfIeee1394 = 144, - IfIfGsn = 145, - IfDvbrccMaclayer = 146, - IfDvbrccDownstream = 147, - IfDvbrccUpstream = 148, - IfAtmVirtual = 149, - IfMplsTunnel = 150, - IfSrp = 151, - IfVoiceOverAtm = 152, - IfVoiceOverFrameRelay = 153, - IfIdsl = 154, - IfCompositeLink = 155, - IfSs7SigLink = 156, - IfPropWirelessP2p = 157, - IfFrForward = 158, - IfRfc1483 = 159, - IfUsb = 160, - IfIeee8023AdLag = 161, - IfBgpPolicyAccounting = 162, - IfFrf16MfrBundle = 163, - IfH323Gatekeeper = 164, - IfH323Proxy = 165, - IfMpls = 166, - IfMfSigLink = 167, - IfHdsl2 = 168, - IfShdsl = 169, - IfDs1Fdl = 170, - IfPos = 171, - IfDvbAsiIn = 172, - IfDvbAsiOut = 173, - IfPlc = 174, - IfNfas = 175, - IfTr008 = 176, - IfGr303Rdt = 177, - IfGr303Idt = 178, - IfIsup = 179, - IfPropDocsWirelessMaclayer = 180, - IfPropDocsWirelessDownstream = 181, - IfPropDocsWirelessUpstream = 182, - IfHiperLan2 = 183, - IfPropBwaP2mp = 184, - IfSonetOverheadChannel = 185, - IfDigitalWrapperOverheadChannel = 186, - IfAal2 = 187, - IfRadioMac = 188, - IfAtmRadio = 189, - IfImt = 190, - IfMvl = 191, - IfReachDsl = 192, - IfFrDlciEndpt = 193, - IfAtmVciEndpt = 194, - IfOpticalChannel = 195, - IfOpticalTransport = 196, - IfIeee80216Wman = 237, - IfWwanPp = 243, - IfWwanPp2 = 244, - IfIeee802154 = 259, - IfXboxWireless = 281 - - InterfaceState* = enum - StatusError = 0, # This is workaround element for ProoveInit warnings. - StatusUp, - StatusDown, - StatusTesting, - StatusUnknown, - StatusDormant, - StatusNotPresent, - StatusLowerLayerDown - - InterfaceAddress* = object - host*: TransportAddress - net*: IpNet - - NetworkInterface* = object - ifIndex*: int - ifType*: InterfaceType - name*: string - desc*: string - mtu*: int - flags*: uint64 - state*: InterfaceState - mac*: array[MaxAdapterAddressLength, byte] - maclen*: int - addresses*: seq[InterfaceAddress] - -proc broadcast*(ifa: InterfaceAddress): TransportAddress {.inline.} = - ## Return broadcast address for ``ifa``. - result = ifa.net.broadcast() - -proc network*(ifa: InterfaceAddress): TransportAddress {.inline.} = - ## Return network address for ``ifa``. - result = ifa.net.network() - -proc netmask*(ifa: InterfaceAddress): TransportAddress {.inline.} = - ## Return network mask for ``ifa``. - result = ifa.net.subnetMask() - -proc init*(ift: typedesc[InterfaceAddress], address: TransportAddress, - prefix: int): InterfaceAddress = - ## Initialize ``InterfaceAddress`` using ``address`` and prefix length - ## ``prefix``. - result.host = address - result.net = IpNet.init(address, prefix) - -proc `$`*(ifa: InterfaceAddress): string {.inline.} = - ## Return string representation of ``ifa``. - if ifa.host.family == AddressFamily.IPv4: - result = $ifa.net - elif ifa.host.family == AddressFamily.IPv6: - result = $ifa.net - -proc `$`*(iface: NetworkInterface): string = - ## Return string representation of network interface ``iface``. - result = $iface.ifIndex - if len(result) == 1: - result.add(". ") - else: - result.add(". ") - result.add(iface.name) - when defined(windows): - result.add(" [") - result.add(iface.desc) - result.add("]") - result.add(": flags = ") - result.add($iface.flags) - result.add(" mtu ") - result.add($iface.mtu) - result.add(" state ") - result.add($iface.state) - result.add("\n ") - result.add($iface.ifType) - result.add(" ") - if iface.maclen > 0: - for i in 0..= int(sizeof(NlMsgHeader))) and - (nlh.nlmsg_len >= uint32(sizeof(NlMsgHeader))) and - (nlh.nlmsg_len <= uint32(length)) - - proc NLMSG_NEXT(nlh: ptr NlMsgHeader, - length: var int): ptr NlMsgHeader {.inline.} = - length = length - int(NLMSG_ALIGN(uint(nlh.nlmsg_len))) - result = cast[ptr NlMsgHeader](cast[uint](nlh) + - cast[uint](NLMSG_ALIGN(uint(nlh.nlmsg_len)))) - - proc NLMSG_DATA(nlh: ptr NlMsgHeader): ptr byte {.inline.} = - result = cast[ptr byte](cast[uint](nlh) + NLMSG_LENGTH(0)) - - - template RTA_HDRLEN(): int = - int(RTA_ALIGN(uint(sizeof(RtAttr)))) - - template RTA_LENGTH(length: int): uint = - uint(RTA_HDRLEN()) + uint(length) - - template RTA_ALIGN*(length: uint): uint = - (length + RTA_ALIGNTO - 1) and not(RTA_ALIGNTO - 1) - - template RTA_PAYLOAD*(length: uint): uint = - length - RTA_LENGTH(0) - - proc IFLA_RTA(r: ptr byte): ptr RtAttr {.inline.} = - cast[ptr RtAttr](cast[uint](r) + NLMSG_ALIGN(uint(sizeof(IfInfoMessage)))) - - proc IFA_RTA(r: ptr byte): ptr RtAttr {.inline.} = - cast[ptr RtAttr](cast[uint](r) + NLMSG_ALIGN(uint(sizeof(IfAddrMessage)))) - - proc RTA_OK(rta: ptr RtAttr, length: int): bool {.inline.} = - result = length >= sizeof(RtAttr) and - rta.rta_len >= cushort(sizeof(RtAttr)) and - rta.rta_len <= cushort(length) - - proc RTA_NEXT(rta: ptr RtAttr, length: var int): ptr RtAttr {.inline.} = - length = length - int(RTA_ALIGN(uint(rta.rta_len))) - result = cast[ptr RtAttr](cast[uint](rta) + - cast[uint](RTA_ALIGN(uint(rta.rta_len)))) - - proc RTA_DATA(rta: ptr RtAttr): ptr byte {.inline.} = - result = cast[ptr byte](cast[uint](rta) + RTA_LENGTH(0)) - - proc toInterfaceState(it: cint, flags: cuint): InterfaceState {.inline.} = - case it - of 1: - result = StatusNotPresent - of 2: - result = StatusDown - of 3: - result = StatusLowerLayerDown - of 4: - result = StatusTesting - of 5: - result = StatusDormant - of 6: - result = StatusUp - else: - result = StatusUnknown - - proc toInterfaceType(ft: uint32): InterfaceType {.inline.} = - case ft - of ARPHRD_ETHER, ARPHRD_EETHER: - result = IfEthernetCsmacd - of ARPHRD_LOOPBACK: - result = IfSoftwareLoopback - of 787..799: - result = IfFibreChannel - of ARPHRD_PPP: - result = IfPpp - of ARPHRD_SLIP, ARPHRD_CSLIP, ARPHRD_SLIP6, ARPHRD_CSLIP6: - result = IfSlip - of ARPHRD_IEEE1394: - result = IfIeee1394 - of ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP: - result = IfIeee80211 - of ARPHRD_ATM: - result = IfAtm - of ARPHRD_HDLC: - result = IfHdlc - of ARPHRD_HIPPI: - result = IfHippiInterface - of ARPHRD_ARCNET: - result = IfArcNet - of ARPHRD_LAPB: - result = IfLapB - of ARPHRD_FRAD: - result = IfFrameRelay - else: - result = IfOther - - proc createNetlinkSocket(pid: Pid): SocketHandle = - var address: SockAddr_nl - address.family = cushort(AF_NETLINK) - address.groups = 0 - address.pid = cast[uint32](pid) - result = posix.socket(AF_NETLINK, posix.SOCK_DGRAM, NETLINK_ROUTE) - if result != SocketHandle(-1): - if posix.bindSocket(result, cast[ptr SockAddr](addr address), - Socklen(sizeof(SockAddr_nl))) != 0: - discard posix.close(result) - result = SocketHandle(-1) - - proc sendNetlinkMessage(fd: SocketHandle, pid: Pid, seqno: uint32, - ntype: uint16, nflags: uint16): bool = - var - rmsg: Tmsghdr - iov: IOVec - req: NLReq - address: SockAddr_nl - address.family = cushort(AF_NETLINK) - req.hdr.nlmsg_len = NLMSG_LENGTH(sizeof(RtGenMsg)) - req.hdr.nlmsg_type = ntype - req.hdr.nlmsg_flags = nflags - req.hdr.nlmsg_seq = seqno - req.hdr.nlmsg_pid = cast[uint32](pid) - req.msg.rtgen_family = byte(AF_PACKET) - iov.iov_base = cast[pointer](addr req) - iov.iov_len = cast[csize](req.hdr.nlmsg_len) - rmsg.msg_iov = addr iov - rmsg.msg_iovlen = 1 - rmsg.msg_name = cast[pointer](addr address) - rmsg.msg_namelen = Socklen(sizeof(SockAddr_nl)) - let res = posix.sendmsg(fd, addr rmsg, 0) - if res == iov.iov_len: - result = true - - proc readNetlinkMessage(fd: SocketHandle, data: var seq[byte]): bool = - var - rmsg: Tmsghdr - iov: IOVec - address: SockAddr_nl - data.setLen(IFLIST_REPLY_BUFFER) - iov.iov_base = cast[pointer](addr data[0]) - iov.iov_len = IFLIST_REPLY_BUFFER - rmsg.msg_iov = addr iov - rmsg.msg_iovlen = 1 - rmsg.msg_name = cast[pointer](addr address) - rmsg.msg_namelen = SockLen(sizeof(SockAddr_nl)) - var length = posix.recvmsg(fd, addr rmsg, 0) - if length >= 0: - data.setLen(length) - result = true - else: - data.setLen(0) - - proc processLink(msg: ptr NlMsgHeader): NetworkInterface = - var iface: ptr IfInfoMessage - var attr: ptr RtAttr - var length: int - - iface = cast[ptr IfInfoMessage](NLMSG_DATA(msg)) - length = int(msg.nlmsg_len) - int(NLMSG_LENGTH(sizeof(IfInfoMessage))) - - attr = IFLA_RTA(cast[ptr byte](iface)) - result.ifType = toInterfaceType(iface.ifi_type) - result.ifIndex = iface.ifi_index - result.flags = cast[uint64](iface.ifi_flags) - - while RTA_OK(attr, length): - if attr.rta_type == IFLA_IFNAME: - var p = cast[cstring](RTA_DATA(attr)) - result.name = $p - elif attr.rta_type == IFLA_ADDRESS: - var p = cast[ptr byte](RTA_DATA(attr)) - var plen = min(int(RTA_PAYLOAD(uint(attr.rta_len))), len(result.mac)) - copyMem(addr result.mac[0], p, plen) - result.maclen = plen - elif attr.rta_type == IFLA_MTU: - var p = cast[ptr uint32](RTA_DATA(attr)) - result.mtu = cast[int](p[]) - elif attr.rta_type == IFLA_OPERSTATE: - var p = cast[ptr byte](RTA_DATA(attr)) - result.state = toInterfaceState(cast[cint](p[]), iface.ifi_flags) - attr = RTA_NEXT(attr, length) - - proc getAddress(f: int, p: pointer): TransportAddress {.inline.} = - if f == posix.AF_INET: - result = TransportAddress(family: AddressFamily.IPv4) - copyMem(addr result.address_v4[0], p, len(result.address_v4)) - elif f == posix.AF_INET6: - result = TransportAddress(family: AddressFamily.IPv6) - copyMem(addr result.address_v6[0], p, len(result.address_v6)) - - proc processAddress(msg: ptr NlMsgHeader): NetworkInterface = - var iaddr: ptr IfAddrMessage - var attr: ptr RtAttr - var length: int - - iaddr = cast[ptr IfAddrMessage](NLMSG_DATA(msg)) - length = int(msg.nlmsg_len) - int(NLMSG_LENGTH(sizeof(IfAddrMessage))) - - attr = IFA_RTA(cast[ptr byte](iaddr)) - - let family = cast[int](iaddr.ifa_family) - result.ifIndex = cast[int](iaddr.ifa_index) - - var address, local: TransportAddress - - while RTA_OK(attr, length): - if attr.rta_type == IFA_LOCAL: - local = getAddress(family, cast[pointer](RTA_DATA(attr))) - elif attr.rta_type == IFA_ADDRESS: - address = getAddress(family, cast[pointer](RTA_DATA(attr))) - attr = RTA_NEXT(attr, length) - - if local.family != AddressFamily.None: - address = local - if len(result.addresses) == 0: - result.addresses = newSeq[InterfaceAddress]() - let prefixLength = cast[int](iaddr.ifa_prefixlen) - let ifaddr = InterfaceAddress.init(address, prefixLength) - result.addresses.add(ifaddr) - - proc getLinks(netfd: SocketHandle, pid: Pid): seq[NetworkInterface] = - if not sendNetlinkMessage(netfd, pid, 1, RTM_GETLINK, - NLM_F_REQUEST or NLM_F_DUMP): - return - var data = newSeq[byte]() - result = newSeq[NetworkInterface]() - while true: - if not readNetlinkMessage(netfd, data): - break - var length = len(data) - if length == 0: - break - var msg = cast[ptr NlMsgHeader](addr data[0]) - var endflag = false - while NLMSG_OK(msg, length): - if msg.nlmsg_type == NLMSG_DONE: - endflag = true - break - elif msg.nlmsg_type == NLMSG_ERROR: - endflag = true - break - else: - var iface = processLink(msg) - result.add(iface) - msg = NLMSG_NEXT(msg, length) - if endflag == true: - break - - proc getAddresses(netfd: SocketHandle, pid: Pid, - ifaces: var seq[NetworkInterface]) = - if not sendNetlinkMessage(netfd, pid, 2, RTM_GETADDR, - NLM_F_REQUEST or NLM_F_DUMP): - return - var data = newSeq[byte]() - while true: - if not readNetlinkMessage(netfd, data): - break - var length = len(data) - if length == 0: - break - var msg = cast[ptr NlMsgHeader](addr data[0]) - var endflag = false - while NLMSG_OK(msg, length): - if msg.nlmsg_type == NLMSG_DONE: - endflag = true - break - elif msg.nlmsg_type == NLMSG_ERROR: - endflag = true - break - else: - var iface = processAddress(msg) - for i in 0..", - pure, final.} = object - ifa_next {.importc: "ifa_next".}: ptr IfAddrs - ifa_name {.importc: "ifa_name".}: ptr cchar - ifa_flags {.importc: "ifa_flags".}: cuint - ifa_addr {.importc: "ifa_addr".}: ptr SockAddr - ifa_netmask {.importc: "ifa_netmask".}: ptr SockAddr - ifa_dstaddr {.importc: "ifa_dstaddr".}: ptr SockAddr - ifa_data {.importc: "ifa_data".}: pointer - - PIfAddrs = ptr IfAddrs - - IfData {.importc: "struct if_data", header: "", - pure, final.} = object - ifi_type {.importc: "ifi_type".}: byte - ifi_typelen {.importc: "ifi_typelen".}: byte - ifi_physical {.importc: "ifi_physical".}: byte - ifi_addrlen {.importc: "ifi_addrlen".}: byte - ifi_hdrlen {.importc: "ifi_hdrlen".}: byte - ifi_recvquota {.importc: "ifi_recvquota".}: byte - ifi_xmitquota {.importc: "ifi_xmitquota".}: byte - ifi_unused1 {.importc: "ifi_unused1".}: byte - ifi_mtu {.importc: "ifi_mtu".}: uint32 - ifi_metric {.importc: "ifi_metric".}: uint32 - ifi_baudrate {.importc: "ifi_baudrate".}: uint32 - ifi_ipackets {.importc: "ifi_ipackets".}: uint32 - ifi_ierrors {.importc: "ifi_ierrors".}: uint32 - ifi_opackets {.importc: "ifi_opackets".}: uint32 - ifi_oerrors {.importc: "ifi_oerrors".}: uint32 - ifi_collisions {.importc: "ifi_collisions".}: uint32 - ifi_ibytes {.importc: "ifi_ibytes".}: uint32 - ifi_obytes {.importc: "ifi_obytes".}: uint32 - ifi_imcasts {.importc: "ifi_imcasts".}: uint32 - ifi_omcasts {.importc: "ifi_omcasts".}: uint32 - ifi_iqdrops {.importc: "ifi_iqdrops".}: uint32 - ifi_noproto {.importc: "ifi_noproto".}: uint32 - ifi_recvtiming {.importc: "ifi_recvtiming".}: uint32 - ifi_xmittiming {.importc: "ifi_xmittiming".}: uint32 - ifi_lastchange {.importc: "ifi_lastchange".}: Timeval - ifi_unused2 {.importc: "ifi_unused2".}: uint32 - ifi_hwassist {.importc: "ifi_hwassist".}: uint32 - ifi_reserved1 {.importc: "ifi_reserved1".}: uint32 - ifi_reserved2 {.importc: "ifi_reserved2".}: uint32 - - SockAddr_dl = object - sdl_len: byte - sdl_family: byte - sdl_index: uint16 - sdl_type: byte - sdl_nlen: byte - sdl_alen: byte - sdl_slen: byte - sdl_data: array[12, byte] - - proc getIfAddrs(ifap: ptr PIfAddrs): cint {.importc: "getifaddrs", - header: """#include - #include - #include """.} - proc freeIfAddrs(ifap: ptr IfAddrs) {.importc: "freeifaddrs", - header: """#include - #include - #include """.} - - proc toInterfaceType(f: byte): InterfaceType {.inline.} = - var ft = cast[int](f) - if (ft >= 1 and ft <= 196) or (ft == 237) or (ft == 243) or (ft == 244): - result = cast[InterfaceType](ft) - else: - result = IfOther - - proc toInterfaceState(f: cuint): InterfaceState {.inline.} = - if (f and IFF_RUNNING) != 0 and (f and IFF_UP) != 0: - result = StatusUp - else: - result = StatusDown - - proc getInterfaces*(): seq[NetworkInterface] = - ## Return list of available interfaces. - var ifap: ptr IfAddrs - let res = getIfAddrs(addr ifap) - if res == 0: - result = newSeq[NetworkInterface]() - while not isNil(ifap): - var iface: NetworkInterface - var ifaddress: InterfaceAddress - - iface.name = $ifap.ifa_name - iface.flags = cast[uint64](ifap.ifa_flags) - var i = 0 - while i < len(result): - if result[i].name == iface.name: - break - inc(i) - if i == len(result): - result.add(iface) - - if not isNil(ifap.ifa_addr): - let family = cast[int](ifap.ifa_addr.sa_family) - if family == AF_LINK: - var data = cast[ptr IfData](ifap.ifa_data) - var link = cast[ptr SockAddr_dl](ifap.ifa_addr) - result[i].ifIndex = cast[int](link.sdl_index) - let nlen = cast[int](link.sdl_nlen) - if nlen < len(link.sdl_data): - let minsize = min(cast[int](link.sdl_alen), len(result[i].mac)) - copyMem(addr result[i].mac[0], addr link.sdl_data[nlen], minsize) - result[i].maclen = cast[int](link.sdl_alen) - result[i].ifType = toInterfaceType(data.ifi_type) - result[i].state = toInterfaceState(ifap.ifa_flags) - result[i].mtu = cast[int](data.ifi_mtu) - elif family == posix.AF_INET: - fromSAddr(cast[ptr Sockaddr_storage](ifap.ifa_addr), - Socklen(sizeof(SockAddr_in)), ifaddress.host) - elif family == posix.AF_INET6: - fromSAddr(cast[ptr Sockaddr_storage](ifap.ifa_addr), - Socklen(sizeof(SockAddr_in6)), ifaddress.host) - if not isNil(ifap.ifa_netmask): - var na: TransportAddress - var slen: Socklen - var family = cast[cint](ifap.ifa_netmask.sa_family) - if family == posix.AF_INET: - fromSAddr(cast[ptr Sockaddr_storage](ifap.ifa_netmask), - Socklen(sizeof(SockAddr_in)), na) - elif family == posix.AF_INET6: - fromSAddr(cast[ptr Sockaddr_storage](ifap.ifa_netmask), - Socklen(sizeof(SockAddr_in6)), na) - ifaddress.net = IpNet.init(ifaddress.host, na) - - if ifaddress.host.family != AddressFamily.None: - if len(result[i].addresses) == 0: - result[i].addresses = newSeq[InterfaceAddress]() - result[i].addresses.add(ifaddress) - ifap = ifap.ifa_next - - sort(result, cmp) - freeIfAddrs(ifap) - -elif defined(windows): - import winlean - - const - IfOperStatusUp = cint(1) - IfOperStatusDown = cint(2) - IfOperStatusTesting = cint(3) - IfOperStatusUnknown = cint(4) - IfOperStatusDormant = cint(5) - IfOperStatusNotPresent = cint(6) - IfOperStatusLowerLayerDown = cint(7) - - IpPrefixOriginOther = cint(0) - IpPrefixOriginManual = cint(1) - IpPrefixOriginWellKnown = cint(2) - IpPrefixOriginDhcp = cint(3) - IpPrefixOriginRouterAdvertisement = cint(4) - IpPrefixOriginUnchanged = cint(1) shl 4 - - IpSuffixOriginOther = cint(0) - IpSuffixOriginManual = cint(1) - IpSuffixOriginWellKnown = cint(2) - IpSuffixOriginDhcp = cint(3) - IpSuffixOriginLinkLayerAddress = cint(4) - IpSuffixOriginRandom = cint(5) - IpSuffixOriginUnchanged = cint(1) shl 4 - - IpDadStateInvalid = cint(0) - IpDadStateTentative = cint(1) - IpDadStateDuplicate = cint(2) - IpDadStateDeprecated = cint(3) - IpDadStatePreferred = cint(4) - - WorkBufferSize = 16384'u32 - MaxTries = 3 - - AF_UNSPEC = 0x00'u32 - - GAA_FLAG_INCLUDE_PREFIX = 0x0010'u32 - - CP_UTF8 = 65001'u32 - - ERROR_BUFFER_OVERFLOW* = 111'u32 - ERROR_SUCCESS* = 0'u32 - - type - WCHAR = distinct uint16 - - SocketAddress = object - lpSockaddr: ptr SockAddr - iSockaddrLength: cint - - IpAdapterUnicastAddressXpLh = object - length: uint32 - flags: uint32 - next: ptr IpAdapterUnicastAddressXpLh - address: SocketAddress - prefixOrigin: cint - suffixOrigin: cint - dadState: cint - validLifetime: uint32 - preferredLifetime: uint32 - leaseLifetime: uint32 - onLinkPrefixLength: byte # This field is available only from Vista - - IpAdapterAnycastAddressXp = object - length: uint32 - flags: uint32 - next: ptr IpAdapterAnycastAddressXp - address: SocketAddress - - IpAdapterMulticastAddressXp = object - length: uint32 - flags: uint32 - next: ptr IpAdapterMulticastAddressXp - address: SocketAddress - - IpAdapterDnsServerAddressXp = object - length: uint32 - flags: uint32 - next: ptr IpAdapterDnsServerAddressXp - address: SocketAddress - - IpAdapterPrefixXp = object - length: uint32 - flags: uint32 - next: ptr IpAdapterPrefixXp - address: SocketAddress - prefixLength: uint32 - - IpAdapterAddressesXp = object - length: uint32 - ifIndex: uint32 - next: ptr IpAdapterAddressesXp - adapterName: cstring - unicastAddress: ptr IpAdapterUnicastAddressXpLh - anycastAddress: ptr IpAdapterAnycastAddressXp - multicastAddress: ptr IpAdapterMulticastAddressXp - dnsServerAddress: ptr IpAdapterDnsServerAddressXp - dnsSuffix: ptr WCHAR - description: ptr WCHAR - friendlyName: ptr WCHAR - physicalAddress: array[MaxAdapterAddressLength, byte] - physicalAddressLength: uint32 - flags: uint32 - mtu: uint32 - ifType: uint32 - operStatus: cint - ipv6IfIndex: uint32 - zoneIndices: array[16, uint32] - firstPrefix: ptr IpAdapterPrefixXp - - proc toInterfaceType(ft: uint32): InterfaceType {.inline.} = - if (ft >= 1'u32 and ft <= 196'u32) or - (ft == 237) or (ft == 243) or (ft == 244) or (ft == 259) or (ft == 281): - result = cast[InterfaceType](ft) - else: - result = IfOther - - proc toInterfaceState(it: cint): InterfaceState {.inline.} = - if it >= 1 and it <= 7: - result = cast[InterfaceState](it) - else: - result = StatusUnknown - - proc GetAdaptersAddresses(family: uint32, flags: uint32, reserved: pointer, - addresses: ptr IpAdapterAddressesXp, - sizeptr: ptr uint32): uint32 {. - stdcall, dynlib: "iphlpapi", importc: "GetAdaptersAddresses".} - - proc WideCharToMultiByte(CodePage: uint32, dwFlags: uint32, - lpWideCharStr: ptr WCHAR, cchWideChar: cint, - lpMultiByteStr: ptr char, cbMultiByte: cint, - lpDefaultChar: ptr char, - lpUsedDefaultChar: ptr uint32): cint - {.stdcall, dynlib: "kernel32.dll", importc: "WideCharToMultiByte".} - - proc `$`(bstr: ptr WCHAR): string = - var buffer: char - var count = WideCharToMultiByte(CP_UTF8, 0, bstr, -1, addr(buffer), 0, - nil, nil) - if count > 0: - result = newString(count + 8) - let res = WideCharToMultiByte(CP_UTF8, 0, bstr, -1, addr(result[0]), - count, nil, nil) - if res > 0: - result.setLen(res - 1) - else: - result.setLen(0) - - proc isVista(): bool = - var ver: OSVERSIONINFO - ver.dwOSVersionInfoSize = DWORD(sizeof(ver)) - let res = getVersionExW(addr(ver)) - if res == 0: - result = false - else: - result = (ver.dwMajorVersion >= 6) - - proc toIPv6(a: TransportAddress): TransportAddress = - ## IPv4-mapped addresses are formed by: - ## <80 bits of zeros> + <16 bits of ones> + <32-bit IPv4 address>. - if a.family == AddressFamily.IPv4: - result = TransportAddress(family: AddressFamily.IPv6) - result.address_v6[10] = 0xFF'u8 - result.address_v6[11] = 0xFF'u8 - copyMem(addr result.address_v6[12], unsafeAddr a.address_v4[0], 4) - elif a.family == AddressFamily.IPv6: - result = a - - proc ipMatchPrefix(number, prefix: TransportAddress, nbits: int): bool = - var num6, prefix6: TransportAddress - if number.family == AddressFamily.IPv4: - num6 = toIPv6(number) - else: - num6 = number - if prefix.family == AddressFamily.IPv4: - prefix6 = toIPv6(number) - else: - prefix6 = prefix - var bytesCount = nbits div 8 - var bitsCount = nbits mod 8 - for i in 0..= 0: - result.net = IpNet.init(result.host, prefixLength) - else: - let prefixLength = cast[int](ifunic.onLinkPrefixLength) - if prefixLength >= 0: - result.net = IpNet.init(result.host, prefixLength) - - proc getInterfaces*(): seq[NetworkInterface] = - ## Return list of network interfaces. - result = newSeq[NetworkInterface]() - var size = WorkBufferSize - var tries = 0 - var buffer: seq[byte] - var res: uint32 - var vista = isVista() - - while true: - buffer = newSeq[byte](size) - var addresses = cast[ptr IpAdapterAddressesXp](addr buffer[0]) - res = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nil, - addresses, addr size) - if res == ERROR_SUCCESS: - buffer.setLen(size) - break - elif res == ERROR_BUFFER_OVERFLOW: - discard - else: - break - inc(tries) - if tries >= MaxTries: - break - - if res == ERROR_SUCCESS: - var slider = cast[ptr IpAdapterAddressesXp](addr buffer[0]) - while not isNil(slider): - var iface = NetworkInterface( - ifIndex: cast[int](slider.ifIndex), - ifType: toInterfaceType(slider.ifType), - state: toInterfaceState(slider.operStatus), - name: $slider.adapterName, - desc: $slider.description, - mtu: cast[int](slider.mtu), - maclen: cast[int](slider.physicalAddressLength), - flags: cast[uint64](slider.flags) - ) - copyMem(addr iface.mac[0], addr slider.physicalAddress[0], - len(iface.mac)) - var unicast = slider.unicastAddress - while not isNil(unicast): - var ifaddr = processAddress(slider, unicast, vista) - iface.addresses.add(ifaddr) - unicast = unicast.next - result.add(iface) - slider = slider.next - - sort(result, cmp) - -else: - {.fatal: "Sorry, your OS is currently not supported!".} diff --git a/libp2p/ipnet/ipnet.nim b/libp2p/ipnet/ipnet.nim deleted file mode 100644 index 2a12068..0000000 --- a/libp2p/ipnet/ipnet.nim +++ /dev/null @@ -1,700 +0,0 @@ -## Nim-LibP2P -## Copyright (c) 2018 Status Research & Development GmbH -## Licensed under either of -## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) -## * MIT license ([LICENSE-MIT](LICENSE-MIT)) -## at your option. -## This file may not be copied, modified, or distributed except according to -## those terms. - -## This module implements various IP network utility procedures. -import endians, strutils -import chronos -export chronos - -type - IpMask* = object - case family*: AddressFamily - of AddressFamily.None, AddressFamily.Unix: - discard - of AddressFamily.IPv4: - mask4*: uint32 - of AddressFamily.IPv6: - mask6*: array[2, uint64] - - IpNet* = object - host*: TransportAddress - mask*: IpMask - -proc toNetworkOrder(mask: IpMask): IpMask {.inline.} = - ## Converts ``mask`` from host order (which can be big/little-endian) to - ## network order (which is big-endian) representation. - result = IpMask(family: mask.family) - if mask.family == AddressFamily.IPv4: - bigEndian32(cast[pointer](addr result.mask4), - cast[pointer](unsafeAddr mask.mask4)) - elif mask.family == AddressFamily.IPv6: - bigEndian64(cast[pointer](addr result.mask6[0]), - cast[pointer](unsafeAddr mask.mask6[0])) - bigEndian64(cast[pointer](addr result.mask6[1]), - cast[pointer](unsafeAddr mask.mask6[1])) - -proc toHostOrder(mask: IpMask): IpMask {.inline.} = - ## Converts ``mask`` from network order (which is big-endian) back to - ## host representation (which can be big/little-endian). - when system.cpuEndian == bigEndian: - result = mask - else: - result = IpMask(family: mask.family) - if mask.family == AddressFamily.IPv4: - swapEndian32(cast[pointer](addr result.mask4), - cast[pointer](unsafeAddr mask.mask4)) - elif mask.family == AddressFamily.IPv6: - swapEndian64(cast[pointer](addr result.mask6[0]), - cast[pointer](unsafeAddr mask.mask6[0])) - swapEndian64(cast[pointer](addr result.mask6[1]), - cast[pointer](unsafeAddr mask.mask6[1])) - -proc `==`*(m1, m2: IpMask): bool {.inline.} = - ## Returns ``true`` if masks ``m1`` and ``m2`` are equal in IP family and - ## by value. - if m1.family == m2.family: - if m1.family == AddressFamily.IPv4: - result = (m1.mask4 == m2.mask4) - elif m1.family == AddressFamily.IPv6: - result = ((m1.mask6[0] == m2.mask6[0]) and (m1.mask6[1] == m2.mask6[1])) - -proc init*(t: typedesc[IpMask], family: AddressFamily, prefix: int): IpMask = - ## Initialize mask of IP family ``family`` from prefix length ``prefix``. - ## - ## For IPv4 mask, if ``prefix`` is ``0`` or more then ``32`` it will be set - ## to ``32``. - ## - ## For IPv6 mask, if ``prefix`` is ``0`` or more then ``128`` it will be set - ## to ``128``. - if family == AddressFamily.IPv4: - result = IpMask(family: AddressFamily.IPv4) - result.mask4 = 0xFFFF_FFFF'u32 - if prefix > 0 and prefix < 32: - result.mask4 = 0xFFFF_FFFF'u32 - result.mask4 = cast[uint32](result.mask4 shl (32 - prefix)) - elif family == AddressFamily.IPv6: - result = IpMask(family: AddressFamily.IPv6) - if prefix >= 128 or prefix <= 0: - result.mask6[0] = 0xFFFF_FFFF_FFFF_FFFF'u64 - result.mask6[1] = 0xFFFF_FFFF_FFFF_FFFF'u64 - else: - result.mask6[0] = 0xFFFF_FFFF_FFFF_FFFF'u64 - if prefix > 64: - result.mask6[1] = 0xFFFF_FFFF_FFFF_FFFF'u64 - result.mask6[1] = result.mask6[1] shl (128 - prefix) - elif prefix == 64: - result.mask6[1] = 0x00'u64 - else: - result.mask6[0] = result.mask6[0] shl (64 - prefix) - result.mask6[1] = 0x00'u64 - result = result.toNetworkOrder() - -proc init*(t: typedesc[IpMask], netmask: TransportAddress): IpMask = - ## Initialize network mask using address ``netmask``. - if netmask.family == AddressFamily.IPv4: - result.family = netmask.family - result.mask4 = cast[ptr uint32](unsafeAddr netmask.address_v4[0])[] - elif netmask.family == AddressFamily.IPv6: - result.family = netmask.family - result.mask6[0] = cast[ptr uint64](unsafeAddr netmask.address_v6[0])[] - result.mask6[1] = cast[ptr uint64](unsafeAddr netmask.address_v6[8])[] - -proc initIp*(t: typedesc[IpMask], netmask: string): IpMask = - ## Initialize network mask using IPv4 or IPv6 address in text representation - ## ``netmask``. - ## - ## If ``netmask`` address string is invalid, result IpMask.family will be - ## set to ``AddressFamily.None``. - try: - var ip = parseIpAddress(netmask) - var tip = initTAddress(ip, Port(0)) - result = t.init(tip) - except ValueError: - discard - -proc init*(t: typedesc[IpMask], netmask: string): IpMask = - ## Initialize network mask using hexadecimal string representation - ## ``netmask``. - ## - ## If ``netmask`` mask is invalid, result IpMask.family will be set to - ## ``AddressFamily.None``. - const - hexNumbers = {'0'..'9'} - hexCapitals = {'A'..'F'} - hexLowers = {'a'..'f'} - let length = len(netmask) - if length == 8 or length == (2 + 8): - ## IPv4 mask - var offset = 0 - if length == 2 + 8: - offset = 2 - var res = IpMask(family: AddressFamily.IPv4) - var r, v: uint32 - for i in 0..<8: - if netmask[offset + i] in hexNumbers: - v = cast[uint32](ord(netmask[offset + i]) - ord('0')) - elif netmask[offset + i] in hexCapitals: - v = cast[uint32](ord(netmask[offset + i]) - ord('A') + 10) - elif netmask[offset + i] in hexLowers: - v = cast[uint32](ord(netmask[offset + i]) - ord('a') + 10) - else: - return - r = (r shl 4) or v - bigEndian32(addr res.mask4, addr r) - result = res - elif length == 32 or length == (2 + 32): - ## IPv6 mask - var offset = 0 - if length == 2 + 32: - offset = 2 - var res = IpMask(family: AddressFamily.IPv6) - for i in 0..1: - var r, v: uint64 - for i in 0..<16: - if netmask[offset + i] in hexNumbers: - v = cast[uint64](ord(netmask[offset + i]) - ord('0')) - elif netmask[offset + i] in hexCapitals: - v = cast[uint64](ord(netmask[offset + i]) - ord('A') + 10) - elif netmask[offset + i] in hexLowers: - v = cast[uint64](ord(netmask[offset + i]) - ord('a') + 10) - else: - return - r = (r shl 4) or v - offset += 16 - bigEndian64(addr res.mask6[i], addr r) - result = res - -proc toIPv6*(address: TransportAddress): TransportAddress = - ## Map IPv4 ``address`` to IPv6 address. - ## - ## If ``address`` is IPv4 address then it will be mapped as: - ## <80 bits of zeros> + <16 bits of ones> + <32-bit IPv4 address>. - ## - ## If ``address`` is IPv6 address it will be returned without any changes. - if address.family == AddressFamily.IPv4: - result = TransportAddress(family: AddressFamily.IPv6) - result.address_v6[10] = 0xFF'u8 - result.address_v6[11] = 0xFF'u8 - let data = cast[ptr uint32](unsafeAddr address.address_v4[0])[] - cast[ptr uint32](addr result.address_v6[12])[] = data - elif address.family == AddressFamily.IPv6: - result = address - -proc isV4Mapped*(address: TransportAddress): bool = - ## Returns ``true`` if ``address`` is (IPv4 to IPv6) mapped address, e.g. - ## 0000:0000:0000:0000:0000:FFFF:xxxx:xxxx - ## - ## Procedure returns ``false`` if ``address`` family is IPv4. - if address.family == AddressFamily.IPv6: - let data0 = cast[ptr uint64](unsafeAddr address.address_v6[0])[] - let data1 = cast[ptr uint16](unsafeAddr address.address_v6[8])[] - let data2 = cast[ptr uint16](unsafeAddr address.address_v6[10])[] - result = (data0 == 0'u64) and (data1 == 0x00'u16) and (data2 == 0xFFFF'u16) - -proc toIPv4*(address: TransportAddress): TransportAddress = - ## Get IPv4 from (IPv4 to IPv6) mapped address. - ## - ## If ``address`` is IPv4 address it will be returned without any changes. - ## - ## If ``address`` is not IPv4 to IPv6 mapped address, then result family will - ## be set to AddressFamily.None. - if address.family == AddressFamily.IPv6: - if isV4Mapped(address): - result = TransportAddress(family: AddressFamily.IPv4) - let data = cast[ptr uint32](unsafeAddr address.address_v6[12])[] - cast[ptr uint32](addr result.address_v4[0])[] = data - elif address.family == AddressFamily.IPv4: - result = address - -proc mask*(a: TransportAddress, m: IpMask): TransportAddress = - ## Apply IP mask ``m`` to address ``a`` and return result address. - ## - ## If ``a`` family is IPv4 and ``m`` family is IPv6, masking is still - ## possible when ``m`` has ``FFFF:FFFF:FFFF:FFFF:FFFF:FFFF`` prefix. Returned - ## value will be IPv4 address. - ## - ## If ``a`` family is IPv6 and ``m`` family is IPv4, masking is still - ## possible when ``a`` holds (IPv4 to IPv6) mapped address. Returned value - ## will be IPv6 address. - ## - ## If ``a`` family is IPv4 and ``m`` family is IPv4, returned value will be - ## IPv4 address. - ## - ## If ``a`` family is IPv6 and ``m`` family is IPv6, returned value will be - ## IPv6 address. - ## - ## In all other cases returned address will have ``AddressFamily.None``. - if a.family == AddressFamily.IPv4 and m.family == AddressFamily.IPv6: - if (m.mask6[0] == 0xFFFF_FFFF_FFFF_FFFF'u64) and - (m.mask6[1] and 0xFFFF_FFFF'u64) == 0xFFFF_FFFF'u64: - result = TransportAddress(family: a.family) - let mask = cast[uint32](m.mask6[1] shr 32) - let data = cast[ptr uint32](unsafeAddr a.address_v4[0])[] - cast[ptr uint32](addr result.address_v4[0])[] = data and mask - result.port = a.port - elif a.family == AddressFamily.IPv6 and m.family == AddressFamily.IPv4: - var ip = a.toIPv4() - if ip.family == AddressFamily.IPv4: - let data = cast[ptr uint32](addr ip.address_v4[0])[] - cast[ptr uint32](addr ip.address_v4[0])[] = data and m.mask4 - result = ip.toIPv6() - result.port = a.port - elif a.family == AddressFamily.IPv4 and m.family == AddressFamily.IPv4: - result = TransportAddress(family: AddressFamily.IPv4) - let data = cast[ptr uint32](unsafeAddr a.address_v4[0])[] - cast[ptr uint32](addr result.address_v4[0])[] = data and m.mask4 - result.port = a.port - elif a.family == AddressFamily.IPv6 and m.family == AddressFamily.IPv6: - result = TransportAddress(family: AddressFamily.IPv6) - let data0 = cast[ptr uint64](unsafeAddr a.address_v6[0])[] - let data1 = cast[ptr uint64](unsafeAddr a.address_v6[8])[] - cast[ptr uint64](addr result.address_v6[0])[] = data0 and m.mask6[0] - cast[ptr uint64](addr result.address_v6[8])[] = data1 and m.mask6[1] - result.port = a.port - -proc prefix*(mask: IpMask): int = - ## Returns number of bits set `1` in IP mask ``mask``. - ## - ## Procedure returns ``-1`` if mask is not canonical, e.g. has holes with - ## ``0`` bits between ``1`` bits. - var hmask = mask.toHostOrder() - if hmask.family == AddressFamily.IPv4: - var n = hmask.mask4 - while n != 0: - if (n and 0x8000_0000'u32) == 0'u32: - result = -1 - return - n = n shl 1 - inc(result) - elif hmask.family == AddressFamily.IPv6: - if hmask.mask6[0] == 0xFFFF_FFFF_FFFF_FFFF'u64: - result += 64 - if hmask.mask6[1] == 0xFFFF_FFFF_FFFF_FFFF'u64: - result += 64: - else: - var n = hmask.mask6[1] - while n != 0: - if (n and 0x8000_0000_0000_0000'u64) == 0'u64: - result = -1 - return - n = n shl 1 - inc(result) - else: - var n = hmask.mask6[0] - while n != 0: - if (n and 0x8000_0000_0000_0000'u64) == 0'u64: - result = -1 - return - n = n shl 1 - inc(result) - if hmask.mask6[1] != 0x00'u64: - result = -1 - -proc subnetMask*(mask: IpMask): TransportAddress = - ## Returns TransportAddress representation of IP mask ``mask``. - result = TransportAddress(family: mask.family) - if mask.family == AddressFamily.IPv4: - cast[ptr uint32](addr result.address_v4[0])[] = mask.mask4 - elif mask.family == AddressFamily.IPv6: - cast[ptr uint64](addr result.address_v6[0])[] = mask.mask6[0] - cast[ptr uint64](addr result.address_v6[8])[] = mask.mask6[1] - -proc `$`*(mask: IpMask, include0x = false): string = - ## Returns hexadecimal string representation of IP mask ``mask``. - var host = mask.toHostOrder() - result = "" - if host.family == AddressFamily.IPv4: - result = if include0x: "0x" else: "" - var n = 32 - var m = host.mask4 - while n > 0: - n -= 4 - var c = cast[int]((m shr n) and 0x0F) - if c < 10: - result.add(chr(ord('0') + c)) - else: - result.add(chr(ord('A') + (c - 10))) - elif host.family == AddressFamily.IPv6: - result = if include0x: "0x" else: "" - for i in 0..1: - var n = 64 - var m = host.mask6[i] - while n > 0: - n -= 4 - var c = cast[int]((m shr n) and 0x0F) - if c < 10: - result.add(chr(ord('0') + c)) - else: - result.add(chr(ord('A') + (c - 10))) - else: - raise newException(ValueError, "Invalid mask") - -proc ip*(mask: IpMask): string = - ## Returns IP address text representation of IP mask ``mask``. - if mask.family == AddressFamily.IPv4: - var ip = IpAddress(family: IpAddressFamily.IPv4) - copyMem(addr ip.address_v4[0], unsafeAddr mask.mask4, sizeof(uint32)) - result = $ip - elif mask.family == AddressFamily.IPv6: - var ip = IpAddress(family: IpAddressFamily.IPv6) - copyMem(addr ip.address_v6[0], unsafeAddr mask.mask6[0], 16) - result = $ip - else: - raise newException(ValueError, "Invalid mask") - -proc init*(t: typedesc[IpNet], host: TransportAddress, - prefix: int): IpNet {.inline.} = - ## Initialize IP Network using host address ``host`` and prefix length - ## ``prefix``. - result.mask = IpMask.init(host.family, prefix) - result.host = host - -proc init*(t: typedesc[IpNet], host, mask: TransportAddress): IpNet {.inline.} = - ## Initialize IP Network using host address ``host`` and network mask - ## address ``mask``. - ## - ## Note that ``host`` and ``mask`` must be from the same IP family. - if host.family == mask.family: - result.mask = IpMask.init(mask) - result.host = host - -proc init*(t: typedesc[IpNet], host: TransportAddress, - mask: IpMask): IpNet {.inline.} = - ## Initialize IP Network using host address ``host`` and network mask - ## ``mask``. - result.mask = mask - result.host = host - -proc init*(t: typedesc[IpNet], network: string): IpNet = - ## Initialize IP Network from string representation in format - ##
/ or
/. - var parts = network.rsplit("/", maxsplit = 1) - var host, mhost: TransportAddress - var ipaddr: IpAddress - var mask: IpMask - var prefix: int - try: - ipaddr = parseIpAddress(parts[0]) - if ipaddr.family == IpAddressFamily.IPv4: - host = TransportAddress(family: AddressFamily.IPv4) - host.address_v4 = ipaddr.address_v4 - prefix = 32 - elif ipaddr.family == IpAddressFamily.IPv6: - host = TransportAddress(family: AddressFamily.IPv6) - host.address_v6 = ipaddr.address_v6 - prefix = 128 - if len(parts) > 1: - try: - prefix = parseInt(parts[1]) - except: - prefix = -1 - if prefix == -1: - ipaddr = parseIpAddress(parts[1]) - if ipaddr.family == IpAddressFamily.IPv4: - mhost = TransportAddress(family: AddressFamily.IPv4) - mhost.address_v4 = ipaddr.address_v4 - elif ipaddr.family == IpAddressFamily.IPv6: - mhost = TransportAddress(family: AddressFamily.IPv6) - mhost.address_v6 = ipaddr.address_v6 - mask = IpMask.init(mhost) - if mask.family != host.family: - raise newException(TransportAddressError, - "Incorrect network address!") - else: - if (ipaddr.family == IpAddressFamily.IPv4 and - (prefix <= 0 or prefix > 32)) or - (ipaddr.family == IpAddressFamily.IPv6 and - (prefix <= 0 or prefix > 128)): - raise newException(TransportAddressError, - "Incorrect network address!") - if prefix == -1: - result = t.init(host, mask) - else: - result = t.init(host, prefix) - except: - raise newException(TransportAddressError, "Incorrect network address!") - -proc `==`*(n1, n2: IpNet): bool {.inline.} = - ## Returns ``true`` if networks ``n1`` and ``n2`` are equal in IP family and - ## by value. - if n1.host.family == n2.host.family: - if n1.host.family == AddressFamily.IPv4: - result = (n1.host.address_v4 == n2.host.address_v4) and - (n1.mask == n2.mask) - elif n1.host.family == AddressFamily.IPv6: - result = (n1.host.address_v6 == n2.host.address_v6) and - (n1.mask == n2.mask) - -proc contains*(net: IpNet, address: TransportAddress): bool = - ## Returns ``true`` if ``address`` belongs to IP Network ``net`` - if net.host.family == address.family: - var host1 = mask(address, net.mask) - var host2 = mask(net.host, net.mask) - host2.port = host1.port - result = (host1 == host2) - -proc broadcast*(net: IpNet): TransportAddress = - ## Returns broadcast address for IP Network ``net``. - result = TransportAddress(family: net.host.family) - if result.family == AddressFamily.IPv4: - let address = cast[ptr uint32](unsafeAddr net.host.address_v4[0])[] - let mask = cast[ptr uint32](unsafeAddr net.mask.mask4)[] - cast[ptr uint32](addr result.address_v4[0])[] = address or (not(mask)) - elif result.family == AddressFamily.IPv6: - let address0 = cast[ptr uint64](unsafeAddr net.host.address_v6[0])[] - let address1 = cast[ptr uint64](unsafeAddr net.host.address_v6[8])[] - let data0 = cast[ptr uint64](unsafeAddr net.mask.mask6[0])[] - let data1 = cast[ptr uint64](unsafeAddr net.mask.mask6[1])[] - cast[ptr uint64](addr result.address_v6[0])[] = address0 or (not(data0)) - cast[ptr uint64](addr result.address_v6[8])[] = address1 or (not(data1)) - -proc subnetMask*(net: IpNet): TransportAddress = - ## Returns netmask address for IP Network ``net``. - result = TransportAddress(family: net.host.family) - if result.family == AddressFamily.IPv4: - let address = cast[ptr uint32](unsafeAddr net.mask.mask4)[] - cast[ptr uint32](addr result.address_v4[0])[] = address - elif result.family == AddressFamily.IPv6: - let address0 = cast[ptr uint64](unsafeAddr net.mask.mask6[0])[] - let address1 = cast[ptr uint64](unsafeAddr net.mask.mask6[1])[] - cast[ptr uint64](addr result.address_v6[0])[] = address0 - cast[ptr uint64](addr result.address_v6[8])[] = address1 - -proc network*(net: IpNet): TransportAddress {.inline.} = - ## Returns network address (host address masked with network mask) for - ## IP Network ``net``. - result = mask(net.host, net.mask) - -proc `and`*(address1, address2: TransportAddress): TransportAddress = - ## Bitwise ``and`` operation for ``address1 and address2``. - ## - ## Note only IPv4 and IPv6 addresses are supported. ``address1`` and - ## ``address2`` must be in equal IP family - if address1.family == address2.family: - if address1.family == AddressFamily.IPv4: - let data1 = cast[ptr uint32](unsafeAddr address1.address_v4[0])[] - let data2 = cast[ptr uint32](unsafeAddr address2.address_v4[0])[] - result = TransportAddress(family: address1.family) - cast[ptr uint32](addr result.address_v4[0])[] = data1 and data2 - elif address1.family == AddressFamily.IPv6: - let data1 = cast[ptr uint64](unsafeAddr address1.address_v6[0])[] - let data2 = cast[ptr uint64](unsafeAddr address1.address_v6[8])[] - let data3 = cast[ptr uint64](unsafeAddr address2.address_v6[0])[] - let data4 = cast[ptr uint64](unsafeAddr address2.address_v6[8])[] - result = TransportAddress(family: address1.family) - cast[ptr uint64](addr result.address_v6[0])[] = data1 and data3 - cast[ptr uint64](addr result.address_v6[8])[] = data2 and data4 - -proc `or`*(address1, address2: TransportAddress): TransportAddress = - ## Bitwise ``or`` operation for ``address1 or address2``. - ## - ## Note only IPv4 and IPv6 addresses are supported. ``address1`` and - ## ``address2`` must be in equal IP family - if address1.family == address2.family: - if address1.family == AddressFamily.IPv4: - let data1 = cast[ptr uint32](unsafeAddr address1.address_v4[0])[] - let data2 = cast[ptr uint32](unsafeAddr address2.address_v4[0])[] - result = TransportAddress(family: address1.family) - cast[ptr uint32](addr result.address_v4[0])[] = data1 or data2 - elif address1.family == AddressFamily.IPv6: - let data1 = cast[ptr uint64](unsafeAddr address1.address_v6[0])[] - let data2 = cast[ptr uint64](unsafeAddr address1.address_v6[8])[] - let data3 = cast[ptr uint64](unsafeAddr address2.address_v6[0])[] - let data4 = cast[ptr uint64](unsafeAddr address2.address_v6[8])[] - result = TransportAddress(family: address1.family) - cast[ptr uint64](addr result.address_v6[0])[] = data1 or data3 - cast[ptr uint64](addr result.address_v6[8])[] = data2 or data4 - -proc `not`*(address: TransportAddress): TransportAddress = - ## Bitwise ``not`` operation for ``address``. - if address.family == AddressFamily.IPv4: - let data = cast[ptr uint32](unsafeAddr address.address_v4[0])[] - result = TransportAddress(family: address.family) - cast[ptr uint32](addr result.address_v4[0])[] = not(data) - elif address.family == AddressFamily.IPv6: - let data1 = cast[ptr uint64](unsafeAddr address.address_v6[0])[] - let data2 = cast[ptr uint64](unsafeAddr address.address_v6[8])[] - result = TransportAddress(family: address.family) - cast[ptr uint64](addr result.address_v6[0])[] = not(data1) - cast[ptr uint64](addr result.address_v6[8])[] = not(data2) - -proc `+`*(address: TransportAddress, v: uint): TransportAddress = - ## Add to IPv4/IPv6 transport ``address`` unsigned integer ``v``. - result = TransportAddress(family: address.family) - if address.family == AddressFamily.IPv4: - var a: uint64 - let data = cast[ptr uint32](unsafeAddr address.address_v4[0]) - when system.cpuEndian == bigEndian: - a = data - else: - swapEndian32(addr a, data) - a = a + v - bigEndian32(cast[pointer](addr result.address_v4[0]), addr a) - elif address.family == AddressFamily.IPv6: - var a1, a2: uint64 - let data1 = cast[ptr uint64](unsafeAddr address.address_v6[0]) - let data2 = cast[ptr uint64](unsafeAddr address.address_v6[8]) - when system.cpuEndian == bigEndian: - a1 = data1 - a2 = data2 - else: - swapEndian64(addr a1, data1) - swapEndian64(addr a2, data2) - var a3 = a2 + v - if a3 < a2: - ## Overflow - a1 = a1 + 1 - bigEndian64(cast[pointer](addr result.address_v6[0]), addr a1) - bigEndian64(cast[pointer](addr result.address_v6[8]), addr a3) - -proc inc*(address: var TransportAddress, v: uint = 1'u) = - ## Increment IPv4/IPv6 transport ``address`` by unsigned integer ``v``. - address = address + v - -proc `$`*(net: IpNet): string = - ## Return string representation of IP network in format: - ## /. - if net.host.family == AddressFamily.IPv4: - var a = IpAddress(family: IpAddressFamily.IPv4, - address_v4: net.host.address_v4) - result = $a - result.add("/") - let prefix = net.mask.prefix() - if prefix == -1: - result.add(net.mask.ip()) - else: - result.add($prefix) - elif net.host.family == AddressFamily.IPv6: - var a = IpAddress(family: IpAddressFamily.IPv6, - address_v6: net.host.address_v6) - result = $a - result.add("/") - let prefix = net.mask.prefix() - if prefix == -1: - result.add(net.mask.ip()) - else: - result.add($prefix) - -proc isUnspecified*(address: TransportAddress): bool {.inline.} = - ## Returns ``true`` if ``address`` is not specified yet, e.g. its ``family`` - ## field is not set or equal to ``AddressFamily.None``. - if address.family == AddressFamily.None: - result = true - -proc isMulticast*(address: TransportAddress): bool = - ## Returns ``true`` if ``address`` is a multicast address. - ## - ## ``IPv4``: 224.0.0.0 - 239.255.255.255 - ## - ## ``IPv6``: FF00:: - FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF - if address.family == AddressFamily.IPv4: - result = ((address.address_v4[0] and 0xF0'u8) == 0xE0'u8) - elif address.family == AddressFamily.IPv6: - result = (address.address_v6[0] == 0xFF'u8) - -proc isInterfaceLocalMulticast*(address: TransportAddress): bool = - ## Returns ``true`` if ``address`` is interface local multicast address. - ## - ## ``IPv4``: N/A (always returns ``false``) - if address.family == AddressFamily.IPv6: - result = (address.address_v6[0] == 0xFF'u8) and - ((address.address_v6[1] and 0x0F'u8) == 0x01'u8) - -proc isLinkLocalMulticast*(address: TransportAddress): bool = - ## Returns ``true`` if ``address` is link local multicast address. - ## - ## ``IPv4``: 224.0.0.0 - 224.0.0.255 - if address.family == AddressFamily.IPv4: - result = (address.address_v4[0] == 224'u8) and - (address.address_v4[1] == 0'u8) and - (address.address_v4[2] == 0'u8) - elif address.family == AddressFamily.IPv6: - result = (address.address_v6[0] == 0xFF'u8) and - ((address.address_v6[1] and 0x0F'u8) == 0x02'u8) - -proc isLoopback*(address: TransportAddress): bool = - ## Returns ``true`` if ``address`` is loopback address. - ## - ## ``IPv4``: 127.0.0.0 - 127.255.255.255 - ## - ## ``IPv6``: ::1 - if address.family == AddressFamily.IPv4: - result = (address.address_v4[0] == 127'u8) - elif address.family == AddressFamily.IPv6: - var test = 0 - for i in 0..<(len(address.address_v6) - 1): - test = test or cast[int](address.address_v6[i]) - result = (test == 0) and (address.address_v6[15] == 1'u8) - -proc isAnyLocal*(address: TransportAddress): bool = - ## Returns ``true`` if ``address`` is a wildcard address. - ## - ## ``IPv4``: 0.0.0.0 - ## - ## ``IPv6``: :: - if address.family == AddressFamily.IPv4: - let data = cast[ptr uint32](unsafeAddr address.address_v4[0])[] - result = (data == 0'u32) - elif address.family == AddressFamily.IPv6: - let data1 = cast[ptr uint32](unsafeAddr address.address_v6[0])[] - let data2 = cast[ptr uint32](unsafeAddr address.address_v6[4])[] - let data3 = cast[ptr uint32](unsafeAddr address.address_v6[8])[] - let data4 = cast[ptr uint32](unsafeAddr address.address_v6[12])[] - result = ((data1 or data2 or data3 or data4) == 0'u32) - -proc isLinkLocal*(address: TransportAddress): bool = - ## Returns ``true`` if ``address`` is link local address. - ## - ## ``IPv4``: 169.254.0.0 - 169.254.255.255 - ## - ## ``IPv6``: FE80:: - FEBF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF - if address.family == AddressFamily.IPv4: - result = (address.address_v4[0] == 169'u8) and - (address.address_v4[1] == 254'u8) - elif address.family == AddressFamily.IPv6: - result = (address.address_v6[0] == 0xFE'u8) and - ((address.address_v6[1] and 0xC0'u8) == 0x80'u8) - -proc isLinkLocalUnicast*(address: TransportAddress): bool {.inline.} = - result = isLinkLocal(address) - -proc isSiteLocal*(address: TransportAddress): bool = - ## Returns ``true`` if ``address`` is site local address. - ## - ## ``IPv4``: 10.0.0.0 - 10.255.255.255, 172.16.0.0 - 172.31.255.255, - ## 192.168.0.0 - 192.168.255.255 - ## - ## ``IPv6``: FEC0:: - FEFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF - if address.family == AddressFamily.IPv4: - result = (address.address_v4[0] == 10'u8) or - ((address.address_v4[0] == 172'u8) and - ((address.address_v4[1] and 0xF0) == 16)) or - ((address.address_v4[0] == 192'u8) and - ((address.address_v4[1] == 168'u8))) - elif address.family == AddressFamily.IPv6: - result = (address.address_v6[0] == 0xFE'u8) and - ((address.address_v6[1] and 0xC0'u8) == 0xC0'u8) - -proc isGlobalMulticast*(address: TransportAddress): bool = - ## Returns ``true`` if the multicast address has global scope. - ## - ## ``IPv4``: 224.0.1.0 - 238.255.255.255 - ## - ## ``IPv6``: FF0E:: - FFFE:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF - if address.family == AddressFamily.IPv4: - result = (address.address_v4[0] >= 224'u8) and - (address.address_v4[0] <= 238'u8) and - not( - (address.address_v4[0] == 224'u8) and - (address.address_v4[1] == 0'u8) and - (address.address_v4[2] == 0'u8) - ) - elif address.family == AddressFamily.IPv6: - result = (address.address_v6[0] == 0xFF'u8) and - ((address.address_v6[1] and 0x0F'u8) == 0x0E'u8) diff --git a/tests/testiface.nim b/tests/testiface.nim deleted file mode 100644 index a82e6f9..0000000 --- a/tests/testiface.nim +++ /dev/null @@ -1,9 +0,0 @@ -import unittest -import ../libp2p/ipnet/iface - -suite "OS interfaces list suite": - test "Get interfaces list test": - var ifaces = getInterfaces() - for item in ifaces: - echo item - check len(ifaces) > 0 diff --git a/tests/testipnet.nim b/tests/testipnet.nim deleted file mode 100644 index c8f1e33..0000000 --- a/tests/testipnet.nim +++ /dev/null @@ -1,219 +0,0 @@ -import unittest, strutils -import ../libp2p/ipnet/ipnet - -const MaskVectors = [ - ["192.168.1.127:1024", "255.255.255.128", "192.168.1.0:1024"], - ["192.168.1.127:1024", "255.255.255.192", "192.168.1.64:1024"], - ["192.168.1.127:1024", "255.255.255.224", "192.168.1.96:1024"], - ["192.168.1.127:1024", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80", - "192.168.1.0:1024"], - ["192.168.1.127:1024", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffc0", - "192.168.1.64:1024"], - ["192.168.1.127:1024", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0", - "192.168.1.96:1024"], - ["192.168.1.127:1024", "255.0.255.0", "192.0.1.0:1024"], - ["[2001:db8::1]:1024", "ffff:ff80::", "[2001:d80::]:1024"], - ["[2001:db8::1]:1024", "f0f0:0f0f::", "[2000:d08::]:1024"] -] - -const NonCanonicalMasks = [ - ["ip", "0.255.255.255", "-1"], - ["ip", "255.0.255.255", "-1"], - ["ip", "255.255.0.255", "-1"], - ["ip", "255.255.255.0", "24"], - ["ms", "0FFFFFFF", "-1"], - ["ms", "F0FFFFFF", "-1"], - ["ms", "FF0FFFFF", "-1"], - ["ms", "FFF0FFFF", "-1"], - ["ms", "FFFF0FFF", "-1"], - ["ms", "FFFFF0FF", "-1"], - ["ms", "FFFFFF0F", "-1"], - ["ms", "FFFFFFF0", "28"], - ["ip", "00FF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", "-1"], - ["ip", "FF00:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", "-1"], - ["ip", "FFFF:00FF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", "-1"], - ["ip", "FFFF:FF00:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", "-1"], - ["ip", "FFFF:FFFF:00FF:FFFF:FFFF:FFFF:FFFF:FFFF", "-1"], - ["ip", "FFFF:FFFF:FF00:FFFF:FFFF:FFFF:FFFF:FFFF", "-1"], - ["ip", "FFFF:FFFF:FFFF:00FF:FFFF:FFFF:FFFF:FFFF", "-1"], - ["ip", "FFFF:FFFF:FFFF:FF00:FFFF:FFFF:FFFF:FFFF", "-1"], - ["ip", "FFFF:FFFF:FFFF:FFFF:00FF:FFFF:FFFF:FFFF", "-1"], - ["ip", "FFFF:FFFF:FFFF:FFFF:FF00:FFFF:FFFF:FFFF", "-1"], - ["ip", "FFFF:FFFF:FFFF:FFFF:FFFF:00FF:FFFF:FFFF", "-1"], - ["ip", "FFFF:FFFF:FFFF:FFFF:FFFF:FF00:FFFF:FFFF", "-1"], - ["ip", "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:00FF:FFFF", "-1"], - ["ip", "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FF00:FFFF", "-1"], - ["ip", "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:00FF", "-1"], - ["ip", "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FF00", "120"], - ["ms", "0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "F0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFF0FFFFFFFFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFF0FFFFFFFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFF0FFFFFFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFF0FFFFFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFF0FFFFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFF0FFFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFF0FFFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFF0FFFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFF0FFFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFF0FFFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFF0FFFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFF0FFFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFF0FFFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFF0FFFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFF0FFFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFF0FFFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFF0FFFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFF0FFFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFF0FFFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFF0FFFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFFF0FFFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFFFF0FFFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFFFFF0FFFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFFFFFF0FFFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFFFFFFF0FFFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFFFFFFFF0FFF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFF0FF", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F", "-1"], - ["ms", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0", "124"], -] - -const NetworkVectors = [ - ["135.104.0.0/32", "true", "135.104.0.0:0", "FFFFFFFF"], - ["0.0.0.0/24", "true", "0.0.0.0:0", "FFFFFF00"], - ["135.104.0.0/24", "true", "135.104.0.0:0", "FFFFFF00"], - ["135.104.0.1/32", "true", "135.104.0.1:0", "FFFFFFFF"], - ["135.104.0.1/24", "true", "135.104.0.1:0", "FFFFFF00"], - ["::1/128", "true", "[::1]:0", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"], - ["abcd:2345::/127", "true", "[abcd:2345::]:0", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"], - ["abcd:2345::/65", "true", "[abcd:2345::]:0", - "FFFFFFFFFFFFFFFF8000000000000000"], - ["abcd:2345::/64", "true", "[abcd:2345::]:0", - "FFFFFFFFFFFFFFFF0000000000000000"], - ["abcd:2345::/63", "true", "[abcd:2345::]:0", - "FFFFFFFFFFFFFFFE0000000000000000"], - ["abcd:2345::/33", "true", "[abcd:2345::]:0", - "FFFFFFFF800000000000000000000000"], - ["abcd:2345::/32", "true", "[abcd:2345::]:0", - "FFFFFFFF000000000000000000000000"], - ["abcd:2344::/31", "true", "[abcd:2344::]:0", - "FFFFFFFE000000000000000000000000"], - ["abcd:2300::/24", "true", "[abcd:2300::]:0", - "FFFFFF00000000000000000000000000"], - ["abcd:2345::/24", "true", "[abcd:2345::]:0", - "FFFFFF00000000000000000000000000"], - ["2001:db8::/48", "true", "[2001:db8::]:0", - "FFFFFFFFFFFF00000000000000000000"], - ["2001:db8::1/48", "true", "[2001:db8::1]:0", - "FFFFFFFFFFFF00000000000000000000"], - ["192.168.1.1/255.255.255.0", "true", "192.168.1.1:0", "FFFFFF00"], - ["192.168.1.1/35", "false", "", ""], - ["2001:db8::1/-1", "false", "", ""], - ["2001:db8::1/-0", "false", "", ""], - ["-0.0.0.0/32", "false", "", ""], - ["0.-1.0.0/32", "false", "", ""], - ["0.0.-2.0/32", "false", "", ""], - ["0.0.0.-3/32", "false", "", ""], - ["0.0.0.0/-0", "false", "", ""], - ["", "false", "", ""] -] - -const NetworkContainsVectors = [ - ["172.16.1.1:1024", "172.16.0.0/12", "true"], - ["172.24.0.1:1024", "172.16.0.0/13", "false"], - ["192.168.0.3:1024", "192.168.0.0/0.0.255.252", "true"], - ["192.168.0.4:1024", "192.168.0.0/0.255.0.252", "false"], - ["[2001:db8:1:2::1]:1024", "2001:db8:1::/47", "true"], - ["[2001:db8:1:2::1]:1024", "2001:db8:2::/47", "false"], - ["[2001:db8:1:2::1]:1024", "2001:db8:1::/ffff:0:ffff::", "true"], - ["[2001:db8:1:2::1]:1024", "2001:db8:1::/0:0:0:ffff::", "false"] -] - -suite "IP network utilities test suite": - - test "IpMask test vectors": - for item in MaskVectors: - var a = initTAddress(item[0]) - var m = IpMask.initIp(item[1]) - var r = a.mask(m) - check $r == item[2] - - test "IpMask serialization/deserialization test": - for i in 1..32: - var m = IpMask.init(AddressFamily.IPv4, i) - check m.prefix() == i - var s0x = `$`(m, true) - var s = $m - var sip = m.ip() - var m1 = IpMask.init(s0x) - var m2 = IpMask.init(s) - var m3 = IpMask.initIp(sip) - check: - m == m1 - m == m2 - m == m3 - for i in 1..128: - var m = IpMask.init(AddressFamily.IPv6, i) - check m.prefix() == i - var s0x = `$`(m, true) - var s = $m - var sip = m.ip() - var m1 = IpMask.init(s0x) - var m2 = IpMask.init(s) - var m3 = IpMask.initIp(sip) - check: - m == m1 - m == m2 - m == m3 - - test "IpMask non-canonical masks": - for item in NonCanonicalMasks: - var m: IpMask - if item[0] == "ip": - m = IpMask.initIp(item[1]) - elif item[0] == "ms": - m = IpMask.init(item[1]) - var c = $(m.prefix()) - check: - c == item[2] - - test "IpNet test vectors": - for item in NetworkVectors: - var res: bool - var inet: IpNet - try: - inet = IpNet.init(item[0]) - res = true - except: - res = false - check: - $res == item[1] - if res: - check: - $inet.host == item[2] - $inet.mask == $item[3] - - test "IpNet contains test vectors": - for item in NetworkContainsVectors: - var a = initTAddress(item[0]) - var n = IpNet.init(item[1]) - var res = a in n - check: - $res == item[2] - - test "IpNet serialization/deserialization test": - var ip4 = initTAddress("192.168.1.0:1024") - for i in 1..32: - var net = IpNet.init(ip4, i) - var s1 = $net - var net2 = IpNet.init(s1) - check net == net2 - - var ip6 = initTAddress("[8000:f123:f456:cafe::]:1024") - for i in 1..128: - var net = IpNet.init(ip6, i) - var s1 = $net - var net2 = IpNet.init(s1) - check net == net2 diff --git a/tests/testnative.nim b/tests/testnative.nim index 7ca7d4c..c14ac8f 100644 --- a/tests/testnative.nim +++ b/tests/testnative.nim @@ -2,4 +2,3 @@ import unittest import testvarint, testbase32, testbase58, testbase64 import testrsa, testecnist, tested25519, testcrypto import testmultibase, testmultihash, testmultiaddress, testcid, testpeer -import testipnet, testiface