From 0122ee156a6bc2d095594a20061bd68c4ae7a88e Mon Sep 17 00:00:00 2001 From: Michael Insel Date: Sun, 27 Sep 2020 11:19:26 +0200 Subject: [PATCH 1/3] Fix wrong values for max down-/upstream --- cmd/check_fritz/check_downstream.go | 52 ++++++++++++++++++++++++----- cmd/check_fritz/check_upstream.go | 52 ++++++++++++++++++++++++----- modules/fritz/fritz_response.go | 29 ++++++++++++++++ 3 files changed, 117 insertions(+), 16 deletions(-) diff --git a/cmd/check_fritz/check_downstream.go b/cmd/check_fritz/check_downstream.go index 1f7a04a..aa135be 100644 --- a/cmd/check_fritz/check_downstream.go +++ b/cmd/check_fritz/check_downstream.go @@ -15,8 +15,20 @@ func CheckDownstreamMax(aI ArgumentInformation) { resps := make(chan []byte) errs := make(chan error) - soapReq := fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wancommonifconfig1", "WANCommonInterfaceConfig", "X_AVM-DE_GetOnlineMonitor") - soapReq.AddSoapDataVariable(fritz.CreateNewSoapVariable("NewSyncGroupIndex", "0")) + var soapReq fritz.SoapData + + isDSL := false + + if strings.ToLower(*aI.Modelgroup) == "dsl" { + isDSL = true + } + + if isDSL { + soapReq = fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wandslifconfig1", "WANDSLInterfaceConfig", "GetInfo") + } else { + soapReq = fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wancommonifconfig1", "WANCommonInterfaceConfig", "GetCommonLinkProperties") + } + go fritz.DoSoapRequest(&soapReq, resps, errs, aI.Debug) res, err := fritz.ProcessSoapResponse(resps, errs, 1, *aI.Timeout) @@ -26,16 +38,40 @@ func CheckDownstreamMax(aI ArgumentInformation) { return } - soapResp := fritz.WANCommonInterfaceOnlineMonitorResponse{} - err = fritz.UnmarshalSoapResponse(&soapResp, res) + var downstream float64 - downstream, err := strconv.ParseFloat(soapResp.NewMaxDS, 64) + if isDSL { + soapResp := fritz.WANDSLInterfaceGetInfoResponse{} + err = fritz.UnmarshalSoapResponse(&soapResp, res) - if err != nil { - panic(err) + if err != nil { + panic(err) + } + + ups, err := strconv.ParseFloat(soapResp.NewDownstreamCurrRate, 64) + + if err != nil { + panic(err) + } + + downstream = ups / 1000 + } else { + soapResp := fritz.WANCommonInterfaceCommonLinkPropertiesResponse{} + err = fritz.UnmarshalSoapResponse(&soapResp, res) + + if err != nil { + panic(err) + } + + ups, err := strconv.ParseFloat(soapResp.NewLayer1DownstreamMaxBitRate, 64) + + if err != nil { + panic(err) + } + + downstream = ups / 1000000 } - downstream = downstream * 8 / 1000000 perfData := perfdata.CreatePerformanceData("downstream_max", downstream, "") GlobalReturnCode = exitOk diff --git a/cmd/check_fritz/check_upstream.go b/cmd/check_fritz/check_upstream.go index 7a0d4a7..1f6fa4a 100644 --- a/cmd/check_fritz/check_upstream.go +++ b/cmd/check_fritz/check_upstream.go @@ -15,8 +15,20 @@ func CheckUpstreamMax(aI ArgumentInformation) { resps := make(chan []byte) errs := make(chan error) - soapReq := fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wancommonifconfig1", "WANCommonInterfaceConfig", "X_AVM-DE_GetOnlineMonitor") - soapReq.AddSoapDataVariable(fritz.CreateNewSoapVariable("NewSyncGroupIndex", "0")) + var soapReq fritz.SoapData + + isDSL := false + + if strings.ToLower(*aI.Modelgroup) == "dsl" { + isDSL = true + } + + if isDSL { + soapReq = fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wandslifconfig1", "WANDSLInterfaceConfig", "GetInfo") + } else { + soapReq = fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wancommonifconfig1", "WANCommonInterfaceConfig", "GetCommonLinkProperties") + } + go fritz.DoSoapRequest(&soapReq, resps, errs, aI.Debug) res, err := fritz.ProcessSoapResponse(resps, errs, 1, *aI.Timeout) @@ -26,16 +38,40 @@ func CheckUpstreamMax(aI ArgumentInformation) { return } - soapResp := fritz.WANCommonInterfaceOnlineMonitorResponse{} - err = fritz.UnmarshalSoapResponse(&soapResp, res) + var upstream float64 - upstream, err := strconv.ParseFloat(soapResp.NewMaxUS, 64) + if isDSL { + soapResp := fritz.WANDSLInterfaceGetInfoResponse{} + err = fritz.UnmarshalSoapResponse(&soapResp, res) - if err != nil { - panic(err) + if err != nil { + panic(err) + } + + ups, err := strconv.ParseFloat(soapResp.NewUpstreamCurrRate, 64) + + if err != nil { + panic(err) + } + + upstream = ups / 1000 + } else { + soapResp := fritz.WANCommonInterfaceCommonLinkPropertiesResponse{} + err = fritz.UnmarshalSoapResponse(&soapResp, res) + + if err != nil { + panic(err) + } + + ups, err := strconv.ParseFloat(soapResp.NewLayer1UpstreamMaxBitRate, 64) + + if err != nil { + panic(err) + } + + upstream = ups / 1000000 } - upstream = upstream * 8 / 1000000 perfData := perfdata.CreatePerformanceData("upstream_max", upstream, "") GlobalReturnCode = exitOk diff --git a/modules/fritz/fritz_response.go b/modules/fritz/fritz_response.go index 0b1fbee..a56c25e 100644 --- a/modules/fritz/fritz_response.go +++ b/modules/fritz/fritz_response.go @@ -163,6 +163,35 @@ type SmartSpecificDeviceInfoResponse struct { NewHkrComfortTemperature string `xml:"Body>GetSpecificDeviceInfosResponse>NewHkrComfortTemperature"` } +// WANCommonInterfaceCommonLinkPropertiesResponse is the date structure for responses from GetCommonLinkProperties +type WANCommonInterfaceCommonLinkPropertiesResponse struct { + TR064Response + NewWANAccessType string `xml:"Body>GetCommonLinkPropertiesResponse>GetCommonLinkPropertiesResponse"` + NewLayer1UpstreamMaxBitRate string `xml:"Body>GetCommonLinkPropertiesResponse>NewLayer1UpstreamMaxBitRate"` + NewLayer1DownstreamMaxBitRate string `xml:"Body>GetCommonLinkPropertiesResponse>NewLayer1DownstreamMaxBitRate"` + NewPhysicalLinkStatus string `xml:"Body>GetCommonLinkPropertiesResponse>NewPhysicalLinkStatus"` +} + +// WANDSLInterfaceGetInfoResponse is the date structure for responses from GetInfo +type WANDSLInterfaceGetInfoResponse struct { + TR064Response + NewEnable string `xml:"Body>GetInfoResponse>NewEnable"` + NewStatus string `xml:"Body>GetInfoResponse>NewStatus"` + NewDataPath string `xml:"Body>GetInfoResponse>NewDataPath"` + NewUpstreamCurrRate string `xml:"Body>GetInfoResponse>NewUpstreamCurrRate"` + NewDownstreamCurrRate string `xml:"Body>GetInfoResponse>NewDownstreamCurrRate"` + NewUpstreamMaxRate string `xml:"Body>GetInfoResponse>NewUpstreamMaxRate"` + NewDownstreamMaxRate string `xml:"Body>GetInfoResponse>NewDownstreamMaxRate"` + NewUpstreamNoiseMargin string `xml:"Body>GetInfoResponse>NewUpstreamNoiseMargin"` + NewDownstreamNoiseMargin string `xml:"Body>GetInfoResponse>NewDownstreamNoiseMargin"` + NewUpstreamAttenuation string `xml:"Body>GetInfoResponse>NewUpstreamAttenuation"` + NewDownstreamAttenuation string `xml:"Body>GetInfoResponse>NewDownstreamAttenuation"` + NewATURVendor string `xml:"Body>GetInfoResponse>NewATURVendor"` + NewATURCountry string `xml:"Body>GetInfoResponse>NewATURCountry"` + NewUpstreamPower string `xml:"Body>GetInfoResponse>NewUpstreamPower"` + NewDownstreamPower string `xml:"Body>GetInfoResponse>NewDownstreamPower"` +} + // UnmarshalSoapResponse unmarshals the soap response to the data structure func UnmarshalSoapResponse(resp TR064Response, inputXML [][]byte) error { for i := range inputXML { From 9b30f0d248df58da4a85635d46992d870eff4a14 Mon Sep 17 00:00:00 2001 From: Michael Insel Date: Sun, 27 Sep 2020 19:45:08 +0200 Subject: [PATCH 2/3] Fix wrong values for usage down-/upstream Query the correct TR-064 action to collect the correct values for downstream_usage and upstream_usage methods. --- cmd/check_fritz/check_downstream.go | 54 +++++++++++++++++++++++++++-- cmd/check_fritz/check_upstream.go | 54 +++++++++++++++++++++++++++-- 2 files changed, 102 insertions(+), 6 deletions(-) diff --git a/cmd/check_fritz/check_downstream.go b/cmd/check_fritz/check_downstream.go index aa135be..b8dbe02 100644 --- a/cmd/check_fritz/check_downstream.go +++ b/cmd/check_fritz/check_downstream.go @@ -196,14 +196,62 @@ func CheckDownstreamUsage(aI ArgumentInformation) { panic(err) } - downstreamMax, err := strconv.ParseFloat(soapResp.NewMaxDS, 64) + isDSL := false + + if strings.ToLower(*aI.Modelgroup) == "dsl" { + isDSL = true + } + + if isDSL { + soapReq = fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wandslifconfig1", "WANDSLInterfaceConfig", "GetInfo") + } else { + soapReq = fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wancommonifconfig1", "WANCommonInterfaceConfig", "GetCommonLinkProperties") + } + + go fritz.DoSoapRequest(&soapReq, resps, errs, aI.Debug) + + res, err = fritz.ProcessSoapResponse(resps, errs, 1, *aI.Timeout) if err != nil { - panic(err) + fmt.Printf("UNKNOWN - %s\n", err) + return + } + + var downstreamMax float64 + + if isDSL { + soapResp := fritz.WANDSLInterfaceGetInfoResponse{} + err = fritz.UnmarshalSoapResponse(&soapResp, res) + + if err != nil { + panic(err) + } + + ups, err := strconv.ParseFloat(soapResp.NewDownstreamCurrRate, 64) + + if err != nil { + panic(err) + } + + downstreamMax = ups / 1000 + } else { + soapResp := fritz.WANCommonInterfaceCommonLinkPropertiesResponse{} + err = fritz.UnmarshalSoapResponse(&soapResp, res) + + if err != nil { + panic(err) + } + + ups, err := strconv.ParseFloat(soapResp.NewLayer1DownstreamMaxBitRate, 64) + + if err != nil { + panic(err) + } + + downstreamMax = ups / 1000000 } downstreamCurrent = downstreamCurrent * 8 / 1000000 - downstreamMax = downstreamMax * 8 / 1000000 if downstreamMax == 0 { fmt.Printf("UNKNOWN - Maximum Downstream is 0\n") diff --git a/cmd/check_fritz/check_upstream.go b/cmd/check_fritz/check_upstream.go index 1f6fa4a..0a08d4e 100644 --- a/cmd/check_fritz/check_upstream.go +++ b/cmd/check_fritz/check_upstream.go @@ -196,14 +196,62 @@ func CheckUpstreamUsage(aI ArgumentInformation) { panic(err) } - upstreamMax, err := strconv.ParseFloat(soapResp.NewMaxUS, 64) + isDSL := false + + if strings.ToLower(*aI.Modelgroup) == "dsl" { + isDSL = true + } + + if isDSL { + soapReq = fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wandslifconfig1", "WANDSLInterfaceConfig", "GetInfo") + } else { + soapReq = fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wancommonifconfig1", "WANCommonInterfaceConfig", "GetCommonLinkProperties") + } + + go fritz.DoSoapRequest(&soapReq, resps, errs, aI.Debug) + + res, err = fritz.ProcessSoapResponse(resps, errs, 1, *aI.Timeout) if err != nil { - panic(err) + fmt.Printf("UNKNOWN - %s\n", err) + return + } + + var upstreamMax float64 + + if isDSL { + soapResp := fritz.WANDSLInterfaceGetInfoResponse{} + err = fritz.UnmarshalSoapResponse(&soapResp, res) + + if err != nil { + panic(err) + } + + ups, err := strconv.ParseFloat(soapResp.NewUpstreamCurrRate, 64) + + if err != nil { + panic(err) + } + + upstreamMax = ups / 1000 + } else { + soapResp := fritz.WANCommonInterfaceCommonLinkPropertiesResponse{} + err = fritz.UnmarshalSoapResponse(&soapResp, res) + + if err != nil { + panic(err) + } + + ups, err := strconv.ParseFloat(soapResp.NewLayer1UpstreamMaxBitRate, 64) + + if err != nil { + panic(err) + } + + upstreamMax = ups / 1000000 } upstreamCurrent = upstreamCurrent * 8 / 1000000 - upstreamMax = upstreamMax * 8 / 1000000 if upstreamMax == 0 { fmt.Printf("UNKNOWN - Maximum Downstream is 0\n") From e7ccfd0067c1a00cdf9ddf6c15868699f587c1d0 Mon Sep 17 00:00:00 2001 From: Michael Insel Date: Sun, 27 Sep 2020 19:54:13 +0200 Subject: [PATCH 3/3] Doc: Upgrading up-/downstream_max/_usage --- doc/upgrading.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/doc/upgrading.md b/doc/upgrading.md index 200958c..c271ade 100644 --- a/doc/upgrading.md +++ b/doc/upgrading.md @@ -7,6 +7,25 @@ The parameter `-i` (`--index`) got removed with the release of v1.2.0. Use the successor `-a` (`--ain`) instead, please read the upgrading to v1.1.0 for details on how to optain the AIN from the Fritz!Box web interface. +### Downstream and Upstream calculation + +A bug was discovered that makes it necessary to provide the `--modelgroup` (short `-M`) parameter to the following +functions, if you use a non DSL Fritz!Box e.g. a Fritz!Box 6591 Cable. + +* `downstream_max` +* `downstream_usage` +* `upstream_max` +* `upstream_usage` + +_Example:_ + +``` +$ ./check_fritz --password secret --method downstream_usage --modelgroup cable +``` + +If you are using a DSL Fritz!Box e.g. a Fritz!Box 7490 you don't need to provide the `--modelgroup` parameter because +the default will use `DSL` as modelgroup. + ## Upgrading to v1.1.0 ### Index parameter