_debug() { echo 1>&2 $* } _echo() { if [ "${rc_router_debug}" = "YES" ] then _debug $* fi } _warn() { if [ -x /usr/bin/logger ]; then logger "$0: WARNING: $*" fi echo 1>&2 "$0: WARNING: $*" } __repeat() { __func=$1;shift 1 while [ "$1" != "" ] do ${__func} $1 shift 1 done } __clone_interface() { _echo Adding $1 to cloned interfaces cloned_interfaces="${cloned_interfaces} $1" _echo "Cloned interfaces are now \"${cloned_interfaces}\"" } clone_interfaces() { __repeat __clone_interface $* } clone_interface() { clone_interfaces $* } __add_wireguard_interface() { _echo "Adding $1 to ${wireguard_interfaces}" wireguard_enable="YES" wireguard_interfaces="${wireguard_interfaces} $1" } add_wireguard_interfaces() { __repeat __add_wireguard_interface $* } add_wireguard_interface() { add_wireguard_interfaces $* } add_wireguard_route() { add_route_policy $1 $2 add_wireguard_interface wg$2 } add_wireguard_route_v4() { add_route_policy_v4 $1 $2 # Assuming v6 did this, for now... #add_wireguard_interface wg$2 } compute_56_net() { _echo Running 56 > /dev/fd/2 _echo 'Computing for `'$1'`' > /dev/fd/2 echo $1 | _hash | cut -c 1-12 | sed -e 's/\([0-9a-f][0-9a-f]\)/\1:/g' | awk -F: '{print "fd"$1":"$2$3":"$4$5":"$6}' } compute_48_net() { _echo Running 48 > /dev/fd/2 _echo 'Computing for `'$1'`' > /dev/fd/2 echo $1 | _hash | cut -c 1-10 | sed -e 's/\([0-9a-f][0-9a-f]\)/\1:/g' | awk -F: '{print "fd"$1":"$2$3":"$4$5":"}' } compute_net() { _echo 'Computing for `'$2'`' > /dev/fd/2 case $1 in 56) compute_56_net "$2" ;; 48) compute_48_net "$2" ;; esac } compute_v4_net() { _card=$(echo ${_iface} | sed -e's/\.[0-9]*//') eval _net=\${v4_net_${_card}} if [ -z "${_net}" ] then _net=${v4_net} fi _prefix=${_net} _subnet=$2 echo "${_prefix}.${_subnet}.1/24" } compute_v6_net() { _subnet=$2 _prefix=$1 echo "${_prefix}${_subnet}::1" } _compute_nets() { _card=$1 shift 1 _vlan=$1 shift 1 _base=$((${_vlan}%10)) _net=$(( ( ( ${_vlan} / 100 ) % 10 ) * 10 )) _subnet=$(( ${_net} + ${_base} )) _extra_address="" if [ -z "${1}" ] then echo "Error in configuration: No network class given" exit 1 fi _class=$1 shift 1 _priv="YES" while true do case ${1} in "no_ula") _priv="NO" ;; "no_isp") _isp="" ;; isp=*) _isp=`echo ${1} | sed -e 's/isp=//'` ;; *) break ;; esac shift 1 done while [ -n "${1}" ] do _extra_address="${_extra_address} $1" shift 1 done } add_vlan() { _card=$1 _vlan=$2 _vlans_var=vlans_${_card} eval _vlans="\${${_vlans_var}}" _echo "XXX ${_vlans} XXX" _echo "QQQ ${_vlans} QQQ" | grep ${_vlan} _qres=$? _echo $_qres echo "${_vlans}" | grep ${_vlan} > /dev/null _res=$? _echo $_res if [ 0 -ne $_res ] then _echo vlans_${_card}="\${vlans_${_card}} ${_vlan}" eval vlans_${_card}=\"\${vlans_${_card}} ${_vlan}\" else _echo "Not adding vlan ${_vlan} to card ${_card}" fi } add_rtadv() { _subcard="$1" _echo "XXX ${rtadvd_interfaces} XXX" _echo "QQQ ${rtadvd_interfaces} QQQ" | grep ${_subcard} _qres=$? _echo $_qres echo "${rtadvd_interfaces}" | grep ${_subcard} > /dev/null _res=$? _echo $_res if [ 0 -ne $_res ] then _echo rtadvd_interfaces="${rtadvd_interfaces} ${_subcard}" rtadvd_interfaces="${rtadvd_interfaces} ${_subcard}" else _echo "Not adding subcard ${_subcard} to ipv6 rtadvd list: ${rtadvd_interfaces}" fi } _add_dhcpv6() { _iface=${1} _isp=${2} if [ -z "${_isp}" ] then echo "No ISP found..." exit 255 fi eval dhcpv6_${_isp}_list=\"\${dhcpv6_${_isp}_list} ${_iface}\" } add_dhcpv6() { _iface=${1} _sla=${2} _isp=${3} if [ -z "${_isp}" ] then _isp=${default_isp} fi eval dhcpv6_${_isp}_supplement_list=\"\${dhcpv6_${_isp}_supplement_list} ${_iface}/${_sla}\" } _emit_dhcpv6_for_iface() { _iface=${1} _sla=${2} echo " prefix-interface ${_iface}" >> ${_dhcp_file} echo " {" >> ${_dhcp_file} echo " sla-id ${_sla};" >> ${_dhcp_file} echo " sla-len $((64 - ${_prefix_len}));" >> ${_dhcp_file} echo " };" >> ${_dhcp_file} echo "" >> ${_dhcp_file} } _emit_dhcpv6_for_isp() { _isp=${1} eval _interface=\"\${dhcp_interface_${_isp}}\" _n=${2} eval _prefix_len=\"\${dhcp_prefix_${_isp}}\" mkdir -p ${rc_router_gen_dir} _dhcp_file=${rc_router_gen_dir}/dhcp6c.${_isp}.conf eval _isp_list=\${dhcpv6_${_isp}_list} _echo "Checking ${_isp} against default: ${default_isp}" if [ "${_isp}" = "${default_isp}" ] then _isp_list="${dhcpv6_default_list} ${_isp_list}" fi eval _isp_supplement_list=\${dhcpv6_${_isp}_supplement_list} _echo "Building DHCP info for ${_isp} (interfaces: ${_isp_list})" echo "######################" > ${_dhcp_file} echo "# Configuration for ${_isp} on ${_interface}" >> ${_dhcp_file} echo "######################" >> ${_dhcp_file} echo "id-assoc pd $_n" >> ${_dhcp_file} echo "{" >> ${_dhcp_file} echo " prefix ::/${_prefix_len} infinity;" >> ${_dhcp_file} for _iface_desc in ${_isp_supplement_list} do _iface=`echo ${_iface_desc} | sed -e 's;/.*$;;'` _sla=`echo ${_iface_desc} | sed -e 's;^.*/;;'` _emit_dhcpv6_for_iface ${_iface} ${_sla} done for _iface in ${_isp_list} do _vlan=`echo ${_iface} | sed -e 's/^.*\.//'` _num=`echo ${_vlan} | sed -e 's/\([0-9]\)0\([0-9]\)/\1\2/'` _vlan_sla=`printf "%d" 0x${_num}` _emit_dhcpv6_for_iface ${_iface} ${_vlan_sla} done echo "};" >> ${_dhcp_file} echo "" >> ${_dhcp_file} echo "interface ${_interface} {" >> ${_dhcp_file} echo " send ia-pd ${_n};" >> ${_dhcp_file} echo "};" >> ${_dhcp_file} echo "" >> ${_dhcp_file} echo "" >> ${_dhcp_file} } _emit_dhcpv6() { _n=0 _echo "Emitting DHCPv6, and default ISP is: ${default_isp}" for _isp in ${dhcp_isps} do _emit_dhcpv6_for_isp $_isp ${_n} _n=$((${_n}+1)) done } add_v4_isp() { _iface="${1}" ; shift 1 eval ifconfig_${_iface}="$*" dhcpd_enable="YES" gateway_enable="YES" pf_enable="YES" } add_v6_isp() { _echo "ISP added: $*" _iface="${1}" ; shift 1 _name="${1}" ; shift 1 _isp_type="${1}" ; shift 1 eval _prefix_len="\${prefix_len_${_isp_type}}" if [ "${1}" = "default" ] then _echo "Saw default, and overriding to ${_isp}" default_isp="${_name}" ; shift 1 fi if [ -z "${default_isp}" ] then default_isp=${_name} fi if [ "${default_isp}" = "${_name}" ] then rtsold_enable="YES" ipv6_default_interface="${_iface}" ipv6_cpe_wanif="${_iface}" ipv6_isp_interfaces="${ipv6_isp_interfaces} ${_iface}" dhcp6c_enable="YES" dhcp6c_config="${rc_router_gen_dir}/dhcp6c.conf" fi dhcp6c_interfaces="${dhcp6c_interfaces} ${_iface}" eval dhcp_interface_${_name}="${_iface}" eval dhcp_prefix_${_name}="${_prefix_len}" dhcp_isps="${dhcp_isps} ${_name}" } add_canned_isp() { load_isp_hints # Make sure ISP hints are loaded, first _iface="${1}" ; shift 1 _name="${1}" ; shift 1 _isp="${1}" ; shift 1 _v4_isp_config="\${rc_router_v4_isp_config_${_isp}}" # DHCP, usually add_v4_isp ${_iface} ${_v4_isp_config} add_v6_isp ${_iface} ${_name} ${_isp} $* } _emit_dhcpv4_for_iface() { _iface=${1} _vlan=${2} # Get a newline in there, to make output more readable echo _base=$((${_vlan}%10)) _net=$((${_vlan}/100)) _subnet=${_net}${_base} eval _net=\${v4_net_${_iface}} if [ -z "${_net}" ] then _net=${v4_net} fi eval _lo="\${dhcpv4_pool_lo_${_iface}}" eval _hi="\${dhcpv4_pool_hi_${_iface}}" [ -z "${_lo}" ] && _lo=${dhcpv4_pool_lo} [ -z "${_hi}" ] && _hi=${dhcpv4_pool_hi} _prefix="${_net}.${_subnet}" echo "subnet ${_prefix}.0 netmask 255.255.255.0" echo "{" echo " option routers ${_prefix}.1;" echo " range ${_prefix}.${_lo} ${_prefix}.${_hi};" echo "}" } _emit_dhcpv4_defaults() { echo "option v6-mostly code 108 = integer 32;" [ -z "${enable_v6_mostly}" ] && enable_v6_mostly="NO" if [ `option_selected enable_v6_mostly` = "YES" ] then echo "option v6-mostly 7200;" fi if [ -n "${dhcpv4_dns}" ] then echo "option domain-name-servers ${dhcpv4_dns};" fi if [ -n "${dhcpv4_default_lease_time}" ] then echo "option default-lease-time ${dhcpv4_default_lease_time};" fi if [ -n "${dhcpv4_max_lease_time}" ] then echo "option max-lease-time ${dhcpv4_max_lease_time};" fi } _emit_dhcpv4() { _dhcp_file=${rc_router_gen_dir}/dhcpd.subnets.conf echo "" > ${_dhcp_file} _emit_dhcpv4_defaults >> ${_dhcp_file} for _iface in ${dhcpd_ifaces} do _iface_root=$( echo ${_iface} | sed -e 's/\.[0-9][0-9]*//' ) _vlan=$( echo ${_iface} | sed -e 's/[a-z][a-z]*[0-9][0-9]*\.//' ) _emit_dhcpv4_for_iface ${_iface_root} ${_vlan} >> ${_dhcp_file} done } add_v4_net() { _compute_nets $* _card_and_vlan="${_card}_${_vlan}" _card_dot_vlan="${_card}.${_vlan}" if [ ${_vlan} -ne 0 ] then add_vlan $_card $_vlan else _card_and_vlan="${_card}" _card_dot_vlan="${_card}" fi _class_group="" if [ ! -z "${_class}" ] then _class_group="group ${_class}" fi eval ifconfig_${_card_and_vlan}=\"$(compute_v4_net $_card $_subnet) group internal ${_class_group}\" eval dhcpd_ifaces=\"${dhcpd_ifaces} ${_card_dot_vlan}\" } _add_v6_prefixes() { _next_alias=$1 shift 1 while [ -n "${1}" ] do eval ifconfig_${_card_and_vlan}_alias${_next_alias}=\"inet6 $1/64\" shift 1 _next_alias=`expr $_next_alias + 1` done } add_v6_net() { _isp="" _compute_nets $* _card_and_vlan="${_card}_${_vlan}" _card_dot_vlan="${_card}.${_vlan}" if [ ${_vlan} -ne 0 ] then add_vlan $_card $_vlan else _card_and_vlan="${_card}" _card_dot_vlan="${_card}" fi add_rtadv ${_card_dot_vlan} _compute_ula_prefix _class_group="" if [ ! -z "${_class}" ] then _class_group="group ${_class}" fi eval ifconfig_${_card_and_vlan}_ipv6=\"inet6 fe80::1/64 group internal ${_class_group}\" _next_alias=0 if [ "${_subnet}" = "0" ] then _subnet="00" fi if [ "${_priv}" = "YES" ] then eval ifconfig_${_card_and_vlan}_alias${_next_alias}=\"inet6 $(compute_v6_net ${secret_ip6_net} ${_subnet})/64\" _next_alias=1 # UGLY HACK!!! Does BASH increment work in BSD's sh? fi if [ -n "${_isp}" ] then _add_dhcpv6 ${_card_dot_vlan} ${_isp} else _echo "Adding ${_card_dot_vlan} to default (which is ${default_isp} at this time)" _add_dhcpv6 ${_card_dot_vlan} default fi _add_v6_prefixes ${_next_alias} ${_extra_address} } add_net() { add_v4_net $* add_v6_net $* } option_selected() { eval _value=\$${1} _echo "option_selected: $1 is set to $_value." case $_value in # "yes", "true", "on", or "1" [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) echo "YES" ;; # "no", "false", "off", or "0" [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) echo "NO" ;; *) _warn "\$${1} is not set properly - see rc.conf(5)." echo "FAILED" ;; esac } build_zoneinfo_for_host() { _ISP_PREFIX=${1};shift 1 _MAIN_SUBNET=${1};shift 1 _host=$( echo ${1} | sed -e 's/=.*$//' ) # Not really the MAC, but maybe that's the right way? # For now it's host=SUFFIX _MAC=$( echo ${1} | sed -e 's/^.*=//' ) #echo "Host: ${_host} --- MAC: ${_MAC}" echo "${_host}" IN AAAA ${_ISP_PREFIX}${_MAIN_SUBNET}:${_MAC} } build_zoneinfo() { _prefix=${1} ; shift 1 _subnet=${1} ; shift 1 echo '$TTL 1h30m' echo '@ IN SOA ${localnet_generated_zone_authority}. ${localnet_generated_zone_admin}. (' date +'%s' echo 7200 echo 1200 echo 7200 echo 5400 echo ')' echo '$ORIGIN ${localnet_generated_zone}.' echo '@ IN NS ${localnet_generated_zone_ns}.' for _hostline in $(cat ${1}) do #echo ${_prefix} ${_subnet} ${_hostline} case "${_hostline}" in "#"*) continue ;; esac build_zoneinfo_for_host ${_prefix} ${_subnet} ${_hostline} done } _hash() { sha1sum } # Now we compute a prefix from the hash of the network name. # This lets us be deterministic, yet still know what our # net name is. # _compute_ula_prefix() { secret_ip6_net=$(compute_net ${rc_router_ula_prefix_size} "${rc_router_network_name}") } load_isp_hints() { _hints="$( find ${rc_router_dir}/hints/ -type f )" if [ -d "${rc_router_conf_dir}/hints/" ] then _hints="${_hints} $( find ${rc_router_conf_dir}/hints/ -type f )" fi for _hint in $(ls ${_hints}) do v4_setup="dhcp" # v4 usually defaults to DHCP _isp=$( basename ${_hint} ) . ${_hint} eval rc_router_v4_isp_config_${_isp}=${v4_setup} eval prefix_len_${_isp}=${v6_prefix_len} done } _rc_router_epilogue() { rtsold_flags="${rtsold_flags} ${ipv6_isp_interfaces}" } #. ${router_conf_dir}/pf-framework.subr # vim: ft=bash