/// <summary> /// Send a SYN request to the next port to check it's state. /// </summary> private void SendRequest() { m_remoteEndPoint.Port = m_ports [m_portIndex]; // increment the local port. if (m_incPorts) { if (m_localEndPoint.Port == ushort.MaxValue) { m_localEndPoint.Port = 1024; } m_localEndPoint.Port++; } IpV4Packet ipHeader = new IpV4Packet(); // fill in the minimal IP fields ipHeader.DestinationAddress = m_remoteEndPoint.Address; ipHeader.SourceAddress = m_localEndPoint.Address; TcpPacket tcpHeader = new TcpPacket(); // fill in the minimal tcp fields tcpHeader.DestinationPort = (ushort)m_remoteEndPoint.Port; tcpHeader.SourcePort = (ushort)m_localEndPoint.Port; tcpHeader.SetFlag(TcpFlags.Synchronize, true); // send the request ipHeader.Data = tcpHeader.Serialize(m_localEndPoint.Address, m_remoteEndPoint.Address); // send each fragment if (m_fragment) { IpV4Packet[] fragments = ipHeader.Fragment(8); for (int i = 0; i < fragments.Length; i++) { byte[] packet = fragments[i].Serialize(); m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(fragments[i].DestinationAddress, 0)); } } // send the packet else { byte[] packet = ipHeader.Serialize(); m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(ipHeader.DestinationAddress, 0)); } // start the time out timer m_timeoutTimer.Enabled = true; }
/// <summary> /// Create a new generic error ICMP packet. /// </summary> /// <param name="packet"> /// The ICMP packet to parse. /// </param> /// <exception cref="ArgumentNullException"> /// If the packet is null then an argument null exception occurs. /// </exception> public void Constructor(IcmpPacket packet) { if (packet == null) { throw new ArgumentNullException("packet"); } // discard the unused field byte[] tempBuffer = new byte[packet.Data.Length - 4]; Array.Copy(packet.Data, 4, tempBuffer, 0, tempBuffer.Length); // parse out the packet data m_badPacket = new IpV4Packet(tempBuffer); }
/// <summary> /// /// </summary> /// <param name="data"> /// /// </param> private void NewPacket(byte[] data) { // store the time the packet arrived m_stop = Environment.TickCount; // parse out the ip header IpV4Packet ipPacket = new IpV4Packet(data); // double check to make sure this is an icmp packet if (ipPacket.TransportProtocol != ProtocolType.Icmp) { return; } // parse out the icmp packet IcmpPacket icmpPacket = new IcmpPacket(ipPacket.Data); // if this is an echo reply if (icmpPacket.MessageType == IcmpMessageType.EchoReply) { // deserialize the packet IcmpEcho echo = new IcmpEcho(icmpPacket); // if this packet matches our identifier, and destination address if (echo.Identifier == m_id && ipPacket.SourceAddress.Equals(m_remoteAddress)) { // disable the timeout timer m_timer.Enabled = false; // raise the event if (PingReply != null) { PingReply(ipPacket, icmpPacket, (int)((uint)m_stop - (uint)m_start)); } // reset the id back to 0 so we can resume sending packets. m_id = 0; // signal the wait event m_waitObject.Set(); } } }
/// <summary> /// Whenever a new IP packet arrives it should be passed to this method. /// If the packet is to be filtered out it will be ignored otherwise the /// IpV4PacketArrived will be raised with the packet /// </summary> /// <param name="packet"> /// The packet which has arrived. /// </param> public void HandleNewPacket(IpV4Packet packet) { bool match = true; // check the source address filter foreach (string filter in m_sourceAddressFilter) { if (!IpV4Filter.IsMatch(packet.SourceAddress.ToString(), filter)) { match = false; break; } } // if no match then exit if (!match) { return; } // check the destination address filter foreach (string filter in m_destAddressFilter) { if (!IpV4Filter.IsMatch(packet.DestinationAddress.ToString(), filter)) { match = false; break; } } // if no match then exit if (!match) { return; } // if we get here then the packet has passed through the filter and we // raise the event if (IpV4PacketArrived != null) { IpV4PacketArrived(packet); } }
/// <summary> /// Send a new ping packet. /// </summary> /// <param name="destination"> /// The address to send the packet to. /// </param> /// <param name="payload"> /// The data to send in the ping. /// </param> /// <param name="async"> /// If this is true, SendPing will return immediately otherwise it will wait /// </param> /// <param name="timeOutTime"> /// The number of milliseconds before the reply times out. /// </param> /// <exception cref="ObjectDisposedException"> /// If the class has been disposed then an ObjectDisposedException will be thrown. /// </exception> /// <exception cref="Exception"> /// If the class is already waiting for a ping reply then an exception will be thrown. /// Use the CancelPing method first. /// </exception> public void SendPing(IPAddress destination, byte[] payload, bool async, double timeOutTime) { if (m_disposed) { throw new ObjectDisposedException(this.ToString(), "This object has already been disposed"); } // check if a ping is already in process if (m_id != 0) { throw new Exception("A ping request is already in process. Either wait for the reply, or cancel the request first"); } Random random = new Random(); IcmpEcho echo = new IcmpEcho(); // generate random identifier and sequence number echo.Identifier = (ushort)random.Next(ushort.MaxValue); echo.SequenceNumber = (ushort)random.Next(ushort.MaxValue); m_id = echo.Identifier; m_remoteAddress = destination; m_timer.Interval = timeOutTime; // store the payload echo.Data = payload; // build the icmp header IcmpPacket icmpHeader = echo.Serialize(false); // build the ip header IpV4Packet ipHeader = new IpV4Packet(); ipHeader.TransportProtocol = ProtocolType.Icmp; ipHeader.SourceAddress = m_networkInterface; ipHeader.DestinationAddress = destination; ipHeader.Data = icmpHeader.Serialize(); if (m_fragment) { IpV4Packet[] fragments = ipHeader.Fragment(8); // send each fragment for (int i = 0; i < fragments.Length; i++) { byte[] packet = fragments[i].Serialize(); m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(fragments[i].DestinationAddress, 0)); } } else { // send the packet byte[] packet = ipHeader.Serialize(); m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(ipHeader.DestinationAddress, 0)); } // save the time and start the timeout timer m_start = Environment.TickCount; m_timer.Enabled = true; // wait for the reply m_waitObject.Reset(); if (!async) { m_waitObject.WaitOne(); } }
public void run() { while (true) { try { Packet packet = packetList.take(); EthernetPacket packet_eth = (EthernetPacket)packet; EthernetHeader head_eth = packet_eth.getHeader(); IpV4Packet ipV4Packet = null; if (ppp) { ipV4Packet = getIpV4Packet_pppoe(packet_eth); } else { if (packet_eth.getPayload() instanceof IpV4Packet) { ipV4Packet = (IpV4Packet)packet_eth.getPayload(); } } if (ipV4Packet != null) { IpV4Header ipV4Header = ipV4Packet.getHeader(); if (ipV4Packet.getPayload() instanceof TcpPacket) { TcpPacket tcpPacket = (TcpPacket)ipV4Packet.getPayload(); TcpHeader tcpHeader = tcpPacket.getHeader(); if (client) { TCPTun conn = tcpManager.getTcpConnection_Client(ipV4Header.getSrcAddr().getHostAddress(), tcpHeader.getSrcPort().value(), tcpHeader.getDstPort().value()); if (conn != null) { conn.process_client(capEnv, packet, head_eth, ipV4Header, tcpPacket, false); } } else { TCPTun conn = null; conn = tcpManager.getTcpConnection_Server(ipV4Header.getSrcAddr().getHostAddress(), tcpHeader.getSrcPort().value()); if ( tcpHeader.getDstPort().value() == listenPort) { if (tcpHeader.getSyn() && !tcpHeader.getAck() && conn == null) { conn = new TCPTun(capEnv, ipV4Header.getSrcAddr(), tcpHeader.getSrcPort().value()); tcpManager.addConnection_Server(conn); } conn = tcpManager.getTcpConnection_Server(ipV4Header.getSrcAddr().getHostAddress(), tcpHeader.getSrcPort().value()); if (conn != null) { conn.process_server(packet, head_eth, ipV4Header, tcpPacket, true); } } } } else if (packet_eth.getPayload() instanceof IllegalPacket) { MLog.println("IllegalPacket!!!"); } } } catch (InterruptedException e) {
/// <summary> /// Whenever a new IP packet arrives it should be passed to this method. /// If the packet is fragmented it will be buffered until all of the other /// fragments have arrived, then it will be pieced back together into a whole /// packet. /// </summary> /// <param name="packet"> /// The packet which has arrived. /// </param> public void HandleNewPacket(IpV4Packet packet) { #region Check for Packets we don't need to parse // first thing we do is check if this packet is whole or not if (packet.ControlFlags.Offset == 0 && !packet.ControlFlags.MoreFragments) { // it's whole so our job is done already. Just forward it on. if (IpV4PacketArrived != null) { IpV4PacketArrived(packet); } return; } #endregion // at this point we know the packet is a fragment. Now what we want to do // is check through the array list to see if it belongs to any other fragments. // If so, we store the index in the array list of the other packets for further // processing. If not, we add it to a new item in the array list and store the new // index for further processing. #region Get Packet Index int index = -1; for (int i = 0; i < m_packets.Count; i++) { IpV4Packet p = (IpV4Packet)((IpFragmentsType)m_packets[i]).Fragments[0]; // we check if fragments belong by comparing their identification field, the // source and destination address, and the transport protocol if (p.Identification == packet.Identification && p.TransportProtocol == packet.TransportProtocol && p.SourceAddress == packet.SourceAddress && p.DestinationAddress == packet.DestinationAddress) { index = i; break; } } // if the index is still -1 then this is a new fragment if (index == -1) { // create and add a new fragments entry to the packets array IpFragmentsType newFragment = new IpFragmentsType(); index = m_packets.Add(newFragment); } #endregion // now we now need to add the new fragment to the packet array. #region Add Fragment IpFragmentsType currentPacket = (IpFragmentsType)m_packets[index]; currentPacket.Fragments.Add(packet); #endregion // now we check if this packet has the More Fragments bit not set. // This indicates that it is the last fragment. // HOWEVER, since ip packets may arrive out of order, this does not mean we have all // the fragments yet. But since it is the last packet, it does let us know how much // data we are waiting on so we can identify when we have all the fragments. // so calculate how much data we are waiting on and check if we have recieved it all. #region Calculate Total Packet Size and Check For Completion // calculate data currently recieved currentPacket.CurrentDataSize += packet.TotalLength - packet.HeaderLength; if (!packet.ControlFlags.MoreFragments) { // the total length of all the data is caculated by adding the offset on to the data // length of this packet, since it's the last one. currentPacket.TotalDataSize = packet.ControlFlags.Offset + packet.TotalLength - packet.HeaderLength; } // if we have recieved all the data then bingo, we have all the fragments // so reassemble them into a complete packet and remove these uneeded fragments if (currentPacket.CurrentDataSize == currentPacket.TotalDataSize) { IpV4Packet[] fragments = new IpV4Packet[currentPacket.Fragments.Count]; for (int i = 0; i < fragments.Length; i++) { fragments[i] = (IpV4Packet)currentPacket.Fragments[i]; } IpV4Packet WholePacket = new IpV4Packet(fragments); if (IpV4PacketArrived != null) { IpV4PacketArrived(WholePacket); } m_packets.RemoveAt(index); } #endregion }
/// <summary> /// A new packet has arrived. /// </summary> /// <param name="data"> /// The packet. /// </param> private void NewPacket(byte[] data) { if (!m_working) { return; } IpV4Packet ipHeader = new IpV4Packet(data); // check to see if this packet doesn't belong to us if ((!ipHeader.SourceAddress.Equals(m_remoteEndPoint.Address)) || (!ipHeader.DestinationAddress.Equals(m_localEndPoint.Address))) { return; } TcpPacket tcpHeader = new TcpPacket(ipHeader.Data); // check to see if this packet doesn't belong to us if (tcpHeader.SourcePort != (ushort)m_remoteEndPoint.Port || tcpHeader.DestinationPort != (ushort)m_localEndPoint.Port) { return; } // disable the timeout timer m_timeoutTimer.Enabled = false; // if this is a reset packet if (tcpHeader.IsFlagSet(TcpFlags.Reset)) { // then the port is closed if (PortReply != null) { PortReply(m_remoteEndPoint, TcpPortState.Closed); } } // if it's a syn ack packet else if (tcpHeader.IsFlagSet(TcpFlags.Synchronize) && tcpHeader.IsFlagSet(TcpFlags.Acknowledgment)) { // then the port is opened if (PortReply != null) { PortReply(m_remoteEndPoint, TcpPortState.Opened); } // at this point the OS will send back a reset packet to close the connection } // increment the port m_portIndex++; // check to see if the port scan is complete if (m_portIndex == m_ports.Length) { if (ScanComplete != null) { ScanComplete(); } m_sendTimer = null; m_working = false; m_waitObject.Set(); return; } // check the next port if (m_sendTimer == null) { SendRequest(); } else { m_sendTimer.Enabled = true; } }
public void packetTvwDecode(byte [] capPacket, TreeView tvwDecode) { #region Parse Ethernet Header Ethernet802_3 ethernet = new Ethernet802_3(capPacket); strSourceMacAddress = ethernet.SourceMACAddress.ToString(); strDestMacAddress = ethernet.DestinationMACAddress.ToString(); strEthernet = "Ethernet II, Src: " + strSourceMacAddress + ", Dst: " + strDestMacAddress; strSrcMac = "Source: " + strSourceMacAddress; strDstMac = "Destination: " + strDestMacAddress; strEthernetType = "Type: " + ethernet.NetworkProtocol.ToString(); strData = "Data: " + ethernet.Data.ToString(); TreeNode nodeEthernet = tvwDecode.Nodes.Add(strEthernet); TreeNode nodeEthernetDstMac = nodeEthernet.Nodes.Add(strDstMac); TreeNode nodeEthernetSrcMac = nodeEthernet.Nodes.Add(strSrcMac); TreeNode nodeType = nodeEthernet.Nodes.Add(strEthernetType); TreeNode nodeData = nodeEthernet.Nodes.Add(strData); #region Parse Network Protocol switch (ethernet.NetworkProtocol) { case NetworkLayerProtocol.IP: IpV4Packet ip = new IpV4Packet(ethernet.Data); strIp = "Internet Protocol, Src Addr: " + ip.SourceAddress.ToString() + ", Dest Addr: " + ip.DestinationAddress.ToString(); strIpVersion = "Version: " + ip.Version.ToString(); int intIpHeaderLengthHex = ip.HeaderLength; int intIpHeaderLengthBytes = intIpHeaderLengthHex * 4; strIpHeaderLength = "Header Length: " + intIpHeaderLengthBytes.ToString() + " bytes"; strTypeOfService = "Type of Service: " + ip.TypeOfService.ToString(); strIpTotalLength = "Total Length: " + ip.TotalLength.ToString(); strIpIdentification = "Identification: " + ip.Identification.ToString(); strIpFlags = "Flags: " + ip.ControlFlags.ToString(); strIpFragment = "Fragment Offset: " + ip.Fragments.ToString(); strIpTtl = "Time To Live: " + ip.TimeToLive.ToString(); strIpProtocol = "Protocol: " + ip.TransportProtocol.ToString(); strIpChecksum = "Header Checksum: " + ip.Checksum.ToString(); if (ip.Options != null) { strIpOptions = "Options: " + ip.Options.ToString(); } if (ip.Padding != null) { strIpPadding = "Padding: " + ip.Padding.ToString(); } TreeNode nodeIP = tvwDecode.Nodes.Add(strIp); TreeNode nodeIpVersion = nodeIP.Nodes.Add(strIpVersion); TreeNode nodeIpHeaderLength = nodeIP.Nodes.Add(strIpHeaderLength); TreeNode nodeTypeOfService = nodeIP.Nodes.Add(strTypeOfService); TreeNode nodeIpTotalLength = nodeIP.Nodes.Add(strIpTotalLength); TreeNode nodeIpIdentification = nodeIP.Nodes.Add(strIpIdentification); TreeNode nodeIpFlags = nodeIP.Nodes.Add(strIpFlags); TreeNode nodeIpFragment = nodeIP.Nodes.Add(strIpFragment); TreeNode nodeIpTtl = nodeIP.Nodes.Add(strIpTtl); TreeNode nodeIpProtocol = nodeIP.Nodes.Add(strIpProtocol); TreeNode nodeIpChecksum = nodeIP.Nodes.Add(strIpChecksum); TreeNode nodeIpOptions = null; TreeNode nodeIpPadding = null; if (ip.Options != null) { nodeIpOptions = nodeIP.Nodes.Add(strIpOptions); } if (ip.Padding != null) { nodeIpPadding = nodeIP.Nodes.Add(strIpPadding); } //TreeNode nodeData = tvwDecode.Nodes.Add(strData); #region Parse Transport Protocol switch (ip.TransportProtocol) { case ProtocolType.Tcp: TcpPacket tcp = new TcpPacket(ip.Data); strTcp = "Transmission Control Protocol, Src Port: " + tcp.SourcePort.ToString() + ", Dst Port: " + tcp.DestinationPort.ToString() + ", Seq: " + tcp.SequenceNumber.ToString() + ", Ack: " + tcp.AcknowledgmentNumber.ToString(); strTcpSrcPort = "Source port: " + tcp.SourcePort.ToString(); strTcpDstPort = "Destination port: " + tcp.DestinationPort.ToString(); strTcpSeq = "Sequence number: " + tcp.SequenceNumber.ToString(); strTcpAck = "Acknowledgement number: " + tcp.AcknowledgmentNumber.ToString(); strTcpOffset = "Offset: " + tcp.Offset.ToString(); strTcpFlags = "Flags: " + tcp.Flags.ToString(); strTcpWindow = "Window size: " + tcp.Window.ToString(); strTcpChecksum = "Checksum: " + tcp.Checksum.ToString(); strTcpUrgetPointer = "Urgent Pointer: " + tcp.UrgentPointer.ToString(); if (tcp.Options != null) { strTcpOptions = "Options: " + tcp.Options.ToString(); } if (tcp.Padding != null) { strTcpPadding = "Padding: " + tcp.Padding.ToString(); } if (tcp.Data != null) { strTcpData = "Data: " + tcp.Data.ToString(); } TreeNode nodeTcp = tvwDecode.Nodes.Add(strTcp); TreeNode nodeTcpSrcPort = nodeTcp.Nodes.Add(strTcpSrcPort); TreeNode nodeTcpDstPort = nodeTcp.Nodes.Add(strTcpDstPort); TreeNode nodeTcpSeq = nodeTcp.Nodes.Add(strTcpSeq); TreeNode nodeTcpAck = nodeTcp.Nodes.Add(strTcpAck); TreeNode nodeTcpOffset = nodeTcp.Nodes.Add(strTcpOffset); TreeNode nodeTcpFlags = nodeTcp.Nodes.Add(strTcpFlags); TreeNode nodeTcpWindow = nodeTcp.Nodes.Add(strTcpWindow); TreeNode nodeTcpChecksum = nodeTcp.Nodes.Add(strTcpChecksum); TreeNode nodeTcpUrgetPointer = nodeTcp.Nodes.Add(strTcpUrgetPointer); TreeNode nodeTcpOptions = null; TreeNode nodeTcpPadding = null; TreeNode nodeTcpData = null; if (tcp.Options != null) { nodeTcpOptions = nodeTcp.Nodes.Add(strTcpOptions); } if (tcp.Padding != null) { nodeTcpPadding = nodeTcp.Nodes.Add(strTcpPadding); } if (tcp.Data != null) { nodeTcpData = nodeTcp.Nodes.Add(strTcpData); } break; case ProtocolType.Udp: UdpPacket udp = new UdpPacket(ip.Data); strUdp = "User Datagram Protocol, Src Port: " + udp.SourcePort.ToString() + ", Dst Port: " + udp.DestinationPort.ToString(); strUdpSrcPort = "Source port: " + udp.SourcePort.ToString(); strUdpDstPort = "Destination port: " + udp.DestinationPort.ToString(); strUdpLength = "Length: " + udp.Length.ToString(); strUdpChecksum = "Checksum: " + udp.Checksum.ToString(); if (udp.Data != null) { strUdpData = "Data: " + udp.Data.ToString(); } TreeNode nodeUdp = tvwDecode.Nodes.Add(strUdp); TreeNode nodeUdpSrcPort = nodeUdp.Nodes.Add(strUdpSrcPort); TreeNode nodeUdpDstPort = nodeUdp.Nodes.Add(strUdpDstPort); TreeNode nodeUdpLength = nodeUdp.Nodes.Add(strUdpLength); TreeNode nodeUdpChecksum = nodeUdp.Nodes.Add(strUdpChecksum); TreeNode nodeUdpData = null; if (udp.Data != null) { nodeUdpData = nodeUdp.Nodes.Add(strUdpData); } break; case ProtocolType.Icmp: IcmpPacket icmp = new IcmpPacket(ip.Data); strIcmp = "Internet Control Message Protocol"; strIcmpMessageType = "Data: " + icmp.MessageType.ToString(); strIcmpCode = "Data: " + icmp.Code.ToString(); strIcmpChecksum = "Data: " + icmp.Checksum.ToString(); strIcmpData = "Data: " + icmp.Data.ToString(); TreeNode nodeIcmp = tvwDecode.Nodes.Add(strIcmp); TreeNode nodeIcmpMessageType = nodeIcmp.Nodes.Add(strIcmpMessageType); TreeNode nodeIcmpCode = nodeIcmp.Nodes.Add(strIcmpCode); TreeNode nodeIcmpChecksum = nodeIcmp.Nodes.Add(strIcmpChecksum); TreeNode nodenodeIcmpData = nodeIcmp.Nodes.Add(strIcmpData); break; } #endregion break; case NetworkLayerProtocol.ARP: ArpPacket arp = new ArpPacket(ethernet.Data); strArp = "Address Resolution Protocol"; strArpMediaType = "Hardware Type: " + arp.MediaType.ToString(); strArpProtocolType = "Protocol Type: " + arp.Protocol.ToString(); strArpType = "Opcode: " + arp.Type.ToString(); strArpSrcMac = "Sender MAC Address: " + arp.SourceMACAddress.ToString(); strArpSrcIp = "Sender IP Address: " + arp.SourceIPAddress.ToString(); strArpDstMac = "Target MAC Address: " + arp.DestinationMACAddress.ToString(); strArpDstIp = "Target IP Address: " + arp.DestinationIPAddress.ToString(); TreeNode nodeArp = tvwDecode.Nodes.Add(strArp); TreeNode nodeMediaType = nodeArp.Nodes.Add(strArpMediaType); TreeNode nodeArpProtocolType = nodeArp.Nodes.Add(strArpProtocolType); TreeNode nodeArpType = nodeArp.Nodes.Add(strArpType); TreeNode nodeArpSrcMac = nodeArp.Nodes.Add(strArpSrcMac); TreeNode nodeArpSrcIp = nodeArp.Nodes.Add(strArpSrcIp); TreeNode nodeArpDstMac = nodeArp.Nodes.Add(strArpDstMac); TreeNode nodeArpDstIp = nodeArp.Nodes.Add(strArpDstIp); break; } #endregion #endregion }
private void btnStop_Click(object sender, EventArgs e) { if (driver.Disposed == true) { return; } captureThread.Abort(); driver.CloseDevice(); for (int packetLoop = 0; packetLoop < packetCount; packetLoop++) { string sourceIp = "N/A"; string sourceMac = "N/A"; string sourcePort = "N/A"; string destIp = "N/A"; string destMac = "N/A"; string destPort = "N/A"; string protocol = "N/A"; Ethernet802_3 ethernet = new Ethernet802_3(capturedPackets[packetLoop]); sourceMac = ethernet.SourceMACAddress.ToString(); destMac = ethernet.DestinationMACAddress.ToString(); switch (ethernet.NetworkProtocol) { case NetworkLayerProtocol.IP: IpV4Packet ip = new IpV4Packet(ethernet.Data); sourceIp = ip.SourceAddress.ToString(); destIp = ip.DestinationAddress.ToString(); protocol = ip.TransportProtocol.ToString().ToUpper(); switch (ip.TransportProtocol) { case ProtocolType.Tcp: TcpPacket tcp = new TcpPacket(ip.Data); sourcePort = tcp.SourcePort.ToString(); destPort = tcp.DestinationPort.ToString(); break; case ProtocolType.Udp: UdpPacket udp = new UdpPacket(ip.Data); sourcePort = udp.SourcePort.ToString(); destPort = udp.DestinationPort.ToString(); break; case ProtocolType.Icmp: IcmpPacket icmp = new IcmpPacket(ip.Data); break; } break; case NetworkLayerProtocol.ARP: ArpPacket arp = new ArpPacket(ethernet.Data); sourceMac = arp.SourceMACAddress.ToString(); destMac = arp.DestinationMACAddress.ToString(); sourceIp = arp.SourceIPAddress.ToString(); destIp = arp.DestinationIPAddress.ToString(); protocol = arp.Protocol.ToString().ToUpper(); break; } string[] items = new string[8]; items[0] = packetLoop.ToString(); items[1] = sourceIp; items[2] = sourceMac; items[3] = sourcePort; items[4] = destIp; items[5] = destMac; items[6] = destPort; items[7] = protocol; lvwPacketCapture.Items.Add(new ListViewItem(items, 0)); } }
/// <summary> /// Log a new IP packet. /// </summary> /// <param name="packet"> /// The packet to log. /// </param> public void LogPacket(IpV4Packet packet) { lock (m_logger.XmlWriter) { // <IpV4Header> m_logger.XmlWriter.WriteStartElement("IpV4Header"); m_logger.XmlWriter.WriteElementString("SourceAddress", packet.SourceAddress.ToString()); m_logger.XmlWriter.WriteElementString("DestinationAddress", packet.DestinationAddress.ToString()); m_logger.XmlWriter.WriteElementString("TransportProtocol", packet.TransportProtocol.ToString()); m_logger.XmlWriter.WriteElementString("TimeToLive", packet.TimeToLive.ToString()); m_logger.XmlWriter.WriteElementString("Identification", packet.Identification.ToString()); m_logger.XmlWriter.WriteElementString("Checksum", packet.Checksum.ToString()); // <LengthFields> m_logger.XmlWriter.WriteStartElement("IpLengthFields"); m_logger.XmlWriter.WriteElementString("TotalLength", packet.TotalLength + " bytes"); m_logger.XmlWriter.WriteElementString("HeaderLength", packet.HeaderLength + " bytes"); m_logger.XmlWriter.WriteElementString("OptionsLength", (packet.TotalLength - (packet.Padding != null ? packet.Padding.Length : 0) - (packet.Data != null ? packet.Data.Length : 0) - 0x14) + " bytes"); m_logger.XmlWriter.WriteElementString("PaddingLength", (packet.Padding != null ? packet.Padding.Length : 0) + " bytes"); m_logger.XmlWriter.WriteElementString("DataLength", (packet.Data != null ? packet.Data.Length : 0) + " bytes"); m_logger.XmlWriter.WriteEndElement(); // </LengthFields> // <Fragmentation> m_logger.XmlWriter.WriteStartElement("Fragmentation"); m_logger.XmlWriter.WriteElementString("Fragments", packet.Fragments.ToString()); m_logger.XmlWriter.WriteElementString("DontFragment", packet.ControlFlags.DontFragment.ToString()); m_logger.XmlWriter.WriteElementString("MoreFragments", packet.ControlFlags.MoreFragments.ToString()); m_logger.XmlWriter.WriteElementString("Offset", packet.ControlFlags.Offset.ToString()); m_logger.XmlWriter.WriteEndElement(); // </Fragmentation> // <TypeOfService> m_logger.XmlWriter.WriteStartElement("TypeOfService"); m_logger.XmlWriter.WriteElementString("Precedence", packet.TypeOfService.Precedence.ToString()); m_logger.XmlWriter.WriteElementString("Delay", packet.TypeOfService.Delay.ToString()); m_logger.XmlWriter.WriteElementString("Reliability", packet.TypeOfService.Reliability.ToString()); m_logger.XmlWriter.WriteElementString("Throughput", packet.TypeOfService.Throughput.ToString()); m_logger.XmlWriter.WriteEndElement(); // </TypeOfService> if (packet.Options != null) { // <Options> m_logger.XmlWriter.WriteStartElement("IpOptions"); foreach (IpV4Option option in packet.Options) { // <Option> m_logger.XmlWriter.WriteStartElement("Option"); m_logger.XmlWriter.WriteElementString("Class", option.Class.ToString()); m_logger.XmlWriter.WriteElementString("Type", option.OptionType.ToString()); m_logger.XmlWriter.WriteElementString("Length", option.Length + " bytes"); m_logger.XmlWriter.WriteElementString("Copied", option.IsCopied.ToString()); #region Specific Options switch (option.OptionType) { case IpV4OptionNumber.EndOfOptions: break; case IpV4OptionNumber.InternetTimestamp: IpV4TimeStampOption option1 = new IpV4TimeStampOption(option); m_logger.XmlWriter.WriteElementString("TimestampType", option1.OptionType.ToString()); m_logger.XmlWriter.WriteElementString("Overflow", option1.Overflow.ToString()); m_logger.XmlWriter.WriteElementString("Pointer", option1.Pointer.ToString()); // TODO: Handle logging of time stamps and address stamps in time stamp IP option break; case IpV4OptionNumber.LooseSourceRouting: IpV4RoutingOption option2 = new IpV4RoutingOption(option); m_logger.XmlWriter.WriteElementString("Pointer", option2.Pointer.ToString()); // TODO: Handle logging of route in routing IP options break; case IpV4OptionNumber.NoOperation: break; case IpV4OptionNumber.RecordRoute: IpV4RoutingOption option3 = new IpV4RoutingOption(option); m_logger.XmlWriter.WriteElementString("Pointer", option3.Pointer.ToString()); // TODO: Handle logging of route in routing IP options break; case IpV4OptionNumber.Security: IpV4SecurityOption option4 = new IpV4SecurityOption(option); m_logger.XmlWriter.WriteElementString("SecurityLevel", option4.SecurityLevel.ToString()); m_logger.XmlWriter.WriteElementString("Compartment", option4.Compartment.ToString()); m_logger.XmlWriter.WriteElementString("HandlingRestrictions", option4.HandlingRestrictions.ToString()); m_logger.XmlWriter.WriteElementString("TransmissionControlCode", option4.TransmissionControlCode.ToString()); break; case IpV4OptionNumber.StreamId: IpV4StreamIdentifierOption option5 = new IpV4StreamIdentifierOption(option); m_logger.XmlWriter.WriteElementString("StreamIdentifier", option5.StreamIdentifier.ToString()); break; case IpV4OptionNumber.StrictSourceRouting: IpV4RoutingOption option6 = new IpV4RoutingOption(option); m_logger.XmlWriter.WriteElementString("Pointer", option6.Pointer.ToString()); // TODO: Handle logging of route in routing IP options break; } #endregion m_logger.XmlWriter.WriteEndElement(); // </Option> } m_logger.XmlWriter.WriteEndElement(); // </Options> } m_logger.XmlWriter.WriteEndElement(); // </IpV4Header> } }
/// <summary> /// This event occurs whenever a new packet arrives. /// </summary> /// <param name="data"> /// The data in the packet. /// </param> private void NewPacket(byte[] data) { if (!m_working) { return; } // store the time the packet arrived m_stop = Environment.TickCount; // parse out the ip header IpV4Packet ipPacket = new IpV4Packet(data); // double check to make sure this is an icmp packet if (ipPacket.TransportProtocol != ProtocolType.Icmp) { return; } // parse out the icmp packet IcmpPacket icmpPacket = new IcmpPacket(ipPacket.Data); // if this is an echo reply if (icmpPacket.MessageType == IcmpMessageType.EchoReply) { #region Reply From Destination // deserialize the packet IcmpEcho echo = new IcmpEcho(icmpPacket); // if this packet matches our identifier, and destination address if (echo.Identifier == m_id) { // disable the timeout timer m_timer.Enabled = false; // raise the event if (RouteUpdate != null) { RouteUpdate(ipPacket.SourceAddress, (int)((uint)m_stop - (uint)m_start), m_ttl); } // raise the event if (TraceFinished != null) { TraceFinished(); } // signal the wait event m_waitObject.Set(); // allow new trace routes m_working = false; } #endregion } // if the time to live exceeded then we have a new hop else if (icmpPacket.MessageType == IcmpMessageType.TimeExceeded) { #region Reply From Router IcmpTimeExceeded icmpTimeExceeded = new IcmpTimeExceeded(icmpPacket); // make sure this packet is for us if (m_ipId != icmpTimeExceeded.BadPacket.Identification) { return; } // disable the timeout timer m_timer.Enabled = false; // raise the event if (RouteUpdate != null && m_working) { RouteUpdate(ipPacket.SourceAddress, (int)((uint)m_stop - (uint)m_start), m_ttl); } // increment the time to live. m_ttl++; // if the max hop count is exceeded if (m_ttl > m_maxHops) { // disable the timeout timer m_timer.Enabled = false; // allow new trace routes m_working = false; // raise the event if (MaxHopsExceeded != null) { MaxHopsExceeded(); } // signal the wait event m_waitObject.Set(); } else { // send the next request SendRequest(); } #endregion } }
/// <summary> /// Send the next request in order to find the next hop. /// </summary> private void SendRequest() { // generate a 32 byte payload string data = new string ('x', 32); byte[] payload = System.Text.ASCIIEncoding.ASCII.GetBytes(data); // fill in ip header fields IpV4Packet ipPacket = new IpV4Packet(); ipPacket.DestinationAddress = m_remoteAddress; ipPacket.SourceAddress = m_localAddress; ipPacket.TransportProtocol = ProtocolType.Icmp; ipPacket.TimeToLive = m_ttl; // save the identification m_ipId = ipPacket.Identification; // add routing options if any if (m_route != null) { ipPacket.Options = new IpV4Option[2]; ipPacket.Options[0] = m_route.Serialize(m_strictRouting ? IpV4OptionNumber.StrictSourceRouting : IpV4OptionNumber.LooseSourceRouting); ipPacket.Options[1] = new IpV4Option(); ipPacket.Options[1].OptionType = IpV4OptionNumber.EndOfOptions; ipPacket.Options[1].IsCopied = false; ipPacket.Options[1].Length = 1; ipPacket.Options[1].Class = IpV4OptionClass.Control; ipPacket.Options[1].Data = null; } // create a new echo packet IcmpEcho echo = new IcmpEcho(); echo.Identifier = m_id; echo.Data = payload; // serialize the icmp packet IcmpPacket icmpPacket = echo.Serialize(false); ipPacket.Data = icmpPacket.Serialize(); if (m_fragment) { IpV4Packet[] fragments = ipPacket.Fragment(8); // send each fragment for (int i = 0; i < fragments.Length; i++) { byte[] packet = fragments[i].Serialize(); m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(fragments[i].DestinationAddress, 0)); } } else { // send the ip packet byte[] packet = ipPacket.Serialize(); m_socket.SendTo(packet, 0, packet.Length, SocketFlags.None, new IPEndPoint(ipPacket.DestinationAddress, 0)); } // grab the current time m_start = Environment.TickCount; // start the timeout timer m_timer.Enabled = true; }