class NetworkConfigurationParser def self.parse_file(file_name : String) : InterfaceConfiguration content = File.read(file_name) content = content.rchop ifname = /.([a-zA-Z0-9]+)$/.match(file_name).try &.[1] if ifname.nil? raise "The interface name is not known from the filename: '#{file_name}'" end self.parse(ifname.not_nil!, content) end def self.parse (ifname : String, data : String) : InterfaceConfiguration up = false description = nil mtu = nil main_ip_v4 = NotSetup.new main_ip_v6 = NotSetup.new dns = NetworkCommands::DNS.new aliasses = [] of IPAddress wireless_networks = {} of String => WirelessAPSetup data.split("\n").each do |line| case line when /^up/ up = true when /^description/ description = /^description (.+)/.match(line).try &.[1] when /^inet6? alias (?[a-f0-9:.\/]+)/ ipstr = $~["ip"] if ipstr.nil? puts "wrong IP address alias, line #{line}" next end aliasses.push IPAddress.parse(ipstr) when /^inet6? dhcp/ # IP address is DHCP if /^inet /.match(line) main_ip_v4 = DHCP.new else main_ip_v6 = DHCP.new end when /^inet6 autoconf/ # IP address is autoconfigured main_ip_v6 = Autoconfiguration.new when /^inet6? (?[a-f0-9:.\/]+)/ ipstr = $~["ip"] if ipstr.nil? puts "wrong IP address, line #{line}" next end if /^inet /.match(line) main_ip_v4 = IPAddress.parse ipstr else main_ip_v6 = IPAddress.parse ipstr end when /^join (?[^ \t]+) wpakey (?[^ \t]+)/ # WPA2-PSK, other security mechanisms are not supported, yet ssid = $~["ssid"] wpakeystr = $~["wpakey"] if ssid.nil? puts "wrong SSID in line: #{line}" next end if wpakeystr.nil? puts "wrong wpa key in line: #{line}" next end new_ap = WirelessAPSetup.new ifname, ssid, WirelessAPSetup::WPA.new(wpakeystr) wireless_networks[ssid] = new_ap when /^network (?[^ \t]+) inet6 autoconf/ ssid = $~["ssid"] if ssid.nil? puts "wrong SSID in line: #{line}" next end access_point = wireless_networks[ssid].not_nil! access_point.main_ip_v6 = Autoconfiguration.new when /^network (?[^ \t]+) inet6? (?[^ \t]+)/ ssid = $~["ssid"] ipstr = $~["ip"] if ssid.nil? puts "wrong SSID in line: #{line}" next end if ipstr.nil? puts "wrong ip address in line: #{line}" next end ipaddr = IPAddress.parse ipstr access_point = wireless_networks[ssid].not_nil! if ipaddr.ipv4? access_point.main_ip_v4 = ipaddr elsif ipaddr.ipv6? access_point.main_ip_v6 = ipaddr else puts "wrong ip address in line: #{line} (neither ipv4 or ipv6)" end when /^network (?[^ \t]+) dhcp6?/ ssid = $~["ssid"] if ssid.nil? puts "wrong SSID in line: #{line}" next end access_point = wireless_networks[ssid].not_nil! if /dhcp6/.match(line) access_point.main_ip_v6 = DHCP.new elsif /dhcp/.match(line) access_point.main_ip_v4 = DHCP.new else puts "wrong dhcp instruction in line: #{line}" end when /^network (?[^ \t]+) dns (?[^ \t]+)/ ssid = $~["ssid"] ipstr = $~["ip"] if ssid.nil? puts "wrong SSID in line: #{line}" next end if ipstr.nil? puts "wrong ip address in line: #{line}" next end access_point = wireless_networks[ssid].not_nil! ipaddr = IPAddress.parse ipstr access_point.dns.addresses << ipaddr.to_s when /^mtu (?[0-9]+)/ mtu = $~["mtu"].to_i when /^dns (?[^ \t]+)/ ipstr = $~["ip"] if ipstr.nil? puts "wrong ip address in line: #{line}" next end ipaddr = IPAddress.parse ipstr dns.addresses << ipaddr.to_s when /^#.*$/ # simple comment when /^[ \t]*$/ # empty line else raise "Cannot parse: #{line}" end end InterfaceConfiguration.new(ifname, up, description, mtu, main_ip_v4, main_ip_v6, aliasses, wireless_networks, dns) end end