#!/bin/bash
#
# Copyright (c) Authors: https://www.armbian.com/authors
#
# This file is licensed under the terms of the GNU General Public
# License version 2. This program is licensed "as is" without any
# warranty of any kind, whether express or implied.

# Functions:
#
# atomic_write
# show_motd_warning
# generate_random_mac
# set_fixed_mac

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
my_name="${0##*/}"
Log=/var/log/armbian-hardware-monitor.log

show_motd_warning() {
cat > /etc/update-motd.d/90-warning <<EOT
#!/bin/bash
echo -e "\e[0;91mAttention:\x1B[0m $1\n"
rm "\$0"
EOT
chmod +x /etc/update-motd.d/90-warning
} # show_motd_warning

# Atomically replace dest with src via rename + sync, surviving power loss
# at any point. Usage: atomic_write <src> <dest> [mode] [owner]
#   src  — temporary file with the new content (consumed/removed by this call)
#   dest — target file to replace atomically
#   mode — optional permission mode (e.g. 600); if omitted, preserves dest's mode
#   owner — optional owner for the replacement, applied before rename
# Uses mv (rename syscall) for atomicity — do NOT replace with `install`,
# which copies data in-place and breaks crash safety on power loss.
atomic_write() {
	local src="$1" dest="$2" mode="${3:-}" owner="${4:-}"
	if [[ -n "${mode}" ]]; then
		chmod "${mode}" "${src}" || return
	elif [[ -e "${dest}" ]]; then
		chmod --reference="${dest}" "${src}" || return
	fi
	[[ -z "${owner}" ]] || chown "${owner}" "${src}" || return
	mv -f "${src}" "${dest}" || return
	# fsync the file contents and then its parent directory: the latter makes the
	# rename itself durable across power loss.
	sync -f "${dest}" 2>/dev/null || sync || return
	sync -f "$(dirname "${dest}")" 2>/dev/null || sync
}

# Generate a random MAC address
generate_random_mac ()
{
	# These prefixes are 4 sets of Locally Administered Address Ranges which can be used on the network without fear of conflict
	local prefixes=("02" "06" "0A" "0E")
	local random=$(shuf -i 0-3 -n 1)
	MACADDR=$(printf ${prefixes[$random]}':%02X:%02X:%02X:%02X:%02X\n' $[RANDOM%256] $[RANDOM%256] $[RANDOM%256] $[RANDOM%256] $[RANDOM%256])
}

# Set a fixed random MAC for each Ethernet interface
set_fixed_mac ()
{

	# we use random mac routine only with sytemd-network.
	if ! grep 'renderer: networkd' /etc/netplan/*.yaml >/dev/null; then
		return
	fi

	local netplan_config_file="/etc/netplan/20-eth-fixed-mac.yaml"

	# Initialize a new Netplan config file
	cat <<- EOF > "${netplan_config_file}"
		network:
		  version: 2
		  ethernets:
	EOF

	# Iterate over each Ethernet interface
	for iface in $(ip link | awk -F: '$0 !~ "lo|vir|wl|^[^0-9]"{print $2;getline}' | sed 's/^[ \t]*//' | grep "^e\|^wan\|^lan")
	do
		generate_random_mac

		# Append the MAC address configuration for the interface to the Netplan configuration file
		cat <<- EOF >> "${netplan_config_file}"
			    $iface:
			      macaddress: $MACADDR
		EOF
	done

	# Change the file permissions according to https://netplan.readthedocs.io/en/stable/security/
	chmod 600 "${netplan_config_file}"

	# Apply the Netplan configuration
	netplan apply
}
