You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
2.2 KiB

  1. #!/bin/sh
  2. #
  3. # script to determine and return SLAAC ipv6 address using prefix from a locally configured interface and the MAC address of the device
  4. # (c) 2018 Keve Mueller <keve at keve dot hu>
  5. #
  6. # activated inside /etc/config/ddns by setting
  7. #
  8. # option ip_source 'script'
  9. # option ip_script '/usr/lib/ddns/slaac_sample.sh br-lan AA:BB:CC:DD:EE:FF'
  10. #
  11. # the script is executed (not parsed) inside get_local_ip() function
  12. # of /usr/lib/ddns/dynamic_dns_functions.sh
  13. #
  14. # useful when this box is the only DDNS client in the network and other clients use SLAAC
  15. # so no need to install ddns client on every "internal" box
  16. #
  17. # NB: this will not catch the actual IPV6 used by the host when it is configured to use temporary addresses
  18. #NB: we need a valid MAC address that is fully expanded with leading zeroes on all positions
  19. format_eui_64() {
  20. local macaddr="$1"
  21. echo ${macaddr:0:1}$(echo ${macaddr:1:1}|tr 0123456789abcdefABCDEF 23016745ab89efcd89efcd)${macaddr:3:2}:${macaddr:6:2}ff:fe${macaddr:9:2}:${macaddr:12:2}${macaddr:15:2}
  22. }
  23. # expand :: in an ipv6 address specification to the appropriate series of 0:
  24. # result will have 8 ipv6 fragments separated by single colon
  25. # NB: input must be a valid IPv6 address, e.g. ::1
  26. # NB: numbers are not prepended with leading zeroes
  27. expand_ipv6_colons() {
  28. local ipv6=$1
  29. # we need :: to be in the middle, so prepend a 0 if the input starts with : and append 0 if it ends with it
  30. if [ "${ipv6:0:1}" = ":" ]; then ipv6=0${ipv6}; fi
  31. if [ "${ipv6: -1:1}" = ":" ]; then ipv6=${ipv6}0; fi
  32. # retain only the real colons
  33. local colons=${ipv6//::|[0123456789abcdefABCDEF]/}
  34. # count them
  35. local num_colons=${#colons}
  36. local filler=":0:0:0:0:0:0:"
  37. # replace the :: with the appropriate substring from filler
  38. local ipv6_x=${ipv6/::/${filler:0:(7-$num_colons)*2-1}}
  39. echo $ipv6_x
  40. }
  41. # obtain the first ipv6 address of the device passed in $1
  42. addr_net=$(ip -6 -o addr show dev $1 scope global up | cut -d" " -f 7 | head -1)
  43. #addr_net=$1
  44. addr=${addr_net%/*}
  45. # TODO: we assume /64 subnet
  46. # get the first 64 bits of the address
  47. prefix=$(expand_ipv6_colons $addr | cut -d: -f -4)
  48. # compute the SLAAC 64 bits from the MAC
  49. suffix=$(format_eui_64 "$2")
  50. echo -n $prefix:$suffix
  51. exit 0
  52. #echo "Should never come here" >&2
  53. #exit 2