Python. Problems populating a dictionary in a loop - python-3.x

I am trying to add geoip information to a bunch of IP addresses I have extracted from netstat. I get my endpoint IPs in my list fine.
DEBUG1: Endpoint IPs: ['165.227.118.82', '155.133.248.39', '20.54.37.64', '173.194.76.188', '74.125.206.109', '47.251.49.246', '52.19.109.21', '151.101.61.229', '151.101.60.193', '162.159.133.234', '162.159.135.232', '162.159.133.232', '162.159.129.232', '75.2.53.94', '54.170.196.176', '143.204.65.104', '34.236.20.64', '75.101.134.98', '75.101.134.98', '75.101.134.98', '52.216.249.68', '52.216.249.68', '142.250.179.228', '142.250.179.228', '52.96.165.18', '52.97.133.194', '52.98.159.194']
But when I try and enrich each of these IPs with additional information via a loop I only get the last IP returned in the dictionary. I ralise it is being over written but I cant see how or why.
Here is what happens when I run the program and I print out the resulting dictionary.
DEBUG2: Enriched IP: {'IP': '52.98.159.194', 'continent': 'Europe', 'country': 'France', 'iso_code': 'FR', 'city': 'Paris', 'lat': 48.8323, 'long': 2.4075, 'timezone': 'Europe/Paris', 'accuracy': 20}
The errant function is as follows:
def enrich_ip(rip):
# ------------------This needs to be a function------------------
# Get ip info on each of the IP's retuned in rip
# add this information to a dictionary
# create a dictionary to hold our ip info
enriched_info = {}
for ip in rip:
# get ip info
try:
enriched_info['IP'] = ip
enriched_info['continent'] = get_ip_info(ip).continent.name
enriched_info['country'] = get_ip_info(ip).country.name
enriched_info['iso_code'] = get_ip_info(ip).country.iso_code
enriched_info['city'] = get_ip_info(ip).city.name
enriched_info['lat'] = get_ip_info(ip).location.latitude
enriched_info['long'] = get_ip_info(ip).location.longitude
enriched_info['timezone'] = get_ip_info(ip).location.time_zone
enriched_info['accuracy'] = get_ip_info(ip).location.accuracy_radius
except Exception as e:
print(e)
continue
return enriched_info
I pass in 'rip' to the function. rip is my list of IPs shown against DEBUG1
I had this working fine outside of a function, but I was then left with the information inside the function and not accessible elsewhere.

Dictionaries cannot contain duplicate keys, that's why you only see the last IP address in resulting dictionary. Instead, create a list of dictionaries and return it:
def enrich_ip(rip):
# ------------------This needs to be a function------------------
# Get ip info on each of the IP's retuned in rip
# add this information to a dictionary
# create a list to hold our ip info
all_data = []
for ip in rip:
enriched_info = {}
try:
enriched_info["IP"] = ip
enriched_info["continent"] = get_ip_info(ip).continent.name
enriched_info["country"] = get_ip_info(ip).country.name
enriched_info["iso_code"] = get_ip_info(ip).country.iso_code
enriched_info["city"] = get_ip_info(ip).city.name
enriched_info["lat"] = get_ip_info(ip).location.latitude
enriched_info["long"] = get_ip_info(ip).location.longitude
enriched_info["timezone"] = get_ip_info(ip).location.time_zone
enriched_info["accuracy"] = get_ip_info(ip).location.accuracy_radius
all_data.append(enriched_info)
except Exception as e:
print(e)
continue
return all_data
Alternative would be to crate a dictionary where keys are IP:
def enrich_ip(rip):
# ------------------This needs to be a function------------------
# Get ip info on each of the IP's retuned in rip
# add this information to a dictionary
# create a dictionary to hold our ip info
all_data = {}
for ip in rip:
enriched_info = {}
try:
enriched_info["IP"] = ip
enriched_info["continent"] = get_ip_info(ip).continent.name
enriched_info["country"] = get_ip_info(ip).country.name
enriched_info["iso_code"] = get_ip_info(ip).country.iso_code
enriched_info["city"] = get_ip_info(ip).city.name
enriched_info["lat"] = get_ip_info(ip).location.latitude
enriched_info["long"] = get_ip_info(ip).location.longitude
enriched_info["timezone"] = get_ip_info(ip).location.time_zone
enriched_info["accuracy"] = get_ip_info(ip).location.accuracy_radius
all_data["IP"] = enriched_info
except Exception as e:
print(e)
continue
return all_data

Related

Use for loop with dictionary

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

Compute pancake pair address via python3

This question is quite related to Compute uniswap pair address via python
I am trying to do the same but for panckage swap v2.
I am using the CAKE/WBNB pair as an example:
CONTRACTS = {
"CAKE": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82",
}
PANCAKE_SWAP_FACTORY = "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73"
PANCAKE_SWAP_ROUTER = "0x10ED43C718714eb63d5aA57B78B54704E256024E"
WBNB_ADDRESS = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
hexadem_ ='0x00fb7f630766e6a796048ea87d01acd3068e8ff67d078148a3fa3f4a84f69bd5'
factory = PANCAKE_SWAP_FACTORY
abiEncoded_1 = encode_abi_packed(['address', 'address'], (CONTRACTS['CAKE'], WBNB_ADDRESS))
salt_ = pancakeswap.w3.solidityKeccak(['bytes'], ['0x' +abiEncoded_1.hex()])
abiEncoded_2 = encode_abi_packed([ 'address', 'bytes32'], ( factory, salt_))
resPair = pancakeswap.w3.solidityKeccak(['bytes','bytes'], ['0xff' + abiEncoded_2.hex(), hexadem_])[12:]
# resPair is the address for the pancakeswap CAKE/WBNB pair
print(resPair.hex())
print('0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6')
print(resPair.hex() == '0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6')
print()
My first problem is the code is not working, it is not producint the correct contract address, in fact it prints:
0x0ed7e52944161450477ee417de9cd3a859b14fd0
0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6
False
I think the problem is the value of the constant hexadem_, which can be found in:
hexadem_ = '0xd0d4c4cd0848c93cb4fd1f498d7013ee6bfb25783ea21593d5834f5d250ece66' # from https://github.com/pancakeswap/pancake-swap-periphery/blob/master/contracts/libraries/PancakeLibrary.sol
hexadem_ ='0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' # from uniswap (most likely wrong...)
hexadem_ ='0x00fb7f630766e6a796048ea87d01acd3068e8ff67d078148a3fa3f4a84f69bd5' # from https://bscscan.com/address/0x10ED43C718714eb63d5aA57B78B54704E256024E#code line 298
The address you obtained is correct. The address that you are attempting to match to is for pancake V1.
You can see this by clicking on "contract creator" for the 2 addresses, and you will see the pancake factory versions for 0x0ed7e52944161450477ee417de9cd3a859b14fd0 and 0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6.

I Want to iterate over some IP address and networks, to check if a IP belongs to a particular network

I Want to iterate over some IP address and networks, to check if an IP belongs to a particular network.
This is what I have written so far.
import netaddr, ipaddress
from netaddr import *
IP_found = []
IP_miss = []
dca = ['172.17.34.2', '172.17.33.1', '172.17.35.1', '172.17.36.2']
ip_net = [IPNetwork('172.17.34.0/27'), IPNetwork('172.17.35.0/27')]
for element in ip_net:
temp = ipaddress.ip_network(element)
for ip in dca:
if ipaddress.ip_address(ip) in (temp):
IP_found.append(ip)
break
else:
IP_miss.append(ip)
print(len(IP_found))
print(len(IP_miss))
print(IP_found)
print(IP_miss)
This is my expected output.
IP_found -> ['172.17.34.2', '172.17.35.1']
IP_miss -> ['172.17.33.1', '172.17.36.2']
I got the below output:
['172.17.34.2', '172.17.35.1']
['172.17.34.2', '172.17.33.1']
import netaddr,ipaddress
from netaddr import *
IP_found = []
IP_miss = []
dca = ['172.17.34.2', '172.17.33.1', '172.17.35.1', '172.17.36.2']
ip_net = [IPNetwork('172.17.34.0/27'), IPNetwork('172.17.35.0/27')]
for ip in dca: # Loops through the ip
if any(ip in ip_subnet for ip_subnet in ip_net): # Loops through subnet
IP_found.append(ip)
else:
IP_miss.append(ip)
print(len(IP_found))
print(len(IP_miss))
print(IP_found)
print(IP_miss)
Try this instead.

Create a DNS server and redirect all request to my site

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

Google Matrix API - python return Nonetype error

"Update"
*Finally resolved the issue, changed the try except to include TypeError and also use pass instead of continue in the except.
"End of update"
I wrote code to search for distance between two locations using Google Distance Matrix API. The origin location are fixed, however for the destination, I get it from an xlsx file. I was expecting to get Dictionary with Destination as the Key and the distance as value. When I run the code below, after certain loop I'm stumbled with this error code:
TypeError: Expected a lat/lng dict or tuple, but got NoneType
Can you help me understand the cause of the error? Here is the code (pygmap.py):
import googlemaps
import openpyxl
#get origin and destination locations
def cleanWB(file_path):
destination = list()
wb = openpyxl.load_workbook(filename=file_path)
ws = wb.get_sheet_by_name('Sheet1')
for i in range(ws.max_row):
cellValueLocation = ws.cell(row=i+2,column=1).value
destination.append(cellValueLocation)
#remove duplicates from destination list
unique_location = list(set(destination))
return unique_location
def getDistance(origin, destination):
#Google distance matrix API key
gmaps = googlemaps.Client(key = 'INSERT API KEY')
distance = gmaps.distance_matrix(origin, destination)
distance_status = distance['rows'][0]['elements'][0]['status']
if distance_status != 'ZERO_RESULTS':
jDistance = distance['rows'][0]['elements'][0]
distance_location = jDistance['distance']['value']
else:
distance_location = 0
return distance_location
And I run it using this code:
import pygmap
unique_location = pygmap.cleanWB('C:/Users/an_id/Documents/location.xlsx')
origin = 'alam sutera'
result = {}
for i in range(len(unique_location)):
try:
result[unique_location[i]] = pygmap.getDistance(origin, unique_location[i])
except (KeyError, TypeError):
pass
If I print results it will show that I have successfully get 46 results
result
{'Pondok Pinang': 25905, 'Jatinegara Kaum': 40453, 'Serdang': 1623167, 'Jatiasih
': 44737, 'Tanah Sereal': 77874, 'Jatikarya': 48399, 'Duri Kepa': 20716, 'Mampan
g Prapatan': 31880, 'Pondok Pucung': 12592, 'Johar Baru': 46791, 'Karet': 26889,
'Bukit Duri': 34039, 'Sukamaju': 55333, 'Pasir Gunung Selatan': 42140, 'Pinangs
ia': 30471, 'Pinang Ranti': 38099, 'Bantar Gebang': 50778, 'Sukabumi Utara': 204
41, 'Kembangan Utara': 17708, 'Kwitang': 25860, 'Kuningan Barat': 31231, 'Cilodo
ng': 58879, 'Pademangan Barat': 32585, 'Kebon Kelapa': 23452, 'Mekar Jaya': 5381
0, 'Kampung Bali': 1188894, 'Pajang': 30008, 'Sukamaju Baru': 53708, 'Benda Baru
': 19965, 'Sukabumi Selatan': 19095, 'Gandaria Utara': 28429, 'Setia Mulya': 635
34, 'Rawajati': 31724, 'Cireundeu': 28220, 'Cimuning': 55712, 'Lebak Bulus': 273
61, 'Kayuringin Jaya': 47560, 'Kedaung Kali Angke': 19171, 'Pagedangan': 16791,
'Karang Anyar': 171165, 'Petukangan Selatan': 18959, 'Rawabadak Selatan': 42765,
'Bojong Sari Baru': 26978, 'Padurenan': 53216, 'Jati Mekar': 2594703, 'Jatirang
ga': 51119}
Resolved the issue to include TypeError in the Try Except. And also use pass instead of continue
import pygmap
unique_location = pygmap.cleanWB('C:/Users/an_id/Documents/location.xlsx')
origin = 'alam sutera'
result = {}
#get getPlace
for i in range(len(unique_location)):
try:
result[unique_location[i]] = pygmap.getDistance(origin, unique_location[i])
except (KeyError, TypeError):
pass
I skipped some locations using this solution though.

Resources