Python - Netmiko read from 2 columns - python

I have the following code that reads a CSV with a list of hostnames, and runs 2 commands.
I need to change this so that the CSV file it receives has 2 columns, one with the hostname, and another with the corresponding command to be inserted in that router.
Hostname
Comand
CPE_1111
sh ip int br
CPE_2222
sh run
etc
(...)
(...)
nodenum=1
f=open('routers.csv', 'r') #File with Hostnames
c=f.read()
file_as_list = c.splitlines()
with open('Output.txt','w') as f: #File with output
logf = open("error.csv", "a") #Logfile
loga = csv.writer(logf)
loga.writerow(["Hostname"])
for i in file_as_list :
print ("Node", nodenum, "...Checking IP Address...", i)
try:
Connection = netmiko.ConnectHandler(ip=i, device_type="cisco_ios" , username=raw_input("Enter your Username:"), password=getpass.getpass(), verbose=False)
except:
try:
print("Cannot connect via SSH. Trying Telnet")
Connection = netmiko.ConnectHandler(ip=i, device_type="cisco_ios_telnet" , username=raw_input("Enter your Username:"), password=getpass.getpass(), verbose=False)
except:
print("SSH and Telnet Failed")
print("")
now = str(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
loga.writerow([i])
nodenum = nodenum+1
continue
hostname = (Connection.send_command("show run | include hostname"))
cellular = (Connection.send_command("sh ip int brief"))
Connection.disconnect
(...)

Your answer lies with how the csv is read. You can use csv.DictReader() to read each row and convert it to a dictionary.
import csv
with open(file="routers.csv", mode="rt") as f:
next(f)
lst = csv.DictReader(f=f, fieldnames=["ip", "cmd"])
ips_cmds = list(lst)
for ip_cmd in ips_cmds:
print("Hostname:", ip_cmd["ip"])
print("Command:", ip_cmd["cmd"], end="\n\n")
# Hostname: CPE_1111
# Command: show ip interface brief
# Hostname: CPE_2222
# Command: show running-config
Then in the for loop where you connect to each router, you can select the value you need from the keys specified in fieldnames.
conn = ConnectHandler(
device_type="cisco_ios",
ip=ip_cmd["ip"],
username=input("Username: "),
password=getpass(prompt="Password: "),
secret=getpass(prompt="Enable Secret: "),
fast_cli=False,
)
hostname = conn.send_command(command_string=ip_cmd["cmd"])
Don't forget to add the parentheses for disconnect() function to be executed.
conn.disconnect()

Related

Multiple IP addresse PING

The below code works perfectly if the input file ip_file.txt have the following format.
8.8.8.8
www.google.com
www.yahoo.com
www.microsoft.com
But how can I ping the IPs if the input is something like this and write the output same in format.
8.8.8.8, www.google.com
www.yahoo.com,www.microsoft.com
My code is given below:
import subprocess
import threading
import time
import re
timestr = time.strftime("%Y-%m-%d %H%M%S")
timesec = time.strftime("%Y-%m-%d%H:%M:%S")
raw_list = []
def ping(host):
results_file = open("results_bng_" + str(timestr) + ".txt", "a")
p = subprocess.Popen(["ping", host, "-n", "5"], shell=True, universal_newlines=True, stdout=subprocess.PIPE)
response = p.communicate()[0]
for i in response.split("\n"):
para =i.split("=")
# print(para)
try:
if para[0].strip() =="Minimum":
latency =para[3].strip()
print(latency)
latfin = re.findall('\d+', latency)
latfin1 = latfin[0]
except:
print("time run")
if "Received = 1" and "Approximate" in response:
print(f"UP {host} Ping Successful")
results_file.write(f"{host},UP,{latfin1},{timesec}"+ "\n")
else:
print(f"Down {host} Ping Unsuccessful")
results_file.write(f"{host},Down,0,{timesec}" + "\n")
results_file.close()
with open(r'bng.txt', "r") as server_list_file:
hosts = server_list_file.read()
hosts_list =hosts.split('\n')
num_threads = 1
number = 0
while number< len(hosts_list):
# print(number)
for i in range(num_threads):
t = threading.Thread(target=ping, args=(hosts_list[number+i],))
t.start()
t.join()
number = number +1
You could replace each newline character with a comma and split at each comma:
bng.txt:
8.8.8.8, www.google.com
www.yahoo.com,www.microsoft.com
Code:
with open(r'bng.txt', "r") as server_list_file:
hosts = server_list_file.read()
hosts_list = hosts.replace('\n', ',').split(',')
for host in hosts_list:
print(host.strip()) # strip remaining whitespaces
Out:
8.8.8.8
www.google.com
www.yahoo.com
www.microsoft.com
Pings are specific IP packets that can only be sent to one ip at a time. There are special IP which are meant for broadcasting. For example, you could direct your ping at a specific subnet and the devices connected to that subnet could all choose to answer to a ping. Note that most routers or IP stacks do not answer to such broadcast pings nowadays as they could be used to discover the devices that are connected to the subnet.
After you open your file you need to do a for loop and read each line at a time and split based on comma. That will ultimately give you a list of all single IPs / hosts to ping. Something like.
listOfAllIPs = []
for line in file:
x = line.split(',') ## this makes x a list
listOfAllIPs = listOfAllIPs + x
After that runs you should be able to use listOfAllIPs as your input. It will have 1 IP or host per item. Just iterate through.
this will be useful for you
import os
import subprocess
list = []
with open('./ip.txt', 'r') as f:
ip = f.read().split(',')
list.append(ip)
for i in range(len(list[0])):
ip = list[0][i]
print(30*'-')
if subprocess.Popen(["ping", "-n", "1", "-w", "200", ip], shell=True).wait() == 1: print('active', ip)
else: print('inactive', ip)

Python script - add file read as alternative option

I have the following code:
#!/usr/bin/env python
# coding=utf-8
import threading
import requests
import Queue
import sys
import re
#ip to num
def ip2num(ip):
ip = [int(x) for x in ip.split('.')]
return ip[0] << 24 | ip[1] << 16 | ip[2] << 8 | ip[3]
#num to ip
def num2ip(num):
return '%s.%s.%s.%s' % ((num & 0xff000000) >> 24,(num & 0x00ff0000) >> 16,(num & 0x0000ff00) >> 8,num & 0x000000ff)
def ip_range(start, end):
return [num2ip(num) for num in range(ip2num(start), ip2num(end) + 1) if num & 0xff]
def bThread(iplist):
threadl = []
queue = Queue.Queue()
for host in iplist:
queue.put(host)
for x in xrange(0, int(SETTHREAD)):
threadl.append(tThread(queue))
for t in threadl:
t.start()
for t in threadl:
t.join()
#create thread
class tThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
while not self.queue.empty():
host = self.queue.get()
try:
checkServer(host)
except:
continue
def checkServer(host):
ports = [80]
for k in ports:
try:
aimurl = "http://"+host+":"+str(k)
response = requests.get(url=aimurl,timeout=3)
serverText = response.headers['server']
if (response.status_code) == 403:
print "-"*50+"\n"+aimurl +" Server: "+serverText
except:
pass
if __name__ == '__main__':
print '\n############# CDN IP #############'
print ' '
print '################################################\n'
global SETTHREAD
try:
SETTHREAD = sys.argv[2]
iplist = []
file = open(sys.argv[1], 'r')
tmpIpList = file.readlines()
for ip in tmpIpList:
iplist.append(ip.rstrip("\n"))
print '\nEscaneando '+str(len(iplist))+" IP's...\n"
bThread(iplist)
except KeyboardInterrupt:
print 'Keyboard Interrupt!'
sys.exit()
This script works as follows, a range of ip is entered:
python2 script.py 104.0.0.0-104.0.1.255 100 (100 is the number of threads)
I want to add support so that it reads the ip of a file, and that the range also works.
python2 script.py ips.txt 100
I tried this:
file = open(sys.argv[1], 'r')
iplist = file.readlines()
But it does not work.
Edit1: added file reading code recommended by user Syed Hasan, the problem seems to be the bThread(iplist) function
I assume you're attempting to use 'iplist' the same way as your CLI input was attempting to parse it. However, the readlines function simply reads the entire file at once and appends a newline (\n) at the end (provided you do format the IPs with a succeeding newline character).
Currently, you should be getting a list of IPs with a succeeding newline character. Try removing it from the rightmost end using rstrip:
file = open(sys.argv[1], 'r')
tmpIpList = file.readlines()
for ip in tmpIpList:
iplist.append(ip.rstrip("\n"))
How you switch between the two modes is a challenge you should attempt to solve. Perhaps use command-line parameter support to identify the mode of operations (look into the argparse library).

find IP address and port in a text file using python

I have a text file which have text similar to mentioned below
harry's source ip and port combination is 192.168.4.1/5897 and he is
trying to access destination 202.158.14.1/7852
The text may vary. My task is to find the first pair of IP and port.
However my code is not working
import re
with open('traffic.txt', 'r') as file:
fi = file.readlines()
re_ip = re.compile("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
re_port = re.compile("^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$\/(\d+)")
for line in fi:
ip = re.findall(re_ip,line)
port = re.findall(re_port,line)
print port , ip
Correct code
import re
with open('traffic.txt', 'r') as file:
fi = file.readlines()
re_ip = re.compile("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")
re_port = re.compile("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/(\d+)")
for line in fi:
port = re.findall(re_port,line)
ip = re.findall(re_ip,line)
print "PORT is " , port , "ip is " ,ip

How to read list of ip address from a text file and print it out

*I want to print out ip addresses from textfile (solved)
****no ip address in the textfile and error message will be shown.** (solved)
I have attached my current codes at the bottom, can any one please help?**
**
****IP addresses in the textfile will look like this.****
**
192.168.12.1
192.168.12.28
*****And the following is my current codes...*****
f=open('output.txt','r')
print "IP address is ", f.read()
f.close()
Use file.readlines() inside a loop.
So, the Code will be:
f=open('output2.txt','r')
c=f.readlines()
for i in c :
print ("IP address of attacker is ", i)
f.close()
Get IP address from text file and check. See my code on git.
import socket
import re
f = open('ip_list.txt', 'r') #Text file with many ip address
o = f.read()
ip1 = re.findall( r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", o )
hosts = ip1
ports = [80]
for host in hosts:
for port in ports:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)
result = s.connect_ex((host, port))
if result == 0:
print(" [*] Port " + str(port) + " open!" + host)
else: print("[+] CLOSE HOST " + host + ":" + str(port))
except:
pass
It is best to open the file in its own context with 'with'. This way it will be closed automatically after the last line has been reached. Then loop trough the lines and add your text before each line. Another upside of this solution is that you do not have to keep all IPs in memory. The IPs will be streamed one at a time.
This code will also print a message if no ip was found.
with open('output2.txt','r') as f:
ip_not_found = True
for line in f:
ip_not_found = False
print "IP address of attacker is {IP}".format(IP=line)
if ip_not_found:
print 'no ip address was found'
import sys
import os
import time
b='sudo tshark -i ens33 -Y "tcp contains "attack"" -T fields -e ip.src -a duration:20>output2.txt'
a=os.popen(b)
time.sleep(22)
with open(output2.txt,"r") as f:
ip=f.read.split('\n')
for Ip in ip:
print "IP address of attacker is ", Ip
You have to just split the contents of the file at every newline.
import ipaddress
ip_address_file = open('ip.txt', 'r') # open text file with ip addresses
for i in ip_address_file: # loop through the ip text file
i = i.strip() # read each line
try:
i = ipaddress.ip_address(str(i)) #validates either ip is ipv4 or 6
except ValueError: #catch error for invalid ip format
print('invalid ip '.format(i))
continue # if line empty continue with loop

When I'm writing to a file deletes everything except the replaced word

When I'm trying to write to a file deletes everything in my file except the words I'm trying to replace..
here is my code:
app.route('/', methods=['POST'])
def writing():
address_1 = address1()
address_2 = network1()
try:
if request.method =="POST":
var1 = request.form ['addr1']
var2 = request.form ['addr2']
changeaddress = [var1, var2]
address = [address_1, address_2]
new_var = []
cur_addr = 0
new_line = None
with open('address.txt','r+') as file:
for line in file:
if address[cur_addr] in line:
new_line = line.replace(address[cur_addr], changeaddress[cur_addr] + "\n")
cur_addr += 1
new_var.append(new_line)
with open('address.txt','w') as file:
file.writelines(new_var)
except BaseException as e:
print e
return render_template('addr.html', var1=var1,var2=var2)
this is my text file :
#######
Address 192.168.0.3
Address 192.168.0.1 <--- I'm reading this
######
##############
########
Network 123.123.0.1 <---- I'm reading this
after runing the code for example I replace 192.168.0.1 for 1.1.1.1 and 123.123.0.1 for 0.0.0.0 I get this:
Address 1.1.1.1
Network 0.0.0.0
As you can see it deleting everything except what I replaced. I would like to get something like this:
#######
Address 192.168.0.3
Address 1.1.1.1
######
##############
########
Network 0.0.0.0
So my app should not replace the lines I want to replace.
You are only adding the replaced line to the list that you write.
As I said in a previous question, indent the new line, and in case it wasn't clear there, append the non-replaced line.
if address[cur_addr] in line:
# replace
new_var.append(new_line)
else:
# keep
new_var.append(line)

Categories