swift crash when getcurrentip address : FixedWidthInteger.init<A> - swift

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

why cannot read the receipt data for on-device validation

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).

Swift “UDP Read” code - unsaferawbufferpointer compile error

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
}

Swift Building IP 4 address class for a iOS project

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

Get NetworkIp in Swift 3

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
}

Get the currently active network adapter in Swift

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