OpenWrt之自定义Hostname

OpenWrt之自定义Client的Hostname

OpenWrt默认的DHCP列表,部分设备无法显示client的hostname,例如iOS设备:

这样对笔者而言,有些不方便,决定增加一列,以显示其hostname的alias,并支持修改,先上效果图:

  • 新增了Customized Hostname一列,显示自定义的Hostname,即Alias;
  • 新增了Set Alias按钮,支持输入自定义的Hostname;

首先,找到对应的代码,在feeds/luci/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/40_dhcp.js中,做以下改动:

24d23
<             L.resolveDefault(uci.load('client')),
29,46d27
<     handleSetAlias: function(lease, alias, ev) {
<               ev.currentTarget.classList.add('spinning');
<               ev.currentTarget.disabled = true;
<               ev.currentTarget.blur();
<
<         var sections = lease.macaddr.toUpperCase().replace(/:/g, '');
<         if (!uci.get('client', sections, 'alias'))
<             uci.add('client', 'client', sections);
<
<         var say = 'Enter a new alias for client(%s)'.format(lease.macaddr.toUpperCase());
<         var new_alias = prompt(say, alias);
<               uci.set('client', sections, 'alias', new_alias || alias);
<
<               return uci.save()
<                       .then(L.bind(L.ui.changes.init, L.ui.changes))
<                       .then(L.bind(L.ui.changes.displayChanges, L.ui.changes));
<       },
<
107d87
<                               E('th', { 'class': 'th' }, _('Customized Hostname')),
134,141d113
<             var alias = null;
<             if (lease.macaddr)
<                 var mac = lease.macaddr.toUpperCase().replace(/:/g, '');
<                 alias = uci.get('client', mac, 'alias');
<
<             if (!alias)
<                 alias = 'Network Device';
<
144d115
<                 alias,
149,153d119
<
<             rows.push(E('button', {
<                 'class': 'cbi-button cbi-button-apply',
<                 'click': L.bind(this.handleSetAlias, this, lease, alias)
<             }, [ _('Set Alias') ]));

以下为文件源码:

'use strict';
'require baseclass';
'require rpc';
'require uci';
'require network';
'require validation';

var callLuciDHCPLeases = rpc.declare({
        object: 'luci-rpc',
        method: 'getDHCPLeases',
        expect: { '': {} }
});

return baseclass.extend({
        title: '',

        isMACStatic: {},
        isDUIDStatic: {},

        load: function() {
                return Promise.all([
                        callLuciDHCPLeases(),
                        network.getHostHints(),
            L.resolveDefault(uci.load('client')),
                        L.resolveDefault(uci.load('dhcp'))
                ]);
        },

    handleSetAlias: function(lease, alias, ev) {
                ev.currentTarget.classList.add('spinning');
                ev.currentTarget.disabled = true;
                ev.currentTarget.blur();

        var sections = lease.macaddr.toUpperCase().replace(/:/g, '');
        if (!uci.get('client', sections, 'alias'))
            uci.add('client', 'client', sections);

        var say = 'Enter a new alias for client(%s)'.format(lease.macaddr.toUpperCase());
        var new_alias = prompt(say, alias);
                uci.set('client', sections, 'alias', new_alias || alias);

                return uci.save()
                        .then(L.bind(L.ui.changes.init, L.ui.changes))
                        .then(L.bind(L.ui.changes.displayChanges, L.ui.changes));
        },

        handleCreateStaticLease: function(lease, ev) {
                ev.currentTarget.classList.add('spinning');
                ev.currentTarget.disabled = true;
                ev.currentTarget.blur();

                var cfg = uci.add('dhcp', 'host');
                uci.set('dhcp', cfg, 'name', lease.hostname);
                uci.set('dhcp', cfg, 'ip', lease.ipaddr);
                uci.set('dhcp', cfg, 'mac', lease.macaddr.toUpperCase());

                return uci.save()
                        .then(L.bind(L.ui.changes.init, L.ui.changes))
                        .then(L.bind(L.ui.changes.displayChanges, L.ui.changes));
        },

        handleCreateStaticLease6: function(lease, ev) {
                ev.currentTarget.classList.add('spinning');
                ev.currentTarget.disabled = true;
                ev.currentTarget.blur();

                var cfg = uci.add('dhcp', 'host'),
                    ip6arr = lease.ip6addrs[0] ? validation.parseIPv6(lease.ip6addrs[0]) : null;

                uci.set('dhcp', cfg, 'name', lease.hostname);
                uci.set('dhcp', cfg, 'duid', lease.duid.toUpperCase());
                uci.set('dhcp', cfg, 'mac', lease.macaddr);
                if (ip6arr)
                        uci.set('dhcp', cfg, 'hostid', (ip6arr[6] * 0xFFFF + ip6arr[7]).toString(16));

                return uci.save()
                        .then(L.bind(L.ui.changes.init, L.ui.changes))
                        .then(L.bind(L.ui.changes.displayChanges, L.ui.changes));
        },

        renderLeases: function(data) {
                var leases = Array.isArray(data[0].dhcp_leases) ? data[0].dhcp_leases : [],
                    leases6 = Array.isArray(data[0].dhcp6_leases) ? data[0].dhcp6_leases : [],
                    machints = data[1].getMACHints(false),
                    hosts = uci.sections('dhcp', 'host'),
                    isReadonlyView = !L.hasViewPermission();

                for (var i = 0; i < hosts.length; i++) {
                        var host = hosts[i];

                        if (host.mac) {
                                var macs = L.toArray(host.mac);
                                for (var j = 0; j < macs.length; j++) {
                                        var mac = macs[j].toUpperCase();
                                        this.isMACStatic[mac] = true;
                                }
                        }
                        if (host.duid) {
                                var duid = host.duid.toUpperCase();
                                this.isDUIDStatic[duid] = true;
                        }
                };

                var table = E('table', { 'class': 'table lases' }, [
                        E('tr', { 'class': 'tr table-titles' }, [
                                E('th', { 'class': 'th' }, _('Hostname')),
                                E('th', { 'class': 'th' }, _('Customized Hostname')),
                                E('th', { 'class': 'th' }, _('IPv4 address')),
                                E('th', { 'class': 'th' }, _('MAC address')),
                                E('th', { 'class': 'th' }, _('Lease time remaining')),
                                E('th', { 'class': 'th cbi-section-actions' }, _('Static Alias')),
                                isReadonlyView ? E([]) : E('th', { 'class': 'th cbi-section-actions' }, _('Static Lease'))
                        ])
                ]);

                cbi_update_table(table, leases.map(L.bind(function(lease) {
                        var exp, rows;

                        if (lease.expires === false)
                                exp = E('em', _('unlimited'));
                        else if (lease.expires <= 0)
                                exp = E('em', _('expired'));
                        else
                                exp = '%t'.format(lease.expires);

                        var hint = lease.macaddr ? machints.filter(function(h) { return h[0] == lease.macaddr })[0] : null,
                            host = null;

                        if (hint && lease.hostname && lease.hostname != hint[1])
                                host = '%s (%s)'.format(lease.hostname, hint[1]);
                        else if (lease.hostname)
                                host = lease.hostname;

            var alias = null;
            if (lease.macaddr)
                var mac = lease.macaddr.toUpperCase().replace(/:/g, '');
                alias = uci.get('client', mac, 'alias');

            if (!alias)
                alias = 'Network Device';

                        rows = [
                                host || '-',
                alias,
                                lease.ipaddr,
                                lease.macaddr,
                                exp
                        ];

            rows.push(E('button', {
                'class': 'cbi-button cbi-button-apply',
                'click': L.bind(this.handleSetAlias, this, lease, alias)
            }, [ _('Set Alias') ]));

                        if (!isReadonlyView && lease.macaddr != null) {
                                var mac = lease.macaddr.toUpperCase();
                                rows.push(E('button', {
                                        'class': 'cbi-button cbi-button-apply',
                                        'click': L.bind(this.handleCreateStaticLease, this, lease),
                                        'disabled': this.isMACStatic[mac]
                                }, [ _('Set Static') ]));
                        }

                        return rows;
                }, this)), E('em', _('There are no active leases')));

                var table6 = E('table', { 'class': 'table leases6' }, [
                        E('tr', { 'class': 'tr table-titles' }, [
                                E('th', { 'class': 'th' }, _('Host')),
                                E('th', { 'class': 'th' }, _('IPv6 address')),
                                E('th', { 'class': 'th' }, _('DUID')),
                                E('th', { 'class': 'th' }, _('Lease time remaining')),
                                isReadonlyView ? E([]) : E('th', { 'class': 'th cbi-section-actions' }, _('Static Lease'))
                        ])
                ]);

                cbi_update_table(table6, leases6.map(L.bind(function(lease) {
                        var exp, rows;

                        if (lease.expires === false)
                                exp = E('em', _('unlimited'));
                        else if (lease.expires <= 0)
                                exp = E('em', _('expired'));
                        else
                                exp = '%t'.format(lease.expires);

                        var hint = lease.macaddr ? machints.filter(function(h) { return h[0] == lease.macaddr })[0] : null,
                            host = null;

                        if (hint && lease.hostname && lease.hostname != hint[1] && lease.ip6addr != hint[1])
                                host = '%s (%s)'.format(lease.hostname, hint[1]);
                        else if (lease.hostname)
                                host = lease.hostname;
                        else if (hint)
                                host = hint[1];

                        rows = [
                                host || '-',
                                lease.ip6addrs ? lease.ip6addrs.join(' ') : lease.ip6addr,
                                lease.duid,
                                exp
                        ];

                        if (!isReadonlyView && lease.duid != null) {
                                var duid = lease.duid.toUpperCase();
                                rows.push(E('button', {
                                        'class': 'cbi-button cbi-button-apply',
                                        'click': L.bind(this.handleCreateStaticLease6, this, lease),
                                        'disabled': this.isDUIDStatic[duid]
                                }, [ _('Set Static') ]));
                        }

                        return rows;
                }, this)), E('em', _('There are no active leases')));

                return E([
                        E('h3', _('Active DHCP Leases')),
                        table,
                        E('h3', _('Active DHCPv6 Leases')),
                        table6
                ]);
        },

        render: function(data) {
                if (L.hasSystemFeature('dnsmasq') || L.hasSystemFeature('odhcpd'))
                        return this.renderLeases(data);

                return E([]);
        }
});

直接替换文件系统中的/www/luci-static/resources/view/status/include/40_dhcp.js

并创建配置文件:

touch /etc/config/client

并删除luci的缓存:

rm -rf /tmp/luci-indexcache*

重新打开浏览器,即得所需效果。
注意:有时候浏览器本身有缓存,可以换个浏览器打开试试;或者使用无痕模式浏览。

posted @   付时凡  阅读(530)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示