Merge pull request #78 from logicog/nic_demagic

MIB Counter fixes and Detailed Display
This commit is contained in:
René van Dorst
2026-01-15 18:45:38 +00:00
committed by GitHub
10 changed files with 297 additions and 54 deletions
+29 -1
View File
@@ -3,14 +3,42 @@
<script src="/main.js"></script> <script src="/main.js"></script>
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
<title>FreeSwitchOS Port Statistics</title> <title>FreeSwitchOS Port Statistics</title>
<style>
.popup {
display: none;
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0, 0, 0, 0.5);
justify-content: center;
align-items: center;
}
.popup-content {
background: #fff;
padding: 20px;
border-radius: 5px;
text-align: center;
height: 80%
}
.popup .popup-content {
overflow-y: scroll;
}
</style>
</head> </head>
<body> <body>
<nav id="sidebar"></nav> <nav id="sidebar"></nav>
<div style="margin-left:16%;padding:1px 16px;height:1000px;"> <div style="margin-left:16%;padding:1px 16px;height:1000px;">
<div id="ports"></div> <div id="ports"></div>
<div id="popup" class="popup">
<div class="popup-content">
<h2>Detailed Port Statistics</h2>
<div id="popup_text"></div>
<button id="closePopup" class="action">Close</button>
</div>
</div>
<h1>Port Statistics</h1> <h1>Port Statistics</h1>
<table id="statstable"> <table id="statstable">
<tr> <th>Port</th> <th>link</th> <th>TX Good</th> <th>TX Bad</th> <th>RX Good</th> <th>RX Bad</th> </tr> <tr> <th>Port</th> <th>link</th> <th>TX Good</th> <th>TX Bad</th> <th>RX Good</th> <th>RX Bad</th> <th> All Counters </th></tr>
<script src="/stat.js"></script> <script src="/stat.js"></script>
</table> </table>
</div> </div>
+170
View File
@@ -1,3 +1,160 @@
const mib_counters = [
"Interface in Octets", 8,
"", 0,
"Interface out Octets", 8,
"", 0,
"Interface in Unicast Pkts", 8,
"", 0,
"Interface in Multicast Pkts", 8,
"", 0,
"Interface in Broadcast Pkts", 8,
"", 0,
"Interface out Unicast Pkts", 8, // 10
"", 0,
"Interface out Multicast Pkts", 8,
"", 0,
"Interface out Broadcast Pkts", 8,
"", 0,
"Interface out discards", 4,
"802.1d Tp Port in discards", 4,
"802.3 Single collision frames", 4,
"802.3 Multi collision frames", 4,
"802.3 Deferred transmissions", 4, // 20
"802.3 Late collisions", 4,
"802.3 Excessive collisions", 4,
"802.3 Symbol errors", 4,
"802.3 Control in unknown opcodes", 4,
"802.3 In Pause frames", 4,
"802.3 Out Pause frames", 4,
"Ether drop events", 4,
"TX Ether Broadcast Pkts", 4,
"TX Ether Multicast Pkts", 4,
"TX Ether CRC Align errors", 4, // 30
"RX Ether CRC Align errors", 4,
"TX Ether Undersized Pkts", 4,
"RX Ether Undersized Pkts", 4,
"TX Ether Oversized Pkts", 4,
"RX Ether Oversized Pkts", 4,
"TX Ether Fragments", 4,
"RX Ether fragments", 4,
"TX Ether Jabbers", 4,
"RX Ether Jabbers", 4,
"TX Ether Collisions", 4, // 40
"TX Ether Pkts 640 Octets", 4,
"RX Ether Pkts 640 Octets", 4,
"TX Ether 65-127 Octets", 4,
"RX Ether 65-127 Octets", 4,
"TX Ether Pkts 128-255 Octets", 4,
"RX Ether Pkts 128-255 Octets", 4,
"TX Ether Pkts 256-511 Octets", 4,
"RX Ether Pkts 256-511 Octets", 4,
"TX Ether Pkts 512-1023 Octets", 4,
"RX Ether Pkts 512-1023 Octets", 4, // 50
"TX Ether Pkts 1024-1518 Octets", 4,
"RX Ether Pkts 1024-1518 Octets", 4,
"", 4,
"RX Ether Undersized Drop Pkts", 4, // 54
"TX Ether Pkts >1518 Octets", 4,
"RX Ether Pkts >1518 Octets", 4,
"TX Ether Pkts too large", 4,
"RX Ether Pkts too large", 4,
"TX Ether Flexible Octets Set 1", 4,
"RX Ether Flexible Octets Set 1", 4,// 60
"TX Ether Flexible Octets CRC Set 1", 4,
"RX Ether Flexible Octets CRC Set 1", 4,
"TX Ether Flexible Octets Set 0", 4,
"RX Ether Flexible Octets Set 0", 4,
"TX Ether Flexible Octets CRC Set 0", 4,
"RX Ether Flexible Octets CRC Set 0", 4,
"Lenth Field Errors", 4,
"False Carriers", 4,
"Undersized Octets", 4,
"Framing Errors", 4, // 70
"", 4,
"RX MAC Discards", 4, // 72
"RX MAC IPG Short Drop", 4,
"", 4,
"802.1d TP Learned Entry Discards", 4, // 75
"Egress Queue 7 Dropped Pkts", 4,
"Egress Queue 6 Dropped Pkts", 4,
"Egress Queue 5 Dropped Pkts", 4,
"Egress Queue 4 Dropped Pkts", 4,
"Egress Queue 3 Dropped Pkts", 4, // 80
"Egress Queue 2 Dropped Pkts", 4,
"Egress Queue 1 Dropped Pkts", 4,
"Egress Queue 0 Dropped Pkts", 4,
"Egress Queue 7 Out Pkts", 4,
"Egress Queue 6 Out Pkts", 4,
"Egress Queue 5 Out Pkts", 4,
"Egress Queue 4 Out Pkts", 4,
"Egress Queue 3 Out Pkts", 4,
"Egress Queue 2 Out Pkts", 4,
"Egress Queue 1 Out Pkts", 4, // 90
"Egress Queue 0 Out Pkts", 4,
"TX Good Counter", 8,
"", 0,
"RX Good Counter", 8,
"", 0,
"RX Error Counter", 4,
"TX Error Counter", 4,
"TX Good Counter PHY", 8,
"", 0,
"RX Good Counter PHY", 8, // 100
"", 0,
"RX Error Counter PHY", 4,
"TX Error Counter PHY", 4
];
function getCounters(port) {
var xhttp = new XMLHttpRequest();
const popup = document.getElementById('popup');
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
const s = JSON.parse(xhttp.responseText);
console.log("Counters: ", JSON.stringify(s));
const ptext = document.getElementById('popup_text');
var t = "<table style='width:100%'> <tr> <th>Counter</th> <th>Value</th> <th>Counter</th> <th>Value</th></tr> <tr>";
console.log("Counter 0: ", BigInt(s[0]).toString(), " length: ", s.length);
var c = 0;
for (i = 0; i < mib_counters.length; i += 4) {
console.log(i, " ", mib_counters[i], ": ", mib_counters[i+1]);
if (mib_counters[i] == "" && mib_counters[i + 1] == 8) {
console.log("c " + i + ": continue");
continue;
}
var count = BigInt(s[i/4]);
if (mib_counters[i+1] == 8) {
t += "<td>" + mib_counters[i] + "</td><td>" + count.toString() + "</td>";
c += 1;
} else if (mib_counters[i+1] == 4) {
if (mib_counters[i] != "") {
t += "<td>" + mib_counters[i] + "</td><td>" + (count >> 32n).toString() + "</td>";
c += 1;
}
if (c == 2) {
t += "</tr> <tr>";
c = 0;
}
if (mib_counters[i+2] != "") {
t += "<td>" + mib_counters[i+2] + "</td><td>" + (count & 4294967295n).toString() + "</td>";
c += 1;
}
}
if (c == 2) {
t += "</tr> <tr>";
c = 0;
}
}
ptext.innerHTML = t + "</tr></table>";
popup.style.display = 'flex';
}
};
xhttp.open("GET", "/counters.json?port=" + port, true);
xhttp.timeout = 1500; xhttp.send();
}
function fillStats() { function fillStats() {
var tbl = document.getElementById('statstable'); var tbl = document.getElementById('statstable');
if (!numPorts) if (!numPorts)
@@ -21,8 +178,21 @@ function fillStats() {
td = tr.insertCell();td.appendChild(document.createTextNode(`${txB[i]} pkts`)); td = tr.insertCell();td.appendChild(document.createTextNode(`${txB[i]} pkts`));
td = tr.insertCell();td.appendChild(document.createTextNode(`${rxG[i]} pkts`)); td = tr.insertCell();td.appendChild(document.createTextNode(`${rxG[i]} pkts`));
td = tr.insertCell();td.appendChild(document.createTextNode(`${rxB[i]} pkts`)); td = tr.insertCell();td.appendChild(document.createTextNode(`${rxB[i]} pkts`));
var button = '<button type="button" style="margin: 0 0 0 24px" onclick="getCounters(' + i + ');">Show</button>';
td = tr.insertCell(); td.innerHTML = button;
} }
} }
} }
const stat = setInterval(fillStats, 1000); const stat = setInterval(fillStats, 1000);
const popup = document.getElementById('popup');
const closePopup = document.getElementById('closePopup');
closePopup.addEventListener('click', () => {
popup.style.display = 'none';
});
window.addEventListener('click', (event) => {
if (event.target === popup) {
popup.style.display = 'none';
}
});
+1 -1
View File
@@ -570,7 +570,7 @@ void httpd_appcall(void)
parse_short(q + 15); parse_short(q + 15);
send_vlan(short_parsed); send_vlan(short_parsed);
} else if (is_word(q, "/counters.json")) { } else if (is_word(q, "/counters.json")) {
send_counters(q[19]-'0'); send_counters(q[20]-'0');
} else if (is_word(q, "/eee.json")) { } else if (is_word(q, "/eee.json")) {
send_eee(); send_eee();
} else if (is_word(q, "/mirror.json")) { } else if (is_word(q, "/mirror.json")) {
+19 -11
View File
@@ -143,6 +143,16 @@ void reg_to_html(register uint16_t reg)
} }
void reg_to_html_long(register uint16_t reg)
{
reg_read_m(reg);
byte_to_html(sfr_data[0]);
byte_to_html(sfr_data[1]);
byte_to_html(sfr_data[2]);
byte_to_html(sfr_data[3]);
}
void send_sfp_info(uint8_t sfp) void send_sfp_info(uint8_t sfp)
{ {
// This loops over the Vendor-name, Vendor OUI, Vendor PN and Vendor rev ASCII fields // This loops over the Vendor-name, Vendor OUI, Vendor PN and Vendor rev ASCII fields
@@ -257,21 +267,19 @@ void send_counters(char port)
dbg_string("send_counters called: "); dbg_byte(port); dbg_char('\n'); dbg_string("send_counters called: "); dbg_byte(port); dbg_char('\n');
slen = strtox(outbuf, HTTP_RESPONCE_JSON); slen = strtox(outbuf, HTTP_RESPONCE_JSON);
dbg_string("sending counters\n"); dbg_string("sending counters\n");
dbg_byte(port);
port--;
uint8_t i = machine.phys_to_log_port[port]; uint8_t i = machine.phys_to_log_port[port];
slen += strtox(outbuf + slen, "{\"portNum\":"); slen += strtox(outbuf + slen, "[");
itoa_html(i + 1); for (uint8_t counter = 0; counter < 0x37; counter++) {
for (uint8_t j = 0; j < 0x3f; j++) { STAT_GET(counter, i);
STAT_GET(j, i); slen += strtox(outbuf + slen, "\"0x");
slen += strtox(outbuf + slen, ",\"cnt_");
itoa_html(j);
slen += strtox(outbuf + slen, "\":\"0x");
reg_to_html(RTL837X_STAT_V_HIGH); reg_to_html(RTL837X_STAT_V_HIGH);
reg_to_html(RTL837X_STAT_V_LOW); reg_to_html_long(RTL837X_STAT_V_LOW);
char_to_html('\"'); char_to_html('\"');
if (counter != 0x36)
char_to_html(',');
} }
char_to_html('}'); char_to_html(']');
} }
+15 -11
View File
@@ -36,8 +36,21 @@
// the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated, // the RTL_FRAME_TAG_ID is used as part of an 8-byte tag. When VLAN is activated,
// the VLAN tag is inserted after the RTL tag // the VLAN tag is inserted after the RTL tag
// See here for the RTL tag: https://github.com/torvalds/linux/commit/1521d5adfc2b557e15f97283c8b7ad688c3ebc40 // See here for the RTL tag: https://github.com/torvalds/linux/commit/1521d5adfc2b557e15f97283c8b7ad688c3ebc40
#define RTL_TAG_SIZE 8 struct rtl_tag {
#define VLAN_TAG_SIZE 4 uint16_t tag; // This is 0x8899 for the RTL837X
uint8_t version; // Version is 4
uint8_t reason;
uint16_t flags;
uint16_t pmask; // A bit mask for a TX pkt, 4-bit port-number for RX
};
struct vlan_tag {
uint16_t svlan; // Service VLAN
uint16_t vlan;
};
#define RTL_TAG_SIZE (sizeof (struct rtl_tag))
#define VLAN_TAG_SIZE (sizeof (struct vlan_tag))
#define RTL_FRAME_TAG_ID 0x8899 #define RTL_FRAME_TAG_ID 0x8899
// For RX and TX, an 8 byte header describing the frame to be moved to the Asic // For RX and TX, an 8 byte header describing the frame to be moved to the Asic
@@ -70,15 +83,6 @@ struct flash_region_t {
extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2]; extern __xdata uint8_t uip_buf[UIP_CONF_BUFFER_SIZE+2];
// 8899 04 0000 20 0004
struct rtl_tag {
uint16_t tag;
uint8_t version;
uint8_t reason;
uint16_t flags;
uint16_t pmask; // A bit mask for a TX pkt, 4-bit port-number for RX
};
// Headers for calls in the common code area (HOME/BANK0) // Headers for calls in the common code area (HOME/BANK0)
void print_string(__code char *p); void print_string(__code char *p);
void print_long(__xdata uint32_t a); void print_long(__xdata uint32_t a);
+8 -8
View File
@@ -400,17 +400,17 @@ void port_stats_print(void) __banked
print_string("Up\t"); print_string("Up\t");
break; break;
} }
STAT_GET(0x2f, i); STAT_GET(STAT_COUNTER_TX_PKTS, i);
print_reg(RTL837X_STAT_V_LOW); write_char('\t'); print_reg(RTL837X_STAT_V_LOW); write_char('\t');
STAT_GET(0x30, i); STAT_GET(STAT_COUNTER_ERR_PKTS, i);
print_reg(RTL837X_STAT_V_LOW); write_char('\t');
STAT_GET(STAT_COUNTER_RX_PKTS, i);
print_reg(RTL837X_STAT_V_LOW); write_char('\t');
STAT_GET(STAT_COUNTER_ERR_PKTS, i);
print_reg(RTL837X_STAT_V_HIGH); write_char('\t'); print_reg(RTL837X_STAT_V_HIGH); write_char('\t');
STAT_GET(0x2e, i);
print_reg(RTL837X_STAT_V_LOW); write_char('\t');
STAT_GET(0x30, i);
print_reg(RTL837X_STAT_V_LOW); write_char('\t');
print_string("\n"); print_string("\n");
} }
} }
+3 -3
View File
@@ -3,9 +3,9 @@
#include <stdint.h> #include <stdint.h>
#define STAT_COUNTER_TX_PKTS 0x2e #define STAT_COUNTER_TX_PKTS 46
#define STAT_COUNTER_RX_PKTS 0x2f #define STAT_COUNTER_RX_PKTS 47
#define STAT_COUNTER_ERR_PKTS 0x30 #define STAT_COUNTER_ERR_PKTS 48
#define STAT_GET(cnt, port) \ #define STAT_GET(cnt, port) \
REG_WRITE(RTL837X_STAT_GET, 0x00, 0x00, cnt >> 3, (cnt << 5) | (port << 1) | 1); \ REG_WRITE(RTL837X_STAT_GET, 0x00, 0x00, cnt >> 3, (cnt << 5) | (port << 1) | 1); \
+6 -3
View File
@@ -93,11 +93,14 @@
*/ */
#define RTL837X_REG_NIC_BUFFSIZE_TX 0x7844 #define RTL837X_REG_NIC_BUFFSIZE_TX 0x7844
#define RTL837X_REG_NIC_RXBUFF_RX 0x7848 #define RTL837X_REG_NIC_RXBUFF_RX 0x7848
#define RTL837X_REG_NIC_RXCMD 0x784c
#define RTL837X_REG_NIC_TXCMD 0x7850
#define RTL837X_REG_RX_CTRL 0x785c #define RTL837X_REG_RX_CTRL 0x785c
#define RTL837X_REG_TX_CTRL 0x7860 #define RTL837X_REG_TX_CTRL 0x7860
#define RTL837X_REG_RX_AVAIL 0x7874 #define RTL837X_REG_NIC_RX_BUFF_DATA 0x7874
#define RTL837X_REG_RX_RINGPTR 0x787c #define RTL837X_REG_CPU_RX_CURR_PKT 0x787c
#define RTL837X_REG_RX_DONE 0x784c #define RTL837X_REG_NIC_TX_CURR_PKT 0x7884
#define RTL837X_REG_CPU_TX_CURR_PKT 0x7890
#define RTL837X_REG_CPU_TAG 0x6720 #define RTL837X_REG_CPU_TAG 0x6720
#define RTL837X_REG_CPU_TAG_AWARE_PMASK 0x603C #define RTL837X_REG_CPU_TAG_AWARE_PMASK 0x603C
#define RTL837X_REG_MAC_FORCE_MODE 0x6344 #define RTL837X_REG_MAC_FORCE_MODE 0x6344
+12 -15
View File
@@ -819,7 +819,7 @@ void tcpip_output(void)
uip_buf[VLAN_TAG_SIZE + 2] = uip_buf[VLAN_TAG_SIZE + 3] = 0; uip_buf[VLAN_TAG_SIZE + 2] = uip_buf[VLAN_TAG_SIZE + 3] = 0;
uip_buf[VLAN_TAG_SIZE + 6] = uip_buf[VLAN_TAG_SIZE + 7] = 0; uip_buf[VLAN_TAG_SIZE + 6] = uip_buf[VLAN_TAG_SIZE + 7] = 0;
reg_read_m(0x7890); reg_read_m(RTL837X_REG_CPU_TX_CURR_PKT);
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8; uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
ring_ptr |= sfr_data[3]; ring_ptr |= sfr_data[3];
@@ -835,20 +835,20 @@ void tcpip_output(void)
// Move data over from xmem buffer to ASIC side using DMA // Move data over from xmem buffer to ASIC side using DMA
nic_tx_packet(ring_ptr); nic_tx_packet(ring_ptr);
reg_read_m(0x7884); // actual bytes sent, for now we assume everything worked // New position of the ring-pointer on the NIC-side indicates number of bytes transmitted
reg_read_m(RTL837X_REG_NIC_TX_CURR_PKT);
// Do actual TX of data on ASIC side // Do actual TX of data on ASIC side
sfr_data[0] = sfr_data[1] = sfr_data[2] = 0; REG_SET(RTL837X_REG_NIC_TXCMD, 1);
sfr_data[3] = 0x1;
reg_write_m(0x7850);
} }
void handle_rx(void) void handle_rx(void)
{ {
reg_read_m(RTL837X_REG_RX_AVAIL); // Check the amount of data available on the NIC/ASIC side
reg_read_m(RTL837X_REG_NIC_RX_BUFF_DATA);
if (sfr_data[2] != 0 || sfr_data[3] != 0) { if (sfr_data[2] != 0 || sfr_data[3] != 0) {
reg_read_m(RTL837X_REG_RX_RINGPTR); reg_read_m(RTL837X_REG_CPU_RX_CURR_PKT);
uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8; uint16_t ring_ptr = ((uint16_t)sfr_data[2]) << 8;
ring_ptr |= sfr_data[3]; ring_ptr |= sfr_data[3];
ring_ptr <<= 3; ring_ptr <<= 3;
@@ -872,16 +872,13 @@ void handle_rx(void)
write_char(' '); write_char(' ');
} }
#endif #endif
sfr_data[0] = sfr_data[1] = sfr_data[2] = 0; REG_SET(RTL837X_REG_NIC_RXCMD, 1);
sfr_data[3] = 0x1;
reg_write_m(RTL837X_REG_RX_DONE);
uip_len = (((uint16_t)rx_headers[5]) << 8) | rx_headers[4]; uip_len = (((uint16_t)rx_headers[5]) << 8) | rx_headers[4];
// write_char('>'); print_byte(uip_buf[ETHERTYPE_OFFSET]); write_char('<');
// write_char('>'); print_byte(uip_buf[ETHERTYPE_OFFSET + 1]); write_char('<'); // Retrieve VLAN from VLAN-tag
// Check for ARP packet rx_packet_vlan = uip_buf[2 * sizeof (struct uip_eth_addr) + RTL_TAG_SIZE + 2] & 0xf;
rx_packet_vlan = uip_buf[12 + RTL_TAG_SIZE + 2] & 0xf;
rx_packet_vlan <<= 8; rx_packet_vlan <<= 8;
rx_packet_vlan |= uip_buf[12 + RTL_TAG_SIZE + 3]; rx_packet_vlan |= uip_buf[2 * sizeof (struct uip_eth_addr) + RTL_TAG_SIZE + 3];
#ifdef RXTXDBG #ifdef RXTXDBG
print_string(" RX-VLAN: "); print_short(rx_packet_vlan); write_char('\n'); print_string(" RX-VLAN: "); print_short(rx_packet_vlan); write_char('\n');
print_string(" RX dst: "); print_byte(uip_buf[0]); print_byte(uip_buf[1]); print_byte(uip_buf[2]); print_string(" RX dst: "); print_byte(uip_buf[0]); print_byte(uip_buf[1]); print_byte(uip_buf[2]);
+34 -1
View File
@@ -18,6 +18,8 @@
#define PORTS 9 #define PORTS 9
#define NSFP 1 #define NSFP 1
#define N_COUNTERS 52
#if PORTS == 9 #if PORTS == 9
const uint8_t physToLogPort[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; const uint8_t physToLogPort[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8};
#else #else
@@ -28,7 +30,7 @@ time_t last_called;
time_t last_session_use; time_t last_session_use;
uint64_t txG[PORTS], txB[PORTS], rxG[PORTS], rxB[PORTS]; uint64_t txG[PORTS], txB[PORTS], rxG[PORTS], rxB[PORTS];
char txG_buff[20], txB_buff[20], rxG_buff[20], rxB_buff[20]; char txG_buff[20], txB_buff[20], rxG_buff[20], rxB_buff[20], counter_buf[20], counter_name[20];
char sfp_temp[8], sfp_vcc[8], sfp_txbias[8], sfp_txpower[8], sfp_rxpower[8], sfp_laser[8], sfp_options[6]; char sfp_temp[8], sfp_vcc[8], sfp_txbias[8], sfp_txpower[8], sfp_rxpower[8], sfp_laser[8], sfp_options[6];
char num_buff[20]; char num_buff[20];
char upload_buffer[4194304]; // 4MB char upload_buffer[4194304]; // 4MB
@@ -199,6 +201,29 @@ void send_status(int s)
} }
void send_counters(int s, int port)
{
struct json_object *v, *counters;
const char *jstring;
char *header = "HTTP/1.1 200 OK\r\n"
"Cache-Control: no-cache\r\n"
"Content-Type: application/json; charset=UTF-8\r\n\r\n";
printf("Sending counters\n");
counters = json_object_new_array_ext(N_COUNTERS);
for (int i = 0; i < N_COUNTERS; i++) {
v = json_object_new_object();
sprintf(counter_buf, "0x%016lx", 0x1234UL + i);
json_object_array_add(counters, json_object_new_string(counter_buf));
}
write(s, header, strlen(header));
jstring = json_object_to_json_string_ext(counters, JSON_C_TO_STRING_PLAIN);
write(s, jstring, strlen(jstring));
json_object_put(counters);
}
void send_eee(int s) void send_eee(int s)
{ {
struct json_object *ports, *v; struct json_object *ports, *v;
@@ -547,6 +572,14 @@ void launch(struct Server *server)
else else
send_config(new_socket); send_config(new_socket);
goto done; goto done;
} else if (!strncmp(&buffer[4], "/counters.json?port=", 20)) {
int port = atoi(&buffer[24]);
printf("Counters request for %d\n", port);
if (!authenticated)
send_unauthorized(new_socket);
else
send_counters(new_socket, port);
goto done;
} }
if (!authenticated && !(!strncmp(&buffer[4], "/login.html", 11) || !strncmp(&buffer[4], "/style.css", 10))) { if (!authenticated && !(!strncmp(&buffer[4], "/login.html", 11) || !strncmp(&buffer[4], "/style.css", 10))) {
send_to_login(new_socket); send_to_login(new_socket);