Chinaunix首页 | 论坛 | 博客
  • 博客访问: 50260
  • 博文数量: 4
  • 博客积分: 75
  • 博客等级: 民兵
  • 技术积分: 67
  • 用 户 组: 普通用户
  • 注册时间: 2011-07-17 00:23
文章分类

全部博文(4)

文章存档

2016年(1)

2013年(2)

2012年(1)

我的朋友

分类: 网络与安全

2012-06-13 17:21:14


点击(此处)折叠或打开

  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
  4. <title>PCAP Parser</title></head>
  5. <table border="1">
  6. <tr align="center" bgcolor="#66cc66"><td><b>Subject</b></td><td><b>Content</b></td></tr>
  7. <?php
  8. date_default_timezone_set('PRC');

  9. // PCAP文件路径
  10. $fpath = "./22-srcport-80-qq.pcap";

  11. // 计算PCAP文件大小,单位byte
  12. $TotalSize = filesize($fpath);
  13. echo "".$fpath." Size is:".$TotalSize."";

  14. // 打开PCAP文件
  15. $f = fopen($fpath, "rb");

  16. // 读取PCAP文件头,长度 24 bytes.
  17. $FileHeader = fread($f, 24);

  18. // 显示文件头信息,这里就不处理文件头信息了.
  19. // 将2进制文件头信息转成16进制的字符
  20. // 这里1个16进制的字符等于实际文件中的4bits长度,即半个byte的长度.
  21. // 1byte = 8bits, 1个16进制的位等同于4个二进制位, 如:(dec)15=(hex)F=(bin)1111
  22. // (24bytes * 8bits/byte) / 4bits = 48
  23. // 所以在用16进制字符显示PCAP文件头信息时会看到有48个字符.
  24. $FileHeader = bin2hex($FileHeader);

  25. // 按32位字符长度分切,便于查看.
  26. $FileHeader = chunk_split($FileHeader, 32, "
    \r\n"
    );

  27. // 显示头信息
  28. echo "FileHeader is:".$FileHeader."";
  29. echo "";

  30. // $position文件指针位置,初始化为24,跳过文件头,从24bytes后开始读取第一个数据包
  31. $position = 24;

  32. // 数据包序列
  33. $n = 0;

  34. // 从24bytes后开始读取文件直至文件结束
  35. while($position < $TotalSize) {

  36.     // 自定义的数据包序列
  37.     $n++;
  38.     echo "Pack $n ";

  39.     // 移动文件指针至24bytes的位置
  40.     fseek($f, $position);

  41.     // 读取16bytes的PCAP包头信息(PackHeader)
  42.     $PackHeader = fread($f, 16);
  43.     // 将PackHeader转成16进制的字符串
  44.     $PackHeader = bin2hex($PackHeader);
  45.     echo "PackHeader is:".$PackHeader."";

  46.     // 从PackHeader截取8个16进制的字符串(即2进制的4*8=32bits,4个字节的长度)
  47.     // Timestamp:时间戳高位,精确到seconds
  48.     $Sec = substr($PackHeader, 0, 8);

  49.     $Sec = substr($Sec, 6, 2).substr($Sec, 4, 2).substr($Sec, 2, 2).substr($Sec, 0, 2);
  50.     $Sec = hexdec($Sec);

  51.     // Timestamp:时间戳低位,精确到microseconds
  52.     $nSec = substr($PackHeader, 8, 8);
  53.     $nSec = substr($nSec, 6, 2).substr($nSec, 4, 2).substr($nSec, 2, 2).substr($nSec, 0, 2);
  54.     $nSec = hexdec($nSec);

  55.     // 得出获取这一数据帧的时间
  56.     $DateTime = date("Y-m-d H:i:s", $Sec);
  57.     echo "DateTime:".$DateTime.".".$nSec."";

  58.     // pack length
  59.     // Caplen:当前数据区的长度,即抓取到的数据帧长度,由此可以得到下一个数据帧的位置。
  60.     $Caplen = substr($PackHeader, 16, 8);
  61.     $Caplen = substr($Caplen, 6, 2).substr($Caplen, 4, 2).substr($Caplen, 2, 2).substr($Caplen, 0, 2);
  62.     $Caplen = hexdec($Caplen);
  63.     echo "Pack Caplen is:".$Caplen."";

  64.     // 移动文件指针跳过PCAP包头.
  65.     fseek($f, $position+16);

  66.     // 按PCAP包头里的Caplen长度读取PCAP包体内容.一个PCAP包体就相当于OSI中的数据链路层(Data Link)的一个帧.
  67.     // 这里说"相当于"是因为在网络上实际传输的数据包在数据链路层上每一个Packet开始都会有7个用于同步的字节(10101010, 10101010, 10101010, 10101010, 10101010, 10101010, 10101010,)和一个用于标识该Packet开始的字节(10101011),最后还会有四个CRC校验字节;而PCAP文件中会把前8个字节和最后4个校验自己去掉,因为这些信息对于协议分析是没有用处的。
  68.     $PackData = fread($f, $Caplen);

  69.     // 取MAC地址,6个字节,48bits.转成16进制表示,字符长度为12.即平时在系统看到的物理地址.
  70.     // 注意:这里PHP函数substr直接从$PackData的二进制内容里取内容,函数参数的单位为Byte.而不是字符串的字符个数了.
  71.     $Dst = bin2hex(substr($PackData, 0, 6));
  72.     $Src = bin2hex(substr($PackData, 6, 6));
  73.     echo "Src MAC is:".$Src."";
  74.     echo "Dst MAC is:".$Dst."";

  75.     // 取以太网类型,2个字节.并转成16进制表示.
  76.     $Ethertype = bin2hex(substr($PackData, 12, 2));
  77.     echo "Ethertype is:".$Ethertype."";

  78.     // 这里只分析以太网类型为0800的数据包,即只分析IP包,其他的arp什么的完蛋去~
  79.     // 这里就开始进入OSI的网络层(Network)
  80.     if ($Ethertype == "0800") {
  81.         
  82.         // IP包头里4bits的版本和4bits的首部长度连续共占1个字节.取1个字节.并转成16进制
  83.         $IPVersion_and_HeaderLen = bin2hex(substr($PackData, 14, 1));
  84.         
  85.         // IP版本号4bits,就取一个16进制的字符,转成10进制.
  86.         $IPVersion = hexdec(substr($IPVersion_and_HeaderLen, 0, 1));
  87.         echo "IP Version is:".$IPVersion."";

  88.         // IP首部长度4bits,也取一个16进制的字符,转成10进制并乘以4.这里乘以4是因为IP首部长度的单位是以32bits为一个单位,即4个byte为1个单位.
  89.         // 从这步得出的首部长度的单位为byte.基本上都是20
  90.         $IPHeaderLen = hexdec(substr($IPVersion_and_HeaderLen, 1, 1)) * 4;
  91.         echo "IP Header Len is:".$IPHeaderLen."(bytes)";
  92.         
  93.         // 14-->32
  94.         // 总共跳过8个字节不做处理.(偷懒).
  95.         // 1字节的服务类型TOS(8bits),
  96.         // 2字节的IP包总长度(16bits),
  97.         // 2字节的标识(16bits)
  98.         // 2字节的标志和片偏移(3bits标识,13bits片偏移)
  99.         // 1字节的生存时间TTL(8bits)
  100.         
  101.         // 第23字节开始取1个字节,8bits的协议类型.就是用来表示上层协议类型的东西(如:TCP,UDP).转成16进制表示.
  102.         $Proctol = bin2hex(substr($PackData, 23, 1));

  103.         // 取4个字节的源IP地址.并转成常见的4段表示格式.
  104.         $SrcIP = bin2hex(substr($PackData, 26, 4));
  105.         $SrcIP = hexdec($SrcIP[0].$SrcIP[1])."."
  106.                 .hexdec($SrcIP[2].$SrcIP[3])."."
  107.                 .hexdec($SrcIP[4].$SrcIP[5])."."
  108.                 .hexdec($SrcIP[6].$SrcIP[7]);
  109.         // 取4个字节的目标IP地址.并转成常见的4段表示格式.
  110.         $DecIP = bin2hex(substr($PackData, 30, 4));
  111.         $DecIP = hexdec($DecIP[0].$DecIP[1])."."
  112.                 .hexdec($DecIP[2].$DecIP[3])."."
  113.                 .hexdec($DecIP[4].$DecIP[5])."."
  114.                 .hexdec($DecIP[6].$DecIP[7]);
  115.         echo "SrcIP Addr is:".$SrcIP."";
  116.         echo "DecIP Addr is:".$DecIP."";
  117.         
  118.         // 根据协议类型开始处理OSI的传输层的数据.
  119.         // 一般的协议类型:6 TCP, 17 UDP, 1 ICMP

  120.         // 在这里只处理TCP类型的协议.
  121.         if ($Proctol == "06") {
  122.             echo "Data Proctol is:".$Proctol."(TCP)";

  123.             $SrcPort = hexdec(bin2hex(substr($PackData, 34, 2)));
  124.             $DecPort = hexdec(bin2hex(substr($PackData, 36, 2)));
  125.             echo "Src Port is:".$SrcPort."";
  126.             echo "Dec Port is:".$DecPort."";
  127.             
  128.             $SEQ = hexdec(bin2hex(substr($PackData, 38, 4)));
  129.             $NSEQ = hexdec(bin2hex(substr($PackData, 42, 4)));
  130.             echo "SEQ -> NSEQ is:".$SEQ."->".$NSEQ."";
  131.             // ...
  132.             
  133.             $Data = substr($PackData, 54);
  134.             $DataLen = strlen($Data);
  135.             $HexData = bin2hex($Data);
  136.             echo "Data Len is:".$DataLen."";
  137.             echo "Hex Data is:";
  138.             echo "Binary Data is:";

  139.         } else {
  140.             echo "WARNING:This is not an TCP Data, I will jump to NEXT.";
  141.         }
  142.     } else {
  143.         echo "WARNING:This is not an IP PackData, I will jump to NEXT.";
  144.     }

  145.     //-- --
  146. /*
  147.     $PackData = bin2hex($PackData);
  148.     $PackData = chunk_split($PackData, 32, "
    \r\n");
  149.     echo "Hex PackData is:".$PackData."";
  150. */    
  151.     $position = $position + 16 + $Caplen;
  152. }

  153. fclose($f);
  154. ?>
  155. </table>

阅读(1928) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:可以用的NTP服务器

给主人留下些什么吧!~~