#!/usr/bin/perl # Andrew Daviel, April 2005 # convert NetStumbler NS1 binary data to Fig # e.g. ns12fig -v blah.ns1 710000 928000 49.2499 -123.2322 50000 > blah.fig # Usage: $0 [] [] [] [] # radius factor makes points bigger; min. size is 1 # options: n - add text legend # e - show WEP encrypted/unencrypted # d - show all APs at same depth # v - verbose (cf. summary data) use Math::BigInt; # remember depths used - for merging files dbmopen(%depth,"ns1depthdb",0644) ; $verb = 0 ; $verb2 = 0 ; # show time # http://www.stumbler.net/ns1files.html # C uint8 S uint16 L uint32 l int32 Q uint64 d double # Flags (HEx) # 0001 ESS extended service set # 0002 IBSS ad hod/P2P # 0004 CF Pollable # 0008 CF-Poll request # 0010 WEP # 0020 Short Preamble # 0040 PBCC # 0080 Channel Agility # 0400 Short slot time # 2000 DSSS-OFDM $quiet = 0 ; $line_style = 0 ; $thickness = 1 ; $pen_color = 4 ; # red $red = 4 ; $gold = 31 ; $green = 14 ; $black = 0 ; $fill_color = 7 ; $pdepth = 40 ; $pen_style = -1 ; $area_fill = 20 ; $style_val = '0.000' ; $angle = '0.000' ; $textangle = '0.700' ; $pt = 2 ; # text point $pt = 18 ; # text point $join_style = 0 ; $cap_style = 0 ; $radius0 = 400000 ; $radius0 = 2000 ; $forward_arrow = 0 ; $backward_arrow = 0 ; $maxcol = 5 ; $legend2 = 0 ; while ($ARGV[0] =~ /-([nedv])/) { if ($1 eq 'n') { shift ; $legend = 1 ; } if ($1 eq 'e') { shift ; $doe = 1 ; } if ($1 eq 'd') { shift ; $dp1 = 1 ; } if ($1 eq 'v') { shift ; $verb = 1 ; } } $file = shift ; open (IN,$file) or die "Usage: $0 [] [] [] []\n" ; $xscale = shift ; unless ($xscale) { die "Usage: $0 [] [] [] []\n" ; # e.g. 180000 } $yscale = shift ; unless ($yscale) { $yscale = $xscale ; } $yoff = shift ; $xoff = shift ; $radius0 = shift ; unless ($radius0) { $radius0 = 4000 ; } $radius = int ($xscale / $radius0) ; unless ($radius>0) { $radius = 1 ; } $scale2 = 1200/100 ; $scale2 = 1200 ; print<$xmax) { $xmax = $x ; } if ($y>$ymax) { $ymax = $y ; } if ($x<$xmin) { $xmin = $x ; } if ($y<$ymin) { $ymin = $y ; } $x = int($x * $scale2 + 0.5 ) ; $y = int($y * -$scale2 + 0.5 ) ; # from ps2fig $lat5 = sprintf("%.5f",$lat) ; $long5 = sprintf("%.5f",$long) ; print<$xmax) { $xmax = $x ; } if ($y>$ymax) { $ymax = $y ; } if ($x<$xmin) { $xmin = $x ; } if ($y<$ymin) { $ymin = $y ; } $x = int($x * $scale2 + 0.5 ) ; $y = int($y * -$scale2 + 0.5 ) ; # from ps2fig $x{$bssid} = $x ; $y{$bssid} = $y ; if ($verb) { #printf ("LL %.5f %.5f alt %.3f Nsat %i speed %.1f track %.1f mvar %.1f HDOP %i\n",$lat,$long, $alt, $nsat, $speed, $track, $mvar, $hdop) ; unless (!$lat and !$long or $lat == 0.0 and $long == 0.0) { $lat5 = sprintf("%.5f",$lat) ; $long5 = sprintf("%.5f",$long) ; print< 5) { $pen_color = $gold ; } if ($snr > 10) { $pen_color = $green ; } $fill_color = $pen_color ; if ($doe) { $pen_color = $gold ; if ($wep) { $pen_color = $red ; } } $fill_color = $pen_color ; if (!$wep and !$doe or $doe and !$fast) { # circle $x2 = $x + $radius ; print "1 3 $line_style $thickness $pen_color" ; print " $fill_color $pdepth $pen_style $area_fill $angle 1 0.000 " ; print "$x $y $radius $radius $x $y $x2 $y \n" ; } else { # square $x1 = $x - $radius ; $x2 = $x + $radius ; $y1 = $y - $radius ; $y2 = $y + $radius ; #print "2 2 0 1 0 0 $depth 0 20 0.000 0 0 -1 0 0 5\n" ; print "2 2 $line_style $thickness $pen_color $fill_color $pdepth $pen_style $area_fill $angle 0 0 -1 0 0 5\n" ; print "\t$x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1\n" ; } } } } else { #if ($verb) { print "\n" ; } } } read (IN,$in,1) ; $len = unpack("C",$in) ; read (IN,$in,$len) ; $name = $in ; $name{$bssid} = $name ; if ($fv >= 8) { read (IN,$in,8) ; @chan = unpack("L2",$in) ; read (IN,$in,4) ; $lchan = unpack("L",$in) ; $lchan{$bssid} = $lchan ; read (IN,$in,4) ; $ip = unpack("L",$in) ; @ip = unpack("C4",$in) ; #printf ("channelbits %4.4x%4.4x",$chan[1], $chan[0]) ; #printf ("\tip %i.%i.%i.%i lastchan %i\n",$ip[0],$ip[1],$ip[2],$ip[3],$lchan) ; } if ($fv >= 11 ) { read (IN,$in,4) ; $minsig = unpack("l",$in) ; $minsig{$bssid} = $minsig ; read (IN,$in,4) ; $maxns = unpack("l",$in) ; $maxns{$bssid} = $maxns ; read (IN,$in,4) ; $maxrate = unpack("L",$in)/10 ; $maxrate{$bssid} = $maxrate ; read (IN,$in,4) ; $subnet = unpack("L",$in) ; @subnet = unpack("C4",$in) ; read (IN,$in,4) ; $mask = unpack("L",$in) ; @mask = unpack("C4",$in) ; #printf ("min sig %i max noise %i max rate %i subnet %i.%i.%i.%i mask %i.%i.%i.%i\n",$minsig,$maxns,$maxrate,$subnet[0],$subnet[1],$subnet[2],$subnet[3], $mask[0],$mask[1],$mask[2],$mask[3]) ; } if ($fv >= 12) { read (IN,$in,4) ; $miscflags = unpack("L",$in) ; #if ($miscflags) { printf ("misc flags %4.4x\n", $miscflags) ; } read (IN,$in,4) ; $ielength = unpack("L",$in) ; read (IN,$in,$ielength) ; @ie = unpack("C*",$in) ; #if ($ielength) { print "ie length $ielength\n" ; } } unless (!$lat and !$long or $lat == 0.0 and $long == 0.0 or $verb) { print< 5) { $pen_color = $gold ; } if ($snr > 10) { $pen_color = $green ; } $fill_color = $pen_color ; if ($doe) { $pen_color = $gold ; if ($wep) { $pen_color = $red ; } } $fill_color = $pen_color ; if (!$wep and !$doe or $doe and !$fast) { # circle $x2 = $x + $radius ; print "1 3 $line_style $thickness $pen_color" ; print " $fill_color $pdepth $pen_style $area_fill $angle 1 0.000 " ; print "$x $y $radius $radius $x $y $x2 $y \n" ; } else { # square $x1 = $x - $radius ; $x2 = $x + $radius ; $y1 = $y - $radius ; $y2 = $y + $radius ; #print "2 2 0 1 0 0 $depth 0 20 0.000 0 0 -1 0 0 5\n" ; print "2 2 $line_style $thickness $pen_color $fill_color $pdepth $pen_style $area_fill $angle 0 0 -1 0 0 5\n" ; print "\t$x1 $y1 $x2 $y1 $x2 $y2 $x1 $y2 $x1 $y1\n" ; } } } unless ($dp1) { print STDERR "Using ns1depthdb file for depth\n" ; foreach $bssid ( sort { $depth{$a} <=> $depth{$b} } keys %ssid) { print STDERR "Depth $depth{$bssid}\t$ssid{$bssid} $bssid $name{$bssid}\tCH $lchan{$bssid} maxsig $maxsig{$bssid} rate $maxrate{$bssid}\n" ; if ($legend) { print "4 0 $black $depth{$bssid} 0 0 $pt $textangle 0 210 750 $x{$bssid} $y{$bssid} $ssid{$bssid} $bssid $name{$bssid} CH $lchan{$bssid}\\001\n" ; } } } exit ; sub filetotime { my ($h,$l,$t,$r) ; ($l,$h) = unpack("L2",$_[0]) ; my $t = Math::BigInt->new($h); $t->blsft(32) ; $t->badd($l) ; $t->bdiv(10000000) ; # convert 100ns ticks to seconds $t->bsub("11644473600") ; # 134774 days = 369 years 1601 - 1970 return $t ; }