bash script tells me when new computer joins LAN via smbclient
I'm thinking of creating a script that loops until it finds a new IP on the Network created by the router DHCP Server. I am thinking of using NMAP.
nmap 192.168.0.1-254
However I am wondering how I could write the script to identify the newly created IP, then send your self a message (smbclient?) on the local computer, that IP### was created. THe meesage would say " IP/HOST ###, has joined your network"
Any idea's? Examples?
I can help you, partly, with the following script.
I added lots of comments (to clarify the script) but you can edit them out.
BTW. I would use the -sP
parameter with nmap
. Default nmap
will scan lots of ports (slow) and usually it's enough to just use the ping-method (in a local network). If it's not, you can always adjust it.
#!/bin/sh
# the file in which the last know ips are stored
LOG_FILE="last_online.txt"
# use this if you want to "hard" set the ip range
# IP_RANGE="192.168.0.1-100"
#
# however, we use this
# this is more flexible and gets the ip range from the ip-command
# if this doesn't work use the "hard"-setting above
# result is i.e. 192.168.0.1/24
IP_RANGE=`ip -o addr show | grep inet\ | grep eth | cut -d\ -f 7 | head -n1`
# this would give you IP numbers ONLY (no text "appears to be up")
# i didn't use it here because the message "Host xx (ip) appears to be up"
# is (almost) exactly what we want
# ONLINE=`nmap -oG - -sP $IP_RANGE | grep ": Up" | awk '/Host/{print $2}'`
# and this line gives us a complete message-line
# like "Host router (192.168.1.254) appears to be up."
ONLINE=`nmap -sP $IP_RANGE | grep "up\."`
# loop through all the "up" ip addresses
while read -r IP
do
# check if IP-line (with complete appears-text) exists in last know ip-file
if ! grep -Fxq "$IP" $LOG_FILE
then
# if not, do this (note the ! in the if-line)
# my own script for sending udp signal to my windows-app
# /home/util/udp.pl 1200 "$IP"
# smclient winpopup message
# couldn't get this to work in win7 anymore
# echo "$IP" | smbclient -M YOUR_PC
# ok, lets send an e-mail
echo "$IP" | mail -s "$IP" [email protected]
fi
done <<< "$ONLINE"
# write the new online ip addresses to the log_file
echo "$ONLINE" > $LOG_FILE
The only problem i encountered was sending a message to my Windows 7 PC.
I have my own Windows-app (always present in task-tray) which monitors incoming phone-calls and which communicates with my Linux server through UDP-packets. In my script that's the line with /home/util/udp.pl
(to send a UDP-broadcast packet on port 1200).
I tried smbclient
to send a message but couldn't get that to work. Maybe you have more luck on your Ubuntu-box.
So i added a line to send a message via e-mail instead.
You should first try if you can send messages with Ununtu to your other workstations (or local desktop):
echo "hello world" | smbclient -M YOUR_PC
or
echo "hello world" | smbclient -M YOUR_PC -U YOUR_USERNAME
If you can't send anything to you desktop you'll have to settle for the e-mail method.
If you are not using a simple router, but a more capable dns/dhcp service like dnsmasq you can let the DHCPd handle this. I have my dnsmasq configured to run a script every time a DHCP lease is given. You can do this with a single line in the dnsmasq.conf:
dhcp-script=/path/to/new_lease.php
In the script I write the mac address, ip, name and datetime to a database. If the mac address is unknown, it sends an email to me notifying me of the new device in my network.
My PHP script with a SQLite database looks like this:
#!/usr/bin/php
<?php
# The arguments sent to the script are "add" or "del",
# then the MAC address, the IP address and finally the hostname
# if there is one.
$params = extract_array($argv, array(null, 'command', 'mac', 'ip', 'name'));
extract($params);
switch ($command) {
case 'old':
case 'add':
$stmt = $db->prepare("UPDATE leases SET ip='' WHERE ip=:ip");
$stmt->bindParam(":ip", $ip);
$stmt->execute();
if ($stmt->rowCount() == 0) {
// new device
$stmt = $db->prepare("SELECT vendor_name FROM vendors WHERE mac_prefix=:mac COLLATE NOCASE");
$stmt->bindParam(":mac", $mac_prefix);
$mac_prefix = substr($mac,0,8);
if ($stmt->execute()) {
$result = $stmt->fetch();
$vendor = $result['vendor_name'];
}
// send email
}
$stmt = $db->prepare("INSERT OR IGNORE INTO leases (mac) VALUES (:mac)");
$stmt->bindParam(":mac", $mac);
$stmt->execute();
$stmt = $db->prepare("UPDATE leases SET ip=:ip,name=:name,`date`=DATETIME('now') WHERE mac=:mac");
$stmt->bindParam(":mac", $mac);
$stmt->bindParam(":ip", $ip);
$stmt->bindParam(":name", $name);
$stmt->execute();
break;
case 'delete':
$stmt = $db->prepare("UPDATE leases SET ip='' WHERE ip=:ip");
$stmt->bindParam(":ip", $ip);
$stmt->execute();
break;
}
?>