#!/bin/bash

#
# NetworkManager-DUID-LLT
#
# a workaround script:
# NM uses DUID-UUID .. and this is not user configurable .. but
# CERN network needs DUID-LL(T) for DHCPv6 so we 'hack' NM feeding 
# it with precalculated DUID-LLT in order to be able to get IPV6 
# address this script shall run from systemd AFTER NetworkManager 
# on each boot.
#
# 07.02.2017 Jaroslaw.Polok@cern.ch

INTS=`/usr/sbin/ifconfig -s | /usr/bin/sed -e 's/ .*//' | /usr/bin/grep -vP "docker|virbr|Iface|lo"`
NML6="/var/lib/NetworkManager/dhclient6"
# type (2b) - arch (2b) - time (4b)
DUID_P="00:01:00:01:1e:f3:ad:7f:" 
CHANGE=0

for IF in $INTS; do
 # this is not entirely correct ... DUID-LLT shall be the same for all interfaces
 # but what if some are not registered in network.cern.ch ? ...
 HWADDR=${DUID_P}`/usr/sbin/ifconfig $IF | /usr/bin/grep ether | /usr/bin/sed -e 's/.*ether //' | /usr/bin/sed -e 's/ .*//'`
 HWADDRARR=(${HWADDR//:/ })
 DUIDOUT=""

 # and we need to convert from hex pairs to mixed oct-ascii ...
 for I in ${!HWADDRARR[@]}; do
  UHW=`echo ${HWADDRARR[$I]} | /usr/bin/tr '[:lower:]' [':upper:']`
  OHW=`echo "obase=8;ibase=16; $UHW" | /usr/bin/bc` 
  NOHW=`echo $OHW | /usr/bin/awk '{printf "\\\%.3d\n", $0}'`  
  if [ $OHW -gt 37 ] && [ $OHW -lt 177 ]; then
   # " and \ need to be escaped!
   if [ $OHW -eq 42 ] || [ $OHW -eq 134 ]; then
    DUIDOUT=${DUIDOUT}$(echo -n '\')
   fi 
    DUIDOUT=${DUIDOUT}$(echo -e '\0'$OHW) 
  else 
    DUIDOUT=${DUIDOUT}$(echo $NOHW)
  fi
 done
 #  echo "GOT: $DUIDOUT"  
  LEASEFILES=`/bin/ls ${NML6}-*-${IF}.lease 2>/dev/null`
  for LEASEFILE in $LEASEFILES; do
   if [ `/usr/bin/fgrep -c \"${DUIDOUT}\" $LEASEFILE 2>/dev/null` -ne 1 ]; then
    echo "default-duid \"${DUIDOUT}\";" > $LEASEFILE
    CHANGE=1 
  fi
  done
done

if [ $CHANGE == 1 ]; then
 /usr/bin/systemctl try-restart NetworkManager
fi