Skip to content

Instantly share code, notes, and snippets.

@fabiotnt
Last active August 17, 2025 17:32
Show Gist options
  • Save fabiotnt/01b33c1b5aeb527e331599c57a657d60 to your computer and use it in GitHub Desktop.
Save fabiotnt/01b33c1b5aeb527e331599c57a657d60 to your computer and use it in GitHub Desktop.
Network Scanner

Network Scanner (nmap-based)

This is a simple Bash script for Linux and macOS that scans your local network using nmap.
It automatically detects your active IP address and subnet, then lists all active devices in a clean table:

IP               Hostname                                 MAC
192.168.0.1      router.local                             00:11:22:33:44:55
192.168.0.42     my-macbook.local                        AA:BB:CC:DD:EE:FF
192.168.0.100    -                                       11:22:33:44:55:66

✨ Features

  • Works on Linux and macOS
  • Auto-detects active IP and CIDR subnet
  • Uses nmap to find active hosts
  • Displays results in a table: IP | Hostname | MAC
  • Stops with a clear message if dependencies are missing

📦 Requirements

  • nmap
  • Linux: ip
  • macOS: ifconfig, route, ipconfig

Install on Linux (Debian/Ubuntu)

sudo apt update
sudo apt install nmap

Install on macOS (with Homebrew)

brew install nmap

🚀 Usage

  1. Clone or download this gist
  2. Make the script executable:
    chmod +x scan-network.sh
  3. Run it:
    ./scan-network.sh

🛠 Example output

📡 Active IP:       192.168.0.42 (wlan0)
🌐 Subnet (CIDR):   192.168.0.42/24
🔎 Running: nmap -sn 192.168.0.42/24 ...

IP               Hostname                                 MAC
192.168.0.1      router.local                             00:11:22:33:44:55
192.168.0.42     my-macbook.local                        AA:BB:CC:DD:EE:FF
192.168.0.100    -                                       11:22:33:44:55:66

⚠️ Disclaimer

This script is intended for educational and network diagnostic purposes only.
Do not use it on networks where you do not have permission.

MIT License
Copyright (c) 2025 Fabio Nicolau | Banana Groove Studios
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
#!/usr/bin/env bash
set -euo pipefail
# ============================================================
# Network Scanner using nmap
# - Auto-detects active IP and subnet (Linux/macOS)
# - Scans the subnet with nmap
# - Outputs a table: IP | Hostname | MAC
#
# Requirements:
# - nmap
# - Linux: ip
# - macOS: ifconfig, route, ipconfig
#
# Author: Fábio Nicolau | Banana Groove Studios
# License: MIT
# ============================================================
need() { command -v "$1" >/dev/null 2>&1 || { echo "❌ Error: '$1' not found. Please install it."; exit 1; }; }
# Mandatory dependency
need nmap
OS="$(uname -s)"
# Convert macOS netmask hex (e.g., 0xffffff00) to CIDR (/24) — portable (no ${var,,}, no here-strings)
hexmask_to_cidr() {
local hex bin cidr
hex="$1"
hex="${hex#0x}"
# lower-case via tr for portability
hex="$(echo "$hex" | tr 'A-F' 'a-f')"
bin=""
local i ch
for ((i=0; i<${#hex}; i++)); do
ch="${hex:$i:1}"
case "$ch" in
0) bin="${bin}0000";;
1) bin="${bin}0001";;
2) bin="${bin}0010";;
3) bin="${bin}0011";;
4) bin="${bin}0100";;
5) bin="${bin}0101";;
6) bin="${bin}0110";;
7) bin="${bin}0111";;
8) bin="${bin}1000";;
9) bin="${bin}1001";;
a) bin="${bin}1010";;
b) bin="${bin}1011";;
c) bin="${bin}1100";;
d) bin="${bin}1101";;
e) bin="${bin}1110";;
f) bin="${bin}1111";;
*) : ;;
esac
done
cidr="$(echo "$bin" | grep -o "1" | wc -l | tr -d ' ')"
echo "$cidr"
}
IP="" CIDR="" SUBNET="" IFACE=""
if [[ "$OS" == "Linux" ]]; then
need ip
IFACE="$(ip route get 1.1.1.1 2>/dev/null | awk '/dev /{for (i=1;i<=NF;i++) if ($i=="dev") {print $(i+1); exit}}')"
if [[ -z "${IFACE:-}" ]]; then
echo "❌ Error: Could not detect default interface on Linux."
exit 1
fi
IP_CIDR="$(ip -o -f inet addr show dev "$IFACE" scope global | awk '{print $4}' | head -n1)"
IP="${IP_CIDR%/*}"
CIDR="${IP_CIDR#*/}"
SUBNET="$IP/$CIDR"
elif [[ "$OS" == "Darwin" ]]; then
need route
need ifconfig
need ipconfig
IFACE="$(route -n get default 2>/dev/null | awk '/interface:/{print $2}')"
if [[ -z "${IFACE:-}" ]]; then
echo "❌ Error: Could not detect default interface on macOS."
exit 1
fi
IP="$(ipconfig getifaddr "$IFACE" 2>/dev/null || true)"
if [[ -z "${IP:-}" ]]; then
IP="$(ifconfig "$IFACE" | awk '/inet /{print $2; exit}')"
fi
HEXMASK="$(ifconfig "$IFACE" | awk '/netmask/{print $4; exit}')"
CIDR="$(hexmask_to_cidr "$HEXMASK")"
SUBNET="$IP/$CIDR"
else
echo "❌ Error: Unsupported OS ($OS)"
exit 1
fi
if [[ -z "${IP:-}" || -z "${CIDR:-}" ]]; then
echo "❌ Error: Could not detect IP/CIDR automatically."
exit 1
fi
echo "Active IP: $IP ($IFACE)"
echo "Subnet (CIDR): $SUBNET"
echo "Running nmap -sn $SUBNET ..."
echo
# Run nmap and format output (table IP | Hostname | MAC)
nmap -sn "$SUBNET" -oG - 2>/dev/null | \
awk '
BEGIN { FS=" "; }
/^Host: / && /Status: Up/ {
ip=$2;
host=$3; gsub(/[()]/,"",host);
if (host=="" || host=="()") host="-";
hosts[ip]=host;
order[++n]=ip;
}
/^MAC: / {
mac=$2;
macs[ip]=mac;
}
END {
printf "%-15s %-40s %-17s\n", "IP", "Hostname", "MAC";
for (i=1;i<=n;i++) {
ip=order[i];
mac=(macs[ip] ? macs[ip] : "-");
printf "%-15s %-40s %-17s\n", ip, hosts[ip], mac;
}
}
' | sort -t. -k1,1n -k2,2n -k3,3n -k4,4n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment