diff --git a/StikJIT/Tunnel/IPv4PacketRewriter.swift b/StikJIT/Tunnel/IPv4PacketRewriter.swift new file mode 100644 index 0000000..e8ed021 --- /dev/null +++ b/StikJIT/Tunnel/IPv4PacketRewriter.swift @@ -0,0 +1,16 @@ +// +// IPv4PacketRewriter.swift +// StikDebug +// + +enum IPv4PacketRewriter { + static func swapEndpoints(in packet: inout [UInt8]) { + guard packet.count >= 20, packet[0] >> 4 == 4 else { + return + } + + for offset in 0..<4 { + packet.swapAt(12 + offset, 16 + offset) + } + } +} diff --git a/StikJIT/Tunnel/StikDebugTunnelConfiguration.swift b/StikJIT/Tunnel/StikDebugTunnelConfiguration.swift new file mode 100644 index 0000000..116e0e8 --- /dev/null +++ b/StikJIT/Tunnel/StikDebugTunnelConfiguration.swift @@ -0,0 +1,31 @@ +// +// StikDebugTunnelConfiguration.swift +// StikDebug +// + +struct StikDebugTunnelConfiguration: Equatable { + static let interfaceIPKey = "interfaceIP" + static let peerIPKey = "peerIP" + + static let `default` = StikDebugTunnelConfiguration( + interfaceIP: "10.7.0.0", + peerIP: "10.7.0.1" + ) + + let interfaceIP: String + let peerIP: String + let peerPrefixLength: Int + + init(interfaceIP: String, peerIP: String, peerPrefixLength: Int = 32) { + self.interfaceIP = interfaceIP + self.peerIP = peerIP + self.peerPrefixLength = peerPrefixLength + } + + var providerConfiguration: [String: String] { + [ + Self.interfaceIPKey: interfaceIP, + Self.peerIPKey: peerIP, + ] + } +} diff --git a/StikJITTests/StikJITTests.swift b/StikJITTests/StikJITTests.swift index a52c821..4a3f514 100644 --- a/StikJITTests/StikJITTests.swift +++ b/StikJITTests/StikJITTests.swift @@ -11,6 +11,36 @@ import Testing struct StikJITTests { + @Test func embeddedTunnelDefaultsMatchLocalDevVPNEndpoint() { + let configuration = StikDebugTunnelConfiguration.default + + #expect(configuration.interfaceIP == "10.7.0.0") + #expect(configuration.peerIP == "10.7.0.1") + #expect(configuration.peerPrefixLength == 32) + #expect(configuration.providerConfiguration["interfaceIP"] == "10.7.0.0") + #expect(configuration.providerConfiguration["peerIP"] == "10.7.0.1") + } + + @Test func ipv4PacketRewriterSwapsPacketEndpoints() { + var packet = [UInt8](repeating: 0, count: 20) + packet.replaceSubrange(12..<16, with: [10, 7, 0, 2]) + packet.replaceSubrange(16..<20, with: [10, 7, 0, 1]) + + IPv4PacketRewriter.swapEndpoints(in: &packet) + + #expect(Array(packet[12..<16]) == [10, 7, 0, 1]) + #expect(Array(packet[16..<20]) == [10, 7, 0, 2]) + } + + @Test func ipv4PacketRewriterLeavesShortPacketsUnchanged() { + var packet = [UInt8](repeating: 0, count: 19) + let original = packet + + IPv4PacketRewriter.swapEndpoints(in: &packet) + + #expect(packet == original) + } + @Test func txmDetectionIgnoresFirmwareFileBeforeIOS26() async throws { let isSupported = ProcessInfo.hasTXMSupport( operatingSystemVersion: OperatingSystemVersion(majorVersion: 18, minorVersion: 7, patchVersion: 2),