mirror of
https://github.com/sileht/bird-lg.git
synced 2024-11-16 12:24:42 +01:00
149 lines
3.3 KiB
Python
149 lines
3.3 KiB
Python
|
|
||
|
import socket
|
||
|
import sys
|
||
|
import traceback
|
||
|
|
||
|
BUFSIZE = 4096
|
||
|
|
||
|
SUCCESS_CODES = {
|
||
|
"0000" : "OK",
|
||
|
"0001" : "Welcome",
|
||
|
"0002" : "Reading configuration",
|
||
|
"0003" : "Reconfigured",
|
||
|
"0004" : "Reconfiguration in progress",
|
||
|
"0005" : "Reconfiguration already in progress, queueing",
|
||
|
"0006" : "Reconfiguration ignored, shutting down",
|
||
|
"0007" : "Shutdown ordered",
|
||
|
"0008" : "Already disabled",
|
||
|
"0009" : "Disabled",
|
||
|
"0010" : "Already enabled",
|
||
|
"0011" : "Enabled",
|
||
|
"0012" : "Restarted",
|
||
|
"0013" : "Status report",
|
||
|
"0014" : "Route count",
|
||
|
"0015" : "Reloading",
|
||
|
"0016" : "Access restricted",
|
||
|
}
|
||
|
|
||
|
TABLES_ENTRY_CODES = {
|
||
|
"1000" : "BIRD version",
|
||
|
"1001" : "Interface list",
|
||
|
"1002" : "Protocol list",
|
||
|
"1003" : "Interface address",
|
||
|
"1004" : "Interface flags",
|
||
|
"1005" : "Interface summary",
|
||
|
"1006" : "Protocol details",
|
||
|
"1007" : "Route list",
|
||
|
"1008" : "Route details",
|
||
|
"1009" : "Static route list",
|
||
|
"1010" : "Symbol list",
|
||
|
"1011" : "Uptime",
|
||
|
"1012" : "Route extended attribute list",
|
||
|
"1013" : "Show ospf neighbors",
|
||
|
"1014" : "Show ospf",
|
||
|
"1015" : "Show ospf interface",
|
||
|
"1016" : "Show ospf state/topology",
|
||
|
"1017" : "Show ospf lsadb",
|
||
|
"1018" : "Show memory",
|
||
|
}
|
||
|
|
||
|
ERROR_CODES = {
|
||
|
"8000" : "Reply too long",
|
||
|
"8001" : "Route not found",
|
||
|
"8002" : "Configuration file error",
|
||
|
"8003" : "No protocols match",
|
||
|
"8004" : "Stopped due to reconfiguration",
|
||
|
"8005" : "Protocol is down => cannot dump",
|
||
|
"8006" : "Reload failed",
|
||
|
"8007" : "Access denied",
|
||
|
|
||
|
"9000" : "Command too long",
|
||
|
"9001" : "Parse error",
|
||
|
"9002" : "Invalid symbol type",
|
||
|
}
|
||
|
|
||
|
END_CODES = ERROR_CODES.keys() + SUCCESS_CODES.keys()
|
||
|
|
||
|
global bird_sockets
|
||
|
bird_sockets = {}
|
||
|
|
||
|
def BirdSocketSingleton(host, port):
|
||
|
global bird_sockets
|
||
|
s = bird_sockets.get((host,port), None)
|
||
|
if not s:
|
||
|
s = BirdSocket(host,port)
|
||
|
bird_sockets[(host,port)] = s
|
||
|
return s
|
||
|
|
||
|
class BirdSocket:
|
||
|
|
||
|
def __init__(self, host, port):
|
||
|
self.__host = host
|
||
|
self.__port = port
|
||
|
self.__sock = None
|
||
|
|
||
|
def __connect(self):
|
||
|
if self.__sock: return
|
||
|
|
||
|
self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||
|
self.__sock.settimeout(3.0)
|
||
|
self.__sock.connect((self.__host, self.__port))
|
||
|
|
||
|
def close(self):
|
||
|
if self.__sock:
|
||
|
try: self.__sock.close()
|
||
|
except: pass
|
||
|
self.__sock = None
|
||
|
|
||
|
def cmd(self, cmd):
|
||
|
try:
|
||
|
self.__connect()
|
||
|
self.__sock.send(cmd + "\n")
|
||
|
return self.__read()
|
||
|
except socket.error:
|
||
|
why = sys.exc_info()[1]
|
||
|
self.close()
|
||
|
return False, "Bird connection problem: %s" % why
|
||
|
|
||
|
def __read(self):
|
||
|
|
||
|
code = "7000" # Not used in bird
|
||
|
parsed_string = ""
|
||
|
lastline = ""
|
||
|
|
||
|
while code not in END_CODES:
|
||
|
data = self.__sock.recv(BUFSIZE)
|
||
|
|
||
|
lines = (lastline + data).split("\n")
|
||
|
if len(data) == BUFSIZE:
|
||
|
lastline = lines[-1]
|
||
|
lines = lines[:-1]
|
||
|
|
||
|
for line in lines:
|
||
|
code = line[0:4]
|
||
|
|
||
|
if not line.strip():
|
||
|
continue
|
||
|
elif code == "0000":
|
||
|
return True, parsed_string
|
||
|
elif code in SUCCESS_CODES.keys():
|
||
|
return True, SUCCESS_CODES.get(code)
|
||
|
elif code in ERROR_CODES.keys():
|
||
|
return False, ERROR_CODES.get(code)
|
||
|
elif code[0] in [ "1", "2"] :
|
||
|
parsed_string += line[5:] + "\n"
|
||
|
elif code[0] == " ":
|
||
|
parsed_string += line[1:] + "\n"
|
||
|
elif code[0] == "+":
|
||
|
parsed_string += line[1:]
|
||
|
else:
|
||
|
parsed_string += "<<<unparsable_string(%s)>>>\n"%line
|
||
|
|
||
|
return True, parsed_string
|
||
|
|
||
|
|
||
|
__all__ = ['BirdSocketSingleton' , 'BirdSocket' ]
|
||
|
|
||
|
|
||
|
|