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 command_lines = [] of String 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 /^!(?.*)/ cmd = $~["cmd"].not_nil! command_lines << cmd puts "new command: #{cmd}" when /^#.*$/ # simple comment when /^[ \t]*$/ # empty line else raise "Cannot parse: #{line}" end end iface_conf = InterfaceConfiguration.new(ifname) iface_conf.up = up iface_conf.description = description iface_conf.mtu = mtu iface_conf.main_ip_v4 = main_ip_v4 iface_conf.main_ip_v6 = main_ip_v6 aliasses.each do |ip| if ip.ipv4? iface_conf.aliasses_v4 << ip else iface_conf.aliasses_v6 << ip end end iface_conf.wireless_networks = wireless_networks iface_conf.dns = dns iface_conf.command_lines = command_lines iface_conf end end