MAC changing program or daemon? - networking

I'm currently have a program which creates a list of all MAC addresses and corresponding names and IP addresses on my network.
I was wondering if it's possible (theoretically) to create a background program which, every hour, would change your MAC address based on the list you provide. The list would continuously be updated by the already stated program.
I'm good with Python and Batch, but I'm running a Mac system right now (which is what I want to implement this program on) and have little knowledge of bash when it comes to the network itself, or of creating background tasks that are time sensitive.
If this is too broad of a question, please do let me know.
Thank you!

You could accomplish this with a simple script, and periodically run it using cron.
Here is an example of how to change your MAC address from a shell script (adapted from here)
#NETWORKING="/etc/init.d/networking" # On some systems
NETWORKING="service network" # On my Fedora 16 box
$NETWORKING stop
ifconfig eth0 hw ether 02:01:02:03:04:08
$NETWORKING start
So you'd need to come up with a way to randomize that MAC address.
Then, use crontab -e to add it to your crontab. Here is a quick reference for crontab.
Here's some python to generate a random MAC address and change it. Only the MAC generation has been tested (for obvious reasons). Also note, you may want to limit the range on some of the bytes in the MAC address, but that is outside the scope of my answer.
from subprocess import call
import random
mac = [random.randint(0, 0xFF) for i in range(6)]
macstr = ':'.join(['{:02X}'.format(x) for x in mac])
print 'Changing MAC address to', macstr
call(['service', 'network', 'stop')
call(['ifconfig', 'eth0', 'hw', 'ether', macstr])
call(['service', 'network', 'start')

Related

Problem communicating over a local area network (LAN) with ROS on WSL2

I am a developer of ROS projects. Recently I am trying using ROS(melodic) on WSL2(Windows Subsystem for Linux), and all things works just great. But I got some trouble when I want to use another PC which also in the same local area network(LAN) to communicate with. Before setting the environment variables like "ROS_MASTER_URI, ROS_IP", I know that since WSL 2 work on Hyper-V so the IP show on WSL2 is not the one in the real LAN. I have to do some command like below in order to make everyone in LAN communicate with the specific host:PORT on WSL2.
netsh interface portproxy delete v4tov4 listenport=$port listenaddress=$addr
But here comes a new question:
The nodes which use TCPROS to communicate with each other have a random PORT every time I launch the file.
How can I handle this kind of problem?
Or is there any information on the internet that I can have a look?
Thank you.
The root problem is described in WSL issue #4150. To quote from that thread,
WSL 2 seems to NAT it's virtual network, instead of making it bridged
to the host NIC.
Option 1 - Port forwarding script on login
Note: From #kraego's comment (and the edited question, which I'm just seeing based on the comment), this is probably not a good option for ROS, since the port numbers are randomly assigned. This makes port forwarding something that would have to be dynamically done.
There are a number of workarounds described in that issue, for which you've already figured out the first part (the port forwarding). The primary technique seems to be to create a PowerShell script to detect the IP address and create the port forwarding rules that runs upon Windows login. This particular comment near the top of the thread seems to be the canonical go-to answer, although many people have posted their tweaks or alternatives throughout the very long thread.
One downside - I believe the script that is mentioned there needs to be run at logon since the WSL subsystem seems to only want to run when a user is logged in. I've found that attempting to run a WSL service or instance through Windows OpenSSH results in that instance/service shutting down soon after the SSH session is closed, unless the user is already logged into Windows with a WSL instance opened.
Option 2 - WSL1
I would also propose that, assuming it fits your workflow and if the ROS works on it (it may not, given the device access you need, but not sure), you can simply use WSL1 instead of WSL2 to avoid this. You can try this out by:
Backing up your existing distro (from PowerShell or cmd, use wsl --export <DistroName> <FileName>
Import the backup into a new WSL1 instance with wsl --import <NewDistroName> <InstallLocation> <FileNameOfBackup> --version 1
It's possible to simply change versions in place, but I tend to like to have a backup anyway before doing it, and as long as you are backing up, you may as well leave the original in place.

User-friendly way to access serial port?

I'm writing an app that allows an Arduino plugged in via USB to send serial data to the app to graph it in realtime. It can scan available ports for the Arduino and attempt to connect to it, but I'm running into permissions issues whether I use pyserial or QtSerialPort. I have added my user to the groups tty, uucp, and dialout. (When listing ports I see that they belong to uucp.) This doesn't seem to do anything. I can chmod a+rw the port every time the Arduino is plugged in but this is not practical because less technical users (i.e. my kids) need to be able to plug it in and use it via a GUI that I'm writing. I've seen suggestions to run the whole script with sudo but this seems less safe than it needs to be, and also requires typing in the command line.
Is there a way to read from the serial port without resetting permissions every time I plug the USB cable in? Or if not, is there an accepted way to do this from the GUI to make sure the permissions are right before the attempt to connect, without running the whole program as sudo? I'm building this on Linux (Arch) btw.
I solved this using udev rules. I created the rules file, which I called /etc/udev/rules.d/80-arduino.rules, and inside I put the following:
SUBSYSTEMS=="usb", ACTION=="add", DRIVERS=="usb", ATTRS{idProduct}=="0042", ATTRS{idVendor}=="2341", ATTRS{manufacturer}=="Arduino (www.arduino.cc)", ATTRS{serial}=="85734323231351404021", RUN+="/bin/arduino_added.sh", RUN+="/bin/device_added.sh", MODE="0660"
This selects for my specific device by serial number as well as manufacturer (ATTRS{serial}=="85734323231351404021"), runs a little script that writes something to a logfile it creates in /tmp (for debugging), and the MODE="0660" opens the port with permissions to let it be accessed.
I had to mess with it a bit to get it to work. Running sudo udevadm control --reload was enough to get the script to write to the logfile each time it was plugged in, but I had to reboot the computer to get it to work with the permissions for some reason.

R - Connect via ssh and execute a command

I would like to connect via ssh to certain equipment in a network.
The requisites are:
It must run a command and capture the output of the ssh session in R (or in bash, or any other programming language, but I would prefer it in R language)
It must enter a plain-text password (as this equipment hasn't been accessed before, and can't be changed with a rsa keypair), so the ssh.utils package doesn't meet this requirement
sshpass can't be used, as I have noticed that it doesn't work for some devices I tested.
I've read all this posts but I can't find an effective way to perform it: link 1, link 2, link 3, link 4
I know the requirements are hard to accomplish, but thank you for your effort!
EDIT:
Sorry if I didn't make myself understandable. I mean I work locally in R and I want to connect to +3000 devices in all of my network via ssh. It is Ubiquiti equipment, and the only open ports are 80 and 22.
If ssh doesn't work, I will use the RSelenium package for R and extract info from port 80. But first I will try with ssh pory 22 as it is a lot more efficient than opening an emulated browser.
The big problem in all these Ubiquiti equipment is that they have a password to log in. That's why requisite No.2 is needed. When I must enter a server that I know, I spend time setting up the rsa keypair so that I don't have to enter a password everytime I connect to a specific server, but it's impossible (or at least, for me it's impossible) to configure all +3000 Ubiquiti equipment with these keypairs.
That's why I don't use snmp, for example, as this equipment maybe they have it activated or not, or the snmp configuration is mistaken. I mean, I have to use something that's activated by default, and in a way, ordered. And only port 80 and port 22 are activated and I know all the user's and password's equipment.
And sshpass is an utility in UNIX/Linux like this link explains that works for servers but doesn't work for Ubiquiti equipment, as long as I've tested it. So I can't use it.
The command I need to extract the output from is mca-status. Simply by entering that into the console makes it print some stats I will like to get from the Ubiquiti equipment.
Correct me, please, if I am wrong in something I've posted. Thanks.
I think you have this wrong. I also have no idea what you are trying to say in point 2, and I have not idea what point 3 is supposed to say.
Now: ssh is a authentication mechanism allowing you (trusted) access to another machine and the ability to run a command. This can be as simple as
edd#max:~$ ssh bud Rscript -e '2+2'
[1] 4
edd#max:~$
where I invoke R (or rather, Rscript) on the machine 'bud' (my desktop) from a session on the machine 'max' (my server). That command could be anything including something which writes to temporary or permanent files. You can then retrieve those files via scp.
Authentication is handled independently -- on Unix we often use ssh-agent which run in the background and against you authenticate on login.
Finally I solved it using the rPython package and the python's paramiko module, as there was no way to do it purely via R.
library(rPython)
python.exec(python.code = c("import paramiko",
"ssh = paramiko.SSHClient()",
"ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())",
sprintf('ssh.connect("%s", username="USER", password="PASSWORD") ', IP),
'stdin, stdout, stderr = ssh.exec_command("mca-status")',
'stats = stdout.readlines()'))

Interprocess communication in Unix/AIX

Is that possible to achieve Inter process communication using any terminal or serial ports in AIX or Unix?
I would like to achieve this by using commands/scripting only where one process writes a string on terminal and another process reads same terminal and processes that string. I know that using pipe also this is possible but I do not have enough idea on that.
Also is there a way we can determine which all ports/terminals are available in AIX machine?
Or is it possible to create new terminal at run time (not the boot time) that will be used by only above two processes?
I think what you want are pty's? Or, another option would be unix domain sockets.
The answer to your first question is "no"... not really. When you write out to a tty, that output is sent out to the real device and not available to be read back.
The list of tty's on a system is: lsdev -Cctty
Creating tty's at run time is possible but not really what you want either. A tty is a child of a serial port and you can not add serial ports arbitrarily. They are real things. With AIX and Power systems, you can add devices while the system is up (hot swap) but that is getting (I'm assuming) way far off your original topic.
The basic different between a pty and a unix domain socket is a pty mimics the output and input process of a real tty in one direction. This is what telnet, rlogin, ssh, and many other daemons use when connections come in. It is easy to make ksh believe that it has a real tty by using pty's. If you don't need that, then they are added trouble that you don't need. Find a link on how to create and use a Unix domain socket and you will have what you need (or a pipe but a pipe requires a parent / child relationship which I assume you do not have).

Can't save the output of minicom into a file

When I use Minicom to capture data from a serial port, I need to save the big data into a file, named minicom.cap. However, if I press Ctrl+A and L to capture file, it failed. No file was created (minicom.cap did not exist beforehand). My download directory was properly created. My OS is Mint, and I read data from Arduino nano v3.0
Did you try to start minicom as
minicom -C capturefile
Unless i got something wrong, it should start to capture incoming data immediately.
OP might miss step "Shift + L" after writing, so the overall procedure is as below:
1 (inside minicom)
2 Ctrl A + Z
3 Shift + L
4 (wait for writing ... )
5 Shift + L
6 (check the file you have written, default is minicom.cap, you may want to find it at /root/minicom.cap)
chown root:dialout /etc/minicom/minirc.dfl
chmod 664 /etc/minicom/minirc.dfl
Now any member of the dialout group can write to minirc.dfl
minicom needs a configuration file that is under root permissions and is stored at /etc/minicom/ and is named minirc.dfl.
Usually when you first run minicom for the first time, as sudo, you can save the minirc.dfl, as if you run as any other user it will not save.
That may be your problem.
This is a little more than the scope of the question calls for but as it has already been answered, I thought somebody might like to do things a little user friendly.
You might be interested in this if you frequently open up a serial connection to multiple devices. You can do this with desktop shortcuts.
I use this for switch and router connections, I have two different console cables, a USB to mini USB and also a db9 with USB A adapter to rj45.
Using the shortcuts here means I don't need to manually reconfigure minicom every time I want to switch devices. The shortcuts give the correct configuration file as a parameter (identifier) as well as the capture file (-C). All i need to do it make sure my devices are connected to my computer with the cables.
If this is something you could use, run these commands as a normal user from your terminal (not from minicom). The configuration files will be saved to your home directory where minicom can find them.
Make a log file directory: You might choose to just log in /var/log but I want quick access to the log files.
mkdir ~/minicom
Find your device:
dmesg | grep tty
If your cable uses an RS-232 chip such as some usb to mini usb console cables, your tty device will likely be on ttyACM* and not ttyUSB*
Create the minicom configuration file using nano. Adapt the capitalised parts to fit your needs, baudrate may be set incorrectly if you get quirky characters or no output. You may create as many as you need along with the desktop shortcuts. just change the identifier.
nano ~/.minirc.IDENTIFIER
pu port /dev/ttyDEVICE
pu baudrate 9600
pu rtscts No
pu logfname /home/USER/minicom/IDENTIFIER.log
Create a desktop shortcut.
nano ~/Desktop/IDENTIFIER.desktop
[Desktop Entry]
Encoding=UTF-8
Name=Minicom IDENTIFIER
Comment=Something relevant to your connection/device name maybe
Exec=minicom IDENTIFIER -C/home/USER/minicom/IDENTIFIER.log
Terminal=1
Type=Application
Make it executable
chmod +x ~/Desktop/IDENTIFIER.desktop
That's it now test the connection, double click your new shortcut.
A note about the IDENTIFIER part, it can be anything. a router or switch model, a device name or type. Do what suits you but maybe use hyphens instead of spaces, I've not tested that but i would imagine they would cause issues such as only getting the name before the first space or worse, attempting to load multiple minicom.identifier files.
Once you have created your first connection, open another terminal:
tail -fn25 ~/minicom/IDENTIFIER.log
Because you have set minicom to capture output, by tailing the log/capture file you can scroll back as far as you need should you be running things with lengthy output, It can be useful for configuration files in routers/switches for example which can be thousands of lines long. Just scroll to the part you are working on in the tailed file to use as a reference while you make changes in minicom, the tail terminal will still collect data but will not automatically jump back to the new line as minicom does when you star to type.
If somebody more shell savvy than myself would like to add to this to make a shell script that accepts the required parameters for setting up a new connection profile,logs etc I wouldn't be too upset about it :)
As an aside, I wanted to add a command prior to minicom running in the shortcut to apply a title to the terminal window using the identifier, I could not get this to work in Ubuntu 20.04 at the time of this posting.

Resources