Interfacing with TUN\TAP for MAC OSX (Lion) using Python - python

I found the following tun\tap example program and can not get it to work:
http://www.secdev.org/projects/tuntap_udp/files/tunproxy.py
I have modified the following lines:
f = os.open("/dev/tun0", os.O_RDWR)
ifs = ioctl(f, TUNSETIFF, struct.pack("16sH", "toto%d", TUNMODE))
ifname = ifs[:16].strip("\x00")
The first line was modified to reflect the real location of the driver. It was originally
f = os.open("/dev/net/tun", os.O_RDWR)
Upon running I get the following error:
sudo ./tuntap.py -s 9000
Password:
Traceback (most recent call last):
File "./tuntap.py", line 65, in <module>
ifs = ioctl(f, TUNSETIFF, struct.pack("16sH", "toto%d", TUNMODE))
IOError: [Errno 25] Inappropriate ioctl for device
I am using the latest tun\tap drivers installed from http://tuntaposx.sourceforge.net/download.xhtml

The OSX tun/tap driver seems to work a bit different. The Linux example dynamically allocates a tun interface, which does not work in OSX, at least not in the same way.
I stripped the code to create a basic example of how tun can be used on OSX using a self-selected tun device, printing each packet to the console. I added Scapy as a dependency for pretty printing, but you can replace it by a raw packet dump if you want:
import os, sys
from select import select
from scapy.all import IP
f = os.open("/dev/tun12", os.O_RDWR)
try:
while 1:
r = select([f],[],[])[0][0]
if r == f:
packet = os.read(f, 4000)
# print len(packet), packet
ip = IP(packet)
ip.show()
except KeyboardInterrupt:
print "Stopped by user."
You will either have to run this as root, or do a sudo chown your_username /dev/tun12 to be allowed to open the device.
To configure it as a point-to-point interface, type:
$ sudo ifconfig tun12 10.12.0.2 10.12.0.1
Note that the tun12 interface will only be available while /dev/tun12 is open, i.e. while the program is running. If you interrupt the program, your tun interface will disappear, and you will need to configure it again next time you run the program.
If you now ping your endpoint, your packets will be printed to the console:
$ ping 10.12.0.1
Ping itself will print request timeouts, because there is no tunnel endpoint responding to your ping requests.

so about the 'No such file or directory' error when doing:
f = os.open("/dev/tun12", os.O_RDWR)
this worked for me:
brew install Caskroom/cask/tuntap

Related

Command output is corrupted when executed using Python Paramiko exec_command

I'm a software tester, trying to verify that the log on a remote QNX (a BSD variant) machine will contain the correct entries after specific actions are taken. I am able to list the contents of the directory in which the log resides, and use that information in the command to read (really want to use tail -n XX <file>) the file. So far, I always get a "(No such file or directory)" when trying to read the file.
We are using Froglogic Squish for automated testing, because the Windows UI (that interacts with the server piece on QNX) is built using Qt extensions for standard Windows elements. Squish uses Python 2.7, so I am using Python 2.7.
I am using paramiko for the SSH connection to the QNX server. This has worked great for sending commands to the simulator piece that also runs on the QNX server.
So, here's the code. Some descriptive names have been changed to avoid upsetting my employer.
import sys
import time
import select
sys.path.append(r"C:\Python27\Lib\site-packages")
sys.path.append(r"C:\Python27\Lib\site-packages\pip\_vendor")
import paramiko
# Import SSH configuration variables
ssh_host = 'vvv.xxx.yyy.zzz'
thelog_dir = "/logs/the/"
ssh_user = 'un'
ssh_pw = 'pw'
def execute_Command(fullCmd):
outptLines = []
#
# Try to connect to the host.
# Retry a few times if it fails.
#
i = 1
while True:
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(ssh_host, 22, ssh_user, ssh_pw)
break
except paramiko.AuthenticationException:
log ("Authentication failed when connecting to %s" % ssh_host)
return 1
except:
log ("Could not SSH to %s, waiting for it to start" % ssh_host)
i += 1
time.sleep(2)
# If we could not connect within time limit
if i == 30:
log ("Could not connect to %s. Giving up" % ssh_host)
return 1
# Send the command (non-blocking?)
stdin, stdout, stderr = ssh.exec_command(fullCmd, get_pty=True)
for line in iter(stdout.readline, ""):
outptLines.append(line)
#
# Disconnect from the host
#
ssh.close()
return outptLines
def get_Latest_Log():
fullCmd = "ls -1 %s | grep the_2" %thelog_dir
files = execute_Command(fullCmd)
theFile = files[-1]
return theFile
def main():
numLines = 20
theLog = get_Latest_Log()
print("\n\nThe latest log is %s\n\n" %theLog)
fullCmd = "cd /logs/the; tail -n 20 /logs/the/%s" %theLog
#fullCmd = "tail -n 20 /logs/the/%s" %theLog
print fullCmd
logLines = execute_Command(fullCmd)
for line in logLines:
print line
if __name__ == "__main__":
# execute only if run as a script
main()
I have tried to read the file using both tail and cat. I have also tried to get and open the file using Paramiko's SFTP client.
In all cases, the response of trying to read the file fails -- despite the fact that listing the contents of the directory works fine. (?!) And BTW, the log file is supposed to be readable by 'world'. Permissions are -rw-rw-r--.
The output I get is:
"C:\Users\xsat086\Documents\paramikoTest>python SSH_THE_MsgChk.py
The latest log is the_20210628_115455_205.log
cd /logs/the; tail -n 20 /logs/the/the_20210628_115455_205.log
(No such file or directory)the/the_20210628_115455_205.log"
The file name is correct. If I copy and paste the tail command into an interactive SSH session with the QNX server, it works fine.
Is it something to do with the 'non-interactive' nature of this method of sending commands? I read that some implementations of SSH are built upon a command that offers a very limited environment. I don't see how that would impact this tail command.
Or am I doing something stupid in this code?
I cannot really explain completely, why you get the results you get.
But in general a corrupted output is a result of enabling and not handling terminal emulation. You enable the terminal emulation using get_pty=True. Remove it. You should not use the terminal emulation, when automating command execution.
Related question:
Is there a simple way to get rid of junk values that come when you SSH using Python's Paramiko library and fetch output from CLI of a remote machine?

Is there a way to make a function to test the ssh connect-ability of devices on the network without typing in the individual device?

I am working on a program where connecting over SSH to a raspberry pi is necessary to run the program through my GUI app window in python, here is what I have right now to "test" ssh connections on all devices but i have to type in the actual IP of the pi itself. I need to make this where it just tests connection of everything on the network and connects to the available device.
Any help?
def raspi_connecter():
for n in range(1, 255):
server_ip= "10.0.0.153".format(n)
subprocess.Popen('ssh' + ' ' + 'dev#' + server_ip, shell= True)
Here's python2 program (I've never reworked it for python3) that finds your Raspberries. It runs nmap to create XML output then crudely parses that.
It needs the iproute module sudo apt install python{,3}-pyroute
#!/usr/bin/python2
from pyroute2 import IPRoute
import socket
import subprocess
import xml.etree.ElementTree as ET
ip = IPRoute()
for x in ip.get_addr(label='eth0',family=socket.AF_INET):
ipa =x.get_attr('IFA_ADDRESS')+"/"+str(x['prefixlen'])
print ipa
process = subprocess.Popen(['sudo','nmap','-oX', '/tmp/nmap.xml','-sn',ipa],stdout=subprocess.PIPE)
process.wait()
tree = ET.parse('/tmp/nmap.xml')
for node in tree.iter('address'):
try:
if node.attrib['addrtype'] == "ipv4":
ip = node.attrib['addr']
except:
pass
try:
if node.attrib['vendor'] == "Raspberry Pi Foundation":
print "IP:", ip
except:
pass
Once you have an IP address for a Raspberry then you can run ssh with subprocess (or ping or netcat). It will need additional testing for Raspberry Pi 4 and Pi400 devices (as I don't have either of those (which use the new MAC OUI).

Can't install the drivers needed to connect my Tracer BN Solar Charger to Raspberry Pi 4

I'm trying to use pymodbus lib to retrieve data from my Epever tracer BN series solar charge controller, here is my pymodbus code:
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
client = ModbusClient(method = 'rtu', port = '/dev/ttyUSB0', baudrate = 115200)
client.connect()
result = client.read_input_registers(0x3100,6,unit=1)
print("result = ")
print (result)
solarVoltage = float(result.registers[0] / 100.0)
solarCurrent = float(result.registers[1] / 100.0)
batteryVoltage = float(result.registers[4] / 100.0)
chargeCurrent = float(result.registers[5] / 100.0)
client.close()
but I kept getting this error:
result =
Modbus Error: [Input/Output] Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (0 received)
Traceback (most recent call last):
File "/home/pi/Documents/solar charge controler.py", line 9, in <module>
solarVoltage = float(result.registers[0] / 100.0)
AttributeError: 'ModbusIOException' object has no attribute 'registers'
So I did a lot of research and found out I need some kind of driver to be able to use my USB to rs485, and I came across this LINK
but I don't understand any of the commands there, I just started writing the on the terminal, I as able to install the raspberrypi-kernel-headers, whatever that is but when I do sudo bundle then sudo make I get this on the terminal:
pi#raspberrypi:~ $ sudo bundle
sudo: bundle: command not found
pi#raspberrypi:~ $ sudo make
make: *** No targets specified and no makefile found. Stop.
So after all that can someone guide me thru the right commands to write on
the terminal in order to install the usb to rs485 driver?
thank you
I followed this guide and the attached code which works in compiling the driver. There's some minute detail that differs it from the normal one. Though still stuck on not being able to read the device, but this will probably help you get the ttyXRUSB0 mapped up:
https://medium.com/#jcrbcn/installing-the-exar-usb-driver-on-the-raspberrypi-for-teknic-sc-hub-39de533f0502

Connect from a cisco device to http server on debian

I'm trying to communicate with a http server which is running on debian strech from a brand new out of the box cisco device. Now, the so called zero touch configuration is no problem:
The Switch gets an IP address and such via DHCP and a link to where to fetch it's initial configuration.
The switch gets its basic configuration such as user credentials etc.
The problem rises when I try to search through a database on the server from the switch. In this database some variables are stored. Depending the serialnumber of the switch, it should receive a specific hostname, Mgmt address etc.
On those new switches there is a python module integrated so I ran some tests. I tried to fetch the serial number and got them whithout any problems. The moment I tried to write the serial number on a txt file on the server I got this error
Traceback (most recent call last): File "", line 1, in
IOError: [Errno 2] No such file or directory:
'http://10.232.152.19:80/temp.txt'
Code so far:
from cli import cli
def get_serial():
serial = cli("show version | include System Serial\n")
serial = (serial.split()[-1])
f = open ("http://10.232.152.19:80/temp.txt", "a")
f.write(serial)
f.close
get_serial()
The problem you are facing is because you are trying to open a file from the network. You need to download the file first in you system and then open it. You should use urllib to fetch the file and then open it. then save it and again push it back.
import urllib
txt = urllib.urlopen(target_url).read()

Python PXSSH GUI spawn on login failure

I can't stop the GUI from spawning when a login failure occurs.
simple example that fails and spawns a GUI.
>>> import pxssh
>>>
>>> ssh = pxssh.pxssh()
>>> ssh.force_password = True
>>> ssh.login('127.0.0.1', 'root', 'falsePW')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/dist-packages/pxssh.py", line 226, in login
raise ExceptionPxssh ('password refused')
pxssh.ExceptionPxssh: password refused
>>>
I have tried disabling x11 forwarding in these files, nothing changed.
/etc/ssh/ssh_config
/etc/ssh/sshd_config
I have also tried going into the pxssh module and where it sets the ssh options I set the flag -x Disables X11 forwarding. still no change.
I am running cinnamon on Linux Mint, the pxssh docs said some x display managers will start up a GUI. To solve this is says to remove all ssh-agents, which I have also tried to no avail.
After tampering with the pxssh.py module I found a solution thats very simple.
inside the pxssh.py module: sudo nano /usr/lib/python2.7/dist-packages/pxssh.py
Location Update: sudo nano /usr/lib/python2.7/dist-packages/pexpect/pxssh.py
class pxssh(spawn)
def _init__( parameters )
# change these variables to shown value
self.force_password = True
self.auto_prompt_reset = False
# next under the login function
def login( parameters )
# set the -x flag: disables x11 forwarding (removing GUI)
ssh_options = '-q -x'

Categories

Resources