#! /bin/sh
# ipmi_sim_lancontrol - provide link addresses to ipmi_sim for device $1
# See lan_config_program in ipmi_lan(5)
#
# 2015-05-06  Noel Burton-Krahn <noel@pistoncloud.com>

#NOTE(colleen) vendored with modifications from https://github.com/wrouesnel/openipmi/blob/master/ipmi_sim_lancontrol

set -eu

# arguments: dev op var
# network interface
dev=$1
# get or set.
op=$2
# var name
var=$3
# value to set if any
val=${4:-''}

veth_peer=$(ip link show dev $dev | awk 'NR==1 { split($2, subfield, "@"); print substr(subfield[2], 1, length(subfield[2])-1)}')
gw_dev=$(bridge link show dev $veth_peer |  awk '{for(j=0;j<=NF;j++) if ($j == "master" ) print $(j+1) }')

link_ip() {
    # We might want to change the IP address of the BMC device, but to avoid having
    # to change the lan conf and re-bind, we just take the latest address
    ip -o -4 addr list $1 | tail -1 | sed -ne 's/.* inet \([.0-9]*\)\/.*/\1/p'
}

link_mac() {
    ip -o link list $1 | sed -ne 's/.* link\/ether \([:0-9a-f]*\) .*/\1/p'
}

link_subnet() {
    addr=$(ip -o -4 addr list $1 | head -n 1 | awk '{print $4}')
    cidr=${addr##*/}
    ruby -e "require 'ipaddr'; puts IPAddr.new('255.255.255.255').mask(${cidr})"
}

get_val() {
    case $var in
    ip_addr_src)
        if grep $(link_mac $dev) /var/lib/libvirt/dnsmasq/*.hostsfile >/dev/null ; then
            echo "dhcp"
        else
            echo "static"
        fi
        ;;

    ip_addr)
        link_ip $dev
        ;;

    mac_addr)
        link_mac $dev
        ;;

    subnet_mask)
        link_subnet $dev
        ;;

    default_gw_ip_addr)
        link_ip $gw_dev
        ;;

    default_gw_mac_addr)
        link_mac $gw_dev
        ;;

    backup_gw_ip_addr)
        link_ip $gw_dev
        ;;

    backup_gw_mac_addr)
        link_mac $gw_dev
        ;;
    esac
}

set_val() {
    case $var in
    ip_addr_src)
        ;;

    ip_addr)
        # If it already has two addresses, replace the last one.
        # Otherwise, just add a second one (keep the first one)
        if [ $(ip -o link list $dev | wc -l) -gt 1 ] ; then
            local current=$(link_ip $dev)
            ip addr del $current dev $dev
        fi
        ip addr add $val dev $dev
        ;;

    mac_addr)
        ;;

    subnet_mask)
        ifconfig $dev netmask $val
        ;;

    default_gw_ip_addr)
        ;;

    default_gw_mac_addr)
        ;;

    backup_gw_ip_addr)
        ;;

    backup_gw_mac_addr)
        ;;
    esac
}

if [ $op = "get" ]; then
    val=$(get_val)
    echo "$var: $val"
elif [ $op = "set" ]; then
    set_val
fi
