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

I would like to convert a blob holding ip address(es) (it's the dnsrecord attribute of the MS AD ldap dnsnode objectclass.

It looks like this (ldif format):

dnsRecord:: BAABAAXwAACkAAAAAAABLAAAAAAAAAAArBQEKA==

This is the format of the dnsRecord string: https://msdn.microsoft.com/en-us/library/ee898781.aspx

I am really not a Perl guru, so I would really appreciate some handholding ;-) with unpacking this. Any help greatly appreciated. I will look into perlpacktut but I am a bit over my head with it right now.

update: I have tried this:

my $blob = "BAABAAXwAACGAAAAAAABLAAAAAAAAAAArBQEKA=="; my ( $dataLength, # 2 bytes $type, # 2 bytes $version, # 1 byte $rank, # 1 byte $flags, # 2 bytes $serial, # 4 bytes $ttl, # 4 bytes $reserved, # 4 bytes $timestamp, # 4 bytes $data ) = unpack( 'S S C C S L N L L a*', $blob ); print $dataLength, "\n"; print "$type\n"; print "$version\n"; print "$rank\n"; print "$flags\n"; print "$serial\n"; print "$ttl\n"; print "$reserved\n"; print "$timestamp\n"; print "$data\n"; $ perl /tmp/kkk.pl 16706 16961 65 65 30552 1195589953 1094795585 1111572801 1094795596 AAAAAAAArBQEKA==
Obviously not what I expected.

Thanks in advance.

Replies are listed 'Best First'.
Re: unpack blob
by VinsWorldcom (Prior) on Jan 12, 2016 at 22:07 UTC

    I think you data is base64 encoded. Try decoding it first:

    use Socket; my $out = `echo BAABAAXwAACkAAAAAAABLAAAAAAAAAAArBQEKA==|base64 -d`; print (unpack "H*", $out); print "\n"; print substr ((unpack "H*", $out), -8); print "\n"; print inet_ntoa(substr $out, -4);

    and output

    VinsWorldcom@C:\Users\VinsWorldcom\tmp> test.pl 0400010005f00000a40000000000012c0000000000000000ac140428 ac140428 172.20.4.40
      Instead of qx, echo and base64, you can use MIME::Base64 (in core since 5.8) and its decode_base64 function.
      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        Obviously a better solution than my backticks and base64 system command. A quick Google turned up Mime::Base64 for base64 in Perl, I did *not* go a step further to see if it was in core and I knew it would not be CPAN module I had downloaded so didn't even try, assumed I didn't have it and rolled something quick.

        Thanks for the tip! Next time I'll check 'corelist' before backtick-ing out.

      We got a winner!

      I need to read it a bit more carefully to understand what you just did, but it works ;-)

      Thanks!

        Combining all the responses:

        #!perl use strict; use warnings; use Socket; use MIME::Base64; # in core, thanks choroba my $blob = "BAABAAXwAACGAAAAAAABLAAAAAAAAAAArBQEKA=="; $blob = decode_base64($blob); my ( $dataLength, # 2 bytes $type, # 2 bytes $version, # 1 byte $rank, # 1 byte $flags, # 2 bytes $serial, # 4 bytes $ttl, # 4 bytes $reserved, # 4 bytes $timestamp, # 4 bytes $data ) = unpack( 'S S C C S L N L L a*', $blob ); # http://www.perlmonks.org/?node_id=1152688 see Tux comment print $dataLength, "\n"; print "$type\n"; print "$version\n"; print "$rank\n"; print "$flags\n"; print "$serial\n"; print "$ttl\n"; print "$reserved\n"; print "$timestamp\n"; print inet_ntoa($data) . "\n";
Re: unpack blob
by 1nickt (Canon) on Jan 12, 2016 at 22:06 UTC

    Edit: See this answer.

    Try double quotes:
    unpack( "S S C C S L N L L a*", $blob );
    The way forward always starts with a minimal test.
      hi, thanks, unfortunately same result.