WIP Packer

This commit is contained in:
AJ ONeal 2017-02-16 15:52:07 -07:00
parent 12fef62e09
commit 28b607857e
7 changed files with 173 additions and 14 deletions

View File

@ -77,16 +77,6 @@ var dnspack = exports.DNS_PACKER = {
total += 4; // two bytes type two bytes class
}
function packRdata(a) {
dv.setUint16(total, 8, false);
total += 2;
dv.setUint32(total, 0xFFFFFFFF, false)
total += 4;
dv.setUint32(total, 0xFFFFFFFF, false)
total += 4;
//throw new Error('not implemented');
}
function packAnswer(a) {
packQuestion(a);
@ -107,7 +97,7 @@ var dnspack = exports.DNS_PACKER = {
total += 1;
});
} else {
packRdata(a);
dnspack.packRdata(ab, dv, total, a);
}
}
@ -148,5 +138,6 @@ var dnspack = exports.DNS_PACKER = {
}
};
dnspack.packRdata = exports.DNS_RDATA_PACK || require('./dns.rdata.pack.js').DNS_RDATA_PACK;
}('undefined' !== typeof window ? window : exports));

21
dns.packer.type.a.js Normal file
View File

@ -0,0 +1,21 @@
(function (exports) {
'use strict';
// An 'A' record is a 32-bit value representing the IP address
exports.DNS_PACKER_TYPE_A = function (ab, dv, total, record) {
if (!record.address) {
throw new Error("no address on A record");
}
// i.e. 127.0.0.1 => 0x7F, 0x00, 0x00, 0x01
//record.rdlength = 4;
record.address.split('.').forEach(function (octet) {
dv.setUint8(total, parseInt(octet, 10), false);
total += 1;
});
return total;
};
}('undefined' !== typeof window ? window : exports));

34
dns.packer.type.aaaa.js Normal file
View File

@ -0,0 +1,34 @@
(function (exports) {
'use strict';
// 'AAAA'
// Value: IP Address
// Meaning:Use: 16 octets (8 sexdectets, 128 bits) represting the IP address
exports.DNS_PACKER_TYPE_AAAA = function (ab, dv, total, record) {
if (!record.address) {
throw new Error("no address on A record");
}
// i.e. ::1 => 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001
// i.e. FFFF:DDDD::1 => 0xFFFF, 0xDDDD, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001
//record.rdlength = 16;
var address = '0' + record.address; // prevent case of two leading blanks, such as '::1'
var parts = address.split(':');
parts.forEach(function (sedectet, i) {
if (!sedectet) {
parts[i] = '0';
while (parts.length < 8) {
parts.splice(i + 1, 0, '0');
}
}
});
parts.forEach(function (sedectet) {
dv.setUint16(total, parseInt(sedectet, 16), false);
total += 2;
});
return total;
};
}('undefined' !== typeof window ? window : exports));

45
dns.rdata.pack.js Normal file
View File

@ -0,0 +1,45 @@
(function (exports) {
'use strict';
var classes = exports.DNS_CLASSES || require('./dns.classes.js').DNS_CLASSES;
var types = exports.DNS_TYPES || require('./dns.types.js').DNS_TYPES;
exports.DNS_RDATA_PACK = function (ab, dv, total, record) {
// ab is needed if the rdata makes use of compression pointers
// packet is given for convenience
var packer;
var className = classes[record.class];
var typeName = types[record.type];
if (!className) {
throw new Error("Support for DNS Class 0x" + record.class.toString(16) + " (" + record.class + ")"
+ " is not implemented yet. Open an issue if you actually need support"
+ " (i.e. you're not working with a malformed packet)"
);
}
if (!typeName) {
throw new Error("Support for DNS Type 0x" + record.type.toString(16) + " (" + record.type + ")"
+ " is not implemented yet. Open an issue if you actually need support"
+ " (i.e. you're not working with a malformed packet)"
);
}
try {
packer = exports['DNS_PACKER_TYPE_' + typeName]
|| require('./dns.packer.type.' + typeName.toLowerCase())['DNS_PACKER_TYPE_' + typeName];
}
catch (e) { /*console.error(e)*/ }
if (!packer) {
throw new Error("Packer for DNS Type " + typeName + " could not be loaded."
+ " Did you include <script src=\"dns.packer.type." + typeName.toLowerCase() + ".js\"></script> ?"
+ " (or perhaps we plan to implement it and haven't yet - in which case please open an issue)"
);
}
return packer(ab, dv, total, record);
};
}('undefined' !== typeof window ? window : exports));

View File

@ -1,9 +1,6 @@
(function (exports) {
'use strict';
var classes = exports.DNS_CLASSES || require('./dns.classes.js').DNS_CLASSES;
var types = exports.DNS_TYPES || require('./dns.types.js').DNS_TYPES;
exports.DNS_RDATA_PARSE = function (ab, packet, record) {
// ab is needed if the rdata makes use of compression pointers
// packet is given for convenience

30
test/packer.type.a.js Normal file
View File

@ -0,0 +1,30 @@
'use strict';
var packer = require('../dns.packer.type.a.js').DNS_PACKER_TYPE_A;
var ab = new ArrayBuffer(4);
var dv = new DataView(ab);
var total;
// just to see that bytes are changed as a marker
dv.setUint32(0x0, 0xDDDDDDDD, false);
[ '0.0.0.0'
, '127.0.0.1'
, '192.168.1.100'
, '216.21.170.44'
, '255.255.255.255'
].forEach(function (ipv4) {
total = 0;
total = packer(ab, dv, total, { address: ipv4 });
if (0x04 !== total) {
console.error('unexpected total ' + total);
process.exit(1);
}
if (ipv4 !== new Uint8Array(ab).join('.')) {
console.error("expected: ", ipv4);
console.error("actual: ", new Uint8Array(ab).join('.'));
process.exit(1);
}
});
console.log('PASS');

41
test/packer.type.aaaa.js Normal file
View File

@ -0,0 +1,41 @@
'use strict';
var packer = require('../dns.packer.type.aaaa.js').DNS_PACKER_TYPE_AAAA;
var ab = new ArrayBuffer(20);
var dv = new DataView(ab);
var total = 0;
// just to see that bytes are changed as a marker
dv.setUint16(0x0, 0xDDDD, false);
dv.setUint16(0x2, 0xDDDD, false);
dv.setUint16(0x4, 0xDDDD, false);
dv.setUint16(0x6, 0xDDDD, false);
dv.setUint16(0x8, 0xDDDD, false);
dv.setUint16(0xA, 0xDDDD, false);
dv.setUint16(0xC, 0xDDDD, false);
dv.setUint16(0xE, 0xDDDD, false);
dv.setUint16(0x10, 0xDDDD, false);
dv.setUint16(0x12, 0xDDDD, false);
[ [ '::1'
, [ 0xDD, 0xDD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0xDD, 0xDD ].join(' ') ]
, [ 'fe80::1'
, [ 0xDD, 0xDD, 0xFE, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0xDD, 0xDD ].join(' ') ]
, [ 'fd41:50ca:2169:f4e:5020:f756:ca4e:c3b5'
, [ 0xDD, 0xDD, 0xFD, 0x41, 0x50, 0xCA, 0x21, 0x69, 0x0F, 0x4E
, 0x50, 0x20, 0xF7, 0x56, 0xCA, 0x4E, 0xC3, 0xB5, 0xDD, 0xDD ].join(' ') ]
].forEach(function (ipv6) {
total = 2; // leave leading 0x00
total = packer(ab, dv, total, { address: ipv6[0] });
if (0x12 !== total) {
console.error('unexpected total ' + total);
process.exit(1);
}
if (ipv6[1] !== new Uint8Array(ab).join(' ')) {
console.error("expected: ", ipv6[1]);
console.error("actual: ", new Uint8Array(ab).join(' '));
process.exit(1);
}
});
console.log('PASS');