Read now works, and terraform directory contains example code

This commit is contained in:
Joachim Friberg committed 2026-08-25 18:58:03 +02:00
1 parent ef498e4a72
commit a6f1019175
43 files changed
+4341 -38

No files matched your search

@@ -0,0 +1,160 @@
// Package client is a Go port of the reference Python implementation's
// switch_client.py (see ~/code/experiments/hpe/switch_client.py).
package client
import (
"fmt"
"io"
"net/http"
"net/http/cookiejar"
"net/url"
"regexp"
"strings"
)
type Client struct {
BaseURL string
httpClient *http.Client
password string
}
func NewClient(host string, https bool, password string) (*Client, error) {
scheme := "http"
if https {
scheme = "https"
}
jar, err := cookiejar.New(nil)
if err != nil {
return nil, fmt.Errorf("creating cookie jar: %w", err)
}
return &Client{
BaseURL: fmt.Sprintf("%s://%s", scheme, host),
httpClient: &http.Client{Jar: jar},
password: password,
}, nil
}
func (c *Client) resolveURL(path string) string {
if strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://") {
return path
}
if strings.HasPrefix(path, "/") {
return c.BaseURL + path
}
return c.BaseURL + "/" + path
}
// Login POSTs to /hp_login.html and establishes the session cookie.
//
// A bare POST occasionally comes back without setting SID (the switch seems
// to want a session cookie already present, even an empty one, before it
// will issue a real one) -- a GET first makes login reliable.
//
// Unlike the Python version, there's no on-disk session cache here: this
// provider process lives for the whole plan/apply run, so Configure() logs
// in once and every resource/data source reuses the same *Client.
func (c *Client) Login() error {
if _, err := c.httpClient.Get(c.resolveURL("/")); err != nil {
return fmt.Errorf("priming session: %w", err)
}
form := url.Values{
"pwd": {c.password},
"login": {"Login"},
"err_flag": {""},
"err_msg": {""},
}
resp, err := c.httpClient.PostForm(c.resolveURL("/hp_login.html"), form)
if err != nil {
return fmt.Errorf("login request: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("reading login response: %w", err)
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("login request returned status %d", resp.StatusCode)
}
if strings.Contains(strings.ToLower(string(body)), "<title>login</title>") {
snippet := string(body)
if len(snippet) > 500 {
snippet = snippet[:500]
}
return fmt.Errorf("login failed, response still looks like the login page: %q", snippet)
}
return nil
}
// Fetch GETs BaseURL+path (path may be relative or absolute) and returns the body.
func (c *Client) Fetch(path string) (string, error) {
resp, err := c.httpClient.Get(c.resolveURL(path))
if err != nil {
return "", fmt.Errorf("fetching %s: %w", path, err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("reading response for %s: %w", path, err)
}
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("fetching %s returned status %d", path, resp.StatusCode)
}
return string(body), nil
}
var errFlagRejectedRe = regexp.MustCompile(`(?i)name="err_flag"[^>]*value="1"`)
var errMsgRe = regexp.MustCompile(`(?i)name="err_msg"[^>]*value="([^"]*)"`)
// SubmitForm POSTs fields to path, merged with the firmware's standard
// bookkeeping fields (submit_flag, submit_target, err_flag, err_msg,
// clazz_information), and returns the response body.
//
// Returns an error if the response's err_flag comes back "1" -- the
// firmware's own validation-failure signal. NOTE: most value validation in
// this firmware happens client-side in JS, not on the server -- an invalid
// enum value, for example, is just silently ignored (state left unchanged)
// rather than reported via err_flag. So this check catches *some* rejected
// writes, but a caller that needs certainty should read the value back
// afterwards and compare, rather than trusting the absence of an error.
func (c *Client) SubmitForm(path string, fields map[string]string) (string, error) {
target := strings.TrimPrefix(path, "/")
form := url.Values{
// 8 == xui_operation_submit (per the firmware's own _xe_jsvars.js);
// 1 is xui_operation_reload and silently applies nothing.
"submit_flag": {"8"},
"submit_target": {target},
"err_flag": {"0"},
"err_msg": {""},
"clazz_information": {target},
}
for k, v := range fields {
form.Set(k, v)
}
resp, err := c.httpClient.PostForm(c.resolveURL(path), form)
if err != nil {
return "", fmt.Errorf("submitting form to %s: %w", path, err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("reading response for %s: %w", path, err)
}
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("submitting form to %s returned status %d", path, resp.StatusCode)
}
bodyStr := string(body)
if errFlagRejectedRe.MatchString(bodyStr) {
msg := "unknown error"
if m := errMsgRe.FindStringSubmatch(bodyStr); m != nil {
msg = m[1]
}
return "", fmt.Errorf("switch rejected write to %q: %s", path, msg)
}
return bodyStr, nil
}
@@ -0,0 +1,67 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- (C) Copyright Broadcom Corporation 2000-2020 : This file is auto-generated by XE - DON'T EDIT -->
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<TITLE>
HP ProCurve Forwarding Database Search
</TITLE>
<link href="/50021801/css/style1.css" rel="stylesheet" type="text/css" id="fastpath">
<script type="text/javascript" src="/50021801/scripts/xui_common.js"></script>
<script type="text/javascript" src="/50021801/scripts/globalStyleJS.js"></script>
<script type="text/javascript" src="/50021801/scripts/globalStyleJS.js"></script>
<script type="text/javascript" >
xuiIncludeCommonJSFiles("/50021801/scripts/");
xuiIncludeJSFile("/50021801/scripts/_xe_FDBSearch.js");
</script>
</HEAD>
<BODY onload="formLoad();" CLASS=page>
<FORM method=post ACTION="/FDBSearch.html">
<DIV ID="topdiv">
<script type="text/javascript" >
</script>
<script type="text/javascript" >
</script>
<DIV id=scalar DIV_XID = 1><TABLE ID=1><CAPTION>MAC Table</CAPTION>
<TR id=1_3 class=def>
<TD class=defleft id=1_3_1>Maximum Entries Supported</TD>
<TD class=defright id=1_3_1><INPUT xid=1_3_1 TYPE=hidden NAME=v_1_3_1 VALUE="8192"></TD>
</TR>
<TR id=1_2 class=def>
<TD class=defleft id=1_2_1>Current Entries</TD>
<TD class=defright id=1_2_1><INPUT xid=1_2_1 TYPE=hidden NAME=v_1_2_1 VALUE="2"></TD>
</TR>
</TABLE></DIV><br>
<DIV id=summary NORENDER DIV_XID = 1_1><TABLE ID=1_1><CAPTION></CAPTION>
<TH id=1_1_1 style="display:none">MAC Address</TH>
<TH id=1_1_5>MAC Address</TH>
<TH id=1_1_4>VLAN</TH>
<TH id=1_1_2>Source Port</TH>
<TH id=1_1_3>MAC Type</TH>
<tr><td CLASS="tabledata0" style="display: none;">00:01:4C:EA:41:63:04:1B</td><td CLASS="tabledata0">4C:EA:41:63:04:1B</td><td CLASS="tabledata0">1</td><td CLASS="tabledata0">5</td><td CLASS="tabledata0">Learned</td></tr>
<tr><td CLASS="tabledata1" style="display: none;">00:01:B4:99:BA:DA:3A:20</td><td CLASS="tabledata1">B4:99:BA:DA:3A:20</td><td CLASS="tabledata1">1</td><td CLASS="tabledata1">CPU</td><td CLASS="tabledata1">Management</td></tr>
</TABLE></DIV><br>
<script type="text/javascript" >
</script>
<!-- redirection elements -->
<INPUT TYPE="hidden" NAME="submit_flag" XC=hidden VALUE="0">
<INPUT TYPE="hidden" NAME="submit_target" XC=hidden VALUE="FDBSearch.html">
<INPUT TYPE="hidden" NAME="err_flag" XC=hidden SIZE="16" MAXLENGTH="15" VALUE="0">
<INPUT TYPE="hidden" NAME="err_msg" XC=hidden SIZE="80" MAXLENGTH="79" VALUE="">
<INPUT TYPE="hidden" NAME="clazz_information" XC=hidden VALUE="FDBSearch.html">
<center>
<DIV ID="buttons" style="visibility:visible;">
<TABLE><TR align=center>
</TR></TABLE>
</DIV>
</center>
</DIV>
</FORM>
</BODY>
</HTML>
@@ -0,0 +1,434 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- (C) Copyright Broadcom Corporation 2000-2020 : This file is auto-generated by XE - DON'T EDIT -->
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<TITLE>
HP ProCurve Port Summary
</TITLE>
<link href="/50021801/css/style1.css" rel="stylesheet" type="text/css" id="fastpath">
<script type="text/javascript" src="/50021801/scripts/xui_common.js"></script>
<script type="text/javascript" src="/50021801/scripts/globalStyleJS.js"></script>
<script type="text/javascript" src="/50021801/scripts/globalStyleJS.js"></script>
<script type="text/javascript" >
xuiIncludeCommonJSFiles("/50021801/scripts/");
xuiIncludeJSFile("/50021801/scripts/_xe_PortSummary.js");
</script>
</HEAD>
<BODY onload="formLoad();" CLASS=page>
<FORM method=post ACTION="/PortSummary.html">
<DIV ID="topdiv">
<script type="text/javascript" >
</script>
<script type="text/javascript" >
</script>
<DIV id=summary DIV_XID = 1_1><TABLE ID=1_1><CAPTION>Port Summary</CAPTION>
<TH id=1_1_21 style="display:none">UnitIndex</TH>
<TH id=1_1_22>Interface</TH>
<TH id=1_1_1 style="display:none">Interface</TH>
<TH id=1_1_2>Physical Type</TH>
<TH id=1_1_3>Port Status</TH>
<TH id=1_1_4>AutoNeg Status</TH>
<TH id=1_1_5>Link Speed</TH>
<TH id=1_1_6>MTU</TH>
<TR p="1.0.240" id=1_1>
<TD style="display:none" class="def" p="1.0.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.0.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.0.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.0.24.v_1_1_22 VALUE="1"></TD>
<TD style="display:none" class="def" p="1.0.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.0.24.v_1_1_1 VALUE="1"></TD>
<TD class="def" p="1.0.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.0.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.0.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.0.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.0.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.0.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.0.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.0.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.0.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.0.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.1.240" id=1_1>
<TD style="display:none" class="def" p="1.1.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.1.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.1.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.1.24.v_1_1_22 VALUE="2"></TD>
<TD style="display:none" class="def" p="1.1.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.1.24.v_1_1_1 VALUE="2"></TD>
<TD class="def" p="1.1.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.1.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.1.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.1.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.1.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.1.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.1.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.1.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.1.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.1.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.2.240" id=1_1>
<TD style="display:none" class="def" p="1.2.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.2.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.2.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.2.24.v_1_1_22 VALUE="3"></TD>
<TD style="display:none" class="def" p="1.2.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.2.24.v_1_1_1 VALUE="3"></TD>
<TD class="def" p="1.2.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.2.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.2.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.2.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.2.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.2.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.2.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.2.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.2.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.2.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.3.240" id=1_1>
<TD style="display:none" class="def" p="1.3.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.3.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.3.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.3.24.v_1_1_22 VALUE="4"></TD>
<TD style="display:none" class="def" p="1.3.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.3.24.v_1_1_1 VALUE="4"></TD>
<TD class="def" p="1.3.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.3.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.3.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.3.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.3.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.3.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.3.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.3.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.3.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.3.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.4.240" id=1_1>
<TD style="display:none" class="def" p="1.4.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.4.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.4.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.4.24.v_1_1_22 VALUE="5"></TD>
<TD style="display:none" class="def" p="1.4.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.4.24.v_1_1_1 VALUE="5"></TD>
<TD class="def" p="1.4.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.4.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.4.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.4.24.v_1_1_3 VALUE="Link Up"></TD>
<TD class="def" p="1.4.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.4.24.v_1_1_4 VALUE="Disable"></TD>
<TD class="def" p="1.4.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.4.24.v_1_1_5 VALUE="100MbpsFullDuplex"></TD>
<TD class="def" p="1.4.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.4.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.5.240" id=1_1>
<TD style="display:none" class="def" p="1.5.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.5.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.5.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.5.24.v_1_1_22 VALUE="6"></TD>
<TD style="display:none" class="def" p="1.5.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.5.24.v_1_1_1 VALUE="6"></TD>
<TD class="def" p="1.5.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.5.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.5.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.5.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.5.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.5.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.5.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.5.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.5.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.5.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.6.240" id=1_1>
<TD style="display:none" class="def" p="1.6.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.6.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.6.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.6.24.v_1_1_22 VALUE="7"></TD>
<TD style="display:none" class="def" p="1.6.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.6.24.v_1_1_1 VALUE="7"></TD>
<TD class="def" p="1.6.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.6.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.6.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.6.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.6.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.6.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.6.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.6.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.6.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.6.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.7.240" id=1_1>
<TD style="display:none" class="def" p="1.7.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.7.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.7.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.7.24.v_1_1_22 VALUE="8"></TD>
<TD style="display:none" class="def" p="1.7.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.7.24.v_1_1_1 VALUE="8"></TD>
<TD class="def" p="1.7.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.7.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.7.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.7.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.7.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.7.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.7.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.7.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.7.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.7.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.8.240" id=1_1>
<TD style="display:none" class="def" p="1.8.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.8.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.8.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.8.24.v_1_1_22 VALUE="9"></TD>
<TD style="display:none" class="def" p="1.8.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.8.24.v_1_1_1 VALUE="9"></TD>
<TD class="def" p="1.8.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.8.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.8.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.8.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.8.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.8.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.8.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.8.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.8.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.8.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.9.240" id=1_1>
<TD style="display:none" class="def" p="1.9.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.9.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.9.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.9.24.v_1_1_22 VALUE="10"></TD>
<TD style="display:none" class="def" p="1.9.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.9.24.v_1_1_1 VALUE="10"></TD>
<TD class="def" p="1.9.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.9.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.9.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.9.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.9.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.9.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.9.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.9.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.9.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.9.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.10.240" id=1_1>
<TD style="display:none" class="def" p="1.10.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.10.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.10.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.10.24.v_1_1_22 VALUE="11"></TD>
<TD style="display:none" class="def" p="1.10.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.10.24.v_1_1_1 VALUE="11"></TD>
<TD class="def" p="1.10.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.10.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.10.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.10.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.10.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.10.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.10.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.10.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.10.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.10.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.11.240" id=1_1>
<TD style="display:none" class="def" p="1.11.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.11.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.11.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.11.24.v_1_1_22 VALUE="12"></TD>
<TD style="display:none" class="def" p="1.11.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.11.24.v_1_1_1 VALUE="12"></TD>
<TD class="def" p="1.11.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.11.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.11.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.11.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.11.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.11.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.11.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.11.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.11.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.11.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.12.240" id=1_1>
<TD style="display:none" class="def" p="1.12.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.12.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.12.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.12.24.v_1_1_22 VALUE="13"></TD>
<TD style="display:none" class="def" p="1.12.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.12.24.v_1_1_1 VALUE="13"></TD>
<TD class="def" p="1.12.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.12.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.12.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.12.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.12.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.12.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.12.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.12.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.12.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.12.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.13.240" id=1_1>
<TD style="display:none" class="def" p="1.13.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.13.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.13.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.13.24.v_1_1_22 VALUE="14"></TD>
<TD style="display:none" class="def" p="1.13.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.13.24.v_1_1_1 VALUE="14"></TD>
<TD class="def" p="1.13.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.13.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.13.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.13.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.13.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.13.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.13.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.13.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.13.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.13.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.14.240" id=1_1>
<TD style="display:none" class="def" p="1.14.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.14.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.14.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.14.24.v_1_1_22 VALUE="15"></TD>
<TD style="display:none" class="def" p="1.14.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.14.24.v_1_1_1 VALUE="15"></TD>
<TD class="def" p="1.14.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.14.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.14.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.14.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.14.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.14.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.14.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.14.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.14.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.14.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.15.240" id=1_1>
<TD style="display:none" class="def" p="1.15.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.15.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.15.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.15.24.v_1_1_22 VALUE="16"></TD>
<TD style="display:none" class="def" p="1.15.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.15.24.v_1_1_1 VALUE="16"></TD>
<TD class="def" p="1.15.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.15.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.15.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.15.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.15.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.15.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.15.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.15.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.15.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.15.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.16.240" id=1_1>
<TD style="display:none" class="def" p="1.16.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.16.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.16.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.16.24.v_1_1_22 VALUE="17"></TD>
<TD style="display:none" class="def" p="1.16.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.16.24.v_1_1_1 VALUE="17"></TD>
<TD class="def" p="1.16.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.16.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.16.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.16.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.16.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.16.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.16.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.16.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.16.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.16.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.17.240" id=1_1>
<TD style="display:none" class="def" p="1.17.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.17.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.17.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.17.24.v_1_1_22 VALUE="18"></TD>
<TD style="display:none" class="def" p="1.17.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.17.24.v_1_1_1 VALUE="18"></TD>
<TD class="def" p="1.17.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.17.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.17.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.17.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.17.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.17.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.17.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.17.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.17.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.17.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.18.240" id=1_1>
<TD style="display:none" class="def" p="1.18.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.18.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.18.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.18.24.v_1_1_22 VALUE="19"></TD>
<TD style="display:none" class="def" p="1.18.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.18.24.v_1_1_1 VALUE="19"></TD>
<TD class="def" p="1.18.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.18.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.18.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.18.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.18.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.18.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.18.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.18.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.18.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.18.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.19.240" id=1_1>
<TD style="display:none" class="def" p="1.19.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.19.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.19.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.19.24.v_1_1_22 VALUE="20"></TD>
<TD style="display:none" class="def" p="1.19.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.19.24.v_1_1_1 VALUE="20"></TD>
<TD class="def" p="1.19.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.19.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.19.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.19.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.19.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.19.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.19.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.19.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.19.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.19.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.20.240" id=1_1>
<TD style="display:none" class="def" p="1.20.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.20.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.20.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.20.24.v_1_1_22 VALUE="21"></TD>
<TD style="display:none" class="def" p="1.20.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.20.24.v_1_1_1 VALUE="21"></TD>
<TD class="def" p="1.20.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.20.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.20.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.20.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.20.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.20.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.20.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.20.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.20.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.20.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.21.240" id=1_1>
<TD style="display:none" class="def" p="1.21.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.21.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.21.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.21.24.v_1_1_22 VALUE="22"></TD>
<TD style="display:none" class="def" p="1.21.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.21.24.v_1_1_1 VALUE="22"></TD>
<TD class="def" p="1.21.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.21.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.21.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.21.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.21.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.21.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.21.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.21.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.21.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.21.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.22.240" id=1_1>
<TD style="display:none" class="def" p="1.22.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.22.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.22.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.22.24.v_1_1_22 VALUE="23"></TD>
<TD style="display:none" class="def" p="1.22.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.22.24.v_1_1_1 VALUE="23"></TD>
<TD class="def" p="1.22.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.22.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.22.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.22.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.22.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.22.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.22.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.22.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.22.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.22.24.v_1_1_6 VALUE="1518"></TD>
</TR>
<TR p="1.23.240" id=1_1>
<TD style="display:none" class="def" p="1.23.240" id=1_1_21 ><INPUT xid=1_1_21 TYPE=hidden NAME=1.23.24.v_1_1_21 VALUE="1"></TD>
<TD class="def" p="1.23.240" id=1_1_22><INPUT xid=1_1_22 TYPE=hidden NAME=1.23.24.v_1_1_22 VALUE="24"></TD>
<TD style="display:none" class="def" p="1.23.240" id=1_1_1 ><INPUT xid=1_1_1 TYPE=hidden NAME=1.23.24.v_1_1_1 VALUE="24"></TD>
<TD class="def" p="1.23.240" id=1_1_2><INPUT xid=1_1_2 TYPE=hidden NAME=1.23.24.v_1_1_2 VALUE="RJ45"></TD>
<TD class="def" p="1.23.240" id=1_1_3><INPUT xid=1_1_3 TYPE=hidden NAME=1.23.24.v_1_1_3 VALUE="Link Down"></TD>
<TD class="def" p="1.23.240" id=1_1_4><INPUT xid=1_1_4 TYPE=hidden NAME=1.23.24.v_1_1_4 VALUE="Enable"></TD>
<TD class="def" p="1.23.240" id=1_1_5><INPUT xid=1_1_5 TYPE=hidden NAME=1.23.24.v_1_1_5 VALUE=" "></TD>
<TD class="def" p="1.23.240" id=1_1_6><INPUT xid=1_1_6 TYPE=hidden NAME=1.23.24.v_1_1_6 VALUE="1518"></TD>
</TR>
</TABLE></DIV><br>
<DIV id=summary NORENDER DIV_XID = 2_3><TABLE ID=2_3><CAPTION>Port Statistics</CAPTION>
<TH id=2_3_1>Interface</TH>
<TH id=2_3_6 style="display:none">ifIndex</TH>
<TH id=2_3_13 style="display:none">ifIndex</TH>
<TH id=2_3_2>Received Packets <BR>w/o Error</TH>
<TH id=2_3_3>Received Packets <BR>with Error</TH>
<TH id=2_3_7>Broadcast<BR>Received Packets</TH>
<TH id=2_3_8>Transmitted Packets <BR>w/o Errors</TH>
<TH id=2_3_9>Transmitted Packets <BR>with Errors</TH>
<TH id=2_3_10>Collisions</TH>
<TH id=2_3_11>Transmitted <BR>Pause Frames</TH>
<TH id=2_3_12>Received <BR>Pause Frames</TH>
<tr><td CLASS="tabledata0">1</td><td CLASS="tabledata0" style="display: none;">1</td><td CLASS="tabledata0" style="display: none;">1</td><td CLASS="tabledata0">11338</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">79</td><td CLASS="tabledata0">11918</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">2</td><td CLASS="tabledata1" style="display: none;">2</td><td CLASS="tabledata1" style="display: none;">2</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">3</td><td CLASS="tabledata0" style="display: none;">3</td><td CLASS="tabledata0" style="display: none;">3</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">4</td><td CLASS="tabledata1" style="display: none;">4</td><td CLASS="tabledata1" style="display: none;">4</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">5</td><td CLASS="tabledata0" style="display: none;">5</td><td CLASS="tabledata0" style="display: none;">5</td><td CLASS="tabledata0">4832</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">27</td><td CLASS="tabledata0">5390</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">6</td><td CLASS="tabledata1" style="display: none;">6</td><td CLASS="tabledata1" style="display: none;">6</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">7</td><td CLASS="tabledata0" style="display: none;">7</td><td CLASS="tabledata0" style="display: none;">7</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">8</td><td CLASS="tabledata1" style="display: none;">8</td><td CLASS="tabledata1" style="display: none;">8</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">9</td><td CLASS="tabledata0" style="display: none;">9</td><td CLASS="tabledata0" style="display: none;">9</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">10</td><td CLASS="tabledata1" style="display: none;">10</td><td CLASS="tabledata1" style="display: none;">10</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">11</td><td CLASS="tabledata0" style="display: none;">11</td><td CLASS="tabledata0" style="display: none;">11</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">12</td><td CLASS="tabledata1" style="display: none;">12</td><td CLASS="tabledata1" style="display: none;">12</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">13</td><td CLASS="tabledata0" style="display: none;">13</td><td CLASS="tabledata0" style="display: none;">13</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">14</td><td CLASS="tabledata1" style="display: none;">14</td><td CLASS="tabledata1" style="display: none;">14</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">15</td><td CLASS="tabledata0" style="display: none;">15</td><td CLASS="tabledata0" style="display: none;">15</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">16</td><td CLASS="tabledata1" style="display: none;">16</td><td CLASS="tabledata1" style="display: none;">16</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">17</td><td CLASS="tabledata0" style="display: none;">17</td><td CLASS="tabledata0" style="display: none;">17</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">18</td><td CLASS="tabledata1" style="display: none;">18</td><td CLASS="tabledata1" style="display: none;">18</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">19</td><td CLASS="tabledata0" style="display: none;">19</td><td CLASS="tabledata0" style="display: none;">19</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">20</td><td CLASS="tabledata1" style="display: none;">20</td><td CLASS="tabledata1" style="display: none;">20</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">21</td><td CLASS="tabledata0" style="display: none;">21</td><td CLASS="tabledata0" style="display: none;">21</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">22</td><td CLASS="tabledata1" style="display: none;">22</td><td CLASS="tabledata1" style="display: none;">22</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
<tr><td CLASS="tabledata0">23</td><td CLASS="tabledata0" style="display: none;">23</td><td CLASS="tabledata0" style="display: none;">23</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td><td CLASS="tabledata0">0</td></tr>
<tr><td CLASS="tabledata1">24</td><td CLASS="tabledata1" style="display: none;">24</td><td CLASS="tabledata1" style="display: none;">24</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td><td CLASS="tabledata1">0</td></tr>
</TABLE></DIV><br>
<DIV id=summary NORENDER DIV_XID = 4_3><TABLE ID=4_3><CAPTION>Trunk Statistics</CAPTION>
<TH id=4_3_1>Trunk</TH>
<TH id=4_3_6 style="display:none">ifIndex</TH>
<TH id=4_3_11 style="display:none">ifIndex</TH>
<TH id=4_3_2>Received Packets <BR>w/o Error</TH>
<TH id=4_3_3>Received Packets <BR>with Error</TH>
<TH id=4_3_7>Broadcast<BR>Received Packets</TH>
<TH id=4_3_8>Transmitted Packets <BR>w/o Errors</TH>
<TH id=4_3_9>Transmitted Packets <BR>with Errors</TH>
<TH id=4_3_10>Collisions</TH>
</TABLE></DIV><br>
<DIV id=buttons DIV_XID = 3><TABLE ID=3><CAPTION> </CAPTION>
<TD id=3_1_2 style="display:none" ><INPUT xid=3_1_2 TYPE=hidden NAME=v_3_1_2 VALUE="TRUE"></TD>
</TABLE></DIV><br>
<script type="text/javascript" >
allWebEnums.e_v_1_1_21_values = [ "1" ];
allWebEnums.e_v_1_1_21_eactions = [];
allWebEnums.e_v_1_1_21 = xuiInsertEActionStrings("1_1_21" , allWebEnums.e_v_1_1_21_values,allWebEnums.e_v_1_1_21_eactions);
allWebEnums.e_v_1_1_22_values = [ "1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24" ];
allWebEnums.e_v_1_1_22_eactions = [];
allWebEnums.e_v_1_1_22 = xuiInsertEActionStrings("1_1_22" , allWebEnums.e_v_1_1_22_values,allWebEnums.e_v_1_1_22_eactions);
allWebEnums.e_v_1_1_1_values = [ "1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24" ];
allWebEnums.e_v_1_1_1_eactions = [];
allWebEnums.e_v_1_1_1 = xuiInsertEActionStrings("1_1_1" , allWebEnums.e_v_1_1_1_values,allWebEnums.e_v_1_1_1_eactions);
</script>
<!-- redirection elements -->
<INPUT TYPE="hidden" NAME="submit_flag" XC=hidden VALUE="0">
<INPUT TYPE="hidden" NAME="submit_target" XC=hidden VALUE="PortSummary.html">
<INPUT TYPE="hidden" NAME="err_flag" XC=hidden SIZE="16" MAXLENGTH="15" VALUE="0">
<INPUT TYPE="hidden" NAME="err_msg" XC=hidden SIZE="80" MAXLENGTH="79" VALUE="">
<INPUT TYPE="hidden" NAME="clazz_information" XC=hidden VALUE="PortSummary.html">
<center>
<DIV ID="buttons" style="visibility:visible;">
<TABLE><TR align=center>
<TD id=3_1_1><INPUT xid=3_1_1 DISABLED TYPE=hidden NAME=v_3_1_1 VALUE="Clear"></TD>
</TR></TABLE>
</DIV>
</center>
</DIV>
</FORM>
</BODY>
</HTML>
@@ -0,0 +1,118 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<!-- (C) Copyright Broadcom Corporation 2000-2020 : This file is auto-generated by XE - DON'T EDIT -->
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<TITLE>
HP ProCurve
</TITLE>
<link href="/50021801/css/style1.css" rel="stylesheet" type="text/css" id="fastpath">
<script type="text/javascript" src="/50021801/scripts/xui_common.js"></script>
<script type="text/javascript" src="/50021801/scripts/globalStyleJS.js"></script>
<script type="text/javascript" src="/50021801/scripts/globalStyleJS.js"></script>
<script type="text/javascript" >
xuiIncludeCommonJSFiles("/50021801/scripts/");
xuiIncludeJSFile("/50021801/scripts/_xe_SysDescription.js");
</script>
</HEAD>
<BODY onload="formLoad();" CLASS=page>
<FORM method=post ACTION="/SysDescription.html">
<DIV ID="topdiv">
<script type="text/javascript" >
xeValData.xv_1_2_1_260 = "Error! Invalid String:Unable to set '$$objName$$' with '$$objValue$$'.";
xeValData.xv_1_2_1_340 = "Error! Invalid String:Unable to set '$$objName$$' with '$$objValue$$'. Enter string with alphanumeric characters, hyphens and commas.";
xeValData.xv_1_3_1_260 = "Error! Invalid String:Unable to set '$$objName$$' with '$$objValue$$'.";
xeValData.xv_1_3_1_340 = "Error! Invalid String:Unable to set '$$objName$$' with '$$objValue$$'. Enter string with alphanumeric characters, hyphens and commas.";
xeValData.xv_1_4_1_260 = "Error! Invalid String:Unable to set '$$objName$$' with '$$objValue$$'.";
xeValData.xv_1_4_1_340 = "Error! Invalid String:Unable to set '$$objName$$' with '$$objValue$$'. Enter string with alphanumeric characters, hyphens and commas.";
</script>
<script type="text/javascript" >
xeData.arghelp_1_11_1 = "( hh:mm:ss )";
</script>
<DIV id=scalar DIV_XID = 1><TABLE ID=1><CAPTION>System Description </CAPTION>
<TR id=1_1 class=def>
<TD class=defleft id=1_1_1>System Description</TD>
<TD class=defright id=1_1_1><INPUT xid=1_1_1 TYPE=hidden NAME=v_1_1_1 VALUE=" HP ProCurve 1810G - 24 GE, P.2.24, eCos-2.0, CFE-2.1"></TD>
</TR>
<TR id=1_2 class=def>
<TD class=defleft id=1_2_1>System Name</TD>
<TD class=defright id=1_2_1><INPUT xid=1_2_1 TYPE=hidden NAME=v_1_2_1 VALUE="Draupnir01"></TD>
</TR>
<TR id=1_3 class=def>
<TD class=defleft id=1_3_1>System Location</TD>
<TD class=defright id=1_3_1><INPUT xid=1_3_1 TYPE=hidden NAME=v_1_3_1 VALUE="Lab"></TD>
</TR>
<TR id=1_4 class=def>
<TD class=defleft id=1_4_1>System Contact</TD>
<TD class=defright id=1_4_1><INPUT xid=1_4_1 TYPE=hidden NAME=v_1_4_1 VALUE=""></TD>
</TR>
<TR id=1_8 class=def>
<TD class=defleft id=1_8_1>Software Version</TD>
<TD class=defright id=1_8_1><INPUT xid=1_8_1 TYPE=hidden NAME=v_1_8_1 VALUE="P.2.24"></TD>
</TR>
<TR id=1_9 class=def>
<TD class=defleft id=1_9_1>System Object ID</TD>
<TD class=defright id=1_9_1><INPUT xid=1_9_1 TYPE=hidden NAME=v_1_9_1 VALUE="1.3.6.1.4.1.11.2.3.7.11.104"></TD>
</TR>
<TR id=1_10 class=def>
<TD class=defleft id=1_10_1>System Up Time</TD>
<TD class=defright id=1_10_1><INPUT xid=1_10_1 TYPE=hidden NAME=v_1_10_1 VALUE="0 days, 3 hours, 56 mins, 19 secs"></TD>
</TR>
<TR id=1_11 class=def>
<TD class=defleft id=1_11_1>Current Time</TD>
<TD class=defright id=1_11_1><INPUT xid=1_11_1 TYPE=hidden NAME=v_1_11_1 VALUE="04:56:19"></TD>
</TR>
<TR id=1_12 class=def>
<TD class=defleft id=1_12_1>Date</TD>
<TD class=defright id=1_12_1><INPUT xid=1_12_1 TYPE=hidden NAME=v_1_12_1 VALUE="01/01/1970"></TD>
</TR>
</TABLE></DIV><br>
<DIV id=buttons DIV_XID = 2><TABLE ID=2><CAPTION> </CAPTION>
</TABLE></DIV><br>
<script type="text/javascript" >
</script>
<!-- redirection elements -->
<INPUT TYPE="hidden" NAME="submit_flag" XC=hidden VALUE="0">
<INPUT TYPE="hidden" NAME="submit_target" XC=hidden VALUE="SysDescription.html">
<INPUT TYPE="hidden" NAME="err_flag" XC=hidden SIZE="16" MAXLENGTH="15" VALUE="0">
<INPUT TYPE="hidden" NAME="err_msg" XC=hidden SIZE="80" MAXLENGTH="79" VALUE="">
<INPUT TYPE="hidden" NAME="clazz_information" XC=hidden VALUE="SysDescription.html">
<center>
<DIV ID="buttons" style="visibility:visible;">
<TABLE><TR align=center>
<TD id=2_1_1><INPUT xid=2_1_1 DISABLED TYPE=hidden NAME=v_2_1_1 VALUE="Apply"></TD>
</TR></TABLE>
</DIV>
</center>
</DIV>
</FORM>
</BODY>
</HTML>
@@ -0,0 +1,137 @@
// Port of ~/code/experiments/hpe/extractors/xe_page.py -- see that file's
// docstring for the two table shapes this parses.
//
// Note on traversal: the switch firmware's HTML puts <TH>/<TR> as direct
// children of <TABLE> with no <TBODY> wrapper. A strict browser-grade HTML5
// parser (which golang.org/x/net/html, underlying goquery, implements) would
// normally insert a synthetic <TBODY> around those rows, which would break a
// "direct children only" traversal the way the Python version does (Python's
// html.parser is lenient and doesn't insert one). We sidestep this by using
// Find() (any descendant) instead of direct-children selectors -- safe here
// because tables in this firmware are never nested inside one another.
package client
import (
"strings"
"github.com/PuerkitoBio/goquery"
)
type Table struct {
Caption string
Kind string // "scalar" | "tabular"
Record map[string]string
FieldNames map[string]string
Rows []map[string]string
ID string
}
func extractCellValue(td *goquery.Selection) string {
if inp := td.Find("input").First(); inp.Length() > 0 {
if v, exists := inp.Attr("value"); exists {
return v
}
return ""
}
return strings.TrimSpace(td.Text())
}
func parseTable(table *goquery.Selection) Table {
id, _ := table.Attr("id")
caption := strings.TrimSpace(table.Find("caption").First().Text())
var headers []string
table.Find("th").Each(func(_ int, th *goquery.Selection) {
headers = append(headers, strings.TrimSpace(th.Text()))
})
if len(headers) > 0 {
var rows []map[string]string
table.Find("tr").Each(func(_ int, tr *goquery.Selection) {
tds := tr.Find("td")
if tds.Length() != len(headers) {
return
}
row := make(map[string]string, len(headers))
tds.Each(func(i int, td *goquery.Selection) {
// Later (visible) column wins on a duplicate header label --
// see the same caveat noted in extractors/xe_page.py.
row[headers[i]] = extractCellValue(td)
})
rows = append(rows, row)
})
return Table{Caption: caption, Kind: "tabular", Rows: rows, ID: id}
}
record := make(map[string]string)
fieldNames := make(map[string]string)
table.Find("tr").Each(func(_ int, tr *goquery.Selection) {
defleft := tr.Find("td.defleft").First()
defright := tr.Find("td.defright").First()
if defleft.Length() == 0 || defright.Length() == 0 {
return
}
label := strings.TrimSpace(defleft.Text())
if label == "" {
return
}
record[label] = extractCellValue(defright)
if inp := defright.Find("input").First(); inp.Length() > 0 {
if name, exists := inp.Attr("name"); exists && name != "" {
fieldNames[label] = name
}
}
})
return Table{
Caption: caption,
Kind: "scalar",
Record: record,
FieldNames: fieldNames,
ID: id,
}
}
// ParseXETables parses every <TABLE> in html, in document order.
func ParseXETables(html string) ([]Table, error) {
doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))
if err != nil {
return nil, err
}
var tables []Table
doc.Find("table").Each(func(_ int, table *goquery.Selection) {
tables = append(tables, parseTable(table))
})
return tables, nil
}
// FetchTables fetches path and returns {caption: table} for every captioned
// table. Tables with no/blank caption are dropped -- use FetchAllTables +
// Table.ID for those (e.g. the MAC Table entries table on FDBSearch.html).
func (c *Client) FetchTables(path string) (map[string]Table, error) {
html, err := c.Fetch(path)
if err != nil {
return nil, err
}
tables, err := ParseXETables(html)
if err != nil {
return nil, err
}
result := make(map[string]Table, len(tables))
for _, t := range tables {
if t.Caption != "" {
result[t.Caption] = t
}
}
return result, nil
}
// FetchAllTables fetches path and returns every table, including
// uncaptioned ones, in document order.
func (c *Client) FetchAllTables(path string) ([]Table, error) {
html, err := c.Fetch(path)
if err != nil {
return nil, err
}
return ParseXETables(html)
}
@@ -0,0 +1,130 @@
package client
import (
"os"
"testing"
)
func loadFixture(t *testing.T, name string) string {
t.Helper()
data, err := os.ReadFile("testdata/" + name)
if err != nil {
t.Fatalf("reading fixture %s: %v", name, err)
}
return string(data)
}
// Expected values below were captured live from the real switch (see
// ~/code/experiments/hpe/page_snapshots/current_state.json) at the time
// these fixtures were saved -- this test is about the parser's correctness,
// not about the switch's current state.
func TestParseXETables_ScalarShape_SysDescription(t *testing.T) {
tables, err := ParseXETables(loadFixture(t, "SysDescription.html"))
if err != nil {
t.Fatalf("ParseXETables: %v", err)
}
var sysDesc *Table
for i := range tables {
if tables[i].Caption == "System Description" {
sysDesc = &tables[i]
}
}
if sysDesc == nil {
t.Fatalf("no table captioned %q found; got captions: %v", "System Description", captions(tables))
}
if sysDesc.Kind != "scalar" {
t.Errorf("Kind = %q, want %q", sysDesc.Kind, "scalar")
}
want := map[string]string{
"System Name": "Draupnir01",
"System Location": "Lab",
"Software Version": "P.2.24",
}
for label, wantValue := range want {
if got := sysDesc.Record[label]; got != wantValue {
t.Errorf("Record[%q] = %q, want %q", label, got, wantValue)
}
}
if fieldName := sysDesc.FieldNames["System Name"]; fieldName != "v_1_2_1" {
t.Errorf("FieldNames[%q] = %q, want %q", "System Name", fieldName, "v_1_2_1")
}
}
func TestParseXETables_TabularShape_PortSummary(t *testing.T) {
tables, err := ParseXETables(loadFixture(t, "PortSummary.html"))
if err != nil {
t.Fatalf("ParseXETables: %v", err)
}
var portSummary *Table
for i := range tables {
if tables[i].Caption == "Port Summary" {
portSummary = &tables[i]
}
}
if portSummary == nil {
t.Fatalf("no table captioned %q found; got captions: %v", "Port Summary", captions(tables))
}
if portSummary.Kind != "tabular" {
t.Errorf("Kind = %q, want %q", portSummary.Kind, "tabular")
}
if len(portSummary.Rows) != 24 {
t.Fatalf("len(Rows) = %d, want 24", len(portSummary.Rows))
}
first := portSummary.Rows[0]
if first["Interface"] != "1" {
t.Errorf(`Rows[0]["Interface"] = %q, want "1"`, first["Interface"])
}
if first["Physical Type"] != "RJ45" {
t.Errorf(`Rows[0]["Physical Type"] = %q, want "RJ45"`, first["Physical Type"])
}
}
func TestFetchAllTables_BlankCaptionTable_FDBSearch(t *testing.T) {
tables, err := ParseXETables(loadFixture(t, "FDBSearch.html"))
if err != nil {
t.Fatalf("ParseXETables: %v", err)
}
var summary, entries *Table
for i := range tables {
if tables[i].Caption == "MAC Table" {
summary = &tables[i]
}
if tables[i].ID == "1_1" {
entries = &tables[i]
}
}
if summary == nil {
t.Fatalf("no table captioned %q found; got captions: %v", "MAC Table", captions(tables))
}
if summary.Record["Current Entries"] != "2" {
t.Errorf(`summary.Record["Current Entries"] = %q, want "2"`, summary.Record["Current Entries"])
}
if entries == nil {
t.Fatalf("no table with id %q found", "1_1")
}
if entries.Kind != "tabular" {
t.Errorf("entries.Kind = %q, want %q", entries.Kind, "tabular")
}
if len(entries.Rows) != 2 {
t.Fatalf("len(entries.Rows) = %d, want 2", len(entries.Rows))
}
if entries.Rows[0]["MAC Address"] != "4C:EA:41:63:04:1B" {
t.Errorf(`entries.Rows[0]["MAC Address"] = %q, want "4C:EA:41:63:04:1B"`, entries.Rows[0]["MAC Address"])
}
}
func captions(tables []Table) []string {
out := make([]string, len(tables))
for i, t := range tables {
out[i] = t.Caption
}
return out
}