Swift Network.framework: получите интерфейс NWInterface для интерфейса rnet без IP-подключения - PullRequest
1 голос
/ 23 января 2020

В беседах «Усовершенствования в сети» для WWDC2019 был приведен пример использования NWEthernetChannel для мониторинга пользовательского (не IP) протокола. Это для MacOS.

import Foundation
import Network
let path = NWPathMonitor(requiredInterfaceType: .wiredEthernet).currentPath
guard let interface = path.availableInterfaces.first else {
  fatalError("not connected to Internet")
}
let channel = NWEthernetChannel(on: interface, etherType: 0xB26E)

Для моего приложения мне нужно использовать NWEthernetChannel для мониторинга пользовательского протокола (фактически протокола обнаружения Cisco и / или протокола обнаружения канального уровня) на Ethe rnet ссылка, которая не имеет IP-соединения Inte rnet (но имеет физическую ссылку на коммутатор). NWPath, по-видимому, дает мне структуру NWInterface только в том случае, если это допустимый путь к Inte rnet.

Как я могу получить список NWInterface Structs на Ma c, не имея действительного Inte rnet путь?

В моем конкретном случае использования меня интересует только .wiredEthernet.

Что-то настолько простое, что было бы достаточно получить полный массив всех NWInterfaces на коробке , но до сих пор единственный способ «продать» NWInterfaces, который я нашел, - это NWPathMonitor, который, кажется, требует подключения по IP.

1 Ответ

1 голос
/ 30 апреля 2020

Вы можете получить NWIntferface, если знаете его соответствующее имя BSD. В документации IPv4Address.init(_:) говорится, что вы можете указать имя интерфейса после IP-адреса, разделенное %.

/// Create an IP address from an address literal string.
/// If the string contains '%' to indicate an interface, the interface will be
/// associated with the address, such as "::1%lo0" being associated with the loopback
/// interface.
/// This function does not perform host name to address resolution. This is the same as calling getaddrinfo
/// and using AI_NUMERICHOST.

. Эту документацию можно найти только в сгенерированном интерфейсе swift, но не в веб-сайт.

Платформа SystemConfiguration предоставляет функциональность для получения списка всех интерфейсов с соответствующими именами BSD.

import Foundation
import Network
import SystemConfiguration

// get all interfaces
let interfaces = SCNetworkInterfaceCopyAll() as? Array<SCNetworkInterface> ?? []
// convert to NWInterface
let nwInterfaces = interfaces.compactMap { interface -> NWInterface? in
    guard let bsdName = SCNetworkInterfaceGetBSDName(interface) else { return nil }
    return IPv4Address("127.0.0.1%\(bsdName)")?.interface
}

print(interfaces)

Это работает хорошо, но это похоже на обходной путь. Я бы sh Network.framework предоставил бы лучший вариант для получения всех интерфейсов.

...