Nmap readingsGroup

Begonnen von igami, 03 April 2017, 17:07:36

Vorheriges Thema - Nächstes Thema

curt

#30
Das gefällt mir, das möchte ich auch.
Leider gibt es ein Problem: MAC und Hersteller werden in der Tabelle nicht angezeigt.

Ich nahm von @supernova1963 die Definitionen. Via PN erkläre er mir das für mich völlig neue Vorgehen mit "Raw definition" und "Execute commands" (Danke!). Nr / IP-Adresse / onl / RechnerName werden angezeigt. Leider werden MAC / Hersteller nicht angezeigt.

in meiner fhem.cfg steht

define Netzwerk Nmap 192.168.127.0/24 192.168.128.0/24
attr Netzwerk room 05 Die Lage

define NetzwerkListe readingsGroup <>,<Nr>,<IP-Adresse>,<onl>,<RechnerName>,<MAC>,<Hersteller> \
Netzwerk:@4,#1_ip,<#1>,#1_state,(.*)_alias,#1_macAddress,#1_macVendor
attr NetzwerkListe cellStyle { "c:1" => 'style="text-align:right"',"c:3" => 'style="text-align:center"',"c:4" => 'style="text-align:left"' }
attr NetzwerkListe icon it_network
attr NetzwerkListe room 92 Informationen
attr NetzwerkListe sortColumn 2
attr NetzwerkListe valueFormat { my $ipAddr = substr($READING,0,index($READING,"_"));;\
  #Icon für #1_state.absent Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>") if($VALUE eq "absent");;\
  #Icon für #1_state.present Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>") if($VALUE eq "present");;\
  #Spalte 'Nr' zur Sortierung aus der IP extrahieren    \
  return(substr($VALUE,rindex($VALUE,".")+1)) if(substr($READING,rindex($READING,"_")) eq "_ip");;\
  return("<a url='http://".$ipAddr."' onclick='window.open(\"http://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "80");;\
  return("<a url='https://".$ipAddr."' onclick='window.open(\"https://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "443");;\
  #Anderenfalls soll das valueFormat leer bleiben bzw. nachstehenden Inhalt verwenden\
  return("");;\
}
attr NetzwerkListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #bfbfbf;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #bfbfbf;; '.$style.'"') if($state eq "absent");;\
}


Auszugsweises Ergebnis in der dargestellten Tabelle ist

106 - 192.168.127.111 - <present> - 192.168.127.111


Da fehlt also MAC/Hersteller - in JEDER Zeile.

Ich klicke also mal bei "Netzwerk" drauf und schaue mir die Readings an: _alias, _hostname, _ip, _lastSeen, _state, _uptime, -uptimeText. Nicht mehr. Es fehlen MAC und Hersteller.

Ok, da wird offensichtlich "/usr/bin/nmap -sn 192.168.127.0/24" aufgerufen. Das vollziehe ich mal mit der bash nach (Auszug):


map scan report for 192.168.127.111
Host is up (-0.10s latency).
MAC Address: 00:0C:29:8B:A8:AA (VMware)


Cool, negative Latenz. - Ok: MAC und Vendor kommen da schon ... nun muss ich nur noch FHEM davon überzeugen.

Was mache ich falsch?

Ganz nebenbei:
Zitat von: supernova1963 am 02 Mai 2017, 06:43:35
Anderenfalls hilft den Experten ein list Nmap_readingsGroup bei der Fehleranalyse oft weiter.

Ähmmm:
Zitat
No device named Netzwerk_readingsGroup found
No device named NetzwerkLIste_readingsGroup found

Nichtmal das kriege ich hin.
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Commandref zum NMap Modul:
Zitat
[...]
<metaReading>_macAddress
MAC-Adresse des Netzwerkgeräts. Diese kann nur ermittelt werden, wenn der Scan mit Root-Rechten ausgeführt wird.
<metaReading>_macVendor
Vermutlicher Hersteller des Netzwerkgeräts. Dieser kann nur ermittelt werden, wenn der Scan mit Root-Rechten ausgeführt wird.
[...]
Vermutlich wird der Scan bei dir also nicht mit root rechten ausgeführt.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

curt

Zitat von: igami am 08 März 2018, 05:57:52
Vermutlich wird der Scan bei dir also nicht mit root rechten ausgeführt.

Vermutlich hast Du recht.

Sagst Du mir bitte, wo und wie ich das konkret einschalte?

Ich danke Dir.
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Soll nicht pampig klingen, aber so wie in der Commandref beschrieben.
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

supernova1963

@curt:

Zitat
sudo 1
Der Scan wird mit Root-Rechten ausgeführt.
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.

Bitte beachten, das du Änderungen an der /etc/sudoers unbedingt mit sudo visudo /etc/sudoersmachst. Besser wäre ggf. eine eigene Datei anzulegen in die du die o.g. Zeile einfügst
sudo visudo -f /etc/sudoers.d/nmap
Anschließend noch booten!
Ich hoffe, dass ich die Befehlssyntax ungetestet noch richtig wiedergegeben habe.

Gernot

curt

Zitat von: igami am 08 März 2018, 06:34:37
Soll nicht pampig klingen

Das klingt nicht nur pampig - sondern ist es auch.

Zwar bin ich ohne Frage doof - aber ich frage nun nicht ohne jeden Hintergrund. Ich komme nicht weiter - was tatsächlich mit Sicherheit an mir liegt. Leider kann ich nicht erkennen, wo der Fehler ist.

Zitat von: supernova1963 am 08 März 2018, 07:08:41
@curt:
Bitte beachten, das du Änderungen an der /etc/sudoers unbedingt mit sudo visudo /etc/sudoersmachst.

Es ist völlig egal, mit welchem Werkzeug man sudoers bearbeitet, da wirkt keine magische Maschine im Hintergrund. Der ständige Hinweis auf visudo bedeutet lediglich, dass man nicht den geringsten Syntaxfehler machen darf.

Bislang stand dort:

fhem    ALL=(ALL) NOPASSWD: ALL


Nun steht dort:

fhem    ALL=(ALL) NOPASSWD: ALL
fhem    ALL=(ALL) NOPASSWD: /usr/bin/nmap

was im Grunde eine Doppelung ist.

Ja, ich habe nicht vergessen, das System zu booten.

Das beeindruckt FHEM genau gar nicht - der Fehler muss an einer anderen Stelle liegen.
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

@curt: Wenn du dich mit dem user fhem per ssh oder direkt in der shell anmeldest, und
sudo /usr/bin/namp 192.168.127.0/24 192.168.128.0/24 -sn
aufrufst, wird dann noch nach dem Passwort gefragt oder erhältst du direkt eine Ausgabe von nmap in der Console?

Der list fhem Befehl lautet korrekt:

list <devicename>

ohne "_" und beinhaltet mehr Informationen als der fhem.cfg Auszug hergibt.

Gernot

P.S.: Ich kann verstehen, dass es dich nervt, wenn's nicht funktioniert, aber einen Verweis auf die commandref ist imo nicht pampig.

igami

Hast du in FHEM denn auch das sudo Attribut vergeben?
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

curt

Zitat von: supernova1963 am 08 März 2018, 08:29:27
P.S.: Ich kann verstehen, dass es dich nervt, wenn's nicht funktioniert, aber einen Verweis auf die commandref ist imo nicht pampig.

Es war zugegeben wenig geschickt um Hilfe zu bitten und gleichzeitig zu kritisieren. Ja, zugegeben. Leider ist die commandref für mich oft wenig hilfreich. Sicher wird sie hilfreich, wenn ich das Modul schon im Einsatz habe und alles kann. Bein neuen Erschließen hilft mir eher ein Beispiel. Solche sind in der commandref leider sehr dünn gesät.

Zitat von: igami am 08 März 2018, 10:30:22
Hast du in FHEM denn auch das sudo Attribut vergeben?

Hallo allerseits,

ich hab ohne Ende gesucht, Forum, Wiki, commandref. Und nichts in der Sache gefunden. Aber die Blöße, nochmals nachzufragen wollte ich mir nun auch nicht geben.

Dann klickte ich in meiner nmap-Device "Netzwerk" die möglichen Attribute durch. Da steht ja ein Attribut "sudo". Das steht auf "0" und kann man auf "1" setzen. Cool, gleich mal probieren. Ahhh - wie schön. Siehe, es funktioniert. Danke!

Gleich mal ein anderes Problem:
Ich habe mehrere Netzwerke, also 192.168.127.0/24, 192.168.128.0/24 usw. Die Sortierung mit den von @supernova1963 Mitteln nutzt aber nur den vierten Block, so dass die Netzwerke munter durcheinander sind. Auf den ersten Blick dachte ich: Das kann ja nun kein Hit sein, höchstens musst Du herausfinden/fragen, wie man da eine Perl-Subroutine unterbringt. Es ginge zum Beispiel (ungestestet) so (aus https://stackoverflow.com/questions/6917314/how-can-i-sort-a-list-of-ip-addresses-in-perl):


#!/usr/bin/perl

use strict;
use warnings;

sub Compare {
    # TODO: Error checking
    my @a  = split /\./, $a;
    my @b = split /\./, $b;
    # TODO: This might be cleaner as a loop
    return $a[0] <=> $b[0] ||
           $a[1] <=> $b[1] ||
           $a[2] <=> $b[2] ||
           $a[3] <=> $b[3];
}

my @ip = qw( 172.20.1.2 10.10.2.3 10.1.2.3 192.168.1.2 );

@ip = sort Compare @ip;

print join("\n", @ip), "\n";


Dann sah ich bei genauerem Hinsehen, dass es sooo einfach nun doch nicht ist. In dem von @supernova1963 gegebenen Code wird gar nicht sortiert, da wird jediglich der letzte Block als Sortierkriterium zurückgegeben.

Gut, ich könnte die IPv4 in eine dezimale Ganzzahl wandeln und als Sortierkriterium zurückgeben - aber sehr schön sieht das dann nicht aus.

Wie müsste man die Sache anstellen? Den Entwickler des Moduls "nmap" um Aufnahme dieser Sortierung bitten? Oder ist es da vielleicht so gar drin und ich stelle mich nur wieder zu dumm an?
RPI 4 - Jeelink HomeMatic Z-Wave

igami

Zum sortieren gibt es das Attribut leadingZeros
Pi3 mit fhem.cfg + DbLog/logProxy
Komm vorbei zum FHEM Treffen im Kreis Gütersloh! Das nächste Mal im April 2020.

MAINTAINER: archetype, LuftdatenInfo, monitoring, msgDialog, Nmap, powerMap
ToDo: AVScene, FluxLED

justme1968

und was spricht dagegen die in readingsGroup dafür vorgesehene rgSortIP routine zu verwenden?

siehe hier: https://forum.fhem.de/index.php/topic,14425.msg496332.html#msg496332
und hier: https://forum.fhem.de/index.php/topic,57804.msg509823.html#msg509823
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

curt

Zitat von: igami am 09 März 2018, 17:14:12
Zum sortieren gibt es das Attribut leadingZeros

Das führt in beschriebenen Fall fehl.

Zitat von: justme1968 am 09 März 2018, 17:26:38
und was spricht dagegen die in readingsGroup dafür vorgesehene rgSortIP routine zu verwenden?

Issjageil!
Dagegen spräche nichts - wenn ich das doch nur gekannt hätte. Nun kenne ich es und nun funktioniert das wunderfein.

Nun gibt es noch eine kleine Kleinigkeit an der ich trotz vieler Experimente scheitere, die Optik. Mein Bezug ist Beitrag #30, ich nutze den Vorschlag von @supernova1963 , viellleicht kann er mir dabei helfen: Die Spalte 1 (Dreieck und "Nr") sowie Spalte 4 ("Rechnername") halte ich in meinem Fall für entbehrlich, das würde ich gern wegmachen wollen.

Das ich die "sortColumn" dann ändern muss ist mir klar. Mir ist auch klar, dass dem Attribut "valueFormat" anschließend etwas zu ändern ist. Aber ich scheitere trotz vieler Experimente schon am define für die readingsGroup - anschließend sehe ich nur eine leere Tabelle. Was tun?
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

#42
Ich habe laienhaft versucht deinen Vorstellungen entsprechend die Definition zu ändern.
Die Definition einer readingsGroup ist imo wirklich tricky.
Wo ich etwas länger gebraucht habe um es zu verstehen, ist, dass mit dem nmap:@<SpaltenNr> die Spalte angegeben werden muss, in der die Regex (.*)<immer gleicher Teil des Readings-Namens> für die Gruppierung steht.

z.B. Achtung "raw Definition" und ohne rgSortIP Routine!

defmod nmapListe2 readingsGroup <>,<IP-Adresse>,<onl>,<MAC>,<Hersteller> \
nmap:@3,#1_ip,#1_state,(.*)_macAddress,#1_macVendor
attr nmapListe2 valueFormat { if ($VALUE eq 'absent') {\
     "<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>"\
     }\
  elsif ($VALUE eq 'present') {\
     "<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>"\
     }\
  else {\
    ""\
    }\
}
attr nmapListe2 sortFn rgSortIP
attr nmapListe2 valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #FF0000;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #FF0000;; '.$style.'"') if($state eq "absent");;\
}



Hoffentlich hilft es dir und ist nicht ganz falsch,

Gernot

curt

Zitat von: supernova1963 am 10 März 2018, 06:23:44
Ich habe laienhaft versucht deinen Vorstellungen entsprechend die Definition zu ändern.
Die Definition einer readingsGroup ist imo wirklich tricky.

Du beschreibst meine Probleme aber sehr schön.

Und ich habe einen neuen Stand:
Ich habe nun via commandref gelernt, dass man den "Rechnernamen" via 192.168.127.1:Router_eth0 quasi von Hand setzen kann. Ganz prima, die Sache.

Du hast es mir ja verboten, aber ich löschte dann direkt in der fhem.cfg MAC und Hersteller. MAC kommt nicht über verschiedene Netzwerke, damit Hersteller auch nicht. Das bleibt faktisch immer leer. Das sieht bei mir auch ganz schick aus, siehe mal bitte das Bild.

Aber nun zu readingsGroup und der Formatierung - da verstehe ich viele Sachen nicht. Ich zitiere mal den aktuellen Stand meiner fhem-Dinge:

define Netzwerk Nmap 192.168.127.0/24 192.168.128.0/24 192.168.1.0/24
attr Netzwerk absenceThreshold 1
attr Netzwerk devAlias 192.168.127.1:Router_eth0
attr Netzwerk keepReadings 1
attr Netzwerk leadingZeros 0
attr Netzwerk room 92 Intranet
attr Netzwerk sudo 1

define NetzwerkListe readingsGroup <>,<Nr>,<IP-Adresse>,<Status>,<Name> \
Netzwerk:@4,#1_ip,<#1>,#1_state,(.*)_alias
attr NetzwerkListe cellStyle { "c:1" => 'style="text-align:right"',"c:3" => 'style="text-align:center"',"c:4" => 'style="text-align:left"' }
attr NetzwerkListe icon it_network
attr NetzwerkListe room 92 Intranet
attr NetzwerkListe sortColumn 1
attr NetzwerkListe sortFn rgSortIP
attr NetzwerkListe valueFormat { my $ipAddr = substr($READING,0,index($READING,"_"));;\
  #Icon für #1_state.absent Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>") if($VALUE eq "absent");;\
  #Icon für #1_state.present Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>") if($VALUE eq "present");;\
  #Spalte 'Nr' zur Sortierung aus der IP extrahieren    \
  return(substr($VALUE,rindex($VALUE,".")+1)) if(substr($READING,rindex($READING,"_")) eq "_ip");;\
  return("<a url='http://".$ipAddr."' onclick='window.open(\"http://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "80");;\
  return("<a url='https://".$ipAddr."' onclick='window.open(\"https://".$ipAddr."\");; return false;;'>".$VALUE."</a>") if(substr(ReadingsVal($DEVICE,$READING,""),rindex(ReadingsVal($DEVICE,$READING,""),"-")+1) eq "443");;\
  #Anderenfalls soll das valueFormat leer bleiben bzw. nachstehenden Inhalt verwenden\
  return("");;\
}
attr NetzwerkListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #bfbfbf;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #bfbfbf;; '.$style.'"') if($state eq "absent");;\
}


* Eigentlich will ich gar nicht Dein "http bei '*-80'": Ich will den Link auf Port 80 immer. Da habe ich mich erfolglos versucht. (Ich verstand das return-Prinzip nicht.)

* Schaue Dir bitte auch nochmal mein Bild an. Ganz links steht ja "Nr" und danach kann man ja sortieren. Brauche ich so nicht, diese "Nr" sagt in meinem Fall ja nichts. Kann diese "Nr" weg?

Kann ich das auf eine andere Spalte ändern? Oder kann ich das gar wie bei Wikipedia-Tabellen mehrere Spalten sortierbar  machen?

Danke für Deinen Langmut - das nmap-Modul ist geil!
RPI 4 - Jeelink HomeMatic Z-Wave

supernova1963

#44
Zitat von: curt am 13 März 2018, 03:12:55
* Eigentlich will ich gar nicht Dein "http bei '*-80'": Ich will den Link auf Port 80 immer. Da habe ich mich erfolglos versucht. (Ich verstand das return-Prinzip nicht.)

* Schaue Dir bitte auch nochmal mein Bild an. Ganz links steht ja "Nr" und danach kann man ja sortieren. Brauche ich so nicht, diese "Nr" sagt in meinem Fall ja nichts. Kann diese "Nr" weg?

Kann ich das auf eine andere Spalte ändern? Oder kann ich das gar wie bei Wikipedia-Tabellen mehrere Spalten sortierbar  machen?
Ungetestet, nur deinen Code geändert (wo immer er herkommt ;) ): Ohne Nr - Spalte und mit generellem Link bei Klick der IP Adresse:
define NetzwerkListe readingsGroup <>,<Nr>,<IP-Adresse>,<Status>,<Name> \
Netzwerk:@3,<#1>,#1_state,(.*)_alias
attr NetzwerkListe cellStyle { "c:1" => 'style="text-align:right"',"c:2" => 'style="text-align:center"'}
attr NetzwerkListe icon it_network
attr NetzwerkListe room 92 Intranet
attr NetzwerkListe sortFn rgSortIP
attr NetzwerkListe valueFormat { my $ipAddr = substr($READING,0,index($READING,"_"));;\
  #Icon für #1_state.absent Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-rot.png' alt='absent'>") if($VALUE eq "absent");;\
  #Icon für #1_state.present Spalte 'onl' \
  return("<img src='./fhem/images/default/10px-kreis-gruen.png' alt='present'>") if($VALUE eq "present");;\
  #Spalte 'IP' mit Link "http://<IP>" \
  return("<a url=\"http://$ipAddr\" onclick='window.open(\"http://$ipAddr\")')>$ipAddr</a>") if(substr($READING,rindex($READING,"_")) eq "_ip");;\
  return("");;\
}
attr NetzwerkListe valueStyle {$READING =~ m/(.+)_/;;\
my $state = ReadingsVal($DEVICE, $1."_state", "NA");;\
my $style = "";;\
\
return('style="text-align: right;; '.$style.'"') if($state eq "present" && $READING =~ m/_uptime/);;\
return('style="color: #bfbfbf;; text-align: right;; '.$style.'"') if($state eq "absent" && $READING =~ m/_uptime/);;\
\
return('style="'.$style.'"') if($state eq "present");;\
return('style="color: #bfbfbf;; '.$style.'"') if($state eq "absent");;\
}

Spalte "Nr" entfernt:
"<Nr>" aus Überschrift entfernt, Gruppierungsspalte angepaßt: "Netzwerk:@3" und Datenspalte "$1_IP" entfernt. Zusätzlich die Spaltennummern des Attributes "cellStyle" geändert.
URL auf die Werte der IP gelegt.

Wenn ich es richtig verstanden habe, wird das Attribut valueStyle auf jede Wertausgabe der readingsGroup angewendet und die bedingten return's werden statt dem Wert in die Zelle eingetragen. Zur Verfügung stehen die Variablen $READING und $VALUE.

Ich hoffe es hilft,

Gernot