diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index 475108faf..c85647339 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -932,13 +932,8 @@ function interface_bring_down($interface = "wan", $ifacecfg = false) } /* clear stale state files associated with this interface */ - @unlink("/tmp/{$realifv6}_nameserverv6"); - @unlink("/tmp/{$realifv6}_prefixv6"); - @unlink("/tmp/{$realifv6}_routerv6"); - @unlink("/tmp/{$realifv6}_searchdomainv6"); - @unlink("/tmp/{$realif}_nameserver"); - @unlink("/tmp/{$realif}_router"); - @unlink("/tmp/{$realif}_searchdomain"); + mwexecf('/usr/local/sbin/ifctl -4c -i %s', $realif); + mwexecf('/usr/local/sbin/ifctl -6c -i %s', $realifv6); } function interfaces_ptpid_used($ptpid) @@ -3930,8 +3925,7 @@ function get_interfaces_info($include_unlinked = false) } } - /* XXX there are more magic files */ - $aux = @file_get_contents("/tmp/{$ifinfo['ifv6']}_prefixv6"); + $aux = trim(shell_exec(exec_safe('/usr/local/sbin/ifctl -6pi %s', $ifinfo['ifv6']))); if (!empty($aux)) { $ifinfo['prefixv6'] = $aux; } diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index ca278a48d..9361427f5 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -294,13 +294,16 @@ function get_zoneinfo() function get_searchdomains() { - $search_list = glob('/tmp/*_searchdomain*'); $syscfg = config_read_array('system'); $master_list = []; + $search_list = []; - if (!isset($syscfg['dnsallowoverride'])) { - /* do not return domains as required by configuration */ - $search_list = []; + if (isset($syscfg['dnsallowoverride'])) { + /* return domains as required by configuration */ + $list = trim(shell_exec('/usr/local/sbin/ifctl -sl')); + if (!empty($list)) { + $search_list = explode("\n", $list); + } } if (is_array($search_list)) { @@ -325,22 +328,29 @@ function get_nameservers($interface = null, $with_gateway = false) global $config; $gateways = new \OPNsense\Routing\Gateways(legacy_interfaces_details()); - $dns_lists = glob('/tmp/*_nameserver*'); $syscfg = config_read_array('system'); $exclude_interfaces = []; $master_list = []; + $dns_lists = []; if (!empty($interface)) { /* only acquire servers provided for this interface */ $realif = get_real_interface($interface); $realifv6 = get_real_interface($interface, 'inet6'); - $dns_lists = [ - "/tmp/{$realif}_nameserver", - "/tmp/{$realifv6}_nameserverv6", - ]; - } elseif (!isset($syscfg['dnsallowoverride'])) { - /* do not return dynamic servers as required by configuration */ - $dns_lists = []; + $list = trim(shell_exec(exec_safe('/usr/local/sbin/ifctl -4nli %s', $realif))); + if (!empty($list)) { + $dns_lists[] = $list; + } + $list = trim(shell_exec(exec_safe('/usr/local/sbin/ifctl -6nli %s', $realifv6))); + if (!empty($list)) { + $dns_lists[] = $list; + } + } elseif (isset($syscfg['dnsallowoverride'])) { + /* return dynamic servers as required by configuration */ + $list = trim(shell_exec('/usr/local/sbin/ifctl -nl')); + if (!empty($list)) { + $dns_lists = explode("\n", $list); + } } if (isset($syscfg['dnsallowoverride_exclude'])) { @@ -355,7 +365,8 @@ function get_nameservers($interface = null, $with_gateway = false) foreach ($dns_lists as $fdns) { /* inspect dynamic servers registered in the system files */ - $intf = explode('_', basename($fdns))[0]; + $intf = explode('_', basename($fdns), 2); + $intf[1] = strpos($intf[1], 'v6') === false ? '4' : '6'; if (in_array($intf, $exclude_interfaces)) { continue; } @@ -365,10 +376,12 @@ function get_nameservers($interface = null, $with_gateway = false) continue; } - /* router file is available for connectivity creating nameserver files */ - $gw = trim(@file_get_contents(str_replace('_nameserver', '_router', $fdns))); - if (is_linklocal($gw) && strpos($gw, '%') === false) { - $gw .= "%{$intf}"; + if ($with_gateway) { + /* router file is available for connectivity creating nameserver files */ + $gw = trim(shell_exec(exec_safe('/usr/local/sbin/ifctl -%s -ri %s', [$intf[1], $intf[0]]))); + if (is_linklocal($gw) && strpos($gw, '%') === false) { + $gw .= "%{$intf[0]}"; + } } foreach ($contents as $dns) { diff --git a/src/man/man8/ifctl.8 b/src/man/man8/ifctl.8 index 752b751f0..83d478740 100644 --- a/src/man/man8/ifctl.8 +++ b/src/man/man8/ifctl.8 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd March 18, 2022 +.Dd July 22, 2022 .Dt IFCTL 8 .Os .Sh NAME @@ -33,15 +33,16 @@ .Sh SYNOPSIS .Nm .Op Fl i Ar device +.Op Fl 46 .Op Fl nprs -.Op Fl d -.Op Fl a Ar data +.Op Fl a Ar data | Fl c | Fl d | Fl l .Sh DESCRIPTION The .Nm utility will display or modify network device related data used by dynamic connections. -If neither +If one of +.Sq Fl c , .Sq Fl d or .Sq Fl a @@ -55,14 +56,16 @@ This is the default. .It Fl 6 Use IPv6 mode. .It Fl a -Append data to the currently selected device information. +Append data to the currently selected device data. The option can be used multiple times in the same command invoke to append data at once. Note that .Sq Fl d will be executed first when given in the same command invoke. +.It Fl c +Clear all registed data of the selected device. .It Fl d -Delete the data of the currently selected device information. +Delete the specified data of the selected device. .It Fl i Ar device Select the .Ar device @@ -70,6 +73,11 @@ to operate on. If none was given .Nm list the available devices. +.It Fl l +List mode turns the output into the storage files available for reading. +For implementational reasons the address family selector is ignored when +not using the interface option +.Sq Fl i . .It Fl n Use name server mode. This is the default. diff --git a/src/opnsense/scripts/interfaces/nameserver.sh b/src/opnsense/scripts/interfaces/nameserver.sh index c62f28062..4edc90808 100755 --- a/src/opnsense/scripts/interfaces/nameserver.sh +++ b/src/opnsense/scripts/interfaces/nameserver.sh @@ -23,9 +23,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +DO_COMMAND= DO_CONTENTS= -DO_DELETE= -DO_MODE= DO_VERBOSE= AF= @@ -33,10 +32,22 @@ MD= EX= IF= +flush_routes() +{ + if [ "${MD}" != "nameserver" -o ! -f "${FILE}" ]; then + return + fi + + for CONTENT in $(cat ${FILE}); do + # flush routes here to make sure they are recycled properly + route delete -${AF} "${CONTENT}" + done +} + # default to IPv4 with nameserver mode set -- -4 -n ${@} -while getopts 46a:di:nprsV OPT; do +while getopts 46a:cdi:lnprsV OPT; do case ${OPT} in 4) AF=inet @@ -47,28 +58,31 @@ while getopts 46a:di:nprsV OPT; do EX=v6 ;; a) + DO_COMMAND="-a" DO_CONTENTS="${DO_CONTENTS} ${OPTARG}" ;; + c) + MD="nameserver prefix router searchdomain" + ;; d) - DO_DELETE="-d" + DO_COMMAND="-d" ;; i) IF=${OPTARG} ;; + l) + DO_COMMAND="-l" + ;; n) - DO_MODE="-n" MD="nameserver" ;; p) - DO_MODE="-p" MD="prefix" ;; r) - DO_MODE="-r" MD="router" ;; s) - DO_MODE="-s" MD="searchdomain" ;; V) @@ -85,6 +99,29 @@ if [ -n "${DO_VERBOSE}" ]; then set -x fi +if [ "${DO_COMMAND}" = "-c" ]; then + if [ -z "${IF}" ]; then + echo "Clearing requires interface option" >&2 + exit 1 + fi + + # iterate through possible files + for MD in nameserver prefix router searchdomain; do + FILE="/tmp/${IF}_${MD}${EX}" + flush_routes + rm -f ${FILE} + done + + exit 0 +elif [ "${DO_COMMAND}" = "-l" ]; then + if [ -z "${IF}" ]; then + EX="*" + IF="*" + fi + find -s /tmp -name "${IF}_${MD}${EX}" + exit 0 +fi + FILE="/tmp/${IF:-*}_${MD}${EX}" if [ -z "${IF}" ]; then @@ -98,20 +135,14 @@ if [ -z "${IF}" ]; then exit 0 fi -if [ -n "${DO_DELETE}" ]; then - if [ "${DO_MODE}" = "-n" -a -f ${FILE} ]; then - for CONTENT in $(cat ${FILE}); do - # flush routes here to make sure they are recycled properly - route delete -${AF} "${CONTENT}" - done - fi +if [ "${DO_COMMAND}" = "-d" ]; then + flush_routes rm -f ${FILE} -fi - -for CONTENT in ${DO_CONTENTS}; do - echo "${CONTENT}" >> ${FILE} -done - -if [ -z "${DO_CONTENTS}${DO_DELETE}" -a -f ${FILE} ]; then +elif [ "${DO_COMMAND}" = "-a" ]; then + for CONTENT in ${DO_CONTENTS}; do + echo "${CONTENT}" >> ${FILE} + done +# if nothing else could be done display data +elif [ -f ${FILE} ]; then cat ${FILE} fi