| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112 |
- # Id ##########################################################################
- # $Id: 74_Nmap.pm 14107 2017-04-26 03:51:05Z igami $
- # copyright ###################################################################
- #
- # 74_Nmap.pm
- #
- # Copyright by igami
- #
- # This file is part of FHEM.
- #
- # FHEM is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 2 of the License, or
- # (at your option) any later version.
- #
- # FHEM is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with FHEM. If not, see <http://www.gnu.org/licenses/>.
- # packages ####################################################################
- package main;
- use strict;
- use warnings;
- use Blocking;
- # forward declarations ########################################################
- sub Nmap_Initialize($);
- sub Nmap_Define($$);
- sub Nmap_Undefine($$);
- sub Nmap_Set($@);
- sub Nmap_Attr(@);
- sub Nmap_statusRequest($);
- sub Nmap_blocking_statusRequest($);
- sub Nmap_done($);
- sub Nmap_aborted($);
- sub Nmap_deleteOldReadings($$);
- sub Nmap_updateUptime($$;$);
- # initialize ##################################################################
- sub Nmap_Initialize($) {
- my ($hash) = @_;
- my $TYPE = "Nmap";
- $hash->{DefFn} = $TYPE."_Define";
- $hash->{UndefFn} = $TYPE."_Undefine";
- $hash->{SetFn} = $TYPE."_Set";
- $hash->{AttrFn} = $TYPE."_Attr";
- $hash->{AttrList} = ""
- . "absenceThreshold "
- . "args "
- . "deleteOldReadings "
- . "devAlias:textField-long "
- . "disable:1,0 "
- . "excludeHosts "
- . "interval "
- . "keepReadings:1,0 "
- . "leadingZeros:1,0 "
- . "metaReading:alias,hostname,ip,macAddress "
- . "path "
- . "sudo:1,0 "
- . $readingFnAttributes
- ;
- }
- # regular Fn ##################################################################
- sub Nmap_Define($$) {
- my ($hash, $def) = @_;
- my ($SELF, $TYPE, $targets) = split(/[\s]+/, $def, 3);
- my $rc = eval{
- require Nmap::Parser;
- Nmap::Parser->import();
- 1;
- };
- return(
- "Error loading Nmap::Parser. Maybe this module is not installed? "
- . "\nUnder debian (based) system it can be installed using "
- . "\n\"apt-get install libnmap-parser-perl\""
- ) unless($rc);
- return("Usage: define <name> $TYPE <target specification>") if(!$targets);
- my $interval = AttrVal($SELF, "interval", 900);
- $interval = 900 if(!looks_like_number($interval));
- $interval = 30 if($interval < 30);
- $hash->{ARGS} = AttrVal($SELF, "args", "-sn");
- $hash->{INTERVAL} = $interval;
- $hash->{PATH} = AttrVal($SELF, "path", "/usr/bin/nmap");
- readingsSingleUpdate($hash, "state", "Initialized", 1);
- RemoveInternalTimer($hash);
- InternalTimer(
- gettimeofday() + $hash->{INTERVAL}, "Nmap_statusRequest", $hash
- );
- return;
- }
- sub Nmap_Undefine($$) {
- my ($hash, $arg) = @_;
- RemoveInternalTimer($hash);
- BlockingKill($hash->{helper}{RUNNING_PID})
- if(defined($hash->{helper}{RUNNING_PID}));
- return;
- }
- sub Nmap_Set($@) {
- my ($hash, @a) = @_;
- my $TYPE = $hash->{TYPE};
- return "\"set $TYPE\" needs at least one argument" if(@a < 2);
- my $SELF = shift @a;
- my $argument = shift @a;
- my $value = join(" ", @a) if (@a);
- my %Nmap_sets = (
- "clear" => "clear:readings",
- "deleteOldReadings" => "deleteOldReadings",
- "interrupt" => "interrupt:noArg",
- "statusRequest" => "statusRequest:noArg"
- );
- Log3($SELF, 5, "$TYPE ($SELF) - entering Nmap_Set");
- return(
- "Unknown argument $argument, choose one of "
- . join(" ", values %Nmap_sets)
- ) if(!exists($Nmap_sets{$argument}));
- if($argument eq "clear" && $value eq "readings"){
- foreach (keys %{$hash->{READINGS}}) {
- delete $hash->{READINGS}->{$_} if($_ ne "state");
- }
- }
- elsif($argument eq "deleteOldReadings" && $value){
- my $ret = Nmap_deleteOldReadings($hash, $value);
- return($ret) if($ret);
- readingsSingleUpdate($hash, "state", "deleteOldReadings $value", 1);
- }
- elsif(!IsDisabled($SELF)){
- if($argument eq "interrupt"){
- BlockingKill($hash->{helper}{RUNNING_PID})
- if(defined($hash->{helper}{RUNNING_PID}));
- Nmap_aborted($hash);
- RemoveInternalTimer($hash);
- InternalTimer(
- gettimeofday() + $hash->{INTERVAL}, "Nmap_statusRequest", $hash
- );
- }
- elsif($argument eq "statusRequest"){
- Nmap_statusRequest($hash);
- }
- }
- return;
- }
- sub Nmap_Attr(@) {
- my ($cmd, $SELF, $attribute, $value) = @_;
- my $hash = $defs{$SELF};
- my $TYPE = $hash->{TYPE};
- Log3($SELF, 5, "$TYPE ($SELF) - entering Nmap_Attr");
- if($attribute eq "args"){
- $hash->{ARGS} = $cmd eq "set" ? $value : "-sn";
- }
- elsif($attribute eq "devAlias" && $cmd eq "set"){
- return(
- "$SELF: Value \"$value\" is not allowed for devAlias!\n"
- . "Must be \"<ID>:<ALIAS> <ID2>:<ALIAS2> ...\", "
- . "e.g. 123abc:MyAndroid\n"
- . "Only these characters are allowed: [alphanumeric - _ .]"
- )if($value !~ /^([\w\.\-]+:[\w\.\-]+\s*)+$/s);
- }
- elsif($attribute eq "disable"){
- if($value && $value == 1){
- BlockingKill($hash->{helper}{RUNNING_PID})
- if(defined($hash->{helper}{RUNNING_PID}));
- RemoveInternalTimer($hash);
- readingsSingleUpdate($hash, "state", "disabled", 1);
- }
- elsif($cmd eq "del" || !$value){
- InternalTimer(
- gettimeofday() + $hash->{INTERVAL}, "Nmap_statusRequest", $hash
- );
- readingsSingleUpdate($hash, "state", "Initialized", 1);
- }
- }
- elsif($attribute eq "leadingZeros"){
- foreach (keys %{$hash->{READINGS}}){
- my $newkey = $_;
- $newkey =~
- s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/sprintf('%03d',$1).".".sprintf('%03d',$2).".".sprintf('%03d',$3).".".sprintf('%03d',$4)/e
- if($value and $value == 1);
- $newkey =~
- s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/sprintf('%00d',$1).".".sprintf('%00d',$2).".".sprintf('%00d',$3).".".sprintf('%00d',$4)/e
- if($cmd eq "del" or !$value);
- $hash->{READINGS}{$newkey} = delete $hash->{READINGS}{$_};
- }
- my $knownHosts = ReadingsVal($SELF, ".knownHosts", "");
- $knownHosts =~
- s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/sprintf('%03d',$1).".".sprintf('%03d',$2).".".sprintf('%03d',$3).".".sprintf('%03d',$4)/ge
- if($value and $value == 1);
- $knownHosts =~
- s/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/sprintf('%00d',$1).".".sprintf('%00d',$2).".".sprintf('%00d',$3).".".sprintf('%00d',$4)/ge
- if($cmd eq "del" or !$value);
- readingsSingleUpdate($hash, ".knownHosts", $knownHosts, 0);
- }
- elsif($attribute eq "path"){
- $hash->{PATH} = $cmd eq "set" ? $value : "/usr/bin/nmap";
- }
- return if(IsDisabled($SELF));
- if($attribute eq "interval"){
- my $interval = $cmd eq "set" ? $value : 900;
- $interval = 900 if(!looks_like_number($interval));
- $interval = 30 if($interval < 30);
- $hash->{INTERVAL} = $interval;
- RemoveInternalTimer($hash);
- InternalTimer(
- gettimeofday() + $hash->{INTERVAL}, "Nmap_statusRequest", $hash
- );
- }
- return;
- }
- # blocking Fn #################################################################
- sub Nmap_statusRequest($) {
- my ($hash) = @_;
- my $SELF = $hash->{NAME};
- my $TYPE = $hash->{TYPE};
- my $interval = $hash->{INTERVAL};
- my $timeout = $interval - 1;
- my $path = $hash->{PATH};
- Log3($SELF, 5, "$TYPE ($SELF) - entering Nmap_statusRequest");
- BlockingKill($hash->{helper}{RUNNING_PID})
- if(defined($hash->{helper}{RUNNING_PID}));
- RemoveInternalTimer($hash);
- return if(IsDisabled($SELF));
- InternalTimer(
- gettimeofday() + $interval, "Nmap_statusRequest", $hash
- );
- unless(-X $path){
- readingsSingleUpdate($hash, "state", "aborted", 1);
- Log3(
- $SELF, 1, "$TYPE ($SELF) - "
- . "please check if Nmap ist installed and available at path $path"
- );
- return;
- }
- if( AttrVal($SELF, "sudo", 0) == 1
- && qx(sudo -n $path -V 2>&1 > /dev/null)
- ){
- readingsSingleUpdate($hash, "state", "aborted", 1);
- Log3($SELF, 1, "$TYPE ($SELF) - sudo password required");
- return;
- }
- readingsSingleUpdate($hash, "state", "running", 1);
- Log3($SELF, 3, "$TYPE ($SELF) - starting network scan");
- Log3($SELF, 5, "$TYPE ($SELF) - BlockingCall Nmap_blocking_statusRequest");
- $hash->{helper}{RUNNING_PID} = BlockingCall(
- "Nmap_blocking_statusRequest", $SELF, "Nmap_done"
- , $timeout, "Nmap_aborted", $hash
- ) unless(exists($hash->{helper}{RUNNING_PID}));
- return;
- }
- sub Nmap_blocking_statusRequest($) {
- my ($SELF) = @_;
- my ($hash) = $defs{$SELF};
- my $TYPE = $hash->{TYPE};
- my @ret = $SELF;
- my $NP = new Nmap::Parser;
- my $path =
- (AttrVal($SELF, "sudo", 0) == 1 ? "sudo " : "")
- . $hash->{PATH}
- ;
- my $excludeHosts = AttrVal($SELF, "excludeHosts", undef);
- my $args = $hash->{ARGS};
- $args .= " --exclude $excludeHosts" if($excludeHosts);
- my $STDERR = "";
- Log3($SELF, 5, "$TYPE ($SELF) - entering Nmap_blocking_statusRequest");
- close STDERR;
- open(STDERR, ">", \$STDERR);
- $NP->parsescan($path, $args, $hash->{DEF});
- close (STDERR);
- Log3($SELF, 4, "$TYPE ($SELF) - $_")
- foreach(split( "\n", $STDERR));
- my $NPS = $NP->get_session();
- push(@ret, $NPS->nmap_version());
- push(@ret, int($NP->all_hosts()));
- push(@ret, $NPS->finish_time() - $NPS->start_time());
- my @hostsUp = $NP->all_hosts("up");
- foreach (@hostsUp){
- my $hostname = $_->hostname() ? $_->hostname() : $_->ipv4_addr();
- my $macAddress = $_->mac_addr() ? $_->mac_addr() : "Unknown";
- my $macVendor = $_->mac_vendor() ? $_->mac_vendor() : "Unknown";
- push(@ret, $_->ipv4_addr()."|$hostname|$macAddress|$macVendor");
- }
- return (join("||", @ret));
- }
- sub Nmap_done($) {
- my ($string) = @_;
- return unless(defined($string));
- my ($SELF, $NmapVersion, $hostsScanned, $scanDuration, @hostsUp) =
- split("\\|\\|", $string);
- my ($hash) = $defs{$SELF};
- my $TYPE = $hash->{TYPE};
- my $devAliases = AttrVal($SELF, "devAlias", undef);
- my %knownHosts = map{$_, 0} split(",", ReadingsVal($SELF, ".knownHosts", ""));
- my $metaReadingAttrVal = AttrVal($SELF, "metaReading", "ip");
- Log3($SELF, 5, "$TYPE ($SELF) - entering Nmap_done");
- delete($hash->{helper}{RUNNING_PID});
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash, "NmapVersion", $NmapVersion);
- readingsBulkUpdate($hash, "hostsScanned", $hostsScanned);
- readingsBulkUpdate($hash, "hostsUp", int(@hostsUp));
- readingsBulkUpdate($hash, "scanDuration", $scanDuration);
- foreach (@hostsUp){
- my ($ip, $hostname, $macAddress, $macVendor) = split("\\|", $_);
- my ($oldMetaReading, $metaReading);
- my $alias = $hostname;
- if(
- $devAliases && $devAliases =~ /$macAddress:(.+?)(\s|$)/
- || $devAliases && $devAliases =~ /$hostname:(.+?)(\s|$)/
- || $devAliases && $devAliases =~ /$ip:(.+?)(\s|$)/
- ){
- $alias = $1;
- }
- if($metaReadingAttrVal eq "ip"){
- $metaReading = $ip;
- }
- elsif($metaReadingAttrVal eq "macAddress"){
- $metaReading = $macAddress ne "Unknown" ? $macAddress : $ip;
- }
- elsif($metaReadingAttrVal eq "alias"){
- $metaReading = $alias;
- }
- elsif($metaReadingAttrVal eq "hostname"){
- $metaReading = $hostname;
- }
- $metaReading =~ s/([0-9]+)/sprintf('%03d',$1)/ge
- if(AttrVal($SELF, "leadingZeros", 0) == 1 && $metaReading eq $ip);
- $metaReading =~ s/:/-/g;
- $knownHosts{$metaReading} = 1;
- if($macAddress ne "Unknown"){
- foreach (keys %knownHosts){
- $oldMetaReading = $_
- if(ReadingsVal($SELF, $_."_macAddress", "") eq $macAddress);
- next unless($oldMetaReading);
- last;
- }
- if( $oldMetaReading
- && ReadingsVal($SELF, $oldMetaReading."_ip", "") ne $ip
- ){
- Log3($SELF, 4, "$TYPE ($SELF) - new IP: $hostname ($ip)");
- DoTrigger($SELF, "new IP: $hostname ($ip)");
- }
- }
- unless($hash->{READINGS}{$metaReading."_hostname"} || $oldMetaReading){
- Log3($SELF, 4, "$TYPE ($SELF) - new host: $hostname ($ip)");
- DoTrigger($SELF, "new host: $hostname ($ip)");
- }
- if( $oldMetaReading && $oldMetaReading ne $metaReading
- && AttrVal($SELF, "keepReadings", 0) == 0
- ){
- delete $knownHosts{$oldMetaReading};
- CommandDeleteReading(undef, "$SELF $oldMetaReading.*");
- Log3($SELF, 4, "$TYPE ($SELF) - delete old host: $oldMetaReading");
- }
- readingsBulkUpdate($hash, $metaReading."_alias", $alias);
- readingsBulkUpdate($hash, $metaReading."_hostname", $hostname);
- readingsBulkUpdate($hash, $metaReading."_ip", $ip);
- readingsBulkUpdate($hash, $metaReading."_lastSeen", TimeNow());
- readingsBulkUpdate($hash, $metaReading."_macAddress", $macAddress)
- if($macAddress ne "Unknown");
- readingsBulkUpdate($hash, $metaReading."_macVendor", $macVendor)
- if($macVendor ne "Unknown");
- readingsBulkUpdate($hash, $metaReading."_state", "present");
- Nmap_updateUptime($hash, $metaReading);
- }
- foreach (keys %knownHosts){
- next if( $knownHosts{$_} == 1
- || ReadingsVal($SELF, $_."_state", "present") eq "absent"
- );
- my $absenceThreshold = ReadingsVal($SELF, ".".$_."_absenceThreshold", 1);
- if($absenceThreshold >= AttrVal($SELF, "absenceThreshold", 1)){
- delete $hash->{READINGS}{".".$_."_absenceThreshold"};
- readingsBulkUpdate($hash, $_."_state", "absent");
- Nmap_updateUptime($hash, $_, 0);
- }
- else{
- $absenceThreshold ++;
- readingsBulkUpdate($hash, ".".$_."_absenceThreshold", $absenceThreshold);
- readingsBulkUpdate($hash, $_."_state", "present");
- Nmap_updateUptime($hash, $_);
- }
- }
- readingsBulkUpdate($hash, ".knownHosts", join(",", sort(keys %knownHosts)));
- readingsBulkUpdate($hash, "knownHosts", int(keys %knownHosts));
- readingsBulkUpdate($hash, "state", "done");
- readingsEndUpdate($hash, 1);
- my $deleteOldReadings = AttrVal($SELF, "deleteOldReadings", 0);
- Nmap_deleteOldReadings($hash, $deleteOldReadings)
- if($deleteOldReadings ne "0");
- Log3($SELF, 3, "$TYPE ($SELF) - network scan done");
- return;
- }
- sub Nmap_aborted($) {
- my ($hash) = @_;
- my $SELF = $hash->{NAME};
- my $TYPE = $hash->{TYPE};
- delete($hash->{helper}{RUNNING_PID});
- Log3($SELF, 2, "$TYPE ($SELF) - network scan aborted");
- readingsSingleUpdate($hash, "state", "aborted", 1);
- return;
- }
- # module Fn ###################################################################
- sub Nmap_deleteOldReadings($$) {
- my ($hash, $value) = @_;
- my $SELF = $hash->{NAME};
- my $TYPE = $hash->{TYPE};
- $value = eval($value);
- Log3($SELF, 5, "$TYPE ($SELF) - entering Nmap_deleteOldReadings");
- unless(looks_like_number($value)){
- my $ret = "no numeric value given for deleteOldReadings";
- Log3($SELF, 2, "$TYPE ($SELF) - $ret");
- return($ret);
- }
- my %knownHosts =
- map{$_, 0} split(",", ReadingsVal($SELF, ".knownHosts", ""));
- foreach (keys %knownHosts) {
- if(ReadingsAge($SELF, $_."_lastSeen", 0) >= $value){
- CommandDeleteReading(undef, "$SELF $_.*");
- delete $knownHosts{$_};
- }
- }
- readingsBeginUpdate($hash);
- readingsBulkUpdate($hash, ".knownHosts", join(",", sort(keys %knownHosts)));
- readingsBulkUpdate($hash, "knownHosts", int(keys %knownHosts));
- readingsEndUpdate($hash, 1);
- Log3($SELF, 4, "$TYPE ($SELF) - delete Readings older than $value seconds");
- return;
- }
- sub Nmap_updateUptime($$;$) {
- my ($hash, $metaReading, $uptime) = @_;
- my $SELF = $hash->{NAME};
- my $TYPE = $hash->{TYPE};
- Log3($SELF, 5, "$TYPE ($SELF) - entering Nmap_updateUptime");
- $uptime = (
- ReadingsVal($SELF, $metaReading."_uptime", 0)
- + ReadingsAge($SELF, $metaReading."_uptime", 0)
- ) unless(defined($uptime));
- my $s = $uptime;
- my $d = int($s / 86400);
- $s -= $d * 86400;
- my $h = int($s / 3600);
- $s -= $h * 3600;
- my $m = int($s / 60);
- $s -= $m * 60;
- my $uptimeText = sprintf(
- "%d days, %02d hours, %02d minutes, %02d seconds"
- , $d, $h, $m, $s
- );
- readingsBulkUpdate($hash, $metaReading."_uptime", $uptime);
- readingsBulkUpdate($hash, $metaReading."_uptimeText", $uptimeText);
- return;
- }
- 1;
- # commandref ##################################################################
- =pod
- =item device
- =item summary Interpret of an Nmap network scans
- =item summary_DE Auswertung eines Nmap Netzwerkscans
- =begin html
- <a name="Nmap"></a>
- <h3>Nmap</h3>
- ( en | <a href="commandref_DE.html#Nmap"><u>de</u></a> )
- <div>
- <ul>
- Nmap is the FHEM module to perform a network scan with Nmap and to display information about the available network devices.<br>
- If a new device is detected, an event
- <code>"<name> new host: <hostname> (<IPv4>)"</code>
- is generated.<br>
- If a device with a known MAC address has been given a new IP, an event
- <code>"<name> new IP: <hostname> (<IPv4>)"</code>
- is generated.<br>
- <br>
- Prerequisites:
- <ul>
- The "Nmap" program and the Perl module "Nmap::Parser" are required.<br>
- Under Debian (based) system, these can be installed using
- <code>"apt-get install nmap libnmap-parser-perl"</code>
- .
- </ul>
- <br>
- <a name="Nmapdefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> Nmap <target specification></code><br>
- In the <target specification> are all target hosts, which are to be
- scanned.<br>
- The simplest case is the description of an IP destination address or a
- target host name for scanning.<br>
- To scan an entire network of neighboring hosts, Nmap supports CIDR-style
- addresses. Numbits can be appended to an IPv4 address or hostname, and
- Nmap will scan all IP addresses where the first numbits match those of
- the given IP or host name. For example, 192.168.10.0/24 would scan the
- 256 hosts between 192.168.10.0 and 192.168.10.255. 192.168.10.40/24 would
- scan exactly the same targets. It's also possible to scan multiple
- networks at the same time. For example 192.168.1.0/24 192.168.2.0/24
- would scan the 512 hosts between 192.168.1.0 and 192.168.2.255.<br>
- See
- <a href="https://nmap.org/man/de/man-target-specification.html">
- <u>Nmap Manpage (Specifying Destinations)</u>
- </a>.
- </ul><br>
- <a name="Nmapset"></a>
- <b>Set</b>
- <ul>
- <li>
- <code>clear readings</code><br>
- Deletes all readings except "state".
- </li>
- <li>
- <code>deleteOldReadings <s></code><br>
- Deletes all readings older than <s> seconds.
- </li>
- <li>
- <code>interrupt</code><br>
- Cancels a running scan.
- </li>
- <li>
- <code>statusRequest</code><br>
- Starts a network scan.
- </li>
- </ul><br>
- <a name="Nmapreadings"></a>
- <b>Readings</b><br>
- <ul>
- General Readings:
- <ul>
- <li>
- <code>NmapVersion</code><br>
- The version number of the installed Nmap program.
- </li>
- <li>
- <code>hostsScanned</code><br>
- The number of scanned addresses.
- </li>
- <li>
- <code>hostsUp</code><br>
- The number of available network devices.
- </li>
- <li>
- <code>knownHosts</code><br>
- The number of known network devices.
- </li>
- <li>
- <code>scanDuration</code><br>
- The scan time in seconds.
- </li>
- <li>
- <code>state</code><br>
- <ul>
- <li>
- <code>Initialized</code><br>
- Nmap has been defined or enabled.
- </li>
- <li>
- <code>running</code><br>
- A network scan is running.
- </li>
- <li>
- <code>done</code><br>
- Network scan completed successfully.
- </li>
- <li>
- <code>aborted</code><br>
- The network scan was aborted due to a timeout or by the user.
- </li>
- <li>
- <code>disabled</code><br>
- Nmap has been disabled.
- </li>
- </ul>
- </li>
- </ul>
- <br>
- Host-specific readings:
- <ul>
- <li>
- <code><metaReading>_alias</code><br>
- Alias which is specified under the attribute "devAlias" for the
- network device. If no alias is specified, the hostname is displayed.
- </li>
- <li>
- <code><metaReading>_hostname</code><br>
- Hostname of the network device. If this can not be determined, the IPv4
- address is displayed.
- </li>
- <li>
- <code><metaReading>_ip</code><br>
- IPv4 address of the network device.
- </li>
- <li>
- <code><metaReading>_lastSeen</code><br>
- The time at which the network device was last seen as.
- </li>
- <li>
- <code><metaReading>_macAddress</code><br>
- MAC address of the network device. This can only be determined if the
- scan is executed with root privileges.
- </li>
- <li>
- <code><metaReading>_macVendor</code><br>
- Probable manufacturer of the network device. This can only be
- determined if the scan is executed with root privileges.
- </li>
- <li>
- <code><metaReading>_state</code><br>
- State of the network device. Can be either "absent" or "present".
- </li>
- <li>
- <code><metaReading>_uptime</code><br>
- Time in seconds since the network device is reachable.
- </li>
- <li>
- <code><metaReading>_uptimeText</code><br>
- Time in "d days, hh hours, mm minutes, ss seconds" since the network
- device is reachable.
- </li>
- </ul>
- </ul><br>
- <a name="Nmapattr"></a>
- <b>Attribute</b>
- <ul>
- <li>
- <code>absenceThreshold <n></code><br>
- The number of network cans that must result in "absent" before the
- state of a network device changes to "absent". With this function you
- can verify the absence of a device before the status is changed to
- "absent". If this attribute is set to a value >1, the reading
- "<metaReading>_state" remains on "present" until the final status
- changes to "absent".
- </li>
- <li>
- <code>args <args></code><br>
- Arguments for the Nmap scan.<br>
- The default is "-sn".
- </li>
- <li>
- <code>deleteOldReadings <s></code><br>
- After a network scan, all host-specific readings older than <s>
- seconds are deleted
- </li>
- <li>
- <code>
- devAlias <ID>:<ALIAS> <ID2>:<ALIAS2> ...
- </code><br>
- A whitespace separated list of <ID>:<ALIAS> pairs that can be used to give an alias to network devices.<br>
- The ID can be MAC address, hostname or IPv4 address.<br>
- Examples:
- <ul>
- MAC address:
- <code>
- attr <name> devAlias 5C:51:88:A5:94:1F:Michaels_Handy_byMAC
- </code><br>
- Hostname:
- <code>
- attr <name> devAlias
- android-87c7a6221093d830:Michaels_Handy_byHOST
- </code><br>
- IPv4 address:
- <code>
- attr <name> devAlias 192.168.1.130:Michaels_Handy_byIP
- </code><br>
- </ul>
- </li>
- <li>
- <code>disable 1</code><br>
- A running scan is canceled and no new scans are started.
- </li>
- <li>
- <code>excludeHosts <target specification></code><br>
- All target hosts in the <target specification> are skipped during the scan.
- </li>
- <li>
- <code>interval <seconds></code><br>
- Interval in seconds in which the scan is performed.<br>
- The default value is 900 seconds and the minimum value is 30 seconds.
- </li>
- <li>
- <code>keepReadings 1</code><br>
- If a new IP address is recognized for a device with a known MAC
- address, the invalid readings are deleted unless this attribute is set.
- </li>
- <li>
- <code>leadingZeros 1</code><br>
- For the readings, the IPv4 addresses are displayed with leading zeros.
- </li>
- <li>
- <code>metaReading <metaReading></code><br>
- You can specify "alias", "hostname", "ip" or "macAddress" as
- <metaReading> and is the identifier for the readings.<br>
- The default is "ip".
- </li>
- <li>
- <code>path</code><br>
- Path under which the Nmap program is to be reached.<br>
- The default is "/urs/bin/nmap".
- </li>
- <li>
- <a href="#readingFnAttributes">
- <u><code>readingFnAttributes</code></u>
- </a>
- </li>
- <li>
- <code>sudo 1</code><br>
- The scan runs with root privileges.<br>
- The prerequisite is that the user has these rights under the FHEM. For
- the user "fhem", on a Debian (based) system, they can be set in the
- "/etc/sudoers" file. For this, the line "fhem ALL=(ALL) NOPASSWD:
- /usr/bin/nmap" must be inserted in the section "#User privilege
- specification".
- </li>
- </ul>
- </ul>
- </div>
- =end html
- =begin html_DE
- <a name="Nmap"></a>
- <h3>Nmap</h3>
- ( <a href="commandref.html#Nmap"><u>en</u></a> | de )
- <div>
- <ul>
- Nmap ist das FHEM Modul um einen Netzwerkscan mit Nmap durchzuführen
- und Informationen über die erreichbaren Netzwerkgeräte
- darzustellen.<br>
- Wird ein neues Gerät erkannt wird ein Event
- <code>"<name> new host: <hostname> (<IPv4>)"</code>
- erzeugt.<br>
- Wird erkannt, dass ein Gerät mit bekannter MAC-Adresse eine neue IP
- erhalten hat wird ein Event
- <code>"<name> new IP: <hostname> (<IPv4>)"</code>
- erzeugt.<br>
- <br>
- Vorraussetzungen:
- <ul>
- Das Programm "Nmap" sowie das Perl-Modul "Nmap::Parser" werden
- benötigt.<br>
- Unter Debian (basierten) System, können diese mittels
- <code>"apt-get install nmap libnmap-parser-perl"</code>
- installiert werden.
- </ul>
- <br>
- <a name="Nmapdefine"></a>
- <b>Define</b>
- <ul>
- <code>define <name> Nmap <target specification></code><br>
- In der <target specification> stehen alle Zielhosts, die gescannet
- werden sollen. <br>
- Der einfachste Fall ist die Beschreibung einer IP-Zieladresse oder eines
- Zielhostnamens zum Scannen. <br>
- Um ein ganzes Netzwerk benachbarter Hosts zu scannen unterstützt
- Nmap Adressen im CIDR-Stil. Es können /numbits an eine IPv4-Adresse
- oder an einen Hostnamen angefügt werden, und Nmap wird alle
- IP-Adressen scannen, bei denen die ersten numbits mit denen der gegebenen
- IP oder des gegebenen Hostnamens übereinstimmen. Zum Beispiel
- würde 192.168.10.0/24 die 256 Hosts zwischen 192.168.10.0 und
- 192.168.10.255 scannen. 192.168.10.40/24 würde genau dieselben Ziele
- scannen. Es ist auch möglich mehrere Netzwerke zur gleichen Zeit zu
- scannen. Zum Beispiel würde 192.168.1.0/24 192.168.2.0/24 die 512
- Hosts zwischen 192.168.1.0 und 192.168.2.255 scannen.<br>
- Siehe
- <a href="https://nmap.org/man/de/man-target-specification.html">
- <u>Nmap Man Page (Angabe von Zielen)</u>
- </a>.
- </ul><br>
- <a name="Nmapset"></a>
- <b>Set</b>
- <ul>
- <li>
- <code>clear readings</code><br>
- Löscht alle Readings außer "state".
- </li>
- <li>
- <code>deleteOldReadings <s></code><br>
- Löscht alle Readings die älter sind als <s> Sekunden.
- </li>
- <li>
- <code>interrupt</code><br>
- Bricht einen laufenden Scan ab.
- </li>
- <li>
- <code>statusRequest</code><br>
- Startet einen Netzwerkscan.
- </li>
- </ul><br>
- <a name="Nmapreadings"></a>
- <b>Readings</b><br>
- <ul>
- Allgemeine Readings:
- <ul>
- <li>
- <code>NmapVersion</code><br>
- Die Versionsnummer des installierten Nmap Programms.
- </li>
- <li>
- <code>hostsScanned</code><br>
- Die Anzahl der gescannten Adressen.
- </li>
- <li>
- <code>hostsUp</code><br>
- Die Anzahl der erreichbaren Netzwerkgeräte.
- </li>
- <li>
- <code>knownHosts</code><br>
- Die Anzahl der bekannten Netzwerkgeräte.
- </li>
- <li>
- <code>scanDuration</code><br>
- Die Scan-Dauer in Sekunden.
- </li>
- <li>
- <code>state</code><br>
- <ul>
- <li>
- <code>Initialized</code><br>
- Nmap wurde definiert oder enabled.
- </li>
- <li>
- <code>running</code><br>
- Ein Netzwerkscan wird ausgeführt.
- </li>
- <li>
- <code>done</code><br>
- Der Netzwerkscan wurde erfolgreich abgeschlossen.
- </li>
- <li>
- <code>aborted</code><br>
- Der Netzwerkscan wurde aufgrund einer Zeitüberschreitung oder
- durch den Benutzer abgebrochen.
- </li>
- <li>
- <code>disabled</code><br>
- Nmap wurde deaktiviert.
- </li>
- </ul>
- </li>
- </ul>
- <br>
- Hostspezifische Readings:
- <ul>
- <li>
- <code><metaReading>_alias</code><br>
- Alias welcher unter dem Attribut "devAlias" für das Netzwerkgerät
- angegeben ist. Ist kein Alias angegeben wird der Hostname angezeigt.
- </li>
- <li>
- <code><metaReading>_hostname</code><br>
- Hostname des Netzwerkgeräts. Kann dieser nicht ermittel werden
- wird die IPv4-Adresse angezeigt.
- </li>
- <li>
- <code><metaReading>_ip</code><br>
- IPv4-Adresse des Netzwerkgeräts.
- </li>
- <li>
- <code><metaReading>_lastSeen</code><br>
- Der Zeitpunkt zu dem das Netzwerkgerät das letzte mal als gesehen
- wurde.
- </li>
- <li>
- <code><metaReading>_macAddress</code><br>
- MAC-Adresse des Netzwerkgeräts. Diese kann nur ermittelt werden,
- wenn der Scan mit Root-Rechten ausgeführt wird.
- </li>
- <li>
- <code><metaReading>_macVendor</code><br>
- Vermutlicher Hersteller des Netzwerkgeräts. Dieser kann nur
- ermittelt werden, wenn der Scan mit Root-Rechten ausgeführt wird.
- </li>
- <li>
- <code><metaReading>_state</code><br>
- Status des Netzwerkgeräts. Kann entweder "absent" oder "present"
- sein.
- </li>
- <li>
- <code><metaReading>_uptime</code><br>
- Zeit in Sekunden seit der das Netzwerkgerät erreichbar ist.
- </li>
- <li>
- <code><metaReading>_uptimeText</code><br>
- Zeit in "d days, hh hours, mm minutes, ss seconds" seit der das
- Netzwerkgerät erreichbar ist.
- </li>
- </ul>
- </ul><br>
- <a name="Nmapattr"></a>
- <b>Attribute</b>
- <ul>
- <li>
- <code>absenceThreshold <n></code><br>
- Die Anzahl an Netzwerkscans, welche in "absent" resultieren
- müssen, bevor der Status eines Netzwerkgeräts auf "absent"
- wechselt. Mit dieser Funktion kann man die Abwesenheit eines
- Gerätes verifizieren bevor der Status final auf "absent"
- geändert wird. Wenn dieses Attribut auf einen Wert >1 gesetzt
- ist, verbleibt das Reading "<metaReading>_state" auf "present",
- bis der Status final auf "absent" wechselt.
- </li>
- <li>
- <code>args <args></code><br>
- Argumente für den Nmap-Scan.<br>
- Die Vorgabe ist "-sn".
- </li>
- <li>
- <code>deleteOldReadings <s></code><br>
- Nach einem Netzwerkscan werden alle hostspezifischen Readings, die
- älter sind als <s> Sekunden, gelöscht
- </li>
- <li>
- <code>
- devAlias <ID>:<ALIAS> <ID2>:<ALIAS2> ...
- </code><br>
- Eine Leerzeichen-getrennte getrennte Liste von <ID>:<ALIAS>
- Paaren, die dazu genutzt werden kann um Netzwerkgeräten einen
- Alias zu geben.<br>
- Die ID kann dabei MAC-Adresse, hostname oder IPv4-Adresse sein.<br>
- Beispiele:
- <ul>
- MAC-Adresse:
- <code>
- attr <name> devAlias 5C:51:88:A5:94:1F:Michaels_Handy_byMAC
- </code><br>
- hostname:
- <code>
- attr <name> devAlias
- android-87c7a6221093d830:Michaels_Handy_byHOST
- </code><br>
- IPv4-Adresse:
- <code>
- attr <name> devAlias 192.168.1.130:Michaels_Handy_byIP
- </code><br>
- </ul>
- </li>
- <li>
- <code>disable 1</code><br>
- Ein laufender Scan wird abgebrochen und es werden keine neuen Scans
- gestartet.
- </li>
- <li>
- <code>excludeHosts <target specification></code><br>
- In der <target specification> stehen alle Zielhosts, die beim
- Scan übersprungen werden sollen.
- </li>
- <li>
- <code>interval <seconds></code><br>
- Intervall in Sekunden in dem der Scan durchgeführt wird.<br>
- Der Vorgabewert ist 900 Sekunden und der Mindestwert 30 Sekunden.
- </li>
- <li>
- <code>keepReadings 1</code><br>
- Wird für ein Gertät mit bekannter MAC-Adresse eine neue IP-Adresse
- erkannt, werden die ungültig gewordenen Readings gelöscht es sei denn
- dieses Attribut ist gesetzt.
- </li>
- <li>
- <code>leadingZeros 1</code><br>
- Bei den Readings-Namen werden die IPv4-Adressen mit führenden
- Nullen dargestellt.
- </li>
- <li>
- <code>metaReading <metaReading></code><br>
- Als <metaReading> kann "alias", "hostname", "ip" oder
- "macAddress" angegeben werden und ist der Bezeichner für die
- Readings.<br>
- Die Vorgabe is "ip".
- </li>
- <li>
- <code>path</code><br>
- Pfad unter dem das Nmap Programm zu erreichen ist.<br>
- Die Vorgabe ist "/urs/bin/nmap".
- </li>
- <li>
- <a href="#readingFnAttributes">
- <u><code>readingFnAttributes</code></u>
- </a>
- </li>
- <li>
- <code>sudo 1</code><br>
- Der Scan wird mit Root-Rechten ausgeführt.<br>
- Voraussetzung ist, dass der Benutzer unter dem FHEM ausgeführt
- diese Rechte besitzt. Für den Benutzer "fhem", auf einem Debian
- (basierten) System, lassen sich diese in der Datei "/etc/sudoers"
- festlegen. Dafür muss im Abschnitt "# User privilege
- specification" die Zeile "fhem ALL=(ALL) NOPASSWD: /usr/bin/nmap"
- eingefügt werden.
- </li>
- </ul>
- </ul>
- </div>
- =end html_DE
- =cut
|