diff --git a/cmd/check_fritz/check_downstream.go b/cmd/check_fritz/check_downstream.go index 1f7a04a..3ce0bd9 100644 --- a/cmd/check_fritz/check_downstream.go +++ b/cmd/check_fritz/check_downstream.go @@ -5,6 +5,8 @@ import ( "strconv" "strings" + "github.com/mcktr/check_fritz/modules/fritzutil" + "github.com/mcktr/check_fritz/modules/fritz" "github.com/mcktr/check_fritz/modules/perfdata" "github.com/mcktr/check_fritz/modules/thresholds" @@ -12,27 +14,86 @@ import ( // CheckDownstreamMax checks the maximum downstream that is available on this internet connection func CheckDownstreamMax(aI ArgumentInformation) { + // Start of the initial request to get the total number of sync groups; we always start with group id 0 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")) - go fritz.DoSoapRequest(&soapReq, resps, errs, aI.Debug) + initialSoapReq := fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wancommonifconfig1", "WANCommonInterfaceConfig", "X_AVM-DE_GetOnlineMonitor") + initialSoapReq.AddSoapDataVariable(fritz.CreateNewSoapVariable("NewSyncGroupIndex", "0")) + go fritz.DoSoapRequest(&initialSoapReq, resps, errs, aI.Debug) - res, err := fritz.ProcessSoapResponse(resps, errs, 1, *aI.Timeout) + initialResponse, err := fritz.ProcessSoapResponse(resps, errs, 1, *aI.Timeout) if err != nil { fmt.Printf("UNKNOWN - %s\n", err) return } - soapResp := fritz.WANCommonInterfaceOnlineMonitorResponse{} - err = fritz.UnmarshalSoapResponse(&soapResp, res) - - downstream, err := strconv.ParseFloat(soapResp.NewMaxDS, 64) + initialSoapResp := fritz.WANCommonInterfaceOnlineMonitorResponse{} + err = fritz.UnmarshalSoapResponse(&initialSoapResp, initialResponse) + // Query the total number of sync groups + totalSyncGroups, err := strconv.Atoi(initialSoapResp.NewTotalNumberSyncGroups) if err != nil { - panic(err) + fmt.Printf("UNKOWN - %s\n", err) + return + } + + foundSupportedSyncMode := false + foundSyncMode := make([]string, 0) + var finalSoapResponse *fritz.WANCommonInterfaceOnlineMonitorResponse + + for currentSyncGroup := 0; currentSyncGroup < totalSyncGroups; currentSyncGroup++ { + soapResp := fritz.WANCommonInterfaceOnlineMonitorResponse{} + + // We only need to perform additional queries when there are more than 1 sync groups + if totalSyncGroups > 1 { + // Start of additional query attempts (depending on how many sync groups are found) + responseChan := make(chan []byte) + errorChan := 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", strconv.Itoa(currentSyncGroup))) + go fritz.DoSoapRequest(&soapReq, responseChan, errorChan, aI.Debug) + + resp, err := fritz.ProcessSoapResponse(responseChan, errorChan, 1, *aI.Timeout) + if err != nil { + fmt.Printf("UNKNOWN - %s\n", err) + return + } + + err = fritz.UnmarshalSoapResponse(&soapResp, resp) + if err != nil { + fmt.Printf("UNKNOWN - %s\n", err) + return + } + } else { + soapResp = initialSoapResp + } + + syncGroupMode := soapResp.NewSyncGroupMode + foundSyncMode = append(foundSyncMode, syncGroupMode) + + // Search for supported sync groups + if fritzutil.Contains(supportedSyncGroupModes, syncGroupMode) { + foundSupportedSyncMode = true + finalSoapResponse = &soapResp + + break + } + } + + var downstream float64 + + if foundSupportedSyncMode { + downstream, err = strconv.ParseFloat(finalSoapResponse.NewMaxDS, 64) + if err != nil { + fmt.Printf("UNKNOWN - %s\n", err) + return + } + } else { + fmt.Printf("UNKNOWN - Could not find a supported SyncGroup (%s); found the following: %s\n", strings.Join(supportedSyncGroupModes, ", "), strings.Join(foundSyncMode, ", ")) + return } downstream = downstream * 8 / 1000000 diff --git a/cmd/check_fritz/check_upstream.go b/cmd/check_fritz/check_upstream.go index 7a0d4a7..adfe44d 100644 --- a/cmd/check_fritz/check_upstream.go +++ b/cmd/check_fritz/check_upstream.go @@ -5,6 +5,8 @@ import ( "strconv" "strings" + "github.com/mcktr/check_fritz/modules/fritzutil" + "github.com/mcktr/check_fritz/modules/fritz" "github.com/mcktr/check_fritz/modules/perfdata" "github.com/mcktr/check_fritz/modules/thresholds" @@ -12,27 +14,86 @@ import ( // CheckUpstreamMax checks the maximum upstream that is available on this internet connection func CheckUpstreamMax(aI ArgumentInformation) { + // Start of the initial request to get the total number of sync groups; we always start with group id 0 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")) - go fritz.DoSoapRequest(&soapReq, resps, errs, aI.Debug) + initialSoapReq := fritz.CreateNewSoapData(*aI.Username, *aI.Password, *aI.Hostname, *aI.Port, "/upnp/control/wancommonifconfig1", "WANCommonInterfaceConfig", "X_AVM-DE_GetOnlineMonitor") + initialSoapReq.AddSoapDataVariable(fritz.CreateNewSoapVariable("NewSyncGroupIndex", "0")) + go fritz.DoSoapRequest(&initialSoapReq, resps, errs, aI.Debug) - res, err := fritz.ProcessSoapResponse(resps, errs, 1, *aI.Timeout) + initialResponse, err := fritz.ProcessSoapResponse(resps, errs, 1, *aI.Timeout) if err != nil { fmt.Printf("UNKNOWN - %s\n", err) return } - soapResp := fritz.WANCommonInterfaceOnlineMonitorResponse{} - err = fritz.UnmarshalSoapResponse(&soapResp, res) - - upstream, err := strconv.ParseFloat(soapResp.NewMaxUS, 64) + initialSoapResp := fritz.WANCommonInterfaceOnlineMonitorResponse{} + err = fritz.UnmarshalSoapResponse(&initialSoapResp, initialResponse) + // Query the total number of sync groups + totalSyncGroups, err := strconv.Atoi(initialSoapResp.NewTotalNumberSyncGroups) if err != nil { - panic(err) + fmt.Printf("UNKOWN - %s\n", err) + return + } + + foundSupportedSyncMode := false + foundSyncMode := make([]string, 0) + var finalSoapResponse *fritz.WANCommonInterfaceOnlineMonitorResponse + + for currentSyncGroup := 0; currentSyncGroup < totalSyncGroups; currentSyncGroup++ { + soapResp := fritz.WANCommonInterfaceOnlineMonitorResponse{} + + // We only need to perform additional queries when there are more than 1 sync groups + if totalSyncGroups > 1 { + // Start of additional query attempts (depending on how many sync groups are found) + responseChan := make(chan []byte) + errorChan := 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", strconv.Itoa(currentSyncGroup))) + go fritz.DoSoapRequest(&soapReq, responseChan, errorChan, aI.Debug) + + resp, err := fritz.ProcessSoapResponse(responseChan, errorChan, 1, *aI.Timeout) + if err != nil { + fmt.Printf("UNKNOWN - %s\n", err) + return + } + + err = fritz.UnmarshalSoapResponse(&soapResp, resp) + if err != nil { + fmt.Printf("UNKNOWN - %s\n", err) + return + } + } else { + soapResp = initialSoapResp + } + + syncGroupMode := soapResp.NewSyncGroupMode + foundSyncMode = append(foundSyncMode, syncGroupMode) + + // Search for supported sync groups + if fritzutil.Contains(supportedSyncGroupModes, syncGroupMode) { + foundSupportedSyncMode = true + finalSoapResponse = &soapResp + + break + } + } + + var upstream float64 + + if foundSupportedSyncMode { + upstream, err = strconv.ParseFloat(finalSoapResponse.NewMaxUS, 64) + if err != nil { + fmt.Printf("UNKNOWN - %s\n", err) + return + } + } else { + fmt.Printf("UNKNOWN - Could not find a supported SyncGroup (%s); found the following: %s\n", strings.Join(supportedSyncGroupModes, ", "), strings.Join(foundSyncMode, ", ")) + return } upstream = upstream * 8 / 1000000 diff --git a/cmd/check_fritz/main.go b/cmd/check_fritz/main.go index 9806d1c..04d468d 100644 --- a/cmd/check_fritz/main.go +++ b/cmd/check_fritz/main.go @@ -21,6 +21,14 @@ const ( // GlobalReturnCode holds always the last set return code var GlobalReturnCode = exitUnknown +// Collection of the supported sync group modes for the downstream_max and upstream_max methods +var supportedSyncGroupModes = []string{ + "DSL", + "VDSL", + "CABLE", + "IP-Client", +} + // ArgumentInformation is the data structure for the passed arguments type ArgumentInformation struct { Hostname *string diff --git a/modules/fritzutil/find.go b/modules/fritzutil/find.go new file mode 100644 index 0000000..88965b2 --- /dev/null +++ b/modules/fritzutil/find.go @@ -0,0 +1,12 @@ +package fritzutil + +// Contains searches for string in a string slice and returns true if the string is found. +func Contains(s []string, v string) bool { + for _, item := range s { + if item == v { + return true + } + } + + return false +} diff --git a/modules/fritzutil/find_test.go b/modules/fritzutil/find_test.go new file mode 100644 index 0000000..1a3db2f --- /dev/null +++ b/modules/fritzutil/find_test.go @@ -0,0 +1,31 @@ +package fritzutil + +import "testing" + +func TestContains(t *testing.T) { + s := []string{ + "Hello", + "we", + "just", + "test", + "here", + } + + f := Contains(s, "Hello") + + if f != true { + t.Errorf("Contains was incorrect, want: true, got %t", f) + } + + f = Contains(s, "CatDog") + + if f != false { + t.Errorf("Contains was incorrect, want: false, got %t", f) + } + + f = Contains(s, "hello") + + if f != false { + t.Errorf("Contains was incorrect, want: false, got %t", f) + } +}