Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 46 additions & 16 deletions modules/network/dns/moddnsparser.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ static void *getQuestionByIndex(xsMachine *the, uint8_t index)
position += 12;
while (index--) {
while (true) {
uint8_t tag = *position++;
uint8_t tag;
if (position >= packetEnd)
return NULL;
tag = *position++;
if (0 == tag)
break;
if (0xC0 == (tag & 0xC0)) {
Expand Down Expand Up @@ -85,7 +88,10 @@ static void *getAnswerByIndex(xsMachine *the, uint8_t index)
uint16_t rdlength;

while (true) {
uint8_t tag = *position++;
uint8_t tag;
if (position >= packetEnd)
return NULL;
tag = *position++;
if (0 == tag)
break;
if (0xC0 == (tag & 0xC0)) {
Expand All @@ -109,35 +115,45 @@ static void *getAnswerByIndex(xsMachine *the, uint8_t index)

static int parseQname(xsMachine *the, int offset)
{
uint8_t *position;
uint8_t *position, *packetEnd;
uint8_t *packet = getPacket(the, &packetEnd);
int qnameEndPosition = 0;

xsVar(1) = xsNewArray(0);
position = offset + (uint8_t *)getPacket(the, NULL);;
position = offset + packet;
while (true) {
char tmp[64];
uint8_t tag = *position++;
uint8_t tag;
if (position >= packetEnd)
xsUnknownError("bad name");
tag = *position++;
offset += 1;
if (0 == tag) {
if (0 == qnameEndPosition)
qnameEndPosition = offset;
break;
}
if (0xC0 == (tag & 0xC0)) {
if (position >= packetEnd)
xsUnknownError("bad name");
if (0 == qnameEndPosition)
qnameEndPosition = offset + 1;
offset = ((tag << 8) | *position) & 0x3FFF; //@@ range check
position = offset + (uint8_t *)getPacket(the, NULL);
offset = ((tag << 8) | *position) & 0x3FFF;
if (offset >= packetEnd - packet)
xsUnknownError("bad name");
position = offset + packet;
continue;
}

if (tag > 63)
xsUnknownError("bad name");
if (position + tag > packetEnd)
xsUnknownError("bad name");
c_memcpy(tmp, position, tag);
xsmcSetStringBuffer(xsVar(2), tmp, tag);
xsCall1(xsVar(1), xsID_push, xsVar(2));
offset += tag;
position = offset + (uint8_t *)getPacket(the, NULL);
position = offset + packet;
}

return qnameEndPosition;
Expand All @@ -148,13 +164,15 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans
int offset;
uint16_t qtype, qclass;
char tmp[256];
uint8_t *packet, *packetEnd;

if (NULL == position) {
xsmcSetNull(xsResult);
return;
}

offset = position - (uint8_t *)getPacket(the, NULL);
packet = getPacket(the, &packetEnd);
offset = position - packet;

xsmcVars(4);

Expand All @@ -163,8 +181,10 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans
offset = parseQname(the, offset);
xsmcSet(xsVar(0), xsID_qname, xsVar(1));

position = offset + (uint8_t *)getPacket(the, NULL);
position = offset + packet;

if (position + 4 > packetEnd)
xsUnknownError("bad name");
qtype = (position[0] << 8) | position[1];
qclass = (position[2] << 8) | position[3];
position += 4;
Expand All @@ -174,16 +194,22 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans
uint32_t ttl;
uint16_t rdlength;

if (position + 6 > packetEnd)
xsUnknownError("bad name");
ttl = (position[0] << 24) | (position[1] << 16) | (position[2] << 8) | position[3];
rdlength = (position[4] << 8) | position[5];

position += 6;
offset += 6;

if (position + rdlength > packetEnd)
xsUnknownError("bad name");
if (rdlength) {
if (0x0001 == qtype) { // A
uint8_t ip[4];
char *out;
if (position + 4 > packetEnd)
xsUnknownError("bad name");
c_memcpy(ip, position, 4);
xsVar(1) = xsStringBuffer(NULL, 4 * 5);
out = xsmcToString(xsVar(1));
Expand Down Expand Up @@ -223,9 +249,12 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans
else
#endif
if (0x0021 == qtype) { // SRV
uint16_t priority = (position[0] << 8) | position[1];
uint16_t weight = (position[2] << 8) | position[3];
uint16_t port = (position[4] << 8) | position[5];
uint16_t priority, weight, port;
if (position + 6 > packetEnd)
xsUnknownError("bad name");
priority = (position[0] << 8) | position[1];
weight = (position[2] << 8) | position[3];
port = (position[4] << 8) | position[5];
offset += 6;

xsVar(3) = xsNewObject();
Expand All @@ -246,10 +275,11 @@ static void parseQuestionOrAnswer(xsMachine *the, uint8_t *position, uint8_t ans
xsVar(1) = xsNewArray(0);
position = offset + (uint8_t *)getPacket(the, NULL);
while (rdlength > 1) {
uint8_t tag;
uint8_t tag = *position++;

tag = *position++;
offset += tag + 1; //@@ bounds check range
if (tag + 1 > rdlength)
break;
offset += tag + 1;
rdlength -= tag + 1;
c_memcpy(tmp, position, tag);
xsmcSetStringBuffer(xsVar(2), tmp, tag);
Expand Down