Hi!
I am new to Apple app development so please bear with me.
I am trying to design an app that can mimic some of the functionality of iptables routing. The crux of it is I would like to redirect local traffic bound for a specific port to a different port and then redirect any outgoing traffic on that port back to the original port:
outgoing packet bound for IP:1234 -> 127.0.0.1:2345
outgoing packet bound for IP:2345 -> IP:1234
I tried to implement this behavior with a packet tunnel but have not made any substantial progress. Is this the right approach?
Here is my implementation:
private func handleConnection(_ connection: NWConnection) {
connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { [weak self] data, context, isComplete, error in
if let data = data, !data.isEmpty {
self?.processData(data, from: connection)
}
if let error = error {
print("Connection error: \(error)")
}
if isComplete {
connection.cancel()
} else {
self?.handleConnection(connection) // Continue to receive data
}
}
connection.start(queue: .main)
}
private func processData(_ data: Data, from connection: NWConnection) {
switch connection.endpoint {
case .hostPort(let host, let port):
let portNumber = port.rawValue
let hostDescription = host.debugDescription
print("Received data from host: \(hostDescription) on port: \(portNumber)")
if portNumber == 1234 {
// Rule 1: Redirect traffic from port 1234 to 127.0.0.1:2345
redirectTraffic(data, to: "127.0.0.1", port: 2345)
print("Redirecting traffic from 1234 to 2345")
} else if portNumber == 2345 {
// Rule 2: Redirect traffic from port 2345 to the original IP address but port 1234
redirectTraffic(data, to: hostDescription, port: 1234)
print("Redirecting traffic from 2345 back to 1234")
}
case .service(name: _, type: _, domain: _, interface: _):
print("Received bonjour service")
case .unix(path: _):
print("Received unix domain path")
case .url(_):
print("Received url")
case .opaque(_):
print("Opaque?")
@unknown default:
fatalError("Unknown endpoint type")
}
}