187 lines
4.2 KiB
Crystal
187 lines
4.2 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 = 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 (?<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 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 /^#.*$/
|
|
# 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
|