#!/usr/bin/env bash
# port-scan.sh - checks which TCP ports accept a connection.
# Connect scan only (uses bash /dev/tcp). No raw sockets, no root needed.
# Only scan machines you own or are authorised to test.
# Run: bash port-scan.sh [host] [ports]
#   ports is a comma list (default: common services)

set -u

HOST="${1:-127.0.0.1}"
PORTS="${2:-21,22,25,53,80,110,135,139,143,443,445,993,995,1433,3000,3306,3389,5000,5432,5900,6379,8080,8443,9200,27017}"
TIMEOUT_S="${3:-0.3}"

echo "Scanning $HOST - connect scan, ${TIMEOUT_S}s timeout each"
echo "(scan machines you own or are authorised to test)"
echo ""

open=""
old_ifs=$IFS
IFS=','
for port in $PORTS; do
  port=$(echo "$port" | tr -d ' ')
  case "$port" in
    ''|*[!0-9]*) continue ;;
  esac
  if timeout "$TIMEOUT_S" bash -c "echo > /dev/tcp/$HOST/$port" 2>/dev/null; then
    printf '  %5s  open\n' "$port"
    open="$open $port"
  fi
done
IFS=$old_ifs

echo ""
if [ -z "$open" ]; then
  echo "No open ports found in the scanned list."
else
  echo "Open ports:$(echo $open)"
fi
echo ""
echo "Note: a filtered (firewalled) port looks the same as a closed one to this kind of scan."