206 lines
4.5 KiB
Crystal
206 lines
4.5 KiB
Crystal
|
|
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 (?<ip>[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? (?<ip>[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 (?<ssid>[^ \t]+) wpakey (?<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 (?<ssid>[^ \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 (?<ssid>[^ \t]+) inet6? (?<ip>[^ \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 (?<ssid>[^ \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 (?<ssid>[^ \t]+) dns (?<ip>[^ \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 (?<mtu>[0-9]+)/
|
|
mtu = $~["mtu"].to_i
|
|
|
|
when /^dns (?<ip>[^ \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 = $~["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
|