wireless stuff
This commit is contained in:
parent
f441648d97
commit
c7290452ad
115
src/main.cr
115
src/main.cr
@ -7,6 +7,7 @@ simulation = false
|
|||||||
file = nil
|
file = nil
|
||||||
|
|
||||||
prefered_network_configuration_program = nil
|
prefered_network_configuration_program = nil
|
||||||
|
prefered_wireless_configuration_program = nil
|
||||||
prefered_dhcp_client = nil
|
prefered_dhcp_client = nil
|
||||||
|
|
||||||
OptionParser.parse! do |parser|
|
OptionParser.parse! do |parser|
|
||||||
@ -14,6 +15,10 @@ OptionParser.parse! do |parser|
|
|||||||
simulation = true
|
simulation = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
parser.on "-w wireless-configuration-program", "--wireless wireless-configuration-program", "iw" do |prog|
|
||||||
|
prefered_wireless_configuration_program = prog
|
||||||
|
end
|
||||||
|
|
||||||
parser.on "-n network-configuration-program", "--net-conf network-configuration-program", "ifconfig | ip" do |prog|
|
parser.on "-n network-configuration-program", "--net-conf network-configuration-program", "ifconfig | ip" do |prog|
|
||||||
prefered_network_configuration_program = prog
|
prefered_network_configuration_program = prog
|
||||||
end
|
end
|
||||||
@ -60,8 +65,17 @@ end
|
|||||||
|
|
||||||
class NetworkCommands
|
class NetworkCommands
|
||||||
class_property cmd_network_configuration : IfconfigCommand.class | IPCommand.class = IfconfigCommand
|
class_property cmd_network_configuration : IfconfigCommand.class | IPCommand.class = IfconfigCommand
|
||||||
|
class_property cmd_wireless_configuration : IWCommand.class | NotSetup.class = NotSetup
|
||||||
class_property cmd_dhcp_client : UDHCPCCommand.class | NotSetup.class = NotSetup
|
class_property cmd_dhcp_client : UDHCPCCommand.class | NotSetup.class = NotSetup
|
||||||
|
|
||||||
|
class IWCommand
|
||||||
|
def self.get_ssid(ifname : String, ssid)
|
||||||
|
unless Do.run(cmd, [ name ]).success?
|
||||||
|
raise "(#{cmd}) dhcp failed on #{ifname}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class UDHCPCCommand
|
class UDHCPCCommand
|
||||||
def self.run(ifname : String)
|
def self.run(ifname : String)
|
||||||
# TODO: verify which dhcp client is installed on the system
|
# TODO: verify which dhcp client is installed on the system
|
||||||
@ -164,6 +178,43 @@ class NetworkCommands
|
|||||||
def self.set_alias(name : String, ip : IPAddress)
|
def self.set_alias(name : String, ip : IPAddress)
|
||||||
@@cmd_network_configuration.set_alias name, ip
|
@@cmd_network_configuration.set_alias name, ip
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.wireless_list_ssid(ifname : String)
|
||||||
|
cmd = @@cmd_wireless_configuration
|
||||||
|
case cmd
|
||||||
|
when NotSetup
|
||||||
|
puts "no wireless configuration program: cannot list ssid"
|
||||||
|
when IWCommand
|
||||||
|
cmd.list_ssid ifname
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.wireless_connect_wpa_psk(ifname : String, ssid : String, passwd : String)
|
||||||
|
cmd = @@cmd_wireless_configuration
|
||||||
|
case cmd
|
||||||
|
when NotSetup
|
||||||
|
puts "no wireless configuration program: cannot connect to ssid #{ssid}"
|
||||||
|
when IWCommand
|
||||||
|
cmd.list_ssid ifname
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
class WirelessAPSetup
|
||||||
|
property ssid : String
|
||||||
|
|
||||||
|
# we currently only support WPA2-PSK wireless security mechanism
|
||||||
|
property security : WPA
|
||||||
|
|
||||||
|
class WPA
|
||||||
|
property key : String
|
||||||
|
def initialize(@key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize(@ssid, @security)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -180,12 +231,18 @@ class InterfaceConfiguration
|
|||||||
|
|
||||||
property name : String
|
property name : String
|
||||||
property up : Bool
|
property up : Bool
|
||||||
|
property description : String?
|
||||||
|
property wireless : Bool
|
||||||
property main_ip_v4 : IPAddress | DHCP | NotSetup
|
property main_ip_v4 : IPAddress | DHCP | NotSetup
|
||||||
property main_ip_v6 : IPAddress | DHCP | NotSetup
|
property main_ip_v6 : IPAddress | DHCP | NotSetup
|
||||||
property aliasses_v4 : Array(IPAddress)
|
property aliasses_v4 : Array(IPAddress)
|
||||||
property aliasses_v6 : Array(IPAddress)
|
property aliasses_v6 : Array(IPAddress)
|
||||||
|
property wireless_networks : Hash(String, WirelessAPSetup)
|
||||||
|
|
||||||
def initialize (@name, @up, @main_ip_v4, @main_ip_v6, aliasses)
|
def initialize (@name, @up,
|
||||||
|
@description,
|
||||||
|
@main_ip_v4, @main_ip_v6, aliasses,
|
||||||
|
@wireless, @wireless_networks)
|
||||||
@aliasses_v4 = Array(IPAddress).new
|
@aliasses_v4 = Array(IPAddress).new
|
||||||
@aliasses_v6 = Array(IPAddress).new
|
@aliasses_v6 = Array(IPAddress).new
|
||||||
|
|
||||||
@ -211,16 +268,19 @@ class InterfaceConfiguration
|
|||||||
end
|
end
|
||||||
|
|
||||||
str << "\t#{@up? "up" : "down"}\n"
|
str << "\t#{@up? "up" : "down"}\n"
|
||||||
str << "\tinet #{@main_ip_v4}\n"
|
description = @description
|
||||||
|
str << "\t#description #{description.not_nil!}\n" unless description.nil?
|
||||||
|
|
||||||
|
# ipv4
|
||||||
|
str << "\tinet #{@main_ip_v4}\n"
|
||||||
unless @aliasses_v4.empty?
|
unless @aliasses_v4.empty?
|
||||||
@aliasses_v4.each do |a|
|
@aliasses_v4.each do |a|
|
||||||
str << "\talias #{a}\n"
|
str << "\talias #{a}\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# ipv6
|
||||||
str << "\tinet6 #{@main_ip_v6}\n"
|
str << "\tinet6 #{@main_ip_v6}\n"
|
||||||
|
|
||||||
unless @aliasses_v6.empty?
|
unless @aliasses_v6.empty?
|
||||||
@aliasses_v6.each do |a|
|
@aliasses_v6.each do |a|
|
||||||
str << "\talias6 #{a}\n"
|
str << "\talias6 #{a}\n"
|
||||||
@ -294,20 +354,31 @@ class NetworkConfigurationParser
|
|||||||
content = File.read(file_name)
|
content = File.read(file_name)
|
||||||
content = content.rchop
|
content = content.rchop
|
||||||
ifname = /.([a-zA-Z0-9]+)$/.match(file_name).try &.[1]
|
ifname = /.([a-zA-Z0-9]+)$/.match(file_name).try &.[1]
|
||||||
self.parse(ifname.not_nil!, content)
|
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
|
end
|
||||||
|
|
||||||
def self.parse (ifname : String, data : String) : InterfaceConfiguration
|
def self.parse (ifname : String, data : String, wireless = false) : InterfaceConfiguration
|
||||||
up = false
|
up = false
|
||||||
|
description = nil
|
||||||
main_ip_v4 = NotSetup.new
|
main_ip_v4 = NotSetup.new
|
||||||
main_ip_v6 = NotSetup.new
|
main_ip_v6 = NotSetup.new
|
||||||
|
|
||||||
aliasses = [] of IPAddress
|
aliasses = [] of IPAddress
|
||||||
|
|
||||||
|
wireless_networks = {} of String => WirelessAPSetup
|
||||||
|
|
||||||
data.split("\n").each do |line|
|
data.split("\n").each do |line|
|
||||||
case line
|
case line
|
||||||
when /^up/
|
when /^up/
|
||||||
up = true
|
up = true
|
||||||
|
when /^description/
|
||||||
|
description = /^description (.+)/.match(line).try &.[1]
|
||||||
when /^inet6? alias .*/
|
when /^inet6? alias .*/
|
||||||
ipstr = /^inet6? alias ([a-f0-9:.\/]+)/.match(line).try &.[1]
|
ipstr = /^inet6? alias ([a-f0-9:.\/]+)/.match(line).try &.[1]
|
||||||
if ipstr.nil?
|
if ipstr.nil?
|
||||||
@ -333,17 +404,32 @@ class NetworkConfigurationParser
|
|||||||
else
|
else
|
||||||
main_ip_v6 = IPAddress.parse ipstr
|
main_ip_v6 = IPAddress.parse ipstr
|
||||||
end
|
end
|
||||||
|
when /^join [^ ]+ wpakey .*/
|
||||||
|
# WPA2-PSK, other security mechanisms are not supported, yet
|
||||||
|
|
||||||
|
when /^network [^ ]+ inet .*/
|
||||||
|
puts "TODO: network SSID inet IP/prefix"
|
||||||
|
|
||||||
|
when /^network [^ ]+ dhcp/
|
||||||
|
puts "TODO: network SSID dhcp"
|
||||||
|
|
||||||
|
when /^#.*$/
|
||||||
|
# simple comment
|
||||||
|
when /^[ \t]*$/
|
||||||
|
# empty line
|
||||||
else
|
else
|
||||||
raise "Cannot parse: #{line}"
|
raise "Cannot parse: #{line}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
InterfaceConfiguration.new(ifname, up, main_ip_v4, main_ip_v6, aliasses)
|
InterfaceConfiguration.new(ifname, up,
|
||||||
|
description,
|
||||||
|
main_ip_v4, main_ip_v6,
|
||||||
|
aliasses,
|
||||||
|
wireless, wireless_networks)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Do.simulation = simulation
|
|
||||||
|
|
||||||
def which(cmd : String)
|
def which(cmd : String)
|
||||||
if Process.run("which", [ cmd ]).success?
|
if Process.run("which", [ cmd ]).success?
|
||||||
puts "#{cmd} installed"
|
puts "#{cmd} installed"
|
||||||
@ -355,6 +441,8 @@ def which(cmd : String)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Do.simulation = simulation
|
||||||
|
|
||||||
#
|
#
|
||||||
# discover available configuration commands
|
# discover available configuration commands
|
||||||
#
|
#
|
||||||
@ -371,6 +459,10 @@ possible_dhcp_clients = {
|
|||||||
"udhcpc" => NetworkCommands::UDHCPCCommand
|
"udhcpc" => NetworkCommands::UDHCPCCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# iw = linux
|
||||||
|
possible_wireless_configuration_cmds = {
|
||||||
|
"iw" => NetworkCommands::IWCommand
|
||||||
|
}
|
||||||
|
|
||||||
key = prefered_network_configuration_program
|
key = prefered_network_configuration_program
|
||||||
key = possible_network_configuration_cmds.keys.find { |key| which(key) } if key.nil?
|
key = possible_network_configuration_cmds.keys.find { |key| which(key) } if key.nil?
|
||||||
@ -382,10 +474,15 @@ key = possible_dhcp_clients.keys.find { |key| which(key) } if key.nil?
|
|||||||
# should not crash if there is no
|
# should not crash if there is no
|
||||||
NetworkCommands.cmd_dhcp_client = possible_dhcp_clients[key] unless key.nil?
|
NetworkCommands.cmd_dhcp_client = possible_dhcp_clients[key] unless key.nil?
|
||||||
|
|
||||||
|
key = prefered_wireless_configuration_program
|
||||||
|
key = possible_wireless_configuration_cmds.keys.find { |key| which(key) } if key.nil?
|
||||||
|
# should crash if there is no wireless command installed
|
||||||
|
NetworkCommands.cmd_wireless_configuration = possible_wireless_configuration_cmds[key.not_nil!]
|
||||||
|
|
||||||
|
|
||||||
if file.nil?
|
if file.nil?
|
||||||
raise "Cannot choose files yet"
|
raise "Cannot choose files yet"
|
||||||
else
|
else
|
||||||
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
|
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
|
||||||
NetworkConfigurationParser.parse_file(file.not_nil!).execute
|
NetworkConfigurationParser.parse_file(file.not_nil!).execute
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user