1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include "dns.h"
int dns_parse_packet ( char* _buffer, int _bufflen, struct dns_message* _msg )
{
if ( !_buffer || !_bufflen || !_msg )
return 1; //Invalid input
if ( _bufflen < 12 )
return 1; //Too short to contain a DNS header
//TODO test
_msg->header.id = *( (uint16_t*) _buffer );
_msg->header.QR = ( 0x80 & *( (uint8_t*) (_buffer + 2)) ) >> 7;
_msg->header.OPCODE = (0x78 & *( (uint8_t*) (_buffer + 2))) >> 3;
_msg->header.AA = (0x04 & *( (uint8_t*) (_buffer + 2))) >> 2;
_msg->header.TC = (0x02 & *( (uint8_t*) (_buffer + 2))) >> 1;
_msg->header.RD = (0x01 & *( (uint8_t*) (_buffer + 2)));
_msg->header.RA = (0x80 & *( (uint8_t*) (_buffer + 3))) >> 7;
_msg->header.Z = (0x70 & *( (uint8_t*) (_buffer + 3))) >> 4;
_msg->header.RCODE = (0x0F & *( (uint8_t*) (_buffer + 3)));
_msg->header.question_count = (*((uint8_t*) (_buffer + 4)) << 8) | *((uint8_t*) (_buffer + 5));
_msg->header.answer_count = (*((uint8_t*) (_buffer + 6)) << 8) | *((uint8_t*) (_buffer + 7));
_msg->header.authorative_count = (*((uint8_t*) (_buffer + 8)) << 8) | *((uint8_t*) (_buffer + 9));
_msg->header.additional_count = (*((uint8_t*) (_buffer + 10)) << 8) | *((uint8_t*) (_buffer + 11));
printf("ANSWER %i\n", _msg->header.answer_count);
printf("QUESTI %i\n", _msg->header.question_count);
printf("AUTHOR %i\n", _msg->header.authorative_count);
printf("ADDITI %i\n", _msg->header.additional_count);
return 1;
}
int fqdn_to_qname( char* _source, int _sourcelen, char* _sink ,int _sinklen )
{
int i;
int lastdot = 0;
if (_sourcelen < 1 || _sinklen < 1)
return -1;
_sink[0] = ' '; //Set to known value
for(i = 0; ((i < _sourcelen) && (i < (_sinklen - 1))); i++) { //Copy offset 1
if(! _source[i])
break;
_sink[i+1] = _source[i];
}
if( _source[i] ) // _source not terminated, thus no valid string
return -1;
for (int o = 0; o < i; o++) {
if( _sink[o] == '.') {
_sink[lastdot] = o - lastdot - 1;
lastdot = o;
}
}
_sink[lastdot] = i - lastdot;
_sink[i + 1] = 0;
return i+2;
}
int qname_to_fqdn( char* _source, int _sourcelen, char* _sink, int _sinklen )
{
if ( !_sourcelen || !_sinklen ) {
return -1;
}
unsigned int next_dot = _source[0] + 1;
int i = 1;
for(i = 1; i < _sourcelen; i++) {
if( i > _sinklen){ //Output too small. Not >= bc sink[i-1] is used
return -1;
}
if ( !_source[i] ) {
_sink[i-1] = '\0';
break;
} else if (i == next_dot) {
_sink[i-1]='.';
next_dot = _source[i] + i + 1;
} else {
_sink[i-1] = _source[i];
}
}
return i-1;
}
|