aboutsummaryrefslogtreecommitdiff
path: root/etc/private/vm-gen-macaddress
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-09-04 13:10:33 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-09-04 13:10:33 +0200
commit9f6b17a091222f8240194ae331f64e92ed2c3c28 (patch)
treeb83996996a6a6cee463e11fc884becd16946ea54 /etc/private/vm-gen-macaddress
parentb026efa58533e7ce1f04bf9fbb8eb5e7da19db65 (diff)
Update private VM management scripts
Diffstat (limited to 'etc/private/vm-gen-macaddress')
-rwxr-xr-xetc/private/vm-gen-macaddress60
1 files changed, 60 insertions, 0 deletions
diff --git a/etc/private/vm-gen-macaddress b/etc/private/vm-gen-macaddress
new file mode 100755
index 0000000..c13a993
--- /dev/null
+++ b/etc/private/vm-gen-macaddress
@@ -0,0 +1,60 @@
+#! /usr/bin/env bash
+
+# Generate a locally administered MAC address (LAA) number <num> based on the
+# specified universally administered address <mac> (UAA, for example, an
+# address corresponding to the host's physical Ethernet interface).
+#
+# Specifically, the resulting address is formed by combining the
+# LAA-conforming first octet with the subsequent five octets from <mac>:
+#
+# x[26ae]:xx:xx:xx:xx:xx
+#
+# The first octet is derived from <num> as follows:
+#
+# 0-15 : 02-f2
+# 16-31 : 06-f6
+# 32-47 : 0a-fa
+# 48-63 : 0e-fe
+#
+# For example, <num> can correspond to the interface number, such as tap0, for
+# which the resulting MAC address will be used.
+#
+usage="usage: $0 <mac> <num>"
+
+owd="$(pwd)"
+trap "{ cd '$owd'; exit 1; }" ERR
+set -o errtrace # Trap in functions.
+
+function info () { echo "$*" 1>&2; }
+function error () { info "$*"; exit 1; }
+
+if [ -z "$1" ]; then
+ error "$usage"
+fi
+
+o='[0-9a-fA-F]'
+mac="$(sed -nr -e "s/^$o$o:($o$o:$o$o:$o$o:$o$o:$o$o)$/\1/p" <<<"$1")"
+
+if [ -z "$mac" ]; then
+ error "invalid MAC address '$1'"
+fi
+
+if [ -z "$2" ]; then
+ error "$usage"
+fi
+
+num="$2"
+
+if (( num < 0 || num > 63 )); then
+ error "number '$num' is out of 0-63 range"
+fi
+
+if (( num < 16 )); then
+ printf "%x2:%s\n" $(( num )) "$mac"
+elif (( num < 32 )); then
+ printf "%x6:%s\n" $(( num - 16 )) "$mac"
+elif (( num < 48 )); then
+ printf "%xa:%s\n" $(( num - 32 )) "$mac"
+else
+ printf "%xe:%s\n" $(( num - 48 )) "$mac"
+fi