sockets - कैसे तेजी से sockaddr_in करने के लिए sockadd डाली




swift3 casting (2)

आपको withMemoryRebound() का पता (जो एक वेरिएबल के लिए addr आवश्यकता होती है) लेना है, withMemoryRebound() के साथ अस्थायी रूप से इसे sockaddr_in पॉइंटर पर withMemoryRebound() करने के लिए उपयोग करें, जो तब dereferenced किया जा सकता है:

var addr: sockaddr = ...
let addr_in = withUnsafePointer(to: &addr) {
    $0.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {
        $0.pointee
    }
}

आपके defaultGatewayAddress() विधि में कुछ समस्याएं हैं:

  • sa = sa!.advanced(by: ROUNDUP(a: Int(sa!.pointee.sa_len))) sa_len द्वारा अग्रिम sa = sa!.advanced(by: ROUNDUP(a: Int(sa!.pointee.sa_len))) के आकार के साथ गुणा, जो कि आप क्या इरादा नहीं है।
  • परीक्षा if ((rt!.pointee.rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY)) for i in 0..<RTAX_MAX के for i in 0..<RTAX_MAX बाद किया जाना चाहिए for i in 0..<RTAX_MAX लूप
  • sa_tab.insert(sa!.pointee, at: Int(i)) आप नए तत्वों को उन्हें बदलने के बजाय सरणी में डालें

यह भी ध्यान दें कि

rt = p!.withMemoryRebound(to: rt_msghdr.self, capacity: 1, {$0})

यहां काम कर सकते हैं, लेकिन यह आम तौर पर असुरक्षित है: $0 पॉइंटर बंद होने के निष्पादन के लिए केवल वैध है और इसे बाहर नहीं किया जाना चाहिए

यहां आपके कोड का एक कार्यशील संस्करण है। यह अनिवार्य रूप से अनुवाद है कि मैं आईफ़ोन पर डिफ़ॉल्ट गेटवे कैसे निर्धारित करूं? स्विफ्ट के लिए (जो बदले में यह https://github.com/getlantern/libnatpmp/blob/master/getgateway.c पर बनाया गया लगता है)।

मैंने इसे थोड़ा सरलीकृत किया है और सभी को मजबूती से लपेटने से बचने के लिए संशोधित किया है।

func defaultGatewayAddress() -> in_addr? {

    var defaultGateway: in_addr?

    var mib:[Int32] = [CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY]
    var len = 0
    if sysctl(&mib, u_int(mib.count), nil, &len, nil, 0) < 0 {
        return nil
    }
    let buffer = UnsafeMutablePointer<CChar>.allocate(capacity: len)
    defer {
        buffer.deallocate(capacity: len)
    }
    if sysctl(&mib, u_int(mib.count), buffer, &len, nil, 0) < 0 {
        return nil
    }

    var sa_tab = [UnsafePointer<sockaddr>?](repeating: nil, count: Int(RTAX_MAX))

    var ptr = buffer
    while ptr < buffer + len {
        ptr.withMemoryRebound(to: rt_msghdr.self, capacity: 1) { rt in
            var sa = UnsafeMutableRawPointer(rt + 1).assumingMemoryBound(to: sockaddr.self)
            for i in 0..<RTAX_MAX {
                if rt.pointee.rtm_addrs & (1 << i) != 0 {
                    sa_tab[Int(i)] = UnsafePointer(sa)
                    sa = (UnsafeMutableRawPointer(sa) + Int(sa.pointee.sa_len)).assumingMemoryBound(to: sockaddr.self)
                } else {
                     sa_tab[Int(i)] =  nil
                }
            }

            if let dst = sa_tab[Int(RTAX_DST)],
                dst.pointee.sa_family == sa_family_t(AF_INET),
                let gateway = sa_tab[Int(RTAX_GATEWAY)],
                gateway.pointee.sa_family == sa_family_t(AF_INET)
            {
                dst.withMemoryRebound(to: sockaddr_in.self, capacity: 1) { addr in
                    if addr.pointee.sin_addr.s_addr == 0 {

                        var name = [CChar](repeating: CChar(0), count: Int(IFNAMSIZ) + 1)
                        if_indextoname(UInt32((rt.pointee.rtm_index)), &name)
                        if String(cString: name) == "en0" {
                            defaultGateway = gateway.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {
                                $0.pointee.sin_addr
                            }
                        }
                    }
                }

            }
            ptr += Int(rt.pointee.rtm_msglen)
        }
    }

    return defaultGateway
}
var sa_tab:[sockaddr?] = [sockaddr](repeating: sockaddr(), count: Int(RTAX_MAX))
let addr:sockaddr = sa_tab[Int(RTAX_DST)]!
let addr_in:sockaddr_in = unsafeBitCast(addr.self, to: UnsafeMutablePointer<sockaddr_in>.self).pointee

तीसरी पंक्ति में दुर्घटना हो रही है, असुरक्षित नहीं हो सकता। विभिन्न आकारों के प्रकार के बीच काट

यहां पूरी प्रक्रिया है

func ROUNDUP(a:Int) -> Int{
    if (a) > 0 {
        return (1 + (((a) - 1) | (MemoryLayout<CLong>.size - 1)))
    }
    else{

    return MemoryLayout<CLong>.size
    }
}

class func defaultGatewayAddress() -> Int{

        var addressIntValue:UInt32 = 0
        var mib:[Int32] = [CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY]
        let l = UnsafeMutablePointer<Int>.allocate(capacity: MemoryLayout<Int>.size)
        var buf: UnsafeMutablePointer<CChar>?
        var p: UnsafeMutablePointer<CChar>?
        var rt: UnsafeMutablePointer<rt_msghdr>?
        var sa:UnsafeMutablePointer<sockaddr>?
        var sa_tab:[sockaddr?] = [sockaddr](repeating: sockaddr(), count: Int(RTAX_MAX))
        var _:Int
        var r:Int = -1

        if(sysctl(&mib, u_int(mib.count), nil, l, nil, 0) < 0) {
            return -1;
        }
        print(Int8.max)
        print(Int8.min)
        if(l.pointee > 0) {

            buf = UnsafeMutablePointer<CChar>.allocate(capacity: l.pointee)

            if(sysctl(&mib, u_int(mib.count), buf, l, nil, 0) < 0) {
                return -1;
            }


            p = buf
            let maxBuf = buf!.advanced(by: l.pointee)

            while (p! < maxBuf) {

                rt = p!.withMemoryRebound(to: rt_msghdr.self, capacity: 1, {$0})
                sa = rt!.advanced(by: 1).withMemoryRebound(to: sockaddr.self, capacity: 1, {$0})

                for i in 0..<RTAX_MAX {
                    if (rt!.pointee.rtm_addrs & (1 << i)) == 1{
                        print("insert \(sa!.pointee) at \(i)")
                        sa_tab.insert(sa!.pointee, at: Int(i))
                        sa = sa!.advanced(by: ROUNDUP(a: Int(sa!.pointee.sa_len)))
                    }
                    else{
                        sa_tab.insert(nil, at: Int(i))
                    }
                    if ((rt!.pointee.rtm_addrs & (RTA_DST|RTA_GATEWAY)) ==  (RTA_DST|RTA_GATEWAY)) &&
                        (sa_tab[Int(RTAX_DST)]?.sa_family == sa_family_t(AF_INET)) &&
                        (sa_tab[Int(RTAX_GATEWAY)]?.sa_family == sa_family_t(AF_INET)){

                        var addr:sockaddr = sa_tab[Int(RTAX_DST)]!

                        let addr_in:sockaddr_in = withUnsafePointer(to: &addr) {
                            $0.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {
                                $0.pointee
                            }
                        }

                        if addr_in.sin_addr.s_addr == 0 {
                            var buffer = [CChar](repeating: CChar(0), count: Int(IFNAMSIZ) + 1)
                            let result = if_indextoname(UInt32((rt?.pointee.rtm_index)!), &buffer)
                            var char = "en0".cString(using: .utf8)
                            #if arch(i386) || arch(x86_64)
                                // This is a Simulator not an idevice
                                char = "en1".cString(using: .utf8)
                            #endif

                            if(strcmp(result, char) == 0){
                                r = 0
                                var gatewayAddr:sockaddr = sa_tab[Int(RTAX_GATEWAY)]!

                                let gatewayAddr_in:sockaddr_in = withUnsafePointer(to: &gatewayAddr) {
                                    $0.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {
                                        $0.pointee
                                    }
                                }
                                addressIntValue = gatewayAddr_in.sin_addr.s_addr
                            }
                        }


                    }
                }

                p = p?.advanced(by: Int((rt?.pointee.rtm_msglen)!))

            }

            buf!.deallocate(capacity: l.pointee)

            let gatewayLongAddress:UInt32 = addressIntValue

            print("gatewayLongAddress: \(gatewayLongAddress)")

            let gatewayIPAddress = String(format:"%d.%d.%d.%d", (gatewayLongAddress & 0xFF),
                                          ((gatewayLongAddress >> 8) & 0xFF),
                                          ((gatewayLongAddress >> 16) & 0xFF),
                                          ((gatewayLongAddress >> 24) & 0xFF))

            print("gatewayIPAddress: \(gatewayIPAddress)")

        }

        return Int(addressIntValue)
    }

इस मुद्दे के लिए मार्टिन के उत्तर के लिए धन्यवाद, नीचे दिए गए गेटवे पता प्राप्त करने के लिए तय किए गए अन्य क्षेत्रों के साथ:

class func defaultGatewayAddress() -> Int{

        var addressIntValue:UInt32 = 0
        var mib:[Int32] = [CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_GATEWAY]
        let l = UnsafeMutablePointer<Int>.allocate(capacity: MemoryLayout<Int>.size)
        var buf: UnsafeMutableRawPointer?
        var p: UnsafeMutableRawPointer?
        var rt: UnsafeMutablePointer<rt_msghdr>?


        var sa_tab:[sockaddr?] = [sockaddr](repeating: sockaddr(), count: Int(RTAX_MAX))

        let lengthSysctl = Darwin.sysctl(UnsafeMutablePointer<Int32>(mutating: &mib), UInt32(mib.count), nil, l, nil, 0)

        if(lengthSysctl < 0) {
            return -1;
        }
        if(l.pointee > 0) {

            buf = malloc(l.pointee)

            let bufferSysctl = Darwin.sysctl(UnsafeMutablePointer<Int32>(mutating: &mib), UInt32(mib.count), buf, l, nil, 0)

            if(bufferSysctl < 0) {
                return -1;
            }

            p = buf
            let maxBuf = buf!.advanced(by: l.pointee)



            while (p! < maxBuf) {

                rt = p!.assumingMemoryBound(to: rt_msghdr.self)

                let destBuf = p!.advanced(by: MemoryLayout<rt_msghdr>.size)
                let gatewayBuf = p!.advanced(by: MemoryLayout<rt_msghdr>.size+MemoryLayout<sockaddr>.size*1)
                let netmaskBuf = p!.advanced(by: MemoryLayout<rt_msghdr>.size+MemoryLayout<sockaddr>.size*2)
                let interfaceNameBuf = p!.advanced(by: MemoryLayout<rt_msghdr>.size+MemoryLayout<sockaddr>.size*4)
                let interfaceAddrBuf = p!.advanced(by: MemoryLayout<rt_msghdr>.size+MemoryLayout<sockaddr>.size*5)


                let dest_sa = destBuf.assumingMemoryBound(to: sockaddr.self)
                let gateway_sa = gatewayBuf.assumingMemoryBound(to: sockaddr.self)
                let netmask_sa = netmaskBuf.assumingMemoryBound(to: sockaddr.self)
                let interfaceName_sa = interfaceNameBuf.assumingMemoryBound(to: sockaddr.self)
                let interfaceAddr_sa = interfaceAddrBuf.assumingMemoryBound(to: sockaddr.self)

                let sockAddrs:[Int32:UnsafeMutablePointer<sockaddr>] = [RTAX_DST:dest_sa, RTAX_GATEWAY:gateway_sa, RTAX_NETMASK:netmask_sa, RTAX_IFP:interfaceName_sa, RTAX_IFA:interfaceAddr_sa]
                for (index, pointer) in sockAddrs {


                    let bin = (rt!.pointee.rtm_addrs & (1 << index))
                    if bin > 0{
                        sa_tab.insert(pointer.pointee, at: Int(index))
                    }
                    else{
                        sa_tab.insert(nil, at: Int(index))
                    }
                }


                print("RTA_DST -> \((sa_tab[Int(RTAX_DST)]?.sa_family == sa_family_t(AF_INET)))")
                print("RTA_GATEWAY -> \((sa_tab[Int(RTAX_GATEWAY)]?.sa_family == sa_family_t(AF_INET)))")
                print("RTAX_DST -> \(RTAX_DST)")
                print("RTAX_GATEWAY -> \(RTAX_GATEWAY)")

                if ((rt!.pointee.rtm_addrs & (RTA_DST|RTA_GATEWAY)) ==  (RTA_DST|RTA_GATEWAY)) &&
                    (sa_tab[Int(RTAX_DST)]?.sa_family == sa_family_t(AF_INET)) &&
                    (sa_tab[Int(RTAX_GATEWAY)]?.sa_family == sa_family_t(AF_INET)){

                    var addr:sockaddr = sa_tab[Int(RTAX_DST)]!

                    let addr_in:sockaddr_in = withUnsafePointer(to: &addr) {
                        $0.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {
                            $0.pointee
                        }
                    }

                    if addr_in.sin_addr.s_addr == 0 {
                        var buffer = [CChar](repeating: CChar(0), count: Int(IFNAMSIZ) + 1)
                        let result = if_indextoname(UInt32((rt?.pointee.rtm_index)!), &buffer)
                        var char = "en0".cString(using: .utf8)
                        #if arch(i386) || arch(x86_64)
                            // This is a Simulator not an idevice
                            char = "en0".cString(using: .utf8)
                        #endif

                        if(strcmp(result, char) == 0){
                            var gatewayAddr:sockaddr = sa_tab[Int(RTAX_GATEWAY)]!

                            let gatewayAddr_in:sockaddr_in = withUnsafePointer(to: &gatewayAddr) {
                                $0.withMemoryRebound(to: sockaddr_in.self, capacity: 1) {
                                    $0.pointee
                                }
                            }
                            addressIntValue = gatewayAddr_in.sin_addr.s_addr
                        }
                    }



                }

                p = p?.advanced(by: Int((rt?.pointee.rtm_msglen)!))

            }

            //            buf!.deallocate

            let gatewayLongAddress:UInt32 = addressIntValue

            print("gatewayLongAddress: \(gatewayLongAddress)")

            let gatewayIPAddress = String(format:"%d.%d.%d.%d", (gatewayLongAddress & 0xFF),
                                          ((gatewayLongAddress >> 8) & 0xFF),
                                          ((gatewayLongAddress >> 16) & 0xFF),
                                          ((gatewayLongAddress >> 24) & 0xFF))

            print("gatewayIPAddress: \(gatewayIPAddress)")

        }

        return Int(addressIntValue)
    }






casting