summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xsrc/lib/dns/tests/testdata/gen-wiredata.py.in105
1 files changed, 82 insertions, 23 deletions
diff --git a/src/lib/dns/tests/testdata/gen-wiredata.py.in b/src/lib/dns/tests/testdata/gen-wiredata.py.in
index fc8975712b..6f181b4e0c 100755
--- a/src/lib/dns/tests/testdata/gen-wiredata.py.in
+++ b/src/lib/dns/tests/testdata/gen-wiredata.py.in
@@ -15,7 +15,7 @@
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-import configparser, re, time, sys
+import configparser, re, time, socket, sys
from datetime import datetime
from optparse import OptionParser
@@ -215,6 +215,74 @@ class EDNS:
f.write('# RDLEN=%d\n' % self.rdlen)
f.write('%04x\n' % self.rdlen)
+class RR:
+ '''This is a base class for various types of RR test data.
+ For each RR type (A, AAAA, NS, etc), we define a derived class of RR
+ to dump type specific RDATA parameters. This class defines parameters
+ common to all types of RDATA, namely the owner name, RR class and TTL.
+ The dump() method of derived classes are expected to call dump_header(),
+ whose default implementation is provided in this class. This method
+ decides whether to dump the test data as an RR (with name, type, class)
+ or only as RDATA (with its length), and dumps the corresponding data
+ via the specified file object.
+
+ By convention we assume derived classes are named after the common
+ standard mnemonic of the corresponding RR types. For example, the
+ derived class for the RR type SOA should be named "SOA".
+
+ Configurable parameters are as follows:
+ - as_rr (bool): Whether or not the data is to be dumped as an RR. False
+ by default.
+ - rr_class (string): The RR class of the data. Only meaningful when the
+ data is dumped as an RR. Default is 'IN'.
+ - rr_ttl (integer): The TTL value of the RR. Only meaningful when the
+ data is dumped as an RR. Default is 86400 (1 day).
+ '''
+
+ def __init__(self):
+ self.as_rr = False
+ # only when as_rr is True, same for class/TTL:
+ self.rr_name = 'example.com'
+ self.rr_class = 'IN'
+ self.rr_ttl = 86400
+ def dump_header(self, f, rdlen):
+ type_txt = self.__class__.__name__
+ type_code = parse_value(type_txt, dict_rrtype)
+ if self.as_rr:
+ rrclass = parse_value(self.rr_class, dict_rrclass)
+ f.write('\n# %s RR (QNAME=%s Class=%s TTL=%d RDLEN=%d)\n' %
+ (type_txt, self.rr_name,
+ code_totext(rrclass, rdict_rrclass), self.rr_ttl, rdlen))
+ f.write('%s %04x %04x %08x %04x\n' %
+ (encode_name(self.rr_name), type_code, rrclass,
+ self.rr_ttl, rdlen))
+ else:
+ f.write('\n# %s RDATA (RDLEN=%d)\n' % (type_txt, rdlen))
+ f.write('%04x\n' % rdlen)
+
+class A(RR):
+ rdlen = 4 # fixed by default
+ address = '192.0.2.1'
+
+ def dump(self, f):
+ self.dump_header(f, self.rdlen)
+ f.write('# Address=%s\n' % (self.address))
+ bin_address = socket.inet_aton(self.address)
+ f.write('%02x%02x%02x%02x\n' % (bin_address[0], bin_address[1],
+ bin_address[2], bin_address[3]))
+
+class NS(RR):
+ rdlen = None # auto calculate
+ nsname = 'ns.example.com'
+
+ def dump(self, f):
+ nsname_wire = encode_name(self.nsname)
+ if self.rdlen is None:
+ self.rdlen = len(nsname_wire) / 2
+ self.dump_header(f, self.rdlen)
+ f.write('# NS name=%s\n' % (self.nsname))
+ f.write('%s\n' % nsname_wire)
+
class SOA:
# this currently doesn't support name compression within the RDATA.
rdlen = -1 # auto-calculate
@@ -432,12 +500,7 @@ class RRSIG:
f.write('# Tag=%d Signer=%s and Signature\n' % (self.tag, self.signer))
f.write('%04x %s %s\n' % (self.tag, name_wire, sig_wire))
-class TSIG:
- as_rr = False
- rr_name = 'example.com' # only when as_rr is True, same for class/TTL
- rr_class = 'ANY'
- rr_ttl = 0
-
+class TSIG(RR):
rdlen = None # auto-calculate
algorithm = 'hmac-sha256'
time_signed = 1286978795 # arbitrarily chosen default
@@ -449,12 +512,17 @@ class TSIG:
other_len = None # 6 if error is BADTIME; otherwise 0
other_data = None # use time_signed + fudge + 1 for BADTIME
dict_macsize = { 'hmac-md5' : 16, 'hmac-sha1' : 20, 'hmac-sha256' : 32 }
+
+ # TSIG has some special defaults
+ def __init__(self):
+ self.rr_class = 'ANY'
+ self.rr_ttl = 0
+
def dump(self, f):
if str(self.algorithm) == 'hmac-md5':
name_wire = encode_name('hmac-md5.sig-alg.reg.int')
else:
name_wire = encode_name(self.algorithm)
- rdlen = self.rdlen
mac_size = self.mac_size
if mac_size is None:
if self.algorithm in self.dict_macsize.keys():
@@ -473,20 +541,10 @@ class TSIG:
if self.error == 18 else ''
else:
other_data = encode_string(self.other_data, other_len)
- if rdlen is None:
- rdlen = int(len(name_wire) / 2 + 16 + len(mac) / 2 + \
- len(other_data) / 2)
- if self.as_rr:
- rrclass = parse_value(self.rr_class, dict_rrclass)
- f.write('\n# TSIG RR (QNAME=%s Class=%s TTL=%d RDLEN=%d)\n' %
- (self.rr_name, code_totext(rrclass, rdict_rrclass),
- self.rr_ttl, rdlen))
- f.write('%s %04x %04x %08x %04x\n' %
- (encode_name(self.rr_name), dict_rrtype['tsig'],
- rrclass, self.rr_ttl, rdlen))
- else:
- f.write('\n# TSIG RDATA (RDLEN=%d)\n' % rdlen)
- f.write('%04x\n' % rdlen);
+ if self.rdlen is None:
+ self.rdlen = int(len(name_wire) / 2 + 16 + len(mac) / 2 + \
+ len(other_data) / 2)
+ self.dump_header(f, self.rdlen)
f.write('# Algorithm=%s Time-Signed=%d Fudge=%d\n' %
(self.algorithm, self.time_signed, self.fudge))
f.write('%s %012x %04x\n' % (name_wire, self.time_signed, self.fudge))
@@ -502,7 +560,8 @@ def get_config_param(section):
config_param = {'name' : (Name, {}),
'header' : (DNSHeader, header_xtables),
'question' : (DNSQuestion, question_xtables),
- 'edns' : (EDNS, {}), 'soa' : (SOA, {}), 'txt' : (TXT, {}),
+ 'edns' : (EDNS, {}), 'a' : (A, {}), 'ns' : (NS, {}),
+ 'soa' : (SOA, {}), 'txt' : (TXT, {}),
'rp' : (RP, {}), 'rrsig' : (RRSIG, {}),
'nsec' : (NSEC, {}), 'nsec3' : (NSEC3, {}),
'tsig' : (TSIG, {}) }