#!/bin/bash

bold ()
{
	echo $(tput bold)"$*"$(tput sgr0)
}

pomoc ()
{
	echo
	echo $(bold NAZWA:)
	echo "	"$(basename $0)
	echo
	echo $(bold ZASTOSOWANIE:)
	echo "	""Ustawianie parametrów interfejsów sieciowych."
	echo "	""Możliwe ustawienia:"
	echo "		""bridge na bond - ma sens, gdy w hoście jest więcej niż jeden"
	echo "		""                 interfejs sieciowy."
	echo "		""tylko bridge   - gdy mamy do dyspozycji tylko jeden interfej sieciowy."
	echo
	echo $(bold SKŁADNIA:)
	echo "	"`basename $0`" [opcje]"
	echo "		""--help | --pomoc  - wyświetla pomoc dla tego skryptu."
	echo "		""--showbondmode    - zwraca tryb pracy bond'a (o ile bond jest ustawiony)."
	echo "		""--showbondinfo    - zwraca informacje o bond (o ile bomd jest ustawiony)."
	echo "		""--showbondspeed   - zwraca prędkość bond."
	echo "		""--shownetorkspeed - zwraca prędkość sieci hosta."
	echo "		""--bridgeonbond    - dla ustawienia bridge na bond."
	echo
	echo "		""                    Poniższe parametry dla bridge i bond są opcjonale. Pominięcie ich lub"
	echo "		""                    niewpisanie wartości po znaku równości spowoduje pryjęcie wartości domyślnych."
	echo "		""                    --mode=          - jest parametrem opcjonalnym. Domyślną wartością jest 0."
	echo "		""                                       Określa jeden z siedmiu trybów pracy bonda:"
	echo "		""                                          0 | balance-rr"
	echo "		""                                          1 | active-backup"
	echo "		""                                          2 | balance-xor3"
	echo "		""                                          3 | broadcast"
	echo "		""                                          4 | 802.3ad"
	echo "		""                                          5 | balance-tlb"
	echo "		""                                          6 | balance-alb"
	echo "		""                    --addressip=       - po znaku równości należy podać adres IP, który ma zostać"
	echo "		""                                        przydzielony bride skonfigurowanym na bond."
	echo "		""                                        Pominięcie tego parametru, lub wartości tego parametru"
	echo "		""                                        powoduje przyjęcie za domyślny bieżący adrs IP hosta."
	echo "		""                                        Można pominąć ten parametr, pod warunkiem, że host ma już"
	echo "		""                                        przydzielony adres IP. Pominięcie tego parametru przy braku"
	echo "		""                                        już przydzielonego hostowi IP spowoduje zakończenie działania"
	echo "		""                                        skryptu bez efektu."
	echo "		""                   --netmask=         - po znaku równości należy podać adres maski, który ma zostać"
	echo "		""                                        przydzielony do hosta. Pominięcie spowoduje użycie wartość"
	echo "		""                                        domyślnej, tj. obecnej hosta."
	echo "		""                   --gateway=         - po znaku rówwności należy podać adres IP bramy. Domyślną wartością"
	echo "		""                                        jest bieżąca wartość branmy przypisanej hostowi."
	echo "		""                   --domain=          - po znaku równości należy podać nazwę domeny. Domyślną wartością"
	echo "		""                                        jest bieżąca wartość domeny przypisana hostowi."
	echo "		""                   --dnsserver=       - po znaku równości należy podać adres IP serwera DNS."
	echo "		""                   --bridgename=      - nazwa dla bridge. Jeżeli nie zostanie podana domyślnie zostanie"
	echo "		""                                        nadana br0."
	echo "		""                                        w sytuacji, gdy host nie ma przydzielonego adresu IP."
	echo "		""--bridgeonly                          - dla ustawienia wyłącznie bridge."
	echo "		""                  --addressip="
	echo "		""                  --gateway="
	echo "		""                  --netmask="
	echo "		""                  --domain="
	echo "		""                  --bridgename="
	echo "		""                                       Patrz opis jak dla --bridgeonbond."

	echo
	echo $(bold AUTOR:)
	echo "		""Radek Bursztynowski"
	echo
	echo $(bold 'DATA UTWORZENIA:')
	echo "		""03.10.2025"
	echo
	echo $(bold 'DATA OSTATNIEJ MODYFIKACJI:')
	echo "		""07.10.2025"
	echo
	echo $(bold WERSJA:)
	echo "		""1.0"
	echo
	echo $(bold PRZYKŁADY:)
	echo "		"`basename $0`" --bridgeonbond --mode=0 --addressip=192.168.0.1 --gateway=192.168.0.254 --domain=maja.domena.com"
	echo "		""     Buduje bridge na bond, przy czym do bonda zostaną dowiązane"
	echo "		""     wszystkie fizyczne interfejsy sieciowe. Bond zbudowany zostanie"
	echo "		""     w trybie "$(bold 0)", z adresem IP "$(bold '192.168.0.1')", bramą "$(bold 192.168.0.254)", i domeną "$(bold moja.domena.com)
	echo
	echo "		"`basename $0`" --bridgeonbond"
	echo "		""     Buduje bridge na bond, przy czym do bonda zostaną dowiązane"
	echo "		""     wszystkie fizyczne interfejsy sieciowe. Bond zbudowany zostanie"
	echo "		""     w trybie "$(bold 6)" (domyślnym) i pozostałe parametry sieci będą przyjęte z pirwotnego ustawienia interfejsu sieciowego hosta."
	echo
	echo "		"`basename $0`" --bridge --addressip=192.168.0.1 --gateway=192.168.0.254 --netmask=255.255.255.0 --domain=moja.domena.com"
	echo "		""     Budje bridge na fizycznym interfejsie sieciowym z adresem IP 192.168.0.1, maską sieci 255.255.255.0 bramą 192.168.0.24 i domeną moja.domena.com."
	echo
}

parsowanie ()
{
	while [ "$#" != 0 ]; do
		if [ "$1" = "--bridgeonbond" ]; then
			if [ "$WhatToDo" != "" ]; then
				echo "Nie możesz jednocześnie korzystać z ""$(bold '--bridgeonbond')"" i ""$(bold '--bridgeonly')"
			else
				WhatToDo="bridgeonbond"
			fi
		elif [ "$1" = "--bridgeonly" ]; then
			if [ "$WhatToDo" != "" ]; then
				echo "Nie możesz jednocześnie korzystać z ""$(bold '--bridgeonbond')"" i ""$(bold '--bridgeonly')"
			else
				WhatToDo="bridgeonly"
			fi
		elif [ "${1:0:7}" = "--mode=" ]; then
			case "$(echo $1 | awk -F = '{print $2}')" in
				[0-6])
					tryb="$(echo $1 | awk -F = '{print $2}')"
				;;
				
				*)
					zlytryb="$1"
					tryb=6
				;;
			esac
		elif [ "${1:0:12}" = "--addressip=" ]; then
			if [ "$(echo $1 | awk -F = '{print $2}')" != "" ]; then
				IPaddress="$(echo $1 | awk -F = '{print $2}')"
			fi
		elif [ "${1:0:10}" = "--gateway=" ]; then
			if [ "$(echo $1 | awk -F = '{print $2}')" != "" ]; then
				Gateway="$(echo $1 | awk -F = '{print $2}')"
			fi
		elif [ "${1:0:9}" = "--domain=" ]; then
			if [ "$(echo $1 | awk -F = '{print $2}')" != "" ]; then
				NICdomain="$(echo $1 | awk -F = '{print $2}')"
			fi
		elif [ "${1:0:13}" = "--bridgename=" ]; then
			if [ "$(echo $1 | awk -F = '{print $2}')" != "" ]; then
				Bridgename="$(echo $1 | awk -F = '{print $2}')"
			fi
		elif [ "${1:0:10}" = "--netmask=" ]; then
			if [ "$(echo $1 | awk -F = '{print $2}')" != "" ]; then
				NetMask="$(echo $1 | awk -F = '{print $2}')"
			fi
		elif [ "${1:0:12}" = "--dnsserver=" ]; then
			if [ "$(echo $1 | awk -F = '{print $2}')" != "" ]; then
				DNSserver="$(echo $1 | awk -F = '{print $2}')"
			fi
		fi

		shift
	done
}

adresyIP ()
{
	# Zwraca listę adresów IP hosta po broadcast.
	# Adres IP hosta
	ipadr="$(cat /opt/LTSP_install/manager-install.conf | grep ipaddress= | awk -F = '{print $2}')"
	# Nazwa interfejsu sieciowego
	NICname=$(ifconfig | grep -B1 $ipadr | grep -o "^\w*")
	# Broadcast po interfejsie sieciowym
	brdcst=`ip address show $NICname | grep 'inet .* brd ' | head -1 | sed -e 's/^.* brd \([0-9\.]*\) .*$/\1/'`
	ifconfig | grep $brdcst | awk '{print $2}'
}

delnetconnectioons ()
{
	while [ "$#" != 0 ]; do
		nmcli connection delete "$1" &>> /dev/null
		shift
	done
}

disableIP ()
{
	while [ "$#" != 0 ]; do
		nmcli connection modify "$1" ipv4.method disabled &>> /dev/null
	done
}

nics_uuid ()
{
	# Listą parametrów funkcji są nazwy kart sieciowych.
	lista=""
	
	while [ "$#" != 0 ]; do
		lista=$lista" "$(nmcli c | grep $1 | awk '{print $2}')
		shift
	done
}

addmemberdev2bond ()
{
	while [ "$#" != 0 ]; do
		nmcli connection add type ethernet ifname "$1" master bond0 &>> /dev/null
		shift
	done
}

setbridgeonbond ()
{
	if [ "$(rpm -qa bridge-utils)" = "" ]; then
		echo -en "Trzeba doinstalować brakujące pakiety (np. bridge-utils). Czy wyrażasz zgodę (tak/nie)?"
		read decyzja
		
		if [ "$decyzja" - "tak" ]; then
			dnf install -y --quiet libguestfs-tools bridge-utils kernel-modules-extras ifenslave network-manager-apple &>> /dev/null
		else
			echo "Wobec braku niezbędnych pakietów przerywam działanie skryptu."
			exit 0
		fi
	fi

	ListOfPhysicalNICs=$(nmcli device | grep en | grep ethernet | awk '{print $1}') &>> /dev/null
	
	if [ "$ListOfPhysicalNICs" = "" ]; then
		ListOfPhysicalNICs=$(ifconfig | grep en | grep flags= | awk '{print $1}' | sed 's/.$//') &>> /dev/null
	fi
	
	# Resetowanie ustawień sieciowych (w tym ewentualne usuwanie bridge, bonda i adresów IP.
	
	# Wyłączanie adresów IP właściwych dla głównego broadcastu.
	disableIP $adresyIP
	
	# Usuwanie bridge (o ile istnieje).
	if [ "$(ifconfig | grep br0)" != "" ]; then
		nmcli connection delete $(ifconfig | grep br0 | awk -F : 'NR==1{print $1}') &>> /dev/null
	fi
	
	# Usuwanie bond'a (o ile istnieje).
	if [ "$(ifconfig | grep bond)" != "" ]; then
		nmcli connection delete $(ifconfig | grep bond | awk -F : '{print $1}') &>> /dev/null
	fi	

	# Usuwanie wszystkich ewentualnie połączeń sieciowych
	delnetconnectioons $ListOfPhysicalNICs &>> /dev/null
	# Na wszelki wypadek usuwamu po UUID
	NICs_UUID=$(nics_uuid `$ListOfPhysicalNICs`)
	delnetconnectioons $NICs_UUID &>> /dev/null
	
	# Resetowanie ustawień sieciowych (w tym ewentualne usuwanie bridge, bonda i adresów IP.
	# Wyłączanie adresów IP właściwych dla głównego broadcastu.
	disableIP $adresyIP
	
	# Usuwanie bridge (o ile istnieje).
	if [ "$(ifconfig | grep br0)" != "" ]; then
		nmcli connection delete $(ifconfig | grep br0 | awk -F : 'NR==1{print $1}') &>> /dev/null
	fi
	
	# Usuwanie bond'a (o ile istnieje).
	if [ "$(ifconfig | grep bond)" != "" ]; then
		nmcli connection delete $(ifconfig | grep bond | awk -F : '{print $1}') &>> /dev/null
	fi	

	# Usuwanie wszystkich ewentualnie połączeń sieciowych
	delnetconnectioons $ListOfPhysicalNICs &>> /dev/null
	# Na wszelki wypadek usuwamu po UUID
	NICs_UUID=$(nics_uuid `$ListOfPhysicalNICs`)
	delnetconnectioons $NICs_UUID &>> /dev/null

	# Add a new bonding device [bond0]
	nmcli connection add type bond ifname bond0 con-name bond0 bond.options "mode=$bondmode" &>> /dev/null

	# Add member devices to the bonding device
	addmemberdev2bond $ListOfPhysicalNICs &>> /dev/null 2>&1

	# Adres IP będzie przywiązany do bridge, a nie do bond.
	nmcli connection modify bond0 ipv4.method disabled &>> /dev/null

	# Activate bond0
	nmcli con up bond0 &>> /dev/null

	# Bridge
	nmcli con add ifname $Bridgename type bridge con-name $Bridgename &>> /dev/null
	nmcli con add type bridge-slave ifname bond0 master $Bridgename &>> /dev/null
		
	# set IP address and so on to the bridge device and restart it
	# IP address
	nmcli connection modify $Bridgename ipv4.addresses "$IPaddress" &>> /dev/null

	# gatway
	nmcli connection modify $Bridgename ipv4.gateway "$Gateway" &>> /dev/null

	# DNS
	nmcli connection modify $Bridgename ipv4.dns "$DNSserver" &>> /dev/null

	# Domain
	nmcli connection modify $Bridgename ipv4.dns-search "$NICdomain" &>> /dev/null

	nmcli connection modify $Bridgename ipv4.method manual &>> /dev/null
	nmcli con modify bond0 master $Bridgename slave-type bridge &>> /dev/null
	# nmcli connection down br0 &>> /dev/null && nmcli connection up br0 &>> /dev/null
		
	systemctl --quiet restart NetworkManager &>> /dev/null

	sleep 5s
	echo
	echo "ZROBIONO"
}

setbridgeobly ()
{

	if [ "$(rpm -qa bridge-utils)" = "" ]; then
		echo -en "Trzeba doinstalować brakujące pakiety (np. bridge-utils). Czy wyrażasz zgodę (tak/nie)?"
		read decyzja
		
		if [ "$decyzja" - "tak" ]; then
			dnf install -y --quiet libguestfs-tools bridge-utils kernel-modules-extras ifenslave &>> /dev/null
		else
			echo "Wobec braku niezbędnych pakietów przerywam działanie skryptu."
			exit 0
		fi
	fi

	ListOfPhysicalNICs=$(nmcli device | grep en | grep ethernet | awk '{print $1}') &>> /dev/null

	if [ "$ListOfPhysicalNICs" = "" ]; then
		ListOfPhysicalNICs=$(ifconfig | grep en | grep flags= | awk '{print $1}' | sed 's/.$//') &>> /dev/null
	fi
	
	# Resetowanie ustawień sieciowych (w tym ewentualne usuwanie bridge, bonda i adresów IP.
	# Wyłączanie adresów IP właściwych dla głównego broadcastu.
	disableIP $adresyIP
	
	# Usuwanie bridge (o ile istnieje).
	if [ "$(ifconfig | grep br0)" != "" ]; then
		nmcli connection delete $(ifconfig | grep br0 | awk -F : 'NR==1{print $1}') &>> /dev/null
	fi
	
	# Usuwanie bond'a (o ile istnieje).
	if [ "$(ifconfig | grep bond)" != "" ]; then
		nmcli connection delete $(ifconfig | grep bond | awk -F : '{print $1}') &>> /dev/null
	fi	

	# Usuwanie wszystkich ewentualnie połączeń sieciowych
	delnetconnectioons $ListOfPhysicalNICs &>> /dev/null
	# Na wszelki wypadek usuwamu po UUID
	NICs_UUID=$(nics_uuid `$ListOfPhysicalNICs`)
	delnetconnectioons $NICs_UUID &>> /dev/null
	
	# bridge
	nmcli connection add type bridge autoconnect yes con-name $Bridgename ifname $Bridgename &>> /dev/null
	nmcli connection modify $Bridgename ipv4.addresses $IPaddress method none &>> /dev/null
	nmcli connection modify $Bridgename ipv4.gateway $Gateway &>> /dev/null
	nmcli connection modify $Bridgename ipv4.dns $serwerDNS &>> /dev/null
	nmcli connection modify $Bridgename ipv4.dns-search "$NICdomain" &>> /dev/null
	nmcli connection add type bridge-slave autoconnect yes con-name $ethNIC ifname $ethNIC master $Bridgename &>> /dev/null
	# nmcli connection add type bridge-slave autoconnect yes con-name $ethNIC ifname $ethNIC master $NICname &>> /dev/null
	nmcli connection up $Bridgename &>> /dev/null
	sleep 5s
	echo
	echo "ZROBIONO"
}

#############################################################################

if [ "$(whoami)" != "root" ]; then
	echo "Musisz być zalogowany jako "$(bold root)". Kończę pracę."
fi

WhatToDo=""

# Domyślny tryb bond
tryb="6"

if [ "$#" = 0 ]; then
	echo "Nie podałeś żadnych parametrów. Sprawdź: "`basename $0`" --help"
else
	case "$1" in
		--help | help | --pomoc | pomoc)
			pomoc
		;;
		
		--showbondmode)
			isbondexists="$(ls /proc/net/bonding/ | head -1)"
			
			if [ "$isbondexists" != "" ]; then
				cat /sys/class/net/$isbondexists/bonding/mode
			else
				echo "Bond nie jest ustawiony."
			fi
		;;
		
		--showbondinfo)
			if [ "$(ls /proc/net/bonding/ | head -1)" != "" ]; then
				cat /proc/net/bonding/"$(ls /proc/net/bonding/ | head -1)"
			else
				echo "Bond nie jest ustawiony."
			fi		
		;;
		
		--showbondspeed)
			if [ "$(ls /proc/net/bonding/ | head -1)" != "" ]; then
				ethtool "$(ls /proc/net/bonding/ | head -1)" | grep Speed: | awk '{print $2}'
			else
				echo "Bond nie jest ustawiony."
			fi
		;;
		
		--shownetworkspeed)
			if [ "$(ip r | grep default | awk '/default/ {print $5}' | grep br)" != "" ]; then
				ethtool "$(ip r | grep default | awk '/default/ {print $5}')" | grep Speed: | awk '{print $2}'
			fi
		;;

		*)
			NICname="$(ip r | grep default | awk '/default/ {print $5}')"
			IPaddress="$(ip -o -f inet addr show | awk '/scope global/ {print $2, $4}' | awk '{print $2}' | awk -F / '{print $1}')"
			Gateway="$(route -n | grep 'UG[ \t]' | awk '{print $2}')"
			NetMask="$(ifconfig $NICname | awk '/netmask/{split($4,a,":"); print a[1]}')"
			NICdomain="$(nslookup alpaga | grep Name: | awk '{print $2}' | cut -d '.' -f 2-)"
			DNSserver=`nmcli --fields ipv4.dns con show $NICname`

			zlytryb=""
			
			parsowanie $@
			
			if [ "$IPaddress" = "" ]; then
				echo "Nie podaéś adresu IP. Przeywam pracę."
				exit 0
			fi
			
			if [ "$WhatToDo" = "bridgeonbond" ]; then
				if [ "$zlytrb" != "" ]; then
					echo -en "Podałeś błędny tryb bond ("$tryb"), choć dozwolony zakres to [0-6]. Czy konynuować z domyślnym trybem 6 {tak/nie)? "
					read decyzja
					
					case "$decyzja" in
						tak | yes)
							setbridgeonbond
						;;
						
						*)
							echo "W takim razie przrywam pracę!"
						;;
					esac
				fi

			elif [ "$WhatToDo" = "bridgeonly" ]; then
				setbridgeobly
			fi
		;;
	esac

	echo
fi

# Sprawdzenie trybu bonda
# cat /sys/class/net/bond0/bonding/mode

# Info o bondzie
# cat /proc/net/bonding/bond0

# Szybkość bond:
# ethtool bond0 | grep Speed: | awk '{print $2}'

# Szybkość bridge
# ethtool br0 | grep Speed: | awk '{print $2}'

# Zwraca adres gateway
# route -n | grep 'UG[ \t]' | awk '{print $2}'

# Maska
# ip -o -f inet addr show | awk '/scope global/ {print $4}' | awk -F / '{print $2}'
# ifconfig br0 | awk '/netmask/{split($4,a,":"); print a[1]}'

# NIC name, IP, netmask
# ip -o -f inet addr show | awk '/scope global/ {print $2, $4}'

# Nicname
# ip r | grep default | awk '/default/ {print $5}'

# Domainname
# nslookup alpaga | grep Name: | awk '{print $2}' | cut -d '.' -f 2-

# Adres IP




