1
1
Fork 0
mirror of https://github.com/BillDietrich/lanwatch.git synced 2024-05-09 11:36:03 +02:00

basic ARP working

This commit is contained in:
Bill Dietrich 2020-03-22 23:34:24 +01:00
parent 3fdda7abb1
commit c486efb890
4 changed files with 424 additions and 1 deletions

174
README.md
View File

@ -1,2 +1,174 @@
# lanwatch
Report new devices that appear on LAN, and maintain an inventory of devices
Report new devices that appear on LAN, and maintain an inventory of devices.
[IN PROTOTYPING STAGE; NOT DANGEROUS, BUT NOT READY FOR USE !!!]
![Do not use](http://4.bp.blogspot.com/-1lTbJMSPZaE/Tyu0eri0bOI/AAAAAAAAEP0/L6yk8jqGUwI/s1600/abnormal%2Bbrain.jpg "Do not use")
https://github.com/BillDietrich/lanwatch
---
## Basic installation
### Copy the minimal files to disk
In the GitHub repo, click the "Clone or download" button, then click the "Download ZIP" button. Save the ZIP file to disk.
#### On Linux
Copy file lanwatch.py from the ZIP file to /usr/local/bin
#### On Windows 10
Copy files lanwatch.cmd and lanwatch.py from the ZIP file to some folder.
### Requires Python 3.3+
#### On Linux
```bash
# See what is installed
python3 --version
# If it's not installed:
# On Debian-type Linux:
sudo apt-get update
sudo apt-get install python3
# After python is installed:
pip3 install plyer
pip3 install scapy
```
#### On Windows 10
Open windows command prompt: Win+X and then choose "Command Shell (as Administrator)".
Type "python -V"
If Python is not installed:
1. Go to https://www.python.org/downloads/windows/
2. Download installer (EXE).
3. Run the installer.
4. In the installer, check the checkboxes "Installer launcher for all users" and "Add Python 3 to PATH" before you click on the Install button.
5. Near end of installation, click on "Disable limit on PATH length".
6. After installer finishes, open windows command prompt (Win+X and then choose "Command Shell (as Administrator)") and type "python -V" to verify the installation.
With Python installed:
* pip install requests
* pip install pywin32
* pip install plyer
* pip install plyer
---
## Quick-start to try lanwatch: run it manually
### On Linux command-line
```bash
sudo lanwatch.py
```
See desktop notifications.
### On Windows 10
Double-click on lanwatch.cmd file.
See notifications in "action center" at right end of system tray.
---
## Ways lanwatch can report IP address changes
You can choose one or more of the following:
### Desktop notifications
(This is the default setting; no edit needed unless you change things later.)
Edit lanwatch.py to set gsUIChoice to "notification".
You will see notifications on the desktop or in the "action center".
### To stdout
Edit lanwatch.py to set gsUIChoice to "stdout".
You will see reports in the command-line window where you ran lanwatch.py.
### To system log
Edit lanwatch.py to set gsUIChoice to "syslog".
You will see reports in the system log:
For Linux, to see output, on command-line do
```bash
sudo journalctl | grep lanwatch
```
For Win10, to see output, run Event Viewer application. Look in administrative events from Applications, and look for events with Origin "lanwatch".
---
## Ways to run lanwatch
### Run the program manually
(Easiest way to start out; try this first.)
#### On Linux command-line
```bash
sudo lanwatch.py
```
Then try steps in the "Testing" section, below.
#### On Windows 10
Double-click on lanwatch.cmd file.
Then try steps in the "Testing" section, below.
### Run the program automatically
#### From a Linux systemd service started at system boot time
```bash
sudo cp lanwatch.py /usr/local/bin # you may have done this already
sudo edit /usr/local/bin/lanwatch.py # to set gsUIChoice to "syslog".
sudo cp lanwatch.service /etc/systemd/system
```
After rebooting, on command-line do
```bash
sudo journalctl | grep lanwatch
```
Then try steps in the "Testing" section, below, and check the journal again.
#### From a Windows 10 task started when you log in
1. Go to Control Panel / Administrative Tools / Program Tasks.
2. In Actions (rightmost pane), click on Local Tasks / Create Basic Task.
3. Set Name of Task to "lanwatch" (not mandatory, just for clarity).
4. Set various fields.
5. For "When do you want to run the task ?" select "At start of session".
6. For "What action do you want to take for this task ?" select "Run a program".
7. For "Program or Script" select the lanwatch.cmd file.
8. Save the task.
9. The task will appear in the list of Active Tasks (bottom of middle pane).
10. Log out and back in.
11. lanwatch should report an IP address change, in whatever way it's configured to report.
---
## Testing
1. After lanwatch.py starts (either via command-line or service), add a new device on the LAN.
---
## Limitations
* Tested only on Linux Mint 19.3 Cinnamon with 5.3 kernel, and Windows 10 Home.
* Tested only with IPv4, not IPv6.
* On Linux, tested only with strongSwan/IPsec to Windscribe VPN.
* On Win10, tested only without VPN.
* Not tested on a LAN with no internet access.
* Requires Python 3.3 or greater.
* Can't guarantee that quick, transient device appear/disappear will be detected.
## To-Do
---
## Privacy Policy
This code doesn't collect, store, process, or transmit anyone's identity or personal information in any way. It does not modify or transmit your system's data outside your system in any way.

3
lanwatch.cmd Executable file
View File

@ -0,0 +1,3 @@
python ./lanwatch.py
pause

224
lanwatch.py Executable file
View File

@ -0,0 +1,224 @@
#!/usr/bin/env python3
#--------------------------------------------------------------------------------------------------
# lanwatch.py Report new devices that appear on LAN, and maintain an inventory of devices.
# https://github.com/BillDietrich/lawatch
# If this is going to run at boot-time, put this file in the root filesystem
# (maybe in /usr/local/bin) instead of under /home, because /home may not
# be mounted or decrypted when the service starts.
# on Linux, to see if app is running in background:
# sudo ps -ax | grep lanwatch
# Copyright Bill Dietrich 2020
# https://www.howtogeek.com/423709/how-to-see-all-devices-on-your-network-with-nmap-on-linux/
# https://itsfoss.com/how-to-find-what-devices-are-connected-to-network-in-ubuntu/
# https://itsfoss.com/nutty-network-monitoring-tool/
# https://quassy.github.io/elementary-apps/Nutty/
# turn off VPN
# python:
# https://scapy.net/
# https://github.com/secdev/scapy
# https://github.com/williamajayi/network-scanner
# https://github.com/Honeypot-R8o/ARP-Alert/blob/master/arp-alert.py
# https://docs.python.org/3/library/csv.html
#--------------------------------------------------------------------------------------------------
# edit these to change the behavior of the app
gsIPRange = '192.168.0.0/24'
gsAccessType = 'HTTP' # HTTP or DNS
gsUIChoice = 'stdout' # one or more of: notification syslog stdout
gsDatabase = 'lanwatch.csv'
#--------------------------------------------------------------------------------------------------
#import subprocess
import sys
import platform
import time # https://www.cyberciti.biz/faq/howto-get-current-date-time-in-python/
import requests
import ipaddress
import os # https://docs.python.org/3/library/os.html
import socket
import scapy.all as scapy
import csv
gbOSLinux = (platform.system() == "Linux")
gbOSWindows = (platform.system() == "Windows")
# for Linux:
if gbOSLinux:
import syslog # https://docs.python.org/2/library/syslog.html
from plyer import notification # https://plyer.readthedocs.io/en/latest/#
# and do "pip3 install plyer"
# for Windows 10:
if gbOSWindows:
import win32evtlogutil
import win32evtlog
# and do "pip install pywin32"
from plyer import notification # https://plyer.readthedocs.io/en/latest/#
# and do "pip install plyer"
#--------------------------------------------------------------------------------------------------
# state variables
gsConnectionState = 'none' # none or 'rejected by site' or connected
gsOldIPAddress = 'start' # start or 'internal error' or 'no network connection' or connected'
gnSleep = 0
gnNextSiteIndex = 0
#--------------------------------------------------------------------------------------------------
# adapted from https://github.com/williamajayi/network-scanner/blob/master/network_scanner.py
def DoARPScan():
global gsIPRange
arp_req = scapy.ARP(pdst=gsIPRange) # get an arp request
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff") # Set the destination mac address
arp_broadcast = broadcast/arp_req # combine the broadcast and request to send to the network
# (scapy.srp) send and respond + allow ether frame for the answered resquests
answered = scapy.srp(arp_broadcast, timeout=1, verbose=False)[0]
arrsMACAddress = []
for element in answered:
# print('element '+str(element))
arrsMACAddress.append(element[1].hwsrc)
return arrsMACAddress
#--------------------------------------------------------------------------------------------------
# adapted from https://github.com/williamajayi/network-scanner/blob/master/network_scanner.py
def get_vendor(mac_address):
r = requests.get("https://api.macvendors.com/" + mac_address)
if r.status_code == 200:
return r.text
else:
return "Unknown vendor"
#--------------------------------------------------------------------------------------------------
def ReportNewDevice(sMsg):
if 'stdout' in gsUIChoice:
print(time.strftime("%H:%M:%S")+': '+sMsg)
if 'notification' in gsUIChoice:
# https://plyer.readthedocs.io/en/latest/#
# https://github.com/kivy/plyer
# no way to have notification remain permanently
if gbOSLinux:
# notifications appear both on desktop (briefly) and in tray
notification.notify(title='New device on LAN', message=sMsg, app_name='lanwatch', timeout=8*60*60)
if gbOSWindows:
notification.notify(title='New device on LAN', message=sMsg, app_name='lanwatch', timeout=8*60*60)
if 'syslog' in gsUIChoice:
if gbOSLinux:
syslog.syslog(sMsg)
# on Linux, to see output:
# sudo journalctl --pager-end
# or
# sudo journalctl | grep lanwatch
if gbOSWindows:
# https://stackoverflow.com/questions/51385195/writing-to-windows-event-log-using-win32evtlog-from-pywin32-library
# https://www.programcreek.com/python/example/96660/win32evtlogutil.ReportEvent
# https://docs.microsoft.com/en-us/windows/win32/eventlog/event-logging-elements
win32evtlogutil.ReportEvent(
"lanwatch",
#7040, # event ID # https://www.rapidtables.com/convert/number/decimal-to-binary.html
1610612737, # event ID # https://www.rapidtables.com/convert/number/decimal-to-binary.html
eventCategory=1,
eventType=win32evtlog.EVENTLOG_INFORMATION_TYPE,
strings=[sMsg],
data=b"")
# https://rosettacode.org/wiki/Write_to_Windows_event_log#Python
# on Win10, to see output:
# run Event Viewer application.
#--------------------------------------------------------------------------------------------------
if __name__ == '__main__':
try:
objDatabaseFile = open(gsDatabase, "r", newline='')
except:
print('open "'+gsDatabase+'" failed, creating file')
try:
f = open(gsDatabase,"w+")
f.close()
print('past close')
objDatabaseFile = open(gsDatabase, "r", newline='')
except:
print('create "'+gsDatabase+'" failed')
sys.exit()
objDatabaseReader = csv.reader(objDatabaseFile, delimiter=' ', quotechar='|')
for row in objDatabaseReader:
print(', '.join(row))
objDatabaseReader = 0
objDatabaseFile.close()
objDatabaseFile = open(gsDatabase, "w", newline='')
objDatabaseWriter = csv.writer(objDatabaseFile, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL)
objDatabaseWriter.writerow([time.strftime("%H:%M:%S")] + ['78901'])
objDatabaseWriter.writerow([time.strftime("%H:%M:%S")] + ['jklmn'])
objDatabaseWriter = 0
objDatabaseFile.close()
while True:
arrsMACAddress = DoARPScan()
print('arrsMACAddress '+str(arrsMACAddress))
for sMACAddress in arrsMACAddress:
sVendor = get_vendor(sMACAddress)
print('sMACAddress '+sMACAddress+' == vendor "'+sVendor+'"')
time.sleep(1)
ReportNewDevice('New device on LAN: zzzzzzzzzzzzzzz')
try:
time.sleep(15)
except KeyboardInterrupt:
sys.exit()
#--------------------------------------------------------------------------------------------------

24
lanwatch.service Normal file
View File

@ -0,0 +1,24 @@
#--------------------------------------------------------------------------------------------------
# lanwatch.service Run lanwatch.py when system starts, after network is up.
# Put this file in /etc/systemd/system
# Copyright Bill Dietrich 2020
#--------------------------------------------------------------------------------------------------
[Unit]
Description=LANWatch
# would like this to start ASAP, but I think running before "online" causes problems ?
After=network-online.target
#After=network.target
Before=graphical.target
Before=multi-user.target
[Service]
Type=simple
ExecStart=/usr/local/bin/lanwatch.py
[Install]
WantedBy=multi-user.target
#--------------------------------------------------------------------------------------------------