mirror of https://github.com/sipwise/www_admin.git
You now can search by uuid (either caller or callee) and call-id, independently from a subscriber.3.4
parent
20921081e3
commit
7d34bff60f
@ -0,0 +1,206 @@
|
||||
package admin::Controller::sipanalysis;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use base 'Catalyst::Controller';
|
||||
use admin::Utils;
|
||||
use HTML::Entities;
|
||||
|
||||
=head1 NAME
|
||||
|
||||
admin::Controller::sipcanalysis- Catalyst Controller
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This provides functionality for analyzing SIP traffic
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
=head2 index
|
||||
|
||||
Display search form.
|
||||
|
||||
=cut
|
||||
|
||||
sub index : Private {
|
||||
my ( $self, $c ) = @_;
|
||||
$c->stash->{template} = 'tt/sipanalysis.tt';
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 search
|
||||
|
||||
Search for SIP sessions and display results.
|
||||
|
||||
=cut
|
||||
|
||||
sub search : Local {
|
||||
my ( $self, $c ) = @_;
|
||||
my $limit = 10;
|
||||
my %filter;
|
||||
|
||||
$c->stash->{template} = 'tt/sipanalysis.tt';
|
||||
|
||||
if($c->request->params->{use_session}) {
|
||||
%filter = %{ $c->session->{search_filter} }
|
||||
if defined $c->session->{search_filter};
|
||||
} else {
|
||||
foreach my $sf (qw(uuid call_id)) {
|
||||
if(defined $c->request->params->{'search_'.$sf}
|
||||
and length $c->request->params->{'search_'.$sf})
|
||||
{
|
||||
$filter{$sf} = $c->request->params->{'search_'.$sf} || '';
|
||||
}
|
||||
}
|
||||
$c->session->{search_filter} = { %filter };
|
||||
}
|
||||
|
||||
foreach my $sf (qw(uuid call_id)) {
|
||||
# set values for webform
|
||||
$c->stash->{'search_'.$sf} = $filter{$sf};
|
||||
|
||||
next unless defined $filter{$sf};
|
||||
}
|
||||
|
||||
my $offset = $c->request->params->{offset} || 0;
|
||||
$offset = 0 if $offset !~ /^\d+$/;
|
||||
|
||||
my $calls;
|
||||
return unless $c->model('Provisioning')->call_prov( $c, 'voip', 'search_sipstat_calls',
|
||||
{ filter => { %filter,
|
||||
# limit => $limit,
|
||||
# offset => $limit * $offset
|
||||
}
|
||||
},
|
||||
\$calls
|
||||
);
|
||||
$c->stash->{searched} = 1;
|
||||
|
||||
# TODO: pagination goes here
|
||||
|
||||
$c->stash->{calls} = $calls;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub pcap : Local {
|
||||
my ( $self, $c ) = @_;
|
||||
|
||||
$c->stash->{template} = 'tt/sipanalysis.tt';
|
||||
my $callid = $c->request->params->{callid};
|
||||
|
||||
my $packets;
|
||||
return unless $c->model('Provisioning')->call_prov( $c, 'voip', 'get_sipstat_packets',
|
||||
{
|
||||
callid => $callid,
|
||||
},
|
||||
\$packets
|
||||
);
|
||||
my $pcap = admin::Utils::generate_pcap($packets);
|
||||
my $filename = $callid . '.pcap';
|
||||
$c->stash->{current_view} = 'Plain';
|
||||
$c->stash->{content_type} = 'application/octet-stream';
|
||||
$c->stash->{content_disposition} = qq[attachment; filename="$filename"];
|
||||
$c->stash->{content} = eval { $pcap };
|
||||
return;
|
||||
}
|
||||
|
||||
sub callmap_png : Local {
|
||||
my ( $self, $c ) = @_;
|
||||
$c->stash->{template} = 'tt/sipanalysis_call.tt';
|
||||
|
||||
my $callid = $c->request->params->{callid};
|
||||
$c->stash->{callid} = $callid;
|
||||
|
||||
my $calls;
|
||||
return unless $c->model('Provisioning')->call_prov( $c, 'voip', 'get_sipstat_packets',
|
||||
{
|
||||
callid => $callid,
|
||||
},
|
||||
\$calls
|
||||
);
|
||||
my $png = admin::Utils::generate_callmap_png($c, $calls);
|
||||
my $filename = $callid . '.png';
|
||||
$c->stash->{current_view} = 'Plain';
|
||||
$c->stash->{content_type} = 'image/png';
|
||||
$c->stash->{content_disposition} = qq[attachment; filename="$filename"];
|
||||
$c->stash->{content} = eval { $png };
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub callmap : Local {
|
||||
my ( $self, $c ) = @_;
|
||||
$c->stash->{template} = 'tt/sipanalysis_call.tt';
|
||||
|
||||
my $callid = $c->request->params->{callid};
|
||||
$c->stash->{callid} = $callid;
|
||||
|
||||
my $calls;
|
||||
return unless $c->model('Provisioning')->call_prov( $c, 'voip', 'get_sipstat_packets',
|
||||
{
|
||||
callid => $callid,
|
||||
},
|
||||
\$calls
|
||||
);
|
||||
$c->stash->{canvas} = admin::Utils::generate_callmap($c, $calls);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
sub packet : Local {
|
||||
my ( $self, $c ) = @_;
|
||||
$c->stash->{template} = 'tt/sipanalysis_call.tt';
|
||||
|
||||
my $pkgid = $c->request->params->{pkgid};
|
||||
|
||||
my $pkg;
|
||||
return unless $c->model('Provisioning')->call_prov( $c, 'voip', 'get_sipstat_packet',
|
||||
{
|
||||
packetid => $pkgid,
|
||||
},
|
||||
\$pkg
|
||||
);
|
||||
|
||||
$pkg->{payload} = encode_entities($pkg->{payload});
|
||||
$pkg->{payload} =~ s/^([^\n]+)\n/<b>$1<\/b>\n/;
|
||||
$pkg->{payload} = $pkg->{src_ip}.':'.$pkg->{src_port}.' → '. $pkg->{dst_ip}.':'.$pkg->{dst_port}.'<br/><br/>'.$pkg->{payload};
|
||||
$pkg->{payload} =~ s/\n([a-zA-Z0-9\-_]+\:)/\n<b>$1<\/b>/g;
|
||||
$pkg->{payload} =~ s/\r?\n/<br\/>/g;
|
||||
$c->stash->{current_view} = 'Plain';
|
||||
$c->stash->{content_type} = 'text/html';
|
||||
$c->stash->{content} = eval { $pkg->{payload} };
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
=head1 BUGS AND LIMITATIONS
|
||||
|
||||
=over
|
||||
|
||||
=item currently none
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
Provisioning model, Catalyst
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over
|
||||
|
||||
=item Andreas Granig <agranig@sipwise.com>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
The subscriber controller is Copyright (c) 2007-2012 Sipwise GmbH,
|
||||
Austria. You should have received a copy of the licences terms together
|
||||
with the software.
|
||||
|
||||
=cut
|
||||
|
||||
1;
|
||||
@ -0,0 +1,93 @@
|
||||
<h3>Find SIP Sessions</h3>
|
||||
<ul class="cleanlist">
|
||||
<form action="/sipanalysis/search" method="post">
|
||||
<li class="ui-state-default">
|
||||
<div class="span-3">
|
||||
<label class="search_label" for="search_by_uuid">UUID:</label>
|
||||
</div>
|
||||
<div class="span-5">
|
||||
<input type="text" size="50" id="search_by_uuid" name="search_uuid" value="[% search_uuid %]"
|
||||
title="search by source or destination UUID" />
|
||||
</div>
|
||||
</li>
|
||||
<li class="ui-state-default">
|
||||
<div class="span-3">
|
||||
<label class="search_label" for="search_by_call_id">Call-ID:</label>
|
||||
</div>
|
||||
|
||||
<div class="span-5">
|
||||
<input type="text" size="50" id="search_by_call_id" name="search_call_id" value="[% search_callid %]"
|
||||
title="search by the SIP Call-ID" />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="hspace-20"></div>
|
||||
<button name="submit" class="button-search">Search</button>
|
||||
</form>
|
||||
<br/>
|
||||
|
||||
<div class="hspace-20"></div>
|
||||
[% IF searched %]
|
||||
<h3>SIP Sessions</h3>
|
||||
<ul class="cleanlist">
|
||||
[% IF !calls.defined || calls.size == 0 %]
|
||||
<li class="ui-state-default">
|
||||
<div class="span-14">No SIP sessions found.</div>
|
||||
</li>
|
||||
[% ELSE %]
|
||||
<li class="ui-state-default">
|
||||
<div class="span-4">Timestamp</div>
|
||||
<div class="span-10">Call-ID</div>
|
||||
<div class="span-2 last">Method</div>
|
||||
</li>
|
||||
[% END %]
|
||||
[% FOREACH call IN calls %]
|
||||
<li class="ui-state-default">
|
||||
<div class="span-4">[% call.timestamp %]</div>
|
||||
<div class="span-10"><a href="callmap?callid=[% call.call_id %]">[% IF call.call_id.length > 50 %][% call.call_id.substr(0, 50) %]...[% ELSE %][% call.call_id %][% END %]</a></div>
|
||||
<div class="span-2 last">[% call.method %]</div>
|
||||
</li>
|
||||
[% END %]
|
||||
</ul>
|
||||
|
||||
[% IF 0 %]
|
||||
[% IF pagination %]
|
||||
<div class="pagination">
|
||||
<ul>
|
||||
[% IF offset == 0 %]
|
||||
<li class="disablepage">« prev</li>
|
||||
[% ELSE %]
|
||||
<li class="nextpage">
|
||||
<a href="/subscriber/search?use_session=1&offset=[% offset - 1 %]">« prev</a>
|
||||
</li>
|
||||
[% END %]
|
||||
[% FOREACH pagine = pagination %]
|
||||
[% IF pagine.offset == offset %]
|
||||
<li class="currentpage">
|
||||
[% pagine.offset + 1 %]
|
||||
</li>
|
||||
[% ELSIF pagine.offset == -1 %]
|
||||
...
|
||||
[% ELSE %]
|
||||
<li>
|
||||
<a href="/subscriber/search?use_session=1&offset=[% pagine.offset %]">[% pagine.offset + 1 %]</a>
|
||||
</li>
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% IF offset >= max_offset %]
|
||||
<li class="disablepage">
|
||||
next »
|
||||
</li>
|
||||
[% ELSE %]
|
||||
<li class="nextpage">
|
||||
<a href="/subscriber/search?use_session=1&offset=[% offset + 1 %]">next »</a>
|
||||
</li>
|
||||
[% END %]
|
||||
</ul>
|
||||
</div>
|
||||
[% END %]
|
||||
[% END %]
|
||||
|
||||
|
||||
[% END %]
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
<script type="text/javascript" src="/js/modal.popup.js"></script>
|
||||
<script type="text/javascript">
|
||||
function pkgPopup(pkgid) {
|
||||
// http://www.jquerypopup.com/documentation.php
|
||||
modalPopup("center", 100, 640, 10, "#666666", 40, "#FFFFFF", "#000000", 4, 5, 300,
|
||||
"packet?pkgid="+pkgid,
|
||||
"/static/images/loader.gif");
|
||||
}
|
||||
</script>
|
||||
|
||||
<h3 id="calldata">Call Details for Call-ID [% callid %]</h3>
|
||||
|
||||
<div style="clear:both"></div>
|
||||
<a href="/sipanalysis"><span class="button-back">Back</span></a>
|
||||
<a href="pcap?callid=[% callid %]"><span class="button-download">Download PCAP</span></a>
|
||||
<div style="clear:both"></div>
|
||||
|
||||
<image src="callmap_png?callid=[% callid %]" width="[% canvas.width %]" height="[% canvas.height %]" usemap="#diamap" />
|
||||
<map name="diamap">
|
||||
[% FOREACH area IN canvas.areas %]
|
||||
<area shape="rect" coords="[% area.coords %]" href="javascript:pkgPopup([% area.id %])" />
|
||||
[% END %]
|
||||
</map>
|
||||
Loading…
Reference in new issue