#!/bin/bash

# Configure networking for device.
#
# Creates a basic network interface file and network-manager connections.
#
# First parameter is the path to the network interface file to
# configure.

if [ -n "$1" ]
then
    IFACES_FILE=$1
else
    IFACES_FILE=/etc/network/interfaces
fi

INTERFACE_DETECT="interface-detect"

function get-wired-interfaces {
    # XXX: Sorting of interfaces is non-numeric
    WIRED_IFACES=$(nmcli --terse --fields type,device device | grep "^ethernet:" | cut -d: -f2 | sort)
    NO_OF_WIRED_IFACES=$(echo $WIRED_IFACES | wc -w)
}

function configure-regular-interface {
    interface="$1"
    zone="$2"

    # Create n-m connection for a regular interface
    nmcli con add con-name freedomboxWAN ifname $interface type ethernet
    nmcli con modify freedomboxWAN connection.autoconnect TRUE
    nmcli con modify freedomboxWAN connection.zone $zone

    echo "Configured interface $interface for $zone use."
}

function configure-shared-interface {
    interface="$1"

    # Create n-m connection for eth1
    nmcli con add con-name freedomboxLAN$interface ifname $interface type ethernet
    nmcli con modify freedomboxLAN$interface connection.autoconnect TRUE
    nmcli con modify freedomboxLAN$interface connection.zone internal

    # Configure this interface to be shared with other computers.
    #  - Self-assign an address and network
    #  - Start and manage DNS server (dnsmasq)
    #  - Start and manage DHCP server (dnsmasq)
    #  - Register address with mDNS
    #  - Add firewall rules for NATing from this interface
    nmcli con modify freedomboxLAN$interface ipv4.method shared

    echo "Configured interface $interface for shared use."
}

function multi-wired-setup {
    first_interface="$1"
    shift
    remaining_interfaces="$@"

    configure-regular-interface $first_interface external

    for interface in $remaining_interfaces
    do
        configure-shared-interface $interface
    done
}

function one-wired-setup {
    interface="$1"
    configure-regular-interface $interface internal
}

function update-null-macs {
    # if interface's mac address is all zeroes, change it to 0:0:0:X:X:X

    # iterate through all the interfaces
    for description in $WIRED_IFACES
    do
        name=`echo $description | cut -d"," -f1`
        mac=`echo $description | cut -d"," -f3`

        # if it's null, swap it out in the interface file.
        if [[ "$mac" == "00:00:00:00:00:00" ]]
        then
            # if macchanger gave us a new mac, use that.  or, generate dummy.
            if [[ `macchanger -a $name` ]]
            then
                newMac=`$INTERFACE_DETECT | grep $name | cut -d, -f3`
            else
                generate_dummy_mac
            fi

            # save new mac.
            sed -i "s/# $name: hwaddress ether .*$/hwaddress ether $newMac/" \
                $IFACES_FILE
        fi
    done
}

function generate_dummy_mac {
    # set "newMac" to a GlobalScale MAC address: F0:AD:4E:XX:XX:XX

    # generate 3 sets of 2 random hex digits.
    allSix="$(tr -dc '[:xdigit:]' < /dev/urandom | tr '[:lower:]' '[:upper:]' | head -c 6)"
    high=`echo $allSix | cut -b1,2`
    med=`echo $allSix | cut -b3,4`
    low=`echo $allSix | cut -b5,6`

    # generate three sets of 2 digits
    newMac="F0:AD:4E:$high:$med:$low"
}

echo "Setting up network configuration..."
get-wired-interfaces

case $NO_OF_WIRED_IFACES in
    "0")
        echo "No wired interfaces detected."
        ;;
    "1")
        one-wired-setup $WIRED_IFACES
        ;;
    *)
        multi-wired-setup $WIRED_IFACES
esac

update-null-macs

echo "Done setting up network configuration."
