/* See LICENSE folder for this sample’s licensing information. Abstract: This file contains the implementation of the NEFilterDataProvider sub-class. */ import NetworkExtension import os.log /** The FilterDataProvider class handles connections that match the installed rules by prompting the user to allow or deny the connections. */ class FilterDataProvider: NEFilterDataProvider { // MARK: Properties // The TCP port which the filter is interested in. static let localPort = "8888" // MARK: NEFilterDataProvider override func startFilter(completionHandler: @escaping (Error?) -> Void) { // Filter incoming TCP connections on port 8888 let filterRules = ["0.0.0.0", "::"].map { address -> NEFilterRule in let localNetwork = NWHostEndpoint(hostname: address, port: "0") let inboundNetworkRule = NENetworkRule(remoteNetwork: nil, remotePrefix: 0, localNetwork: localNetwork, localPrefix: 0, protocol: .any, direction: .any) return NEFilterRule(networkRule: inboundNetworkRule, action: .filterData) } // Allow all flows that do not match the filter rules. let filterSettings = NEFilterSettings(rules: filterRules, defaultAction: .allow) apply(filterSettings) { error in if let applyError = error { os_log("Failed to apply filter settings: %@", applyError.localizedDescription) } completionHandler(error) os_log("started"); } } override func stopFilter(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { completionHandler() } override func handleNewFlow(_ flow: NEFilterFlow) -> NEFilterNewFlowVerdict { os_log("[NEW] flow %{public}@ %{public}p %{public}@", flow.identifier as CVarArg, flow, flow) return .allow() } }