blob: 554cbe6f6922a7ca75a8ffae3930a4504678f771 (
plain)
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
|
"""Python libknot interface."""
import ctypes
import sys
class KnotLookup(ctypes.Structure):
"""Libknot lookup return structure."""
_fields_ = [('id', ctypes.c_int), ('name', ctypes.c_char_p)]
class KnotRdataDescriptor(ctypes.Structure):
"""Rdata descriptor structure."""
_fields_ = [('block_types', ctypes.c_int * 8), ('name', ctypes.c_char_p)]
class Knot(object):
"""Basic libknot interface."""
LIBKNOT = None
LIBKNOT_VERSION = "@libknot_SOVERSION@"
RCODE_NAMES = None
STRERROR = None
RDATA_DESC = None
@classmethod
def __init__(cls, path: str = None) -> None:
"""Loads shared libknot library.
An explicit library path can be specified.
"""
if cls.LIBKNOT:
return
if path is None:
version = ""
try:
version = ".%u" % int(cls.LIBKNOT_VERSION)
except Exception:
pass
if sys.platform == "darwin":
path = "libknot%s.dylib" % version
else:
path = "libknot.so%s" % version
cls.LIBKNOT = ctypes.cdll.LoadLibrary(path)
cls.RCODE_NAMES = (KnotLookup * 32).in_dll(cls.LIBKNOT, "knot_rcode_names")
cls.STRERROR = cls.LIBKNOT.knot_strerror
cls.STRERROR.restype = ctypes.c_char_p
cls.STRERROR.argtypes = [ctypes.c_int]
cls.RDATA_DESC = cls.LIBKNOT.knot_get_rdata_descriptor
cls.RDATA_DESC.restype = ctypes.POINTER(KnotRdataDescriptor)
cls.RDATA_DESC.argtypes = [ctypes.c_ushort]
@classmethod
def rclass_str(cls, rclass: int) -> str:
"""Returns RRCLASS in text form."""
if (rclass == 1):
return "IN"
elif (rclass == 3):
return "CH"
elif (rclass == 254):
return "NONE"
elif (rclass == 255):
return "ANY"
else:
return "CLASS%i" % rclass
@classmethod
def rtype_str(cls, rtype: int) -> str:
"""Returns RRTYPE in text form."""
descr = cls.RDATA_DESC(rtype).contents.name
if descr:
return descr.decode()
else:
return "TYPE%i" % rtype
@classmethod
def rcode_str(cls, rcode: int) -> str:
"""Returns RCODE in text form."""
for item in cls.RCODE_NAMES:
if item.name and item.id == rcode:
return item.name.decode()
return "RCODE%i" % rcode
|