net/mdns-repeater: Modernize plugin code; Add blocklist support (contributed by Kodehyrden) (#4375)

* net/mdns-repeater: Modernize plugin code; Add blacklist support (contributed by Kodehyrden)

* net/mdns-repeater: bump version

* net/mdns-repeater: fix indentation of model and form

* Update net/mdns-repeater/src/etc/inc/plugins.inc.d/mdnsrepeater.inc

Co-authored-by: Franco Fichtner <franco@lastsummer.de>

* Update net/mdns-repeater/src/opnsense/mvc/app/views/OPNsense/MDNSRepeater/index.volt

Co-authored-by: Franco Fichtner <franco@lastsummer.de>

* Update net/mdns-repeater/pkg-descr

Co-authored-by: Franco Fichtner <franco@lastsummer.de>

* net/mdnsrepeater: Change blacklist to blocklist

---------

Co-authored-by: Franco Fichtner <franco@lastsummer.de>
This commit is contained in:
Monviech 2024-12-06 17:28:15 +01:00 committed by GitHub
parent 80ef988989
commit 65cbc82053
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 193 additions and 193 deletions

View file

@ -1,6 +1,5 @@
PLUGIN_NAME= mdns-repeater
PLUGIN_VERSION= 1.1
PLUGIN_REVISION= 1
PLUGIN_VERSION= 1.2
PLUGIN_COMMENT= Proxy multicast DNS between networks
PLUGIN_MAINTAINER= franz.fabian.94@gmail.com
PLUGIN_DEPENDS= mdns-repeater

View file

@ -7,6 +7,11 @@ It can be used to bridge zeroconf devices to work properly across the two subnet
Plugin Changelog
================
1.2
* modernize plugin code
* blocklist support (contributed by Kodehyrden)
1.1
* CARP support (contributed by Markus Reiter)

View file

@ -1,63 +1,65 @@
<?php
/*
Copyright (C) 2017 Fabian Franz
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
function mdnsrepeater_enabled()
{
$model = new \OPNsense\MDNSRepeater\MDNSRepeater();
return (string)$model->enabled == '1';
}
function mdnsrepeater_firewall($fw)
{
if (!mdnsrepeater_enabled()) {
return;
}
}
* Copyright (c) 2017 Fabian Franz
* Copyright (c) 2024 Cedrik Pischem
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS`` AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
function mdnsrepeater_services()
{
$services = array();
global $config;
// don't load the service if it is not enabled
// maybe there are no settings yet
if (!mdnsrepeater_enabled()) {
return $services;
$services = [];
if (isset($config['OPNsense']['MDNSRepeater']['enabled']) &&
$config['OPNsense']['MDNSRepeater']['enabled'] == '1') {
$services[] = [
'description' => gettext('mDNS Repeater'),
'configd' => [
'start' => ['mdnsrepeater start'],
'restart' => ['mdnsrepeater restart'],
'stop' => ['mdnsrepeater stop'],
],
'name' => 'mdns-repeater',
'pidfile' => '/var/run/mdns-repeater.pid',
];
}
$services[] = array(
'description' => gettext('mDNS Repeater'),
'configd' => array(
'restart' => array('mdnsrepeater restart'),
'start' => array('mdnsrepeater start'),
'stop' => array('mdnsrepeater stop'),
),
'name' => 'mdns-repeater',
);
return $services;
}
function mdnsrepeater_xmlrpc_sync()
{
$result = [];
$result[] = [
'description' => gettext('mDNS Repeater'),
'section' => 'OPNsense.MDNSRepeater',
'id' => 'mdns-repeater',
'services' => ['mdns-repeater'],
];
return $result;
}

View file

@ -2,6 +2,7 @@
/**
* Copyright (C) 2017 Fabian Franz
* Copyright (C) 2024 Cedrik Pischem
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -28,52 +29,12 @@
namespace OPNsense\MDNSRepeater\Api;
use OPNsense\Base\ApiControllerBase;
use OPNsense\Core\Backend;
use OPNsense\MDNSRepeater\MDNSRepeater;
use OPNsense\Base\ApiMutableServiceControllerBase;
class ServiceController extends ApiControllerBase
class ServiceController extends ApiMutableServiceControllerBase
{
public function statusAction()
{
$backend = new Backend();
$result = array('result' => 'failed');
$res = $backend->configdRun('mdnsrepeater status');
if (stripos($res, 'is running')) {
$result['result'] = 'running';
} elseif (stripos($res, 'not running')) {
$general = new MDNSRepeater();
if ((string)$general->enabled == '1') {
$result['result'] = 'stopped';
} else {
$result['result'] = 'disabled';
}
} else {
$result['message'] = $res;
}
return $result;
}
public function startAction()
{
$backend = new Backend();
$result = array('result' => 'failed');
$backend->configdRun('template reload OPNsense/MDNSRepeater');
$result['result'] = $backend->configdRun('mdnsrepeater start');
return $result;
}
public function stopAction()
{
$backend = new Backend();
$result = array("result" => "failed");
$result['result'] = $backend->configdRun('mdnsrepeater stop');
return $result;
}
public function restartAction()
{
$this->stopAction();
return $this->startAction();
}
protected static $internalServiceClass = '\OPNsense\MDNSRepeater\MDNSRepeater';
protected static $internalServiceTemplate = 'OPNsense/MDNSRepeater';
protected static $internalServiceEnabled = 'enabled';
protected static $internalServiceName = 'mdnsrepeater';
}

View file

@ -1,20 +1,32 @@
<form>
<field>
<id>mdnsrepeater.enabled</id>
<label>Enable</label>
<type>checkbox</type>
<help>Enable the repeater.</help>
</field>
<field>
<id>mdnsrepeater.enablecarp</id>
<label>Enable CARP Failover</label>
<type>checkbox</type>
<help>This will activate the repeater service only on the master device.</help>
</field>
<field>
<id>mdnsrepeater.interfaces</id>
<label>Listen Interfaces</label>
<type>select_multiple</type>
<help>At least 2 interfaces must be selected. The maximum number of supported interfaces by the daemon is 5.</help>
</field>
<field>
<type>header</type>
<label>General Settings</label>
</field>
<field>
<id>mdnsrepeater.enabled</id>
<label>Enable</label>
<type>checkbox</type>
<help>Enable the repeater.</help>
</field>
<field>
<id>mdnsrepeater.enablecarp</id>
<label>Enable CARP Failover</label>
<type>checkbox</type>
<help>This will activate the repeater service only on the master device.</help>
</field>
<field>
<id>mdnsrepeater.interfaces</id>
<label>Listen Interfaces</label>
<type>select_multiple</type>
<help>At least 2 interfaces must be selected. The maximum number of supported interfaces by the daemon is 5.</help>
</field>
<field>
<id>mdnsrepeater.blocklist</id>
<label>Blocklist</label>
<type>select_multiple</type>
<style>tokenize</style>
<allownew>true</allownew>
<help>Enter up to 16 client IPv4 addresses including subnet or networks to be exluded.</help>
</field>
</form>

View file

@ -1,20 +1,28 @@
<model>
<mount>//OPNsense/MDNSRepeater</mount>
<version>1.0.1</version>
<description>mdns-repeater settings</description>
<items>
<enabled type="BooleanField">
<Default>0</Default>
<Required>Y</Required>
</enabled>
<enablecarp type="BooleanField">
<Default>0</Default>
<Required>Y</Required>
</enablecarp>
<interfaces type="InterfaceField">
<Default>lan</Default>
<Required>Y</Required>
<Multiple>Y</Multiple>
</interfaces>
</items>
<mount>//OPNsense/MDNSRepeater</mount>
<version>1.0.1</version>
<description>mdns-repeater settings</description>
<items>
<enabled type="BooleanField">
<Default>0</Default>
<Required>Y</Required>
</enabled>
<enablecarp type="BooleanField">
<Default>0</Default>
<Required>Y</Required>
</enablecarp>
<interfaces type="InterfaceField">
<Default>lan</Default>
<Required>Y</Required>
<Multiple>Y</Multiple>
</interfaces>
<blocklist type="NetworkField">
<NetMaskRequired>Y</NetMaskRequired>
<AddressFamily>ipv4</AddressFamily>
<FieldSeparator>,</FieldSeparator>
<WildcardEnabled>N</WildcardEnabled>
<AsList>Y</AsList>
<ValidationMessage>Only valid IPv4 networks or individual addresses including subnet are allowed.</ValidationMessage>
</blocklist>
</items>
</model>

View file

@ -1,63 +1,75 @@
{#
Copyright © 2017 Fabian Franz
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
#}
# Copyright (c) 2017 Fabian Franz
# Copyright (c) 2024 Cedrik Pischem
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#}
<script>
$( document ).ready(function() {
var data_get_map = {'general': '/api/mdnsrepeater/settings/get'};
mapDataToFormUI(data_get_map).done(function(data){
$(document).ready(function() {
mapDataToFormUI({'frm_GeneralSettings': "/api/mdnsrepeater/settings/get"}).done(function() {
formatTokenizersUI();
$('select').selectpicker('refresh');
});
ajaxCall(url="/api/mdnsrepeater/service/status", sendData={}, callback=function(data,status) {
updateServiceStatusUI(data['result']);
$('.selectpicker').selectpicker('refresh');
updateServiceControlUI('mdnsrepeater');
});
// link save button to API set action
$("#saveAct").click(function(){
saveFormToEndpoint(url="/api/mdnsrepeater/settings/set", formid='general',callback_ok=function(){
$("#saveAct_progress").addClass("fa fa-spinner fa-pulse");
ajaxCall(url="/api/mdnsrepeater/service/restart", sendData={}, callback=function(data,status) {
ajaxCall(url="/api/mdnsrepeater/service/status", sendData={}, callback=function(data,status) {
updateServiceStatusUI(data['result']);
$("#reconfigureAct").SimpleActionButton({
onPreAction: function() {
const dfObj = $.Deferred();
saveFormToEndpoint("/api/mdnsrepeater/settings/set", 'frm_GeneralSettings', dfObj.resolve, true, dfObj.reject);
return dfObj;
},
onAction: function(data, status) {
if (status === "success" && data.status === 'ok') {
ajaxCall("/api/mdnsrepeater/service/reconfigure", {}, function(reconfigData, reconfigStatus) {
if (reconfigStatus === "success" && reconfigData.status === 'ok') {
updateServiceControlUI('mdnsrepeater');
}
});
$("#saveAct_progress").removeClass("fa fa-spinner fa-pulse");
});
});
}
}
});
});
// Initialize service control UI
updateServiceControlUI('mdnsrepeater');
});
</script>
<div class="content-box" style="padding-bottom: 1.5em;">
{{ partial("layout_partials/base_form",['fields': general,'id':'general'])}}
<div class="col-md-12">
<hr />
<button class="btn btn-primary" id="saveAct" type="button"><b>{{ lang._('Save') }}</b> <i id="saveAct_progress"></i></button>
<section class="page-content-main">
<div class="content-box">
{{ partial("layout_partials/base_form", ['fields': general, 'id': 'frm_GeneralSettings']) }}
</div>
</div>
<br/>
<div class="content-box">
<div class="col-md-12">
<br/>
<button class="btn btn-primary" id="reconfigureAct"
data-endpoint="/api/mdnsrepeater/service/reconfigure"
data-label="{{ lang._('Apply') }}"
type="button">
{{ lang._('Apply') }}
</button>
<br/><br/>
</div>
</div>
</section>

View file

@ -17,8 +17,3 @@ message:mdns-repeater status
command:service mdns-repeater restart
type:script
message:restarting mdns-repeater
[reload]
command:service mdns-repeater reload
type:script
message:reload mdns-repeater

View file

@ -9,7 +9,13 @@ required_files="/var/run/mdns-repeater.CARP_MASTER"
{% for i in osifnames %}
{% do interface_list.append(physical_interface(i)) %}
{% endfor %}
mdns_repeater_interfaces="{{ interface_list | join(' ') }}"
{% set repeater_interfaces = interface_list | join(' ') %}
{% if helpers.exists('OPNsense.MDNSRepeater.blocklist') and OPNsense.MDNSRepeater.blocklist != '' %}
{% set blocklist_and_repeater_interfaces = "-b " + OPNsense.MDNSRepeater.blocklist.split(',') | join(' -b ') + " " + repeater_interfaces %}
mdns_repeater_interfaces="{{ blocklist_and_repeater_interfaces }}"
{% else %}
mdns_repeater_interfaces="{{ repeater_interfaces }}"
{% endif %}
{% else %}
mdns_repeater_enable="NO"
{% endif %}