Skip to content

Commit

Permalink
DNS-SD, debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
veniware committed Aug 10, 2024
1 parent 726f3d6 commit ac7699e
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 49 deletions.
26 changes: 13 additions & 13 deletions Protest/Front/hexviewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ class HexViewer extends Window {
}

hex.onmouseenter = char.onmouseenter = ()=>{
hex.style.boxShadow = char.style.boxShadow = "#808080 0 0 0 1px inset";
hex.style.boxShadow = char.style.boxShadow = "#000 0 0 0 2px inset";
this.details.textContent = `0x${j.toString(16).padStart(4, "0")}`;
};

Expand Down Expand Up @@ -676,7 +676,7 @@ class HexViewer extends Window {
this.PopulateLabel(`Questions counter: ${qCount}`, 0, hexContainer, charContainer, 4, 2);

const anCount = stream[index][6] << 8 | stream[index][7];
this.PopulateLabel(`Answers counter: ${anCount}`, 0, hexContainer, charContainer, 6, 2);
this.PopulateLabel(`Answers counter: ${anCount}`, 0, hexContainer, charContainer, 6, 2);

const auCount = stream[index][8] << 8 | stream[index][9];
this.PopulateLabel(`Authority RRs: ${auCount}`, 0, hexContainer, charContainer, 8, 2);
Expand All @@ -686,17 +686,17 @@ class HexViewer extends Window {

let offset = 12;
let count = 0;
while (offset < stream.length && count < qCount + anCount + auCount + adCount) { //answers
while (offset < stream[index].length && count < qCount + anCount + auCount + adCount) {
let start = offset;
let end = offset;

switch (stream[offset]) {
switch (stream[index][offset]) {
case 0xc0: //pointer
end += 2;
break;

default:
while (end < stream.length && stream[end] !== 0) {
while (end < stream[index].length && stream[index][end] !== 0) {
end++;
}
break;
Expand All @@ -706,27 +706,27 @@ class HexViewer extends Window {

offset = end + 1;

let type = (stream[offset] << 8) | stream[offset+1];
let type = (stream[index][offset] << 8) | stream[index][offset+1];
this.PopulateLabel(`Type: ${type} ${HexViewer.dnsRecordTypes[type] ? `(${HexViewer.dnsRecordTypes[type]})` : ""}`, 1, hexContainer, charContainer, offset, 2);
offset += 2;

let class_ = (stream[offset] << 8) | stream[offset+1];
let class_ = (stream[index][offset] << 8) | stream[index][offset+1];
this.PopulateLabel(`Class: ${class_} ${HexViewer.dnsClasses[class_] ? `(${HexViewer.dnsClasses[class_]})` : ""}`, 1, hexContainer, charContainer, offset, 2);
offset += 2;

let ttl = (stream[offset] << 24) | (stream[offset+1] << 16) | (stream[offset+2] << 8) | stream[offset+3];
let ttl = (stream[index][offset] << 24) | (stream[index][offset+1] << 16) | (stream[index][offset+2] << 8) | stream[index][offset+3];
this.PopulateLabel(`TTL: ${ttl}`, 1, hexContainer, charContainer, offset, 4);
offset += 4;

let len = (stream[offset] << 8) | stream[offset+1];
let len = (stream[index][offset] << 8) | stream[index][offset+1];
this.PopulateLabel(`Length: ${len}`, 1, hexContainer, charContainer, offset, 2);
offset += 2;

let data;
switch (type) {
case 1: //A
if (len === 4) {
data = `${stream[offset]}.${stream[offset+1]}.${stream[offset+2]}.${stream[offset+3]}`;
data = `${stream[index][offset]}.${stream[index][offset+1]}.${stream[index][offset+2]}.${stream[index][offset+3]}`;
this.PopulateLabel(data, 1, hexContainer, charContainer, offset, len);
}
break;
Expand All @@ -736,8 +736,8 @@ class HexViewer extends Window {
data = "";
for (let j = 0; j < 16; j+=2) {
if (j > 0) data += ":";
data += stream[offset + j].toString(16).padStart(2, "0");
data += stream[offset + j + 1].toString(16).padStart(2, "0");
data += stream[index][offset + j].toString(16).padStart(2, "0");
data += stream[index][offset + j + 1].toString(16).padStart(2, "0");
}
this.PopulateLabel(data, 1, hexContainer, charContainer, offset, len);
}
Expand Down
101 changes: 65 additions & 36 deletions Protest/Protocols/Mdns.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ private struct Answer {
public RecordType type;
public int ttl;
public ushort length;
public byte[] name;
public string nameString;
public byte[] data;
public string questionString;
public string answerString;
public bool isAuthoritative;
public bool isAdditional;
public byte error;
Expand Down Expand Up @@ -122,14 +123,14 @@ public static byte[] Resolve(string queryString, int timeout = 2000, RecordType
List<byte[]> matchingData = new List<byte[]>();
List<Answer> answers = new List<Answer>();

try {
/*try*/ {
foreach (byte[] response in receivedData) {
ushort answerCount, authorityCount, additionalCount;
Answer[] answer = DeconstructResponse(response, type, out answerCount, out authorityCount, out additionalCount);
bool matched = false;
for (int i = 0; i < answer.Length; i++) {
if (type != RecordType.ANY && answer[i].type != type) { continue; }
if (!answer[i].nameString.Equals(queryString, StringComparison.OrdinalIgnoreCase)) { continue; }
if (!answer[i].questionString.Equals(queryString, StringComparison.OrdinalIgnoreCase)) { continue; }

answers.Add(answer[i]);
if (!matched) {
Expand All @@ -139,9 +140,9 @@ public static byte[] Resolve(string queryString, int timeout = 2000, RecordType
}
}
}
catch {
/*catch {
return "{\"error\":\"unknown error\",\"errorcode\":\"0\"}"u8.ToArray();
}
}*/

return Serialize(query, matchingData, answers);
}
Expand Down Expand Up @@ -202,13 +203,7 @@ private static byte[] ConstructQuery(string queryString, RecordType type) {
return query;
}

private static Answer[] DeconstructResponse(
byte[] response,
RecordType queryType,
out ushort answerCount,
out ushort authorityCount,
out ushort additionalCount) {

private static Answer[] DeconstructResponse(byte[] response, RecordType queryType, out ushort answerCount, out ushort authorityCount, out ushort additionalCount) {
if (response.Length < 12) {
answerCount = 0;
authorityCount = 0;
Expand All @@ -230,7 +225,7 @@ private static Answer[] DeconstructResponse(

int index = 12;

for (int i = 0; i < questionCount; i++) { //skip questions
for (int i = 0; i < questionCount; i++) { //skip questions section
while (index < response.Length) {
byte len = response[index++];
if (len == 0) break;
Expand All @@ -250,17 +245,18 @@ private static Answer[] DeconstructResponse(

int nameStartIndex = index;

if ((response[index] & 0xFF) == 0xC0) {
if ((response[index] & 0xFF) == 0xC0) { //pointer
index += 2;
}
else {
while (index + 1 < response.Length && response[index] != 0) {
while (index < response.Length && response[index] != 0) {
index += response[index] + 1;
}
index++;
index++; //null-termination byte
}

if (index >= response.Length) {
if (index + 10 > response.Length) {
ans.error = 254;
break;
}

Expand All @@ -275,22 +271,55 @@ private static Answer[] DeconstructResponse(
ans.length = (ushort)((response[index] << 8) | response[index + 1]);
index += 2;

if (ans.type == RecordType.MX) {
ans.length -= 2;
index += 2; //skip preference



switch (ans.type) {
case RecordType.A:
if (ans.length == 4 && index + 4 <= response.Length) {
ans.answerString = $"{response[index]}.{response[index + 1]}.{response[index + 2]}.{response[index + 3]}";
index += 4;
}
break;

case RecordType.AAAA:
if (ans.length == 16 && index + 16 <= response.Length) {
ans.answerString = string.Join(":", Enumerable.Range(0, 8)
.Select(j => ((response[index + 2 * j] << 8) | response[index + 2 * j + 1]).ToString("x4")));
index += 16;
}
break;

case RecordType.MX:
if (index + 2 <= response.Length) {
//preference = (ushort)((response[index] << 8) | response[index + 1]);
index += 2;
ans.answerString = ExtractName(response, index);
}
break;

case RecordType.CNAME:
case RecordType.NS:
case RecordType.PTR:
ans.answerString = ExtractName(response, index);
break;

default:
ans.answerString = String.Empty; //BitConverter.ToString(response, index, ans.length);
index += ans.length;
break;
}

if (ans.length > response.Length - index) {
ans.error = 254;
break;
}
ans.name = new byte[ans.length];
Array.Copy(response, index, ans.name, 0, ans.length);

ans.data = new byte[ans.length];
Array.Copy(response, index, ans.data, 0, ans.length);
index += ans.length;

//extract name from the response
string responseName = ExtractName(response, nameStartIndex);
ans.nameString = responseName;
ans.questionString = ExtractName(response, nameStartIndex);

if (i >= answerCount + authorityCount) {
ans.isAdditional = true;
Expand Down Expand Up @@ -387,42 +416,42 @@ private static byte[] Serialize(byte[] query, List<byte[]> data, List<Answer> an
switch (answers[i].type) {
case RecordType.A:
builder.Append("\"type\":\"A\",");
builder.Append($"\"name\":\"{String.Join(".", answers[i].name)}\",");
builder.Append($"\"name\":\"{String.Join(".", answers[i].data)}\",");
break;

case RecordType.NS:
builder.Append("\"type\":\"NS\",");
builder.Append($"\"name\":\"{answers[i].nameString}\",");
builder.Append($"\"name\":\"{answers[i].answerString}\",");
break;

case RecordType.CNAME:
builder.Append("\"type\":\"CNAME\",");
builder.Append($"\"name\":\"{answers[i].nameString}\",");
builder.Append($"\"name\":\"{answers[i].answerString}\",");
break;

case RecordType.SOA:
builder.Append("\"type\":\"SOA\",");
builder.Append($"\"name\":\"{answers[i].nameString}\",");
builder.Append($"\"name\":\"{answers[i].answerString}\",");
break;

case RecordType.PTR:
builder.Append("\"type\":\"PTR\",");
builder.Append($"\"name\":\"{answers[i].nameString}\",");
builder.Append($"\"name\":\"{answers[i].answerString}\",");
break;

case RecordType.MX:
builder.Append("\"type\":\"MX\",");
builder.Append($"\"name\":\"{answers[i].nameString}\",");
builder.Append($"\"name\":\"{answers[i].answerString}\",");
break;

case RecordType.TXT:
builder.Append("\"type\":\"TXT\",");
builder.Append($"\"name\":\"{answers[i].nameString}\",");
builder.Append($"\"name\":\"{answers[i].answerString}\",");
break;

case RecordType.AAAA:
builder.Append("\"type\":\"AAAA\",");
if (answers[i].name.Length != 16) {
if (answers[i].data.Length != 16) {
builder.Append($"\"name\":\"\"");
break;
}
Expand All @@ -431,7 +460,7 @@ private static byte[] Serialize(byte[] query, List<byte[]> data, List<Answer> an
for (int j = 0; j < 16; j += 2) {
if (j > 0)
builder.Append(':');
ushort word = (ushort)((answers[i].name[j] << 8) | answers[i].name[j + 1]);
ushort word = (ushort)((answers[i].data[j] << 8) | answers[i].data[j + 1]);
builder.Append(word.ToString("x4"));
}

Expand All @@ -440,7 +469,7 @@ private static byte[] Serialize(byte[] query, List<byte[]> data, List<Answer> an

case RecordType.SRV:
builder.Append("\"type\":\"SRV\",");
builder.Append($"\"name\":\"{String.Join(".", answers[i].name)}\",");
builder.Append($"\"name\":\"{String.Join(".", answers[i].data)}\",");
break;
}

Expand Down

0 comments on commit ac7699e

Please sign in to comment.