-
Notifications
You must be signed in to change notification settings - Fork 1
/
ip-api.py
112 lines (102 loc) · 4.29 KB
/
ip-api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import argparse
import requests
import os
import re
import sys
import traceback
def query_api(host):
"""Queries the ip-api site in order to check geolocation and mx record of
the host"""
main_api = 'http://ip-api.com/json/'
# For every host do an API request
try:
for x in host:
# Store response in 'json_data'
json_data = requests.get(main_api + x).json()
# Checks to see if there is a 'message' field in the json data and
# prints the message instead of printing our formatted data.
# This is done because messages are always an error with this api.
if 'message' in json_data:
print('\nThe IP "{}" is {}'.format(x, json_data['message']))
# Print out wanted JSON data formatted nicely
else:
print('\nAS: {}\n'
'City\State: {}, {}\n'
'Country: {}\n'
'ISP: {}\n'
'IP: {}\n'
'MX: {}'.format(
json_data['as'],
json_data['city'],
json_data['regionName'],
json_data['country'],
json_data['isp'],
json_data['query'],
x))
# Added exception handling of key errors to help identify problems when
# reading the json data
except KeyError:
traceback.print_exc(file=sys.stdout)
print('Key Error')
print('JSON: ')
print(json_data)
def findMX(host):
"""Looks up the MX record of a host"""
p = os.popen('host -t MX ' + host)
# initialize dicts
std_out = []
# Stores the standard output of p(above)
split = []
# Used to hold the a line in std_out that we want to split.
MXServer = []
# The server address that we are sending to the api.
# Append terminal output to list std_out
for line in p:
if re.search('not found', line):
print('No MX record found querying ' + host)
query_api([host])
break
# Check to see if 'domain name pointer' is in the line and finds the
# ip associated with the pointer to do a query on. Created for IPs that
# do not have a easily parsed MX record return.
elif re.search('domain name pointer', line):
print(line)
print('Domain name pointer found querying original host: ' + host)
query_api([host])
extra = re.search('.in-addr.arpa .*', str(line))
# This finds out the 'extra' stuff I dont really care about. i only
# need the IP that is in the line before .in-addr.arpa
thing = line.replace(extra.group(0), '')
# This takes the line and replaces what is stored in the 'extra'
# variable with nothing and gives us the 'thing' we want to query,
# an IP address.
print('\nDomain Name pointer Query: ' + thing)
query_api([thing.rstrip()])
break
std_out.append(line)
p.close
# split line into dict and return MX servers
i = 0
for x in std_out:
# When using os.popen it basically acts like a terminal allowing you to
# run terminal commands from your Python script and use its output. We
# are using as an example 'host -t MX google.com' the output would look
# like:
# google.com mail is handled by 30 alt2.aspmx.l.google.com
# google.com mail is handled by 40 alt3.aspmx.l.google.com
# google.com mail is handled by 10 aspmx.l.google.com
# google.com mail is handled by 20 alt1.aspmx.l.google.com
# google.com mail is handled by 50 alt4.aspmx.l.google.com
split = std_out[i].split()
i = i + 1
# We use .split() method to split the std_out list entry by spaces
MXServer.append(split[-1])
# We take the last item in the split(aspmx.l.google.com) and append it
# to the list 'MXServer'
query_api(MXServer)
# Now we send the list 'MXServer' to the query_api function
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("host", help="hostname to lookip")
args = parser.parse_args()
findMX(args.host)