VMConfigNetworkView.swift 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //
  2. // Copyright © 2020 osy. All rights reserved.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. //
  16. import SwiftUI
  17. #if os(macOS)
  18. import Virtualization
  19. #endif
  20. struct VMConfigNetworkView: View {
  21. @AppStorage("HostNetworks") var hostNetworksData: Data = Data()
  22. @Binding var config: UTMQemuConfigurationNetwork
  23. @Binding var system: UTMQemuConfigurationSystem
  24. @State private var hostNetworks: [UTMConfigurationHostNetwork] = []
  25. @State private var showAdvanced: Bool = false
  26. private func loadData() {
  27. hostNetworks = (try? PropertyListDecoder().decode([UTMConfigurationHostNetwork].self, from: hostNetworksData)) ?? []
  28. }
  29. var body: some View {
  30. VStack {
  31. Form {
  32. Section(header: Text("Hardware")) {
  33. #if os(macOS)
  34. VMConfigConstantPicker("Network Mode", selection: $config.mode)
  35. if config.mode == .bridged {
  36. Picker("Bridged Interface", selection: $config.bridgeInterface) {
  37. Text("Automatic")
  38. .tag(nil as String?)
  39. ForEach(VZBridgedNetworkInterface.networkInterfaces, id: \.identifier) { interface in
  40. Text(interface.localizedDisplayName.map { "\($0) (\(interface.identifier))" } ?? interface.identifier)
  41. .tag(interface.identifier as String?)
  42. }
  43. }
  44. }
  45. if config.mode == .host {
  46. Picker("Host Network", selection: $config.hostNetUuid) {
  47. Text("Default (private)")
  48. .tag(nil as String?)
  49. ForEach(hostNetworks) { interface in
  50. Text(interface.name)
  51. .tag(interface.uuid as String?)
  52. }
  53. }.help("You can configure additional host networks in UTM Settings.")
  54. if config.hostNetUuid != nil {
  55. Text("Note: No DHCP will be provided by UTM")
  56. }
  57. }
  58. #endif
  59. VMConfigConstantPicker("Emulated Network Card", selection: $config.hardware, type: system.architecture.networkDeviceType)
  60. }.onAppear(perform: loadData)
  61. HStack {
  62. DefaultTextField("MAC Address", text: $config.macAddress, prompt: "00:00:00:00:00:00")
  63. Button("Random") {
  64. config.macAddress = UTMQemuConfigurationNetwork.randomMacAddress()
  65. }
  66. }
  67. Toggle(isOn: $showAdvanced.animation(), label: {
  68. Text("Show Advanced Settings")
  69. })
  70. if showAdvanced {
  71. Section(header: Text("IP Configuration")) {
  72. IPConfigurationSection(config: $config).multilineTextAlignment(.trailing)
  73. }
  74. }
  75. #if os(macOS)
  76. /// Bridged and shared networking doesn't support port forwarding
  77. if #unavailable(macOS 12), config.mode == .emulated {
  78. VMConfigNetworkPortForwardLegacyView(config: $config)
  79. }
  80. #else
  81. VMConfigNetworkPortForwardView(config: $config)
  82. #endif
  83. }
  84. }
  85. }
  86. }
  87. struct VMConfigNetworkingView_Previews: PreviewProvider {
  88. @State static private var config = UTMQemuConfigurationNetwork()
  89. @State static private var system = UTMQemuConfigurationSystem()
  90. static var previews: some View {
  91. VMConfigNetworkView(config: $config, system: $system)
  92. }
  93. }