diff options
author | euxane | 2024-11-24 17:17:02 +0100 |
---|---|---|
committer | euxane | 2024-11-24 17:17:02 +0100 |
commit | ece6c54f1b4db27abac52ee3c627f619d1090544 (patch) | |
tree | f59c3b8f15e7f4f7ebd5521969637beae4c26025 | |
parent | a2d15bdd78f071549d46aa6ac5467a8a8cf6ebbd (diff) | |
download | tickwatch-ece6c54f1b4db27abac52ee3c627f619d1090544.tar.gz |
ping: add hostname resolution
-rw-r--r-- | main.nim | 2 | ||||
-rw-r--r-- | ping.nim | 34 |
2 files changed, 35 insertions, 1 deletions
@@ -70,7 +70,7 @@ proc main() = | |||
70 | of "max": max = parseInt(val) | 70 | of "max": max = parseInt(val) |
71 | 71 | ||
72 | of "ping": | 72 | of "ping": |
73 | let targetIp = parseIpAddress(val) | 73 | let targetIp = resolve(val) |
74 | let mon = initPingMonitor(targetIp, procIdent()) | 74 | let mon = initPingMonitor(targetIp, procIdent()) |
75 | probe = (timeout: Duration) => mon.ping(timeout).inMilliseconds.int | 75 | probe = (timeout: Duration) => mon.ping(timeout).inMilliseconds.int |
76 | 76 | ||
@@ -167,6 +167,40 @@ proc receiveReply(sock: Socket, timeout: Duration): seq[uint8] = | |||
167 | stripIPHeader(ipAddr.family, cast[seq[uint8]](buffer)) | 167 | stripIPHeader(ipAddr.family, cast[seq[uint8]](buffer)) |
168 | 168 | ||
169 | 169 | ||
170 | func toIpAddress(info: ptr AddrInfo): IpAddress = | ||
171 | case info.ai_family: | ||
172 | of posix.AF_INET6: | ||
173 | let sockAddr = cast[ptr posix.SockAddr_in6](info.ai_addr)[] | ||
174 | IpAddress( | ||
175 | family: IPv6, | ||
176 | address_v6: cast[array[0..15, uint8]](sockAddr.sin6_addr.s6_addr), | ||
177 | ) | ||
178 | of posix.AF_INET: | ||
179 | let sockAddr = cast[ptr posix.SockAddr_in](info.ai_addr)[] | ||
180 | IpAddress( | ||
181 | family: IPv4, | ||
182 | address_v4: cast[array[0..3, uint8]](sockAddr.sin_addr.s_addr), | ||
183 | ) | ||
184 | else: | ||
185 | raise newException(ValueError, "Invalid address info") | ||
186 | |||
187 | func splitDomainHostname(target: string): (Domain, string) = | ||
188 | let parts = target.split('/', 1) | ||
189 | case parts[0]: | ||
190 | of "6": (AF_INET6, parts[1]) | ||
191 | of "4": (AF_INET, parts[1]) | ||
192 | else: (AF_UNSPEC, target) | ||
193 | |||
194 | proc resolve*(target: string): IpAddress = | ||
195 | try: | ||
196 | parseIpAddress(target) | ||
197 | except ValueError: | ||
198 | let (domain, hostname) = splitDomainHostname(target) | ||
199 | let addrInfo = getAddrInfo(hostname, Port 0, domain) | ||
200 | defer: freeAddrInfo(addrInfo) | ||
201 | addrInfo.toIpAddress | ||
202 | |||
203 | |||
170 | type PingMonitor = ref object | 204 | type PingMonitor = ref object |
171 | socket: Socket | 205 | socket: Socket |
172 | target: IpAddress | 206 | target: IpAddress |