punchnet-macos/Tun/Punchnet/SDLUtil.swift
2026-04-10 15:23:12 +08:00

108 lines
3.3 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Util.swift
// Tun
//
// Created by on 2024/1/19.
//
import Foundation
import SystemConfiguration
import Network
struct SDLUtil {
public static func int32ToIp(_ num: UInt32) -> String {
let ip0 = (UInt8) (num >> 24 & 0xFF)
let ip1 = (UInt8) (num >> 16 & 0xFF)
let ip2 = (UInt8) (num >> 8 & 0xFF)
let ip3 = (UInt8) (num & 0xFF)
return "\(ip0).\(ip1).\(ip2).\(ip3)"
}
public static func netMaskIp(maskLen: UInt8) -> String {
let len0 = 32 - maskLen
let num: UInt32 = (0xFFFFFFFF >> len0) << len0
let ip0 = (UInt8) (num >> 24 & 0xFF)
let ip1 = (UInt8) (num >> 16 & 0xFF)
let ip2 = (UInt8) (num >> 8 & 0xFF)
let ip3 = (UInt8) (num & 0xFF)
return "\(ip0).\(ip1).\(ip2).\(ip3)"
}
public static func ipv4StrToInt32(_ ip: String) -> UInt32? {
let parts = ip.split(separator: ".")
guard parts.count == 4 else {
return nil
}
var result: UInt32 = 0
for part in parts {
guard let byte = UInt8(part) else { return nil }
result = (result << 8) | UInt32(byte)
}
return result
}
// ip
public static func inSameNetwork(ip: UInt32, compareIp: UInt32, maskLen: UInt8) -> Bool {
if ip == compareIp {
return true
}
let len0 = 32 - maskLen
//
let mask: UInt32 = (0xFFFFFFFF >> len0) << len0
return ip & mask == compareIp & mask
}
public static func formatMacAddress(mac: Data) -> String {
let bytes = [UInt8](mac)
return bytes.map { String(format: "%02X", $0) }.joined(separator: ":").lowercased()
}
public static func getMacOSSystemDnsServers() -> [String] {
var results = [String]()
// DNS
if let dict = SCDynamicStoreCopyValue(nil, "State:/Network/Global/DNS" as CFString) as? [String: Any] {
if let servers = dict["ServerAddresses"] as? [String] {
results = servers
}
}
return results
}
//
static func resolveHostname(host: String) async -> String? {
let endpoint = NWEndpoint.hostPort(host: NWEndpoint.Host(host), port: 53)
let parameters = NWParameters.udp
// 使 utun
parameters.prohibitedInterfaceTypes = [.other]
let connection = NWConnection(to: endpoint, using: parameters)
return await withCheckedContinuation { continuation in
connection.stateUpdateHandler = { state in
if case .ready = state {
if let path = connection.currentPath,
case .hostPort(let resolvedHost, _) = path.remoteEndpoint {
let ip = String(describing: resolvedHost)
continuation.resume(returning: ip)
connection.cancel()
}
} else if case .failed = state {
continuation.resume(returning: nil)
}
}
connection.start(queue: .global())
}
}
}