luci-mod-network: Add DNS-RR resource record tab to DHCP
authorPaul Donald <newtwen@gmail.com>
Sat, 23 Dec 2023 18:27:59 +0000 (18:27 +0000)
committerPaul Donald <newtwen+github@gmail.com>
Tue, 22 Oct 2024 23:13:04 +0000 (01:13 +0200)
As a convenience at load/save, the hex field de/encodes hex respectively

This follows https://github.com/openwrt/openwrt/pull/14975

Signed-off-by: Paul Donald <newtwen+github@gmail.com>
modules/luci-mod-network/htdocs/luci-static/resources/view/network/dhcp.js

index 97d97e98531101b2b414a81df4dd11b31f85d052..6a94952eabe1e6f9b9eff47e3ae1c652102479da 100644 (file)
@@ -876,6 +876,7 @@ return view.extend({
                dnss.tab('srvhosts', _('SRV'));
                dnss.tab('mxhosts', _('MX'));
                dnss.tab('cnamehosts', _('CNAME'));
+               dnss.tab('dnsrr', _('DNS-RR'));
 
                o = dnss.taboption('srvhosts', form.SectionValue, '__srvhosts__', form.TableSection, 'srvhost', null,
                        _('Bind service records to a domain name: specify the location of services. See <a href="%s">RFC2782</a>.').format('https://datatracker.ietf.org/doc/html/rfc2782')
@@ -994,6 +995,70 @@ return view.extend({
                        so.value(ipv4, '%s (%s)'.format(ipv4, ipaddrs[ipv4]));
                });
 
+               o = dnss.taboption('dnsrr', form.SectionValue, '__dnsrr__', form.TableSection, 'dnsrr', null, 
+                       _('Set an arbitrary resource record (RR) type.') + '<br/>' + 
+                       _('Hexdata is automatically en/decoded on save and load'));
+
+               ss = o.subsection;
+
+               ss.addremove = true;
+               ss.anonymous = true;
+               ss.sortable  = true;
+               ss.rowcolors = true;
+               ss.nodescriptions = true;
+
+               function hexdecodeload(section_id) {
+                       let arr = uci.get('dhcp', section_id, this.option) || [];
+                       // Remove any spaces or colons from the hex string - they're allowed
+                       arr = arr.replace(/[\s:]/g, '');
+                       // Hex-decode the string before displaying
+                       let decodedString = '';
+                       for (let i = 0; i < arr.length; i += 2) {
+                               decodedString += String.fromCharCode(parseInt(arr.substr(i, 2), 16));
+                       }
+                       return decodedString;
+               }
+
+               function hexencodesave(section, value) {
+                       if (!value || value.length === 0) {
+                               uci.unset('dhcp', section, 'hexdata');
+                               return;
+                       }
+                       // Hex-encode the string before saving
+                       const encodedArr = value.split('').map(c => c.charCodeAt(0).toString(16).padStart(2, '0')).join('');
+                       uci.set('dhcp', section, this.option, encodedArr);
+               }
+
+               so = ss.option(form.Value, 'dnsrr', _('Resource Record Name'));
+               so.rmempty = false;
+               so.datatype = 'hostname';
+               so.placeholder = 'svcb.example.com.';
+
+               so = ss.option(form.Value, 'rrnumber', _('Resource Record Number'));
+               so.rmempty = false;
+               so.datatype = 'uinteger';
+               so.placeholder = '64';
+
+               so = ss.option(form.Value, 'hexdata', _('Raw Data'));
+               so.rmempty = true;
+               so.datatype = 'string';
+               so.placeholder = 'free-form string';
+               so.load = hexdecodeload;
+               so.write = hexencodesave;
+
+               so = ss.option(form.DummyValue, '_hexdata', _('Hex Data'));
+               so.width = '10%';
+               so.rawhtml = true;
+               so.load = function(section_id) {
+                       let hexdata = uci.get('dhcp', section_id, 'hexdata') || [];
+                       hexdata = hexdata.replace(/[:]/g, '');
+                       if (hexdata) {
+                               return hexdata.replace(/(.{20})/g, '$1<br/>'); // Inserts <br> after every 2 characters (hex pair)
+                       } else {
+                               return '';
+                       }
+               }
+
                o = s.taboption('ipsets', form.SectionValue, '__ipsets__', form.GridSection, 'ipset', null,
                        _('List of IP sets to populate with the IPs of DNS lookup results of the FQDNs also specified here.') + '<br />' +
                        _('The netfilter components below are only regarded when running fw4.'));