I found this bug when tried to get ip address through wifi. After install fabric, i got this error
0 MY_APP 0x1020e538c specialized FixedWidthInteger.init<A>(_:radix:)
(My_Screen.swift)
After find the method error, i found this line :
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) linked to FixedWidthInteger:
public struct UInt8 : FixedWidthInteger, UnsignedInteger
I dont know why this problem triggered. can some one help?
Here i my full code to get currentIp address
func getIPAddress() -> String? {
var address: String?
var ifaddr: UnsafeMutablePointer<ifaddrs>? = nil
if getifaddrs(&ifaddr) == 0 {
var ptr = ifaddr
while ptr != nil {
defer { ptr = ptr?.pointee.ifa_next }
let interface = ptr?.pointee
let addrFamily = interface?.ifa_addr.pointee.sa_family
if addrFamily == UInt8(AF_INET) || addrFamily == UInt8(AF_INET6) {
if let name = String(cString: (interface?.ifa_name)!) as String?, name == "en0" {
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
getnameinfo(interface?.ifa_addr, socklen_t((interface?.ifa_addr.pointee.sa_len)!), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST)
address = String(cString: hostname)
}
}
}
freeifaddrs(ifaddr)
}
return address
}
UPDATE NOTE:
I have 4 devices ios 12.1 + 1 device ios 12.2, only 1 device ios 12.1 + ios device 12.2 crash, 3 other devices work normally.
Related
I am using the following code to read the receipt data. I can successfully validate the receipt signature by using OpenSSL static library 1.1.1k
private func readReceipt(_ receiptPKCS7: UnsafeMutablePointer<PKCS7>?) {
// Get a pointer to the start and end of the ASN.1 payload
let receiptSign = receiptPKCS7?.pointee.d.sign
let octets = receiptSign?.pointee.contents.pointee.d.data
var ptr = UnsafePointer(octets?.pointee.data)
let end = ptr!.advanced(by: Int(octets!.pointee.length))
var type: Int32 = 0
var xclass: Int32 = 0
var length: Int = 0
ASN1_get_object(&ptr, &length, &type, &xclass, ptr!.distance(to: end))
guard type == V_ASN1_SET else {
status = .unexpectedASN1Type
return
}
// 1
while ptr! < end {
// 2
ASN1_get_object(&ptr, &length, &type, &xclass, ptr!.distance(to: end))
guard type == V_ASN1_SEQUENCE else {
status = .unexpectedASN1Type
return
}
// 3 type
guard let attributeType = readASN1Integer(ptr: &ptr, maxLength: length) else {
status = .unexpectedASN1Type
return
}
print("shark-IAP, ", attributeType)
// 4 version
guard let _ = readASN1Integer(ptr: &ptr, maxLength: ptr!.distance(to: end)) else {
print("shark-IAP, 3")
status = .unexpectedASN1Type
return
}
// 5 value
ASN1_get_object(&ptr, &length, &type, &xclass, ptr!.distance(to: end))
guard type == V_ASN1_OCTET_STRING else {
print("shark-IAP, 4")
status = .unexpectedASN1Type
return
}
switch attributeType {
case 2: // The bundle identifier
var stringStartPtr = ptr
bundleIdString = readASN1String(ptr: &stringStartPtr, maxLength: length)
bundleIdData = readASN1Data(ptr: ptr!, length: length)
case 3: // Bundle version
var stringStartPtr = ptr
bundleVersionString = readASN1String(ptr: &stringStartPtr, maxLength: length)
case 4: // Opaque value
let dataStartPtr = ptr!
opaqueData = readASN1Data(ptr: dataStartPtr, length: length)
case 5: // Computed GUID (SHA-1 Hash)
let dataStartPtr = ptr!
hashData = readASN1Data(ptr: dataStartPtr, length: length)
case 12: // Receipt Creation Date
var dateStartPtr = ptr
receiptCreationDate = readASN1Date(ptr: &dateStartPtr, maxLength: length)
case 17: // IAP Receipt
var iapStartPtr = ptr
let parsedReceipt = IAPReceipt(with: &iapStartPtr, payloadLength: length)
if let newReceipt = parsedReceipt {
inAppReceipts.append(newReceipt)
}
case 19: // Original App Version
var stringStartPtr = ptr
originalAppVersion = readASN1String(ptr: &stringStartPtr, maxLength: length)
case 21: // Expiration Date
var dateStartPtr = ptr
expirationDate = readASN1Date(ptr: &dateStartPtr, maxLength: length)
default: // Ignore other attributes in receipt
print("Not processing attribute type: \(attributeType)")
}
// Advance pointer to the next item
ptr = ptr!.advanced(by: length)
} // end while
}
func readASN1Integer(ptr: inout UnsafePointer<UInt8>?, maxLength: Int) -> Int? {
var type: Int32 = 0
var xclass: Int32 = 0
var length: Int = 0
ASN1_get_object(&ptr, &length, &type, &xclass, maxLength)
guard type == V_ASN1_INTEGER else {
print("shark-IAP no!", type)
return nil
}
// let integerObject = c2i_ASN1_INTEGER(nil, &ptr, length)
let integerObject = d2i_ASN1_UINTEGER(nil, &ptr, length)
let intValue = ASN1_INTEGER_get(integerObject)
ASN1_INTEGER_free(integerObject)
return intValue
}
I got these print outputs. I suspect the function readASN1Integer is wrong. Maybe c2i_ASN1_INTEGER will be fine but this is deprecated in OpenSSL 1.1*, that d2i_ASN1_UINTEGER is used instead. And d2i_ASN1_UINTEGER needs to pass (identifier + length/octet + content), not just the content. In ASN1_get_object, the pointer has changed position. So d2i_ASN1_UINTEGER reads wrong. The first readASN1Integer causes bias that the second readASN1Integer throws error.
shark-IAP, 0
shark-IAP no! 8
shark-IAP, 3
shark-IAP, bundleVersionString nil
shark-IAP, expirationData nil
shark-IAP, 0
shark-IAP no! 8
shark-IAP, 3
shark-IAP, bundleVersionString nil
shark-IAP, expirationData nil
But I dont' know how to adjust the code to suit d2i_ASN1_UINTEGER. Thank you for your help!
Stackoverflow is a place to suppress devils.
I found the solution. I modified the readASN1Integer to this
func readASN1Integer(ptr: inout UnsafePointer<UInt8>?, maxLength: Int) -> Int? {
var type: Int32 = 0
var xclass: Int32 = 0
var length: Int = 0
let save_ptr = ptr
ASN1_get_object(&ptr, &length, &type, &xclass, maxLength)
guard type == V_ASN1_INTEGER else {
return nil
}
// let integerObject = c2i_ASN1_INTEGER(nil, &ptr, length)
ptr = save_ptr
let integerObject = d2i_ASN1_UINTEGER(nil, &ptr, maxLength)
let intValue = ASN1_INTEGER_get(integerObject)
ASN1_INTEGER_free(integerObject)
return intValue
}
Since the pointer position is changed, need to set it back, that's why save_ptr comes (referenced from c2i_ASN1_INTEGER function in Openssl 1.1.0)
d2i_ASN1_UINTEGER(nil, &ptr, length) is changed to d2i_ASN1_UINTEGER(nil, &ptr, maxLength). For every place, including in readReceipt, length should be maxLength or ptr!.distance(to: end).
I’m sure someone can solve this in seconds but I’m very new to swift, using playgrounds on the iPad. I’m trying to modify some SendUDP code to recieve instead, but I can’t solve the compile error (unsafepointer is not convertible to unsaferawbufferpointer) on the readResult= line. The SEND works fine with very similar code, but I’m really struggling here, way out of my depth...
Here’s the code
func readUDP() {
guard
let addresses =
try ? addressesFor(host: "192.168.4.1", port: 80)
else {
print("host not found")
return
}
if addresses.count != 1 {
print("host ambiguous; using the first one")
}
address = addresses[0]
fd1 = socket(Int32(address.ss_family), SOCK_DGRAM, 0)
guard fd1 >= 0
else {
print("`socket` failed`")
return
}
defer {
let junk = close(fd1)
assert(junk == 0)
}
var message = [UInt8](repeating: 0, count: 1024)
let messageCount = message.count
var readResult = message.withUnsafeBytes {
(messagePtr: UnsafePointer < UInt8 > ) - > Int in
return address.withSockAddr {
(sa, saLen) - > Int in
return recvfrom(fd1, messagePtr, messageCount, 0, sa, & saLen)
}
}
guard readResult >= 0
else {
print("read failed")
return
}
print("success")
}
You can use Swift's implicit bridging to simplify to something like this:
var message = [UInt8](repeating: 0, count: 1024)
let messageCount = message.count
var readResult = address.withSockAddr {
(sa, saLen) - > Int in
return recvfrom(fd1, &message, messageCount, 0, sa, &saLen)
}
guard readResult >= 0
else {
print("read failed")
return
}
I was trying to create my own class for IP Address. I want to use this for a iOS project. I'm trying to figure out were to put the code to put the range between 0 to 255. The separator isn't working correctly. I want it to hold a ip address like 192.168.0.1 if I enter 400.168.0.1 it should return a error or say please type a real ip address as one of the output that that something wrong. I trying to create a class that when you input a ip address it should hold in the class itself. I want make a iOS app later on that will help people figure how to distribute IP address for cisco routers and switches. basically want to make a app that helps people with CIDR ip address notations like this webpage program that I found online, but I can barely use without internet connection. http://jodies.de/ipcalc if I could program a mobile application that can do what this website would be great for my line of work in networking.
import UIKit
class IP4 {
var ipA: Int?
var ipB: Int?
var ipC: Int?
var ipD: Int?
func fullIP() -> Int {
var parts: [Int] = []
if let ipA = self.ipA {
parts += [ipA]
}
if let ipB = self.ipB {
parts += [ipB]
}
if let ipC = self.ipC {
parts += [ipC]
}
if let ipD = self.ipD {
parts += [ipD]
}
return parts.joined(separator: ".")
}
}
let ipaddress = IP4()
ipaddress.ipA = 223
ipaddress.ipB = 9
ipaddress.ipC = 50
ipaddress.ipD = 60
This is an example, which can be tested on the Playground. (Tested on Xcode 9.4.1.)
import Foundation
struct IPv4: CustomStringConvertible, Equatable, Hashable {
enum Errors: Error {
case invalidFormat
case octetOutOfRange
}
var ipA: UInt8
var ipB: UInt8
var ipC: UInt8
var ipD: UInt8
init() {
ipA = 0
ipB = 0
ipC = 0
ipD = 0
}
init(_ ipA: UInt8, _ ipB: UInt8, _ ipC: UInt8, _ ipD: UInt8) {
self.ipA = ipA
self.ipB = ipB
self.ipC = ipC
self.ipD = ipD
}
private static let parsingRegex = try! NSRegularExpression(pattern: "^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$")
init(_ ipString: String) throws {
guard let match = IPv4.parsingRegex.firstMatch(in: ipString, range: NSRange(0..<ipString.utf16.count)) else {
throw Errors.invalidFormat
}
let strA = ipString[Range(match.range(at: 1), in: ipString)!]
let strB = ipString[Range(match.range(at: 2), in: ipString)!]
let strC = ipString[Range(match.range(at: 3), in: ipString)!]
let strD = ipString[Range(match.range(at: 4), in: ipString)!]
guard
let ipA = UInt8(strA),
let ipB = UInt8(strB),
let ipC = UInt8(strC),
let ipD = UInt8(strD)
else {throw Errors.octetOutOfRange}
self.ipA = ipA
self.ipB = ipB
self.ipC = ipC
self.ipD = ipD
}
var description: String {
return "\(ipA).\(ipB).\(ipC).\(ipD)"
}
var networkBytes: Data {
return Data(bytes: [ipA, ipB, ipC, ipD])
}
var hostWord: UInt32 {
return UInt32(ipA) << 24 + UInt32(ipB) << 16 + UInt32(ipC) << 8 + UInt32(ipD)
}
}
let ip = IPv4(223, 9, 50, 60)
print(ip) //->223.9.50.60
do {
let ip = try IPv4("400.168.0.1")
print(ip)
} catch {
print(error) //->octetOutOfRange
}
Better use struct than class. As its equality should be judged by its contents, not by its address in the heap.
IPv4 address is made of 4 octets. You should better use UInt8, non-Optional. No parts can be nil.
There's no numeric type which can hold 3-decimal points. If you want to generate a notation like 192.168.0.1, it needs to be a String.
I have prepared 3 types of outputs. Think carefully which one you want.
Also find which part of my code is implementing if I enter 400.168.0.1 it should return a error.
I show you some extensions for my struct, which may be some help to make similar functionalities shown in the linked site.
To make binary representation:
extension UInt8 {
var fixedBinaryDescription: String {
let binStr = String(self, radix: 2)
return String(repeating: "0", count: 8-binStr.count) + binStr
}
}
extension IPv4 {
var binaryDescription: String {
return "\(ipA.fixedBinaryDescription).\(ipB.fixedBinaryDescription).\(ipC.fixedBinaryDescription).\(ipD.fixedBinaryDescription)"
}
}
print(ip.binaryDescription) //->11011111.00001001.00110010.00111100
To work with masks:
extension IPv4 {
init(maskOfLength len: Int) {
let highBits: [UInt8] = [
0b10000000,
0b11000000,
0b11100000,
0b11110000,
0b11111000,
0b11111100,
0b11111110,
0b11111111,
]
switch len {
case 0:
self = IPv4(0, 0, 0, 0)
case 1...8:
self = IPv4(highBits[len-1], 0, 0, 0)
case 9...16:
self = IPv4(0b11111111, highBits[len-9], 0, 0)
case 17...24:
self = IPv4(0b11111111, 0b11111111, highBits[len-17], 0)
case 25...32:
self = IPv4(0b11111111, 0b11111111, 0b11111111, highBits[len-25])
default:
fatalError()
}
}
func masked(by mask: IPv4) -> IPv4 {
return IPv4(self.ipA & mask.ipA, self.ipB & mask.ipB, self.ipC & mask.ipC, self.ipD & mask.ipD)
}
}
let mask = IPv4(maskOfLength: 24)
print(mask.binaryDescription) //->11111111.11111111.11111111.00000000
print(ip.masked(by: mask).binaryDescription) //->11011111.00001001.00110010.00000000
An extension to get address class of IP v4.
enum IPv4AddressClass {
case a
case b
case c
case d
case e
}
extension IPv4 {
var addressClass: IPv4AddressClass {
if ipA & 0b1_0000000 == 0b0_0000000 {
return .a
} else if ipA & 0b11_000000 == 0b10_000000 {
return .b
} else if ipA & 0b111_00000 == 0b110_00000 {
return .c
} else if ipA & 0b1111_0000 == 0b1110_0000 {
return .d
} else {
return .e
}
}
}
print(ip.addressClass) //->c
Any one help me to get Network IP (i.e 103.62.238.190) in Swift 3
I tried below code for it, but this function get System Ip.
I tried so many time to find the solution but still i didn't get any exact function for it.
func getIFAddresses() -> [String] {
var addresses = [String]()
// Get list of all interfaces on the local machine:
var ifaddr : UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&ifaddr) == 0 else { return [] }
guard let firstAddr = ifaddr else { return [] }
// For each interface ...
for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next }) {
let flags = Int32(ptr.pointee.ifa_flags)
var addr = ptr.pointee.ifa_addr.pointee
// Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
if (flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING) {
if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {
// Convert interface address to a human readable string:
var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
if (getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count),
nil, socklen_t(0), NI_NUMERICHOST) == 0) {
let address = String(cString: hostname)
addresses.append(address)
}
}
}
}
freeifaddrs(ifaddr)
return addresses
}
I am using the following code to get the network adapters of my macOS System:
private func getAdapters() -> [Adapter]
{
var adapters: [Adapter] = []
var addresses: UnsafeMutablePointer<ifaddrs>?
guard getifaddrs(&addresses) == 0 else { return adapters }
guard let firstAddr = addresses else { return adapters }
for ptr in sequence(first: firstAddr, next: { $0.pointee.ifa_next })
{
let address = ptr.pointee
let rawData = address.ifa_data
let name = address.ifa_name
let socket: sockaddr = address.ifa_addr.pointee
// Set up some filters
let loopback = (address.ifa_flags & UInt32(IFF_LOOPBACK)) != 0
let up = (address.ifa_flags & UInt32(IFF_UP)) != 0
let p2p = (address.ifa_flags & UInt32(IFF_POINTOPOINT)) != 0
if rawData != nil && name != nil && socket.sa_family == UInt8(AF_LINK) && !loopback && up && !p2p
{
let adapterName = String(utf8String: UnsafePointer<CChar>(name!))
let adapter = Adapter(name: adapterName!)
adapters.append(adapter)
}
}
freeifaddrs(addresses)
return adapters
}
Now I am looking for a way to figure out, which of those adapters is the "active" one, i.e. which one is connected to the internet.
I want to get the adapter that has the "green dot" in the network settings. How can I get this information?
Regards,
Sascha