A simple introduction to network programming using Python 3 socket module. This material was used in a 2-day summer training at Mansoura University in August 2016.
The examples included come from other tutorials with some changes. The source code of these and other examples can be found here:
https://github.com/ksonbol/socket_examples
What is Socket Programming in Python | EdurekaEdureka!
YouTube Link: https://youtu.be/T0rYSFPAR0A
** Python Certification Training: https://www.edureka.co/python **
This Edureka PPT on 'Socket Programming in Python' is to educate you as to how networks are created using the socket module in Python. Below are the topics covered in this PPT:
What are sockets?
How to achieve socket programming in Python?
Servers and clients
Client-server communication
Transferring Python objects
Python Tutorial Playlist: https://goo.gl/WsBpKe
Blog Series: http://bit.ly/2sqmP4s
Follow us to never miss an update in the future.
YouTube: https://www.youtube.com/user/edurekaIN
Instagram: https://www.instagram.com/edureka_learning/
Facebook: https://www.facebook.com/edurekaIN/
Twitter: https://twitter.com/edurekain
LinkedIn: https://www.linkedin.com/company/edureka
Castbox: https://castbox.fm/networks/505?country=in
A simple introduction to network programming using Python 3 socket module. This material was used in a 2-day summer training at Mansoura University in August 2016.
The examples included come from other tutorials with some changes. The source code of these and other examples can be found here:
https://github.com/ksonbol/socket_examples
What is Socket Programming in Python | EdurekaEdureka!
YouTube Link: https://youtu.be/T0rYSFPAR0A
** Python Certification Training: https://www.edureka.co/python **
This Edureka PPT on 'Socket Programming in Python' is to educate you as to how networks are created using the socket module in Python. Below are the topics covered in this PPT:
What are sockets?
How to achieve socket programming in Python?
Servers and clients
Client-server communication
Transferring Python objects
Python Tutorial Playlist: https://goo.gl/WsBpKe
Blog Series: http://bit.ly/2sqmP4s
Follow us to never miss an update in the future.
YouTube: https://www.youtube.com/user/edurekaIN
Instagram: https://www.instagram.com/edureka_learning/
Facebook: https://www.facebook.com/edurekaIN/
Twitter: https://twitter.com/edurekain
LinkedIn: https://www.linkedin.com/company/edureka
Castbox: https://castbox.fm/networks/505?country=in
Overview of socket API.
A network socket is an interface for an application to connect to a host‘s network stack (part of the OS). Sockets provide an abstraction of the network. Applications use the transport services available on the socket interface for communication with a peer application.
Transport protocol such as TCP, UDP or SCTP offer different levels of service. TCP for example provides reliable stream-oriented transport service while UDP more reflects the best-effort kind of service provided by the underlying IP protocol layer.
Sockets are bound to a transport address. For TCP/IP sockets this means an IP address and port number.
Sockets provide only very basic data transport services without any higher level functions like parameter marshaling or serialization. These functions have to be performed by the applications. These functions are often hidden in middleware platforms like distributed object technologies (CORBA, RMI, DCOM) or web service frameworks (WCF, JAX-WS).
Multicast sockets make the IP multicast capability accessible to applications. Multicast sockets are often used for streaming services where multiple applications are recipients of the same data packets.
Introduction
This Tutorial is On Socket Programming In C Language for Linux. Instructions Give Below will only work On Linux System not in windows.
Socket API In windows is called Winsock and there we can discuss about that in another tutorial.
What is Socket?
Sockets are a method for communication between a client program and a server program in a network.
A socket is defined as "the endpoint in a connection." Sockets are created and used with a set of programming requests or "function calls" sometimes called the sockets application programming interface (API).
The most common sockets API is the Berkeley UNIX C interface for sockets.
Sockets can also be used for communication between processes within the same computer.
Overview of socket API.
A network socket is an interface for an application to connect to a host‘s network stack (part of the OS). Sockets provide an abstraction of the network. Applications use the transport services available on the socket interface for communication with a peer application.
Transport protocol such as TCP, UDP or SCTP offer different levels of service. TCP for example provides reliable stream-oriented transport service while UDP more reflects the best-effort kind of service provided by the underlying IP protocol layer.
Sockets are bound to a transport address. For TCP/IP sockets this means an IP address and port number.
Sockets provide only very basic data transport services without any higher level functions like parameter marshaling or serialization. These functions have to be performed by the applications. These functions are often hidden in middleware platforms like distributed object technologies (CORBA, RMI, DCOM) or web service frameworks (WCF, JAX-WS).
Multicast sockets make the IP multicast capability accessible to applications. Multicast sockets are often used for streaming services where multiple applications are recipients of the same data packets.
Introduction
This Tutorial is On Socket Programming In C Language for Linux. Instructions Give Below will only work On Linux System not in windows.
Socket API In windows is called Winsock and there we can discuss about that in another tutorial.
What is Socket?
Sockets are a method for communication between a client program and a server program in a network.
A socket is defined as "the endpoint in a connection." Sockets are created and used with a set of programming requests or "function calls" sometimes called the sockets application programming interface (API).
The most common sockets API is the Berkeley UNIX C interface for sockets.
Sockets can also be used for communication between processes within the same computer.
در جلسه به بررسی ماژول ها و برنامه نویسی ماژولار در پایتون پرداختیم
PySec101 Fall 2013 J5E2 By Mohammad Reza Kamalifard
Talk About:
Modular programming and Python modules
The detail architecture of the most relevant consumer drones will be introduced, continuing with the communications protocol between the pilot (app in the smartphone or remote controller) and the drone. Manual reverse engineering on the binary protocol used for this communication will lead to identifying and understanding all the commands from each of the drones, and later inject commands back.
Learning Objectives:
1: Understand whenever a protocol between drone and pilot is secure.
2: Learn about a new reverse engineering methodology for these protocols.
3: Review a set of good practices to secure the environment surrounding a drone.
(Source: RSA Conference USA 2018)
Curious about how to take that first step from CCNP to Programmer? Hey guess what, you don't even have to make an entire career out of programming, you can use it to AUGMENT your existing job responsibilities and make your life easier. This deck won't teach you everything you need to know, but it should help making that first step a little bit easier.
Python se ha convertido en el lenguaje más usado para desarrollar herramientas dentro del ámbito de la seguridad. Esta charla se centrará en las diferentes formas en que un analista puede aprovechar el lenguaje de programación Python tanto desde el punto de vista defensivo como ofensivo.
Desde el punto de vista defensivo Python es una de las mejores opciones como herramienta de pentesting por la gran cantidad de módulos que nos pueden ayudar a desarrollar nuestras propias herramientas con el objetivo de realizar un análisis de nuestro objetivo.
Desde el punto de vista ofensivo podemos utilizar Python para recolección de información de nuestro objetivo de forma pasiva y activa. El objetivo final es obtener el máximo conocimiento posible en el contexto que estamos auditando. Entre los principales puntos a tratar podemos destacar:
1.Introducción a Python para proyectos de ciberseguridad(5 min)
2.Herramientas de pentesting(10 min)
3.Herramientas Python desde el punto de vista defensivo(10 min)
4.Herramientas Python desde el punto de vista ofensivo(10 min)
[CB16] Esoteric Web Application Vulnerabilities by Andrés RianchoCODE BLUE
This talk will show esoteric web application vulnerabilities in detail, these vulnerabilities would be missed in a quick review by most security consultants, but could lead to remote code execution, authentication bypass and purchasing items in merchants using Paypal as their payment gateway without actually paying. SQL injections are dead, and I don’t care: let's explore the world of null, nil and NULL; noSQL injections; host header injections that lead to phone call audio interception; paypal’s double spent and Rails’ MessageVerifier remote code execution.
--- Andres Riancho
Andrés Riancho is an application security expert that currently leads the community driven, Open Source, w3af project and provides in-depth Web Application Penetration Testing services to companies around the world.
In the research field, he discovered critical vulnerabilities in IPS appliances from 3com and ISS, contributed with SAP research performed at one of his former employers and reported vulnerabilities in hundreds of web applications.
His main focus has always been the Web Application Security field, in which he developed w3af, a Web Application Attack and Audit Framework used extensively by penetration testers and security consultants.
Andrés has spoken and hold trainings at many security conferences around the globe, like BlackHat (USA and Europe), SEC-T (Sweden),DeepSec (Austria), PHDays (Moscow), SecTor (Toronto), OWASP (Poland),CONFidence (Poland), OWASP World C0n (USA), CanSecWest (Canada),PacSecWest (Japan), T2 (Finland) and Ekoparty (Buenos Aires).
Andrés founded Bonsai Information Security, a web security focused consultancy firm, in 2009 in order to further research into automated Web Application Vulnerability detection and exploitation.
A year ago, I was a committed VPS and dedicated-machine deployer. I thought the cloud imposed silly restrictions - how dare you take away my shell account! Whaddya mean I can't save files locally? Since then, I've had some interesting experiences. I've worked on big cloud-deployed systems, and certain large traditionally-deployed systems, and I've seen how a lot of the decisions that you're ... encouraged to make when designing an app to run in the cloud. Most interestingly, I've discovered how those same decisions can make for a much better app regardless of where it'll end up. In this talk, I'll share those architectural patterns with you, and show why they work. Hopefully, I'll convince all of you to build cloud castles -- even if you've got your foundation firmly on the ground.
How to Design a Great API (using flask) [ploneconf2017]Devon Bernard
How do you build an API that developers love building and consumers love using?
There's a lot that goes into creating a great API. This presentation shares some tips & tricks, architectural patterns, and best practices that go into building a great engineering environment around your API.
Talk presented on Oct 18, 2017 at PloneConf2017.
Topics covered by this talk:
Intuitive Practices:
standardization, configuration/environment files, ORMs, SQLAlchemy, database migrations, Alembic, database seeds, requirements.txt, package management, dependency management, setup scripts
Durable Practices:
Unit Tests, virtual environments, flush vs commit, error rollbacks, request lifecycle, session lifecycle
Flexible Practices:
Directory structures, application factories, blueprints, python debugger
Reliable Practices:
Logging, progressive rollouts, slack hooks, cron health checks, api versioning, api analytics
Use Friendly Practices:
Endpoint design, endpoint documentation, debugging tools, postman
Speed Practices:
Python profiling, Bulk SQL Inserts, caching
Python se ha convertido en el lenguaje más usado para desarrollar herramientas dentro del ámbito de la seguridad. Esta charla se centrará en las diferentes formas en que un analista puede aprovechar el lenguaje de programación Python tanto desde el punto de vista defensivo como ofensivo.
Desde el punto de vista defensivo Python es una de las mejores opciones como herramienta de pentesting por la gran cantidad de módulos que nos pueden ayudar a desarrollar nuestras propias herramientas con el objetivo de realizar un análisis de nuestro objetivo.
Desde el punto de vista ofensivo podemos utilizar Python para recolección de información de nuestro objetivo de forma pasiva y activa. El objetivo final es obtener el máximo conocimiento posible en el contexto que estamos auditando. Entre los principales puntos a tratar podemos destacar:
1.Introducción a Python para proyectos de ciberseguridad(5 min)
2.Herramientas de pentesting(10 min)
3.Herramientas Python desde el punto de vista defensivo(10 min)
4.Herramientas Python desde el punto de vista ofensivo(10 min)
( ** Python Certification Training: https://www.edureka.co/python ** )
This Edureka PPT on Advanced Python tutorial covers all the important aspects of using Python for advanced use-cases and purposes. It establishes all of the concepts like system programming , shell programming, pipes and forking to show how wide of a spectrum Python offers to the developers.
Python Tutorial Playlist: https://goo.gl/WsBpKe
Blog Series: http://bit.ly/2sqmP4s
Follow us to never miss an update in the future.
Instagram: https://www.instagram.com/edureka_learning/
Facebook: https://www.facebook.com/edurekaIN/
Twitter: https://twitter.com/edurekain
LinkedIn: https://www.linkedin.com/company/edureka
Cisco Malware: A new risk to consider in perimeter security designsManuel Santander
The networking equipment like switches and routers have historically been considered as passive elements in implementations of the security architecture. However, the new programming capabilities of these devices involve the risk of malicious software. If this risk materializes, imagine the consequences to the company\'s information. This presentation shows proof of concept on what features could support a malware inside IOS devices, how to detect it, how to remediate it and how to minimize the risk of occurrence within a security architecture.
Fire & Ice: Making and Breaking macOS FirewallsPriyanka Aash
"In the ever raging battle between malicious code and anti-malware tools, firewalls play an essential role. Many a malware has been generically thwarted thanks to the watchful eye of these products.
However on macOS, firewalls are rather poorly understood. Apple's documentation surrounding it's network filter interfaces is rather lacking and all commercial macOS firewalls are closed source.
This talk aims to take a peek behind the proverbial curtain revealing how to both create and 'destroy' macOS firewalls.
In this talk, we'll first dive into what it takes to create an effective firewall for macOS. Yes we'll discuss core concepts such as kernel-level socket filtering—but also how to communicate with user-mode components, install privileged code in a secure manner, and simple ways to implement self-defense mechanisms (including protecting the UI from synthetic events).
Of course any security tool, including firewalls, can be broken. After looking at various macOS malware specimens that proactively attempt to detect such firewalls, we'll don our 'gray' (black?) hats to discuss various attacks against these products. And while some attacks are well known, others are currently undisclosed and can generically bypass even today's most vigilant Mac firewalls.
But all is not lost. By proactively discussing such attacks, combined with our newly-found understandings of firewall internals, we can improve the existing status quo, advancing firewall development. With a little luck, such advancements may foil, or at least complicate the lives of tomorrow's sophisticated Mac malware!"
Similar to Python Network Programming – Course Applications Guide (20)
PHP Frameworks: I want to break free (IPC Berlin 2024)Ralf Eggert
In this presentation, we examine the challenges and limitations of relying too heavily on PHP frameworks in web development. We discuss the history of PHP and its frameworks to understand how this dependence has evolved. The focus will be on providing concrete tips and strategies to reduce reliance on these frameworks, based on real-world examples and practical considerations. The goal is to equip developers with the skills and knowledge to create more flexible and future-proof web applications. We'll explore the importance of maintaining autonomy in a rapidly changing tech landscape and how to make informed decisions in PHP development.
This talk is aimed at encouraging a more independent approach to using PHP frameworks, moving towards a more flexible and future-proof approach to PHP development.
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
The publishing industry has been selling digital audiobooks and ebooks for over a decade and has found its groove. What’s changed? What has stayed the same? Where do we go from here? Join a group of leading sales peers from across the industry for a conversation about the lessons learned since the popularization of digital books, best practices, digital book supply chain management, and more.
Link to video recording: https://bnctechforum.ca/sessions/selling-digital-books-in-2024-insights-from-industry-leaders/
Presented by BookNet Canada on May 28, 2024, with support from the Department of Canadian Heritage.
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...DanBrown980551
Do you want to learn how to model and simulate an electrical network from scratch in under an hour?
Then welcome to this PowSyBl workshop, hosted by Rte, the French Transmission System Operator (TSO)!
During the webinar, you will discover the PowSyBl ecosystem as well as handle and study an electrical network through an interactive Python notebook.
PowSyBl is an open source project hosted by LF Energy, which offers a comprehensive set of features for electrical grid modelling and simulation. Among other advanced features, PowSyBl provides:
- A fully editable and extendable library for grid component modelling;
- Visualization tools to display your network;
- Grid simulation tools, such as power flows, security analyses (with or without remedial actions) and sensitivity analyses;
The framework is mostly written in Java, with a Python binding so that Python developers can access PowSyBl functionalities as well.
What you will learn during the webinar:
- For beginners: discover PowSyBl's functionalities through a quick general presentation and the notebook, without needing any expert coding skills;
- For advanced developers: master the skills to efficiently apply PowSyBl functionalities to your real-world scenarios.
Securing your Kubernetes cluster_ a step-by-step guide to success !KatiaHIMEUR1
Today, after several years of existence, an extremely active community and an ultra-dynamic ecosystem, Kubernetes has established itself as the de facto standard in container orchestration. Thanks to a wide range of managed services, it has never been so easy to set up a ready-to-use Kubernetes cluster.
However, this ease of use means that the subject of security in Kubernetes is often left for later, or even neglected. This exposes companies to significant risks.
In this talk, I'll show you step-by-step how to secure your Kubernetes cluster for greater peace of mind and reliability.
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Ramesh Iyer
In today's fast-changing business world, Companies that adapt and embrace new ideas often need help to keep up with the competition. However, fostering a culture of innovation takes much work. It takes vision, leadership and willingness to take risks in the right proportion. Sachin Dev Duggal, co-founder of Builder.ai, has perfected the art of this balance, creating a company culture where creativity and growth are nurtured at each stage.
Accelerate your Kubernetes clusters with Varnish CachingThijs Feryn
A presentation about the usage and availability of Varnish on Kubernetes. This talk explores the capabilities of Varnish caching and shows how to use the Varnish Helm chart to deploy it to Kubernetes.
This presentation was delivered at K8SUG Singapore. See https://feryn.eu/presentations/accelerate-your-kubernetes-clusters-with-varnish-caching-k8sug-singapore-28-2024 for more details.
Epistemic Interaction - tuning interfaces to provide information for AI supportAlan Dix
Paper presented at SYNERGY workshop at AVI 2024, Genoa, Italy. 3rd June 2024
https://alandix.com/academic/papers/synergy2024-epistemic/
As machine learning integrates deeper into human-computer interactions, the concept of epistemic interaction emerges, aiming to refine these interactions to enhance system adaptability. This approach encourages minor, intentional adjustments in user behaviour to enrich the data available for system learning. This paper introduces epistemic interaction within the context of human-system communication, illustrating how deliberate interaction design can improve system understanding and adaptation. Through concrete examples, we demonstrate the potential of epistemic interaction to significantly advance human-computer interaction by leveraging intuitive human communication strategies to inform system design and functionality, offering a novel pathway for enriching user-system engagements.
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...UiPathCommunity
💥 Speed, accuracy, and scaling – discover the superpowers of GenAI in action with UiPath Document Understanding and Communications Mining™:
See how to accelerate model training and optimize model performance with active learning
Learn about the latest enhancements to out-of-the-box document processing – with little to no training required
Get an exclusive demo of the new family of UiPath LLMs – GenAI models specialized for processing different types of documents and messages
This is a hands-on session specifically designed for automation developers and AI enthusiasts seeking to enhance their knowledge in leveraging the latest intelligent document processing capabilities offered by UiPath.
Speakers:
👨🏫 Andras Palfi, Senior Product Manager, UiPath
👩🏫 Lenka Dulovicova, Product Program Manager, UiPath
SAP Sapphire 2024 - ASUG301 building better apps with SAP Fiori.pdfPeter Spielvogel
Building better applications for business users with SAP Fiori.
• What is SAP Fiori and why it matters to you
• How a better user experience drives measurable business benefits
• How to get started with SAP Fiori today
• How SAP Fiori elements accelerates application development
• How SAP Build Code includes SAP Fiori tools and other generative artificial intelligence capabilities
• How SAP Fiori paves the way for using AI in SAP apps
1. Page 1 of 185
1 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
Python Network Programming
by Mihai Cătălin Teodosiu, CCNP, Udemy & GNS3 Academy Instructor
2. Page 2 of 185
2 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
1. What’s this document all about?
Note: This e-book is a comprehensive guide containing all the applications developed
throughout my Python Network Programming courses: “Python Network Programming
- Part 1: Build 7 Python Apps”, “Python Network Programming - Part 2: Multivendor
Environment” & “Python Network Programming - Part 3: Scapy & Security Tools”.
Note: This document is intended for students enrolled in all three courses and is
distributed for personal use only. The distribution of this material to people not
enrolled in the “Python Network Programming” course series is strictly prohibited
and is subject to copyright infringement. The author of this document is entitled to
invoke legal and technological measures to prevent and penalize copyright infringement.
More information here: https://en.wikipedia.org/wiki/Copyright_infringement
IMPORTANT, BEFORE YOU CONTINUE!
All the code, scripts and applications are explained, turned into working applications and
tested inside the course. For detailed explanations and testing, please see the course
sections referenced by each application below. Pay attention to comments in the code!
3. Page 3 of 185
3 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
2. Python Network Programming - Part 1: Build 7 Python Apps
NOTE! Python programming knowledge is required in order to understand the network
automation applications below. Learn Python from scratch inside the video course series!
2.1. Telnet with Python
(template only, reference: Section 11. Python Networking)
#Open telnet connection to devices
def open_telnet_conn(ip):
#Change exception message
try:
#Define telnet parameters
username = 'teopy'
password = 'python'
TELNET_PORT = 23
TELNET_TIMEOUT = 5
READ_TIMEOUT = 5
#Logging into device
connection = telnetlib.Telnet(ip, TELNET_PORT, TELNET_TIMEOUT)
output = connection.read_until("name:", READ_TIMEOUT)
connection.write(username + "n")
output = connection.read_until("word:", READ_TIMEOUT)
connection.write(password + "n")
time.sleep(1)
#Setting terminal length for entire output - no pagination
connection.write("terminal length 0n")
time.sleep(1)
#Entering global config mode
connection.write("n")
connection.write("configure terminaln")
time.sleep(1)
#Open user selected file for reading
selected_cmd_file = open(cmd_file, 'r')
#Starting from the beginning of the file
selected_cmd_file.seek(0)
#Writing each line in the file to the device
for each_line in selected_cmd_file.readlines():
connection.write(each_line + 'n')
time.sleep(1)
4. Page 4 of 185
4 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Closing the file
selected_cmd_file.close()
#Test for reading command output
#output = connection.read_very_eager()
#print output
#Closing the connection
connection.close()
except IOError:
print "Input parameter error! Please check username, password and
file name."
#Calling the Telnet function
open_telnet_conn(ip)
5. Page 5 of 185
5 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
2.2. SSH with Python
(template only, reference: Section 11. Python Networking)
#Open SSHv2 connection to devices
def open_ssh_conn(ip):
#Change exception message
try:
#Define SSH parameters
selected_user_file = open(user_file, 'r')
#Starting from the beginning of the file
selected_user_file.seek(0)
username = selected_user_file.readlines()[0].split(',')[0]
#Starting from the beginning of the file
selected_user_file.seek(0)
password = selected_user_file.readlines()[0].split(',')[1]
#Logging into device
session = paramiko.SSHClient()
session.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
session.connect(ip, username = username, password = password)
connection = session.invoke_shell()
#Setting terminal length for entire output - no pagination
connection.send("terminal length 0n")
time.sleep(1)
#Entering global config mode
connection.send("n")
connection.send("configure terminaln")
time.sleep(1)
#Open user selected file for reading
selected_cmd_file = open(cmd_file, 'r')
#Starting from the beginning of the file
selected_cmd_file.seek(0)
#Writing each line in the file to the device
for each_line in selected_cmd_file.readlines():
connection.send(each_line + 'n')
time.sleep(2)
6. Page 6 of 185
6 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Closing the user file
selected_user_file.close()
#Closing the command file
selected_cmd_file.close()
#Checking command output for IOS syntax errors
output = connection.recv(65535)
if re.search(r"% Invalid input detected at", output):
print "* There was at least one IOS syntax error on device %s"
% ip
else:
print "nDONE for device %s" % ip
#Test for reading command output
#print output + "n"
#Closing the connection
session.close()
except paramiko.AuthenticationException:
print "* Invalid username or password. n* Please check the
username/password file or the device configuration!"
print "* Closing program...n"
#Calling the SSH function
open_ssh_conn(ip)
7. Page 7 of 185
7 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
2.3. SNMP with Python
(template only, reference: Section 11. Python Networking)
#!/usr/bin/env python
from pysnmp.entity.rfc3413.oneliner import cmdgen
#SNMP function
def snmp_get(ip):
#Creating command generator object
cmdGen = cmdgen.CommandGenerator()
#Performing SNMP GETNEXT operations on the OSPF OIDs
#The basic syntax of nextCmd: nextCmd(authData, transportTarget,
*varNames)
#The nextCmd method returns a tuple of (errorIndication, errorStatus,
errorIndex, varBindTable)
errorIndication, errorStatus, errorIndex, varBindNbrTable =
cmdGen.nextCmd(cmdgen.CommunityData(comm),
cmdgen.UdpTransportTarget((ip, 161)),
'1.3.6.1.2.1.14.10.1.3')
#print
cmdGen.nextCmd(cmdgen.CommunityData(comm),cmdgen.UdpTransportTarget((ip,
161)),'1.3.6.1.2.1.14.10.1.3')
#print varBindNbrTable
errorIndication, errorStatus, errorIndex, varBindNbrIpTable =
cmdGen.nextCmd(cmdgen.CommunityData(comm),
cmdgen.UdpTransportTarget((ip, 161)),
'1.3.6.1.2.1.14.10.1.1')
#print varBindNbrIpTable
errorIndication, errorStatus, errorIndex, varBindHostTable =
cmdGen.nextCmd(cmdgen.CommunityData(comm),
cmdgen.UdpTransportTarget((ip, 161)),
'1.3.6.1.4.1.9.2.1.3')
#print varBindHostTable
8. Page 8 of 185
8 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
errorIndication, errorStatus, errorIndex, varBindHostIdTable =
cmdGen.nextCmd(cmdgen.CommunityData(comm),
cmdgen.UdpTransportTarget((ip, 161)),
'1.3.6.1.2.1.14.1.1')
#print varBindHostIdTable
10. Page 10 of 185
10 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
############# Application #1 - Part #1 #############
import random
import sys
def subnet_calc():
try:
print "n"
#Checking IP address validity
while True:
ip_address = raw_input("Enter an IP address: ")
#Checking octets
a = ip_address.split('.')
if (len(a) == 4) and (1 <= int(a[0]) <= 223) and (int(a[0]) !=
127) and (int(a[0]) != 169 or int(a[1]) != 254) and (0 <= int(a[1]) <= 255
and 0 <= int(a[2]) <= 255 and 0 <= int(a[3]) <= 255):
break
else:
print "nThe IP address is INVALID! Please retry!n"
continue
masks = [255, 254, 252, 248, 240, 224, 192, 128, 0]
#Checking Subnet Mask validity
while True:
subnet_mask = raw_input("Enter a subnet mask: ")
#Checking octets
b = subnet_mask.split('.')
if (len(b) == 4) and (int(b[0]) == 255) and (int(b[1]) in
masks) and (int(b[2]) in masks) and (int(b[3]) in masks) and (int(b[0]) >=
int(b[1]) >= int(b[2]) >= int(b[3])):
break
else:
print "nThe subnet mask is INVALID! Please retry!n"
continue
############# Application #1 - Part #2 #############
#Algorithm for subnet identification, based on IP and Subnet Mask
#Convert mask to binary string
mask_octets_padded = []
mask_octets_decimal = subnet_mask.split(".")
#print mask_octets_decimal
for octet_index in range(0, len(mask_octets_decimal)):
11. Page 11 of 185
11 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#print bin(int(mask_octets_decimal[octet_index]))
binary_octet =
bin(int(mask_octets_decimal[octet_index])).split("b")[1]
#print binary_octet
if len(binary_octet) == 8:
mask_octets_padded.append(binary_octet)
elif len(binary_octet) < 8:
binary_octet_padded = binary_octet.zfill(8)
mask_octets_padded.append(binary_octet_padded)
#print mask_octets_padded
decimal_mask = "".join(mask_octets_padded)
#print decimal_mask #Example: for 255.255.255.0 =>
11111111111111111111111100000000
#Counting host bits in the mask and calculating number of
hosts/subnet
no_of_zeros = decimal_mask.count("0")
no_of_ones = 32 - no_of_zeros
no_of_hosts = abs(2 ** no_of_zeros - 2) #return positive value for
mask /32
#print no_of_zeros
#print no_of_ones
#print no_of_hosts
#Obtaining wildcard mask
wildcard_octets = []
for w_octet in mask_octets_decimal:
wild_octet = 255 - int(w_octet)
wildcard_octets.append(str(wild_octet))
#print wildcard_octets
wildcard_mask = ".".join(wildcard_octets)
#print wildcard_mask
############# Application #1 - Part #3 #############
#Convert IP to binary string
ip_octets_padded = []
ip_octets_decimal = ip_address.split(".")
for octet_index in range(0, len(ip_octets_decimal)):
binary_octet =
bin(int(ip_octets_decimal[octet_index])).split("b")[1]
if len(binary_octet) < 8:
binary_octet_padded = binary_octet.zfill(8)
12. Page 12 of 185
12 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
ip_octets_padded.append(binary_octet_padded)
else:
ip_octets_padded.append(binary_octet)
#print ip_octets_padded
binary_ip = "".join(ip_octets_padded)
#print binary_ip #Example: for 192.168.2.100 =>
11000000101010000000001001100100
#Obtain the network address and broadcast address from the binary
strings obtained above
network_address_binary = binary_ip[:(no_of_ones)] + "0" *
no_of_zeros
#print network_address_binary
broadcast_address_binary = binary_ip[:(no_of_ones)] + "1" *
no_of_zeros
#print broadcast_address_binary
net_ip_octets = []
for octet in range(0, len(network_address_binary), 8):
net_ip_octet = network_address_binary[octet:octet+8]
net_ip_octets.append(net_ip_octet)
#print net_ip_octets
net_ip_address = []
for each_octet in net_ip_octets:
net_ip_address.append(str(int(each_octet, 2)))
#print net_ip_address
network_address = ".".join(net_ip_address)
#print network_address
bst_ip_octets = []
for octet in range(0, len(broadcast_address_binary), 8):
bst_ip_octet = broadcast_address_binary[octet:octet+8]
bst_ip_octets.append(bst_ip_octet)
#print bst_ip_octets
bst_ip_address = []
for each_octet in bst_ip_octets:
bst_ip_address.append(str(int(each_octet, 2)))
#print bst_ip_address
broadcast_address = ".".join(bst_ip_address)
#print broadcast_address
13. Page 13 of 185
13 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Results for selected IP/mask
print "n"
print "Network address is: %s" % network_address
print "Broadcast address is: %s" % broadcast_address
print "Number of valid hosts per subnet: %s" % no_of_hosts
print "Wildcard mask: %s" % wildcard_mask
print "Mask bits: %s" % no_of_ones
print "n"
############# Application #1 - Part #4 #############
#Generation of random IP in subnet
while True:
generate = raw_input("Generate random ip address from subnet?
(y/n)")
if generate == "y":
generated_ip = []
#Obtain available IP address in range, based on the
difference between octets in broadcast address and network address
for indexb, oct_bst in enumerate(bst_ip_address):
#print indexb, oct_bst
for indexn, oct_net in enumerate(net_ip_address):
#print indexn, oct_net
if indexb == indexn:
if oct_bst == oct_net:
#Add identical octets to the generated_ip
list
generated_ip.append(oct_bst)
else:
#Generate random number(s) from within
octet intervals and append to the list
generated_ip.append(str(random.randint(int(oct_net), int(oct_bst))))
#IP address generated from the subnet pool
#print generated_ip
y_iaddr = ".".join(generated_ip)
#print y_iaddr
print "Random IP address is: %s" % y_iaddr
print "n"
continue
else:
print "Ok, bye!n"
break
except KeyboardInterrupt:
print "nnProgram aborted by user. Exiting...n"
sys.exit()
14. Page 14 of 185
14 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Calling the function
subnet_calc()
16. Page 16 of 185
16 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
2.5.1. SSH network configuration
############# Application #2 - Part #1 #############
import paramiko
import threading
import os.path
import subprocess
import time
import sys
import re
#Checking IP address file and content validity
def ip_is_valid():
check = False
global ip_list
while True:
#Prompting user for input
print "n# # # # # # # # # # # # # # # # # # # # # # # # # # #
#n"
ip_file = raw_input("# Enter IP file name and extension: ")
print "n# # # # # # # # # # # # # # # # # # # # # # # # # # # #"
#Changing exception message
try:
#Open user selected file for reading (IP addresses file)
selected_ip_file = open(ip_file, 'r')
#Starting from the beginning of the file
selected_ip_file.seek(0)
#Reading each line (IP address) in the file
ip_list = selected_ip_file.readlines()
#Closing the file
selected_ip_file.close()
except IOError:
print "n* File %s does not exist! Please check and try
again!n" % ip_file
#Checking octets
for ip in ip_list:
a = ip.split('.')
if (len(a) == 4) and (1 <= int(a[0]) <= 223) and (int(a[0]) !=
127) and (int(a[0]) != 169 or int(a[1]) != 254) and (0 <= int(a[1]) <= 255
and 0 <= int(a[2]) <= 255 and 0 <= int(a[3]) <= 255):
check = True
17. Page 17 of 185
17 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
break
else:
print 'n* There was an INVALID IP address! Please check
and try again!n'
check = False
continue
#Evaluating the 'check' flag
if check == False:
continue
elif check == True:
break
############# Application #2 - Part #2 #############
#Checking IP reachability
print "n* Checking IP reachability. Please wait...n"
check2 = False
while True:
for ip in ip_list:
ping_reply = subprocess.call(['ping', '-c', '2', '-w', '2', '-
q', '-n', ip])
if ping_reply == 0:
check2 = True
continue
elif ping_reply == 2:
print "n* No response from device %s." % ip
check2 = False
break
else:
print "n* Ping to the following device has FAILED:", ip
check2 = False
break
#Evaluating the 'check' flag
if check2 == False:
print "* Please re-check IP address list or device.n"
ip_is_valid()
elif check2 == True:
print 'n* All devices are reachable. Waiting for
username/password file...n'
break
#Checking user file validity
def user_is_valid():
global user_file
18. Page 18 of 185
18 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
while True:
print "# # # # # # # # # # # # # # # # # # # # # # # # # # # #n"
user_file = raw_input("# Enter user/pass file name and extension:
")
print "n# # # # # # # # # # # # # # # # # # # # # # # # # # # #"
#Changing output messages
if os.path.isfile(user_file) == True:
print "n* Username/password file has been validated. Waiting
for command file...n"
break
else:
print "n* File %s does not exist! Please check and try
again!n" % user_file
continue
#Checking command file validity
def cmd_is_valid():
global cmd_file
while True:
print "nn# # # # # # # # # # # # # # # # # # # # # # # # # # #
#n"
cmd_file = raw_input("# Enter command file name and extension: ")
print "n# # # # # # # # # # # # # # # # # # # # # # # # # # # #"
#Changing output messages
if os.path.isfile(cmd_file) == True:
print "n* Sending command(s) to device(s)...n"
break
else:
print "n* File %s does not exist! Please check and try
again!n" % cmd_file
continue
#Change exception message
try:
#Calling IP validity function
ip_is_valid()
except KeyboardInterrupt:
print "nn* Program aborted by user. Exiting...n"
sys.exit()
#Change exception message
try:
#Calling user file validity function
user_is_valid()
except KeyboardInterrupt:
print "nn* Program aborted by user. Exiting...n"
19. Page 19 of 185
19 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
sys.exit()
#Change exception message
try:
#Calling command file validity function
cmd_is_valid()
except KeyboardInterrupt:
print "nn* Program aborted by user. Exiting...n"
sys.exit()
############# Application #2 - Part #3 #############
#Open SSHv2 connection to devices
def open_ssh_conn(ip):
#Change exception message
try:
#Define SSH parameters
selected_user_file = open(user_file, 'r')
#Starting from the beginning of the file
selected_user_file.seek(0)
#Reading the username from the file
username = selected_user_file.readlines()[0].split(',')[0]
#Starting from the beginning of the file
selected_user_file.seek(0)
#Reading the password from the file
password =
selected_user_file.readlines()[0].split(',')[1].rstrip("n")
#Logging into device
session = paramiko.SSHClient()
#For testing purposes, this allows auto-accepting unknown host
keys
#Do not use in production! The default would be RejectPolicy
session.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Connect to the device using username and password
session.connect(ip, username = username, password = password)
#Start an interactive shell session on the router
connection = session.invoke_shell()
#Setting terminal length for entire output - disable pagination
connection.send("terminal length 0n")
time.sleep(1)
#Entering global config mode
connection.send("n")
connection.send("configure terminaln")
20. Page 20 of 185
20 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
time.sleep(1)
#Open user selected file for reading
selected_cmd_file = open(cmd_file, 'r')
#Starting from the beginning of the file
selected_cmd_file.seek(0)
#Writing each line in the file to the device
for each_line in selected_cmd_file.readlines():
connection.send(each_line + 'n')
time.sleep(2)
#Closing the user file
selected_user_file.close()
#Closing the command file
selected_cmd_file.close()
#Checking command output for IOS syntax errors
router_output = connection.recv(65535)
if re.search(r"% Invalid input detected at", router_output):
print "* There was at least one IOS syntax error on device %s"
% ip
else:
print "nDONE for device %s" % ip
#Test for reading command output
#print router_output + "n"
#Closing the connection
session.close()
except paramiko.AuthenticationException:
print "* Invalid username or password. n* Please check the
username/password file or the device configuration!"
print "* Closing program...n"
############# Application #2 - Part #4 #############
#Creating threads
def create_threads():
threads = []
for ip in ip_list:
th = threading.Thread(target = open_ssh_conn, args = (ip,))
#args is a tuple with a single element
th.start()
threads.append(th)
for th in threads:
th.join()
21. Page 21 of 185
21 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Calling threads creation function
create_threads()
#End of program
22. Page 22 of 185
22 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
2.5.2. Telnet network configuration
#!/usr/bin/env python
import telnetlib
import threading
import os.path
import subprocess
import time
import sys
#Checking IP address validity
def ip_is_valid():
check = False
global ip_list
while True:
#Prompting user for input
ip_file = raw_input("Enter IP file name and extension: ")
#Changing exception message
try:
#Open user selected file for reading (IP addresses file)
selected_ip_file = open(ip_file, 'r')
#Starting from the beginning of the file
selected_ip_file.seek(0)
#Reading each line (IP address) in the file
ip_list = selected_ip_file.readlines()
#Closing the file
selected_ip_file.close()
except IOError:
print "nFile %s does not exist! Please check and try
again!n" % ip_file
#Checking octets
for ip in ip_list:
a = ip.split('.')
if (len(a) == 4) and (1 <= int(a[0]) <= 223) and (int(a[0]) !=
127) and (int(a[0]) != 169 or int(a[1]) != 254) and (0 <= int(a[1]) <= 255
and 0 <= int(a[2]) <= 255 and 0 <= int(a[3]) <= 255):
check = True
break
else:
23. Page 23 of 185
23 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
print 'n* There was an INVALID IP address! Please check
and try again!n'
check = False
continue
#Evaluating the 'check' flag
if check == False:
continue
elif check == True:
break
#Checking IP reachability
print "nChecking IP reachability...n"
check2 = False
while True:
for ip in ip_list:
ping_reply = subprocess.call(['ping', '-c', '3', '-w', '3', '-
q', '-n', ip])
if ping_reply == 0:
check2 = True
continue
elif ping_reply == 2:
print "nNo response from device %s." % ip
check2 = False
break
else:
print "nPing to the following device has FAILED:", ip
check2 = False
break
#Evaluating the 'check' flag
if check2 == False:
print "Please re-check IP address list or device.n"
ip_is_valid()
elif check2 == True:
print 'nAll devices are reachable. Waiting for command
file...n'
break
#Checking command file validity
def cmd_is_valid():
global cmd_file
while True:
cmd_file = raw_input("Enter command file name and extension: ")
#Changing exception message
24. Page 24 of 185
24 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
if os.path.isfile(cmd_file) == True:
print "nSending command(s) to device(s)...n"
break
else:
print "nFile %s does not exist! Please check and try
again!n" % cmd_file
continue
#Change exception message
try:
#Calling IP validity function
ip_is_valid()
except KeyboardInterrupt:
print "nnProgram aborted by user. Exiting...n"
sys.exit()
#Change exception message
try:
#Calling command file validity function
cmd_is_valid()
except KeyboardInterrupt:
print "nnProgram aborted by user. Exiting...n"
sys.exit()
#Open telnet connection to devices
def open_telnet_conn(ip):
#Change exception message
try:
#Define telnet parameters
username = 'teopy'
password = 'python'
#Specify the Telnet port (default is 23, anyway)
port = 23
#Specify the connection timeout in seconds for blocking
operations, like the connection attempt
connection_timeout = 5
#Specify a timeout in seconds. Read until the string is found or
until the timout has passed
reading_timeout = 5
#Logging into device
connection = telnetlib.Telnet(ip, port, connection_timeout)
#Waiting to be asked for an username
router_output = connection.read_until("Username:",
reading_timeout)
#Enter the username when asked and a "n" for Enter
25. Page 25 of 185
25 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
connection.write(username + "n")
#Waiting to be asked for a password
router_output = connection.read_until("Password:",
reading_timeout)
#Enter the password when asked and a "n" for Enter
connection.write(password + "n")
time.sleep(1)
#Setting terminal length for the entire output - disabling
pagination
connection.write("terminal length 0n")
time.sleep(1)
#Entering global config mode
connection.write("n")
connection.write("configure terminaln")
time.sleep(1)
#Open user selected file for reading
selected_cmd_file = open(cmd_file, 'r')
#Starting from the beginning of the file
selected_cmd_file.seek(0)
#Writing each line in the file to the device
for each_line in selected_cmd_file.readlines():
connection.write(each_line + 'n')
time.sleep(1)
#Closing the file
selected_cmd_file.close()
#Test for reading command output
#router_output = connection.read_very_eager()
#print router_output
#Closing the connection
connection.close()
except IOError:
print "Input parameter error! Please check username, password and
file name."
#Creating threads
def create_threads():
threads = []
for ip in ip_list:
th = threading.Thread(target = open_telnet_conn, args = (ip,))
#args is a tuple with a single element
th.start()
threads.append(th)
26. Page 26 of 185
26 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
for th in threads:
th.join()
#Calling threads creation function
create_threads()
#End of program
31. Page 31 of 185
31 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
import subprocess
import logging
import random
import sys
#This will suppress all messages that have a lower level of seriousness
than error messages, while running or loading Scapy
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
logging.getLogger("scapy.interactive").setLevel(logging.ERROR)
logging.getLogger("scapy.loading").setLevel(logging.ERROR)
try:
from scapy.all import *
except ImportError:
print "Scapy package for Python is not installed on your system."
print "Get it from https://pypi.python.org/pypi/scapy and try again."
sys.exit()
#To see a list of what commands Scapy has available, run the lsc()
function.
#Run the ls() command to see ALL the supported protocols.
#Run the ls(protocol) command to see the fields and default values for any
protocol.
#See packet layers with the .summary() function.
#See packet contents with the .show() function.
#Dig into a specific packet layer using a list index:
pkts[3][2].summary()...
#...the first index chooses the packet out of the pkts list, the second
index chooses the layer for that specific packet.
#Using the .command() packet method will return a string of the command
necessary to recreate that sniffed packet.
print "n! Make sure to run this program as ROOT !n"
#Setting network interface in promiscuous mode
net_iface = raw_input("Enter the interface to the target network: ")
subprocess.call(["ifconfig", net_iface, "promisc"], stdout=None,
stderr=None, shell=False)
print "nInterface %s was set to PROMISC mode." % net_iface
32. Page 32 of 185
32 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Scapy normally makes sure that replies come from the same IP address the
stimulus was sent to.
#But our DHCP packet is sent to the IP broadcast address (255.255.255.255)
and any answer packet will have the IP address of the replying DHCP server
as its source IP address (e.g. 192.168.2.101).
#Because these IP addresses don't match, we have to disable Scapy's check
with conf.checkIPaddr = False before sending the stimulus.
#Source:
https://bitbucket.org/pbi/test/wiki/doc/IdentifyingRogueDHCPServers
conf.checkIPaddr = False
############# Application #3 - Part #2 #############
################## DHCP SEQUENCE #################
all_given_leases = []
server_id = []
client_mac = []
#Generate entire DHCP sequence
def generate_dhcp_seq():
global all_given_leases
#Defining some DHCP parameters
x_id = random.randrange(1, 1000000)
hw = "00:00:5e" + str(RandMAC())[8:]
hw_str = mac2str(hw)
#print hw
#Assigning the .command() output of a captured DHCP DISCOVER packet to
a variable
dhcp_dis_pkt = Ether(dst="ff:ff:ff:ff:ff:ff",
src=hw)/IP(src="0.0.0.0",dst="255.255.255.255") /
UDP(sport=68,dport=67)/BOOTP(op=1, xid=x_id,
chaddr=hw_str)/DHCP(options=[("message-type","discover"),("end")])
#Sending the DISCOVER packet and catching the OFFER reply
#Generates two lists (answ and unansw). answd is a list containg a
tuple: the first element is the DISCOVER packet, the second is the OFFER
packet
answd, unanswd = srp(dhcp_dis_pkt, iface=pkt_inf, timeout = 2.5,
verbose=0)
#print answd
#print unanswd
#print answd.summary()
#print unanswd.summary()
#print answd[0][1][BOOTP].yiaddr
#The IP offered by the DHCP server to the client is extracted from the
received answer
offered_ip = answd[0][1][BOOTP].yiaddr
#print offered_ip
33. Page 33 of 185
33 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Assigning the .command() output of a captured DHCP REQUEST packet to
a variable
dhcp_req_pkt = Ether(dst="ff:ff:ff:ff:ff:ff",
src=hw)/IP(src="0.0.0.0",dst="255.255.255.255") /
UDP(sport=68,dport=67)/BOOTP(op=1, xid=x_id,
chaddr=hw_str)/DHCP(options=[("message-type","request"),("requested_addr",
offered_ip),("end")])
#Sending the REQUEST for the offered IP address
#Capturing the ACK from the server
answr, unanswr = srp(dhcp_req_pkt, iface=pkt_inf, timeout = 2.5,
verbose=0)
#print answr
#print unanswr
#print answr[0][1][IP].src
#print answr[0][1][BOOTP].yiaddr
#The IP offered by the DHCP server to the client is extracted from the
received answer
offered_ip_ack = answr[0][1][BOOTP].yiaddr
#DHCP Server IP/ID
server_ip = answr[0][1][IP].src
#print server_ip
#Adding each leased IP to the list of leases
all_given_leases.append(offered_ip_ack)
#Adding the server IP to a list
server_id.append(server_ip)
client_mac.append(hw)
return all_given_leases, server_id, client_mac
############# Application #3 - Part #3 #############
################## DHCP RELEASE #################
def generate_dhcp_release(ip, hw, server):
#Defining DHCP Transaction ID
x_id = random.randrange(1, 1000000)
hw_str = mac2str(hw)
#Creating the RELEASE packet
dhcp_rls_pkt = IP(src=ip,dst=server) /
UDP(sport=68,dport=67)/BOOTP(chaddr=hw_str, ciaddr=ip,
xid=x_id)/DHCP(options=[("message-type","release"),("server_id",
server),("end")])
34. Page 34 of 185
34 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Sending the RELEASE packet
send(dhcp_rls_pkt, verbose=0)
############# Application #3 - Part #4 #############
################## USER MENU #################
try:
#Enter option for the first screen
while True:
print "nUse this tool to:ns - Simulate DHCP Clientsnr -
Simulate DHCP Releasene - Exit programn"
user_option_sim = raw_input("Enter your choice: ")
if user_option_sim == "s":
print "nObtained leases will be exported to
'DHCP_Leases.txt'!"
pkt_no = raw_input("nNumber of DHCP clients to simulate: ")
pkt_inf = raw_input("Interface on which to send packets: ")
print "nWaiting for clients to obtain IP addresses...n"
try:
#Calling the function for the required number of times
(pkt_no)
for iterate in range(0, int(pkt_no)):
all_leased_ips = generate_dhcp_seq()[0]
#print all_leased_ips
except IndexError:
print "No DHCP Server detected or connection is broken."
print "Check your network settings and try again.n"
sys.exit()
#List of all leased IPs
dhcp_leases = open("DHCP_Leases.txt", "w")
#print all_leased_ips
#print server_id
#print client_mac
#Print each leased IP to the file
for index, each_ip in enumerate(all_leased_ips):
print >>dhcp_leases, each_ip + "," + server_id[index] +
"," + client_mac[index]
dhcp_leases.close()
35. Page 35 of 185
35 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
continue
elif user_option_sim == "r":
while True:
print "ns - Release a single addressna - Release all
addressesne - Exit to the previous screenn"
user_option_release = raw_input("Enter your choice: ")
if user_option_release == "s":
print "n"
user_option_address = raw_input("Enter IP address to
release: ")
#print all_leased_ips
#print server_id
#print client_mac
try:
#Check if required IP is in the list and run the
release function for it
if user_option_address in all_leased_ips:
index =
all_leased_ips.index(user_option_address)
generate_dhcp_release(user_option_address,
client_mac[index], server_id[index])
print "nSending RELEASE packet...n"
else:
print "IP Address not in list.n"
continue
except (NameError, IndexError):
print "nSimulating DHCP RELEASES cannot be done
separately, without prior DHCP Client simulation."
print "Restart the program and simulate DHCP
Clients and RELEASES in the same program session.n"
sys.exit()
elif user_option_release == "a":
#print all_leased_ips
#print server_id
#print client_mac
try:
#Check if required IP is in the list and run the
release function for it
for user_option_address in all_leased_ips:
36. Page 36 of 185
36 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
index =
all_leased_ips.index(user_option_address)
generate_dhcp_release(user_option_address,
client_mac[index], server_id[index])
except (NameError, IndexError):
print "nSimulating DHCP RELEASES cannot be done
separately, without prior DHCP Client simulation."
print "Restart the program and simulate DHCP
Clients and RELEASES in the same program session.n"
sys.exit()
print "nThe RELEASE packets have been sent.n"
#Erasing all leases from the file
open("DHCP_Leases.txt", "w").close()
print "File 'DHCP_Leases.txt' has been cleared."
continue
else:
break
else:
print "Exiting... See ya...nn"
sys.exit()
except KeyboardInterrupt:
print "nnProgram aborted by user. Exiting...n"
sys.exit()
#End of program
38. Page 38 of 185
38 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
############# Application #4 - Part #1 #############
#Configure the permissions on the script first! 'chmod 755 script.py"
#Make sure to have SSHv2 enabled and RSA 1024 bit key generated on every
device!
import MySQLdb as mdb
import paramiko
import threading
import os.path
import subprocess
import datetime
import time
import sys
import re
#Module for output coloring
from colorama import init, deinit, Fore, Style
# Procedure for configuring Linux scheduler:
# root@kali:/# crontab -l view scheduled tasks
# root@kali:/# crontab -e edit scheduler
# Add the following line to run the script every 5 minutes, every hour,
every day, every month:
# */5 * * * * /path_to_file/NetMon_SQL_v1.py /path_to_file/NETWORK_IP
/path_to_file/SSH_USERPASS.txt /path_to_file/SQL_CONN.txt
# For more info about configuring scheduler:
http://kvz.io/blog/2007/07/29/schedule-tasks-on-linux-using-crontab/
# Before scheduling this task, run the script in the console to check for
errors:
# Go to the folder containing the script and all files, using cd
/netmon_folder_path
# Enter this command: python NetMon_SQL_v1.py NETWORK_IP.txt
SSH_USERPASS.txt SQL_CONN.txt
# Check the console output and SQL_Error_Log.txt file for any errors.
# Running the script is recommended at intervals of at least 5 minutes.
#Initialize colorama
init()
#Checking number of arguments passed into the script
if len(sys.argv) == 4:
ip_file = sys.argv[1]
user_file = sys.argv[2]
sql_file = sys.argv[3]
print Fore.BLUE + Style.BRIGHT + "nn* The script will be executed
using files:n"
print Fore.BLUE + "Cisco network IP file is: " + Fore.YELLOW + "%s" %
ip_file
39. Page 39 of 185
39 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
print Fore.BLUE + "SSHv2 connection file is: " + Fore.YELLOW + "%s" %
user_file
print Fore.BLUE + "MySQL connection file is: " + Fore.YELLOW + "%s" %
sql_file
print Fore.BLUE + Style.BRIGHT + "n"
else:
print Fore.RED + Style.BRIGHT + "nIncorrect number of arguments
(files) passed into the script."
print Fore.RED + "Please try again.n"
sys.exit()
#Checking IP address file and content validity
def ip_is_valid():
check = False
global ip_list
while True:
#Changing exception message
try:
#Open user selected file for reading (IP addresses file)
selected_ip_file = open(ip_file, 'r')
#Starting from the beginning of the file
selected_ip_file.seek(0)
#Reading each line (IP address) in the file
ip_list = selected_ip_file.readlines()
#Closing the file
selected_ip_file.close()
except IOError:
print Fore.RED + "n* File %s does not exist! Please check and
try again!n" % ip_file
sys.exit()
#Checking octets
for ip in ip_list:
a = ip.split('.')
if (len(a) == 4) and (1 <= int(a[0]) <= 223) and (int(a[0]) !=
127) and (int(a[0]) != 169 or int(a[1]) != 254) and (0 <= int(a[1]) <= 255
and 0 <= int(a[2]) <= 255 and 0 <= int(a[3]) <= 255):
check = True
break
else:
print 'n* There was an INVALID IP address! Please check
and try again!n'
check = False
continue
40. Page 40 of 185
40 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Evaluating the 'check' flag
if check == False:
sys.exit()
elif check == True:
break
#Checking IP reachability
print "* Checking IP reachability... Please wait...n"
check2 = False
while True:
for ip in ip_list:
ping_reply = subprocess.call(['ping', '-c', '3', '-w', '3', '-
q', '-n', ip], stdout = subprocess.PIPE)
if ping_reply == 0:
check2 = True
continue
elif ping_reply == 2:
print Fore.RED + "n* No response from device %s." % ip
check2 = False
break
else:
print Fore.RED + "n* Ping to the following device has
FAILED:", ip
check2 = False
break
#Evaluating the 'check' flag
if check2 == False:
print Fore.RED + "* Please re-check IP address list or
device.n"
sys.exit()
elif check2 == True:
print 'n* All devices are reachable. Checking SSHv2
connection file...n'
break
#Checking user file validity
def user_is_valid():
global user_file
while True:
#Changing output messages
if os.path.isfile(user_file) == True:
print "n* SSHv2 connection file has been validated. Checking
MySQL connection file...n"
break
41. Page 41 of 185
41 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
else:
print Fore.RED + "n* File %s does not exist! Please check and
try again!n" % user_file
sys.exit()
#Checking SQL connection command file validity
def sql_is_valid():
global sql_file
while True:
#Changing output messages
if os.path.isfile(sql_file) == True:
print "n* MySQL connection file has been validated...n"
print "n* Any MySQL errors will be logged to: " + Fore.YELLOW
+ "SQL_Error_Log.txtn" + Fore.BLUE
print "n* Reading network data and writing to MySQL...n"
break
else:
print Fore.RED + "n* File %s does not exist! Please check and
try again!n" % sql_file
sys.exit()
#Change exception message
try:
#Calling IP validity function
ip_is_valid()
except KeyboardInterrupt:
print Fore.RED + "nn* Program aborted by user. Exiting...n"
sys.exit()
#Change exception message
try:
#Calling user file validity function
user_is_valid()
except KeyboardInterrupt:
print Fore.RED + "nn* Program aborted by user. Exiting...n"
sys.exit()
#Change exception message
try:
#Calling MySQL file validity function
sql_is_valid()
except KeyboardInterrupt:
print Fore.RED + "nn* Program aborted by user. Exiting...n"
sys.exit()
############# Application #4 - Part #2 #############
check_sql = True
def sql_connection(command, values):
42. Page 42 of 185
42 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
global check_sql
#Define SQL connection parameters
selected_sql_file = open(sql_file, 'r')
#Starting from the beginning of the file
selected_sql_file.seek(0)
sql_host = selected_sql_file.readlines()[0].split(',')[0]
#Starting from the beginning of the file
selected_sql_file.seek(0)
sql_username = selected_sql_file.readlines()[0].split(',')[1]
#Starting from the beginning of the file
selected_sql_file.seek(0)
sql_password = selected_sql_file.readlines()[0].split(',')[2]
#Starting from the beginning of the file
selected_sql_file.seek(0)
sql_database =
selected_sql_file.readlines()[0].split(',')[3].rstrip("n")
#Connecting and writing to database
try:
sql_conn = mdb.connect(sql_host, sql_username, sql_password,
sql_database)
cursor = sql_conn.cursor()
cursor.execute("USE NetMon")
cursor.execute(command, values)
#Commit changes
sql_conn.commit()
except mdb.Error, e:
sql_log_file = open("SQL_Error_Log.txt", "a")
#Print any SQL errors to the error log file
print >>sql_log_file, str(datetime.datetime.now()) + ": Error %d:
%s" % (e.args[0],e.args[1])
#Closing sql log file:
sql_log_file.close()
#Setting check_sql flag to False if any sql error occurs
check_sql = False
#Closing the sql file
43. Page 43 of 185
43 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
selected_sql_file.close()
#Initialize the necessary lists and dictionaries
cpu_values = []
io_mem_values = []
proc_mem_values = []
upint_values = []
top3_cpu = {}
top3_io_mem = {}
top3_proc_mem = {}
top3_upint = {}
#Open SSHv2 connection to devices
def open_ssh_conn(ip):
global check_sql
#Change exception message
try:
#Define SSH parameters
selected_user_file = open(user_file, 'r')
#Starting from the beginning of the file
selected_user_file.seek(0)
#Reading the username from the file
username = selected_user_file.readlines()[0].split(',')[0]
#Starting from the beginning of the file
selected_user_file.seek(0)
#Reading the password from the file
password =
selected_user_file.readlines()[0].split(',')[1].rstrip("n")
#Logging into device
session = paramiko.SSHClient()
#For testing purposes, this allows auto-accepting unknown host
keys
#Do not use in production! The default would be RejectPolicy
session.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#Connect to the device using username and password
session.connect(ip, username = username, password = password)
#Start an interactive shell session on the router
connection = session.invoke_shell()
#Setting terminal length for entire output - disable pagination
connection.send("terminal length 0n")
time.sleep(1)
44. Page 44 of 185
44 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Entering global config mode
#connection.send("n")
#connection.send("configure terminaln")
#time.sleep(1)
#Reading commands from within the script
#Using the "" line continuation character for better readability
of the commands to be sent
selected_cisco_commands = '''show version | include (,
Version|uptime is|bytes of memory|Hz)&
show inventory&
show interfaces | include bia&
show processes cpu | include CPU
utilization&
show memory statistics&
show ip int brief | include
(Ethernet|Serial)&
show cdp neighbors detail | include
Device ID&
show ip protocols | include Routing
Protocol'''
#Splitting commands by the "&" character
command_list = selected_cisco_commands.split("&")
#Writing each line in the command string to the device
for each_line in command_list:
connection.send(each_line + 'n')
time.sleep(3)
#Closing the user file
selected_user_file.close()
#Checking command output for IOS syntax errors
output = connection.recv(65535)
if re.search(r"% Invalid input detected at", output):
print Fore.RED + "* There was at least one IOS syntax error on
device %s" % ip
else:
print Fore.GREEN + "* All parameters were extracted from
device %s" % ip,
#Test for reading command output
#print output + "n"
############# Application #4 - Part #3 #############
#Extracting device parameters
#...starting with the ones destined to the NetworkDevices table in
MySQL
dev_hostname = re.search(r"(.+) uptime is", output)
45. Page 45 of 185
45 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
hostname = dev_hostname.group(1)
#print hostname
dev_mac = re.findall(r"(bia (.+?))", output)
#print dev_mac
mac = dev_mac[0]
#print mac
dev_vendor = re.search(r"(.+?) (.+) bytes of memory", output)
vendor = dev_vendor.group(1)
#print vendor
dev_model = re.search(r"(.+?) (.+?) (.+) bytes of memory", output)
model = dev_model.group(2)
#print model
dev_image_name = re.search(r" ((.+)), Version", output)
image_name = dev_image_name.group(1)
#print image_name
dev_os = re.search(r"), Version (.+),", output)
os = dev_os.group(1)
#print os
serial_no = ""
if len(re.findall(r"(.+), SN: (.+?)rn", output)) == 0:
serial_no = "unknown"
else:
serial_no = re.findall(r"(.+), SN: (.+?)rn",
output)[0][1].strip()
#print serial_no
dev_uptime = re.search(r" uptime is (.+)n", output)
uptime = dev_uptime.group(1)
uptime_value_list = uptime.split(', ')
#Getting the device uptime in seconds
y_sec = 0
w_sec = 0
d_sec = 0
h_sec = 0
m_sec = 0
for j in uptime_value_list:
if 'year' in j:
y_sec = int(j.split(' ')[0]) * 31449600
elif 'week' in j:
w_sec = int(j.split(' ')[0]) * 604800
elif 'day' in j:
d_sec = int(j.split(' ')[0]) * 86400
47. Page 47 of 185
47 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
############# Application #4 - Part #4 #############
### CPU ###
dev_cpu_util_per5min = re.search(r"CPU utilization for five
seconds: (.+) five minutes: (.+?)%", output)
cpu_util_per5min = dev_cpu_util_per5min.group(2)
#print cpu_util_per5min
#Append CPU value for each device to the cpu_values list
cpu_values.append(int(cpu_util_per5min))
#Get top 3 CPU devices
top3_cpu[hostname] = cpu_util_per5min
### Processor Memory ###
dev_used_proc_mem = re.search(r"Processor(.+)n ", output)
dev_used_proc_mem = dev_used_proc_mem.group(1)
#print dev_used_proc_mem
total_proc_mem = dev_used_proc_mem.split(' ')[2].strip()
used_proc_mem = dev_used_proc_mem.split(' ')[3].strip()
#print total_proc_mem
#print used_proc_mem
#Get percentage of used proc mem
proc_mem_percent = format(int(used_proc_mem) * 100 /
float(total_proc_mem), ".2f")
#print proc_mem_percent
#Append used proc memory values for each device to the mem_values
list
proc_mem_values.append(float(proc_mem_percent))
#Get top 3 proc memory devices
top3_proc_mem[hostname] = proc_mem_percent
### I/O Memory ###
dev_used_io_mem = re.search(r" I/O(.+)n", output)
dev_used_io_mem = dev_used_io_mem.group(1)
#print dev_used_io_mem
total_io_mem = dev_used_io_mem.split(' ')[2].strip()
used_io_mem = dev_used_io_mem.split(' ')[3].strip()
#print total_io_mem
#print used_io_mem
#Get percentage of used proc mem
io_mem_percent = format(int(used_io_mem) * 100 /
float(total_io_mem), ".2f")
#print io_mem_percent
48. Page 48 of 185
48 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Append used I/O memory values for each device to the mem_values
list
io_mem_values.append(float(io_mem_percent))
#Get top 3 I/O memory devices
top3_io_mem[hostname] = io_mem_percent
### UP Interfaces ###
dev_total_int = re.findall(r"([A-Za-z]*)Ethernet([0-
9]*)(.+)YES(.+)n", output)
total_int = len(dev_total_int)
#print total_int
dev_total_up_int = re.findall(r"(.+)Ethernet([0-9]*)/([0-
9]*)[s]*(.+)up[s]*up", output)
total_up_int = len(dev_total_up_int)
#print total_up_int
#Get percentage of Eth UP interfaces out of the total number of
Eth interfaces
intf_percent = format(total_up_int * 100 / float(total_int),
".2f")
#print intf_percent
#Append percentage of UP interfaces for each device to the
upint_values list
upint_values.append(float(intf_percent))
#Get top 3 UP Eth interfaces density devices
top3_upint[hostname] = intf_percent
#Insert/Update if exists all network devices data into the MySQL
database table NetworkDevices. Calling sql_connection function
sql_connection("REPLACE INTO
NetworkDevices(Hostname,MACAddr,Vendor,Model,Image,IOSVersion,SerialNo,Upt
ime,CPUModel,CPUSpeed,SerialIntfNo,CiscoNeighbors,IntRoutingPro,ExtRouting
Pro) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
(hostname, mac, vendor, model, image_name, os, serial_no,
total_uptime_sec, cpu_model, cpu_speed, serial_int, all_cdp_neighbors,
internal_pro, external_pro))
#Closing the SSH connection
session.close()
except paramiko.AuthenticationException:
print Fore.RED + "* Invalid SSH username or password. n* Please
check the username/password file or the device configuration!n"
check_sql = False
#Creating threads
def create_threads():
threads = []
49. Page 49 of 185
49 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
for ip in ip_list:
th = threading.Thread(target = open_ssh_conn, args = (ip,))
#args is a tuple with a single element
th.start()
threads.append(th)
for th in threads:
th.join()
#Calling threads creation function
create_threads()
############# Application #4 - Part #5 #############
#Poll date and time are based on the system clock
poll_timestamp = datetime.datetime.now()
#print poll_timestamp
###Testing code###
#print cpu_values
#print proc_mem_values
#print io_mem_values
#print upint_values
#print top3_cpu
#print top3_proc_mem
#print top3_io_mem
#print top3_upint
###
#Defining a function to get top 3 devices in CPU/mem/intf usage
def top3(each_dict):
global top3_list
top3 = []
for host, usage in sorted(each_dict.items(), key = lambda x: x[1],
reverse = True)[:3]:
top3.append(host)
top3_list = ",".join(top3)
#print top3_list
#CPU average function
def cpu_average():
try:
cpu = sum(cpu_values) / float(len(cpu_values))
#Calling the top3 function for the CPU dictionary
top3(top3_cpu)
#Write values to the MySQL database CPUUtilization table
sql_connection("INSERT INTO
CPUUtilization(NetworkCPUUtilizationPercent,Top3CPUDevices,PollTimestamp)
VALUES(%s, %s, %s)", (cpu, top3_list, poll_timestamp))
50. Page 50 of 185
50 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
except ZeroDivisionError:
print "* There was an error while computing a network parameter.
No record has been added to MySQL. Please retry."
cpu_average()
#Used proc memory average function
def mem_proc_average():
try:
mem_proc = sum(proc_mem_values) / float(len(proc_mem_values))
#Calling the top3 function for the mem proc dictionary
top3(top3_proc_mem)
#Write values to the MySQL database ProcMemUtilization table
sql_connection("INSERT INTO
ProcMemUtilization(NetworkProcMemUtilizationPercent,Top3ProcMemDevices,Pol
lTimestamp) VALUES(%s, %s, %s)", (mem_proc, top3_list, poll_timestamp))
except ZeroDivisionError:
print "* There was an error while computing a network parameter.
No record has been added to MySQL. Please retry."
mem_proc_average()
#Used I/O memory average function
def mem_io_average():
try:
mem_io = sum(io_mem_values) / float(len(io_mem_values))
#Calling the top3 function for the mem I/O dictionary
top3(top3_io_mem)
#Write values to the MySQL database IOMemUtilization table
sql_connection("INSERT INTO
IOMemUtilization(NetworkIOMemUtilizationPercent,Top3IOMemDevices,PollTimes
tamp) VALUES(%s, %s, %s)", (mem_io, top3_list, poll_timestamp))
except ZeroDivisionError:
print "* There was an error while computing a network parameter.
No record has been added to MySQL. Please retry."
mem_io_average()
#Total UP Eth interfaces function
def upint_total():
try:
upint = sum(upint_values) / float(len(upint_values))
#Calling the top3 function for the UP intf dictionary
top3(top3_upint)
#Write values to the MySQL database UPEthInterfaces table
51. Page 51 of 185
51 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
sql_connection("INSERT INTO
UPEthInterfaces(NetworkUPEthIntfPercent,Top3UPEthIntf,PollTimestamp)
VALUES(%s, %s, %s)", (upint, top3_list, poll_timestamp))
except ZeroDivisionError:
print "* There was an error while computing a network parameter.
No record has been added to MySQL. Please retry."
upint_total()
#print check_sql
if check_sql == True:
print "n* All parameters were successfully exported to MySQL."
else:
print Fore.RED + "n* There was a problem exporting data to MySQL.n*
Check the files, database and SQL_Error_Log.txt.n"
#De-initialize colorama
deinit()
#End of program
52. Page 52 of 185
52 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
2.8. Application #5 - OSPF network discovery via SNMP
(full code, reference: Section 17. Application #5 - OSPF network discovery via
SNMP)
Logical flow diagram
53. Page 53 of 185
53 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
############# Application #5 - Part #1 #############
'''
Make the following configuration on each router in the network:
configure terminal
snmp-server community public RO
'''
# Open a regular Linux terminal
# Go to the folder containing the script, using cd /folder_path
# Enter "sudo python OSPF_SNMP.py" and the password for the account
# You may also need to configure the permissions on the script first!
"chmod 755 script.py"
# Check the console output for any errors
#Necessary Python packages (they are already installed on the Debian VM)
#https://pypi.python.org/pypi/setuptools
#https://pypi.python.org/pypi/networkx
#https://pypi.python.org/pypi/matplotlib
#https://pypi.python.org/pypi/pysnmp
#https://pypi.python.org/pypi/colorama
import pprint
import subprocess
import binascii
import sys
try:
import matplotlib.pyplot as matp
except ImportError:
print Fore.RED + Style.BRIGHT + "n* Module matplotlib needs to be
installed on your system."
print "* Download it from: https://pypi.python.org/pypi/matplotlibn"
+ Fore.WHITE + Style.BRIGHT
sys.exit()
try:
import networkx as nx
except ImportError:
print Fore.RED + Style.BRIGHT + "n* Module networkx needs to be
installed on your system."
print "* Download it from: https://pypi.python.org/pypi/networkx"
print "* You should also install decorator:
https://pypi.python.org/pypi/decoratorn" + Fore.WHITE + Style.BRIGHT
sys.exit()
try:
#Module for output coloring
from colorama import init, deinit, Fore, Style
except ImportError:
54. Page 54 of 185
54 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
print Fore.RED + Style.BRIGHT + "n* Module colorama needs to be
installed on your system."
print "* Download it from: https://pypi.python.org/pypi/coloraman" +
Fore.WHITE + Style.BRIGHT
sys.exit()
try:
#Module for SNMP
from pysnmp.entity.rfc3413.oneliner import cmdgen
except ImportError:
print Fore.RED + Style.BRIGHT + "n* Module pysnmp needs to be
installed on your system."
print "* Download it from: https://pypi.python.org/pypi/pysnmpn" +
Fore.WHITE + Style.BRIGHT
sys.exit()
#Initialize colorama
init()
#Prompting user for input
try:
print Style.BRIGHT + "n######################## OSPF DISCOVERY TOOL
########################"
print "Make sure to connect to a device already running OSPF in the
network!"
print "SNMP community string should be the same on all devices running
OSPF!n"
ip = raw_input(Fore.BLUE + Style.BRIGHT + "n* Please enter root
device IP: ")
comm = raw_input("n* Please enter community string: ")
except KeyboardInterrupt:
print Fore.RED + Style.BRIGHT + "nn* Program aborted by user.
Exiting...n"
sys.exit()
############# Application #5 - Part #2 #############
#Checking IP address validity
def ip_is_valid():
while True:
#Checking octets
a = ip.split('.')
if (len(a) == 4) and (1 <= int(a[0]) <= 223) and (int(a[0]) !=
127) and (int(a[0]) != 169 or int(a[1]) != 254) and (0 <= int(a[1]) <= 255
and 0 <= int(a[2]) <= 255 and 0 <= int(a[3]) <= 255):
break
55. Page 55 of 185
55 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
else:
print 'n* There was an INVALID IP address! Please check and
try again!n'
sys.exit()
#Checking IP reachability
print Fore.GREEN + Style.BRIGHT + "n* Valid IP address. Checking IP
reachability...n"
while True:
ping_reply = subprocess.call(['ping', '-c', '3', '-w', '3', '-q',
'-n', ip], stdout = subprocess.PIPE)
if ping_reply == 0:
print Fore.GREEN + Style.BRIGHT + "* Device is reachable.
Performing SNMP extraction...n"
print Fore.GREEN + Style.BRIGHT + "* This may take a few
moments...n"
break
elif ping_reply == 2:
print Fore.RED + Style.BRIGHT + "n* No response from device
%s." % ip
sys.exit()
else:
print Fore.RED + Style.BRIGHT + "n* Ping to the following
device has FAILED:", ip
print "n"
sys.exit()
#Change exception message
try:
#Calling IP validity function
ip_is_valid()
except KeyboardInterrupt:
print Fore.RED + Style.BRIGHT + "nn* Program aborted by user.
Exiting...n"
sys.exit()
ospf = []
#SNMP function
def snmp_get(ip):
nbridlist = []
nbriplist = []
ospf_devices = {}
#Creating command generator object
cmdGen = cmdgen.CommandGenerator()
56. Page 56 of 185
56 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Performing SNMP GETNEXT operations on the OSPF OIDs
#The basic syntax of nextCmd: nextCmd(authData, transportTarget,
*varNames)
#The nextCmd method returns a tuple of (errorIndication, errorStatus,
errorIndex, varBindTable)
errorIndication, errorStatus, errorIndex, varBindNbrTable =
cmdGen.nextCmd(cmdgen.CommunityData(comm),
cmdgen.UdpTransportTarget((ip, 161)),
'1.3.6.1.2.1.14.10.1.3')
#print
cmdGen.nextCmd(cmdgen.CommunityData(comm),cmdgen.UdpTransportTarget((ip,
161)),'1.3.6.1.2.1.14.10.1.3')
#print varBindNbrTable
errorIndication, errorStatus, errorIndex, varBindNbrIpTable =
cmdGen.nextCmd(cmdgen.CommunityData(comm),
cmdgen.UdpTransportTarget((ip, 161)),
'1.3.6.1.2.1.14.10.1.1')
#print varBindNbrIpTable
errorIndication, errorStatus, errorIndex, varBindHostTable =
cmdGen.nextCmd(cmdgen.CommunityData(comm),
cmdgen.UdpTransportTarget((ip, 161)),
'1.3.6.1.4.1.9.2.1.3')
#print varBindHostTable
errorIndication, errorStatus, errorIndex, varBindHostIdTable =
cmdGen.nextCmd(cmdgen.CommunityData(comm),
cmdgen.UdpTransportTarget((ip, 161)),
'1.3.6.1.2.1.14.1.1')
#print varBindHostIdTable
#Extract and print out the results
for varBindNbrTableRow in varBindNbrTable:
for oid, nbrid in varBindNbrTableRow:
hex_string = binascii.hexlify(str(nbrid))
#print hex_string
octets = [hex_string[i:i+2] for i in range(0, len(hex_string),
2)]
#print octets
ip = [int(i, 16) for i in octets]
57. Page 57 of 185
57 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#print ip
nbr_r_id = '.'.join(str(i) for i in ip)
#print nbr_r_id
nbridlist.append(nbr_r_id)
#print('%s = %s' % (oid, nbr_r_id))
for varBindNbrIpTableRow in varBindNbrIpTable:
for oid, nbrip in varBindNbrIpTableRow:
hex_string = binascii.hexlify(str(nbrip))
octets = [hex_string[i:i+2] for i in range(0, len(hex_string),
2)]
ip = [int(i, 16) for i in octets]
nbr_ip = '.'.join(str(i) for i in ip)
nbriplist.append(nbr_ip)
#print('%s = %s' % (oid, nbr_ip))
for varBindHostTableRow in varBindHostTable:
for oid, host in varBindHostTableRow:
ospf_host = str(host)
#print('%s = %s' % (oid, host))
for varBindHostIdTableRow in varBindHostIdTable:
for oid, hostid in varBindHostIdTableRow:
hex_string = binascii.hexlify(str(hostid))
octets = [hex_string[i:i+2] for i in range(0, len(hex_string),
2)]
ip = [int(i, 16) for i in octets]
ospf_host_id = '.'.join(str(i) for i in ip)
#print('%s = %s' % (oid, hostid))
#Adding OSPF data by device in the ospf_device dictionary
ospf_devices["Host"] = ospf_host
ospf_devices["HostId"] = ospf_host_id
ospf_devices["NbrRtrId"] = nbridlist
ospf_devices["NbrRtrIp"] = nbriplist
ospf.append(ospf_devices)
return ospf
#Calling the function for the user specified IP address
ospf = snmp_get(ip)
#pprint.pprint(ospf)
############# Application #5 - Part #3 #############
def find_unqueried_neighbors():
#Host OSPF Router IDs
all_host_ids = []
for n in range(0, len(ospf)):
hid = ospf[n]["HostId"]
all_host_ids.append(hid)
58. Page 58 of 185
58 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#print "HID"
#print all_host_ids
#print "n"
#Neighbor OSPF Router IDs
all_nbr_ids = []
for n in range(0, len(ospf)):
for each_nid in ospf[n]["NbrRtrId"]:
if each_nid == "0.0.0.0":
pass
else:
all_nbr_ids.append(each_nid)
#print "NBR"
#print all_nbr_ids
#print list(set(all_nbr_ids))
#print "n"
#Determining which neighbors were not queried and adding them to a
list
all_outsiders = []
for p in all_nbr_ids:
if p not in all_host_ids:
all_outsiders.append(p)
#print "OUT"
#print all_outsiders
#print "n"
#Running the snmp_get() function for each unqueried neighbor
for q in all_outsiders:
for r in range(0, len(ospf)):
for index, s in enumerate(ospf[r]["NbrRtrId"]):
#print index, s
if q == s:
new_ip = ospf[r]["NbrRtrIp"][index]
snmp_get(new_ip)
else:
pass
return all_host_ids, all_nbr_ids, ospf
############# Application #5 - Part #4 #############
#Calling the function above
while True:
59. Page 59 of 185
59 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
if (len(list(set(find_unqueried_neighbors()[0]))) ==
len(list(set(find_unqueried_neighbors()[1])))):
break
final_devices_list = find_unqueried_neighbors()[2]
#pprint.pprint(final_devices_list)
#Creating list of neighborships
neighborship_dict = {}
for each_dictionary in final_devices_list:
for index, each_neighbor in enumerate(each_dictionary["NbrRtrId"]):
each_tuple = (each_dictionary["HostId"], each_neighbor)
neighborship_dict[each_tuple] = each_dictionary["NbrRtrIp"][index]
#pprint.pprint(neighborship_dict)
############# Application #5 - Part #5 #############
while True:
try:
#User defined actions
print Fore.BLUE + Style.BRIGHT + "* Please choose an action:nn1
- Display OSPF devices on the screenn2 - Export OSPF devices to CSV
filen3 - Generate OSPF network topologyne - Exit"
user_choice = raw_input("n* Enter your choice: ")
print "n"
#Defining actions
if user_choice == "1":
for each_dict in final_devices_list:
print "Hostname: " + Fore.YELLOW + Style.BRIGHT + "%s" %
each_dict["Host"] + Fore.BLUE + Style.BRIGHT
print "OSFP RID: " + Fore.YELLOW + Style.BRIGHT + "%s" %
each_dict["HostId"] + Fore.BLUE + Style.BRIGHT
print "OSPF Neighbors by ID: " + Fore.YELLOW +
Style.BRIGHT + "%s" % ', '.join(each_dict["NbrRtrId"]) + Fore.BLUE +
Style.BRIGHT
print "OSPF Neighbors by IP: " + Fore.YELLOW +
Style.BRIGHT + "%s" % ', '.join(each_dict["NbrRtrIp"]) + Fore.BLUE +
Style.BRIGHT
print "n"
continue
#Printing devices to CSV file
elif user_choice == "2":
print Fore.CYAN + Style.BRIGHT + "* Generating " + Fore.YELLOW
+ Style.BRIGHT + "OSPF_DEVICES" + Fore.CYAN + Style.BRIGHT + " file...n"
60. Page 60 of 185
60 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
print Fore.CYAN + Style.BRIGHT + "* Check the script folder.
Import the file into Excel for a better view of the devices.n"
csv_file = open("OSPF_DEVICES.txt", "w")
print >>csv_file, "Hostname" + ";" + "OSPFRouterID" + ";" +
"OSPFNeighborRouterID" + ";" + "OSPFNeighborIP"
for each_dict in final_devices_list:
print >>csv_file, each_dict["Host"] + ";" +
each_dict["HostId"] + ";" + ', '.join(each_dict["NbrRtrId"]) + ";" + ',
'.join(each_dict["NbrRtrIp"])
csv_file.close()
continue
############# Application #5 - Part #6 #############
#Generating OSPF network topology
elif user_choice == "3":
print Fore.CYAN + Style.BRIGHT + "* Generating OSPF network
topology...n" + Fore.BLUE + Style.BRIGHT
#Drawing the topology using the list of neighborships
G = nx.Graph()
G.add_edges_from(neighborship_dict.keys())
pos = nx.spring_layout(G, k = 0.1, iterations = 70)
nx.draw_networkx_labels(G, pos, font_size = 9, font_family =
"sans-serif", font_weight = "bold")
nx.draw_networkx_edges(G, pos, width = 4, alpha = 0.4,
edge_color = 'black')
nx.draw_networkx_edge_labels(G, pos, neighborship_dict,
label_pos = 0.3, font_size = 6)
nx.draw(G, pos, node_size = 700, with_labels = False)
matp.show()
continue
elif user_choice == "e":
print Fore.RED + Style.BRIGHT + "* Exiting... Bye!n"
sys.exit()
else:
print Fore.RED + Style.BRIGHT + "* Invalid option. Please
retry.n"
continue
except KeyboardInterrupt:
print Fore.RED + Style.BRIGHT + "nn* Program aborted by user.
Exiting...n"
sys.exit()
#De-initialize colorama
61. Page 61 of 185
61 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
deinit()
#End of program
62. Page 62 of 185
62 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
2.9. Application #6 - Basic network sniffer
(full code, reference: Section 18. Application #6 - Basic network sniffer)
This application is a basic network sniffer, which captures some predefined protocols and
saves info about each network packet in an external file.
As with the other applications in this course, the full code is available for download.
Based on what you have learned so far in the course, it’s your job now to study,
understand and test the code against a network device, as you’ve seen me doing with the
previous applications.
Feel free to alter the code in any way you want, add new protocols to be captured, more
data to be exported in the external file and so on. New functionality of any kind is welcome.
Just make sure to adapt your code to the contents of the packet in Scapy.
Also, please read the first 33 lines in the code carefully, as they are a good introduction
to the code that follows.
As you’ve probably guessed, I used Scapy to build this sniffer, because this tool allows
packet handling, decoding and analysis in a very intuitive way.
Also, pay special attention to the recommendations and settings that I made before
starting to build the user menu and so on. I am referring to these lines and the ones above
them:
net_iface = raw_input("* Enter the interface on which to run the sniffer (like 'eth1'):
")
subprocess.call(["ifconfig", net_iface, "promisc"], stdout=None, stderr=None,
shell=False)
Further more, please read the comments before every code block, as they are good
guidelines to what functionality is covered by that piece of code.
As you can see at line 72, the program asks the user what network interface is the capture
process going to be executed on. A good example is entering “eth1”.
net_iface = raw_input("* Enter the interface on which to run the sniffer (like 'eth1'):
")
Then, at line 80, the user is asked to enter the number of packets he wishes to be captured
by the sniffer:
63. Page 63 of 185
63 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
pkt_to_sniff = raw_input("* Enter the number of packets to capture (0 is infinity): ")
At line 92, the program requires the number of seconds to run the capture:
time_to_sniff = raw_input("* Enter the number of seconds to run the capture: ")
At line 103, the program asks the user for the protocol to filter the packets by:
proto_sniff = raw_input("* Enter the protocol to filter by (arp|bootp|icmp|0 is all): ")
Lines 115 and 116 are dedicated to choosing the file name and creating the file, by
opening it for writing (“w”):
file_name = raw_input("* Please give a name to the log file: ")
sniffer_log = open(file_name, "w")
At line 124, you can find the function that takes care of the parameter extraction from
each packet and logging the packet info to the file: def packet_log(pkt)
The program implements a counter for each packet, then records the source MAC
address and destination MAC address to the file, on a single row.
Finally, the sniffing process is initialized by the sniff() function in Scapy, at line 138,
passing the values collected from the user as arguments to this function.
pkt = sniff(iface=net_iface, count=int(pkt_to_sniff), timeout=int(time_to_sniff),
prn=packet_log)
Now, to test the program, first you should have direct connectivity from the Debian VM to
the router in GNS3 (R1 - 192.168.2.101 was my test device):
root@debian:/home/debian/workingdir# ping 192.168.2.101
PING 192.168.2.101 (192.168.2.101) 56(84) bytes of data.
64 bytes from 192.168.2.101: icmp_req=1 ttl=255 time=429 ms
Let’s choose ICMP packets for capturing purposes and after the capture is started, I am
going to ping the VM (192.168.2.100) from R1.
Please see the following way to use the program menu as an example:
root@debian:/home/debian/workingdir# python Sniffer.py
! Make sure to run this program as ROOT !
* Enter the interface on which to run the sniffer (like 'eth1'): eth1
64. Page 64 of 185
64 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
Interface eth1 was set to PROMISC mode.
Enter the number of packets to capture (0 is infinity): 0
The program will capture packets until the timeout expires.
* Enter the number of seconds to run the capture: 10
The program will capture packets for 10 seconds.
* Enter the protocol to filter by (arp|bootp|icmp|0 is all): icmp
The program will capture only ICMP packets.
* Please give a name to the log file: udemy.txt
* Starting the capture... Waiting for 10 seconds...
At this point, the program listens for all the ICMP packets it receives in the next 10
seconds on eth1 (ping from R1 now!). The results will be exported to the udemy.txt file.
And these are the results in this case:
root@debian:/home/debian/workingdir# cat udemy.txt
Packet 1: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 2: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
Packet 3: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 4: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
Packet 5: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 6: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
Packet 7: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 8: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
Packet 9: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 10: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
Packet 11: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 12: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
Packet 13: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 14: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
Packet 15: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 16: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
Packet 17: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 18: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
Packet 19: SMAC: c0:01:24:c0:00:00 DMAC: 08:00:27:f2:9b:7c
Packet 20: SMAC: 08:00:27:f2:9b:7c DMAC: c0:01:24:c0:00:00
65. Page 65 of 185
65 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
Logical flow diagram
############# Application #6 - Basic Network Sniffer #############
#In Scapy, we will use the sniff() function to capture network packets.
#To see a list of what commands Scapy has available, run the lsc()
function.
#Run the ls() command to see ALL the supported protocols.
#Run the ls(protocol) command to see the fields and default values for any
protocol.
#See packet layers with the .summary() function.
#See packet contents with the .show() function.
#Dig into a specific packet layer using a list index:
pkts[3][2].summary()...
66. Page 66 of 185
66 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#...the first index chooses the packet out of the pkts list, the second
index chooses the layer for that specific packet.
#Using the .command() packet method will return a string of the command
necessary to recreate that sniffed packet.
#To see the list of optional arguments for the sniff() function:
'''
>>> print sniff.__doc__
Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] +
L2ListenSocket args) -> list of packets
count: number of packets to capture. 0 means infinity
store: wether to store sniffed packets or discard them
prn: function to apply to each packet. If something is returned,
it is displayed. Ex:
ex: prn = lambda x: x.summary()
lfilter: python function applied to each packet to determine
if further action may be done
ex: lfilter = lambda x: x.haslayer(Padding)
offline: pcap file to read packets from, instead of sniffing them
timeout: stop sniffing after a given time (default: None)
L2socket: use the provided L2socket
opened_socket: provide an object ready to use .recv() on
stop_filter: python function applied to each packet to determine
if we have to stop the capture after this packet
ex: stop_filter = lambda x: x.haslayer(TCP)
'''
#Importing the necessary modules
import logging
import subprocess
#This will suppress all messages that have a lower level of seriousness
than error messages, while running or loading Scapy
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
logging.getLogger("scapy.interactive").setLevel(logging.ERROR)
logging.getLogger("scapy.loading").setLevel(logging.ERROR)
try:
from scapy.all import *
except ImportError:
print "Scapy package for Python is not installed on your system."
print "Get it from https://pypi.python.org/pypi/scapy and try again."
sys.exit()
67. Page 67 of 185
67 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Asking the user for some parameters: interface on which to sniff, the
number of packets to sniff, the time interval to sniff, the protocol
#Making the necessary configurations
print "n! Make sure to run this program as ROOT !n"
#Setting network interface in promiscuous mode
#Wikipedia: In computer networking, promiscuous mode or "promisc mode"[1]
is a mode for a wired network interface controller (NIC) or wireless
network interface controller (WNIC)...
#...that causes the controller to pass all traffic it receives to the
central processing unit (CPU) rather than passing only the frames that the
controller is intended to receive.
#This mode is normally used for packet sniffing that takes place on a
router or on a computer connected to a hub.
#Also, when using our setup (VirtualBox-to-GNS3), you should go to the
Settings section for the virtual machine you are using...
#...select the adapter that connects to the GNS3 network and set
Promiscuous Mode: Allow All
net_iface = raw_input("* Enter the interface on which to run the sniffer
(like 'eth1'): ")
subprocess.call(["ifconfig", net_iface, "promisc"], stdout=None,
stderr=None, shell=False)
print "nInterface %s was set to PROMISC mode." % net_iface
print
#Asking the user for the number of packets to sniff (the "count"
parameter)
pkt_to_sniff = raw_input("Enter the number of packets to capture (0 is
infinity): ")
#Considering the case when the user enters 0 (infinity)
if int(pkt_to_sniff) != 0:
print "nThe program will capture %d packets." % int(pkt_to_sniff)
print
elif int(pkt_to_sniff) == 0:
print "nThe program will capture packets until the timeout expires."
print
#Asking the user for the time interval to sniff (the "timeout" parameter)
time_to_sniff = raw_input("* Enter the number of seconds to run the
capture: ")
#Handling the value entered by the user
if int(time_to_sniff) != 0:
print "nThe program will capture packets for %d seconds." %
int(time_to_sniff)
print
68. Page 68 of 185
68 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
#Asking the user for any protocol filter he might want to apply to the
sniffing process
#For this example I chose three protocols: ARP, BOOTP, ICMP
#You can customize this to add your own desired protocols
proto_sniff = raw_input("* Enter the protocol to filter by
(arp|bootp|icmp|0 is all): ")
#Considering the case when the user enters 0 (all)
if (proto_sniff == "arp") or (proto_sniff == "bootp") or (proto_sniff ==
"icmp"):
print "nThe program will capture only %s packets." %
proto_sniff.upper()
print
elif int(proto_sniff) == 0:
print "nThe program will capture all protocols."
print
#Creating an external file for packet logging
file_name = raw_input("* Please give a name to the log file: ")
sniffer_log = open(file_name, "w")
#Initializing the packet counter
packet_no = 0
#This is the function that will be applied to each captured packet
#The function will extract some parameters from the packet and then log
each packet to an external file
def packet_log(pkt):
#The packet index
global packet_no
#Filtering the packets based on the protocol. Using the lower() method
to ignore the case when searching for the protocol in the packet.
if proto_sniff.lower() in pkt[0][1].summary().lower():
packet_no = packet_no + 1
#Writing the data for each packet to the external file
print >>sniffer_log, "Packet " + str(packet_no) + ": " + "SMAC: "
+ pkt[0].src + " DMAC: " + pkt[0].dst
print "n* Starting the capture... Waiting for %s seconds..." %
time_to_sniff
#Running the sniffing process
pkt = sniff(iface=net_iface, count=int(pkt_to_sniff),
timeout=int(time_to_sniff), prn=packet_log)
#print pkt.show()
#Printing the closing message
print "n* The timeout of %s seconds has passed." % time_to_sniff
69. Page 69 of 185
69 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
print "* Please check the %s file to see the captured packets.n" %
file_name
#Closing the log file
sniffer_log.close()
#End of program. Feel free to modify it, test it, add new protocols to
sniff and improve de code whenever you feel the need to.
70. Page 70 of 185
70 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
2.10. Application #7 - Configuration file comparator
(full code, reference: Section 19. Application #7 - Configuration file comparator)
This application connects to a router in the network via Telnet, extracts the output
of “show running-config” and “show startup-config”, filters the irrelevant lines and
finally compares the configurations. Now, I know this can be accomplished using
the “show archive config differences”command in Cisco CLI, but I wanted you to know
how can this task be accomplished using Python.
As with the other applications in this course, the full code is available for download.
Based on what you have learned so far in the course, it’s your job now to study,
understand and test the code against a network device, as you’ve seen me doing with the
previous applications.
Feel free to alter the code in any way you want. New functionality of any kind is welcome,
enhancements as well. Just make sure to adapt your code to the command output format.
Also, please read the first 13 lines in the code carefully, as they are a good introduction
to the code that follows. As you can see, the first thing you should do is configure Telnet
access on the router and the username and password:
username teopy privilege 15 password 0 python
line vty 0 4
privilege level 15
login local
transport input telnet ssh
At line 27, I have defined the ip_validity() function, which takes care of checking whether
the IP address of the router, which the user enters at the prompt, is valid or not. You have
already seen this kind of validity check in action in the previous applications, so there is
nothing new here. The same comment is valid for the file_validity() function (line 46).
Both functions are defined at this point and will be called later in the code.
At line 61, the telnet() function is defined, which takes a single parameter:command. The
value of this parameter will be passed to theconnection.write() method at line 96.
Starting with line 108, I defined the user menu, which will accept 3 options, except e -
Exit program:
1 - Compare running-config with startup-config
2 - Compare running-config with local file
3 - Compare startup-config with local file
I had treated only the first option, comparing the running-config with the startup-config -
71. Page 71 of 185
71 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
lines 115-196, leaving you with the job of coding and testing the other two options, having
my code from option 1 as a guideline.
Now, let’s look at option 1 for a bit. First, I called the ip_validity() function to get this out
of the way. Next, a very important step, I called the telnet()function for each of the two
commands I am interested in, and saved the returned output to a separate
variable: output_run for the running-config and output_start for the startup-config.
Then, I have created (opened for writing) two files, each of them storing the output of the
corresponding command. The file names are intuitively chosen. Don’t forget to close the
files after writing the contents of those variables, to save the information.
Next, I opened the files for reading and used the readlines() method on each file object
to store the lines in each file as elements of a list. Of course, then I closed the files.
Then, using a for loop, I have filtered the lines in each file which were of no interest to
our goal. We are only interested in the lines starting with the one defining the IOS
version: “version 12.4” for example. That is actually the first relevant line in each file.
Now, after “cleaning” the files, we are left with only the pure router configurations. It’s time
to create a new file (file_diff.txt), in which all the config differences are going to be stored.
Actually, we are going to compare the two lists obtained with the readlines() method.
Finally, using list comprehensions, we are going to find the lines in the running-config
which are not present in the startup-config and vice versa. In case there are multiple
differences, we use a for loop to iterate over the lists and then print those differences
directly into the file_diff.txt file., one per line As stated in the code, the rule is:
A "+" sign means the line is present in the RUNNING-CONFIG but not in the
STARTUP-CONFIG
A "-" sign means the line is present in the STARTUP-CONFIG but not in the
RUNNING-CONFIG
Now, let’s make a quick test. If you have just started the router and made no config yet,
then the startup-config and running-config are the same. No surprise here. But, to make
the test more relevant, let’s configure a few things before starting the comparison, without
saving the changes to the startup-config. So, let’s go to router R1:
R1(config)#username udemy1 password udemy
R1(config)#username udemy2 password udemy
R1(config)#username udemy3 password udemy
Now, these three configurations are the differences between the startup-config and the
running-config. We should see them after running our program, saved in
the file_diff.txt file. Let’s test this:
72. Page 72 of 185
72 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
root@debian:/home/debian/workingdir# python ConfigFileComp.py
Use this tool to:
1 - Compare running-config with startup-config
2 - Compare running-config with local file
3 - Compare startup-config with local file
e - Exit program
Enter your choice: 1
Enter an IP address: 192.168.2.101
Please wait while the config file is being analyzed...
Use this tool to:
1 - Compare running-config with startup-config
2 - Compare running-config with local file
3 - Compare startup-config with local file
e - Exit program
Enter your choice: e
Exiting... See ya...
Now let’s check the results. We should see all three commands with a “+”sign, right?
root@debian:/home/debian/workingdir# cat file_diff.txt
+username udemy1 password 0 udemy
+username udemy2 password 0 udemy
+username udemy3 password 0 udemy
root@debian:/home/debian/workingdir#
...and success! As expected, the three commands are marked as differences, in the file.
73. Page 73 of 185
73 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
Logical flow diagram
74. Page 74 of 185
74 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
############# Application #7 - Config File Comparator #############
#This program will:
# * Connect to a router via Telnet and it will compare the running-config
file to the startup-config file on that device (this can be usually done
with: show archive config differences)
# * Compare a locally stored config file (.txt) with the running-config
file or startup-config file running on a router.
#Please see the "Python File Operations" section in the course for a recap
of the necessary concepts.
#Don't forget to configure Telnet access on the router!
#username teopy privilege 15 password 0 python
#line vty 0 4
# privilege level 15
# login local
# transport input telnet ssh
#The first part of the program is very similar to Application #2 in the
course.
import telnetlib
import os.path
import subprocess
import time
import sys
def ip_validity():
global ip_address
#Checking IP validity
while True:
ip_address = raw_input("Enter an IP address: ")
#Checking octets
a = ip_address.split('.')
if (len(a) == 4) and (1 <= int(a[0]) <= 223) and (int(a[0]) !=
127) and (int(a[0]) != 169 or int(a[1]) != 254) and (0 <= int(a[1]) <= 255
and 0 <= int(a[2]) <= 255 and 0 <= int(a[3]) <= 255):
break
else:
print "nThe IP address is INVALID! Please retry!n"
continue
def file_validity():
while True:
75. Page 75 of 185
75 Python Network Programming – Course Applications Guide by Mihai Cătălin Teodosiu
cfg_file = raw_input("Enter config file name and extension: ")
#Changing exception message
if os.path.isfile(cfg_file) == True:
print "nFile was found...n"
break
else:
print "nFile %s does not exist! Please check and try
again!n" % cfg_file
continue
def telnet(command):
#Connecting to router via Telnet
#Define telnet parameters
username = 'teopy'
password = 'python'
#Specify the Telnet port (default is 23, anyway)
port = 23
#Specify the connection timeout in seconds for blocking operations,
like the connection attempt
connection_timeout = 5
#Specify a timeout in seconds. Read until the string is found or until
the timout has passed
reading_timeout = 5
#Logging into device
connection = telnetlib.Telnet(ip_address, port, connection_timeout)
#Waiting to be asked for an username
router_output = connection.read_until("Username:", reading_timeout)
#Enter the username when asked and a "n" for Enter
connection.write(username + "n")
#Waiting to be asked for a password
router_output = connection.read_until("Password:", reading_timeout)
#Enter the password when asked and a "n" for Enter
connection.write(password + "n")
time.sleep(1)
#Setting terminal length for the entire output - disabling pagination
connection.write("terminal length 0n")
time.sleep(1)
#Entering global config mode
connection.write("n")
connection.write(command + "n")
time.sleep(5)