While loop adding unwanted line to file - python-3.x

The while loop adds the user input to the file as desired, but when I am done and hit Q to stop, instead of just stopping the while loop, a q gets concatenated and written to the file, which is not desired.
How do I quit the script without writing/concatenating q ?
def regular_host():
host = ''
while host !='q':
host = input('Enter host >')
stuff = (f'add host name h-{host}-g ip-address {host}\n')
print(stuff)
with open('file.txt', 'a') as f:
f.write(stuff)
File contents after running the script:
add host name h-192.168.1.1-g ip-address 192.168.1.1
add host name h-q-g ip-address q
Expected results:
add host name h-192.168.1.1-g ip-address 192.168.1.1
Actual results:
add host name h-192.168.1.1-g ip-address 192.168.1.1
add host name h-q-g ip-address q

The unwanted line is added since when the user presses q the block of code inside while loop runs for one last time and the loop is terminated since host == 'q'. A simple modification in the code just below should solve the issue.
def regular_host():
host = ''
while host !='q':
host = input('Enter host >')
if host == 'q':
break
stuff = (f'add host name h-{host}-g ip-address {host}\n')
print(stuff)
with open('file.txt', 'a') as f:
f.write(stuff)

Related

Use for loop with dictionary

I'm using Napalm to change the hostname of many network devices. Since the config will be different for each device, I need the script to assign the proper config to each device based on it's IP address. This seems like a dictionary would work best.
devicelist = {'10.255.32.1': 'device1.cfg', '10.255.32.5': 'device2.cfg'}
I need help calling the key value in the script below for each IP address. I have highlighted the line of code where this is required.
from napalm import get_network_driver
devicelist = ['10.255.32.1',
'10.255.32.5'
]
for ip_address in devicelist:
print ("Connecting to " + str(ip_address))
driver = get_network_driver('ios')
iosv = driver(ip_address, 'admin', 'password')
iosv.open()
**iosv.load_merge_candidate(filename='device1.cfg')**
diffs = iosv.compare_config()
if len(diffs) > 0:
print(diffs)
iosv.commit_config()
else:
print('No changes required.')
iosv.discard_config()
iosv.close()
You are asking for a simple access by key on your dictionary, combined with a for loop over the dictionary which is automatically a for loop over the keys. Minimal example:
devicelist = {'10.255.32.1': 'device1.cfg', '10.255.32.5': 'device2.cfg'}
for ipAdress in devicelist:
print("This IP : {} maps to this name: {}".format(ipAdress, devicelist[ipAdress]))
Output:
This IP : 10.255.32.1 maps to this name: device1.cfg
This IP : 10.255.32.5 maps to this name: device2.cfg

Multiple inputs and lines loop to write to file - python

Currently I'm pasting multiple lines of names which loops through each line and writes into a file. This prompts me to paste values in which works.
However I would like to have another prompt for other values like IPs etc going through the same loop.
Probably something very simple but any help would be appreciated.
Thanks in advance.
subnet = input(('Paste the subnet mask: '))
quit = ''
for line in iter(input, quit):
with open('my_file.yml', 'a') as data_file:
data_file.write(" - host: " + line + "\n ip: " + ips + "\n subnet:
" + subnet)
You can do what you want without iter by using an infinite while that only breaks out when no input is entered. I could have also checked for no input with if not host, because empty strings return False (See: Truth Value Testing).
The file is only opened once. There no need to repeatedly open it each iteration.
I have used an f-string with the call to write(), but you can still use normal strings like you did.
subnet = input('Paste the subnet mask: ')
with open('my_file.yml', 'a') as data_file:
while True:
host = input('Enter host: ')
if host == '':
break
ips = input('Enter IPs: ')
if ips == '':
break
data_file.write(f' - host: {host}\n ip: {ips}\n subnet: {subnet}\n')
Contents of my_file.yml:
- host: localhost
ip: 192.168.0.5
subnet: 255.255.255.0
- host: anotherhost
ip: 192.168.1.1
subnet: 255.255.255.0

How to fix windows decline error for lan file transfer

I'm a 14 year old beginner in software design but have good knowledge in python basic and acute amounts in networking. i recently got a raspberry pi 3 b+ brand new and am trying to make a python program that will allow me to transmit information input from my hp PC to my pi so it can display the info, this project is to help me with school, i have code typed and it runs but when i try to run the "client code", this is so my pi can receive the input data, i get an error saying that the device has declined my connection request, what should i do to fix the issue? if you want to see the code i can post it, but i'm not sure if that is necessary.
i only tried changing the port number in both programs, since that is not the issue and i' new to LAN and networking, i haven't tried anything else.
as requested my code is:(not HTML, CSS, or HTML. it's just easier to use that interface.
# send.py
import socket # Import socket module
port = 60000 # Reserve a port for your service.
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
print 'Server listening....'
while True:
conn, addr = s.accept() # Establish connection with client.
print 'Got connection from', addr
data = conn.recv(1024)
print('Server received', repr(data))
filename='mytext.txt'
f = open(filename,'rb')
l = f.read(1024)
while (l):
conn.send(l)
print('Sent ',repr(l))
l = f.read(1024)
f.close()
print('Done sending')
conn.send('Thank you for connecting')
conn.close()
# recieve.py
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 60000 # Reserve a port for your service.
s.connect((host, port))
s.send("Hello server!")
with open('received_file', 'wb') as f:
print 'file opened'
while True:
print('receiving data...')
data = s.recv(1024)
print('data=%s', (data))
if not data:
break
# write data to a file
f.write(data)
f.close()
print('Successfully get the file')
s.close()
print('connection closed')
Unfortunately, this answer requires Python 3.5+.
Before running this code please make sure you've worked out which IP you will be using for your server and client (help at the bottom).
Step 1 - Ensure a simple ping works
Server code:
import socket
# FIND IP
# The IP to use will be different depending
# on whether you have WiFi or Ethernet, so
# you need to choose whichever one that is
ips = socket.gethostbyname_ex(socket.gethostname())[-1]
print(*[f"{i}: {j}" for i, j in enumerate(ips)], sep="\n")
ip = ips[int(input(" > "))]
# SELECT PORT
port = 10000
#SETUP SERVER
# Create server socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((ip, port))
# A queue of 1 clients is more than enough for our application
sock.listen(1)
print(f"Listening on {ip}:{port}")
while True:
try:
(clientsock, address) = sock.accept()
# so if there's nothing to read we don't wait too long
clientsock.settimeout(0.01)
ping_string = clientsock.recv(5).decode()
if ping_string == "ping!":
print("ping!")
clientsock.sendall(b"ping!")
else:
print("no ping!")
print(ping_string)
clientsock.sendall(b"nopng")
clientsock.shutdown(1)
clientsock.close()
except KeyboardInterrupt:
# Add a way to safely exit the infinite loop
break
sock.close()
Client code:
import socket
# GET IP
print("IP of server")
ip = input(" > ")
# SELECT PORT
port = 10000
# SETUP SOCKET
# Create server socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
print(f"Conencted to {ip}:{port}")
# so if there's nothing to read we don't wait too long
sock.settimeout(0.01)
sock.sendall(b"ping!")
ping_string = sock.recv(5).decode()
if ping_string == "ping!":
print("ping!")
else:
print("no ping!")
sock.close()
OUTPUT:
Server:
0: 192.168.56.1
1: 192.168.1.151
> 1
Listening on 192.168.1.151:10000
Client:
Type ip of server
> 192.168.1.151
Conencted to 192.168.1.151:10000
ping!
If this doesn't work, make sure your computer can ping your raspberry pi, and vice versa. Go into CMD (I presume your HP PC is Windows) and type ping ____ (replacing ____ with the internal ip address of your raspberry pi.
If the terminal doesn't appear to be pinging something, you need to go onto your computer and raspberry pi to find they're internal ips, which you can find out how to do online.
Step 2 - The fun part
We're now going to setup your file server.
Server code:
import socket
# OPEN FILE TO SEND ACROSS
with open("filesend.txt", mode="rb") as file:
file_string = file.read()
# FIND IP
# The IP to use will be different depending
# on whether you have WiFi or Ethernet, so
# you need to choose whichever one that is
ips = socket.gethostbyname_ex(socket.gethostname())[-1]
print(*[f"{i}: {j}" for i, j in enumerate(ips)], sep="\n")
ip = ips[int(input(" > "))]
# SELECT PORT
port = 10000
#SETUP SERVER
# Create server socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((ip, port))
# A queue of 1 clients is more than enough for our application
sock.listen(1)
print(f"Listening on {ip}:{port}")
while True:
try:
(clientsock, address) = sock.accept()
# so if there's nothing to read we don't wait too long
clientsock.settimeout(0.01)
# send length
clientsock.sendall((str(len(file_string)) + ".").encode())
clientsock.sendall(file_string)
print("Sent file!")
response_code = clientsock.recv(1).decode()
if response_code != "0":
print("ERROR! response was not 0")
print(response_code)
clientsock.shutdown(1)
clientsock.close()
except KeyboardInterrupt:
# Add a way to safely exit the infinite loop
break
sock.close()
Client code:
import socket
# SELECT IP
print("IP of server")
ip = input(" > ")
# SELECT PORT
port = 10000
# SETUP SOCKET
# Create server socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip, port))
print(f"Conencted to {ip}:{port}")
# so if there's nothing to read we don't wait too long
sock.settimeout(0.01)
# Get length of file sent across
len_string = ""
c = ""
while c != ".":
c = sock.recv(1).decode()
len_string += c
length = int(len_string[:-1])
file_string = sock.recv(length)
# send a status code back to the server
sock.sendall(b"0")
with open("filerecv.txt", mode="wb") as file:
file.write(file_string)
print(file_string.decode())
sock.close()
OUTPUT:
Server:
0: 192.168.56.1
1: 192.168.1.151
> 1
Listening on 192.168.1.151:10000
Client:
IP of server
> 192.168.1.151
Conencted to 192.168.1.151:10000
THIS IS A TEST!
Once again, ensure the ip you tell the client to connect to is the same as the one you have selected from the list provided in the server script. Also ensure that the ip address can be connected to, ie don't use the one for when the pc's on WiFi if it's currently on Ethernet.
Hope this works for you. Any issues leave down in the comments :)
EDIT
WINDOWS
Sample output from ipconfig:
> ipconfig
Windows IP Configuration
Ethernet adapter Ethernet:
Connection-specific DNS Suffix . : home
IPv6 Address. . . . . . . . . . . : 2a00:23c6:6586:2400:e47a:c60e:812b:1123
IPv6 Address. . . . . . . . . . . : fdaa:bbcc:ddee:0:e47a:c60e:812b:1123
Temporary IPv6 Address. . . . . . : 2a00:23c6:6586:2400:d1fe:95f5:27c3:c4b8
Temporary IPv6 Address. . . . . . : fdaa:bbcc:ddee:0:d1fe:95f5:27c3:c4b8
Link-local IPv6 Address . . . . . : fe80::e47a:c60e:812b:1123%19
IPv4 Address. . . . . . . . . . . : 192.168.1.151
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : fe80::8aa6:c6ff:fe23:7a15%19
192.168.1.254
You're looking for this line:
IPv4 Address. . . . . . . . . . . : 192.168.1.151
And the IP is whatever value is at the end (eg 192.168.1.151)
FIND THE IP OF YOUR RASPBERRY PI
Unless you've changed some advanced settings your Raspberry Pi's hostname will be raspberrypi, or raspberrypi.local. I've seen both. If you want to know the IP address, use the Python script below, and try to ping all the IPs from the list it prints to find out which one IP is actually used by the Pi.
Run this on your PC:
import socket
host1 = "raspberrypi"
host2 = "raspberrypi.local"
try:
ip1 = socket.gethostbyname_ex(host1)[-1]
except:
ip1 = []
try:
ip2 = socket.gethostbyname_ex(host2)[-1]
except:
ip2 = []
print(list(set(ip1+ip2)))
Any more issues, please let me know :)

Is their way, I can open a putty session and execute the commands written in the code below; (don't not share pywinauto examples)

Below is the source code which I created on python, however, unable to run from window machine.
If I use the same on Ubuntu, it works well.
Is their way, I can open a putty session and execute the commands written in the code below;
HOST = " 192.168.15.101"
user = input("Enter your device username: ")
password = getpass.getpass()
tn = telnetlib.Telnet(HOST)
tn.read_until("login: ")
tn.write(user + "\n")
if password:
tn.read_until("Password: ")
tn.write(password + "\n")
tn.write("enable\n")
tn.write("cisco\n")
tn.write("conf t\n")
tn.write("interface loop 1\n")
tn.write("ip address 1.1.1.1 255.255.255.255\n")
tn.write("interface loop 2\n")
tn.write("ip address 1.1.1.2 255.255.255.255\n")
tn.write("interface loop 3\n")
tn.write("ip address 1.1.1.3 255.255.255.255\n")
tn.write("interface loop 4\n")
tn.write("ip address 1.1.1.4 255.255.255.255\n")
tn.write("end\n")
tn.write("exit\n")
print(tn.read_all())

Create a DNS server and redirect all request to my site

I want to change in my router the DNS server and in the DNS server I want that every request will return the same site. Basically I need to add some more logic befure the DNS response an answer.
I don't want to write a DNS from scratch. Do you have any suggestions for me ?
maybe, open-source DNS (מo matter what language-c, cpp, python, java...) that can I easily change (if so, which one and where)
can I do it with google-cloud-dns ?
Thanks you.
Take a look here: http://code.activestate.com/recipes/491264-mini-fake-dns-server/
It's a Python script, and it looks like exactly what you need to have.
import socket
class DNSQuery:
def __init__(self, data):
self.data=data
self.dominio=''
tipo = (ord(data[2]) >> 3) & 15 # Opcode bits
if tipo == 0: # Standard query
ini=12
lon=ord(data[ini])
while lon != 0:
self.dominio+=data[ini+1:ini+lon+1]+'.'
ini+=lon+1
lon=ord(data[ini])
def respuesta(self, ip):
packet=''
if self.dominio:
packet+=self.data[:2] + "\x81\x80"
packet+=self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00' # Questions and Answers Counts
packet+=self.data[12:] # Original Domain Name Question
packet+='\xc0\x0c' # Pointer to domain name
packet+='\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04' # Response type, ttl and resource data length -> 4 bytes
packet+=str.join('',map(lambda x: chr(int(x)), ip.split('.'))) # 4bytes of IP
return packet
if __name__ == '__main__':
ip='192.168.1.1'
print 'pyminifakeDNS:: dom.query. 60 IN A %s' % ip
udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udps.bind(('',53))
try:
while 1:
data, addr = udps.recvfrom(1024)
p=DNSQuery(data)
udps.sendto(p.respuesta(ip), addr)
print 'Respuesta: %s -> %s' % (p.dominio, ip)
except KeyboardInterrupt:
print 'Finalizando'
udps.close()
Regards.

Resources