1package Classes::UPNP::AVM::FritzBox7390; 2our @ISA = qw(Classes::UPNP::AVM); 3use strict; 4 5{ 6 our $sid = undef; 7} 8 9sub sid : lvalue { 10 my ($self) = @_; 11 $Classes::UPNP::AVM::FritzBox7390::sid; 12} 13 14sub init { 15 my ($self) = @_; 16 foreach my $module (qw(HTML::TreeBuilder LWP::UserAgent Encode Digest::MD5 JSON)) { 17 if (! eval "require $module") { 18 $self->add_unknown("could not find $module module"); 19 } 20 } 21 if (! $self->check_messages()) { 22 if ($self->mode =~ /device::hardware::health/) { 23 $self->login(); 24 $self->analyze_environmental_subsystem(); 25 $self->check_environmental_subsystem(); 26 } elsif ($self->mode =~ /device::hardware::load/) { 27 $self->login(); 28 $self->analyze_cpu_subsystem(); 29 $self->check_cpu_subsystem(); 30 } elsif ($self->mode =~ /device::hardware::memory/) { 31 $self->login(); 32 $self->analyze_mem_subsystem(); 33 $self->check_mem_subsystem(); 34 } elsif ($self->mode =~ /device::interfaces/) { 35 $self->analyze_and_check_interface_subsystem("Classes::UPNP::AVM::FritzBox7390::Component::InterfaceSubsystem"); 36 } elsif ($self->mode =~ /device::smarthome/) { 37 $self->login(); 38 $self->analyze_and_check_smarthome_subsystem("Classes::UPNP::AVM::FritzBox7390::Component::SmartHomeSubsystem"); 39 } else { 40 $self->no_such_mode(); 41 } 42 $self->logout(); 43 } 44} 45 46sub login { 47 my ($self) = @_; 48 my $ua = LWP::UserAgent->new; 49 my $loginurl = sprintf "http://%s/login_sid.lua", $self->opts->hostname; 50 my $resp = $ua->get($loginurl); 51 my $content = $resp->content(); 52 my $challenge = ($content =~ /<Challenge>(.*?)<\/Challenge>/ && $1); 53 my $input = $challenge . '-' . $self->opts->community; 54 Encode::from_to($input, 'ascii', 'utf16le'); 55 my $challengeresponse = $challenge . '-' . lc(Digest::MD5::md5_hex($input)); 56 $resp = HTTP::Request->new(POST => $loginurl); 57 $resp->content_type("application/x-www-form-urlencoded"); 58 my $login = "response=$challengeresponse"; 59 if ($self->opts->username) { 60 $login .= "&username=" . $self->opts->username; 61 } 62 $resp->content($login); 63 my $loginresp = $ua->request($resp); 64 $content = $loginresp->content(); 65 $self->sid() = ($content =~ /<SID>(.*?)<\/SID>/ && $1); 66 if (! $loginresp->is_success() || ! $self->sid() || $self->sid() =~ /^0+$/) { 67 $self->add_critical($loginresp->status_line()); 68 } else { 69 $self->debug("logged in with sid ".$self->sid()); 70 } 71} 72 73sub logout { 74 my ($self) = @_; 75 return if ! $self->sid(); 76 my $ua = LWP::UserAgent->new; 77 my $loginurl = sprintf "http://%s/login_sid.lua", $self->opts->hostname; 78 my $resp = HTTP::Request->new(POST => $loginurl); 79 $resp->content_type("application/x-www-form-urlencoded"); 80 my $logout = "sid=".$self->sid()."&security:command/logout=1"; 81 $resp->content($logout); 82 my $logoutresp = $ua->request($resp); 83 $self->sid() = undef; 84 $self->debug("logged out"); 85} 86 87sub DESTROY { 88 my ($self) = @_; 89 $self->logout(); 90} 91 92sub http_get { 93 my ($self, $page) = @_; 94 my $ua = LWP::UserAgent->new; 95 if ($page =~ /\?/) { 96 $page .= "&sid=".$self->sid(); 97 } else { 98 $page .= "?sid=".$self->sid(); 99 } 100 my $url = sprintf "http://%s/%s", $self->opts->hostname, $page; 101 $self->debug("http get ".$url); 102 my $resp = $ua->get($url); 103 if (! $resp->is_success()) { 104 $self->add_critical($resp->status_line()); 105 } else { 106 } 107 return $resp->content(); 108} 109 110sub analyze_cpu_subsystem { 111 my ($self) = @_; 112 my $html = $self->http_get('system/ecostat.lua'); 113 if ($html =~ /uiSubmitLogin/) { 114 $self->add_critical("wrong login"); 115 $self->{cpu_usage} = 0; 116 } elsif ($html =~ /StatCPU/) { 117 my $cpu = (grep /StatCPU/, split(/\n/, $html))[0]; 118 my @cpu = ($cpu =~ /= "(.*?)"/ && split(/,/, $1)); 119 $self->{cpu_usage} = $cpu[0]; 120 } elsif ($html =~ /uiViewCpu/) { 121 $html =~ /Query1 = "(.*?)"/; 122 $self->{cpu_usage} = (split(",", $1))[0]; 123 } 124} 125 126sub analyze_mem_subsystem { 127 my ($self) = @_; 128 my $html = $self->http_get('system/ecostat.lua'); 129 if ($html =~ /uiSubmitLogin/) { 130 $self->add_critical("wrong login"); 131 $self->{ram_used} = 0; 132 } elsif ($html =~ /StatRAMCacheUsed/) { 133 my $ramcacheused = (grep /StatRAMCacheUsed/, split(/\n/, $html))[0]; 134 my @ramcacheused = ($ramcacheused =~ /= "(.*?)"/ && split(/,/, $1)); 135 $self->{ram_cache_used} = $ramcacheused[0]; 136 my $ramphysfree = (grep /StatRAMPhysFree/, split(/\n/, $html))[0]; 137 my @ramphysfree = ($ramphysfree =~ /= "(.*?)"/ && split(/,/, $1)); 138 $self->{ram_phys_free} = $ramphysfree[0]; 139 my $ramstrictlyused = (grep /StatRAMStrictlyUsed/, split(/\n/, $html))[0]; 140 my @ramstrictlyused = ($ramstrictlyused =~ /= "(.*?)"/ && split(/,/, $1)); 141 $self->{ram_strictly_used} = $ramstrictlyused[0]; 142 $self->{ram_used} = $self->{ram_strictly_used} + $self->{ram_cache_used}; 143 } elsif ($html =~ /uiViewRamValue/) { 144 $html =~ /Query1 ="(.*?)"/; 145 $self->{ram_free} = (split(",", $1))[0]; 146 $html =~ /Query2 ="(.*?)"/; 147 $self->{ram_dynamic} = (split(",", $1))[0]; 148 $html =~ /Query3 ="(.*?)"/; 149 $self->{ram_fix} = (split(",", $1))[0]; 150 $self->{ram_used} = $self->{ram_fix} + $self->{ram_dynamic}; 151 } 152} 153 154sub check_cpu_subsystem { 155 my ($self) = @_; 156 $self->add_info('checking cpus'); 157 $self->add_info(sprintf 'cpu usage is %.2f%%', $self->{cpu_usage}); 158 $self->set_thresholds(warning => 40, critical => 60); 159 $self->add_message($self->check_thresholds($self->{cpu_usage}), $self->{info}); 160 $self->add_perfdata( 161 label => 'cpu_usage', 162 value => $self->{cpu_usage}, 163 uom => '%', 164 warning => $self->{warning}, 165 critical => $self->{critical}, 166 ); 167} 168 169sub check_mem_subsystem { 170 my ($self) = @_; 171 $self->add_info('checking memory'); 172 $self->add_info(sprintf 'memory usage is %.2f%%', $self->{ram_used}); 173 $self->set_thresholds(warning => 80, critical => 90); 174 $self->add_message($self->check_thresholds($self->{ram_used}), $self->{info}); 175 $self->add_perfdata( 176 label => 'memory_usage', 177 value => $self->{ram_used}, 178 uom => '%', 179 warning => $self->{warning}, 180 critical => $self->{critical}, 181 ); 182} 183 184 185 186 187 188