diff --git a/index.js b/index.js index 72f9346..aeab452 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,6 @@ var types = require('./types') var rcodes = require('./rcodes') +var opcodes = require('./opcodes') var ip = require('ip') var Buffer = require('safe-buffer').Buffer @@ -128,7 +129,7 @@ header.decode = function (buf, offset) { type: flags & RESPONSE_FLAG ? 'response' : 'query', flags: flags & 32767, flag_qr: ((flags >> 15) & 0x1) === 1, - opcode: (flags >> 11) & 0xf, + opcode: opcodes.toString((flags >> 11) & 0xf), flag_auth: ((flags >> 10) & 0x1) === 1, flag_trunc: ((flags >> 9) & 0x1) === 1, flag_rd: ((flags >> 8) & 0x1) === 1, diff --git a/opcodes.js b/opcodes.js new file mode 100644 index 0000000..6b42db3 --- /dev/null +++ b/opcodes.js @@ -0,0 +1,48 @@ +/* + * Traditional DNS header OPCODEs (4-bits) defined by IANA in + * https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-5 + */ + +exports.toString = function (opcode) { + switch (opcode) { + case 0: return 'QUERY' + case 1: return 'IQUERY' + case 2: return 'STATUS' + case 3: return 'OPCODE_3' + case 4: return 'NOTIFY' + case 5: return 'UPDATE' + case 6: return 'OPCODE_6' + case 7: return 'OPCODE_7' + case 8: return 'OPCODE_8' + case 9: return 'OPCODE_9' + case 10: return 'OPCODE_10' + case 11: return 'OPCODE_11' + case 12: return 'OPCODE_12' + case 13: return 'OPCODE_13' + case 14: return 'OPCODE_14' + case 15: return 'OPCODE_15' + } + return 'OPCODE_' + opcode +} + +exports.toOpcode = function (code) { + switch (code.toUpperCase()) { + case 'QUERY': return 0 + case 'IQUERY': return 1 + case 'STATUS': return 2 + case 'OPCODE_3': return 3 + case 'NOTIFY': return 4 + case 'UPDATE': return 5 + case 'OPCODE_6': return 6 + case 'OPCODE_7': return 7 + case 'OPCODE_8': return 8 + case 'OPCODE_9': return 9 + case 'OPCODE_10': return 10 + case 'OPCODE_11': return 11 + case 'OPCODE_12': return 12 + case 'OPCODE_13': return 13 + case 'OPCODE_14': return 14 + case 'OPCODE_15': return 15 + } + return 0 +} diff --git a/package.json b/package.json index a0acdc4..5f646d3 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "files": [ "index.js", "types.js", - "rcodes.js" + "rcodes.js", + "opcodes.js" ], "author": "Mathias Buus", "license": "MIT" diff --git a/test.js b/test.js index 996acad..fad0ddc 100644 --- a/test.js +++ b/test.js @@ -1,6 +1,7 @@ var tape = require('tape') var packet = require('./') var rcodes = require('./rcodes') +var opcodes = require('./opcodes') var Buffer = require('safe-buffer').Buffer tape('unknown', function (t) { @@ -181,6 +182,12 @@ tape('rcode', function (t) { t.ok(errors[i] === rcodes.toString(code), 'rcode conversion from/to string matches: ' + rcodes.toString(code)) } + const ops = ['QUERY', 'IQUERY', 'STATUS', 'OPCODE_3', 'NOTIFY', 'UPDATE', 'OPCODE_6', 'OPCODE_7', 'OPCODE_8', 'OPCODE_9', 'OPCODE_10', 'OPCODE_11', 'OPCODE_12', 'OPCODE_13', 'OPCODE_14', 'OPCODE_15'] + for (i in ops) { + code = opcodes.toOpcode(ops[i]) + t.ok(ops[i] === opcodes.toString(code), 'opcode conversion from/to string matches: ' + opcodes.toString(code)) + } + var buf = packet.encode({ type: 'response', id: 45632, @@ -193,7 +200,7 @@ tape('rcode', function (t) { }) var val = packet.decode(buf) t.ok(val.type === 'response', 'decode type') - t.ok(val.opcode === 0, 'decode opcode') + t.ok(val.opcode === 'QUERY', 'decode opcode') t.ok(val.flag_qr === true, 'decode flag_auth') t.ok(val.flag_auth === true, 'decode flag_auth') t.ok(val.flag_trunc === false, 'decode flag_trunc')