meh, plein de trucs
This commit is contained in:
parent
edb7955f30
commit
e184ef6158
242
src/main.cr
242
src/main.cr
@ -10,11 +10,19 @@ prefered_network_configuration_program = nil
|
|||||||
prefered_wireless_configuration_program = nil
|
prefered_wireless_configuration_program = nil
|
||||||
prefered_dhcp_client = nil
|
prefered_dhcp_client = nil
|
||||||
|
|
||||||
|
print_autodetect = false
|
||||||
|
|
||||||
|
command = "list"
|
||||||
|
|
||||||
OptionParser.parse! do |parser|
|
OptionParser.parse! do |parser|
|
||||||
parser.on "-s", "--simulation", "Export the network configuration." do
|
parser.on "-s", "--simulation", "Export the network configuration." do
|
||||||
simulation = true
|
simulation = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
parser.on "-a", "--print-autodetect", "Print autodetection of the installed programs." do
|
||||||
|
print_autodetect = true
|
||||||
|
end
|
||||||
|
|
||||||
parser.on "-w wireless-configuration-program", "--wireless wireless-configuration-program", "iw" do |prog|
|
parser.on "-w wireless-configuration-program", "--wireless wireless-configuration-program", "iw" do |prog|
|
||||||
prefered_wireless_configuration_program = prog
|
prefered_wireless_configuration_program = prog
|
||||||
end
|
end
|
||||||
@ -36,6 +44,35 @@ OptionParser.parse! do |parser|
|
|||||||
verbosity = optsn.to_i
|
verbosity = optsn.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
|
parser.missing_option do |opt|
|
||||||
|
STDERR.puts "You missed the argument for option #{opt}"
|
||||||
|
# TODO: explain the different arguments
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
parser.invalid_option do |flag|
|
||||||
|
STDERR.puts "Error: #{flag} not a valid option"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
parser.unknown_args do |arg|
|
||||||
|
command = arg.shift
|
||||||
|
|
||||||
|
case command
|
||||||
|
when /^(list)/
|
||||||
|
STDERR.puts "TODO: list" unless arg.empty?
|
||||||
|
when /^(connect)/
|
||||||
|
STDERR.puts "TODO: connect" unless arg.empty?
|
||||||
|
else
|
||||||
|
STDERR.puts "Command #{command} not understood"
|
||||||
|
end
|
||||||
|
|
||||||
|
unless arg.empty?
|
||||||
|
STDERR.puts "unknown arg: #{arg}"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
parser.on "-h", "--help", "Show this help" do
|
parser.on "-h", "--help", "Show this help" do
|
||||||
puts parser
|
puts parser
|
||||||
exit 0
|
exit 0
|
||||||
@ -61,12 +98,17 @@ class NotSetup
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class DHCP
|
||||||
|
def to_s(io : IO)
|
||||||
|
io << "dhcp"
|
||||||
|
end
|
||||||
|
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_wireless_configuration : IWCommand.class | NotSetup.class = NotSetup
|
||||||
class_property cmd_dhcp_client : UDHCPCCommand.class | NotSetup.class = NotSetup
|
class_property cmd_dhcp_client : UDHCPCCommand.class | DHClientCommand.class | NotSetup.class = NotSetup
|
||||||
|
|
||||||
class IWCommand
|
class IWCommand
|
||||||
def self.get_ssid(ifname : String, ssid)
|
def self.get_ssid(ifname : String, ssid)
|
||||||
@ -86,6 +128,16 @@ class NetworkCommands
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class DHClientCommand
|
||||||
|
def self.run(ifname : String)
|
||||||
|
# TODO: verify which dhcp client is installed on the system
|
||||||
|
cmd = "udhcpc"
|
||||||
|
unless Do.run(cmd, [ name ]).success?
|
||||||
|
raise "(#{cmd}) dhcp failed on #{ifname}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class IfconfigCommand
|
class IfconfigCommand
|
||||||
def self.interface_exists(name : String)
|
def self.interface_exists(name : String)
|
||||||
Do.run("ifconfig", [ name ]).success?
|
Do.run("ifconfig", [ name ]).success?
|
||||||
@ -236,6 +288,15 @@ end
|
|||||||
class WirelessAPSetup
|
class WirelessAPSetup
|
||||||
property ssid : String
|
property ssid : String
|
||||||
|
|
||||||
|
# This is a list of parameters that should be unique to each AP
|
||||||
|
property up : Bool
|
||||||
|
property description : String?
|
||||||
|
property mtu : Int32?
|
||||||
|
property main_ip_v4 : IPAddress | DHCP | NotSetup
|
||||||
|
property main_ip_v6 : IPAddress | DHCP | NotSetup
|
||||||
|
property aliasses_v4 : Array(IPAddress)
|
||||||
|
property aliasses_v6 : Array(IPAddress)
|
||||||
|
|
||||||
# we currently only support WPA2-PSK wireless security mechanism
|
# we currently only support WPA2-PSK wireless security mechanism
|
||||||
property security : WPA
|
property security : WPA
|
||||||
|
|
||||||
@ -246,6 +307,40 @@ class WirelessAPSetup
|
|||||||
end
|
end
|
||||||
|
|
||||||
def initialize(@ssid, @security)
|
def initialize(@ssid, @security)
|
||||||
|
@main_ip_v4 = NotSetup.new
|
||||||
|
@main_ip_v6 = NotSetup.new
|
||||||
|
@aliasses_v4 = Array(IPAddress).new
|
||||||
|
@aliasses_v6 = Array(IPAddress).new
|
||||||
|
@up = true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def to_s(io : IO)
|
||||||
|
io << to_string
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_string
|
||||||
|
String.build do |str|
|
||||||
|
str << "#{CBLUE}#{ssid}: {ssid}#{CRESET}\n"
|
||||||
|
|
||||||
|
str << "\t#description #{description.not_nil!}\n" unless description.nil?
|
||||||
|
str << "\t#{@up? "up" : "down"}\n"
|
||||||
|
str << "\tmtu #{mtu}\n" unless mtu.nil?
|
||||||
|
|
||||||
|
# ipv4
|
||||||
|
str << "\tinet #{@main_ip_v4}\n"
|
||||||
|
@aliasses_v4.each do |a|
|
||||||
|
str << "\talias #{a}\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
# ipv6
|
||||||
|
str << "\tinet6 #{@main_ip_v6}\n"
|
||||||
|
unless @aliasses_v6.empty?
|
||||||
|
@aliasses_v6.each do |a|
|
||||||
|
str << "\talias6 #{a}\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -255,11 +350,6 @@ end
|
|||||||
#
|
#
|
||||||
|
|
||||||
class InterfaceConfiguration
|
class InterfaceConfiguration
|
||||||
class DHCP
|
|
||||||
def to_s(io : IO)
|
|
||||||
io << "dhcp"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
property name : String
|
property name : String
|
||||||
property up : Bool
|
property up : Bool
|
||||||
@ -302,7 +392,7 @@ class InterfaceConfiguration
|
|||||||
str << "#{CRED}#{@name}#{CRESET}\n"
|
str << "#{CRED}#{@name}#{CRESET}\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
str << "\t#description #{description.not_nil!}\n" unless description.nil?
|
str << "\tdescription: '#{description.not_nil!}'\n" unless description.nil?
|
||||||
|
|
||||||
str << "\t#{@up? "up" : "down"}\n"
|
str << "\t#{@up? "up" : "down"}\n"
|
||||||
|
|
||||||
@ -325,6 +415,14 @@ class InterfaceConfiguration
|
|||||||
str << "\talias6 #{a}\n"
|
str << "\talias6 #{a}\n"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if wireless_networks.empty?
|
||||||
|
puts "no wireless connection configured" if wireless
|
||||||
|
else
|
||||||
|
wireless_networks.each do |k,v|
|
||||||
|
puts v
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -440,9 +538,9 @@ class NetworkConfigurationParser
|
|||||||
when /^inet6? dhcp/
|
when /^inet6? dhcp/
|
||||||
# IPaddress is DHCP
|
# IPaddress is DHCP
|
||||||
if /^inet /.match(line)
|
if /^inet /.match(line)
|
||||||
main_ip_v4 = InterfaceConfiguration::DHCP.new
|
main_ip_v4 = DHCP.new
|
||||||
else
|
else
|
||||||
main_ip_v6 = InterfaceConfiguration::DHCP.new
|
main_ip_v6 = DHCP.new
|
||||||
end
|
end
|
||||||
when /^inet6 autoconf/
|
when /^inet6 autoconf/
|
||||||
# IPaddress is autoconfigured
|
# IPaddress is autoconfigured
|
||||||
@ -458,14 +556,98 @@ class NetworkConfigurationParser
|
|||||||
else
|
else
|
||||||
main_ip_v6 = IPAddress.parse ipstr
|
main_ip_v6 = IPAddress.parse ipstr
|
||||||
end
|
end
|
||||||
when /^join [^ ]+ wpakey .*/
|
when /^join [^ \t]+ wpakey .*/
|
||||||
# WPA2-PSK, other security mechanisms are not supported, yet
|
# 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]
|
||||||
|
|
||||||
when /^network [^ ]+ inet .*/
|
if ssid.nil?
|
||||||
puts "TODO: network SSID inet IP/prefix"
|
puts "wrong SSID in line: #{line}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
when /^network [^ ]+ dhcp/
|
if wpakeystr.nil?
|
||||||
puts "TODO: network SSID dhcp"
|
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
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
access_point = wireless_networks[ssid].not_nil!
|
||||||
|
|
||||||
|
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
|
||||||
|
# ssid = /^network ([^ \t]+)/.match(line).try &.[1]
|
||||||
|
# ipstr = /^network [^ \t]+ inet6? (?<ip>[^ \t]+)/.match(line).try &.["ip"]
|
||||||
|
|
||||||
|
if ssid.nil?
|
||||||
|
puts "wrong SSID in line: #{line}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
if ipstr.nil?
|
||||||
|
puts "wrong ip address in line: #{line}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
ipaddr = IPAddress.parse ipstr
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
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 ([^ \t]+)/.match(line).try &.[1]
|
||||||
|
|
||||||
|
if ssid.nil?
|
||||||
|
puts "wrong SSID in line: #{line}"
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
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 .*/
|
when /^network [^ ]+ dns .*/
|
||||||
puts "TODO: network SSID dns"
|
puts "TODO: network SSID dns"
|
||||||
@ -491,18 +673,25 @@ class NetworkConfigurationParser
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def which(cmd : String)
|
|
||||||
|
|
||||||
|
class Autodetect
|
||||||
|
class_property print_autodetect : Bool = false
|
||||||
|
|
||||||
|
def self.which(cmd : String)
|
||||||
if Process.run("which", [ cmd ]).success?
|
if Process.run("which", [ cmd ]).success?
|
||||||
puts "#{cmd} installed"
|
puts "#{cmd} installed" if print_autodetect
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
puts "#{cmd} not installed"
|
puts "#{cmd} not installed" if print_autodetect
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
Do.simulation = simulation
|
Do.simulation = simulation
|
||||||
|
Autodetect.print_autodetect = print_autodetect
|
||||||
|
|
||||||
#
|
#
|
||||||
# discover available configuration commands
|
# discover available configuration commands
|
||||||
@ -517,7 +706,8 @@ possible_network_configuration_cmds = {
|
|||||||
|
|
||||||
# udhcpc = busybox dhcp client
|
# udhcpc = busybox dhcp client
|
||||||
possible_dhcp_clients = {
|
possible_dhcp_clients = {
|
||||||
"udhcpc" => NetworkCommands::UDHCPCCommand
|
"udhcpc" => NetworkCommands::UDHCPCCommand,
|
||||||
|
"dhclient" => NetworkCommands::DHClientCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
# iw = linux
|
# iw = linux
|
||||||
@ -526,24 +716,30 @@ possible_wireless_configuration_cmds = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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| Autodetect.which(key) } if key.nil?
|
||||||
# should crash if there is no network command installed
|
# should crash if there is no network command installed
|
||||||
NetworkCommands.cmd_network_configuration = possible_network_configuration_cmds[key.not_nil!]
|
NetworkCommands.cmd_network_configuration = possible_network_configuration_cmds[key.not_nil!]
|
||||||
|
|
||||||
key = prefered_dhcp_client
|
key = prefered_dhcp_client
|
||||||
key = possible_dhcp_clients.keys.find { |key| which(key) } if key.nil?
|
key = possible_dhcp_clients.keys.find { |key| Autodetect.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 = prefered_wireless_configuration_program
|
||||||
key = possible_wireless_configuration_cmds.keys.find { |key| which(key) } if key.nil?
|
key = possible_wireless_configuration_cmds.keys.find { |key| Autodetect.which(key) } if key.nil?
|
||||||
# should crash if there is no wireless command installed
|
# should crash if there is no wireless command installed
|
||||||
NetworkCommands.cmd_wireless_configuration = possible_wireless_configuration_cmds[key.not_nil!]
|
NetworkCommands.cmd_wireless_configuration = possible_wireless_configuration_cmds[key.not_nil!]
|
||||||
|
|
||||||
|
|
||||||
if file.nil?
|
if file.nil?
|
||||||
raise "Cannot choose files yet"
|
raise "Cannot search for files yet"
|
||||||
else
|
end
|
||||||
|
|
||||||
|
case command
|
||||||
|
when "list"
|
||||||
|
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
|
||||||
|
puts NetworkConfigurationParser.parse_file(file.not_nil!)
|
||||||
|
when "connect"
|
||||||
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
|
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
|
||||||
network_configuration = NetworkConfigurationParser.parse_file(file.not_nil!)
|
network_configuration = NetworkConfigurationParser.parse_file(file.not_nil!)
|
||||||
network_configuration.execute
|
network_configuration.execute
|
||||||
|
Loading…
Reference in New Issue
Block a user