// Parse resource record: // - variable length name // - 16-bit RR type // - 16-bit RR class // - 32-bit TTL // - 16-bit resource data length in bytes // - variable length resource data function unpackResourceRecord(buf, offset) { var bytes = 0; // - variable length name var nbname = NBName.fromBuffer(buf, offset + bytes); if (nbname.error) { return {error: nbname.error}; } bytes += nbname.bytesRead; var record = {}; record.nbname = nbname; // - 16-bit RR type var t = buf.readUInt16BE(offset + bytes); bytes += 2; record.type = con.RR_TYPE_TO_STRING[t]; if (record.type === undefined) { return { error: new Error('Illegal resource record type [' + t + '] for name [' + nbname + ']') }; } var rdataParser = RR_TYPE_TO_PARSER[record.type]; // - 16-bit RR class var clazz = buf.readUInt16BE(offset + bytes); bytes += 2; if (clazz !== con.CLASS_IN) { return { error: new Error('Unexpected resource record class [' + clazz + '] for name [' + record.nbname + ']; expected class [' + con.CLASS_IN + '].') }; } // - 32-bit TTL record.ttl = buf.readUInt32BE(offset + bytes); bytes += 4; // - 16-bit resource data length in bytes var dataLen = buf.readUInt16BE(offset + bytes); bytes += 2; // - variable length resource data var res = rdataParser(buf, offset + bytes, dataLen, record); if (res.error) { return {error: res.error}; } bytes += res.bytesRead; return {bytesRead: bytes, record: record}; }
// Parse question section // - variable length compressed question name // - 16-bit question type // - 16-bit question class function unpackQuestion(buf, offset) { var bytes = 0; var question = {}; // - variable length compressed question name var nbname = NBName.fromBuffer(buf, offset + bytes); if (nbname.error) { return {error: nbname.error}; } question.nbname = nbname; bytes += nbname.bytesRead; // Ensure we have enough space left before proceeding to avoid throwing if (offset + bytes + 4 > buf.length) { return { error: new Error('Question section is too large to fit in remaining ' + 'packet bytes.') }; } // - 16-bit question type var t = buf.readUInt16BE(offset + bytes); bytes += 2; question.type = con.QUESTION_TYPE_TO_STRING[t]; if (question.type === undefined) { return { error: new Error('Unexpected question type [' + t + '] for name [' + question.nbname + ']; should be either [nb] or ' + '[nbstat]') }; } // - 16-bit question class var clazz = buf.readUInt16BE(offset + bytes); bytes += 2; if (clazz !== con.CLASS_IN) { return { error: new Error('Unexpected question class [' + clazz + '] for name [' + question.nbname + ']; should be [' + CLASS_IN + ']') }; } return {bytesRead: bytes, record: question}; }
function nsRDataParser(buf, offset, length, record) { var bytes = 0; var nbname = NBName.fromBuffer(buf, offset + bytes); if (nbname.error) { return {error: nbname.error}; } else if (length !== nbname.bytesRead) { return { error: new Expect('Unexpected NS record name length for record [' + record.nbname + '].') }; } bytes += nbname.bytesRead; record.ns = { nbname: nbname, }; return {bytesRead: bytes}; }