in reply to How to create DNS packet
So, a DNS message takes the form:
+---------------------+
| Header |
+---------------------+
| Question | the question for the name server
+---------------------+
| Answer | RRs answering the question
+---------------------+
| Authority | RRs pointing toward an authority
+---------------------+
| Additional | RRs holding additional information
+---------------------+
where the header is:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
which is 6 network order 16 bit values (the pack/unpack code for those is 'n'). You're constructing a query, so you'll have at least one Question Section, which takes the form:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where the name is a sequence of labels, each of which is a length byte followed by the label characters, terminated by a zero length byte. You'll want to look at the pack/unpack 'C/a*' and a plain 'C' to terminate.
You appear to almost have that -- where you append "C a* " to your $lformat you want "C/a*". Or you could try:
my @labels = split(/\./, $hostname) ; my $n = scalar(@labels) ; my $question = pack("(C/a*)$n C n2", @labels, 0, 1, 1) ;
For some reason the DNS RFC numbers the bits with '0' being the MS bit (!).
Unpacking the responses is moderately straightforward, once you get over the name handling. Watch out for the message compression stuff -- the length byte in front of a label can only have a value in the range 0x00..0x3F, any length byte >= 0xC0 is the first byte of a two byte offset, pointing somewhere else in the packet for the rest of the name -- note that this is a "jump" not a "call".
It's a lot of fun !
|
|---|