diff options
Diffstat (limited to 'contrib/check_asterisk.pl')
-rw-r--r-- | contrib/check_asterisk.pl | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/contrib/check_asterisk.pl b/contrib/check_asterisk.pl new file mode 100644 index 00000000..179d3671 --- /dev/null +++ b/contrib/check_asterisk.pl | |||
@@ -0,0 +1,259 @@ | |||
1 | #!/usr/bin/perl -w | ||
2 | |||
3 | use strict; | ||
4 | use IO::Socket; | ||
5 | use Getopt::Long; | ||
6 | $|=1; | ||
7 | |||
8 | my ( | ||
9 | $host, $username, $password, $verbose, $help, $command, $mode, | ||
10 | $ipaddr, $respaddr, $sendto, $msg, $recvfrom, | ||
11 | $version, $response, $message, $line, | ||
12 | $sock, $port, $reply, | ||
13 | $warning, $critical, | ||
14 | %warnval, %critval, | ||
15 | %channels, | ||
16 | $runmode, | ||
17 | $key, | ||
18 | $s, | ||
19 | ); | ||
20 | my $stop = 0; | ||
21 | my $mgr_port = 5038; | ||
22 | my $iax_port = 4569; | ||
23 | my $exitcode = 0; | ||
24 | my $cause = ""; | ||
25 | |||
26 | my $iax_answer = 0; | ||
27 | my $iax_maxlen = 1024; | ||
28 | my $iax_timeout = 5; | ||
29 | my $iax_src_call = "8000"; #8000 most siginificant bit is IAX packet type full ... required for a poke etc... | ||
30 | my $iax_dst_call = "0000"; | ||
31 | my $iax_timestamp = "00000000"; | ||
32 | my $iax_outbound_seq = "00"; | ||
33 | my $iax_inbound_seq = "00"; | ||
34 | my $iax_type = "06"; #IAX_Control | ||
35 | |||
36 | sub ok { | ||
37 | $s = shift; | ||
38 | $s =~ s/[\r\n]//g; | ||
39 | print "OK: $s\n"; | ||
40 | exit(0); | ||
41 | } | ||
42 | |||
43 | sub warning { | ||
44 | $s = shift; | ||
45 | $s =~ s/[\r\n]//g; | ||
46 | print "WARNING: $s\n"; | ||
47 | exit(1); | ||
48 | } | ||
49 | |||
50 | sub error { | ||
51 | $s = shift; | ||
52 | $s =~ s/[\r\n]//g; | ||
53 | print "ERROR: $s\n"; | ||
54 | exit(2); | ||
55 | } | ||
56 | |||
57 | sub unknown { | ||
58 | $s = shift; | ||
59 | $s =~ s/[\r\n]//g; | ||
60 | print "UNKNOWN: $s\n"; | ||
61 | exit(3); | ||
62 | } | ||
63 | |||
64 | sub syntax { | ||
65 | $s = shift; | ||
66 | unless ($s =~ m/Help:/) { | ||
67 | $s = "Error: (".$s.")" or $s = 'Unknown'; | ||
68 | } | ||
69 | print "$s\n" unless ($help); | ||
70 | print "Syntax: $0 -m mgr -h <host> -u <username> -p <password> [-cwv]\n"; | ||
71 | print "Syntax: $0 -m iax -h <host> [-v]\n"; | ||
72 | print "* --host -h Host\n"; | ||
73 | print "* --mode -m Mode - eithr 'mgr' or 'iax'\n"; | ||
74 | print " --username -u Username\n"; | ||
75 | print " --password -p Password\n"; | ||
76 | print " --port -P n Port (if not using $mgr_port for manager or $iax_port for IAX)\n"; | ||
77 | print " --warning xxx=n Return warning if > n channels of type xxx.\n"; | ||
78 | print " --critical xxx=n Return critical if > n channels of type xxx.\n"; | ||
79 | print " --verbose -v Verbose\n"; | ||
80 | print " --help -h This help\n"; | ||
81 | exit(3); | ||
82 | } | ||
83 | |||
84 | Getopt::Long::Configure('bundling'); | ||
85 | GetOptions | ||
86 | ("p=s" => \$password, "password=s" => \$password, | ||
87 | "u=s" => \$username, "username=s" => \$username, | ||
88 | "h=s" => \$host, "host=s" => \$host, | ||
89 | "P=i" => \$port, "port=i" => \$port, | ||
90 | "H" => \$help, "help" => \$help, | ||
91 | "v" => \$verbose, "verbose" => \$verbose, | ||
92 | "m=s" => \$mode, "mode=s" => \$mode, | ||
93 | "critical=s" => \$critical, "warning=s" => \$warning); | ||
94 | |||
95 | syntax("Help:") if ($help); | ||
96 | syntax("Missing host") unless (defined($host)); | ||
97 | syntax("Missing mode") unless (defined($mode)); | ||
98 | if ($mode =~ /^iax$/i) { | ||
99 | print "Running in IAX mode\n" if ($verbose); | ||
100 | $runmode = 1; | ||
101 | } elsif ($mode =~ /^mgr$/i) { | ||
102 | print "Running in Manager mode\n" if ($verbose); | ||
103 | $runmode = 2; | ||
104 | } else { | ||
105 | syntax("Unknown mode $mode") | ||
106 | } | ||
107 | |||
108 | ############################################################################## | ||
109 | |||
110 | if ($runmode == 2) { | ||
111 | $port = $mgr_port; | ||
112 | syntax("Missing username") unless (defined($username)); | ||
113 | syntax("Missing password") unless (defined($password)); | ||
114 | if (defined($warning)) { | ||
115 | foreach $s (split(/,/, $warning)) { | ||
116 | syntax("Warning value given, $s, is invalid") | ||
117 | unless ($s =~ /^(\w+)=(\d+)$/); | ||
118 | $warnval{$1} = $2; | ||
119 | print "Clear to give WARNING after $2 connections on $1\n" if ($verbose); | ||
120 | } | ||
121 | } | ||
122 | if (defined($critical)) { | ||
123 | foreach $s (split(/,/, $critical)) { | ||
124 | syntax("Critical value given, $s, is invalid") | ||
125 | unless ($s =~ /^(\w+)=(\d+)$/); | ||
126 | $critval{$1} = $2; | ||
127 | print "Clear to give CRITICAL after $2 connections on $1\n" if ($verbose); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | print "Connecting to $host:$port\n" if ($verbose); | ||
132 | unless ($sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $port, Proto => 'tcp')) { | ||
133 | print("Could not connect to asterisk server ".$host.":".$port."\n"); | ||
134 | exit(2); | ||
135 | } | ||
136 | print "Connected to $host:$port\n" if ($verbose); | ||
137 | $version = <$sock>; | ||
138 | print $version if ($verbose); | ||
139 | |||
140 | print $sock "Action: Login\r\nUsername: $username\r\nSecret: $password\r\nEvents: off\r\n\r\n"; | ||
141 | print "Action: Login\r\nUsername: $username\r\nSecret: $password\r\n\r\n" if ($verbose); | ||
142 | $response = <$sock>; | ||
143 | $message = <$sock>; | ||
144 | $s = <$sock>; | ||
145 | print $response.$message if ($verbose); | ||
146 | print $s if ($verbose); | ||
147 | |||
148 | exit(1) unless ($response =~ m/^Response:\s+(.*)$/i); | ||
149 | exit(1) unless ($1 =~ m/Success/i); | ||
150 | |||
151 | print $sock "Action: Status\r\n\r\n"; | ||
152 | print "Action: Status\r\n\r\n" if ($verbose); | ||
153 | |||
154 | $response = <$sock>; | ||
155 | $message = <$sock>; | ||
156 | print $response.$message if ($verbose); | ||
157 | |||
158 | &unknown("Unknown answer $response (wanted Response: something)") unless ($response =~ m/^Response:\s+(.*)$/i); | ||
159 | &unknown("$response didn't say Success") unless ($1 =~ m/Success/i); | ||
160 | &unknown("Unknown answer $response (wanted Message: something)") unless ($message =~ m/^Message:\s+(.*)$/i); | ||
161 | &unknown("didn't understand message $message") unless ($1 =~ m/Channel status will follow/i); | ||
162 | |||
163 | $stop=0; | ||
164 | while (($stop == 0) && ($line = <$sock>)) { | ||
165 | print "$line" if ($verbose); | ||
166 | if ($line =~ m/Channel:\s+(\w+)\//) { | ||
167 | $channels{$1}++; | ||
168 | print "Found $1 channel\n" if ($verbose); | ||
169 | } | ||
170 | if ($line =~ m/Event:\s*StatusComplete/i) { | ||
171 | $stop++; | ||
172 | } | ||
173 | } | ||
174 | |||
175 | # Log out | ||
176 | print $sock "Action: Logoff\r\n\r\n"; | ||
177 | |||
178 | undef($s); | ||
179 | foreach $key (keys %channels) { | ||
180 | $s .= " " . $key . " (" . $channels{$key} . ")"; | ||
181 | } | ||
182 | |||
183 | foreach $key (keys %critval) { | ||
184 | print "key = $key\n" if ($verbose); | ||
185 | if (defined($channels{$key}) && ($channels{$key} > $critval{$key})) { | ||
186 | $exitcode = 2; | ||
187 | $cause .= $channels{$key} . " $key channels detected. "; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | if ($exitcode < 2) { | ||
192 | foreach $key (keys %warnval) { | ||
193 | print "key = $key\n" if ($verbose); | ||
194 | if (defined($channels{$key}) && ($channels{$key} > $warnval{$key})) { | ||
195 | $exitcode = 1; | ||
196 | $cause .= $channels{$key} . " $key channels detected. "; | ||
197 | } | ||
198 | } | ||
199 | } | ||
200 | |||
201 | if ($exitcode == 0) { | ||
202 | print "OK "; | ||
203 | } elsif ($exitcode == 1) { | ||
204 | print "WARNING "; | ||
205 | } elsif ($exitcode == 2) { | ||
206 | print "CRITICAL "; | ||
207 | } elsif ($exitcode > 2) { | ||
208 | print "UNKNOWN "; | ||
209 | } | ||
210 | if (defined($s)) { | ||
211 | $cause .= " Channels:$s"; | ||
212 | } else { | ||
213 | $cause .= " (idle)"; | ||
214 | } | ||
215 | |||
216 | print $cause; | ||
217 | |||
218 | print "\n" if ($verbose); | ||
219 | |||
220 | exit($exitcode); | ||
221 | } elsif ($runmode == 1) { | ||
222 | $port = $iax_port; | ||
223 | |||
224 | socket(PING, PF_INET, SOCK_DGRAM, getprotobyname("udp")); | ||
225 | |||
226 | $msg = pack "H24", $iax_src_call . $iax_dst_call . $iax_timestamp . | ||
227 | $iax_outbound_seq . $iax_inbound_seq . $iax_type . $iax_type; | ||
228 | |||
229 | $ipaddr = inet_aton($host); | ||
230 | $sendto = sockaddr_in($port,$ipaddr); | ||
231 | |||
232 | send(PING, $msg, 0, $sendto) == length($msg) or die "cannot send to $host : $port : $!\n"; | ||
233 | |||
234 | eval { | ||
235 | local $SIG{ALRM} = sub { die("alarm time out"); }; | ||
236 | alarm $iax_timeout; | ||
237 | |||
238 | while (1) { | ||
239 | $recvfrom = recv(PING, $msg, $iax_maxlen, 0) or die "recv: $!"; | ||
240 | ($port, $ipaddr) = sockaddr_in($recvfrom); | ||
241 | $respaddr = inet_ntoa($ipaddr); | ||
242 | $iax_answer++; | ||
243 | # print "Response from $respaddr : $port\n"; | ||
244 | } | ||
245 | |||
246 | }; | ||
247 | |||
248 | if ($iax_answer) { | ||
249 | if ($iax_answer == 1) { | ||
250 | $reply = "reply"; | ||
251 | } else { | ||
252 | $reply = "replies"; | ||
253 | } | ||
254 | &ok("Got $iax_answer $reply"); | ||
255 | } else { | ||
256 | &error("Got no reply"); | ||
257 | } | ||
258 | } | ||
259 | |||