in reply to Parsing output from Nmap::Scanner with varying hash address.

Now we're talking my language... networking and network penetration testing :)

The return you get is definitely a reference to a hash, but it is a blessed() hash, meaning it is an object (aka instance of a class (package)).

Per the SYNOPSIS of perldoc Nmap::Scanner, we see that: $results is an instance of Nmap::Scanner::Backend::Results.

What you're doing to extract the parts of the return are typical for a hash, but if you can specify what exactly you're trying to do, it may help us sort out a different/better/cleaner way. For the most part, you want to use the object's methods to extract the data you need (if the class has the methods to do so) instead of opening the object up like a can of tuna. Not all classes have such methods available though (and if this one doesn't, I've found my module to work on) :)

You might be interested to read Nmap::Scanner::Backend::Results documentation and the rest of the sub-modules for methods that may allow you to extract the info you need using the object's built-ins. (Nmap::Scanner module listing).

Beyond that, again, state what it is you need out of the object.

-stevieb

Replies are listed 'Best First'.
Re^2: Parsing output from Nmap::Scanner with varying hash address.
by mopmeat (Initiate) on Jul 10, 2015 at 23:40 UTC

    For starters, I'd like to produce a simpler hash with a few key elements. Something like the following;

    ( 'smtp' => 'closed', 'http' => 'open', 'https' => 'open', )

    Right now I have the following and I'd like a more elegant/cleaner solution, if possible.

    my %shortlist; for my $key (keys $results->{'ALLHOSTS'}){ for my $key2 (keys $results->{'ALLHOSTS'}{$key}->{'ports'}->{' +tcp'}){ $shortlist{"$results->{'ALLHOSTS'}{$key}->{'ports'}->{'tcp +'}->{$key2}->{'service'}->{'name'}"} = $results->{'ALLHOSTS'}{$key}-> +{'ports'}->{'tcp'}->{$key2}->{'state'}; } }
      I do not know if this is cleaner or more elegant, but you could remove most of these -> dereferencing arrows (those between closing and opening curly braces), thereby making the syntax at least a bit shorter.

      Something like this should probably work (but is untested):

      my %shortlist; for my $key (keys $results->{'ALLHOSTS'}){ for my $key2 (keys $results->{'ALLHOSTS'}{$key}{'ports'}{'tcp'}){ $shortlist{"$results->{'ALLHOSTS'}{$key}{'ports'}{'tcp'}{$key2 +}{'service'}{'name'}"} = $results->{'ALLHOSTS'}{$key}{'ports'}{'tcp'} +{$key2}{'state'}; } }

        Removing most of the '->'s is a good idea. You could also remove 26 single-quotes (around all the literal key names) and a pair of double-quotes. Splitting the assignment over two lines gives a maximum line length of 80 characters (previously 156). I think that provides additional readability.

        my %shortlist; for my $key (keys $results->{ALLHOSTS}) { for my $key2 (keys $results->{ALLHOSTS}{$key}{ports}{tcp}) { $shortlist{$results->{ALLHOSTS}{$key}{ports}{tcp}{$key2}{servi +ce}{name}} = $results->{ALLHOSTS}{$key}{ports}{tcp}{$key2}{state}; } }

        [Note: as I'm editing untested code, mine is also untested.]

        Update: I've also added spaces before the opening braces of the for blocks: I think that makes those a little clearer.

        -- Ken