1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-07 13:11:28 +00:00
Files
nmap/scripts/sort-prints.pl
2005-04-11 22:34:19 +00:00

129 lines
3.2 KiB
Perl
Executable File

#!/usr/bin/perl -w
sub usage() {
print STDERR "Usage: sort-prints.pl <nmap-os-fingerprints file>\n" .
"Slurps up the given nmap-os-fingerprints file, sorts it appropriately (Class, then name string), then spits it out to stdout. Some minor canonicalization is done too.\n\n";
exit(0);
}
sub fprintsort {
lc($a->{firstClass}) cmp lc($b->{firstClass})
or
lc($a->{name}) cmp lc($b->{name});
}
if ($#ARGV != 0) {
print STDERR "ERROR: Wrong number of command-line arguments (must be exactly 1)\n";
usage();
}
my $osfile = shift();
open(OSFILE, "<$osfile") or die "Failed to open purported nmap-os-fingerprints file: $osfile\n";
my $state = "headertxt";
my $lineno = 0;
my $headertxt = "";
my @prints;
my %newFP = ();
while($nxtline = <OSFILE>) {
$lineno++;
if ($state eq "headertxt") {
if ($nxtline =~ /^\#/) {
$headertxt .= $nxtline;
} else {
$state = "fprint-comments";
}
next;
}
if ($nxtline =~ /^\s*$/) {
# REMEMBER TO COPY ANY TEXT HERE TO THE FINAL PRINT CAPTURE BELOW THIS LOOP
if ($state eq "fprint-tests") {
# A blank line ends a fingerprint
my %copy = %newFP;
push @prints, \%copy;
# print "Read in an FP! There are now " . ($#prints + 1) . "\n";
%newFP = ();
$state = "fprint-comments";
}
next;
}
if ($state eq "fprint-comments") {
if ($nxtline =~ /^\#/) {
if (!($nxtline =~ /^\# /)) {
$nxtline =~ s/^\#/\# /;
}
$newFP{comments} .= $nxtline;
next;
} else {
$state = "fprint-name";
}
}
if ($state eq "fprint-name") {
if ($nxtline =~ /^Fingerprint (\S.*\S)\s*$/) {
$newFP{name} = $1;
$state = "fprint-class";
next;
}
die "ERROR: Parse error on $osfile:$lineno -- expected Fingerprint directive";
}
if ($state eq "fprint-class") {
if ($nxtline =~ /^Class (\S.*\S)$/) {
if (!$newFP{firstClass}) {
$newFP{firstClass} = $1;
}
$newFP{data} .= "$nxtline";
next;
} else {
if (!$newFP{firstClass}) {
die "ERROR: Parse error on $osfile:$lineno -- expected Class directive";
}
$state = "fprint-tests";
}
}
if ($state eq "fprint-tests") {
if ($nxtline =~ /^(TSeq|T[1-7]|PU)\(.*\)(\s*\#.*)?$/) {
$newFP{data} .= "$nxtline";
next;
}
die "ERROR: Parse error on $osfile:$lineno -- expected a Tseq, T1-T7, or PU test line";
}
}
# Capture the final print
if ($state eq "fprint-tests") {
# A blank line ends a fingerprint
my %copy = %newFP;
push @prints, \%copy;
# print "Read final FP! There are now " . ($#prints + 1) . "\n";
} elsif ($state ne "fprint-comments") {
die "ERROR: $osfile appears to have ended in mid-fingerprint";
}
# print "Successfully read in " . ($#prints + 1) . " fingerprints from $osfile\n";
my @sortedprints = sort fprintsort @prints;
# print "The first name is $prints[0]->{name} and the second is $prints[1]->{name}\n";
# print "The sorted first name is $sortedprints[0]->{name} and the second is $sortedprints[1]->{name}\n";
print $headertxt;
print "\n";
my $firstline = "true";
foreach $print (@sortedprints) {
if ($firstline) {
$firstline = 0;
} else { print "\n"; }
if ($print->{comments}) {
print $print->{comments};
}
print "Fingerprint $print->{name}\n";
print "$print->{data}";
}