networkctl/src/network_configuration_parse...

211 lines
4.8 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
wireless = false
wireless = true unless /^wl[0-9]+$/.match(ifname)
self.parse(ifname.not_nil!, content, wireless)
end
def self.parse (ifname : String, data : String, wireless = false) : InterfaceConfiguration
up = false
description = nil
mtu = nil
main_ip_v4 = NotSetup.new
main_ip_v6 = NotSetup.new
dns = Array(IPAddress).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 .*/
ipstr = /^inet6? alias ([a-f0-9:.\/]+)/.match(line).try &.[1]
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? .*/
ipstr = /^inet6? ([a-f0-9:.\/]+)/.match(line).try &.[1]
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 .*/
# WPA2-PSK, other security mechanisms are not supported, yet
ssid = /^join ([^ \t]+)/.match(line).try &.[1]
wpakeystr = /^join [^ \t]+ wpakey ([^ \t]+)/.match(line).try &.[1]
if ssid.nil?
puts "wrong SSID in line: #{line}"
next
end
if wpakeystr.nil?
puts "wrong wpa key in line: #{line}"
next
end
# TODO
new_ap = WirelessAPSetup.new ssid, WirelessAPSetup::WPA.new(wpakeystr)
wireless_networks[ssid] = new_ap
when /^network [^ \t]+ inet6 autoconf/
puts "TODO: network SSID inet6 autoconf"
ssid = /^network ([^ \t]+)/.match(line).try &.[1]
ipstr = /^network [^ \t]+ inet6? ([^ \t]+)/.match(line).try &.[1]
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!
access_point.main_ip_v6 = Autoconfiguration.new
puts "for SSID: #{ssid} ipv6 configuration = autoconf"
when /^network [^ \t]+ inet6? .*/
ssid = nil
ipstr = nil
/^network (?<ssid>[^ \t]+) inet6? (?<ip>[^ \t]+)/.match(line).try do |m|
ssid = m["ssid"]
ipstr = m["ip"]
end
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 [^ ]+ dhcp6?/
ssid = /^network (?<ssid>[^ \t]+)/.match(line).try &.["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 [^ ]+ dns .*/
ssid = nil
ipstr = nil
/^network (?<ssid>[^ \t]+) dns (?<ip>[^ \t]+)/.match(line).try do |m|
ssid = m["ssid"]
ipstr = m["ip"]
end
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 << ipaddr
when /^mtu [0-9]+/
mtu = /^mtu ([0-9]+)/.match(line).try &.[1].to_i
when /^dns [^ \t]+/
ipstr = nil
/^dns (?<ip>[^ \t]+)/.match(line).try do |m|
ipstr = m["ip"]
end
if ipstr.nil?
puts "wrong ip address in line: #{line}"
next
end
ipaddr = IPAddress.parse ipstr
dns << ipaddr
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, wireless_networks,
dns)
end
end