Global: Change MAC address storage to use BIGINT

This requires changes to the MySQL database!

Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
This commit is contained in:
Adrian Schmutzler 2018-08-27 12:33:27 +02:00
parent 2a7d58413d
commit bc3460f2e0
16 changed files with 148 additions and 84 deletions

View File

@ -44,9 +44,9 @@ mysql.execute("""
mysql.execute("""
CREATE TABLE gw_netif (
`gw` smallint(5) UNSIGNED NOT NULL,
`mac` char(17) COLLATE utf8_unicode_ci NOT NULL,
`mac` bigint(20) UNSIGNED NOT NULL,
`netif` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
`vpnmac` char(17) COLLATE utf8_unicode_ci DEFAULT NULL,
`vpnmac` bigint(20) UNSIGNED DEFAULT NULL,
`ipv4` char(18) COLLATE utf8_unicode_ci DEFAULT NULL,
`ipv6` varchar(60) COLLATE utf8_unicode_ci DEFAULT NULL,
`dhcpstart` char(15) COLLATE utf8_unicode_ci DEFAULT NULL,

View File

@ -10,7 +10,7 @@ mysql = FreifunkMySQL()
mysql.execute("""
CREATE TABLE banned (
`mac` char(17) COLLATE utf8_unicode_ci NOT NULL,
`mac` bigint(20) UNSIGNED NOT NULL,
`added` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
""")
@ -22,7 +22,7 @@ mysql.execute("""
mysql.execute("""
CREATE TABLE blocked (
`mac` char(17) COLLATE utf8_unicode_ci NOT NULL,
`mac` bigint(20) UNSIGNED NOT NULL,
`added` datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
""")
@ -139,9 +139,9 @@ mysql.execute("""
mysql.execute("""
CREATE TABLE router_gw (
`router` mediumint(8) UNSIGNED NOT NULL,
`mac` char(17) COLLATE utf8_unicode_ci NOT NULL,
`mac` bigint(20) UNSIGNED NOT NULL,
`quality` float NOT NULL,
`nexthop` char(17) COLLATE utf8_unicode_ci DEFAULT NULL,
`nexthop` bigint(20) UNSIGNED DEFAULT NULL,
`netif` varchar(15) COLLATE utf8_unicode_ci DEFAULT NULL,
`gw_class` varchar(25) COLLATE utf8_unicode_ci DEFAULT NULL,
`selected` tinyint(1) NOT NULL DEFAULT '0'
@ -169,7 +169,7 @@ mysql.execute("""
mysql.execute("""
CREATE TABLE router_neighbor (
`router` mediumint(8) UNSIGNED NOT NULL,
`mac` char(17) COLLATE utf8_unicode_ci NOT NULL,
`mac` bigint(20) UNSIGNED NOT NULL,
`netif` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
`quality` float NOT NULL,
`type` varchar(10) COLLATE utf8_unicode_ci DEFAULT 'l2'
@ -192,7 +192,7 @@ mysql.execute("""
`tx` int(10) UNSIGNED NOT NULL,
`fe80_addr` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`ipv4_addr` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`mac` char(17) COLLATE utf8_unicode_ci NOT NULL,
`mac` bigint(20) UNSIGNED DEFAULT NULL,
`wlan_channel` tinyint(3) UNSIGNED DEFAULT NULL,
`wlan_type` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
`wlan_width` tinyint(3) UNSIGNED DEFAULT NULL,
@ -236,7 +236,7 @@ mysql.execute("""
CREATE TABLE router_stats_gw (
`time` int(11) NOT NULL,
`router` mediumint(8) UNSIGNED NOT NULL,
`mac` char(17) COLLATE utf8_unicode_ci NOT NULL,
`mac` bigint(20) UNSIGNED NOT NULL,
`quality` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
""")
@ -251,7 +251,7 @@ mysql.execute("""
CREATE TABLE router_stats_neighbor (
`time` int(11) NOT NULL,
`router` mediumint(8) UNSIGNED NOT NULL,
`mac` char(17) COLLATE utf8_unicode_ci NOT NULL,
`mac` bigint(20) UNSIGNED NOT NULL,
`quality` float NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
""")

View File

@ -29,7 +29,7 @@ mysql.execute("""
mysql.execute("""
CREATE TABLE stats_gw (
`time` int(11) NOT NULL,
`mac` char(17) COLLATE utf8_unicode_ci NOT NULL,
`mac` bigint(20) UNSIGNED NOT NULL,
`clients` mediumint(9) NOT NULL,
`online` smallint(6) NOT NULL,
`offline` smallint(6) NOT NULL,

View File

@ -39,7 +39,7 @@ def import_gw_data(mysql, gw_data):
ndata = []
for n in gw_data["netifs"]:
if len(n["mac"])<17:
if len(n["mac"])<17 or len(n["mac"])>17:
continue
if n["netif"].startswith("l2tp"): # Filter l2tp interfaces
continue
@ -56,7 +56,7 @@ def import_gw_data(mysql, gw_data):
if not "dhcpend" in n or not n["dhcpend"]:
n["dhcpend"] = None
ndata.append((newid,n["mac"],n["netif"],n["vpnmac"],n["ipv4"],n["ipv6"],n["dhcpstart"],n["dhcpend"],time,))
ndata.append((newid,mac2int(n["mac"]),n["netif"],mac2int(n["vpnmac"]),n["ipv4"],n["ipv6"],n["dhcpstart"],n["dhcpend"],time,))
mysql.executemany("""
INSERT INTO gw_netif (gw, mac, netif, vpnmac, ipv4, ipv6, dhcpstart, dhcpend, last_contact)
@ -92,12 +92,12 @@ def gw_name(gw):
if gw["gw"] and gw["gwif"]:
s = gw["gw"] + " (" + gw["gwif"] + ")"
else:
s = gw["mac"]
s = int2mac(gw["mac"])
return s
def gw_bat(gw):
if gw["batif"] and gw["batmac"]:
s = gw["batmac"] + " (" + gw["batif"] + ")"
s = int2mac(gw["batmac"]) + " (" + gw["batif"] + ")"
else:
s = "---"
return s

View File

@ -8,6 +8,48 @@ from ffmap.config import CONFIG
def utcnow():
return datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
def int2mac(data,keys=None):
if keys:
for k in keys:
data[k] = int2mac(data[k])
return data
if data:
return ':'.join(format(s, '02x') for s in data.to_bytes(6,byteorder='big'))
#return ':'.join(format(s, '02x') for s in bytes.fromhex('{0:x}'.format(data)))
else:
return ''
def int2shortmac(data,keys=None):
if keys:
for k in keys:
data[k] = int2shortmac(data[k])
return data
if data:
return '{:012x}'.format(data)
else:
return ''
def shortmac2mac(data):
if data:
return ':'.join(format(s, '02x') for s in bytes.fromhex(data.replace(':','')))
else:
return ''
def mac2int(data):
if data:
return int(data.replace(":",""),16)
else:
return None
def int2mactuple(data,index=None):
if index:
for r in data:
r[index] = int2mac(r[index])
else:
for r in data:
r = int2mac(r)
return data
def writelog(path, content):
with open(path, "a") as csv:
csv.write(time.strftime('{%Y-%m-%d %H:%M:%S}') + " - " + content + "\n")

View File

@ -125,5 +125,3 @@ class FreifunkMySQL:
#r = pytz.utc.localize(r)
r = r.replace(tzinfo=datetime.timezone.utc)
return data

View File

@ -62,7 +62,7 @@ def import_nodewatcher_xml(mysql, mac, xml, banned, netifdict, statstime):
reset = False
try:
findrouter = mysql.findone("SELECT router FROM router_netif WHERE mac = %s LIMIT 1",(mac.lower(),))
findrouter = mysql.findone("SELECT router FROM router_netif WHERE mac = %s LIMIT 1",(mac2int(mac),))
router_update = parse_nodewatcher_xml(xml,statstime)
# cancel if banned mac found
@ -798,7 +798,7 @@ def parse_nodewatcher_xml(xml,statstime):
"tx": 0,
},
"ipv4_addr": evalxpath(netif,"ipv4_addr/text()"),
"mac": evalxpath(netif,"mac_addr/text()").lower(),
"mac": mac2int(evalxpath(netif,"mac_addr/text()")),
"wlan_channel": evalxpathint(netif,"wlan_channel/text()",None),
"wlan_type": evalxpath(netif,"wlan_type/text()",None),
"wlan_width": evalxpathint(netif,"wlan_width/text()",None),
@ -819,12 +819,12 @@ def parse_nodewatcher_xml(xml,statstime):
for originator in tree.xpath("/data/batman_adv_originators/*"):
visible_neighbours += 1
o_mac = evalxpath(originator,"originator/text()")
o_nexthop = evalxpath(originator,"nexthop/text()")
o_mac = mac2int(evalxpath(originator,"originator/text()"))
o_nexthop = mac2int(evalxpath(originator,"nexthop/text()"))
# mac is the mac of the neighbour w2/5mesh if
# (which might also be called wlan0-1)
o_out_if = evalxpath(originator,"outgoing_interface/text()")
if o_mac.upper() == o_nexthop.upper():
if o_mac == o_nexthop:
# skip vpn server
if o_out_if == CONFIG["vpn_netif"]:
continue
@ -833,7 +833,7 @@ def parse_nodewatcher_xml(xml,statstime):
elif o_out_if == CONFIG["vpn_netif_aux"]:
continue
neighbour = {
"mac": o_mac.lower(),
"mac": o_mac,
"netif": o_out_if,
"quality": evalxpathfloat(originator,"link_quality/text()"),
"type": "l2"
@ -849,10 +849,12 @@ def parse_nodewatcher_xml(xml,statstime):
for gw in tree.xpath("/data/batman_adv_gateway_list/*"):
gw_mac = evalxpath(gw,"gateway/text()")
if (gw_mac and len(gw_mac)>12): # Throw away headline
if len(gw_mac) > 17:
gw_mac = gw_mac[0:17]
gw = {
"mac": gw_mac.lower(),
"mac": mac2int(gw_mac),
"quality": evalxpath(gw,"link_quality/text()"),
"nexthop": evalxpath(gw,"nexthop/text()",None),
"nexthop": mac2int(evalxpath(gw,"nexthop/text()",None)),
"netif": evalxpath(gw,"outgoing_interface/text()",None),
"gw_class": evalxpath(gw,"gw_class/text()",None),
"selected": evalxpathbool(gw,"selected/text()")
@ -886,7 +888,7 @@ def get_l3_neighbours(tree):
if not iptmp:
iptmp = neighbour.text
neighbour = {
"mac": get_mac_from_v6_link_local(iptmp).lower(),
"mac": mac2int(get_mac_from_v6_link_local(iptmp)),
"netif": neighbour.xpath("outgoing_interface/text()")[0],
"quality": -1.0*evalxpathfloat(neighbour,"link_cost/text()",1),
"type": "l3"
@ -894,7 +896,6 @@ def get_l3_neighbours(tree):
l3_neighbours.append(neighbour)
return l3_neighbours
def get_mac_from_v6_link_local(v6_fe80):
fullip = ipaddress.ip_address(v6_fe80).exploded
first = '%02x' % (int(fullip[20:22], 16) ^ 2)

View File

@ -162,7 +162,7 @@ def router_models(mysql,selecthood=None,selectgw=None):
WHERE mac = %s
GROUP BY hardware
ORDER BY hardware
""",(selectgw,),"hardware")
""",(mac2int(selectgw),),"hardware")
else:
return mysql.fetchdict("""
SELECT hardware, COUNT(id) AS count, SUM(clients) AS clients
@ -188,7 +188,7 @@ def router_firmwares(mysql,selecthood=None,selectgw=None):
WHERE mac = %s
GROUP BY firmware
ORDER BY firmware
""",(selectgw,),"firmware","count")
""",(mac2int(selectgw),),"firmware","count")
else:
return mysql.fetchdict("""
SELECT firmware, COUNT(id) AS count
@ -342,7 +342,7 @@ def gws_admin(mysql,selectgw):
INNER JOIN gw_admin ON gw_netif.gw = gw_admin.gw
WHERE mac = %s
ORDER BY prio ASC
""",(selectgw,),"name")
""",(mac2int(selectgw),),"name")
return data
def record_global_stats(mysql):

View File

@ -6,7 +6,7 @@ from ffmap.maptools import *
from ffmap.mysqltools import FreifunkMySQL
from ffmap.stattools import record_global_stats, record_hood_stats
from ffmap.config import CONFIG
from ffmap.misc import writelog, writefulllog, neighbor_color
from ffmap.misc import *
from flask import Blueprint, request, make_response, redirect, url_for, jsonify, Response
from bson.json_util import dumps as bson2json
@ -121,7 +121,7 @@ def get_router_by_mac(mac):
INNER JOIN router_netif ON router.id = router_netif.router
WHERE mac = %s
GROUP BY mac, id
""",(mac.lower(),))
""",(mac2int(mac),))
mysql.close()
if len(res_routers) != 1:
return redirect(url_for("router_list", q="mac:%s" % mac))
@ -279,13 +279,13 @@ def wifianalhelper(router_data, headline):
if not router['mac']:
continue
if router["netif"] == 'br-mesh':
s += router["mac"] + "|Mesh_" + router['hostname'] + "\n"
s += int2mac(router["mac"]) + "|Mesh_" + router['hostname'] + "\n"
elif router["netif"] == 'w2ap':
s += router["mac"] + "|" + router['hostname'] + "\n"
s += int2mac(router["mac"]) + "|" + router['hostname'] + "\n"
elif router["netif"] == 'w5ap':
s += router["mac"] + "|W5_" + router['hostname'] + "\n"
s += int2mac(router["mac"]) + "|W5_" + router['hostname'] + "\n"
elif router["netif"] == 'w5mesh':
s += router["mac"] + "|W5Mesh_" + router['hostname'] + "\n"
s += int2mac(router["mac"]) + "|W5Mesh_" + router['hostname'] + "\n"
return Response(s,mimetype='text/plain')
@ -304,7 +304,7 @@ def dnslist():
s = ""
for router in router_data:
s += router["mac"].replace(":","") + "\t" + router["fd43"] + "\n"
s += int2shortmac(router["mac"]) + "\t" + router["fd43"] + "\n"
return Response(s,mimetype='text/plain')
@ -323,7 +323,7 @@ def dnsentries():
s = ""
for router in router_data:
s += router["mac"].replace(":","") + ".fff.community. 300 IN AAAA " + router["fd43"] + " ; " + router["hostname"] + "\n"
s += int2shortmac(router["mac"]) + ".fff.community. 300 IN AAAA " + router["fd43"] + " ; " + router["hostname"] + "\n"
return Response(s,mimetype='text/plain')
@ -367,18 +367,21 @@ def routers():
#elif netif['netif'] == 'br-mesh' and 'mac' in netif:
# mac = netif["mac"]
if not router['mac']:
continue
nodelist_data['nodes'].append(
{
'id': str(router['id']),
'name': router['hostname'],
'mac': router['mac'],
'mac': int2mac(router['mac']),
'hood': router['hood'],
'status': router['status'],
'user': router['nickname'],
'hardware': router['hardware'],
'firmware': router['firmware'],
'loadavg': router['sys_loadavg'],
'href': 'https://monitoring.freifunk-franken.de/mac/' + router['mac'],
'href': 'https://monitoring.freifunk-franken.de/mac/' + int2shortmac(router['mac']),
'clients': router['clients'],
'lastcontact': router['last_contact'].isoformat(),
'uplink': {
@ -454,7 +457,7 @@ def get_routers_by_nickname(nickname):
{
'name': router['hostname'],
'oid': str(router['id']),
'mac': router['mac'],
'mac': int2mac(router['mac']),
'ipv6_fe80_addr': router['fe80_addr']
}
)

View File

@ -13,7 +13,7 @@ from ffmap.routertools import delete_router, ban_router
from ffmap.gwtools import gw_name, gw_bat
from ffmap.web.helpers import *
from ffmap.config import CONFIG
from ffmap.misc import writelog, writefulllog, neighbor_color
from ffmap.misc import *
from flask import Flask, render_template, request, Response, redirect, url_for, flash, session
import bson
@ -79,7 +79,7 @@ def router_mac(mac):
INNER JOIN router_netif ON router.id = router_netif.router
WHERE mac = %s
GROUP BY mac, id
""",(mac.lower(),))
""",(mac2int(mac),))
mysql.close()
if len(res_routers) != 1:
return redirect(url_for("router_list", q="mac:%s" % mac))
@ -486,7 +486,8 @@ def global_hoodstatistics(selecthood):
@app.route('/gwstatistics/<selectgw>')
def global_gwstatistics(selectgw):
mysql = FreifunkMySQL()
stats = mysql.fetchall("SELECT * FROM stats_gw WHERE mac = %s",(selectgw,))
stats = mysql.fetchall("SELECT * FROM stats_gw WHERE mac = %s",(mac2int(selectgw),))
selectgw = shortmac2mac(selectgw)
return helper_statistics(mysql,stats,None,selectgw)
def helper_statistics(mysql,stats,selecthood,selectgw):
@ -494,10 +495,15 @@ def helper_statistics(mysql,stats,selecthood,selectgw):
hoods = stattools.hoods(mysql,selectgw)
gws = stattools.gws(mysql,selecthood)
if selectgw:
selectgwint = mac2int(selectgw)
else:
selectgwint = None
if selecthood and not selecthood in hoods:
mysql.close()
return "Hood not found"
if selectgw and not selectgw in gws:
if selectgw and not selectgwint in gws:
mysql.close()
return "Gateway not found"
@ -515,7 +521,7 @@ def helper_statistics(mysql,stats,selecthood,selectgw):
WHERE hardware <> 'Legacy' AND mac = %s
ORDER BY created DESC
LIMIT %s
""",(selectgw,numnew,))
""",(mac2int(selectgw),numnew,))
else:
if selecthood:
where = " AND hood = %s"
@ -546,6 +552,7 @@ def helper_statistics(mysql,stats,selecthood,selectgw):
return render_template("statistics.html",
selecthood = selecthood,
selectgw = selectgw,
selectgwint = selectgwint,
stats = stats,
clients = clients,
router_status = router_status,

View File

@ -9,6 +9,7 @@ import json
import datetime
import re
import hashlib
from ffmap.misc import int2mac, int2shortmac
sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + '/' + '../..'))
from ffmap.misc import *
@ -19,6 +20,14 @@ filters = Blueprint("filters", __name__)
def sumdict(d):
return sum(d.values())
@filters.app_template_filter('int2mac')
def int2macfilter(d):
return int2mac(d)
@filters.app_template_filter('int2shortmac')
def int2shortmacfilter(d):
return int2shortmac(d)
@filters.app_template_filter('utc2local')
def utc2local(dt):
return dt.astimezone(tz.tzlocal())
@ -115,7 +124,12 @@ def mac_to_ipv6_linklocal(mac):
# Remove the most common delimiters; dots, dashes, etc.
mac_bare = re.sub('[%s]+' % re.escape(' .:-'), '', mac)
mac_value = int(mac_bare, 16)
return macint_to_ipv6_linklocal(int(mac_bare, 16))
@filters.app_template_filter('macint2fe80')
def macint_to_ipv6_linklocal(mac_value):
if not mac_value:
return ''
# Split out the bytes that slot into the IPv6 address
# XOR the most significant byte with 0x02, inverting the

View File

@ -68,16 +68,16 @@ def parse_router_list_search_query(args):
k = key + ' = "" OR ' + key + " IS NULL"
elif key == 'mac':
j += " INNER JOIN ( SELECT router, mac FROM router_netif GROUP BY router, mac) AS j ON router.id = j.router "
k = "mac {} REGEXP %s".format(no)
t.append(value.lower())
k = "HEX(mac) {} REGEXP %s".format(no)
t.append(value.replace(':',''))
elif (key == 'gw'):
j += " INNER JOIN router_gw ON router.id = router_gw.router "
k = "router_gw.mac {} REGEXP %s".format(no)
t.append(value.lower())
k = "HEX(router_gw.mac) {} REGEXP %s".format(no)
t.append(value.replace(':',''))
elif (key == 'selected'):
j += " INNER JOIN router_gw ON router.id = router_gw.router "
k = "router_gw.mac {} REGEXP %s AND router_gw.selected = TRUE".format(no)
t.append(value.lower())
k = "HEX(router_gw.mac) {} REGEXP %s AND router_gw.selected = TRUE".format(no)
t.append(value.replace(':',''))
elif (key == 'bat'):
j += """ INNER JOIN router_gw ON router.id = router_gw.router
INNER JOIN (
@ -85,8 +85,8 @@ def parse_router_list_search_query(args):
INNER JOIN gw_netif AS n2 ON n1.mac = n2.vpnmac AND n1.gw = n2.gw
) ON router_gw.mac = n1.mac
"""
k = "n2.mac {} REGEXP %s".format(no)
t.append(value.lower())
k = "HEX(n2.mac) {} REGEXP %s".format(no)
t.append(value.replace(':',''))
elif (key == 'batselected'):
j += """ INNER JOIN router_gw ON router.id = router_gw.router
INNER JOIN (
@ -94,12 +94,12 @@ def parse_router_list_search_query(args):
INNER JOIN gw_netif AS n2 ON n1.mac = n2.vpnmac AND n1.gw = n2.gw
) ON router_gw.mac = n1.mac
"""
k = "n2.mac {} REGEXP %s AND router_gw.selected = TRUE".format(no)
t.append(value.lower())
k = "HEX(n2.mac) {} REGEXP %s AND router_gw.selected = TRUE".format(no)
t.append(value.replace(':',''))
elif (key == 'neighbor') or (key == 'neighbour'):
j += " INNER JOIN ( SELECT router, mac FROM router_neighbor GROUP BY router, mac) AS j ON router.id = j.router "
k = "mac {} REGEXP %s".format(no)
t.append(value.lower())
k = "HEX(mac) {} REGEXP %s".format(no)
t.append(value.replace(':',''))
elif (key == 'hardware') or (key == 'hood') or (key == 'nickname'):
k = key + " {} REGEXP %s".format(no)
t.append(value.replace("_","."))

View File

@ -102,7 +102,6 @@ function neighbour_graph(neigh_label) {
var meshstat = $("#meshstat");
var pdata = [];
var len, i;
var mac;
for (var j in neigh_stats) {
var dataset = neigh_stats[j];

View File

@ -147,7 +147,7 @@ map.on('click', function(pos) {
// skip unknown neighbours
if ('id' in neighbour) {
popup_html += "<tr style=\"background-color: "+neighbour.color+";\">";
popup_html += '<td><a href="'+url_router_info+neighbour.id+'" title="'+escapeHTML(neighbour.mac)+'" style="color:#000000">'+escapeHTML(neighbour.hostname)+'</a></td>';
popup_html += '<td><a href="'+url_router_info+neighbour.id+'" title="'+escapeHTML(neighbour.mac)+'" style="color:#000000">'+escapeHTML(neighbour.hostname)+'</a></td>'; // MACTODO
popup_html += "<td>"+neighbour.quality+"</td>";
popup_html += "<td>"+escapeHTML(neighbour.netif)+"</td>";
popup_html += "</tr>";

View File

@ -51,7 +51,7 @@
<div class="col-xs-12 col-sm-10">
<h2 style="margin-top: 10px;">{%- if router.gateway %}Gateway{%- else %}Router{%- endif %}: {{ router.hostname }}</h2>
{%- if mac %}
<h4 style="margin-top: 10px;margin-bottom: 20px">Perma-Link: <a href="{{ url_for('router_mac', mac=mac, _external=True) }}">{{ url_for('router_mac', mac=mac, _external=True) }}</a></h4>
<h4 style="margin-top: 10px;margin-bottom: 20px">Perma-Link: <a href="{{ url_for('router_mac', mac=mac|int2shortmac, _external=True) }}">{{ url_for('router_mac', mac=mac|int2shortmac, _external=True) }}</a></h4>
{%- endif %}
</div>
<div class="col-xs-12 col-sm-2 text-right" style="margin-top: 10px; margin-bottom: 10px;">
@ -240,7 +240,7 @@
<tr style="background-color: {{ neighbour.color }};">
<td>{%- if neighbour.hostname -%}<a href="{{ url_for('router_info', dbid=neighbour.id) }}" style="color:#000000">{{ neighbour.hostname }}</a>{%- else -%}---{%- endif -%}</td>
<td>{{ neighbour.mac }}</td>
<td>{{ neighbour.mac|int2mac }}</td>
<td>{{ neighbour.quality }}</td>
<td>{{ neighbour.netif }}</td>
</tr>
@ -272,14 +272,14 @@
<li class="list-group-item active" data-name="{{ netif.netif|replace('.', '')|replace('$', '') }}">
<div class="row">
<div class="col-xs-7 col-sm-7"><h4 class="list-group-item-heading">br-mesh: <span class="netifdesc">Bridge</span></h4></div>
<div class="col-xs-5 col-sm-5 text-right" style="text-transform: uppercase;"><h4 class="list-group-item-heading">{{ netif.mac }}</h4></div>
<div class="col-xs-5 col-sm-5 text-right" style="text-transform: uppercase;"><h4 class="list-group-item-heading">{{ netif.mac|int2mac }}</h4></div>
</div>
<div class="row">
<div class="col-xs-5 col-sm-5">
{%- if netif.ipv6_fe80_addr -%}
{{ netif.ipv6_fe80_addr }}
{%- else -%}
<em title="Calculated from MAC Address">{{ netif.mac|mac2fe80 }}</em>
<em title="Calculated from MAC Address">{{ netif.mac|macint2fe80 }}</em>
{%- endif -%}
{%- if netif.ipv4_addr -%}
<br />{{ netif.ipv4_addr }}
@ -301,7 +301,7 @@
<li class="list-group-item" data-name="{{ netif.netif|replace('.', '')|replace('$', '') }}">
<div class="row">
<div class="col-xs-7 col-sm-7"><h4 class="list-group-item-heading" style="{%- if netif.color -%}color:{{ netif.color }}{%- endif -%}">{{ netif.netif }}{%- if netif.description -%}: <span class="netifdesc">{{ netif.description }}</span>{%- endif %}</h4></div>
<div class="col-xs-5 col-sm-5 text-right" style="text-transform: uppercase;"><h4 class="list-group-item-heading">{{ netif.mac }}</h4></div>
<div class="col-xs-5 col-sm-5 text-right" style="text-transform: uppercase;"><h4 class="list-group-item-heading">{{ netif.mac|int2mac }}</h4></div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12" style="padding-bottom:6px;font-size:14px">
@ -324,7 +324,7 @@
{%- if netif.ipv6_fe80_addr -%}
{{ netif.ipv6_fe80_addr }}
{%- else -%}
<em title="Calculated from MAC Address">{{ netif.mac|mac2fe80 }}</em>
<em title="Calculated from MAC Address">{{ netif.mac|macint2fe80 }}</em>
{%- endif -%}
{%- if netif.ipv4_addr -%}
<br />{{ netif.ipv4_addr }}
@ -363,7 +363,7 @@
{%- else %}
<tr>
{%- endif %}
<td><a href="{{ url_for('router_list', q='selected:^%s$' % gw.mac) }}">{{ gw.label }}</a></td>
<td><a href="{{ url_for('router_list', q='selected:^%s$' % gw.mac|int2shortmac) }}">{{ gw.label }}</a></td>
<td>{{ gw.batX }}</td>
<td>{{ gw.quality }}</td>
<td>{{ gw.netif }}</td>
@ -424,7 +424,7 @@
var gw_stats = {{ gwstats|statbson2json|safe }};
var neighbours = [
{%- for neighbour in router.neighbours %}
{"name": "{{ neighbour.hostname or neighbour.mac }}", "mac": "{{ neighbour.mac }}", "netif": "{{ neighbour.netif }}"},
{"name": "{{ neighbour.hostname or neighbour.mac|int2mac }}", "mac": "{{ neighbour.mac }}", "netif": "{{ neighbour.netif }}"},
{%- endfor %}
];
var gws = [

View File

@ -163,11 +163,11 @@
<tbody>
{%- for mac, value in gws.items() %}
<tr>
<td class="firstrow" data-order="{{ value["sort"] }}"><p style="margin:0"><a href="{{ url_for('router_list', q='selected:^%s$' % mac) }}">{{ gws_info[mac]["label"] }}</a></p>
<td class="firstrow" data-order="{{ value["sort"] }}"><p style="margin:0"><a href="{{ url_for('router_list', q='selected:^%s$' % mac|int2shortmac) }}">{{ gws_info[mac]["label"] }}</a></p>
{%- if gws_info[mac]["gw"] %}
<p style="margin:0;font-size:12px">{{ mac }}
<p style="margin:0;font-size:12px">{{ mac|int2mac }}
{%- if gws_info[mac]["batmac"] %}
/ {{ gws_info[mac]["batmac"] }}
/ {{ gws_info[mac]["batmac"]|int2mac }}
{%- endif %}
</p>
{%- endif %}
@ -176,7 +176,7 @@
<td class="danger" data-order="{{ (value["selected"]["offline"] or 0) + (value["others"]["offline"] or 0) }}"><span style="font-weight:bold">{{ value["selected"]["offline"] or 0 }}</span> / {{ value["others"]["offline"] or 0 }}</td>
<td class="warning" data-order="{{ (value["selected"]["unknown"] or 0) + (value["others"]["unknown"] or 0) }}"><span style="font-weight:bold">{{ value["selected"]["unknown"] or 0 }}</span> / {{ value["others"]["unknown"] or 0 }}</td>
<td class="active" data-order="{{ (value["selected"]|sumdict if value["selected"] else 0) + (value["others"]|sumdict if value["others"] else 0) }}"><span style="font-weight:bold">{{ gws_sum[mac]["routers"] if gws_sum[mac] else 0 }}</span> / {{ value["others"]|sumdict if value["others"] else 0 }}</td>
<td class="stats"><a href="{{ url_for('global_gwstatistics', selectgw='%s' % mac) }}">Stats</a></td>
<td class="stats"><a href="{{ url_for('global_gwstatistics', selectgw='%s' % mac|int2shortmac) }}">Stats</a></td>
</tr>
{%- endfor %}
</tbody>
@ -190,21 +190,21 @@
<div class="panel-heading">Gateway-Details</div>
<div class="panel-body">
<table class="table table-condensed">
<tr><th>Gateway</th><td>{{ gws_info[selectgw]["gw"] }}</td></tr>
<tr><th>Interface</th><td>{{ gws_info[selectgw]["gwif"] }}</td></tr>
<tr><th>Gateway</th><td>{{ gws_info[selectgwint]["gw"] }}</td></tr>
<tr><th>Interface</th><td>{{ gws_info[selectgwint]["gwif"] }}</td></tr>
<tr><th>MAC address</th><td>{{ selectgw }}</td></tr>
<tr><th>BatX interface</th><td>{{ gws_info[selectgw]["batX"] }}</td></tr>
{%- if gws_info[selectgw]["ipv4"] %}
<tr><th>Internal IPv4</th><td>{{ gws_info[selectgw]["ipv4"] }}</td></tr>
<tr><th>BatX interface</th><td>{{ gws_info[selectgwint]["batX"] }}</td></tr>
{%- if gws_info[selectgwint]["ipv4"] %}
<tr><th>Internal IPv4</th><td>{{ gws_info[selectgwint]["ipv4"] }}</td></tr>
{%- endif %}
{%- if gws_info[selectgw]["ipv6"] %}
<tr><th>Internal IPv6</th><td>{{ gws_info[selectgw]["ipv6"] }}</td></tr>
{%- if gws_info[selectgwint]["ipv6"] %}
<tr><th>Internal IPv6</th><td>{{ gws_info[selectgwint]["ipv6"] }}</td></tr>
{%- endif %}
{%- if gws_info[selectgw]["dhcpstart"] %}
<tr><th>DHCP range</th><td>{{ gws_info[selectgw]["dhcpstart"] }} - {{ gws_info[selectgw]["dhcpend"] }}</td></tr>
{%- if gws_info[selectgwint]["dhcpstart"] %}
<tr><th>DHCP range</th><td>{{ gws_info[selectgwint]["dhcpstart"] }} - {{ gws_info[selectgwint]["dhcpend"] }}</td></tr>
{%- endif %}
{%- if gws_info[selectgw]["stats_page"] %}
<tr><th>Stats page</th><td>{{ gws_info[selectgw]["stats_page"] }}</td></tr>
{%- if gws_info[selectgwint]["stats_page"] %}
<tr><th>Stats page</th><td>{{ gws_info[selectgwint]["stats_page"] }}</td></tr>
{%- endif %}
{%- for a in gws_admin %}
<tr><th>Admin</th><td>{{ a }}</td></tr>