2011-12-16 11:02:24 +01:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
|
|
|
import sys
|
2011-12-16 13:19:48 +01:00
|
|
|
from dns import resolver,reversename
|
2011-12-16 11:02:24 +01:00
|
|
|
from flask import Flask, render_template, jsonify
|
|
|
|
app = Flask(__name__)
|
|
|
|
|
|
|
|
import socket
|
|
|
|
|
2011-12-16 13:19:48 +01:00
|
|
|
def get_ip(n, q):
|
|
|
|
return str(resolver.query(n,q)[0])
|
|
|
|
|
2011-12-16 11:02:24 +01:00
|
|
|
def check_mask(n):
|
|
|
|
if not n:
|
|
|
|
return True
|
|
|
|
try:
|
|
|
|
mask = int(n)
|
|
|
|
return ( mask > 1 and mask < 128)
|
|
|
|
except:
|
|
|
|
return False
|
|
|
|
|
|
|
|
def check_ipv4(n):
|
|
|
|
try:
|
|
|
|
socket.inet_pton(socket.AF_INET, n)
|
|
|
|
return True
|
|
|
|
except socket.error:
|
|
|
|
return False
|
|
|
|
|
|
|
|
def check_ipv6(n):
|
|
|
|
try:
|
|
|
|
socket.inet_pton(socket.AF_INET6, n)
|
|
|
|
return True
|
|
|
|
except socket.error:
|
|
|
|
return False
|
|
|
|
|
|
|
|
@app.route("/")
|
|
|
|
def hello():
|
|
|
|
return render_template('index.html')
|
|
|
|
|
2011-12-19 00:17:30 +01:00
|
|
|
@app.route("/<host>/<proto>/prefix/")
|
|
|
|
@app.route("/<host>/<proto>/prefix/<prefix>")
|
|
|
|
@app.route("/<host>/<proto>/prefix/<prefix>/<mask>")
|
2011-12-18 12:32:00 +01:00
|
|
|
@app.route("/<host>/<proto>/prefix<all>/")
|
|
|
|
@app.route("/<host>/<proto>/prefix<all>/<prefix>")
|
|
|
|
@app.route("/<host>/<proto>/prefix<all>/<prefix>/<mask>")
|
|
|
|
def prefix(host, proto, prefix="", mask="", all=False):
|
2011-12-16 13:19:48 +01:00
|
|
|
qprefix = prefix
|
2011-12-16 11:02:24 +01:00
|
|
|
|
2011-12-16 19:05:16 +01:00
|
|
|
|
2011-12-16 11:02:24 +01:00
|
|
|
# security check
|
2011-12-16 13:19:48 +01:00
|
|
|
allowed = True
|
2011-12-16 19:05:16 +01:00
|
|
|
if not prefix:
|
|
|
|
allowed = False
|
|
|
|
elif not check_mask(mask):
|
2011-12-16 13:19:48 +01:00
|
|
|
allowed = False
|
|
|
|
elif proto == "ipv6":
|
|
|
|
if not check_ipv6(prefix):
|
|
|
|
try:
|
|
|
|
qprefix = get_ip(prefix, "AAAA")
|
|
|
|
except:
|
2011-12-16 19:15:49 +01:00
|
|
|
qprefix = "unresolvable"
|
2011-12-16 13:19:48 +01:00
|
|
|
allowed = False
|
2011-12-16 19:15:49 +01:00
|
|
|
|
2011-12-16 13:19:48 +01:00
|
|
|
|
|
|
|
elif proto == "ipv4":
|
|
|
|
if not check_ipv4(prefix):
|
|
|
|
try:
|
|
|
|
qprefix = get_ip(prefix, "A")
|
|
|
|
except:
|
2011-12-16 19:15:49 +01:00
|
|
|
qprefix = "unresolvable"
|
2011-12-16 13:19:48 +01:00
|
|
|
allowed = False
|
|
|
|
else:
|
|
|
|
allowed = False
|
2011-12-16 19:05:16 +01:00
|
|
|
|
2011-12-18 12:32:00 +01:00
|
|
|
output = '<h3>' + host + ' (' + proto + ') show route for ' + prefix + (prefix != qprefix and " (%s)"%qprefix or "") + (mask and '/' + mask or '' ) + (all and " all" or "") + '</h3>'
|
2011-12-16 13:19:48 +01:00
|
|
|
if allowed:
|
|
|
|
if mask: qprefix = qprefix +"/"+mask
|
2011-12-16 11:02:24 +01:00
|
|
|
if mask: prefix = prefix +"/"+mask
|
2011-12-18 12:32:00 +01:00
|
|
|
ok, string = get_cmd_result(host , proto, "show route for " + qprefix + (all and "all" or ""))
|
2011-12-16 11:02:24 +01:00
|
|
|
if ok:
|
|
|
|
string = "\n".join([ s.replace("1007-"," ") for s in string.split("\n") if not s.startswith("0000") ])
|
|
|
|
output +='<pre>' + string + '</pre>'
|
|
|
|
else:
|
|
|
|
output += string
|
|
|
|
else:
|
2011-12-16 19:15:49 +01:00
|
|
|
if prefix and qprefix != "unresolvable":
|
|
|
|
output += prefix + ' not valid'
|
|
|
|
elif prefix:
|
|
|
|
output += prefix + ' unresolvable'
|
2011-12-16 19:05:16 +01:00
|
|
|
else:
|
|
|
|
output += 'prefix missing'
|
2011-12-16 13:19:48 +01:00
|
|
|
|
2011-12-18 12:32:00 +01:00
|
|
|
return render_template('index.html', output=output, typ="prefix" + (all and "_detail" or ""), host=host+"/"+proto, prefix=prefix)
|
2011-12-16 11:02:24 +01:00
|
|
|
|
2011-12-16 19:05:16 +01:00
|
|
|
@app.route("/<host>/<proto>/detail/")
|
2011-12-16 11:02:24 +01:00
|
|
|
@app.route("/<host>/<proto>/detail/<name>")
|
2011-12-16 19:05:16 +01:00
|
|
|
def detail(host, proto, name=""):
|
|
|
|
output = '<h3>' + host + ' (' + proto + ') show protocols all ' + name + '</h3>'
|
2011-12-16 11:02:24 +01:00
|
|
|
|
2011-12-16 19:05:16 +01:00
|
|
|
if name:
|
|
|
|
ok, string = get_cmd_result(host , proto, "show protocols all " + name)
|
|
|
|
if ok:
|
|
|
|
string = "\n".join([ s.strip() for s in string.split("\n") if s.startswith(" ")])
|
|
|
|
output +='<pre>' + string + '</pre>'
|
|
|
|
else:
|
|
|
|
output += string
|
2011-12-16 11:02:24 +01:00
|
|
|
else:
|
2011-12-16 19:05:16 +01:00
|
|
|
output += "name missing"
|
|
|
|
|
2011-12-16 11:02:24 +01:00
|
|
|
return render_template('index.html', output=output, typ="detail", host=host+"/"+proto, name=name)
|
|
|
|
|
2011-12-16 19:05:16 +01:00
|
|
|
@app.route("/<host>/")
|
|
|
|
@app.route("/<host>/<proto>/")
|
2011-12-16 11:02:24 +01:00
|
|
|
@app.route("/<host>/<proto>/summary")
|
2011-12-16 19:05:16 +01:00
|
|
|
def summary(host, proto="ipv4"):
|
|
|
|
output = '<h3>' + host + ' (' + proto + ') show protocols</h3>'
|
2011-12-16 11:02:24 +01:00
|
|
|
|
|
|
|
ok, string = get_cmd_result(host , proto, "show protocols")
|
|
|
|
if ok:
|
|
|
|
output += '<pre><table>'
|
2011-12-16 12:52:56 +01:00
|
|
|
for infos in string.split("\n"):
|
|
|
|
if not infos.startswith(" "): continue
|
2011-12-16 11:02:24 +01:00
|
|
|
d = infos.split()
|
|
|
|
name = d[0]
|
|
|
|
typ = d[1]
|
|
|
|
if typ == "BGP":
|
2011-12-16 12:52:56 +01:00
|
|
|
output += '<tr><td><a href="/%s/%s/detail/%s">%s</a><td><td>%s</td></tr>'%(host,proto,name,name,infos.replace(name,"").strip())
|
2011-12-16 11:02:24 +01:00
|
|
|
output += '</table></pre>'
|
|
|
|
else:
|
|
|
|
output += string
|
|
|
|
return render_template('index.html', output=output, typ="summary", host=host+"/"+proto)
|
|
|
|
|
|
|
|
@app.route("/<host>/<proto>/status")
|
|
|
|
def status(host, proto):
|
|
|
|
string = get_cmd_result(host, proto, "show status")
|
|
|
|
output = '<pre>' + string + '</pre>'
|
|
|
|
return render_template('index.html', output=output, host=host+"/"+proto)
|
|
|
|
|
|
|
|
def get_cmd_result(host, proto, cmd):
|
|
|
|
|
|
|
|
ret = True
|
|
|
|
if proto == "ipv4":
|
|
|
|
port = 9994
|
|
|
|
else:
|
|
|
|
port = 9996
|
|
|
|
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
sock.settimeout(3.0)
|
|
|
|
# sock.setblocking(0)
|
|
|
|
try:
|
|
|
|
sock.connect((host, port))
|
2011-12-16 19:15:49 +01:00
|
|
|
app.logger.debug("open socket on %s:%d", host, port)
|
2011-12-16 11:02:24 +01:00
|
|
|
|
|
|
|
sock.send(cmd + "\n")
|
2011-12-16 19:15:49 +01:00
|
|
|
app.logger.debug("send %s socket on %s:%d", cmd, host, port)
|
2011-12-16 11:02:24 +01:00
|
|
|
|
|
|
|
bufsize = 4096
|
|
|
|
data = sock.recv(bufsize)
|
|
|
|
string = data
|
2011-12-16 19:15:49 +01:00
|
|
|
app.logger.debug("read %s (%d)", data, len(data))
|
2011-12-16 11:02:24 +01:00
|
|
|
code = string.split("\n")[-2][0:4]
|
2011-12-16 12:52:56 +01:00
|
|
|
while not code[0] in ["0", "9", "8"]:
|
2011-12-16 11:02:24 +01:00
|
|
|
data = sock.recv(bufsize)
|
|
|
|
string = string + data
|
2011-12-16 19:15:49 +01:00
|
|
|
app.logger.debug("read %s (%d)", data, len(data))
|
2011-12-16 11:02:24 +01:00
|
|
|
code = string.strip()[len(string.strip())-4:]
|
|
|
|
|
2011-12-16 12:52:56 +01:00
|
|
|
if code[0] in [ "9", "8" ]:
|
2011-12-16 11:02:24 +01:00
|
|
|
ret = False
|
|
|
|
|
2011-12-16 19:15:49 +01:00
|
|
|
app.logger.debug("return %s",string)
|
2011-12-16 11:02:24 +01:00
|
|
|
except Exception as detail:
|
|
|
|
ret = False
|
|
|
|
string = "Failed connect to %s:%d (%s)"%(host, port, detail)
|
|
|
|
app.logger.error(string)
|
|
|
|
sock.close()
|
|
|
|
return (ret, string)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2011-12-16 19:15:49 +01:00
|
|
|
#app.debug = True
|
2011-12-16 11:02:24 +01:00
|
|
|
app.run()
|