Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

How to create a DNS message in perl?

by sanjay nayak (Sexton)
on Jul 29, 2008 at 07:55 UTC ( [id://700743]=perlquestion: print w/replies, xml ) Need Help??

sanjay nayak has asked for the wisdom of the Perl Monks concerning the following question:


I am writing a code as follows
$ID= 1; #2 octets $flags = 0; #(For Request value is 0)#2 octets $QDCOUNT=1; #2 octets $ANCOUNT=0;#2 octets $NSCOUNT=0;#2 octets $ARCOUNT=0;#2 octets $QNAME= "www.google.com";#16 octets $QTYPE=23; #(For NAPTR)#2 octets $QCLASS=1; #(For IN)#2 octet my $DNS_Request= "$ID$flags$QDCOUNT$ANCOUNT$NSCOUNT$ARCOUNT$QNAME$QTYP +E$QCLASS"; $MySocket->send($DNS_Request);

Here the problem is that Suppose i am assigning the value $ID=1. How can can i convert it into the hexa value of 2 octets which is '0001' and so for other values with their respective octets.

The $QNAME = "www.google.com". How can i convert it into the hexa value '0377777706676F6F676C6503636F6D00'.

So that Wire shark will decoded it properly without showing malformed packet.

The problem is that if i am sending the $QNAME value diretly (That means without converting into the hexa format). The wireshark decoded it as '7777772e676F6F676C652e636F6D'.Which shows it as a malformed packet.

Plz suggest me a suitable code. So that i can send a DNS request properly.

Regd's
Sanjay

Replies are listed 'Best First'.
Re: How to create a DNS message in perl?
by ikegami (Patriarch) on Jul 29, 2008 at 08:23 UTC

    How can can i convert it into the hexa value of 2 octets which is '0001'

    pack. Specifically, pack('n', 1).

    The $QNAME = "www.google.com". How can i convert it into the hexa value '0377777706676F6F676C6503636F6D00'.

    Each segment of the domain is passed as a byte indicating the length of the string followed by the string itself. The whole is ended with a NUL byte (pack('C', 0) or "\x00").

    0377777706676F6F676C6503636F6D00 03 777777 3 www 06 676F6F676C65 6 google 03 636F6D 3 com 00 0

    Update: Fixed with better understanding.


      Hi Ikegami

      Thanks for reply.

      pack('n',1) encodes the data as '0001'. But how can can i convert $QTYPE=23 to the hexa value of 2 octets which is '0023'. If i use pack('n', 23) then it enocdes it as '0017'. Plz suggest.

      The second thing is that I am extracting the domain name from the Req URI of a SIP message received. By using which i am sending the DNS request.Suppose sometimes i am getting 'www.google.com' ,

      sometimes i am getting 'www.yahoo.com' or anything else in the SIP message which is not fixed. So is there any function in perl which directly convert the domain name into the required hexa format so that wireshark will decode it properly without doing any manual countings of characters in each segment of the domain name.

      Actually what i am wanting is as follows. I am getting the domain as 'www.google.com'. After putting it in the argument in any perl function it converts it into the '0377777706676F6F676C6503636F6D00' without doing any further things. So that i can use that variable along with other variables while sending the DNS request.Plz suggest

      Regd's
      Sanjay

        But how can can i convert $QTYPE=23 to the hexa value of 2 octets which is '0023'

        Wrong question.

        You need to learn how to store 2316 into $QTYPE. Right now, you are storing 2310, a completely different number.

        $QTYPE = 0x23; # 35

        If you're starting with a string, you can use hex or oct.

        $QTYPE = hex('23'); # 35 $QTYPE = oct('0x23'); # 35

        So is there any function in perl which directly convert the domain name into the required hexa format

        There's no builtin function. I've specified the format (from which a solution is easily derived using split, length, and pack 'C') in an earlier post. Furthermore, someone gave you the name of a module that supposedly does the work for you.

Re: How to create a DNS message in perl?
by moritz (Cardinal) on Jul 29, 2008 at 09:17 UTC
    If you don't want to reinvent the wheel, look at Net::DNS, and perhaps gethostbyname in very simple cases.
Re: How to create a DNS message in perl?
by busunsl (Vicar) on Jul 29, 2008 at 08:10 UTC
    Use the unpack funtion to convert the name to hex:

    $QNAME = unpack("H*", "www.google.com")

    For more read:

    perldoc -f unpack
    and
    perldoc -f pack

Re: How to create a DNS message in perl?
by broomduster (Priest) on Jul 29, 2008 at 08:53 UTC
    You are not encoding $QNAME correctly. Each segment of the host name (i.e., 'www', 'google', and 'com' here) must be preceded by the character length of the segment and the whole thing terminated by a null byte; and you drop the dots (not needed, as the length bytes tell their positions). See http://www.tcpipguide.com/free/t_DNSNameNotationandMessageCompressionTechnique.htm

    So in your case, you need something like

    $QNAME="\03www\06google\03com\00;"

    Note that this matches what you see in wireshark if you run a DNS query from the command line and look at the hex dump of the packet (especially note the presence and values of the length bytes).

    Updated:Add note to pay attention to the length bytes in wireshark dump.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://700743]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-24 15:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found