#!/bin/bash
# -------------------------------------------------------------------------
# Observium
#
#   This file is part of Observium.
#
# @package    observium
# @subpackage scripts
# @copyright  (C) 2006-2013 Adam Armstrong, (C) 2013-2023 Observium Limited
# -------------------------------------------------------------------------

# Add to snmpd.conf something like:
# pass .1.3.6.1.2.1.31.1.1.1.18 /usr/local/bin/ifAlias
BASE=".1.3.6.1.2.1.31.1.1.1.18" # IF-MIB::ifAlias
REQ="$1"                        # -g get, -n getnext, -s set
OID="$2"                        # Requested OID

if [ "$REQ" = "-s" ]; then
  #echo $* >> /tmp/passtest.log
  exit 0
fi

#1 lo
#2 eth0
#3 eth1
LINKS="$(ip link | awk -F ": " '/^[0-9]+:/ {print $1 " " $2}')"
#echo "$LINKS"

_starts_with() {
  local _str="$1"
  local _sub="$2"
  echo "$_str" | grep "^$_sub" >/dev/null 2>&1
}

ifindex() {
  local IF="${OID#"${BASE}".}"
  local line

  if [ "$REQ" = "-g" ]; then
    # GET request
    case $IF in ''|*[!0-9]*) return 1;; esac; # not int number
    echo "$IF"
    return 0
  else
    # GETNEXT request
    if [ "$IF" = "$BASE" ] || [ "$IF" = "" ]; then
      # first interface index
      echo "${LINKS%% *}"
      return 0
    else
      local next=false
      echo "$LINKS" | while read line; do
        if $next; then echo "${line%% *}"; return 0; fi
        if _starts_with "$line" "$IF "; then next=true; fi
      done
    fi
  fi

  return 1
}

ifname() {
  local IF="$1"
  local line

  echo "$LINKS" | while read line; do
    if _starts_with "$line" "$IF "; then echo "${line##* }"; fi
  done
}

ifalias_sys() {
  #local IFNAME="$1"
  local sys_file="/sys/class/net/${1}/ifalias"

  # 15: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
  #    link/none
  #    alias Wireguard VPN
  if [ -f "$sys_file" ]; then
    cat "$sys_file"
  fi
}

ifalias_frr() {
  local IFNAME="$1"

  # FRR
  if [ -x "/bin/vtysh" ]; then
    # prefer vtysh
    vtysh -c "show interface description" 2>&1 /dev/null | grep -si -m1 "^$IFNAME " | awk '{for (i=4; i<NF; i++) printf $i " "; print $NF}'
  elif [ -f "/etc/frr/frr.conf" ]; then
    awk "/^interface ${IFNAME}/,/^exit/" /etc/frr/frr.conf | awk "/^ description /" | sed "s/^\\ description\\ //"
  fi
}

ifalias_conf() {
  local IFNAME="$1"

  if [ -f "/etc/network/interfaces.d/$IFNAME" ]; then
      CFG="/etc/network/interfaces.d/$IFNAME"
  elif [ -f "/etc/network/interfaces" ]; then
    CFG="/etc/network/interfaces"
  elif [ -f "/etc/sysconfig/network-scripts/ifcfg-$IFNAME" ]; then
    CFG="/etc/sysconfig/network-scripts/ifcfg-$IFNAME"
  elif [ -f "/etc/conf.d/net-conf-$IFNAME" ]; then
    CFG="/etc/conf.d/net-conf-$IFNAME"
  elif [ -f "/etc/conf.d/net" ]; then
    CFG="/etc/conf.d/net"
  else
    return 1
  fi
  grep -si -m1 "^# $IFNAME:" $CFG | sed "s/^# $IFNAME: //i"
}

IFINDEX="$(ifindex)"
[ "$IFINDEX" ] || exit 1 # incorrect ifindex

IFNAME="$(ifname "$IFINDEX")"
IFALIAS="$(ifalias_frr "$IFNAME")"
# get ifalias from config files
[ "$IFALIAS" ] || IFALIAS="$(ifalias_conf "$IFNAME")"
# if not found in config, try common link alias
# sudo ip link set <interface> alias "<ifalias>"
[ "$IFALIAS" ] || IFALIAS="$(ifalias_sys "$IFNAME")"

echo "${BASE}.${IFINDEX}"
echo "string"
echo "$IFALIAS"

exit 0