#!/bin/bash # # Copyright (c) 2012 # # Authors: Wild Man, Krytarik # Helpers: chili555 # # This script gathers the infos necessary for troubleshooting a wireless # connection and saves them in a text file, wrapping it in an archive if it # exceeds the 200 KB size limit for ".txt" attachments. # ############################################################################## # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # SCRIPTDATE="2026-10-29 3:55 -0700" FILEBASE="wireless-info" OUTPUTDIR="$PWD" OUTPUTDIRFB="/tmp" MODMATCHES="(air|ar5|at7|ath[^3]?|b43|bcma|brcm|carl|ipw|iwl|mt[a-z0-9]+|ndis|r(818|8192[eu]|871|92su)|8(188|189|192|723|812)[acde][esu]|rt[23567]|rtl|ssb|wl|rtw8|(cfg|mac)80211)" LSMODMATCHES="(wmi|(dell|ideapad)[-_]laptop)" IFACEMATCHES="(wlan[0-9]|wlp[0-9]+[a-z0-9]*|eth[0-9]|enp[0-9]+[a-z0-9]*)" DMESGMATCHES="(firmware|[nN]etwork|sdio|SDIO)" NMPROFMATCHES="\(\[connection\]\|id=\|type=\|permissions=\|autoconnect=\|\[802-11-wireless\]\|\[wifi\]\|ssid=\|bssid=\|mac-address\(-blacklist\)\?=\|mtu=\|\[802-1x\]\|[[:graph:]]*ca-certs\?=\|\[ipv[46]\]\|method=\)" DMESGEXCL="apparmor|(cfg|mac)80211" MODINFOINCL="filename|license|description|depends|retpoline|intree|name|vermagic|parm" MODPROBEXCL="(alsa-base|blacklist-(firewire|framebuffer|modem|oss|watchdog)|fglrx|nvidia|fbdev|bumblebee)" PMUTILSEXCL="/etc/pm/(power.d/(95hdparm-apm|intel-audio-powersave|sata_alpm)|sleep.d/(10_grub-common|10_unattended-upgrades.*|novatel_3g.*))" NETMGRNAMES=("NetworkManager" "Wicd" "ConnMan" "iwd") NETMGRPATHS=("/usr/sbin/NetworkManager" "/usr/sbin/wicd" "/usr/sbin/connmand" "/usr/bin/iwd") DEC2BI=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}) DEC2HEX=($(printf "%02x " {0..255})) export LANG="en_US.UTF-8" export LANGUAGE="en_US:en" export LC_ALL="en_US.UTF-8" if [ -t 0 ]; then DIALOGAPP="terminal" DIALOGBREAK=" " TERMOUT="yes" elif [ -x /usr/bin/zenity ]; then DIALOGAPP="zenity" DIALOGBREAK="\n" elif [ -x /usr/bin/kdialog ]; then DIALOGAPP="kdialog" DIALOGBREAK="\n" else exit 1 fi # Streamlined modern privilege escalation if [ -t 0 ]; then SUDO="sudo" elif [ -x /usr/bin/pkexec ]; then SUDO="pkexec" fi dialog_info () { case $DIALOGAPP in terminal) printf "%b\n" "$1" ;; zenity) zenity --info --text="$1" ;; kdialog) kdialog --msgbox "$1" ;; esac } dialog_error () { case $DIALOGAPP in terminal) printf "%b\n" "$1" >&2 ;; zenity) zenity --error --text="$1" ;; kdialog) kdialog --error "$1" ;; esac } dialog_question () { case $DIALOGAPP in terminal) local INPUT read -r -p "$1 [Y/n]: " INPUT echo "${INPUT,,}" ;; zenity) zenity --question --text="$1" || echo "no" ;; kdialog) kdialog --yesno "$1" || echo "no" ;; esac } ip6-mac () { for MAC in "$@"; do OCT1BI=${DEC2BI[0x${MAC:0:2}]} OCT1BI7=$((${OCT1BI:6:1} - 1)) OCT1BIM="${OCT1BI:0:6}${OCT1BI7#-}${OCT1BI:7}" IP6S+=${IP6S:+$'\n'}"${DEC2HEX[2#$OCT1BIM]}${MAC:3:2}:${MAC:6:2}ff:fe${MAC:9:2}:${MAC:12:2}${MAC:15:2}" done sed 's/\(^\|:\)0\+\([[:alnum:]]\)/\1\2/g;s/^\([0:]\+\)/\\(::\\|\1\\)/' <<< "$IP6S" } exec 3>&1 4>&2 exec 1> "$OUTPUTDIR/$FILEBASE.txt" || { dialog_error "${TERMOUT+\n}Cannot write output file in \"$OUTPUTDIR\",${DIALOGBREAK}trying in \"$OUTPUTDIRFB\" instead.${TERMOUT+\n}" OUTPUTDIR="$OUTPUTDIRFB" exec 1> "$OUTPUTDIR/$FILEBASE.txt" || { dialog_error "${TERMOUT+\n}Cannot write output file in \"$OUTPUTDIR\" either, aborting.${TERMOUT+\n}" exit 1 } } exec 2>&1 printf "\n########## wireless info START ##########\n\n" REPORTDATE=$(date +"%d %b %Y %H:%M %Z %z") SCRIPTDATE=$(date -u -d "$SCRIPTDATE" +"%d %b %Y %H:%M %Z %z") if command -v last >/dev/null 2>&1; then LASTBOOTDT=$(last -FRn 1 reboot 2>/dev/null | sed -n 's/.*system boot[ ]\+\(.\+\) - .*/\1/p') if [ -n "$LASTBOOTDT" ]; then LASTBOOTDT=$(date -d "$LASTBOOTDT" +"%d %b %Y %H:%M %Z %z" 2>/dev/null) fi fi if [ -z "$LASTBOOTDT" ] && command -v uptime >/dev/null 2>&1; then UPTIME_SINCE=$(uptime -s 2>/dev/null) if [ -n "$UPTIME_SINCE" ]; then LASTBOOTDT=$(date -d "$UPTIME_SINCE" +"%d %b %Y %H:%M %Z %z" 2>/dev/null) fi fi LASTBOOTDT="${LASTBOOTDT:-Unknown}" printf "Report from: %s\n" "$REPORTDATE" printf "Booted last: %s\n" "$LASTBOOTDT" printf "Script from: %s\n\n" "$SCRIPTDATE" printf "\n##### release ###########################\n\n" RELEASE_FILE="/etc/os-release" if [ -f "/var/lib/snapd/hostfs/etc/os-release" ]; then RELEASE_FILE="/var/lib/snapd/hostfs/etc/os-release" fi if [ -f "$RELEASE_FILE" ]; then OS_NAME=$(awk -F= '$1=="NAME"{print $2}' "$RELEASE_FILE" | tr -d '"') OS_VERSION=$(awk -F= '$1=="VERSION"{print $2}' "$RELEASE_FILE" | tr -d '"') OS_ID=$(awk -F= '$1=="ID"{print $2}' "$RELEASE_FILE" | tr -d '"') OS_VERSION_ID=$(awk -F= '$1=="VERSION_ID"{print $2}' "$RELEASE_FILE" | tr -d '"') OS_VERSION_CODENAME=$(awk -F= '$1=="VERSION_CODENAME"{print $2}' "$RELEASE_FILE" | tr -d '"') OS_UBUNTU_CODENAME=$(awk -F= '$1=="UBUNTU_CODENAME"{print $2}' "$RELEASE_FILE" | tr -d '"') DIST_ID=$(echo "$OS_ID" | awk '{print toupper(substr($0,1,1)) substr($0,2)}') CODENAME="${OS_VERSION_CODENAME:-$OS_UBUNTU_CODENAME}" echo "Distributor ID: ${DIST_ID:-Linux}" echo "Description: ${OS_VERSION:-$OS_NAME}" echo "Release: ${OS_VERSION_ID}" echo "Codename: ${CODENAME}" else echo "Release information unavailable." fi printf "\n##### kernel ############################\n\n" uname -srvmpio echo sed 's/root=[^ ]*//;s/[ ]\+/, /g;s/^BOOT_IMAGE=[^ ]*/Parameters:/' /proc/cmdline printf "\n##### desktop environment ###############\n\n" REAL_HOME="$HOME" if [ -n "$SUDO_USER" ]; then REAL_HOME="$(getent passwd "$SUDO_USER" | cut -d: -f6)" fi if [ -f "$REAL_HOME/.dmrc" ]; then printf -- "--- .dmrc ---\n" cat "$REAL_HOME/.dmrc" echo else echo ".dmrc not found for the user session." fi if [ -f "$REAL_HOME/.xprofile" ]; then printf -- "--- .xprofile ---\n" cat "$REAL_HOME/.xprofile" echo fi echo "XDG_CURRENT_DESKTOP: ${XDG_CURRENT_DESKTOP:-Not set}" echo "DESKTOP_SESSION: ${DESKTOP_SESSION:-Not set}" printf "\n##### lspci hardware info ###############\n\n" if command -v lspci >/dev/null 2>&1; then lspci -nnk 2> >(grep -v "pcilib:" >&2) | awk ' BEGIN { printer=0 } /^[0-9a-f]{2}:[0-9a-f]{2}\.[0-9]/ { if ($0 ~ /Network controller|Ethernet controller/) { printer=1 } else { printer=0 } } printer { print } ' else echo "'lspci' command is not available." fi printf "\n##### lsusb #############################\n\n" lsusb printf "\n##### rfkill ############################\n\n" if command -v rfkill >/dev/null 2>&1; then rfkill list else echo "'rfkill' command is not available." fi printf "\n##### secure boot #######################\n\n" if [ -x /usr/bin/mokutil ]; then mokutil --sb else echo "'mokutil' is not installed." fi printf "\n##### lsmod #############################\n\n" if command -v lsmod >/dev/null 2>&1; then LSMOD=$(lsmod 2>/dev/null | grep -E "(^|[[:punct:] ])($MODMATCHES|$LSMODMATCHES)[^[:punct:] ]*([[:punct:] ]|$)") if [ -n "$LSMOD" ]; then echo "$LSMOD" else echo "No matching wireless modules found in lsmod output." fi else echo "'lsmod' command is not available." fi # Enhanced Driver Module Management (Supports DKMS for Ubuntu/Debian/Arch/Mint & Akmods for Fedora/RHEL/CentOS) printf "\n##### dkms / akmods status #############\n\n" if command -v dkms >/dev/null 2>&1; then DKMS_TREE="/var/lib/dkms" if [ -d "/var/lib/snapd/hostfs/var/lib/dkms" ]; then DKMS_TREE="/var/lib/snapd/hostfs/var/lib/dkms" fi DKMS_OUT=$(dkms status --dkmstree "$DKMS_TREE" 2>/dev/null) if [ -n "$DKMS_OUT" ]; then echo "$DKMS_OUT" else echo "No DKMS modules found or tree is empty." fi elif [ -d "/var/lib/snapd/hostfs/var/cache/akmods" ] || [ -d "/var/cache/akmods" ]; then echo "Fedora/RHEL Akmods cache found:" ls -la /var/lib/snapd/hostfs/var/cache/akmods 2>/dev/null || ls -la /var/cache/akmods 2>/dev/null else echo "Neither DKMS nor Akmods module tools found." fi printf "\n##### interfaces ########################\n\n" NET_BASE="/etc/network" if [ -d "/var/lib/snapd/hostfs/etc/network" ]; then NET_BASE="/var/lib/snapd/hostfs/etc/network" fi for IFACESFILE in "$NET_BASE/interfaces" "$NET_BASE"/interfaces.d/*; do [ -f "$IFACESFILE" ] || continue IFACESFLCNT=$(sed '/^#/d;s/^wpa-psk [[:graph:]]\+/wpa-psk /' "$IFACESFILE" 2>/dev/null) if [ -n "$IFACESFLCNT" ]; then DISPLAY_PATH="${IFACESFILE#/var/lib/snapd/hostfs}" printf "[%s]\n%s\n\n" "$DISPLAY_PATH" "$IFACESFLCNT" fi done # openSUSE Network Configuration Check (Wicked / sysconfig) SUSE_NET_DIR="/etc/sysconfig/network" if [ -d "/var/lib/snapd/hostfs/etc/sysconfig/network" ]; then SUSE_NET_DIR="/var/lib/snapd/hostfs/etc/sysconfig/network" fi if [ -d "$SUSE_NET_DIR" ]; then for susefile in "$SUSE_NET_DIR"/ifcfg-*; do [ -f "$susefile" ] || continue SUSECNT=$(grep -v -E '^(#|$)' "$susefile" 2>/dev/null) if [ -n "$SUSECNT" ]; then DISPLAY_PATH="${susefile#/var/lib/snapd/hostfs}" printf "[openSUSE %s]\n%s\n\n" "$DISPLAY_PATH" "$SUSECNT" fi done fi printf "\n##### ifconfig / ip address #############\n\n" if command -v ip >/dev/null 2>&1; then IFCONFIG=$(ip address show 2>/dev/null) elif command -v ifconfig >/dev/null 2>&1; then IFCONFIG=$(ifconfig -a 2>/dev/null) else echo "'ip' command is not available (package \"iproute2\")." IFCONFIG="" fi if [ -n "$IFCONFIG" ]; then echo "$IFCONFIG" IFCONFIG_FLATTENED=$(sed -n '1h; 1!H; ${g;s/\n /\\ /g;p}' <<< "$IFCONFIG") IFACESETH=($(sed -n 's#^[0-9]\+: \([^ :]\+\):.* link/ether.*#\1#p; s/^\([^ :]\+\):\?.* \(Link encap:Ethernet\|ether\).*/\1/p' <<< "$IFCONFIG_FLATTENED")) if (( ${#IFACESETH[@]} > 0 )); then IFETHMATCHES="${IFACESETH[*]}" IFACEMATCHES="($IFACEMATCHES|(${IFETHMATCHES// /|}))" fi else echo "Failed to retrieve network interface configuration." fi printf "\n##### iw link ##########################\n\n" if command -v iw >/dev/null 2>&1; then wireless_interfaces=$(iw dev | awk '$1=="Interface"{print $2}') if [ -z "$wireless_interfaces" ]; then echo "No wireless interfaces found." else for iface in $wireless_interfaces; do printf -- "--- Interface: %s ---\n" "$iface" iw dev "$iface" link echo done fi else echo "'iw' command is not available." fi printf "\n##### route #############################\n\n" if command -v ip >/dev/null 2>&1; then ip route show 2>/dev/null elif command -v route >/dev/null 2>&1; then route -n 2>/dev/null else echo "'ip' command is not available." fi printf "\n##### resolv.conf #######################\n\n" RESOLV_PATH="/etc/resolv.conf" if [ -f "/var/lib/snapd/hostfs/etc/resolv.conf" ]; then RESOLV_PATH="/var/lib/snapd/hostfs/etc/resolv.conf" fi if [ -f "$RESOLV_PATH" ]; then stat -c "[%a %U %N]" "$RESOLV_PATH" 2>/dev/null || echo "stat failed" grep -v '^#' "$RESOLV_PATH" 2>/dev/null else echo "resolv.conf not found." fi printf "\n##### network managers ##################\n\n" printf "Installed:\n\n" NETMGRINST=() for NETMGRNR in "${!NETMGRPATHS[@]}"; do CHECK_PATH="${NETMGRPATHS[$NETMGRNR]}" if [ ! -f "$CHECK_PATH" ] && [ -f "/var/lib/snapd/hostfs$CHECK_PATH" ]; then CHECK_PATH="/var/lib/snapd/hostfs$CHECK_PATH" fi if [ -f "$CHECK_PATH" ]; then NETMGRINST+=("${NETMGRNAMES[$NETMGRNR]}") fi done printf "\t%s\n" "${NETMGRINST[*]:-None found.}" NETMGRMATCHES=${NETMGRPATHS[@]/#*\//|} NETMGRMATCHES=${NETMGRMATCHES// |/|} NETMGRMATCHES="(${NETMGRMATCHES#|})" printf "\nRunning:\n\n" ps -ef 2>/dev/null | grep -E "( |/)$NETMGRMATCHES($| )" || printf "\tNone found.\n" # Arch Linux iwd (Intel Wireless Daemon) Configuration Check IWD_CONF_DIR="/etc/iwd" if [ -d "/var/lib/snapd/hostfs/etc/iwd" ]; then IWD_CONF_DIR="/var/lib/snapd/hostfs/etc/iwd" fi if [ -d "$IWD_CONF_DIR" ]; then printf "\n##### Arch Linux iwd configuration #####\n\n" for iwdfile in "$IWD_CONF_DIR"/*.conf; do [ -f "$iwdfile" ] || continue IWDCNT=$(grep -v -E '^(#|$)' "$iwdfile" 2>/dev/null) if [ -n "$IWDCNT" ]; then DISPLAY_PATH="${iwdfile#/var/lib/snapd/hostfs}" printf "[%s]\n%s\n\n" "$DISPLAY_PATH" "$IWDCNT" fi done fi printf "\n##### NetworkManager info ###############\n\n" if command -v nmcli >/dev/null 2>&1; then nmcli -f all device show 2>/dev/null | sed '/^GENERAL.DEVICE:[ ]\+lo$/,/^$/d; /^AP\[[0-9]\+\]\./d' echo nmcli -f SSID,BSSID,MODE,CHAN,FREQ,RATE,SIGNAL,BARS,SECURITY,ACTIVE,IN-USE device wifi list 2>/dev/null else echo "NetworkManager is not installed." fi printf "\n##### NetworkManager.state ##############\n\n" NM_STATE_PATH="/var/lib/NetworkManager/NetworkManager.state" if [ -f "/var/lib/snapd/hostfs/var/lib/NetworkManager/NetworkManager.state" ]; then NM_STATE_PATH="/var/lib/snapd/hostfs/var/lib/NetworkManager/NetworkManager.state" fi if [ -f "$NM_STATE_PATH" ]; then if [ -n "$SUDO" ]; then $SUDO cat -s "$NM_STATE_PATH" 2>/dev/null else cat -s "$NM_STATE_PATH" 2>/dev/null fi else echo "NetworkManager.state not found." fi printf "\n##### NetworkManager config #############\n\n" NM_CONF_BASE="" if [ -d "/var/lib/snapd/hostfs/etc/NetworkManager" ]; then NM_CONF_BASE="/var/lib/snapd/hostfs" fi for NMCONFFILE in $(find "$NM_CONF_BASE/etc/NetworkManager" "$NM_CONF_BASE/usr/lib/NetworkManager" -name "*.conf" 2>/dev/null | sort); do if [ -f "$NMCONFFILE" ]; then NMCONFCNT=$(grep -v -E '^(#|$)' "$NMCONFFILE" 2>/dev/null) if [ -n "$NMCONFCNT" ]; then DISPLAY_PATH="${NMCONFFILE#/var/lib/snapd/hostfs}" printf "[[%s]]\n%s\n\n" "$DISPLAY_PATH" "$NMCONFCNT" fi fi done printf "\n##### NetworkManager profiles ###########\n\n" NM_PROFILES_DIR="/etc/NetworkManager/system-connections" if [ -d "/var/lib/snapd/hostfs/etc/NetworkManager/system-connections" ]; then NM_PROFILES_DIR="/var/lib/snapd/hostfs/etc/NetworkManager/system-connections" fi if [ -d "$NM_PROFILES_DIR" ]; then if [ -n "$SUDO" ]; then trap "" 2 3 NMPROFILES=$($SUDO find "$NM_PROFILES_DIR" -maxdepth 1 -type f -exec grep -vH '^$' {} + 2>/dev/null) && SUDOSUCCESS="yes" || SUDOSUCCESS="no" trap 2 3 if [ "$SUDOSUCCESS" = "yes" ] && [ -n "$NMPROFILES" ]; then ORIGIFS="$IFS" IFS=$'\n' NMWLPROFSOUT="" for NMWLPRFFILE in $(sed -n 's/^\(.\+\):type=\(802-11-wireless\|wifi\).*$/\1/p' <<< "$NMPROFILES"); do CLEAN_PATH="${NMWLPRFFILE#/var/lib/snapd/hostfs}" NMWLPRFFLPERMS=$(stat -c "%a %U" "$NMWLPRFFILE" 2>/dev/null || echo "unknown") NMWLPROFILE=($(sed -n "s;^$NMWLPRFFILE:\($NMPROFMATCHES.*\)$;\1 |;p" <<< "$NMPROFILES")) NMWLPROFSOUT+="[[$CLEAN_PATH]] ($NMWLPRFFLPERMS)"$'\n'"${NMWLPROFILE[@]}"$'\n\n' done IFS="$ORIGIFS" sed 's# | \[#\n\[#g;s#\] |#\]#g;s/ |$//' <<< "$NMWLPROFSOUT" | sed '/^\[[^]]*\]$/d' else echo "No active wireless profiles found or privilege escalation failed." fi else echo "No way to acquire admin privileges found." fi else echo "No NetworkManager profiles found." fi # Netplan config (Guarded safely so it runs cleanly on Ubuntu/Debian/Mint derivatives) printf "\n##### Netplan config ####################\n\n" NETPLAN_PREFIX="" if [ -d "/var/lib/snapd/hostfs/etc/netplan" ] || [ -d "/var/lib/snapd/hostfs/lib/netplan" ]; then NETPLAN_PREFIX="/var/lib/snapd/hostfs" fi NETPLAN_DIRS="$NETPLAN_PREFIX/lib/netplan $NETPLAN_PREFIX/etc/netplan $NETPLAN_PREFIX/run/netplan" NETPLAN_FOUND=0 for dir in $NETPLAN_DIRS; do if [ -d "$dir" ]; then for NPLANFILE in "$dir"/*.yaml; do [ -f "$NPLANFILE" ] || continue NETPLAN_FOUND=1 NPLANFLCNT=$(grep -v -E '^(#|$)' "$NPLANFILE" 2>/dev/null) if [ -n "$NPLANFLCNT" ]; then DISPLAY_PATH="${NPLANFILE#/var/lib/snapd/hostfs}" printf "[%s]\n%s\n\n" "$DISPLAY_PATH" "$NPLANFLCNT" | grep -E -v "password|mac|MAC" fi done fi done if [ "$NETPLAN_FOUND" -eq 0 ]; then echo "No Netplan configuration files found (normal for non-Ubuntu distros)." fi printf "\n##### iw reg get ########################\n\n" if command -v iw >/dev/null 2>&1; then IWREGGET=$(iw reg get 2>&1) IW_SUCCESS=$? TIMEZONE_PATH="/etc/timezone" if [ -f "/var/lib/snapd/hostfs/etc/timezone" ]; then TIMEZONE_PATH="/var/lib/snapd/hostfs/etc/timezone" fi if [ -f "$TIMEZONE_PATH" ]; then REGION=$(cat "$TIMEZONE_PATH" 2>/dev/null) if [ -n "$REGION" ]; then printf "Timezone: %s (from %s)\n\n" "$REGION" "${TIMEZONE_PATH#/var/lib/snapd/hostfs}" fi elif [ -L "/var/lib/snapd/hostfs/etc/localtime" ] || [ -L "/etc/localtime" ]; then LOCALTIME_TARGET="/var/lib/snapd/hostfs/etc/localtime" [ -L "$LOCALTIME_TARGET" ] || LOCALTIME_TARGET="/etc/localtime" REAL_LOCALTIME=$(readlink -f "$LOCALTIME_TARGET" 2>/dev/null) if [[ "$REAL_LOCALTIME" =~ zoneinfo/(.*)$ ]]; then printf "Timezone: %s (derived from system localtime)\n\n" "${BASH_REMATCH[1]}" fi fi if [ "$IW_SUCCESS" -eq 0 ] && [ -n "$IWREGGET" ]; then echo "$IWREGGET" else echo "$IWREGGET" echo "Failed to retrieve wireless regulatory domain via iw." fi else echo "'iw' command is not available." fi printf "\n##### iw scan ###########################\n\n" if command -v iw >/dev/null 2>&1; then wireless_interfaces=$(iw dev | awk '$1=="Interface"{print $2}') if [ -z "$wireless_interfaces" ]; then echo "No wireless interfaces found." else for iface in $wireless_interfaces; do printf -- "--- Interface: %s ---\n\n" "$iface" if [ -n "$SUDO" ]; then trap "" 2 3 IWSCAN=$($SUDO${KDESUDO+ -d} iw dev "$iface" scan 2>/dev/null) && SUDOSUCCESS="yes" || SUDOSUCCESS="no" trap 2 3 if [ "$SUDOSUCCESS" = "yes" ]; then if [[ $IWSCAN = *freq:* ]]; then printf "Frequency occupancy:\n\n" grep '^[ ]*freq:' <<< "$IWSCAN" | sort | uniq -c | sed 's/^[ ]\+\([ ][0-9]\+\)[ ]\+/ \1 APs on freq /' echo fi grep -E 'BSS |freq:|signal:|SSID:' <<< "$IWSCAN" | sed 's/^[[:space:]]*//' else printf "\nAcquisition of admin privileges failed for %s.\n" "$iface" fi else echo "No way to acquire admin privileges found." fi echo done fi else echo "'iw' is not installed." fi printf "\n##### module infos ######################\n\n" if command -v modinfo >/dev/null 2>&1; then MODINFO_ARGS="" if [ -d "/var/lib/snapd/hostfs/lib/modules/$(uname -r)" ]; then MODINFO_ARGS="-b /var/lib/snapd/hostfs" fi if [ -n "$LSMOD" ]; then MODULES=$(grep -o -E "^$MODMATCHES[^ ]*" <<< "$LSMOD") if [ -n "$MODULES" ]; then for MODULE in $MODULES; do MODINFO=$(modinfo $MODINFO_ARGS "$MODULE" 2>/dev/null | grep -i -E "^$MODINFOINCL:") if [ -n "$MODINFO" ]; then printf "[%s]\n%s\n\n" "$MODULE" "$MODINFO" fi done else echo "No matching wireless modules found to inspect." fi else echo "No loaded modules data available from lsmod." fi else echo "'modinfo' command is not available." fi printf "\n##### module parameters #################\n\n" if [ -n "$MODULES" ]; then for MODULE in $MODULES; do PARAM_DIR="/sys/module/$MODULE/parameters" if [ ! -d "$PARAM_DIR" ] && [ -d "/var/lib/snapd/hostfs/sys/module/$MODULE/parameters" ]; then PARAM_DIR="/var/lib/snapd/hostfs/sys/module/$MODULE/parameters" fi if [ -d "$PARAM_DIR" ]; then MODPARAMS=$(grep -H '^[[:graph:]]' "$PARAM_DIR"/* 2>/dev/null | sed 's#^.*/##;s/:/: /') if [ -n "$MODPARAMS" ]; then printf "[%s]\n%s\n\n" "$MODULE" "$MODPARAMS" fi fi done else echo "No wireless modules available to inspect for parameters." fi printf "\n##### modprobe options ##################\n\n" for MODPROBEFILE in $(find /etc/modprobe.{conf,d} -name "*.conf" -regextype posix-egrep -not -regex ".*$MODPROBEXCL.*" 2> /dev/null | sort); do MODPROBEOPTS=$(grep -v -E '^(#|$)' "$MODPROBEFILE" 2>/dev/null) if [ -n "$MODPROBEOPTS" ]; then printf "[%s]\n%s\n\n" "$MODPROBEFILE" "$MODPROBEOPTS" fi done printf "\n##### systemd-sleep hooks ###############\n\n" SYSTEMD_SLEEP_DIRS="/var/lib/snapd/hostfs/etc/systemd/system-sleep /var/lib/snapd/hostfs/lib/systemd/system-sleep" found_hooks=0 for sleep_dir in $SYSTEMD_SLEEP_DIRS; do if [ -d "$sleep_dir" ]; then for hook in "$sleep_dir"/*; do if [ -f "$hook" ]; then found_hooks=1 DISPLAY_PATH="${hook#/var/lib/snapd/hostfs}" printf -- "--- Hook: %s ---\n" "$DISPLAY_PATH" if [ -r "$hook" ]; then head -n 20 "$hook" else echo "[Permission denied or unreadable]" fi echo fi done fi done if [ "$found_hooks" -eq 0 ]; then echo "No custom systemd sleep hooks found." fi printf "\n##### udev rules ########################\n\n" UDEV_BASE="/etc/udev/rules.d" if [ -d "/var/lib/snapd/hostfs/etc/udev/rules.d" ]; then UDEV_BASE="/var/lib/snapd/hostfs/etc/udev/rules.d" fi for UDEVRLFILE in $(find "$UDEV_BASE" -name "*net*.rules" 2>/dev/null | sort); do UDEVRULES=$(grep -B1 '^[^#]' "$UDEVRLFILE" 2>/dev/null | grep -E -v '^(--)?$') if [ -n "$UDEVRULES" ]; then DISPLAY_PATH="${UDEVRLFILE#/var/lib/snapd/hostfs}" printf "[%s]\n%s\n\n" "$DISPLAY_PATH" "$UDEVRULES" fi done printf "\n##### dmesg wireless diagnostics ########\n\n" if command -v dmesg >/dev/null 2>&1; then if [ -n "$SUDO" ]; then trap "" 2 3 DMESG_OUT=$($SUDO${KDESUDO+ -d} dmesg -T 2>/dev/null) && SUDOSUCCESS="yes" || SUDOSUCCESS="no" trap 2 3 if [ "$SUDOSUCCESS" = "yes" ] && [ -n "$DMESG_OUT" ]; then echo "$DMESG_OUT" | grep -i -E "$DMESGMATCHES" | grep -v -E "$DMESGEXCL" else echo "Failed to retrieve dmesg logs or privilege escalation failed." fi else dmesg -T 2>/dev/null | grep -i -E "$DMESGMATCHES" | grep -v -E "$DMESGEXCL" fi else echo "'dmesg' command is not available." fi printf "\n########## wireless info END ############\n\n" exec 2>&4 4>&- exec 1>&3 3>&- ##### MAC & IP address masking ##### RESULTS=$(cat -s "$OUTPUTDIR/$FILEBASE.txt")$'\n' ORIGIFS="$IFS" IFS=$'\n' IFACESIDS=($(sed -n "/\([[:alnum:]]\{2\}:\)\{5\}[[:alnum:]]\{2\}/ {/\(00:\)\{5\}00/! {s/^[0-9]\+: \([^ :]\+\):.*/'\1'/p; s/^\([^ :]\+\):\? .*/'\1'/p}}" <<< "$IFCONFIG")) IFACESMACS=($(sed -n '/\(00:\)\{5\}00/! s#.*\(HWaddr\|link/[^ ]\+\|ether\) \(\([[:alnum:]]\{2\}:\)\{5\}[[:alnum:]]\{2\}\).*#\2#p' <<< "$IFCONFIG")) IFACESIP6S=($(ip6-mac "${IFACESMACS[@]}")) WLAPSIWLIDS=($(sed -n "/^[ ]*Cell [0-9]\+/,/^[ ]*ESSID:/ {/^[ ]*Cell [0-9]\+/h; /^[ ]*ESSID:/ {H;g;s/^[ ]*Cell 0\?\([0-9]\+\).*ESSID:\"\(.*\)\"$/'\2' [AC\1]/p}}" <<< "$IWLISTSCAN")) WLAPSIWLMACS=($(sed -n 's/^[ ]*Cell [0-9]\+.*Address: \([^ ]\+\)/\1/p' <<< "$IWLISTSCAN")) WLAPSIWLIP6S=($(ip6-mac "${WLAPSIWLMACS[@]}")) WLAPSNMRAW=$(sed -n '/^##### NetworkManager info #####/,/^##### / {/^[ ]*Wireless Access Points/,/^$/ {/Wireless Access Points/d;s/^[ ]\+\*\?//;s/:[ ]\+/\t/;p}; /^SSID[ ]\+BSSID[ ]\+/,/^$/ {/^SSID[ ]\{2,\}BSSID[ ]\{2,\}/d;s/[ ]\{2,\}/\t/;p}}' <<< "$RESULTS") WLAPSNMIDS=($(awk -F '\t' '{print "'\''" $1 "'\''"}' <<< "$WLAPSNMRAW")) WLAPSNMMACS=($(grep -o '\([[:alnum:]]\{2\}:\)\{5\}[[:alnum:]]\{2\}' <<< "$WLAPSNMRAW")) WLAPSNMIP6S=($(ip6-mac "${WLAPSNMMACS[@]}")) IFS="$ORIGIFS" for IFACENR in "${!IFACESMACS[@]}"; do MACMASKSED+="s;${IFACESMACS[$IFACENR]};;I;" MACMASKSED+=" /${IFACESIP6S[$IFACENR]}/ s;${IFACESIP6S[$IFACENR]/#\\(::/\(};;I;" IFACEMACC=${IFACESMACS[$IFACENR]//:/} if [[ ${IFACESIDS[$IFACENR],,} =~ ${IFACEMACC,,} ]]; then MACMASKSED+="s;\(${IFACESIDS[$IFACENR]:1:3}\)$IFACEMACC;\1;Ig;" fi done for WLAPIWLNR in "${!WLAPSIWLMACS[@]}"; do MACMASKSED+="s;${WLAPSIWLMACS[$WLAPIWLNR]};;I;" MACMASKSED+=" /${WLAPSIWLIP6S[$WLAPIWLNR]}/ s;${WLAPSIWLIP6S[$WLAPIWLNR]/#\\(::/\(};;I;" done for WLAPNMNR in "${!WLAPSNMMACS[@]}"; do MACMASKSED+="s;${WLAPSNMMACS[$WLAPNMNR]};;I;" MACMASKSED+=" /${WLAPSNMIP6S[$WLAPNMNR]}/ s;${WLAPSNMIP6S[$WLAPNMNR]/#\\(::/\(};;I;" done sed "$MACMASKSED /\([[:alnum:]]\{2\}:\)\{6,\}/! s/\([[:alnum:]]\{2\}:\)\{5\}[[:alnum:]]\{2\}//g; s/\b[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\b//g" <<< "$RESULTS" > "$OUTPUTDIR/$FILEBASE.txt" ##### The End ##### dialog_info "${TERMOUT+\n}Results saved in \"$OUTPUTDIR/$FILEBASE.txt\".${TERMOUT+\n}" # Updated size limit check (200 KB) if (( $(stat -c %s "$OUTPUTDIR/$FILEBASE.txt") > 200000 )); then tar -czf "$OUTPUTDIR/$FILEBASE.tar.gz" -C "$OUTPUTDIR" "$FILEBASE.txt" && \ dialog_info "Results also archived in \"$OUTPUTDIR/$FILEBASE.tar.gz\",${DIALOGBREAK}as they exceed the 200 KB size limit for \".txt\" attachments${DIALOGBREAK}on the forums.${TERMOUT+\n}" || \ dialog_error "Results exceed the 200 KB size limit for \".txt\" attachments${DIALOGBREAK}on the forums, but archive could not be created.${TERMOUT+\n}" fi # Multi-stage account-free paste service upload handler do_pastebin_upload() { local file_to_paste="$1" local paste_url="" if [ ! -s "$file_to_paste" ]; then return 1 fi # Option 1: termbin.com (TCP port 9999 via netcat or bash /dev/tcp) if command -v nc >/dev/null 2>&1; then paste_url=$(nc termbin.com 9999 < "$file_to_paste" 2>/dev/null | tr -d '\r\n\0') elif [ -e /dev/tcp ]; then paste_url=$( (exec 3<>/dev/tcp/termbin.com/9999 && cat "$file_to_paste" >&3 && cat <&3) 2>/dev/null | tr -d '\r\n\0' ) fi # Option 2: paste.rs (Fallback anonymous curl paste service) if [ -z "$paste_url" ] && command -v curl >/dev/null 2>&1; then paste_url=$(curl -sS --data-binary @"$file_to_paste" https://paste.rs 2>/dev/null | tr -d '\r\n\0') fi # Option 3: Legacy pastebinit fallback if [ -z "$paste_url" ] && command -v pastebinit >/dev/null 2>&1; then paste_url=$(pastebinit "$file_to_paste" 2>/dev/null | tr -d '\r\n\0') fi if [ -n "$paste_url" ]; then echo "$paste_url" return 0 else return 1 fi } if command -v nc >/dev/null 2>&1 || command -v curl >/dev/null 2>&1 || command -v pastebinit >/dev/null 2>&1 || [ -e /dev/tcp ]; then PASTEBIN=$(dialog_question "Do you also want to post them${DIALOGBREAK}to an online paste service (termbin/paste.rs)?") if [[ ! $PASTEBIN =~ ^no?$ ]]; then PASTESUCCESS="no" # If text log was archived due to 200KB limit, uncompress temporarily for paste upload TARGET_PASTE_FILE="$OUTPUTDIR/$FILEBASE.txt" TEMP_UNCOMPRESSED="no" if [ ! -f "$TARGET_PASTE_FILE" ] && [ -f "$OUTPUTDIR/$FILEBASE.tar.gz" ]; then tar -xzf "$OUTPUTDIR/$FILEBASE.tar.gz" -C "$OUTPUTDIR" "$FILEBASE.txt" 2>/dev/null TEMP_UNCOMPRESSED="yes" fi PASTERESULT=$(do_pastebin_upload "$TARGET_PASTE_FILE" 2>&1) && PASTESUCCESS="yes" # Clean up temporary uncompressed text file if we unpacked it just for uploading if [ "$TEMP_UNCOMPRESSED" = "yes" ] && [ -f "$OUTPUTDIR/$FILEBASE.tar.gz" ]; then rm -f "$TARGET_PASTE_FILE" fi if [ "$PASTESUCCESS" = "yes" ] && [ -n "$PASTERESULT" ]; then dialog_info "${TERMOUT+\n}Paste successful:\n\n${PASTERESULT}${TERMOUT+\n}" else if [ -n "$PASTERESULT" ]; then dialog_error "${TERMOUT+\n}Online upload failed, error message is:\n\n${PASTERESULT}${TERMOUT+\n}" else dialog_error "${TERMOUT+\n}Online upload failed, no error message given.${TERMOUT+\n}" fi fi else echo fi fi