Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7313165
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
97 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/status/images/30/Nokia810.png b/images/30/Nokia810.png
similarity index 100%
rename from status/images/30/Nokia810.png
rename to images/30/Nokia810.png
diff --git a/status/images/30/aastra.png b/images/30/aastra.png
similarity index 100%
rename from status/images/30/aastra.png
rename to images/30/aastra.png
diff --git a/status/images/30/asterisk.png b/images/30/asterisk.png
similarity index 100%
rename from status/images/30/asterisk.png
rename to images/30/asterisk.png
diff --git a/status/images/30/audiocodes-mp124.png b/images/30/audiocodes-mp124.png
similarity index 100%
rename from status/images/30/audiocodes-mp124.png
rename to images/30/audiocodes-mp124.png
diff --git a/status/images/30/avm-fritzbox-wlan.png b/images/30/avm-fritzbox-wlan.png
similarity index 100%
rename from status/images/30/avm-fritzbox-wlan.png
rename to images/30/avm-fritzbox-wlan.png
diff --git a/status/images/30/avm-fritzbox-wlan2.png b/images/30/avm-fritzbox-wlan2.png
similarity index 100%
rename from status/images/30/avm-fritzbox-wlan2.png
rename to images/30/avm-fritzbox-wlan2.png
diff --git a/status/images/30/budgetone100.png b/images/30/budgetone100.png
similarity index 100%
rename from status/images/30/budgetone100.png
rename to images/30/budgetone100.png
diff --git a/status/images/30/cirpack.png b/images/30/cirpack.png
similarity index 100%
rename from status/images/30/cirpack.png
rename to images/30/cirpack.png
diff --git a/status/images/30/cisco-5380.png b/images/30/cisco-5380.png
similarity index 100%
rename from status/images/30/cisco-5380.png
rename to images/30/cisco-5380.png
diff --git a/status/images/30/cisco-7960.png b/images/30/cisco-7960.png
similarity index 100%
rename from status/images/30/cisco-7960.png
rename to images/30/cisco-7960.png
diff --git a/status/images/30/cisco-ata.png b/images/30/cisco-ata.png
similarity index 100%
rename from status/images/30/cisco-ata.png
rename to images/30/cisco-ata.png
diff --git a/status/images/30/cisco.png b/images/30/cisco.png
similarity index 100%
rename from status/images/30/cisco.png
rename to images/30/cisco.png
diff --git a/status/images/30/copperjet16162p.png b/images/30/copperjet16162p.png
similarity index 100%
rename from status/images/30/copperjet16162p.png
rename to images/30/copperjet16162p.png
diff --git a/status/images/30/draytek-vigor2600v.png b/images/30/draytek-vigor2600v.png
similarity index 100%
rename from status/images/30/draytek-vigor2600v.png
rename to images/30/draytek-vigor2600v.png
diff --git a/status/images/30/draytek-vigor2600vg.png b/images/30/draytek-vigor2600vg.png
similarity index 100%
rename from status/images/30/draytek-vigor2600vg.png
rename to images/30/draytek-vigor2600vg.png
diff --git a/status/images/30/draytek-vigor2800g.png b/images/30/draytek-vigor2800g.png
similarity index 100%
rename from status/images/30/draytek-vigor2800g.png
rename to images/30/draytek-vigor2800g.png
diff --git a/status/images/30/draytek-vigor2900g.png b/images/30/draytek-vigor2900g.png
similarity index 100%
rename from status/images/30/draytek-vigor2900g.png
rename to images/30/draytek-vigor2900g.png
diff --git a/status/images/30/eStara.png b/images/30/eStara.png
similarity index 100%
rename from status/images/30/eStara.png
rename to images/30/eStara.png
diff --git a/status/images/30/ekiga.png b/images/30/ekiga.png
similarity index 100%
rename from status/images/30/ekiga.png
rename to images/30/ekiga.png
diff --git a/status/images/30/eyebeam.png b/images/30/eyebeam.png
similarity index 100%
rename from status/images/30/eyebeam.png
rename to images/30/eyebeam.png
diff --git a/status/images/30/handytone.png b/images/30/handytone.png
similarity index 100%
rename from status/images/30/handytone.png
rename to images/30/handytone.png
diff --git a/status/images/30/hitachi-wip5000-2.png b/images/30/hitachi-wip5000-2.png
similarity index 100%
rename from status/images/30/hitachi-wip5000-2.png
rename to images/30/hitachi-wip5000-2.png
diff --git a/status/images/30/hitachi-wip5000-3.png b/images/30/hitachi-wip5000-3.png
similarity index 100%
rename from status/images/30/hitachi-wip5000-3.png
rename to images/30/hitachi-wip5000-3.png
diff --git a/status/images/30/hitachi-wip5000.png b/images/30/hitachi-wip5000.png
similarity index 100%
rename from status/images/30/hitachi-wip5000.png
rename to images/30/hitachi-wip5000.png
diff --git a/status/images/30/innomedia-mta5000.png b/images/30/innomedia-mta5000.png
similarity index 100%
rename from status/images/30/innomedia-mta5000.png
rename to images/30/innomedia-mta5000.png
diff --git a/status/images/30/ipDialog.png b/images/30/ipDialog.png
similarity index 100%
rename from status/images/30/ipDialog.png
rename to images/30/ipDialog.png
diff --git a/status/images/30/linksys-pap2-vert.png b/images/30/linksys-pap2-vert.png
similarity index 100%
rename from status/images/30/linksys-pap2-vert.png
rename to images/30/linksys-pap2-vert.png
diff --git a/status/images/30/linksys-pap2.png b/images/30/linksys-pap2.png
similarity index 100%
rename from status/images/30/linksys-pap2.png
rename to images/30/linksys-pap2.png
diff --git a/status/images/30/messenger.png b/images/30/messenger.png
similarity index 100%
rename from status/images/30/messenger.png
rename to images/30/messenger.png
diff --git a/status/images/30/nokia.png b/images/30/nokia.png
similarity index 100%
rename from status/images/30/nokia.png
rename to images/30/nokia.png
diff --git a/status/images/30/session.png b/images/30/session.png
similarity index 100%
rename from status/images/30/session.png
rename to images/30/session.png
diff --git a/status/images/30/siemens-3610.png b/images/30/siemens-3610.png
similarity index 100%
rename from status/images/30/siemens-3610.png
rename to images/30/siemens-3610.png
diff --git a/status/images/30/sipps.png b/images/30/sipps.png
similarity index 100%
rename from status/images/30/sipps.png
rename to images/30/sipps.png
diff --git a/status/images/30/sjphone.png b/images/30/sjphone.png
similarity index 100%
rename from status/images/30/sjphone.png
rename to images/30/sjphone.png
diff --git a/status/images/30/snom100.png b/images/30/snom100.png
similarity index 100%
rename from status/images/30/snom100.png
rename to images/30/snom100.png
diff --git a/status/images/30/snom200.png b/images/30/snom200.png
similarity index 100%
rename from status/images/30/snom200.png
rename to images/30/snom200.png
diff --git a/status/images/30/snom320-front.png b/images/30/snom320-front.png
similarity index 100%
rename from status/images/30/snom320-front.png
rename to images/30/snom320-front.png
diff --git a/status/images/30/snom320-left.png b/images/30/snom320-left.png
similarity index 100%
rename from status/images/30/snom320-left.png
rename to images/30/snom320-left.png
diff --git a/status/images/30/snom320.png b/images/30/snom320.png
similarity index 100%
rename from status/images/30/snom320.png
rename to images/30/snom320.png
diff --git a/status/images/30/snom360-front.png b/images/30/snom360-front.png
similarity index 100%
rename from status/images/30/snom360-front.png
rename to images/30/snom360-front.png
diff --git a/status/images/30/snom360-left.png b/images/30/snom360-left.png
similarity index 100%
rename from status/images/30/snom360-left.png
rename to images/30/snom360-left.png
diff --git a/status/images/30/snom360.png b/images/30/snom360.png
similarity index 100%
rename from status/images/30/snom360.png
rename to images/30/snom360.png
diff --git a/status/images/30/spa2000.png b/images/30/spa2000.png
similarity index 100%
rename from status/images/30/spa2000.png
rename to images/30/spa2000.png
diff --git a/status/images/30/unknown.png b/images/30/unknown.png
similarity index 100%
rename from status/images/30/unknown.png
rename to images/30/unknown.png
diff --git a/status/images/30/unknown3.png b/images/30/unknown3.png
similarity index 100%
rename from status/images/30/unknown3.png
rename to images/30/unknown3.png
diff --git a/status/images/30/vizufon.png b/images/30/vizufon.png
similarity index 100%
rename from status/images/30/vizufon.png
rename to images/30/vizufon.png
diff --git a/status/images/30/vizufon2.png b/images/30/vizufon2.png
similarity index 100%
rename from status/images/30/vizufon2.png
rename to images/30/vizufon2.png
diff --git a/status/images/30/webstarepx2203.png b/images/30/webstarepx2203.png
similarity index 100%
rename from status/images/30/webstarepx2203.png
rename to images/30/webstarepx2203.png
diff --git a/status/images/30/xten.png b/images/30/xten.png
similarity index 100%
rename from status/images/30/xten.png
rename to images/30/xten.png
diff --git a/status/images/30/zoep.png b/images/30/zoep.png
similarity index 100%
rename from status/images/30/zoep.png
rename to images/30/zoep.png
diff --git a/status/images/30/zyxel-p2000.png b/images/30/zyxel-p2000.png
similarity index 100%
rename from status/images/30/zyxel-p2000.png
rename to images/30/zyxel-p2000.png
diff --git a/images/ClassicNode.png b/images/ClassicNode.png
new file mode 100644
index 0000000..1e5eb99
Binary files /dev/null and b/images/ClassicNode.png differ
diff --git a/images/ClassicRectangle.png b/images/ClassicRectangle.png
new file mode 100644
index 0000000..3a31906
Binary files /dev/null and b/images/ClassicRectangle.png differ
diff --git a/images/Node.png b/images/Node.png
new file mode 100644
index 0000000..cb5bc5e
Binary files /dev/null and b/images/Node.png differ
diff --git a/images/P2PDNS.png b/images/P2PDNS.png
new file mode 100644
index 0000000..79d9a06
Binary files /dev/null and b/images/P2PDNS.png differ
diff --git a/images/P2PThorTitle.png b/images/P2PThorTitle.png
new file mode 100644
index 0000000..3f2a582
Binary files /dev/null and b/images/P2PThorTitle.png differ
diff --git a/images/thorNetworkImage.php b/images/thorNetworkImage.php
new file mode 100644
index 0000000..72e8cb4
--- /dev/null
+++ b/images/thorNetworkImage.php
@@ -0,0 +1,132 @@
+<?php
+include("../global.inc");
+page_open(
+ array("sess" => "CDRTool_Session",
+ "auth" => "CDRTool_Auth",
+ "perm" => "CDRTool_Perm"
+ ));
+
+$perm->check("statistics");
+
+class ThorNetwork {
+ var $imgsize = 630;
+
+ function ThorNetwork($node='demo.example.com') {
+
+ if ($fp = fsockopen ($node, "2000", $errno, $errstr, 5)) {
+ fwrite($fp,"get\r\n");
+ while(!feof($fp)) {
+ $json.=fgets ($fp,200000);
+ }
+ fclose($fp);
+ } else {
+ print "Error: cannot connect.\n";
+ exit;
+ }
+
+ $this->nodes=json_decode(trim($json),1);
+ }
+
+ function buildImage() {
+ $img = imagecreatetruecolor($this->imgsize, $this->imgsize);
+ $white = imagecolorallocate($img, 255, 255, 255);
+ $black = imagecolorallocate($img, 0, 0, 0);
+
+ imagefill($img, 0, 0, $white);
+
+ $c=count($this->nodes);
+ imagestring ($img, 5, 20, 20, "SIP UA distribution", $black);
+
+ $cx=$this->imgsize/2;
+ $cy=$cx;
+
+ $radius=0.7*$cx;
+
+ // Get ThorNode image
+ $node_img = @imagecreatefrompng('Node.png');
+ list($nw, $nh) = getimagesize('Node.png');
+
+ // Get ClassicNode image
+ $cnode_img = @imagecreatefrompng('ClassicNode.png');
+ list($cnw, $cnh) = getimagesize('ClassicNode.png');
+
+ // Get Cloud Image
+ $cloud_img = @imagecreatefrompng('InternetCloud.png');
+ list($cw, $ch) = getimagesize('InternetCloud.png');
+
+ // Get Thor rectangle image
+ $thor_img = @imagecreatefrompng('P2PThorTitle.png');
+ list($tw, $th) = getimagesize('P2PThorTitle.png');
+
+ // Get Classic rectangle image
+ $cthor_img = @imagecreatefrompng('ClassicRectangle.png');
+ list($ctw, $cth) = getimagesize('ClassicRectangle.png');
+
+ if (count($this->nodes)) {
+ if (count($this->nodes) > 1) {
+ imagecopy ($img,$thor_img, $this->imgsize/2-$tw/2, $this->imgsize/2-$th/2-5, 0, 0, $tw, $th);
+ imagecopy ($img,$cloud_img, $this->imgsize/2-$cw/2, $this->imgsize/2-$ch/2, 0, 0, $cw, $ch);
+
+ $dash=false;
+ $dashsize=2;
+
+ for ($angle=0; $angle<=(180+$dashsize); $angle+=$dashsize) {
+ $x = ($radius * cos(deg2rad($angle)));
+ $y = ($radius * sin(deg2rad($angle)));
+
+ if ($dash) {
+ imageline($img, $cx+$px, $cy+$py, $cx+$x, $cy+$y, 'black');
+ imageline($img, $cx-$px, $cx-$py, $cx-$x, $cy-$y, 'black');
+ }
+
+ $dash=!$dash;
+ $px=$x;
+ $py=$y;
+ }
+ } else {
+ imagecopy ($img,$cthor_img, $this->imgsize/2-$ctw/2, $this->imgsize/2-$cth/2+50, 0, 0, $ctw, $cth);
+ }
+
+ $dashsize=360/count($this->nodes);
+ $j=0;
+
+ $node_names=array_keys($this->nodes);
+
+ for ($angle=0; $angle<360; $angle+=$dashsize) {
+
+ $x = ($radius * cos(deg2rad($angle)));
+ $y = ($radius * sin(deg2rad($angle)));
+
+ $text = $node_names[$j];
+ $px=$x;
+ $py=$y;
+
+ if (count($this->nodes) > 1) {
+ if (($angle >= 120 && $angle < 240)) {
+ imagestring ($img, 3, $cx+$px-70, $cy+$py-60, $text, $black);
+ } else {
+ imagestring ($img, 3, $cx+$px-110, $cy+$py-30, $text, $black);
+ }
+ imagecopy ($img,$node_img, $cx+$px-$nw/2+7, $cy+$py-$nh/2+5, 0, 0, $nw-20, $nh-20);
+ } else {
+ imagecopy ($img,$cnode_img, $this->imgsize/2-$cnw/2-100, $this->imgsize/2-$cnh/2, 0, 0, $cnw, $cnh);
+ imagestring ($img, 3, $this->imgsize/2-$cnw/2-60, $this->imgsize/2-$cnh/2+220, $text, $black);
+ }
+ $j++;
+
+ }
+ }
+
+ return $img;
+ }
+}
+
+$ThorNetwork = new ThorNetwork($_REQUEST['node']);
+$img=$ThorNetwork->buildImage();
+
+header("Content-type: image/png");
+imagepng($img);
+imagedestroy($img);
+
+page_close();
+?>
diff --git a/media_sessions_lib.phtml b/media_sessions_lib.phtml
index b9d3cb1..70e9313 100644
--- a/media_sessions_lib.phtml
+++ b/media_sessions_lib.phtml
@@ -1,861 +1,861 @@
<?
class MediaSessions {
/*
connect to a mediaproxy dispatcher
get media sessions and display them
*/
var $dispatcher_port = 25061;
var $sessions = array();
var $relays = array();
var $timeout = 3;
function MediaSessions ($dispatcher='',$allowedDomains=array(),$filters=array()) {
if (!strlen($dispatcher)) return false;
global $userAgentImages;
require_once("phone_images.php");
$this->userAgentImages = $userAgentImages;
$this->filters = $filters;
$this->allowedDomains = $allowedDomains;
list($ip,$port) = explode(":",$dispatcher);
$this->dispatcher_ip = $ip;
if ($port) $this->dispatcher_port = $port;
return $this->getSessions();
}
function getSessions () {
if (!$this->dispatcher_ip) return false;
if (!$this->dispatcher_port) return false;
if ($fp = fsockopen ($this->dispatcher_ip, $this->dispatcher_port, $errno, $errstr, $this->timeout)) {
if (!count($this->allowedDomains)) {
fputs($fp, "summary\r\n");
while (!feof($fp)) {
$line = fgets($fp);
if (preg_match("/^\r\n/",$line)) {
break;
}
$this->relays[] = json_decode($line);
}
}
fputs($fp, "sessions\r\n");
while (!feof($fp)) {
$line = fgets($fp);
if (preg_match("/^\r\n/",$line)) {
break;
}
$line=json_decode($line);
if (count($this->allowedDomains)) {
list($user1,$domain1)=explode("@",$line->from_uri);
list($user2,$domain2)=explode("@",$line->to_uri);
if (!in_array($domain1,$this->allowedDomains) && !in_array($domain2,$this->allowedDomains)) {
continue;
}
}
if (strlen($this->filters['user'])) {
$user=$this->filters['user'];
if (preg_match("/$user/",$line->from_uri) ||
preg_match("/$user/",$line->to_uri)
) {
$this->sessions[] = $line;
}
} else {
$this->sessions[] = $line;
}
}
fclose($fp);
return true;
} else {
printf ("<p><font color=red>Error connecting to %s:%s: %s (%s) </font>\n",$this->dispatcher_ip,$this->dispatcher_port,$errstr,$errno);
return false;
}
}
function showSearch() {
printf ("<form method=post action=%s>
<input type=text name=user value='%s'>
<input type=submit value='Search callers'>
<p>
",
$_SERVER['PHP_SELF'],
$_REQUEST['user']
);
}
function showHeader() {
print "
<html>
<head>
<title>Media sessions</title>
</head>
<body marginwidth=20 leftmargin=20 link=#000066 vlink=#006666 bgcolor=white>
<style type=\"text/css\">
<!--
.border {
border: 1px solid #999999;
border-collapse: collapse;
}
.bordertb {
border-top: 1px solid #999999;
border-bottom: 1px solid #999999;
border-collapse: collapse;
}
body {
font-family: Verdana, Sans, Arial, Helvetica, sans-serif;
font-size: 10pt;
color: gray;
}
p {
font-family: Verdana, Sans, Arial, Helvetica, sans-serif;
font-size: 8pt;
color: gray;
}
pre {
font-family: Lucida Console, Courier;
font-size: 10pt;
color: black;
}
td {
font-family: Verdana, Sans, Arial, Helvetica, sans-serif;
font-size: 8pt;
vertical-align: top;
color: #444444;
}
th {
font-family: Verdana, Sans, Arial, Helvetica, sans-serif;
font-size: 8pt;
vertical-align: bottom;
color: black;
}
-->
</style>
";
}
function showFooter() {
print "<a href=http://www.ag-projects.com><img src=images/PoweredbyAGProjects.gif border=0></a>";
print "
</body>
</html>
";
}
function show() {
$this->showHeader();
print "<h3>Media sessions</h3>";
$this->showSearch();
if (!count($this->allowedDomains)) {
$this->showRelays();
}
$this->showSessions();
$this->showFooter();
}
function showRelays() {
print "
<table border=0 class=border cellpadding=2 cellspacing=0>
<tr bgcolor=#c0c0c0 class=border align=right>
<th class=bordertb width=10px></th>
<th class=bordertb width=10px></th>
<th class=bordertb>Address</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Version</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Uptime</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Relayed traffic</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Sessions</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Streams</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Status</th>
</tr>";
$i = 1;
foreach ($this->relays as $relay) {
unset($media_types);
foreach ($relay->stream_count as $key => $value) {
$media_types++;
}
if ($media_types > 1) {
$streams = "<table border=0>";
foreach ($relay->stream_count as $key => $value) {
$streams .= sprintf("<tr><td>%s</td><td>%s</td></tr>",$key,$value);
}
$streams .= "</table>";
} else {
foreach ($relay->stream_count as $key => $value) {
$streams=sprintf("%s %s",$key,$value);
}
}
printf ("
<tr class=border align=right>
<td class=border>%d</td>
<td class=bordertb width=10px></td>
<td class=bordertb>%s</td>
<td class=bordertb width=10px></td>
<td class=bordertb>%s</td>
<td class=bordertb width=10px></td>
<td class=bordertb>%s</td>
<td class=bordertb width=10px></td>
<td class=bordertb>%s</td>
<td class=bordertb width=10px></td>
<td class=bordertb>%d</td>
<td class=bordertb width=10px></td>
<td class=bordertb valign=top>%s</td>
<td class=bordertb width=10px></td>
<td class=bordertb>%s</td>
</tr>",
$i,
$relay->ip,
$relay->version,
$this->normalizeTime($relay->uptime),
$this->normalizeTraffic($relay->bps_relayed),
$relay->session_count,
$streams,
ucfirst($relay->status)
);
$i++;
}
print "
</table>
<br />
";
}
function showSessions () {
print "
<table border=0 cellpadding=2 cellspacing=0 class=border>
<tr valign=bottom bgcolor=black>
<th rowspan=2> </th>
<th rowspan=2><font color=white>Callers</font></th>
<th rowspan=2 colspan=2><font color=white>Phones</font></th>
<th colspan=10 bgcolor=#393939><font color=white>Media Streams</font></th>
</tr>
<tr valign=bottom bgcolor=#afafaf>
<th class=border><nobr>Caller address</nobr></th>
<th class=border>Relay caller</th>
<th class=border>Relay callee</th>
<th class=border><nobr>Callee address</nobr></th>
<th class=border>Status</th>
<th class=border>Codec</th>
<th class=border>Type</th>
<th class=border>Duration</th>
<th class=border>Bytes<br>Caller</th>
<th class=border>Bytes<br>Called</th>
</tr>";
$i = 1;
foreach ($this->sessions as $session) {
$from = $session->from_uri;
$to = $session->to_uri;
$fromAgent = $session->caller_ua;
$toAgent = $session->callee_ua;
$fromImage = $this->getImageForUserAgent($fromAgent);
$toImage = $this->getImageForUserAgent($toAgent);
$sc = count($session->streams);
print "
<tr valign=top class=border>
<td class=border rowspan=$sc>$i</td>
<td class=border rowspan=$sc>
<nobr><b>From:</b> $from</nobr><br>
<nobr><b>To:</b> $to</nobr><br>
</td>
<td class=border rowspan=$sc align=center>
<img src=\"images/30/$fromImage\"
alt=\"$fromAgent\"
title=\"$fromAgent\"
ONMOUSEOVER='window.status=\"$fromAgent\";'
ONMOUSEOUT='window.status=\"\";'
border=0
/>
</td>
<td class=border rowspan=$sc align=center>
<img src=\"images/30/$toImage\"
alt=\"$toAgent\"
title=\"$toAgent\"
ONMOUSEOVER='window.status=\"$toAgent\";'
ONMOUSEOUT='window.status=\"\";'
border=0
/>
</td>";
$duration = $this->normalizeTime($session->duration);
foreach ($session->streams as $streamInfo) {
$status = $streamInfo->status;
if ($status=="idle" || $status=='hold') {
$idletime = $this->normalizeTime($streamInfo->timeout_wait);
$status = sprintf("%s %s", $status, $idletime);
}
$caller = $streamInfo->caller_remote;
$callee = $streamInfo->callee_remote;
$relay_caller = $streamInfo->caller_local;
$relay_callee = $streamInfo->callee_local;
$codec = $streamInfo->caller_codec;
$type = $streamInfo->media_type;
if ($caller == '?.?.?.?:?') {
$caller = '–'; // a dash
$align1 = 'center';
} else {
$align1 = 'left';
}
if ($callee == '?.?.?.?:?') {
$callee = '–'; // a dash
$align2 = 'center';
} else {
$align2 = 'left';
}
if ($codec == 'Unknown')
$codec = '–'; // a dash
if ($type == 'Unknown')
$type = '–'; // a dash
$bytes_in1 = $this->normalizeBytes($streamInfo->caller_bytes);
$bytes_in2 = $this->normalizeBytes($streamInfo->callee_bytes);
print "
<td class=border align=$align1>$caller</td>
<td class=border align=left>$relay_caller</td>
<td class=border align=left>$relay_callee</td>
<td class=border align=$align2>$callee</td>
<td class=border align=center><nobr>$status</nobr></td>
<td class=border align=center>$codec</td>
<td class=border align=center>$type</td>
<td class=border align=right>$duration</td>
<td class=border align=right>$bytes_in1</td>
<td class=border align=right>$bytes_in2</td>
</tr>";
}
$i++;
}
print "
</table>
<br />";
}
function normalizeBytes($bytes) {
$mb = $bytes/1024/1024.0;
$kb = $bytes/1024.0;
if ($mb >= 0.95) {
return sprintf("%.2fM", $mb);
} else if ($kb >= 1) {
return sprintf("%.2fk", $kb);
} else {
return sprintf("%d", $bytes);
}
}
function normalizeTime($period) {
$sec = $period % 60;
$min = floor($period/60);
$h = floor($min/60);
$min = $min % 60;
if ($h >= 1) {
return sprintf('%dh%02d\'%02d"', $h, $min, $sec);
} else {
return sprintf('%d\'%02d"', $min, $sec);
}
}
function normalizeTraffic($traffic) {
// input is in bytes/second
$mb = $traffic/1024/1024.0;
$kb = $traffic/1024.0;
if ($mb >= 0.95) {
return sprintf("%.2fMbps", $mb);
} else if ($kb >= 1) {
return sprintf("%.2fkbps",$kb);
} else {
return sprintf("%dbps",$traffic);
}
}
function getImageForUserAgent($agent) {
foreach ($this->userAgentImages as $agentRegexp => $image) {
if (preg_match("/$agentRegexp/i", $agent)) {
return $image;
}
}
return "unknown.png";
}
}
class MediaSessions1 {
function MediaSessions1 ($servers=array(),$allowedDomains=array()) {
$this->servers = $servers;
$this->allowedDomains = $allowedDomains;
global $userAgentImages;
require_once("phone_images.php");
$this->userAgentImages = $userAgentImages;
}
function isDomainAllowed($from,$to) {
$els = explode("@",$from);
$fromDomain = $els[1];
$els = explode("@",$to);
$toDomain = $els[1];
if (count($this->allowedDomains)) {
if (in_array($fromDomain,$this->allowedDomains) || in_array($toDomain,$this->allowedDomains)) {
return 1;
} else {
return 0;
}
} else {
return 1;
}
}
function normalizeBytes($bytes) {
$mb = $bytes/1024/1024.0;
$kb = $bytes/1024.0;
if ($mb >= 0.95) {
return sprintf("%.2fM", $mb);
} else if ($kb >= 1) {
return sprintf("%.2fk", $kb);
} else {
return sprintf("%d", $bytes);
}
}
function normalizeTime($period) {
$sec = $period % 60;
$min = floor($period/60);
$h = floor($min/60);
$min = $min % 60;
if ($h >= 1) {
return sprintf('%dh%02d\'%02d"', $h, $min, $sec);
} else {
return sprintf('%d\'%02d"', $min, $sec);
}
}
function normalizeTraffic($traffic) {
// input is in bytes/second
$traffic = $traffic * 8;
$mb = $traffic/1024/1024.0;
$kb = $traffic/1024.0;
if ($mb >= 0.95) {
return sprintf("%.2fMbps", $mb);
} else if ($kb >= 1) {
return sprintf("%.2fkbps",$kb);
} else {
return sprintf("%dbps",$traffic);
}
}
function getImageForUserAgent($agent) {
foreach ($this->userAgentImages as $agentRegexp => $image) {
if (preg_match("/$agentRegexp/i", $agent)) {
return $image;
}
}
return "unknown.png";
}
function getRTPSessions($ip, $port) {
if ($fp = fsockopen ($ip, $port, $errno, $errstr, "3") ) {
fputs($fp, "status\n");
$proxy = array('status' => 'Ok');
$crtSession = 'None';
while (!feof($fp)) {
$line = fgets($fp, 2048);
$elements = explode(" ", $line);
if ($elements[0] == 'version' && count($elements)==2) {
$proxy['version'] = $elements[1];
} else if ($elements[0] == 'proxy' && count($elements)==3) {
$proxy['sessionCount'] = $elements[1];
$traffic = explode("/", $elements[2]);
$proxy['traffic'] = array('caller' => $traffic[0],
'called' => $traffic[1],
'relayed' => $traffic[2]);
$proxy['sessions'] = array();
} else if ($elements[0]=='session' && count($elements)==7) {
if ($this->isDomainAllowed($elements[2],$elements[3])) {
$crtSession = $elements[1];
$info = array('from' => $elements[2],
'to' => $elements[3],
'fromAgent' => quoted_printable_decode($elements[4]),
'toAgent' => quoted_printable_decode($elements[5]),
'duration' => $elements[6],
'streams' => array());
$proxy['sessions'][$crtSession] = $info;
$allowed_session=1;
} else {
unset($allowed_session);
}
} else if ($elements[0] == 'stream' && count($elements)==9) {
if (!$allowed_session) continue;
$stream = array('caller' => $elements[1],
'called' => $elements[2],
'via' => $elements[3],
'bytes' => explode("/", $elements[4]),
'status' => $elements[5],
'codec' => $elements[6],
'type' => $elements[7],
'idletime' => $elements[8]);
$proxy['sessions'][$crtSession]['streams'][] = $stream;
} else {
//print "Invalid line: '$line'<br>\n";
}
}
fclose($fp);
if (!isset($proxy['version'])) {
if ($fp = fsockopen ($ip, $port, $errno, $errstr, "2") ) {
fputs($fp, "version\n");
$line = fgets($fp, 2048);
$version = trim($line);
if (!$version)
$version = 'unknown';
$proxy['version'] = $version;
fclose($fp);
}
}
return $proxy;
} else {
return array('status' => "<font color=red>$errstr</font>");
}
}
function haveSessions() {
foreach ($this->servers as $server) {
if ($this->sessions[$server]['sessionCount'] > 0) {
return True;
}
}
return False;
}
function showSummary() {
// IE seems to ignore border on <tr> elements
// that's why we used bordertb on <th> and <td>
print "
<table border=0 class=border cellpadding=2 cellspacing=0>
<tr bgcolor=#c0c0c0 class=border align=right>
<th class=bordertb width=10px></th>
<th class=bordertb width=10px></th>
<th class=bordertb>Server</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Version</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Caller traffic</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Called traffic</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Relayed traffic</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Sessions</th>
<th class=bordertb width=10px></th>
<th class=bordertb>Status</th>
</tr>";
$i = 1;
foreach ($this->servers as $server) {
list($ip, $port) = explode(":", $server);
$sessionInfo = $this->sessions[$server];
$status = $sessionInfo['status'];
if ($status=='Ok')
$version = $sessionInfo['version'];
else
$version = " ";
if ($status!='Ok' || $sessionInfo['sessionCount'] == 0) {
$caller = " ";
$called = " ";
$relayed = " ";
$sessionCount = " ";
} else {
$caller = $this->normalizeTraffic($sessionInfo['traffic']['caller']);
$called = $this->normalizeTraffic($sessionInfo['traffic']['called']);
$relayed = $this->normalizeTraffic($sessionInfo['traffic']['relayed']);
$sessionCount = $sessionInfo['sessionCount'];
}
print "
<tr class=border align=right>
<td class=border>$i</td>
<td class=bordertb width=10px></td>
<td class=bordertb>$ip</td>
<td class=bordertb width=10px></td>
<td class=bordertb>$version</td>
<td class=bordertb width=10px></td>
<td class=bordertb>$caller</td>
<td class=bordertb width=10px></td>
<td class=bordertb>$called</td>
<td class=bordertb width=10px></td>
<td class=bordertb>$relayed</td>
<td class=bordertb width=10px></td>
<td class=bordertb>$sessionCount</td>
<td class=bordertb width=10px></td>
<td class=bordertb><nobr>$status</nobr></td>
</tr>";
$i++;
}
print "
</table>
<br />
";
}
function showSessions() {
if ($this->haveSessions($this->servers, $sessions)) {
print "
<table border=0 cellpadding=2 cellspacing=0 class=border>
<tr valign=bottom bgcolor=black>
<th rowspan=2> </th>
<th rowspan=2><font color=white>Call</font></th>
<th rowspan=2 colspan=2><font color=white>Phones</font></th>
<th colspan=10 bgcolor=#393939><font color=white>Media Streams</font></th>
</tr>
<tr valign=bottom bgcolor=#afafaf>
<th class=border><nobr>Caller address</nobr></th>
<th class=border><nobr>Called address</nobr></th>
<th class=border>Via address</th>
<th class=border>Status</th>
<th class=border>Codec</th>
<th class=border>Type</th>
<th class=border>Duration</th>
<th class=border>Bytes<br>Caller</th>
<th class=border>Bytes<br>Called</th>
<th class=border>Bytes<br>Relayed</th>
</tr>";
$i = 1;
foreach ($this->servers as $server) {
$serverSessions = $this->sessions[$server]['sessions'];
foreach ($serverSessions as $id => $sessionInfo) {
$sc = count($sessionInfo['streams']);
$from = $sessionInfo['from'];
$to = $sessionInfo['to'];
$fromAgent = $sessionInfo['fromAgent'];
$toAgent = $sessionInfo['toAgent'];
$fromImage = $this->getImageForUserAgent($fromAgent);
$toImage = $this->getImageForUserAgent($toAgent);
print "
<tr valign=top class=border>
<td class=border rowspan=$sc>$i</td>
<td class=border rowspan=$sc>
<nobr><b>From:</b> $from</nobr><br>
<nobr><b>To:</b> $to</nobr><br>
</td>
<td class=border rowspan=$sc align=center>
- <img src=\"status/images/30/$fromImage\"
+ <img src=\"images/30/$fromImage\"
alt=\"$fromAgent\"
title=\"$fromAgent\"
ONMOUSEOVER='window.status=\"$fromAgent\";'
ONMOUSEOUT='window.status=\"\";'
border=0
/>
</td>
<td class=border rowspan=$sc align=center>
- <img src=\"status/images/30/$toImage\"
+ <img src=\"images/30/$toImage\"
alt=\"$toAgent\"
title=\"$toAgent\"
ONMOUSEOVER='window.status=\"$toAgent\";'
ONMOUSEOUT='window.status=\"\";'
border=0
/>
</td>";
$duration = $this->normalizeTime($sessionInfo['duration']);
foreach ($sessionInfo['streams'] as $streamInfo) {
$status = $streamInfo['status'];
if ($status=="idle" || $status=='hold') {
$idletime = $this->normalizeTime($streamInfo['idletime']);
$status = sprintf("%s %s", $status, $idletime);
}
$caller = $streamInfo['caller'];
$called = $streamInfo['called'];
$via = $streamInfo['via'];
$codec = $streamInfo['codec'];
$type = $streamInfo['type'];
if ($caller == '?.?.?.?:?') {
$caller = '–'; // a dash
$align1 = 'center';
} else {
$align1 = 'left';
}
if ($called == '?.?.?.?:?') {
$called = '–'; // a dash
$align2 = 'center';
} else {
$align2 = 'left';
}
if ($codec == 'Unknown')
$codec = '–'; // a dash
if ($type == 'Unknown')
$type = '–'; // a dash
$bytes_in1 = $this->normalizeBytes($streamInfo['bytes'][0]);
$bytes_in2 = $this->normalizeBytes($streamInfo['bytes'][1]);
$bytes_rel = $this->normalizeBytes($streamInfo['bytes'][2]);
print "
<td class=border align=$align1>$caller</td>
<td class=border align=$align2>$called</td>
<td class=border align=left>$via</td>
<td class=border align=center><nobr>$status</nobr></td>
<td class=border align=center>$codec</td>
<td class=border align=center>$type</td>
<td class=border align=right>$duration</td>
<td class=border align=right>$bytes_in1</td>
<td class=border align=right>$bytes_in2</td>
<td class=border align=right>$bytes_rel</td>
</tr>";
}
$i++;
}
}
print "
</table>
<br />";
}
}
function showHeader() {
print "
<html>
<head>
<title>Media Sessions</title>
</head>
<body marginwidth=20 leftmargin=20 link=#000066 vlink=#006666 bgcolor=white>
<style type=\"text/css\">
<!--
.border {
border: 1px solid #999999;
border-collapse: collapse;
}
.bordertb {
border-top: 1px solid #999999;
border-bottom: 1px solid #999999;
border-collapse: collapse;
}
body {
font-family: Verdana, Sans, Arial, Helvetica, sans-serif;
font-size: 10pt;
color: gray;
}
p {
font-family: Verdana, Sans, Arial, Helvetica, sans-serif;
font-size: 8pt;
color: gray;
}
pre {
font-family: Lucida Console, Courier;
font-size: 10pt;
color: black;
}
td {
font-family: Verdana, Sans, Arial, Helvetica, sans-serif;
font-size: 8pt;
vertical-align: top;
color: #444444;
}
th {
font-family: Verdana, Sans, Arial, Helvetica, sans-serif;
font-size: 8pt;
vertical-align: bottom;
color: black;
}
-->
</style>
<h2>Media Sessions</h2>
";
}
function show() {
$this->sessions = array();
foreach ($this->servers as $server) {
list($ip, $port) = explode(":", $server);
if (!$port)
$port = "25060";
$this->sessions[$server] = $this->getRTPSessions($ip, $port);
}
print "<h3>Media sessions</h3>";
$this->showSessions();
if (!count($this->allowedDomains)) {
$this->showSummary();
}
}
}
?>
diff --git a/phplib/local.inc b/phplib/local.inc
index ee49ea1..b19adef 100644
--- a/phplib/local.inc
+++ b/phplib/local.inc
@@ -1,971 +1,971 @@
<?
class CDRTool_CT_Sql extends CT_Sql {
var $database_class = "DB_CDRTool"; ## Which database to connect...
var $database_table = "active_sessions"; ## and find our session data in this table.
}
class CDRTool_Session extends Session {
var $classname = "CDRTool_Session";
var $auto_init = "setup.inc";
var $cookiename = "CDRc"; ## defaults to classname
var $magic = "bzssdgaune"; ## ID seed
var $mode = "cookie"; ## We propagate session IDs with cookies
var $fallback_mode = "get";
var $allowcache = "no";
var $allowcache_expires = "5";
var $lifetime = 0; ## 0 = do session cookies, else minutes
var $that_class = "CDRTool_CT_Sql"; ## name of data storage container
var $gc_probability = 5;
}
class CDRTool_User extends User {
var $classname = "CDRTool_User";
var $magic = "Abraacdascadabra"; ## ID seed
var $that_class = "CDRTool_CT_Sql"; ## data storage container
}
class CDRTool_Auth extends Auth {
var $classname = "CDRTool_Auth";
var $lifetime = 240;
var $database_class = "DB_CDRTool";
var $database_table = "auth_user";
function auth_loginform() {
global $sess;
global $_PHPLIB;
global $max_login_attempts;
global $CDRTool;
$username = $_POST["username"];
$sendotp = $_POST["sendotp"];
$password = $_POST["password"];
$challenge = $_POST["challenge"];
$response = $_POST["response"];
$max_login_attempts=5;
$sess->register("challenge");
if (!$challenge) {
$challenge = md5(uniqid($this->magic));
}
$query=sprintf("select * from spam where ip = '%s'",$_SERVER['REMOTE_ADDR']);
$this->db->query($query);
if ($this->db->num_rows()) {
$this->db->next_record();
$spam_login_ip = $this->db->f('ip');
$spam_login_tries = $this->db->f('tries');
$spam_login_stamp = $this->db->f('stamp');
$next_try = $spam_login_stamp+120;
$remains = $next_try-time();
$next_try = Date("Y-m-d H:i:s",$next_try);
$now = Date("Y-m-d H:i:s",time());
}
if ($remains < 0) {
$query="delete from spam where ip = '$spam_login_ip'";
if ($this->db->query("$query")) {
unset($spam_login_tries);
}
}
if ($spam_login_tries < $max_login_attempts) {
$title="Login";
if (is_readable("$CDRTool[Path]/local/header.phtml")) {
include("$CDRTool[Path]/local/header.phtml");
} else {
include("$CDRTool[Path]/header.phtml");
}
$layout = new pageLayoutLocal();
$layout->showLoginForm($this);
$layout->showFooter();
} else {
if ($spam_login_tries == $max_login_attempts) {
$log_time=Date("Y-m-d H:i:s",time());
$log_query=sprintf("insert into log (date,login,ip,description,results)
values ('%s','%s','%s','%s attempts to wrong login', 'IP blocked until %s')",
$log_time,addslashes($username),$_SERVER['REMOTE_ADDR'],$spam_login_tries,$next_try);
$this->db->query($log_query);
}
$new_stamp=time();
$query=sprintf("update spam
set tries = tries + 1
where ip = '%s' ",$_SERVER['REMOTE_ADDR']);
$this->db->query($query);
print "
<html>
<body>
<p>The current time on this system is $now.
<p>Too many wrong attempts to login, wait until
$next_try (over $remains seconds) and try again.
<p>
If you forgot your password please contact your system administrator for obtaining a new one.
</body>
</html>
";
exit;
}
}
function auth_validatelogin() {
global $d_cli, $d_card, $prepaid_login, $cust_form, $codeFilter, $aNumberFilter,$login_for;
global $CDRTool;
global $otp_error, $otpasswd;
global $verbose;
global $DATASOURCES;
$username = $_POST["username"];
$sendotp = $_POST["sendotp"];
$password = $_POST["password"];
$challenge = $_POST["challenge"];
$response = $_POST["response"];
$REMOTE_ADDR = $_SERVER["REMOTE_ADDR"];
if(isset($username)) {
$this->auth["uname"]=$username; ## This provides access for "loginform.ihtml"
}
$uid = false;
if ($username) {
$username=trim($username);
if (preg_match ("/\@/",$username)) {
$a=explode("@",$username);
$domainAuth = new DomainAuthLocal();
$ret=$domainAuth->validate($a[0],$a[1],$password);
if ($ret[0]) {
foreach ($ret[2] as $allowedDS) {
$CDRTool[dataSourcesAllowed][]=$allowedDS;
}
if ($ret[1] == "subscriber") {
$CDRTool[filter][aNumber] = $username;
$this->auth["perm"] = "callsearch,statistics,showPrice,showCallerId";
} else {
$CDRTool[filter][domain] = $a[1];
$this->auth["perm"] = "callsearch,statistics,showPrice,showCallerId";
}
}
return $ret[0];
} else {
$username_sql=addslashes($username);
$this->db->query("select * from auth_user where
username = '$username_sql' and expire > NOW()");
$this->db->next_record();
$otp_enabled_db =$this->db->f('otp_enable');
$otp_email =$this->db->f('email');
$otp_tel =$this->db->f('tel');
$otp_passwd =$this->db->f('otp_passwd');
$otp_passwd_md5 =md5($this->db->f('otp_passwd'));
if ($sendotp) {
if ($otp_email || $otp_tel) {
$interval="15";
print "<p>Sending OneTimePassword ";
$random_otp=random_passwd_gen();
$expire_otp= date("Y-m-d H:i:s", mktime(date("H"),date("i")+$interval,0,date("m") ,date("d"),date("Y")));
$update="update auth_user
set otp_passwd='$random_otp',
otp_expire = '$expire_otp'
where username = '$username_sql'
";
if ($this->db->query($update)) {
if ($otp_email) {
mail("$otp_email", "OTP for CDRTool", "$random_otp valid until $expire_otp CET (GMT+1) requested from $REMOTE_ADDR", "From: support@ag-projects.com");
dprint ("via email to $otp_email");
}
if ($otp_tel) {
$otp_tel=preg_replace("/[^0-9+]/","",$otp_tel);
dprint ("via SMS to $otp_tel");
otp_sms("$otp_tel", "Password is $random_otp valid until $expire_otp CET (GMT+1) from $REMOTE_ADDR","1");
}
print "<p>
Password will expire at: $expire_otp (in $interval minutes)<br>";
}
} else {
print "<p>No OTP recipient exists for this account. ";
}
}
$this->db->query(sprintf("
select *,UNIX_TIMESTAMP(otp_expire) as timestamp_otp ,
UNIX_TIMESTAMP() as timestamp_now ".
" from %s ".
" where username = '%s' " .
" and expire > NOW() " ,
$this->database_table,
addslashes($username)));
$this->db->next_record();
$uid = $this->db->f("user_id");
$perm = $this->db->f("perms");
$pass = $this->db->f("password");
$pass_md5 = md5($this->db->f("password"));
$otp_passwd = $this->db->f("otp_passwd");
if (strlen($this->db->f('otp_passwd'))) {
$otp_passwd_md5 =md5($this->db->f('otp_passwd'));
} else {
$otp_passwd_md5="garbage";
}
$timestamp_otp = $this->db->f("timestamp_otp");
$timestamp_now = $this->db->f("timestamp_now");
$CDRTool['loginName'] = $this->db->f("name");
$CDRTool['loginEmail'] = $this->db->f("email");
$_dataSourcesAllowed = explode(",",$this->db->f("sources"));
$_datasourceDefined = array_keys($DATASOURCES);
$CDRTool['dataSourcesAllowed'] = array_intersect($_dataSourcesAllowed,$_datasourceDefined);
// limits per CDRTool login account
$CDRTool['filter']['user_id'] = $this->db->f("user_id");
$CDRTool['filter']['aNumber'] = $this->db->f('aNumberFilter');
$CDRTool['filter']['displayA'] = $this->db->f('display_cli');
$CDRTool['filter']['domain'] = $this->db->f('domainFilter');
$CDRTool['filter']['gateway'] = $this->db->f('gatewayFilter');
$CDRTool['filter']['compid'] = $this->db->f('compidFilter');
$CDRTool['filter']['cscode'] = $this->db->f('cscodeFilter');
$CDRTool['impersonate'] = $this->db->f('impersonate');
if ($this->db->f('only_after_date') && $this->db->f('only_after_date') != "0000-00-00") {
$CDRTool[filter][after_date]=$this->db->f('only_after_date');
}
$expected_response = md5("$username:$pass_md5:$challenge");
$expect_otp=md5("$username:$otp_passwd_md5:$challenge");
## True when JS is disabled
if ($response == "") {
if ($password == $pass || ($password == $otp_passwd && $timestamp_otp > $timestamp_now)) {
$this->auth["perm"] = $perm;
return $uid;
} else {
return false;
}
} else {
## Response is set, JS is enabled
// we check if either otp or normal password match
//print "<p>$response == $expected_response <p>$response == $expect_otp";
if ($expected_response == $response || ($response == $expect_otp && $timestamp_otp > $timestamp_now)) {
$this->auth["perm"] = $perm;
return $uid;
} else {
return false;
}
}
}
}
}
}
class CDRTool_Perm extends Perm {
var $classname = "CDRTool_Perm";
var $permissions = array(
"admin" => 1,
"callsearch" => 2,
"statistics" => 4,
"sqlquery" => 8,
"soapclient" => 16,
"rates" => 32,
"showCallerId" => 64,
"showPrice" => 128,
"provisioning" => 256,
"readonly" => 512
);
function perm_invalid($does_have, $must_have) {
global $perm, $auth, $sess;
global $_PHPLIB;
include($_PHPLIB["libdir"] . "perminvalid.phtml");
}
}
class SIP_Subscriber_Session extends Session {
var $classname = "SIP_Subscriber_Session";
var $auto_init = "SIP_setup.inc";
var $cookiename = "SIPCookie2"; ## defaults to classname
var $magic = "3333jhjjjss13"; ## ID seed
var $mode = "cookie"; ## We propagate session IDs with cookies
var $fallback_mode = "get";
var $allowcache = "public";
var $lifetime = 0; ## 0 = do session cookies, else minutes
var $that_class = "CDRTool_CT_Sql"; ## name of data storage container
var $gc_probability = 5;
}
class SIP_Subscriber_Auth extends Auth {
// use this auth for SIP accounts
var $classname = "SIP_Subscriber_Auth";
var $lifetime = 0;
var $magic = "d66mmmg111dsgzz"; ## Challenge seed
var $database_class = "DB_subscribers";
var $database_table = "subscriber";
function auth_loginform() {
global $sess;
global $max_login_attempts;
$username = $_POST["username"];
$password = $_POST["password"];
$challenge = $_POST["challenge"];
$step = $_POST["step"];
$REMOTE_ADDR = $_SERVER["REMOTE_ADDR"];
$sess->register("challenge");
if (!$challenge) {
$challenge = md5(uniqid($this->magic));
}
include("sip_login.phtml");
}
function auth_validatelogin() {
global $SIP;
$username = $_POST["username"];
$password = $_POST["password"];
$challenge = $_POST["challenge"];
$response = $_POST["response"];
if(isset($username)) {
$this->auth["uname"]=$username;
}
$a=explode("@",$username);
$domain= $a[1];
if (count($a) !=2 ) return false;
global $domainFilters, $resellerFilters, $soapEngines ;
require_once('SOAP/Client.php');
require_once("provisioning/ngnpro_soap_library.phtml");
require_once("provisioning/ngnpro_engines.inc");
$SIP['account'] = $username;
if ($domainFilters[$domain]['sip_engine']) {
$SIP['engine'] = $domainFilters[$domain]['sip_engine'];
$SIP['customer'] = $domainFilters[$domain]['customer'];
$SIP['reseller'] = $domainFilters[$domain]['reseller'];
} else if ($domainFilters['default']['sip_engine']) {
$SIP['engine']=$domainFilters['default']['sip_engine'];
} else {
print "Error: no domainFilter available in ngnpro_engines.inc";
return false;
}
$this->SOAPlogin=array(
"username" => $soapEngines[$SIP['engine']]['username'],
"password" => $soapEngines[$SIP['engine']]['password'],
"admin" => true
);
$this->SoapAuth = array('auth', $this->SOAPlogin , 'urn:AGProjects:NGNPro', 0, '');
$this->SipPort = new WebService_NGNPro_SipPort($soapEngines[$SIP['engine']]['url']);
$log=sprintf ("Forward authorization to %s",$soapEngines[$SIP['engine']]['url']);
dprint($log);
$this->SipPort->setOpt('curl', CURLOPT_TIMEOUT, 5);
$this->SipPort->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0);
$this->SipPort->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0);
$this->SipPort->addHeader($this->SoapAuth);
$result = $this->SipPort->getAccount(array("username" =>$a[0],"domain" =>$domain));
//dprint_r($result);
if (PEAR::isError($result)) {
$error_msg = $result->getMessage();
$error_fault= $result->getFault();
$error_code = $result->getCode();
printf ("<p><font color=red>Error (SipPort): %s (%s): %s</font>",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring);
return false;
}
$pass_md5 = md5($result->password);
$expected_response = md5("$username:$pass_md5:$challenge");
if ($expected_response == $response) {
return true;
} else {
return false;
}
}
}
function otp_sms($tel,$message,$hideoutput) {
$tel=preg_replace("/[^0-9]/","",$tel);
$tel="+".$tel;
$message=substr($message,0,135);
if (!$tel || !$message) return 0;
$cmd="/usr/bin/sms --destination $tel --message \"$message\"";
exec($cmd,$output,$returnCode);
if ($returnCode == "0") {
if (!$hideoutput) {
print "<p>";
printf (_("SMS sent succesfully to %s. "), $tel);
}
} else {
print "<p>";
print "<b>";
print "OTP ";
print _("Error");
}
}
function random_passwd_gen() {
# Calculating random password
$alf=array("a","b","c","d","e","f",
"h","i","j","k","l","m",
"n","p","r","s","t","w",
"x","y","1","2","3","4",
"5","6","7","8","9");
while($i < 5) {
srand((double)microtime()*1000000);
$randval = rand(0,28);
$random_otp="$random_otp"."$alf[$randval]";
$i++;
}
return $random_otp;
}
function dprint($msg="") {
global $verbose;
if ($verbose) {
print "<br>$msg\n";
}
}
function dprint_r($obj) {
global $verbose;
if ($verbose) {
print "<pre>\n";
print_r($obj);
print "</pre>\n";
}
}
function checkEmail($email) {
global $verbose;
dprint ("<b>checkEmail($email) </b>");
if (stristr($email,"-.") ||
!preg_match("/^[a-zA-Z0-9][a-zA-Z0-9_.-]*@([a-zA-Z0-9][a-zA-Z0-9-]*\.)+[a-zA-Z]{2,}$/i",$email)) {
return 0;
}
return 1;
}
class DomainAuth {
function DomainAuth () {
$this->userDB = new DB_openser;
$this->allowedDataSourcesSubscriber = array('ser_radius');
}
function validate ($user, $domain, $password) {
$ha1 = md5($user. ':' . $domain . ':' . $password);
$query = sprintf("SELECT * FROM subscriber
WHERE username = '%s'
AND domain = '%s'
AND ( password = '%s' or ha1 = '%s') ",
addslashes($user),
addslashes($domain),
addslashes($password),
addslashes($ha1)
);
if ($this->userDB->query($query)) {
$this->userDB->next_record();
$uid = $this->userDB->f('username');
if ($uid) {
return array($uid, "subscriber", $this->allowedDataSourcesSubscriber);
}
}
}
}
class pageLayout {
function showLoginForm(&$parentAuth) {
global $simplewire_ID, $username, $otp_error, $CDRTool;
$auth=$parentAuth;
print "
<script language=javascript src=md5.js></script>
<script language=javascript>
function doChallengeResponse() {
str = document.login.username.value + \":\" +
MD5(document.login.password.value) + \":\" +
document.login.challenge.value;
document.login.response.value = MD5(str);
document.login.password.value = \"\";
document.login.submit();
}
</script>
<script language=JavaScript>
<!--
if (document.forms[0][0].value != '') {
document.forms[0][1].focus();
} else {
document.forms[0][0].focus();
}
// -->
</script>
";
$url=$auth->url();
print "
<center>
<br>
";
$this->hasAGProjectslogo=1;
$logo=$CDRTool['tld']."/images/CDRTool.gif";
print "<a href=http://ag-projects.com target=agprojects><img src=$logo border=0></a>";
print "
<form action=\"$url\" method=post>
<p>
<table align=center cellspacing=0 cellpadding=2 width=300 border=5>
<tr>
<td colspan=2>
<p>
Please identify yourself with username and password.
";
if ($CDRTool[provider][sampleLoginSubscriber]) {
$sampleLoginSubscriber = $CDRTool[provider][sampleLoginSubscriber];
} else {
$sampleLoginSubscriber="account@example.com";
}
if ($CDRTool[provider][sampleLoginDomain]) {
$sampleLoginDomain = $CDRTool[provider][sampleLoginDomain];
} else {
$sampleLoginDomain="client2.eurovoice.ro";
}
$web_username=$auth->auth["uname"];
print "
<p>
<ul>
<li>Subscriber account (e.g. $sampleLoginSubscriber)</li>
<li>Domain account (e.g. $sampleLoginDomain)</li>
<li>Administrator account
</ul>
</td>
</tr>
<tr valign=middle align=left>
<td>Username:</td>
<td>
<input type=text name=username value=\"$web_username\" size=40 maxlength=255></td>
</tr>
<tr valign=middle align=left>
<td>Password:</td>
<td>
<input type=password name=password size=40 maxlength=32></td>
</tr>
<tr>
<td valign=center align=center>
</td>
<td align=left>
<input onClick=\"doChallengeResponse(); return false;\" type=submit name=submitbtn value=\"Login now\">
</td>
</tr>
";
if ($simplewire_ID) {
print "
<tr>
<td colspan=2>
<p>
If you make use of <b>O</b>ne <b>T</b>ime <b>P</b>asswords:
<ul class=s>
<li>Fill in your username
<li>Press the Send OTP button
<li>Collect the password
<li>Fill it in the password field
<li>Press the Login Now button to login
</ul>
<input type=submit name=sendotp value=\"Send OTP\">
</td>
</tr>
";
}
print "
</table>
";
if ( isset($username)) {
if (!$sendotp || $username) {
print "
<p>
<table>
<tr>
<td colspan=2><font color=red><b>Invalid username/password combination. <br>
<br> $otp_error</b></font></td>
</tr>
</table>
";
$spam=new DB_CDRTool;
$query="select * from spam where ip = '$_SERVER[REMOTE_ADDR]'";
$spam->query($query);
if (!$spam->num_rows()) {
$query=sprintf("insert into spam (ip,tries,login,stamp)
values ('%s','1','%s','%s')
",$_SERVER[REMOTE_ADDR],addslashes($username),time());
} else {
$query=sprintf("update spam set
tries = tries +1 where ip = '%s'", $_SERVER[REMOTE_ADDR]);
}
$spam->query($query);
} else {
print "Please fill in your One Time Password!";
}
}
print "
</table>
</form>
";
}
function showHeader($title='') {
}
function showTopMenu($title='') {
global $DATASOURCES, $CDRTool, $cdr_source, $perm;
$version=trim(file_get_contents('version'));
print "<table width=100% cellpadding=5 CELLSPACING=0 border=5 align=center>
<tr>
";
if (is_readable("local/images/logo.gif")) {
print "<td valign=middle><img src=\"local/images/logo.gif\"></td>";
} else if (is_readable("local/images/logo.jpg")) {
print "<td valign=middle><img src=\"local/images/logo.jpg\"></td>";
} else if (is_readable("local/images/logo.png")) {
print "<td valign=middle><img src=\"local/images/logo.png\"></td>";
} else {
$this->hasAGProjectslogo=1;
$logo=$CDRTool['tld']."/images/CDRTool.gif";
print "<td>";
print "<a href=http://ag-projects.com target=agprojects><img src=$logo border=0></a>";
print "</td>";
}
print "
<td width=100%>
<table width=100%>
</tr>
<td>";
print "<h1>$title";
print " ";
print $DATASOURCES[$cdr_source]['name'];
print "</h1><p>";
print "<td align=right>";
print "</td></tr>
</table>
";
print "<table width=100%>
<tr>
<td align=left>
";
if ($perm->have_perm("callsearch")) {
print " <a href=callsearch.phtml>CDRs</a> ";
}
if ($perm->have_perm("rates")) {
print " | <a href=rating_tables.phtml>Rating</a>";
}
if ($perm->have_perm("provisioning")) {
print " | <a href=provisioning.phtml>SIP</a>";
}
if ($perm->have_perm("statistics")) {
- print " | <a href=sip_online.phtml>Registrar</a>";
+ print " | <a href=sip_registrar.phtml>Registrar</a>";
print " | <a href=media_sessions.phtml>Sessions</a>";
print " | <a href=status/usage/index.phtml target=usage>Usage</a>";
}
if ($perm->have_perm("admin")) {
print " | <a href=mysql_replication_status.phtml>Replication</a>";
}
print " | <a href=log.phtml>Logs</a>";
print " | <a href=accounts.phtml>Login accounts</a>";
$now_print=Date("Y-m-d H:i:s",time());
$tz=$CDRTool['provider']['timezone'];
print " | $now_print | <a href=doc/changelog target=changelog>v. $version</a>";
print "
</td>
<td align=right>
";
printf ("<a href=logout.phtml target=_top><b>Logout %s</b></a>",$CDRTool['loginName']);
print "
</tr>
</table>
</td>
</tr>
</table>
<p>
";
}
function showTopMenuSubscriber($title="") {
global $DATASOURCES, $CDRTool, $cdr_source, $perm;
$version=trim(file_get_contents(version));
print "<table width=100% cellpadding=5 CELLSPACING=0 border=5 align=center>
<tr>
<td>
<table width=100%>
</tr>
<td>";
print "<h1>$title";
print " ";
print $DATASOURCES[$cdr_source]['name'];
print "</h1><p>";
print "<td align=right>";
print "</td></tr>
</table>
";
print "<table width=100%>
<tr>
<td align=left>
";
if ($perm->have_perm("callsearch")) {
print " <a href=callsearch.phtml>Call detail records</a>";
}
$now_print=Date("Y-m-d H:i:s",time());
$tz=getenv('TZ');
print " | $now_print ($tz) | v. $version";
print "
</td>
<td align=right>
";
printf ("<a href=logout.phtml target=_top><b>Logout %s</b></a>",$CDRTool['loginName']);
print "
</tr>
</table>
</td>
</tr>
</table>
<p>
";
}
function showLegalNotice () {
global $loginname, $CDRTool;
$CDRTool_company=$CDRTool[provider][name];
$legalNotice="Legal Notice".
"\n\n".
"This software is intended for the use of $CDRTool_company, ".
"resellers of $CDRTool_company and the customers of $CDRTool_company. ".
"The use of this software by any natural or legal person that does ".
"not belong to $CDRTool_company, its Resellers or is a not a ".
"customer of $CDRTool_company or its resellers is therefore ".
"expressly prohibited.".
"\n\n".
"All the information stored on, and accessible through this software ".
"are personal data protected as such by international and domestic ".
"legislation relating to the processing of personal data and ".
"the protection of the right to privacy. For these reasons: ".
"1. This software shall exclusively be used to the extent that it ".
"is necessary for the provision of services to $CDRTool_company ".
"customers and its resellers; ".
"2. No information displayed on, and accessible through this software ".
"shall be communicated to any natural or legal person outside ".
"$CDRTool_company and its resellers, without prejudice to the ".
"possibility for competent authorities (namely government bodies, ".
"courts, regulatory authorities) to be informed of billing or ".
"traffic data in conformity with the applicable legislation. ".
"\n\n";
$loginName=$CDRTool[loginName];
$this->hasAGProjectslogo=1;
print "
<table border=0 align=center>
<tr>
<td>
<a href=http://ag-projects.com target=agprojects><img src=images/CDRTool.gif border=0></a>
<p>
<h2>Terms and conditions</h2>
<p>
<form action=callsearch.phtml method=post>
<textarea name=legal rows=20 cols=60 wrap=virtual readonly=yes>$legalNotice</textarea>
<p>
You are logged in as $loginname
<p>
If you agree with the Terms and Conditions, <br>
press on <b>I agree</b> button to continue.
<p>
<input type=submit value=\"I agree\">
<input type=hidden name=previous_page value=license_page>
</form>
</td>
</tr>
</table>
";
}
function showFooter() {
global $CDRTool;
if (!$CDRTool['filter']['aNumber'] && !$this->hasAGProjectslogo) {
$thisYear=date("Y",time());
print "
<p>
<table width=100% border=0 align=center>
<tr>
<td align=right>
<a href=http://ag-projects.com target=agprojects><img src=images/PoweredbyAGProjects.gif border=0>
</td>
</tr>
</table>
";
}
}
function showLogout ($loginname) {
print "
<table width=70% align=center>
<td>
<br>
<br>
<h1>Logout</h1>
<p>
You have been logged in as $loginname.</b>
<p>
You have been logged out.
<br>
<br>
<p>
<a href=index.phtml>Login again</a>
</td>
</table>
";
}
}
function unLockTables ($dbid) {
$dbid->query("unlock tables");
}
function changeLanguage() {
}
class E164 {
// Class that helps normalization of a telephone number in E164 format
// Based on this normalization, CDRTool rating engine decides whether
// to consider the session a PSTN destination and rate it according
// to the PSTN rating plan
function E164($intAccessCode='00', $natAccessCode='0',$CountryCode='',$ENUMtldRegexp="") {
$this->regexp_international = "/^".$intAccessCode."([0-9]{5,})\$/";
$this->regexp_national = "/^".$natAccessCode."([0-9]{3,})\$/";
$this->CountryCode = trim($CountryCode);
$this->ENUMtldRegexp = trim($ENUMtldRegexp);
}
function E164Format($Number) {
//dprint "E164Format($Number,ENUMtldRegexp=$this->ENUMtldRegexp)";
// This function returns the full E164 format for a PSTN number without leading zero or +
// E164 = Country Code + Network Code + Subscriber Number
// Example: 31208015100 is an E164 number from Holland (country code 31)
// If nothing is returned by this function the session is considered an Internet destination
if (preg_match($this->regexp_international,$Number,$m)) {
return $m[1];
} else if (preg_match($this->regexp_national,$Number,$m)) {
// Add default country code
return $this->CountryCode.$m[1];
} else if (strlen($this->ENUMtldRegexp)) {
$_regexp="/^".$this->ENUMtldRegexp."\$/";
if (preg_match($_regexp,$Number,$m)) {
return $m[1];
}
}
return false;
}
}
function RandomString($len=11) {
$alf=array("a","b","c","d","e","f",
"h","i","j","k","l","m",
"n","p","r","s","t","w",
"x","y","1","2","3","4",
"5","6","7","8","9");
$i=0;
while($i < $len) {
srand((double)microtime()*1000000);
$randval = rand(0,28);
$string="$string"."$alf[$randval]";
$i++;
}
return $string;
}
function microtime_float() {
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
?>
diff --git a/sip_online.phtml b/sip_registrar.phtml
similarity index 94%
rename from sip_online.phtml
rename to sip_registrar.phtml
index 202ac17..f75bb00 100644
--- a/sip_online.phtml
+++ b/sip_registrar.phtml
@@ -1,49 +1,49 @@
<?
include("global.inc");
page_open(
array("sess" => "CDRTool_Session",
"auth" => "CDRTool_Auth",
"perm" => "CDRTool_Perm"
));
$perm->check("statistics");
$title="SIP registrar - online subscribers";
include("header.phtml");
require("cdrlib.phtml");
$layout = new pageLayoutLocal();
$layout->showTopMenu($title);
if ($_REQUEST['datasource']) {
$datasources=array($_REQUEST['datasource']);
} else {
$datasources=array_keys($DATASOURCES);
}
foreach ($datasources as $datasource) {
if (in_array($datasource,$CDRTool['dataSourcesAllowed'])) {
if ($DATASOURCES[$datasource]['enableThor'] && $DATASOURCES[$datasource]['thorStatusNode']) {
printf ("<h1>%s</h1>",$DATASOURCES[$datasource]['name']);
printf ("
<p>
- <img src=status/images/thorNetworkImage.php?node=%s>
+ <img src=images/thorNetworkImage.php?node=%s>
",
$DATASOURCES[$datasource]['thorStatusNode']);
} else if ($DATASOURCES[$datasource]['db_class_siponline']){
printf ("<h1>%s</h1>",$DATASOURCES[$datasource]['name']);
$online= new SIPonline($datasource,$DATASOURCES[$datasource]['db_class_siponline']);
$online->showAll();
}
}
}
page_close();
?>
diff --git a/sip_statistics_lib.phtml b/sip_statistics_lib.phtml
index c506b20..7689c7e 100644
--- a/sip_statistics_lib.phtml
+++ b/sip_statistics_lib.phtml
@@ -1,539 +1,551 @@
<?
/*
- Copyright (c) 2007 AG Projects
+ Copyright (c) 2007-2008 AG Projects
http://ag-projects.com
Author Adrian Georgescu
This page provides functions for building graphical
usage statistics for OpenSER and MediaProxy
*/
class SIPstatistics {
var $SipEnabledZones = array();
var $online = array();
var $StatisticsPresentities = array();
function SIPstatistics () {
global $CDRTool;
$this->mrtgcfg_file = $CDRTool['Path']."/status/usage/sip_statistics.mrtg";
$this->harvest_file = "/tmp/CDRTool-sip-statistics.txt";
$this->mrtgcfg_dir = $CDRTool['Path']."/status/usage";
$this->index_file = $CDRTool['Path']."/status/usage/index.phtml";
$this->harvest_script = $CDRTool['Path']."/scripts/harvestStatistics.php";
$this->generateMrtgDataScript = $CDRTool['Path']."/scripts/generateMrtgData.php";
$this->generateMrtgConfigScript = $CDRTool['Path']."/scripts/generateMrtgConfig.php";
$this->db = new DB_cdrtool();
$this->ser_db = new DB_openser();
if (class_exists('DB_siponline')) {
$this->online_db = new DB_siponline();
} else {
$this->online_db = new DB_openser();
}
if (is_array($CDRTool['StatisticsPresentities'])) {
$this->StatisticsPresentities = $CDRTool['StatisticsPresentities'];
}
}
function getSipEnabledZones () {
global $CDRTool;
$query="select domain from domain";
dprint($query);
if (!$this->ser_db->query($query)) return 0;
if (!$this->ser_db->num_rows()) return 0;
while ($this->ser_db->next_record()) {
$zName=$this->ser_db->f('domain');
if (is_array($CDRTool['statistics']['zoneFilter']) && !in_array($zName,$CDRTool['statistics']['zoneFilter'])) continue;
if (!$seen[$zName]) {
$this->SipEnabledZones[$zName] = $zName;
$this->statistics[$zName] =
array( 'online_users' => '0',
'sessions' => '0',
'traffic' => '0',
'caller' => '0',
'called' => '0'
);
$seen[$zName]++;
}
}
if (is_array($CDRTool['statistics']['extraZones'])) {
foreach ($CDRTool['statistics']['extraZones'] as $zName) {
if (!$seen[$zName]) {
$this->SipEnabledZones[$zName] = $zName;
$this->statistics[$zName] =
array( 'online_users' => '0',
'sessions' => '0',
'traffic' => '0',
'caller' => '0',
'called' => '0'
);
$seen[$zName]++;
}
}
}
//print_r($this->SipEnabledZones);
//dprint_r($this->statistics);
}
function generateMrtgConfigFile () {
$this->getSipEnabledZones();
if (!$handle = fopen($this->mrtgcfg_file, 'w+')) {
echo "Error opening {$this->mrtgcfg_file}.\n";
return 0;
}
// printing cfg header
fwrite($handle,"
### Global Config Options
WorkDir: {$this->mrtgcfg_dir}
IconDir: {$this->mrtgcfg_dir}/images
Refresh: 300
#WriteExpires: Yes
");
$_zones=$this->SipEnabledZones;
$_zones['total']='total';
while(list($key,$value) = each($_zones)) {
fwrite($handle,"\n\n
## {$key}
Target[{$key}_users]: `{$this->generateMrtgDataScript} {$key} users`
Options[{$key}_users]: growright, gauge, nobanner
BodyTag[{$key}_users]: <BODY LEFTMARGIN=\"1\" TOPMARGIN=\"1\">
#PNGTitle[{$key}_users]: <center>Online Users for {$key}</center>
MaxBytes[{$key}_users]: 5000000
Title[{$key}_users]: Online Users for {$key}
ShortLegend[{$key}_users]: U
XSize[{$key}_users]: 300
YSize[{$key}_users]: 75
Ylegend[{$key}_users]: Users
Legend1[{$key}_users]: Online Users
LegendI[{$key}_users]: Online Users
LegendO[{$key}_users]:
PageTop[{$key}_users]: <H1> Online Users for {$key} </H1>
Target[{$key}_sessions]: `{$this->generateMrtgDataScript} {$key} sessions`
Options[{$key}_sessions]: growright, nobanner, gauge
BodyTag[{$key}_sessions]: <BODY LEFTMARGIN=\"1\" TOPMARGIN=\"1\">
MaxBytes[{$key}_sessions]: 50000
Title[{$key}_sessions]: Sessions Statistics for {$key}
ShortLegend[{$key}_sessions]: Ses
XSize[{$key}_sessions]: 300
YSize[{$key}_sessions]: 75
Ylegend[{$key}_sessions]: Sessions
Legend1[{$key}_sessions]: Active Sessions
LegendI[{$key}_sessions]: Active Sessions
LegendO[{$key}_sessions]:
PageTop[{$key}_sessions]: <H1> Active Sessions for {$key} </H1>
Target[{$key}_traffic]: `{$this->generateMrtgDataScript} {$key} traffic`
Options[{$key}_traffic]: gauge, growright, bits, nobanner
BodyTag[{$key}_traffic]: <BODY LEFTMARGIN=\"1\" TOPMARGIN=\"1\">
#PNGTitle[{$key}_traffic]: {$key} traffic
MaxBytes[{$key}_traffic]: 1250000000
Title[{$key}_traffic]: IP traffic for {$key}
XSize[{$key}_traffic]: 300
YSize[{$key}_traffic]: 75
Legend1[{$key}_traffic]: Caller Traffic in Bits per Second
Legend2[{$key}_traffic]: Called Traffic in Bits per Second
LegendI[{$key}_traffic]: caller
LegendO[{$key}_traffic]: called
PageTop[{$key}_traffic]: <H1> IP Traffic for {$key} </H1>
");
}
fclose($handle);
}
function generateMrtgData($domain,$dataType) {
$value1=0;
$value2=0;
$lines=explode("\n",file_get_contents($this->harvest_file));
foreach ($lines as $line) {
if (preg_match("/^$domain\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/",$line,$m)) {
if ($dataType == 'sessions') {
$value1 = $m[2];
$value2 = $m[2];
} else if ($dataType == 'traffic') {
$value1 = $m[3];
$value2 = $m[4];
} else if ($dataType == 'users') {
$value1 = $m[1];
$value2 = $m[1];
}
}
}
printf ("%d\n%d\n0\n0\n\n",$value1,$value2);
}
function getSIPOnlineUsers() {
$query="select count(*) as c, domain from location group by domain";
dprint($query);
if (!$this->online_db->query($query)) return 0;
if (!$this->online_db->num_rows()) return 0;
while ($this->online_db->next_record()) {
$this->online[$this->online_db->f('domain')]=$this->online_db->f('c');
}
dprint_r($this->online);
}
function harvestStatistics() {
if (!$handle = fopen($this->harvest_file, 'w+')) {
echo "Error opening $this->harvest_file\n";
return 0;
}
- $path = dirname(realpath($_SERVER['PHP_SELF']));
- include($path."/../status/config/media_servers.php");
+ global $DATASOURCES;
- $this->mediaServers=$servers;
+ $_mediaServers = array();
+ $_mediaDispatchers = array();
+
+ foreach (array_keys($DATASOURCES) as $ds) {
+ if (is_array($DATASOURCES[$ds]['mediaServers'])) {
+ $_mediaServers=array_merge($_mediaServers,$DATASOURCES[$ds]['mediaServers']);
+ }
+ if (strlen($DATASOURCES[$ds]['mediaDispatcher'])) {
+ $_mediaDispatchers[]=$DATASOURCES[$ds]['mediaDispatcher'];
+ }
+ }
+
+ $this->mediaServers = array_unique($_mediaServers);
+ $this->mediaDispatchers = array_unique($_mediaDispatchers);
fwrite($handle,"domains\t\t\tonline_users\tsessions\tcaller\tcalled\n\n");
$this->getSipEnabledZones();
$this->getSIPOnlineUsers();
foreach($this->mediaServers as $server) {
$this->statistics = $this->getrtpsessions($server, "25060", $this->statistics);
}
$domains=array_keys($this->SipEnabledZones);
ksort($domains);
foreach($domains as $_domain) {
foreach (array_keys($this->online) as $_domain_online) {
if ($_domain == $_domain_online) {
// update online users in big stats array
$this->statistics[$_domain]['online_users']=$this->online[$_domain];
}
}
}
// we must multiply the IP traffic by 2 when traffic enters and exists the network where the relay is located
// this depends however on topology, if IP traffic is relayed to a node on the same physical network as the media relay
// the relayed traffic will not corespond with the IP traffic monitored at the edge of the network
$totals=array('online_users' =>0,
'sessions' =>0,
'caller' =>0,
'called' =>0
);
dprint_r($this->statistics);
while(list($key, $usage) = each($this->statistics)) {
if ($usage['online_users']) {
$online_users=$usage['online_users'];
$totals['online_users']+=$usage['online_users'];
} else {
$online_users=0;
}
if ($usage['sessions']) {
$sessions=$usage['sessions'];
$totals['sessions']+=$usage['sessions'];
} else {
$sessions=0;
}
if ($usage['caller']) {
$caller=$usage['caller']*2;
$totals['caller']+=$usage['caller']*2;
} else {
$caller=0;
}
if ($usage['called']) {
$called=$usage['called']*2;
$totals['called']+=$usage['called']*2;
} else {
$called=0;
}
fwrite($handle,"{$key}\t\t{$online_users}\t\t{$sessions}\t\t{$caller}\t{$called}\n");
if (in_array($key,array_keys($this->StatisticsPresentities))) {
if (!$online_users) {
$activity='busy';
} else {
$activity='open';
}
$note=sprintf("%s: Sessions %d, Online %d",$key, $sessions,$online_users);
$this->publishPresence ($this->StatisticsPresentities[$key]['soapEngine'],
$this->StatisticsPresentities[$key]['SIPaccount'],
$note,
$activity);
}
}
$total_text=sprintf("total\t\t%d\t\t%d\t\t%s\t%s\n",
$totals['online_users'],
$totals['sessions'],
$totals['caller'],
$totals['called']
);
fwrite($handle,$total_text);
fclose($handle);
}
function getrtpsessions($ip, $port, $_domains) {
if ($fp = fsockopen ($ip, $port, $errno, $errstr, "5") ) {
fputs($fp, "status\n");
$proxy = array('status' => 'Ok');
$crtSession = 'None';
while (!feof($fp)) {
$j++;
$line = fgets($fp, 2048);
$elements = explode(" ", $line);
if ($elements[0] == 'proxy' && count($elements)==3) {
$proxy['sessionCount'] = $elements[1];
$traffic = explode("/", $elements[2]);
$proxy['traffic'] = array('caller' => $traffic[0],
'called' => $traffic[1],
'relayed' => $traffic[2]);
$proxy['sessions'] = array();
} else if ($elements[0]=='session' && count($elements)==7) {
$crtSession = $elements[1];
$info = array('from' => $elements[2],
'to' => $elements[3],
'fromAgent' => "'".$elements[4]."'",
'toAgent' => "'".$elements[5]."'",
'duration' => $elements[6],
'streams' => array());
$proxy['sessions'][$crtSession] = $info;
list($caller, $caller_domain) = explode("@", $proxy['sessions'][$crtSession]['from']);
$caller_domain_els=explode(":",$caller_domain);
$caller_domain=$caller_domain_els[0];
$_domains[$caller_domain]['sessions'] += 1;
} else if ($elements[0] == 'stream' && count($elements)==9 && $proxy['sessions'][$crtSession]['duration'] > 0) {
$stream = array('caller' => $elements[1],
'called' => $elements[2],
'via' => $elements[3],
'bytes' => explode("/", $elements[4]),
'status' => $elements[5],
'codec' => $elements[6],
'type' => $elements[7],
'idletime' => $elements[8]);
$proxy['sessions'][$crtSession]['streams'][] = $stream;
$_domains[$caller_domain]['caller'] += floor($proxy['sessions'][$crtSession]['streams'][0]['bytes'][0]/$proxy['sessions'][$crtSession]['duration']);
$_domains[$caller_domain]['called'] += floor($proxy['sessions'][$crtSession]['streams'][0]['bytes'][1]/$proxy['sessions'][$crtSession]['duration']);
$_domains[$caller_domain]['traffic'] += $proxy['sessions'][$crtSession]['streams'][0]['bytes'][0];
$_domains[$caller_domain]['traffic'] += $proxy['sessions'][$crtSession]['streams'][0]['bytes'][1];
}
}
return $_domains;
}
}
function normalizeBytes($bytes) {
$mb = $bytes/1024/1024.0;
$kb = $bytes/1024.0;
if ($mb >= 0.95) {
return sprintf("%.2fM", $mb);
} else if ($kb >= 1) {
return sprintf("%.2fk", $kb);
} else {
return sprintf("%d", $bytes);
}
}
function normalizeTraffic($traffic) {
// input is in bytes/second
$traffic = $traffic * 8;
$mb = $traffic/1024/1024.0;
$kb = $traffic/1024.0;
if ($mb >= 0.95) {
return sprintf("%.2fMbps", $mb);
} else if ($kb >= 1) {
return sprintf("%.2fkbps",$kb);
} else {
return sprintf("%dbps",$traffic);
}
}
function buildStatistics() {
system($this->generateMrtgConfigScript);
system($this->harvest_script);
system("mrtg $this->mrtgcfg_file");
}
function getOnlineTrend() {
$ips_old=array();
$ips_new=array();
$query="select count(*) as c from location";
$this->online_db->query($query);
$this->online_db->next_record();
$count_new=$this->online_db->f('c');
printf ("%d Contacts new registerd\n",$count_new);
$query="select count(*) as c from count_contacts";
$this->online_db->query($query);
$this->online_db->next_record();
$count_old=$this->online_db->f('c');
printf ("%d Contacts old registerd\n",$count_old);
$query="select * from online_ips";
dprint($query);
$this->online_db->query($query);
while ($this->online_db->next_record()) {
$els=explode(";",$this->online_db->f('ip'));
$ips_old[]=$els[0];
}
sort($ips_old);
printf ("%d IPs old registerd\n",count($ips_old));
$query="select distinct(SUBSTRING_INDEX(SUBSTRING_INDEX(contact, '@',-1),':',1))
as ip from location";
dprint($query);
$this->online_db->query($query);
while ($this->online_db->next_record()) {
$els=explode(";",$this->online_db->f('ip'));
$ips_new[]=$els[0];
}
sort($ips_new);
printf ("%d IPs new registerd\n",count($ips_new));
$left=array_diff($ips_old,$ips_new);
$join=array_diff($ips_new,$ips_old);
sort($left);
sort($join);
if (count($join)) {
printf ("%d IPs joined: ",count($join));
foreach ($join as $var) print "$var ";
print "\n";
}
if (count($left)) {
printf ("%d IPs left: ",count($left));
foreach ($left as $var) print "$var ";
print "\n";
}
//print_r($left);
$query="drop table if exists online_ips";
dprint($query);
$this->online_db->query($query);
$query="create table online_ips
select distinct(SUBSTRING_INDEX(SUBSTRING_INDEX(contact, '@',-1),':',1))
as ip from location";
dprint($query);
$this->online_db->query($query);
$query="drop table if exists count_contacts";
dprint($query);
$this->online_db->query($query);
$query="create table count_contacts
select count(*)a as c from location";
dprint($query);
$this->online_db->query($query);
//dprint_r($this->online);
}
function publishPresence ($soapEngine,$SIPaccount,$note,$activity) {
unset($soapEngines);
require_once("provisioning/ngnpro_soap_library.phtml");
require("provisioning/ngnpro_engines.inc");
//$soapEngines
if (!array_key_exists($soapEngine,$soapEngines)) {
print "Error: soapEngine '$soapEngine' does not exist.\n";
return false;
}
$this->SOAPurl = $soapEngines[$soapEngine]['url'];
$this->PresencePort = new WebService_SoapSIMPLEProxy_PresencePort($this->SOAPurl);
$this->PresencePort->setOpt('curl', CURLOPT_SSL_VERIFYPEER, 0);
$this->PresencePort->setOpt('curl', CURLOPT_SSL_VERIFYHOST, 0);
$this->PresencePort->setOpt('curl', CURLOPT_TIMEOUT, 1);
$allowed_activities=array('open',
'idle',
'busy',
'available'
);
if (in_array($activity,$allowed_activities)) {
$presentity['activity'] = $activity;
} else {
$presentity['activity'] = 'open';
}
$presentity['note'] = $note;
dprint_r($presentity);
$result = $this->PresencePort->setPresenceInformation(array("username" =>$SIPaccount['username'],"domain" =>$SIPaccount['domain']),$SIPaccount['password'], $presentity);
if (PEAR::isError($result)) {
$error_msg = $result->getMessage();
$error_fault= $result->getFault();
$error_code = $result->getCode();
printf ("<p><font color=red>Error: %s (%s): %s</font>",$error_msg, $error_fault->detail->exception->errorcode,$error_fault->detail->exception->errorstring);
return false;
}
return true;
}
}
?>
diff --git a/status/images/PoweredbyAGProjects.gif b/status/images/PoweredbyAGProjects.gif
deleted file mode 100644
index 95153a4..0000000
Binary files a/status/images/PoweredbyAGProjects.gif and /dev/null differ
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Feb 1, 10:51 AM (23 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3489232
Default Alt Text
(97 KB)
Attached To
Mode
rCDRT CDRTool
Attached
Detach File
Event Timeline
Log In to Comment