<?php
require_once 'XByteArray.php';
require_once 'http.php';
class MyPacket
{
public $port_src = 0;
public $ip_src = 0;
public $port_dst = 0;
public $ip_dst = 0;
public $tcp_flags = 0;
public $tcp_flags_res = 0;
public $tcp_flags_ns = 0;
public $tcp_flags_cwr = 0;
public $tcp_flags_ecn = 0;
public $tcp_flags_urg = 0;
public $tcp_flags_ack = 0;
public $tcp_flags_reset = 0;
public $tcp_flags_syn = 0;
public $tcp_flags_fin = 0;
public $tcp_flags_push = 0;
public $data = "";
public $timestamp = 0;
public $timestamp_name = "";
public $key = "";
public $frame_num= 0;
public $frame_len=0;
public $frame_caplen=0;
public function genKey()
{
$keyarr =array($this->ip_src.":".$this->port_src, $this->ip_dst.":".$this->port_dst);
sort($keyarr,SORT_STRING);
$this->key = implode("<->",$keyarr);
}
public function dump()
{
printf("%10d ", $this->frame_num);
echo $this->timestamp;
echo " {$this->ip_src}";
echo ":{$this->port_src}";
echo "->{$this->ip_dst}";
echo ":{$this->port_dst}";
printf(" len %5d ", $this->frame_len);
printf(" caplen %5d ", $this->frame_caplen);
echo " flags ". dechex($this->tcp_flags);
echo " res {$this->tcp_flags_res}";
echo " ns {$this->tcp_flags_ns}";
echo " cwr {$this->tcp_flags_cwr}";
echo " ecn {$this->tcp_flags_ecn}";
echo " urg {$this->tcp_flags_urg}";
echo " ack {$this->tcp_flags_ack}";
echo " reset {$this->tcp_flags_reset}";
echo " syn {$this->tcp_flags_syn}";
echo " fin {$this->tcp_flags_fin}";
echo " push {$this->tcp_flags_push}";
echo " data:".strlen($this->data);
echo "\n";
}
};
class MyHttpRequestAndResponse
{
const STAT_NONE =0;
const STAT_REQUEST_FIRST_SENT =1;
const STAT_REQUEST_FIRST_SENT_ACK =2;
const STAT_REQUEST_LAST_SENT =4;
const STAT_REQUEST_LAST_SENT_ACK =8;
const STAT_RESPONSE_FIRST_RECEIVED =16;
const STAT_RESPONSE_FIRST_RECEIVED_ACK =32;
const STAT_RESPONSE_LAST_RECEIVED =64;
const STAT_RESPONSE_LAST_RECEIVED_ACK =128;
public $host = "";
public $url = "";
public $begin_time ="";
public $request_sent_first_packet_timestamp =0;
public $request_sent_first_packet_ack_timestamp =0;
public $request_sent_last_packet_timestamp =0;
public $request_sent_last_packet_ack_timestamp =0;
public $response_first_packet_timestamp =0;
public $response_first_packet_ack_timestamp =0;
public $response_last_packet_timestamp =0;
public $response_last_packet_ack_timestamp=0;
public $request_data_length=0;
public $response_data_length=0;
public $stat = 0;
public $need_send_ack = 0;
public $reqdata='';
public $mypacketlist = array();
};
class MyConnection
{
const STAT_SENDING_REQUEST = 0;
const STAT_WATTING_RESPONSE = 1;
public $packetlist = array();
public $client_ip ="";
public $client_port ="";
public $server_ip ="";
public $server_port ="";
public function analize()
{
if($this->packetlist[0]->tcp_flags!=0x02)
{
echo "legacy connection ".$this->packetlist[0]->key." \n";
return ;
}
if(count($this->packetlist)<3 || $this->packetlist[1]->tcp_flags!=0x12 || $this->packetlist[2]->tcp_flags!=0x10)
{
echo "connection ".$this->packetlist[0]->key." not establish \n";
}
$connect_ack_cost = $this->packetlist[1]->timestamp - $this->packetlist[0]->timestamp;
$connect_total_cost = $this->packetlist[2]->timestamp - $this->packetlist[0]->timestamp;
echo "CONNECT(".$this->packetlist[0]->key.") COST: $connect_total_cost($connect_ack_cost) \n" ;
$ctx = new HttpContext();
$bufs = new XAutoBuffer(4096);
$stat = MyConnection::STAT_SENDING_REQUEST;
$collectorlist = array();
$collector = new MyHttpRequestAndResponse();
for($i=3;$i<count($this->packetlist);$i++)
{
$packet = $this->packetlist[$i];
array_push($collector->mypacketlist,$packet);
if($packet->tcp_flags_ack)
{
switch($collector->stat)
{
case MyHttpRequestAndResponse::STAT_REQUEST_FIRST_SENT:
case MyHttpRequestAndResponse::STAT_REQUEST_LAST_SENT:
if(!($this->client_ip==$packet->ip_src && $this->client_port == $packet->port_src))
{
if($collector->request_sent_first_packet_ack_timestamp==0)
{
$collector->request_sent_first_packet_ack_timestamp = $packet->timestamp;
}
if($collector->need_send_ack==1)
{
$collector->request_sent_last_packet_ack_timestamp = $packet->timestamp;
$collector->stat =MyHttpRequestAndResponse::STAT_REQUEST_LAST_SENT_ACK;
}
$collector->need_send_ack --;
}
break;
case MyHttpRequestAndResponse::STAT_RESPONSE_FIRST_RECEIVED:
if(($this->client_ip==$packet->ip_src && $this->client_port == $packet->port_src))
{
$collector->response_first_packet_ack_timestamp = $packet->timestamp;
$collector->stat =MyHttpRequestAndResponse::STAT_RESPONSE_FIRST_RECEIVED_ACK;
}
break;
case MyHttpRequestAndResponse::STAT_RESPONSE_LAST_RECEIVED:
if($this->client_ip==$packet->ip_src && $this->client_port == $packet->port_src)
{
$collector->response_last_packet_ack_timestamp = $packet->timestamp;
$collector->stat =MyHttpRequestAndResponse::STAT_RESPONSE_LAST_RECEIVED_ACK;
array_push($collectorlist,$collector);
$collector = new MyHttpRequestAndResponse();
}
break;
}
}
if(strlen($packet->data)>0)
{
if($this->client_ip=="")
{
$this->client_ip = $packet->ip_src;
$this->client_port = $packet->port_src;
$this->server_ip = $packet->ip_dst;
$this->server_port = $packet->port_dst;
}
//截包缺失处理
if($stat==MyConnection::STAT_SENDING_REQUEST)
{
if(!($this->client_ip==$packet->ip_src && $this->client_port == $packet->port_src))
{
$collector->request_sent_last_packet_timestamp = $packet->timestamp;
$collector->request_data_length = $bufs->GetLength();
$collector->url = $ctx->m_header->status_code;
$collector->host = $ctx->getHeaderValueByName('Host');
$ctx->reset();
$bufs->Clear();
}
}
else
{
if($this->client_ip==$packet->ip_src && $this->client_port == $packet->port_src)
{
$collector->stat = MyHttpRequestAndResponse::STAT_RESPONSE_LAST_RECEIVED;
$collector->response_last_packet_timestamp = $packet->timestamp;
$collector->response_data_length = $bufs->GetLength();
$collector->response_last_packet_ack_timestamp = $packet->timestamp;
$collector->stat =MyHttpRequestAndResponse::STAT_RESPONSE_LAST_RECEIVED_ACK;
array_push($collectorlist,$collector);
$collector = new MyHttpRequestAndResponse();
$ctx->reset();
$bufs->Clear();
}
}
if($collector->stat == MyHttpRequestAndResponse::STAT_NONE )
{
$collector->stat = MyHttpRequestAndResponse::STAT_REQUEST_FIRST_SENT;
$collector->begin_time = $packet->timestamp_name;
$collector->request_sent_first_packet_timestamp = $packet->timestamp;
}
if($this->client_ip==$packet->ip_src && $this->client_port == $packet->port_src)
{
$collector->need_send_ack ++;
}
else
{
if($collector->stat < MyHttpRequestAndResponse::STAT_RESPONSE_FIRST_RECEIVED)
{
if($collector->request_sent_last_packet_ack_timestamp==0)
{
$collector->request_sent_last_packet_ack_timestamp = $collector->request_sent_first_packet_ack_timestamp;
}
$collector->stat =MyHttpRequestAndResponse::STAT_RESPONSE_FIRST_RECEIVED;
$collector->response_first_packet_timestamp = $packet->timestamp;
}
}
$bytetotal = strlen($packet->data);
$consumeLen =0;
$consumeLen = HttpProtocolClient::parseHttp($ctx,$packet->data,$bytetotal,$bufs);
if($consumeLen!=$bytetotal)
{
// var_dump($ctx);
echo "error $consumeLen!=$bytetotal , it is not ok in http\n";
//$of = fopen("/tmp/httpdata.dump", "wb");
for($k=0;$k<count($collector->mypacketlist);$k++)
{
$collector->mypacketlist[$k]->dump();
// $datalen = strlen($collector->mypacketlist[$k]->data);
// if($datalen>0)
// {
// fwrite($of, $collector->mypacketlist[$k]->data, strlen($collector->mypacketlist[$k]->data));
// }
}
//fclose($of);
//exit(0);
}
if($ctx->m_state==HttpProtocolClient::PACKET_COMPLETE)
{
if($stat==MyConnection::STAT_SENDING_REQUEST)
{
$stat=MyConnection::STAT_WATTING_RESPONSE;
//echo "request data sent: ". $packet->timestamp_name. ": ". $ctx->m_header->status_code . "\n";
}
else
{
//echo "response data recv: ". $packet->timestamp_name. ": ". $ctx->m_header->status_code . "\n";
$stat=MyConnection::STAT_SENDING_REQUEST;
}
if($collector->stat < MyHttpRequestAndResponse::STAT_RESPONSE_FIRST_RECEIVED )
{
$collector->stat = MyHttpRequestAndResponse::STAT_REQUEST_LAST_SENT;
$collector->request_sent_last_packet_timestamp = $packet->timestamp;
$collector->request_data_length = $bufs->GetLength();
$collector->url = $ctx->m_header->status_code;
$collector->host = $ctx->getHeaderValueByName('Host');
$collector->reqdata = $bufs->GetBuffer();
}
else
{
$collector->stat = MyHttpRequestAndResponse::STAT_RESPONSE_LAST_RECEIVED;
$collector->response_last_packet_timestamp = $packet->timestamp;
$collector->response_data_length = $bufs->GetLength();
}
//var_dump($packet);
//var_dump($ctx);
$ctx->reset();
$bufs->Clear();
}
}
}
if(count($collectorlist)==0)
{
for($i=0;$i<count($this->packetlist);$i++)
{
$this->packetlist[$i]->dump();
}
}
else
{
// for($i=0;$i<3;$i++)
// {
// $this->packetlist[$i]->dump();
// }
foreach($collectorlist as $c)
{
printf("%0.3f REQUEST TOTAL:%0.3f WRITTEN: %0.3f RESPONSE_FIRST:%0.3f READ: %.3f DATA:%6d URL: %s d:%s\n",
$c->request_sent_first_packet_timestamp,
$c->response_last_packet_ack_timestamp - $c->request_sent_first_packet_timestamp, //TOTAL
$c->request_sent_last_packet_ack_timestamp- $c->request_sent_first_packet_timestamp, //WRITTEN
$c->response_first_packet_timestamp - $c->request_sent_last_packet_ack_timestamp, //RESPONSE_FIRST
$c->response_last_packet_timestamp - $c->response_first_packet_timestamp, //READ
$c->response_data_length, //time
$c->host . $c->url, //url
$c->reqdata
);
// for($i=0;$i<count($c->mypacketlist); $i++)
// {
// $c->mypacketlist[$i]->dump();
// }
}
}
echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\n";
//var_dump($collectorlist);
}
};
$connections = array();
$doc = simplexml_load_file("xxxxxx");
$simle_packets = array();
foreach($doc->packet as $packet)
{
$mypacket = new MyPacket();
foreach($packet->proto as $proto)
{
if($proto->attributes()->name=='tcp')
{
foreach($proto->field as $field)
{
$attrs = $field->attributes();
if($attrs->name=="tcp.srcport")
$mypacket->port_src = strval($attrs->show);
else if($attrs->name=="tcp.dstport")
$mypacket->port_dst = strval($attrs->show);
else if($attrs->name=="tcp.flags")
{
$mypacket->tcp_flags = hexdec($attrs->show);
foreach($field->field as $flag)
{
$fatt = $flag->attributes();
if($fatt->name=="tcp.flags.fin")
{
$mypacket->tcp_flags_fin = intval($fatt->value);
}
else if($fatt->name=="tcp.flags.ack")
{
$mypacket->tcp_flags_ack = intval($fatt->value);
}
else if($fatt->name=="tcp.flags.syn")
{
$mypacket->tcp_flags_syn = intval($fatt->value);
}
else if($fatt->name=="tcp.flags.reset")
{
$mypacket->tcp_flags_reset = intval($fatt->value);
}
else if($fatt->name=="tcp.flags.push")
{
$mypacket->tcp_flags_push = intval($fatt->value);
}
else if($fatt->name=="tcp.flags.urg")
{
$mypacket->tcp_flags_urg = intval($fatt->value);
}
else if($fatt->name=="tcp.flags.ecn")
{
$mypacket->tcp_flags_ecn = intval($fatt->value);
}
else if($fatt->name=="tcp.flags.cwr")
{
$mypacket->tcp_flags_cwr = intval($fatt->value);
}
else if($fatt->name=="tcp.flags.ns")
{
$mypacket->tcp_flags_ns = intval($fatt->value);
}
else if($fatt->name=="tcp.flags.res")
{
$mypacket->tcp_flags_res = intval($fatt->value);
}
}
}
// else if($attrs->name=="tcp.data")
// {
// $xtmp = str_replace(':',' ',$attrs->show);
// $mypacket->data = HexStringToBytes($xtmp, strlen($xtmp));
// }
}
}
else if($proto->attributes()->name=='ip')
{
foreach($proto->field as $field)
{
$attrs = $field->attributes();
if($attrs->name=="ip.src")
$mypacket->ip_src = strval($attrs->show);
else if($attrs->name=="ip.dst")
$mypacket->ip_dst = strval($attrs->show);
}
}
else if($proto->attributes()->name=='geninfo')
{
foreach($proto->field as $field)
{
$attrs = $field->attributes();
if($attrs->name=="timestamp")
{
$mypacket->timestamp = doubleval($attrs->value);
$mypacket->timestamp_name = strval($attrs->show);
}
else if($attrs->name=="num")
{
$mypacket->frame_num = hexdec($attrs->value);
}
else if($attrs->name=="len")
{
$mypacket->frame_len = hexdec($attrs->value);
}
else if($attrs->name=="caplen")
{
$mypacket->frame_caplen = hexdec($attrs->value);
}
}
}
else if($proto->attributes()->name=='fake-field-wrapper')
{
foreach($proto->field as $field)
{
$attrs = $field->attributes();
if($attrs->name=="data")
{
$mypacket->data = HexStringToBytes(strval($attrs->value), strlen($attrs->value));
}
}
}
}
$mypacket->genKey();
if(!isset($connections[$mypacket->key]))
{
$connections[$mypacket->key] = new MyConnection();
}
array_push($connections[$mypacket->key]->packetlist,$mypacket);
}
foreach($connections as $k=>$v)
{
//echo "packet number : ". count($v->packetlist) . "\n";
// for($i=0;$i<count($v->packetlist);$i++)
// {
// $v->packetlist[$i]->dump();
// }
//if(strpos($v->packetlist[0]->key, "53777"))
$v->analize();
}