115 lines
3.7 KiB
Swift
Executable File
115 lines
3.7 KiB
Swift
Executable File
import Foundation
|
|
|
|
public struct Utils {
|
|
public struct HTTPData {
|
|
public static let DoubleCRLF = "\r\n\r\n".data(using: String.Encoding.utf8)!
|
|
public static let CRLF = "\r\n".data(using: String.Encoding.utf8)!
|
|
public static let ConnectSuccessResponse = "HTTP/1.1 200 Connection Established\r\n\r\n".data(using: String.Encoding.utf8)!
|
|
}
|
|
|
|
public struct DNS {
|
|
// swiftlint:disable:next nesting
|
|
public enum QueryType {
|
|
// swiftlint:disable:next type_name
|
|
case a, aaaa, unspec
|
|
}
|
|
|
|
public static func resolve(_ name: String, type: QueryType = .unspec) -> String {
|
|
let remoteHostEnt = gethostbyname2((name as NSString).utf8String, AF_INET)
|
|
|
|
if remoteHostEnt == nil {
|
|
return ""
|
|
}
|
|
|
|
let remoteAddr = UnsafeMutableRawPointer(remoteHostEnt?.pointee.h_addr_list[0])
|
|
|
|
var output = [Int8](repeating: 0, count: Int(INET6_ADDRSTRLEN))
|
|
inet_ntop(AF_INET, remoteAddr, &output, socklen_t(INET6_ADDRSTRLEN))
|
|
return NSString(utf8String: output)! as String
|
|
}
|
|
}
|
|
|
|
// swiftlint:disable:next type_name
|
|
public struct IP {
|
|
public static func isIPv4(_ ipAddress: String) -> Bool {
|
|
if IPv4ToInt(ipAddress) != nil {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
public static func isIPv6(_ ipAddress: String) -> Bool {
|
|
let utf8Str = (ipAddress as NSString).utf8String
|
|
var dst = [UInt8](repeating: 0, count: 16)
|
|
return inet_pton(AF_INET6, utf8Str, &dst) == 1
|
|
}
|
|
|
|
public static func isIP(_ ipAddress: String) -> Bool {
|
|
return isIPv4(ipAddress) || isIPv6(ipAddress)
|
|
}
|
|
|
|
public static func IPv4ToInt(_ ipAddress: String) -> UInt32? {
|
|
let utf8Str = (ipAddress as NSString).utf8String
|
|
var dst = in_addr(s_addr: 0)
|
|
if inet_pton(AF_INET, utf8Str, &(dst.s_addr)) == 1 {
|
|
return UInt32(dst.s_addr)
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public static func IPv4ToBytes(_ ipAddress: String) -> [UInt8]? {
|
|
if let ipv4int = IPv4ToInt(ipAddress) {
|
|
return Utils.toByteArray(ipv4int).reversed()
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
public static func IPv6ToBytes(_ ipAddress: String) -> [UInt8]? {
|
|
let utf8Str = (ipAddress as NSString).utf8String
|
|
var dst = [UInt8](repeating: 0, count: 16)
|
|
if inet_pton(AF_INET6, utf8Str, &dst) == 1 {
|
|
return Utils.toByteArray(dst).reversed()
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// struct GeoIPLookup {
|
|
//
|
|
// static func Lookup(_ ipAddress: String) -> String? {
|
|
// if Utils.IP.isIP(ipAddress) {
|
|
// guard let result = GeoIP.LookUp(ipAddress) else {
|
|
// return "--"
|
|
// }
|
|
// return result.isoCode
|
|
// } else {
|
|
// return nil
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
static func toByteArray<T>(_ value: T) -> [UInt8] {
|
|
var value = value
|
|
return withUnsafeBytes(of: &value) {
|
|
Array($0)
|
|
}
|
|
}
|
|
|
|
struct Random {
|
|
static func fill(data: inout Data, from: Int = 0, to: Int = -1) {
|
|
let c = data.count
|
|
data.withUnsafeMutableBytes {
|
|
arc4random_buf($0.baseAddress!.advanced(by: from), to == -1 ? c - from : to - from)
|
|
}
|
|
}
|
|
|
|
static func fill(data: inout Data, from: Int = 0, length: Int) {
|
|
fill(data: &data, from: from, to: from + length)
|
|
}
|
|
}
|
|
}
|