Network Manager Control for OpenBSD
Posted on 2017-10-23 10:12:00 from Vincent in OpenBSD Desktop nmctl
nmctl is no more maintained
I propose you a small script allowing you to easily manage your networks connections. This script is integrated within the openbox dynamic menus. Moreover, it allow you to automatically have the connections you have pre-defined based.
This is no more the last post concerning nmctl. Please check the category nmctl
I was frustrated to not be able to swap quickly from one network interface to an another, to connect simply and quickly to my wifi, to my cable connection, to the wifi of a friend, ...
Every time you have to type the ifconfig commands, .... This is nice, but boring. Surely, when you are in a middle of a presentation and you just want a quick connection to your mobile in tethering mode.
Thanks to OpenBSD those commands are not so hard, but this frustrate me to not be able to do it with one click. Directly from my windows environment. Since I'm using Openbox, from a menu of openbox.
So, I've looked around to see what is currently existing.
One tool I've found was netctl. The idea is to have a repository of hostname.if files ready to use for different cases.
The idea sounds great, but I had some difficulties to use it.
But what annoys me the most, is that it modify the current hostname.if files in /etc.
To my eyes, I would avoid to modify those files because they are my working basis. I want to rely on them and make sure that my network will be back to a normal mode after a reboot.
Nevertheless, if I've well understood netctl, you have a feature where it will look for the predefined network config matching the environment where you are. Very cool.
So, after having played with netctl, look for alternative on internet, I've decided to create nmctl. A small python script which just perform the mandatory network commands.
1. nmctl: a Network Manager Control tool for OpenBSD
Nmctl a small tool that allow you to manage your network connections.
Why python ? Just because it's the easiest programming language for me. But I should maybe rewrite it in shell, more standard in the OpenBSD world than python.
1.1. download and install
I've put nmctl on my sourceforge account here
You can dowload the last version here
To install you just have to run: make install (as root)
The prerequisites are:
- having python2.7 installed
- Since nmctl must be run as root, I strongly recommend you to run it via doas.
1.2. The config file
First you have to create a config and store it in /etc/nmctl.conf.
This file must respect few rules:
- Each block must starts with a line having the following format: '''<-name->:<-interface->'''
- Each following lines must start by at least one space. Those lines have more or less the same format as for hostname.if.
- You have to create a block with the name "open". This will be used to establish a connection to the Open Wifi around you (in restaurant for example)
- The order of those elements is important. In case you use the -restart option, nmctl will try each of those network configs one after one until it can ping www.google.com. (if you wan to ping something else, you can change it in the python script if you want).
- You can use external commands. Just precede them with the "!".
- You have macors. Macros allow you to perform some actions. The 2 currently implemented are '''<-nwid->''' and '''<-random mac->'''.
- You can use keywords. Currently the only one implemented is "dhcp"
Basically you can put all commands that nmctl will apply to the interface to which those commands are referring to. So, you will always have "ifconfig <-interface-> <-command you type in the config file->".
Check the manpage of ifconfig to see how flexible command is.
You have currently 2 macros:
- <-nwid-> which refers to the "nwid <-nwid name->" when you select an Open Wifi with the -open option of nmctl.
- <-random mac-> is a macro generating a random mac address. This is useful test a dhcp server for example.
The keyword "dhcp" will trigger a command like "dhclient <-interface->".
1.3. Config file sample.
Let me show you one nmctl.conf example. It speaks by itself.
#the name open is required for Open wifi.
#this is the interface that nmctl will take to establish a connection
#We must put the macro <nwid>. This is where nmctl will put the nwid command
#and the selected openwifi selected by the parameter --open
open:iwn0
!route flush
<nwid> -wpa
dhcp
cable:em0
!route flush
dhcp
lgg4:iwn0
!route flush
nwid LGG4s_8114 wpakey aanotherpassword
dhcp
home:iwn0
!route flush
nwid Linksys19594 wpakey apassword
dhcp
college:iwn0
!route flush
nwid john wpakey haahaaaguessme
dhcp
cable_fixip:em0
!route flush
inet 192.168.3.3 netmask 255.255.255.0
!route add -host default 192.168.3.1
#with this network interface I'm using the macro <random mac>
#which will do what you guess it will do :-)
cable_random:em0
!route flush
lladdr <random mac>
dhcp
In this config we have several cable's networks associated with my interface "em0" and several wifi networks associated with my wireless interface "iwn0".
You see that you can switch from dhcp, to fixed IP and even you can play with the random mac address macro.
Thanks to the network called "open", you can connect to any open wifi system. To do that, just type ''' nmctl --open <-name of the open wifi->'''
So, now, with just one command you can switch from one network configuration to an another one.
That's become cool :-).
2. Integration with openbox
Thanks to the dynamic menu feature of openbox, you can have your different pre-defined networks under one click of your mouse.
For that, you just have to add, at the most appropriate place for you, the following code in your ./config/openbox/menu.xml
<menu id="network-menu" label="Network">
<menu id="wifi-list" label="Wifi configured" execute="doas /usr/local/bin/nmctl --list" />
<menu id="wifi-scan" label="Wifi scan" execute="doas /usr/local/bin/nmctl --scan" />
<separator />
I just have 2 wifi available around me.
In this case, you see the different networks as defined in the config file just above.
3. Automatically identify your available connection and connect to it in one go
But the most interesting part, is coming from a loop through all of your defined networks.
This loop is reachable via the -restart option.
Basically the idea is to loop from the first network config to the last and test a ping for each of them. Once the ping works, we break the loop and keep this setting.
Thus where ever you are, you just have to initiate a nmctl -restart and you will be connected to the network you have defined for this place. There is one small exception, the open-wifis. We do not include them in this loop exercise.
Thus the way you define your config file is important.
Since the network called "open" is dedicated to "open wifi", it will not be part of this scan exercise. I propose you keep it at the first place.
Then, in my case, if my mobile, called lgg4, is open and visible by my laptop, I will connect it immediately.
Second, I check if my "home wifi" is visible.
Third, if I have a cable connected on my laptop, I'm using this connection and do a dhcp command.
Then, I check to see if my laptop is not viewing the "college" wifi.
? and so on until a ping command works.
If you do not have a cable in your laptop and if none of your pre-defined wifi connections are visible, the scan will stop.
3.1 examples
No cable connected, no pre-defined wifi around me:
t420:~$ time doas nmctl -r
nwids around you: bbox2-d954
0m02.97s real 0m00.08s user 0m00.11s system
t420:~$
t420:~$
I'm at home and my wifi router is running:
t420:~$ time doas nmctl -r
nwids around you: Linksys19594 bbox2-d954
ifconfig em0 down: 0
default fw done
fw 00:22:4d:ac:30:fd done
nas link#2 done
route flush: 0
ifconfig iwn0 nwid Linksys19594 ...: 0
iwn0: no link ........... sleeping
dhclient iwn0: 0
Done.
PING www.google.com (216.58.212.164): 56 data bytes
64 bytes from 216.58.212.164: icmp_seq=0 ttl=52 time=12.758 ms
--- www.google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 12.758/12.758/12.758/0.000 ms
ping -c1 -w2 www.google.com: 0
0m22.49s real 0m00.08s user 0m00.11s system
t420:~$
I'm at home but tethering is active on my mobile:
t420:~$
t420:~$ time doas nmctl -r
nwids around you: Linksys19594 bbox2-d954 LGG4s_8114
ifconfig em0 down: 0
default fw done
fw 00:22:4d:ac:30:fd done
nas link#2 done
route flush: 0
ifconfig iwn0 nwid LGG4s_8114 ...: 0
iwn0: DHCPDISCOVER - interval 1
iwn0: DHCPDISCOVER - interval 2
iwn0: DHCPOFFER from 192.168.43.1 (a0:91:69:be:10:49)
iwn0: DHCPREQUEST to 255.255.255.255
iwn0: DHCPACK from 192.168.43.1 (a0:91:69:be:10:49)
iwn0: bound to 192.168.43.214 -- renewal in 1800 seconds
dhclient iwn0: 0
Done.
ping: Warning: www.google.com has multiple addresses; using 173.194.69.99
PING www.google.com (173.194.69.99): 56 data bytes
64 bytes from 173.194.69.99: icmp_seq=0 ttl=43 time=42.863 ms
--- www.google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 42.863/42.863/42.863/0.000 ms
ping -c1 -w2 www.google.com: 0
0m13.78s real 0m00.08s user 0m00.13s system
t420:~$
Same situation, but I cut the tethering just after the scan. Thus the dhcp command will not succeed.
We see that, after timeouts, nmctl see that the ping is failing (return code 1), thus he pass to the next possible pre-defined network.
t420:~$ time doas nmctl -r
nwids around you: Linksys19594 bbox2-d954 LGG4s_8114
ifconfig em0 down: 0
default 192.168.43.1 done
192.168.43.1 a0:91:69:be:10:49 done
route flush: 0
ifconfig iwn0 nwid LGG4s_8114 ...: 0
iwn0: no link ........... sleeping
dhclient iwn0: 0
Done.
ping: no address associated with name
ping -c1 -w2 www.google.com: 1
ifconfig em0 down: 0
192.168.43.1 link#2 done
route flush: 0
ifconfig iwn0 nwid Linksys19594 ...: 0
iwn0: DHCPREQUEST to 255.255.255.255
iwn0: DHCPACK from 192.168.3.1 (00:22:4d:ac:30:fd)
iwn0: bound to 192.168.3.16 -- renewal in 302400 seconds
dhclient iwn0: 0
Done.
PING www.google.com (216.58.212.164): 56 data bytes
64 bytes from 216.58.212.164: icmp_seq=0 ttl=52 time=12.654 ms
--- www.google.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 12.654/12.654/12.654/0.000 ms
ping -c1 -w2 www.google.com: 0
3m34.85s real 0m00.17s user 0m00.20s system
t420:~$