[创建时间:2016-05-12 00:19:00]
在NetAnalyzer2016中加入了一个HTTP分析功能,很过用户对此都很感兴趣,那么今天写一下具体的实现方式,对我自己也算是一个总结吧,好了,废话就不多少了,直接开始吧。
本文是专注于HTTP数据的分析,所以前期数据包采集相关的内容并不会本文不会涉及,相关内容可以见 NetAnalyzer 笔记 四
在这边默认你已经获取到了http数据报文。
一,提取TCP会话数据
通过TCP/IP协议知道,我们可以通过网络层的IP地址可以唯一的确定一台主机,通过传输层的端口确定一个主机应用,而主机应用与另外一个主机应用的一次数据通信(报文交换)我们称之为一次会话,而建立的传输层协议为TCP上面的一次交互数据我们就称之为TCP会话数据。
一次常规的TCP会话
在这里我们可以看到本地主机应用标志 IP地址: 192.168.1.102 端口 55298 和远端主机应用标志 IP地址:124.238.254.191 端口 80 (80端口所对应的应用协议就是HTTP),通过这组标志,而下面每行记录都代表一TCP数据包,
每个TCP包包含了TCP状态标志,载荷数据(TCP数据包封装的数据)量,序列号等信息,大家可以留意一下每两条记录之间的序列号和载荷数据量之间的关系。
我们这里要提取的数据正是这组TCP报文中的载荷数据
这段代码用于定义并生成一个TCP标志
1 /// <summary> 2 /// 根据IP与端口构建ID 3 /// </summary> 4 public class ConnIDbyIPPort : IConnectionID 5 { 6 /// <summary> 7 /// Client IP 8 /// </summary> 9 IPAddress _srcIPaddress;//Client IP 10 /// <summary> 11 /// Server IP 12 /// </summary> 13 IPAddress _dstIPaddress;//Server IP 14 /// <summary> 15 /// Client port 16 /// </summary> 17 int _srcPort;//Client port 18 /// <summary> 19 /// Server port 20 /// </summary> 21 int _dstPort;//Server port 22 /// <summary> 23 /// 源IP地址属性 24 /// </summary> 25 public IPAddress SrcIPAddress 26 { 27 get { return _srcIPaddress; } 28 } 29 /// <summary> 30 /// 目标IP地址属性 31 /// </summary> 32 public IPAddress DstIPAddress 33 { 34 get { return _dstIPaddress; } 35 } 36 /// <summary> 37 /// 源端口属性 38 /// </summary> 39 public int SrcPort 40 { 41 get { return _srcPort; } 42 } 43 /// <summary> 44 /// 目的端口属性 45 /// </summary> 46 public int DstPort 47 { 48 get { return _dstPort; } 49 } 50 51 /// <summary> 52 /// 判断当前的数据包的方向 53 /// 注意: 54 /// 此处所说的方向具有相对性 55 /// </summary> 56 /// <param name="srcPort"></param> 57 /// <returns></returns> 58 public bool isSameDirection(int srcPort) 59 { 60 if (srcPort == _srcPort) 61 return true; 62 else if (srcPort == _dstPort) 63 return false; 64 else 65 throw new ArgumentException("无效的参数,不是该链接之中的数据!"); 66 } 67 /// <summary> 68 /// 构造方法 69 /// </summary> 70 /// <param name="ClientIPaddress">源IP地址</param> 71 /// <param name="ClientPort">源端口</param> 72 /// <param name="ServerIPaddress">目标IP地址</param> 73 /// <param name="ServerPort">目标端口</param> 74 public ConnIDbyIPPort(IPAddress ClientIPaddress, int ClientPort, IPAddress ServerIPaddress, int ServerPort) 75 { 76 _srcIPaddress = ClientIPaddress; 77 _srcPort = ClientPort; 78 _dstIPaddress = ServerIPaddress; 79 _dstPort = ServerPort; 80 } 81 /// <summary> 82 /// 构造函数 83 /// </summary> 84 /// <param name="rawpacket"></param> 85 public ConnIDbyIPPort(RawCapture rawpacket) 86 { 87 SetInfo(rawpacket); 88 } 89 /// <summary> 90 /// 创建ID 91 /// </summary> 92 /// <param name="rawpacket"></param> 93 private void SetInfo(RawCapture rawpacket) 94 { 95 try 96 { 97 Packet packet = Packet.ParsePacket(rawpacket.LinkLayerType, rawpacket.Data); 98 99 TcpPacket tcp = TcpPacket.GetEncapsulated(packet); 100 if (tcp != null) 101 { 102 IpPacket ip = (IpPacket)tcp.ParentPacket; 103 _srcIPaddress = ip.SourceAddress; 104 _srcPort = tcp.SourcePort; 105 _dstIPaddress = ip.DestinationAddress; 106 _dstPort = tcp.DestinationPort; 107 return; 108 } 109 UdpPacket udp = UdpPacket.GetEncapsulated(packet); 110 if (udp != null) 111 { 112 IpPacket ip = (IpPacket)udp.ParentPacket; 113 _srcIPaddress = ip.SourceAddress; 114 _srcPort = udp.SourcePort; 115 _dstIPaddress = ip.DestinationAddress; 116 _dstPort = udp.DestinationPort; 117 return; 118 } 119 } 120 catch (Exception ex) 121 { 122 throw ex; 123 } 124 } 125 /// <summary> 126 /// 创建ConnectionID; 127 /// </summary> 128 /// <param name="rawpacket">原始数据报文</param> 129 /// <returns></returns> 130 public IConnectionID CreatID(RawCapture rawpacket) 131 { 132 try 133 { 134 ConnIDbyIPPort id = new ConnIDbyIPPort(rawpacket); 135 return id; 136 137 } 138 catch (Exception ex) 139 { 140 return null; 141 } 142 } 143 /// <summary> 144 /// 重写Equals()方法 145 /// </summary> 146 /// <param name="obj">所要比较的ConnectionID</param> 147 /// <returns>比较结果</returns> 148 public override bool Equals(object obj)//重写的Equals,用于比较两个连接是否相同 149 { 150 if (obj == null) 151 return false; 152 ConnIDbyIPPort tempID = (ConnIDbyIPPort)obj; 153 if (this._srcIPaddress.Equals(tempID._srcIPaddress) && this._srcPort == tempID._srcPort && this._dstIPaddress.Equals(tempID._dstIPaddress) && this._dstPort.Equals(tempID._dstPort))//正向比较 154 { 155 return true; 156 } 157 else if (this._srcIPaddress.Equals(tempID._dstIPaddress) && this._srcPort == tempID._dstPort && this._dstIPaddress.Equals(tempID._srcIPaddress) &&this._dstPort==tempID._srcPort)//逆向比较 158 { 159 return true; 160 } 161 else 162 { 163 return false; 164 } 165 } 166 /// <summary> 167 /// 使标识用Equals进行比较 168 /// </summary> 169 /// <returns></returns> 170 public override int GetHashCode()//系统默认对象通过HashCode比较,故在此屏蔽此方法 171 { 172 return 1; 173 } 174 /// <summary> 175 /// 重写ToString()方法 176 /// </summary> 177 /// <returns>ConnectionID</returns> 178 public override string ToString()//获取ID字符串 179 { 180 return _srcIPaddress.ToString() + ":" + _srcPort.ToString() + "--" + 181 _dstIPaddress.ToString() + ":" + _dstPort.ToString(); 182 } 183 #region 操作符重载 184 //public static bool operator==(ConnectionID id1,ConnectionID id2) 185 //{ 186 // return id1.Equals(id2); 187 //} 188 //public static bool operator !=(ConnectionID id1, ConnectionID id2) 189 //{ 190 // return !id1.Equals(id2); 191 //} 192 #endregion 193 194 }