class NotSetup def to_s(io : IO) io << "not setup" end end class Autoconfiguration def to_s(io : IO) io << "autoconfiguration" end end class DHCP def to_s(io : IO) io << "dhcp" end end class WirelessAPSetup property ifname : String property ssid : String # This is a list of parameters that should be unique to each AP property up : Bool property description : String? property mtu : Int32? property main_ip_v4 : IPAddress | DHCP | NotSetup property main_ip_v6 : IPAddress | DHCP | Autoconfiguration | NotSetup property aliasses_v4 : Array(IPAddress) property aliasses_v6 : Array(IPAddress) property dns : NetworkCommands::DNS # we currently only support WPA2-PSK wireless security mechanism property security : WPA class WPA property key : String def initialize(@key) end def to_s(io : IO) io << "WPA access point, key #{key}" end end def initialize(@ifname, @ssid, @security) @main_ip_v4 = NotSetup.new @main_ip_v6 = NotSetup.new @aliasses_v4 = Array(IPAddress).new @aliasses_v6 = Array(IPAddress).new @up = true @dns = NetworkCommands::DNS.new end def to_s(io : IO) io << indent(1, to_string) end def to_string String.build do |str| str << "#{CBLUE}#{ssid}#{CRESET}\n" str << "\t#description #{description.not_nil!}\n" unless description.nil? str << "\t#{@up? "up" : "down"}\n" str << "\tmtu #{mtu}\n" unless mtu.nil? # ipv4 unless main_ip_v4.is_a?(NotSetup) str << "\tinet #{main_ip_v4}\n" aliasses_v4.each do |a| str << "\talias #{a}\n" end end # ipv6 unless main_ip_v6.is_a?(NotSetup) str << "\tinet6 #{main_ip_v6}\n" @aliasses_v6.each do |a| str << "\talias6 #{a}\n" end end str << indent(1, dns.to_s) unless dns.addresses.empty? end end def store_access_point_keys NetworkCommands.store_access_point_keys ssid, security end def execute puts "TODO: wireless configuration" NetworkCommands.wireless_access_point_connection ifname, ssid # DNS configuration dns.execute end end # # interface configuration # class InterfaceConfiguration property name : String property up : Bool property description : String? property mtu : Int32? property main_ip_v4 : IPAddress | DHCP | NotSetup property main_ip_v6 : IPAddress | Autoconfiguration | DHCP | NotSetup property aliasses_v4 : Array(IPAddress) property aliasses_v6 : Array(IPAddress) property wireless_networks : Hash(String, WirelessAPSetup) property dns : NetworkCommands::DNS def initialize (@name, @up, @description, @mtu, @main_ip_v4, @main_ip_v6, aliasses, @wireless_networks, @dns ) @aliasses_v4 = Array(IPAddress).new @aliasses_v6 = Array(IPAddress).new aliasses.each do |ip| if ip.ipv4? aliasses_v4 << ip else aliasses_v6 << ip end end end def to_s(io : IO) io << to_string end def to_string String.build do |str| if NetworkCommands.interface_exists(@name) str << "#{CGREEN}#{@name}#{CRESET}\n" else str << "#{CRED}#{@name}#{CRESET}\n" end str << "\tdescription: '#{description.not_nil!}'\n" unless description.nil? str << "\t#{@up? "up" : "down"}\n" unless mtu.nil? str << "\tmtu #{mtu}\n" end # ipv4 unless main_ip_v4.is_a?(NotSetup) str << "\tinet #{main_ip_v4}\n" aliasses_v4.each do |a| str << "\talias #{a}\n" end end # warning: alias but no main ip address if main_ip_v4.is_a?(NotSetup) && ! aliasses_v4.empty? str << "\t#{CRED}alias configured but no main ipv4 configuration.#{CRESET}\n" str << "\t#{CRED}Should main ipv4 be obtained from DHCP? Static configuration?#{CRESET}\n" end # ipv6 unless main_ip_v6.is_a?(NotSetup) str << "\tinet6 #{main_ip_v6}\n" aliasses_v6.each do |a| str << "\talias6 #{a}\n" end end # warning: alias but no main ip address if main_ip_v6.is_a?(NotSetup) && ! aliasses_v6.empty? str << "\t#{CRED}alias6 configured but no main ipv6 configuration.#{CRESET}\n" str << "\t#{CRED}Should main ipv6 be obtained from autoconfiguration? DHCP? Static configuration?#{CRESET}\n" end str << indent(1, dns.to_s) unless dns.addresses.empty? unless wireless_networks.empty? wireless_networks.each do |k,v| str << v end end end end def access_point_connection ssid_list = NetworkCommands.scan name if ssid_list.nil? raise "no ssid scanned" end if wireless_networks.empty? raise "no configured access point for interface #{name}, cannot connect" end wireless_networks.each do |k,v| ssid_list.each do |ssid| if k == ssid puts "#{CGREEN}#{k} == #{ssid}#{CRESET}" v.execute end end end # TODO: sleep for a second before testing the gateway? # TODO: configuring the interface puts "TODO: connectivity check with the gateway" end def store_access_point_keys if wireless_networks.empty? raise "no configured access point for interface #{name}" end wireless_networks.each do |ssid, wireless_configuration| puts "#{CGREEN}storing access point key for #{ssid}#{CRESET}" wireless_configuration.store_access_point_keys end end # configure the interface def execute unless NetworkCommands.interface_exists(@name) raise "The interface #{@name} doesn't exists, yet." end if up NetworkCommands.up name else puts "not marked as 'up' -- ending here" return end unless mtu.nil? NetworkCommands.mtu name, mtu end unless description.nil? NetworkCommands.description name, description.not_nil! end # TODO: treat differently wireless and non-wireless interfaces if @wireless_networks.empty? puts "interface #{name} is not wireless" else puts "interface #{name} is wireless: connection to the access point" store_access_point_keys access_point_connection end # ipv4 configuration main_ip_v4.tap do |ip| case ip when IPAddress NetworkCommands.set_ip name, ip when DHCP NetworkCommands.dhcp name when NotSetup # do nothing else raise "ipv4 configuration: neither static nor dynamic" end # We wont setup aliasses unless there is an actual IP address if ip != NotSetup aliasses_v4.each do |ip_alias| NetworkCommands.set_alias name, ip_alias end end end # ipv6 configuration main_ip_v6.tap do |ip| case ip when IPAddress NetworkCommands.set_ip name, ip when Autoconfiguration NetworkCommands.autoconfiguration name when DHCP NetworkCommands.dhcp6 name when NotSetup # do nothing else raise "ipv6 configuration: neither static nor dynamic" end # We wont setup aliasses unless there is an actual IP address if ip != NotSetup aliasses_v6.each do |ip_alias| NetworkCommands.set_alias name, ip_alias end end end # DNS configuration dns.execute end def down unless NetworkCommands.interface_exists(@name) raise "The interface #{@name} doesn't exists or is already down." end NetworkCommands.flush name NetworkCommands.down name end def scan unless NetworkCommands.interface_exists(@name) raise "The interface #{@name} doesn't exists or is already down." end ssid_list = NetworkCommands.scan name pp! ssid_list end end