Projects

Find all our projects in development below.
All source code is GNU General Public License (GPL)

javaSpy

Browsing clsPacketMonitor.vb (25.05 KB)

Option Explicit On

Imports System.Net
Imports System.Net.Sockets
Imports System.Runtime.InteropServices
Imports System.Text

Public Class clsPacketMonitor

    ''' <summary>
    ''' The Network Control precedence designation is intended to be used within a network only. The actual use and control of that designation is up to each network. The Internetwork Control designation is intended for use by gateway control originators only. If the actual use of these precedence designations is of concern to a particular network, it is the responsibility of that network to control the access to, and use of, those precedence designations.
    ''' </summary>
    Public Enum Precedence
        Routine = 0
        Priority = 1
        Immediate = 2
        Flash = 3
        FlashOverride = 4
        CRITICECP = 5
        InternetworkControl = 6
        NetworkControl = 7
    End Enum

    ''' <summary>
    ''' The use of the Delay, Throughput, and Reliability indications may increase the cost (in some sense) of the service. In many networks better performance for one of these parameters is coupled with worse performance on another.
    ''' </summary>
    Public Enum Delay
        NormalDelay = 0
        LowDelay = 1
    End Enum

    ''' <summary>
    ''' The use of the Delay, Throughput, and Reliability indications may increase the cost (in some sense) of the service. In many networks better performance for one of these parameters is coupled with worse performance on another.
    ''' </summary>
    Public Enum Throughput
        NormalThroughput = 0
        HighThroughput = 1
    End Enum

    ''' <summary>
    ''' The use of the Delay, Throughput, and Reliability indications may increase the cost (in some sense) of the service. In many networks better performance for one of these parameters is coupled with worse performance on another.
    ''' </summary>
    Public Enum Reliability
        NormalReliability = 0
        HighReliability = 1
    End Enum

    ''' <summary>
    ''' This field indicates the next level protocol used in the data portion of the internet datagram.
    ''' </summary>
    Public Enum Protocol
        Ggp = 3
        Icmp = 1
        Idp = 22
        Igmp = 2
        IP = 4
        ND = 77
        Pup = 12
        Tcp = 6
        Udp = 17
        Other = -1
    End Enum

    Public Class clsPacket

        ' private variables
        Private m_Raw As Byte()
        Private m_Time As DateTime
        Private m_Version As Integer
        Private m_HeaderLength As Integer
        Private m_Precedence As Precedence
        Private m_Delay As Delay
        Private m_Throughput As Throughput
        Private m_Reliability As Reliability
        Private m_TotalLength As Integer
        Private m_Identification As Integer
        Private m_TimeToLive As Integer
        Private m_Protocol As Protocol
        Private m_Checksum As Byte()
        Private m_SourceAddress As IPAddress
        Private m_DestinationAddress As IPAddress
        Private m_SourcePort As Integer
        Private m_DestinationPort As Integer

        ''' <summary>
        ''' Initializes a new version of the Packet class.
        ''' </summary>
        ''' <param name="raw">The raw bytes of the IP packet.</param>
        ''' <exception cref="ArgumentNullException"><paramref name="raw"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception>
        ''' <exception cref="ArgumentException"><paramref name="raw"/> represents an invalid IP packet.</exception>
        ''' <remarks>The intercept time will be set to DateTime.Now.</remarks>
        Public Sub New(ByVal raw As Byte())
            Me.New(raw, DateTime.Now)
        End Sub
        ''' <summary>
        ''' Initializes a new version of the Packet class.
        ''' </summary>
        ''' <param name="raw">The raw bytes of the IP packet.</param>
        ''' <param name="time">The time when the IP packet was intercepted.</param>
        ''' <exception cref="ArgumentNullException"><paramref name="raw"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception>
        ''' <exception cref="ArgumentException"><paramref name="raw"/> represents an invalid IP packet.</exception>
        Public Sub New(ByVal raw As Byte(), ByVal time As DateTime)
            If raw Is Nothing Then
                Throw New ArgumentNullException()
            End If
            If raw.Length < 20 Then
                Throw New ArgumentException()
            End If
            ' invalid IP packet
            m_Raw = raw
            m_Time = time
            m_Version = (raw(0) And &HF0) >> 4
            ' sizeof(int) 
            m_HeaderLength = (raw(0) And &HF) * 4
            If (raw(0) And &HF) < 5 Then
                Throw New ArgumentException()
            End If
            ' invalid header of packet
            m_Precedence = DirectCast((raw(1) And &HE0) >> 5, Precedence)
            m_Delay = DirectCast((raw(1) And &H10) >> 4, Delay)
            m_Throughput = DirectCast((raw(1) And &H8) >> 3, Throughput)
            m_Reliability = DirectCast((raw(1) And &H4) >> 2, Reliability)
            m_TotalLength = raw(2) * 256 + raw(3)
            If m_TotalLength <> raw.Length Then
                Throw New ArgumentException()
            End If
            ' invalid size of packet
            m_Identification = raw(4) * 256 + raw(5)
            m_TimeToLive = raw(8)
            If [Enum].IsDefined(GetType(Protocol), CInt(raw(9))) Then
                m_Protocol = raw(9)
            Else
                m_Protocol = Protocol.Other
            End If
            m_Checksum = New Byte(1) {}
            m_Checksum(0) = raw(11)
            m_Checksum(1) = raw(10)
            m_SourceAddress = New IPAddress(BitConverter.ToUInt32(raw, 12))
            m_DestinationAddress = New IPAddress(BitConverter.ToUInt32(raw, 16))
            If m_Protocol = Protocol.Tcp OrElse m_Protocol = Protocol.Udp Then
                m_SourcePort = raw(m_HeaderLength) * 256 + raw(m_HeaderLength + 1)
                m_DestinationPort = raw(m_HeaderLength + 2) * 256 + raw(m_HeaderLength + 3)
            Else
                m_SourcePort = -1
                m_DestinationPort = -1
            End If
        End Sub
        ''' <summary>
        ''' Gets the raw bytes of the IP packet.
        ''' </summary>
        ''' <value>An array of bytes.</value>
        Public ReadOnly Property Raw() As Byte()
            Get
                Return m_Raw
            End Get
        End Property
        ''' <summary>
        ''' Gets the time when the IP packet was intercepted.
        ''' </summary>
        ''' <value>A <see cref="DateTime"/> value.</value>
        Public ReadOnly Property Time() As DateTime
            Get
                Return m_Time
            End Get
        End Property
        ''' <summary>
        ''' Gets the version of the IP protocol used.
        ''' </summary>
        ''' <value>A 32-bits signed integer.</value>
        Public ReadOnly Property Version() As Integer
            Get
                Return m_Version
            End Get
        End Property
        ''' <summary>
        ''' Gets the length of the IP header [in bytes].
        ''' </summary>
        ''' <value>A 32-bits signed integer.</value>
        Public ReadOnly Property HeaderLength() As Integer
            Get
                Return m_HeaderLength
            End Get
        End Property
        ''' <summary>
        ''' Gets the precedence parameter.
        ''' </summary>
        ''' <value>A <see cref="Precedence"/> instance.</value>
        Public ReadOnly Property Precedence() As Precedence
            Get
                Return m_Precedence
            End Get
        End Property
        ''' <summary>
        ''' Gets the delay parameter.
        ''' </summary>
        ''' <value>A <see cref="Delay"/> instance.</value>
        Public ReadOnly Property Delay() As Delay
            Get
                Return m_Delay
            End Get
        End Property
        ''' <summary>
        ''' Gets the throughput parameter.
        ''' </summary>
        ''' <value>A <see cref="Throughput"/> instance.</value>
        Public ReadOnly Property Throughput() As Throughput
            Get
                Return m_Throughput
            End Get
        End Property
        ''' <summary>
        ''' Gets the reliability parameter.
        ''' </summary>
        ''' <value>A <see cref="Reliability"/> instance.</value>
        Public ReadOnly Property Reliability() As Reliability
            Get
                Return m_Reliability
            End Get
        End Property
        ''' <summary>
        ''' Gets the total length of the IP packet.
        ''' </summary>
        ''' <value>A 32-bits signed integer.</value>
        Public ReadOnly Property TotalLength() As Integer
            Get
                Return m_TotalLength
            End Get
        End Property
        ''' <summary>
        ''' Gets the identification number of the IP packet.
        ''' </summary>
        ''' <value>A 32-bits signed integer.</value>
        Public ReadOnly Property Identification() As Integer
            Get
                Return m_Identification
            End Get
        End Property
        ''' <summary>
        ''' Gets the time-to-live [hop count] of the IP packet.
        ''' </summary>
        ''' <value>A 32-bits signed integer.</value>
        Public ReadOnly Property TimeToLive() As Integer
            Get
                Return m_TimeToLive
            End Get
        End Property
        ''' <summary>
        ''' Gets the protocol of the IP packet.
        ''' </summary>
        ''' <value>A <see cref="Protocol"/> instance.</value>
        Public ReadOnly Property Protocol() As Protocol
            Get
                Return m_Protocol
            End Get
        End Property
        ''' <summary>
        ''' Gets the checksum of the IP packet.
        ''' </summary>
        ''' <value>An array of two bytes.</value>
        Public ReadOnly Property Checksum() As Byte()
            Get
                Return m_Checksum
            End Get
        End Property
        ''' <summary>
        ''' Gets the source address of the IP packet.
        ''' </summary>
        ''' <value>An <see cref="IPAddress"/> instance.</value>
        Public ReadOnly Property SourceAddress() As IPAddress
            Get
                Return m_SourceAddress
            End Get
        End Property
        ''' <summary>
        ''' Gets the destination address of the IP packet.
        ''' </summary>
        ''' <value>An <see cref="IPAddress"/> instance.</value>
        Public ReadOnly Property DestinationAddress() As IPAddress
            Get
                Return m_DestinationAddress
            End Get
        End Property
        ''' <summary>
        ''' Gets the source port of the packet.
        ''' </summary>
        ''' <value>A 32-bits signed integer.</value>
        ''' <remarks>
        ''' This property will only return meaningful data if the IP packet encapsulates either a TCP or a UDP packet.
        ''' If the IP address encapsulates a packet of another protocol, the returned source port will be set to minus one.
        ''' </remarks>
        Public ReadOnly Property SourcePort() As Integer
            Get
                Return m_SourcePort
            End Get
        End Property
        ''' <summary>
        ''' Gets the destination port of the packet.
        ''' </summary>
        ''' <value>A 32-bits signed integer.</value>
        ''' <remarks>
        ''' This property will only return meaningful data if the IP packet encapsulates either a TCP or a UDP packet.
        ''' If the IP address encapsulates a packet of another protocol, the returned destination port will be set to minus one.
        ''' </remarks>
        Public ReadOnly Property DestinationPort() As Integer
            Get
                Return m_DestinationPort
            End Get
        End Property
        ''' <summary>
        ''' Gets a string representation of the source.
        ''' </summary>
        ''' <value>An <see cref="String"/> instance.</value>
        ''' <remarks>
        ''' If the encapsulated packet is a TCP or UDP packet, the returned string will consist of the IP address and the port number.
        ''' If the IP packet does not encapsulate a TCP or UDP packet, the returned string will consist of the IP address.
        ''' </remarks>
        Public ReadOnly Property Source() As String
            Get
                If m_SourcePort <> -1 Then
                    Return SourceAddress.ToString() + ":" + m_SourcePort.ToString()
                Else
                    Return SourceAddress.ToString()
                End If
            End Get
        End Property
        ''' <summary>
        ''' Gets a string representation of the destination.
        ''' </summary>
        ''' <value>An <see cref="String"/> instance.</value>
        ''' <remarks>
        ''' If the encapsulated packet is a TCP or UDP packet, the returned string will consist of the IP address and the port number.
        ''' If the IP packet does not encapsulate a TCP or UDP packet, the returned string will consist of the IP address.
        ''' </remarks>
        Public ReadOnly Property Destination() As String
            Get
                If m_DestinationPort <> -1 Then
                    Return DestinationAddress.ToString() + ":" + m_DestinationPort.ToString()
                Else
                    Return DestinationAddress.ToString()
                End If
            End Get
        End Property
        ''' <summary>
        ''' Returns a string representation of the Packet 
        ''' </summary>
        ''' <returns>An instance of the <see cref="String"/> class.</returns>
        Public Overrides Function ToString() As String
            Return Me.ToString(False)
        End Function
        ''' <summary>
        ''' Returns a string representation of the Packet 
        ''' </summary>
        ''' <param name="raw"><b>true</b> if the returned string should ony contain the raw bytes, <b>false</b> if the returned string should also contain a hexadecimal representation.</param>
        ''' <returns>An instance of the <see cref="String"/> class.</returns>
        Public Overloads Function ToString(ByVal raw__1 As Boolean) As String
            Dim sb As New StringBuilder(Raw.Length)
            If raw__1 Then
                For i As Integer = 0 To Raw.Length - 1
                    If Raw(i) > 31 Then
                        sb.Append(Chr(Raw(i)))
                    Else
                        sb.Append(".")
                    End If
                Next
            Else
                Dim rawString As String = Me.ToString(True)
                For i As Integer = 0 To Raw.Length - 1 Step 16
                    Dim j As Integer = i
                    While j < Raw.Length AndAlso j < i + 16
                        sb.Append(Raw(j).ToString("X2") + " ")
                        j += 1
                    End While
                    If rawString.Length < i + 16 Then
                        sb.Append(" "c, ((16 - (rawString.Length Mod 16)) Mod 16) * 3)
                        sb.Append(" " + rawString.Substring(i) + vbCr & vbLf)
                    Else
                        sb.Append(" " + rawString.Substring(i, 16) + vbCr & vbLf)
                    End If
                Next
            End If
            Return sb.ToString()
        End Function

    End Class

    ''' <summary>
    ''' The AllocateAndInitializeSid function allocates and initializes a security identifier (SID) with up to eight subauthorities.
    ''' </summary>
    ''' <param name="pIdentifierAuthority">Pointer to a SID_IDENTIFIER_AUTHORITY structure, giving the top-level identifier authority value to set in the SID.</param>
    ''' <param name="nSubAuthorityCount">Specifies the number of subauthorities to place in the SID. This parameter also identifies how many of the subauthority parameters have meaningful values. This parameter must contain a value from 1 to 8.</param>
    ''' <param name="dwSubAuthority0">Subauthority value to place in the SID.</param>
    ''' <param name="dwSubAuthority1">Subauthority value to place in the SID.</param>
    ''' <param name="dwSubAuthority2">Subauthority value to place in the SID.</param>
    ''' <param name="dwSubAuthority3">Subauthority value to place in the SID.</param>
    ''' <param name="dwSubAuthority4">Subauthority value to place in the SID.</param>
    ''' <param name="dwSubAuthority5">Subauthority value to place in the SID.</param>
    ''' <param name="dwSubAuthority6">Subauthority value to place in the SID.</param>
    ''' <param name="dwSubAuthority7">Subauthority value to place in the SID.</param>
    ''' <param name="pSid">Pointer to a variable that receives the pointer to the allocated and initialized SID structure.</param>
    ''' <returns>If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError.</returns>
    <DllImport("advapi32.dll")> _
    Private Shared Function AllocateAndInitializeSid(ByVal pIdentifierAuthority As Byte(), ByVal nSubAuthorityCount As Byte, ByVal dwSubAuthority0 As Integer, ByVal dwSubAuthority1 As Integer, ByVal dwSubAuthority2 As Integer, ByVal dwSubAuthority3 As Integer, _
    ByVal dwSubAuthority4 As Integer, ByVal dwSubAuthority5 As Integer, ByVal dwSubAuthority6 As Integer, ByVal dwSubAuthority7 As Integer, ByRef pSid As IntPtr) As Integer
    End Function
    ''' <summary>
    ''' The CheckTokenMembership function determines whether a specified SID is enabled in an access token.
    ''' </summary>
    ''' <param name="TokenHandle">Handle to an access token. The handle must have TOKEN_QUERY access to the token. The token must be an impersonation token.</param>
    ''' <param name="SidToCheck">Pointer to a SID structure. The CheckTokenMembership function checks for the presence of this SID in the user and group SIDs of the access token.</param>
    ''' <param name="IsMember">Pointer to a variable that receives the results of the check. If the SID is present and has the SE_GROUP_ENABLED attribute, IsMember returns TRUE; otherwise, it returns FALSE.</param>
    ''' <returns>If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError.</returns>
    <DllImport("advapi32.dll")> _
    Private Shared Function CheckTokenMembership(ByVal TokenHandle As IntPtr, ByVal SidToCheck As IntPtr, ByRef IsMember As Integer) As Integer
    End Function
    ''' <summary>
    ''' The FreeSid function frees a security identifier (SID) previously allocated by using the AllocateAndInitializeSid function.
    ''' </summary>
    ''' <param name="pSid">Pointer to the SID structure to free.</param>
    ''' <returns>This function does not return a value.</returns>
    <DllImport("advapi32.dll")> _
    Private Shared Function FreeSid(ByVal pSid As IntPtr) As IntPtr
    End Function
    ' <summary>
    ' Tests whether the current user is a member of the Administrator's group.
    ' </summary>
    ' <returns>Returns TRUE if the user is a member of the Administrator's group, FALSE if not.</returns>
    '[DllImport("shell32.dll")]
    'private extern static int IsUserAnAdmin();

    ''' <summary>
    ''' Represents the method that will handle the NewPacket event.
    ''' </summary>
    ''' <param name="pm">The <see cref="PacketMonitor"/> that intercepted the <see cref="Packet"/>.</param>
    ''' <param name="p">The newly arrived <see cref="Packet"/>.</param>
    Public Delegate Sub NewPacketEventHandler(ByVal pm As clsPacketMonitor, ByVal p As clsPacket)

    ''' <summary>
    ''' Initializes a new instance of the PacketMonitor class.
    ''' </summary>
    ''' <param name="ip">The interface on which to listen for IP packets.</param>
    ''' <exception cref="NotSupportedException">The operating system does not support intercepting packets.</exception>
    Public Sub New(ByVal ip As IPAddress)
        ' make sure the user runs this program on Windows NT 5.0 or higher
        If Environment.OSVersion.Platform <> PlatformID.Win32NT OrElse Environment.OSVersion.Version.Major < 5 Then
            Throw New NotSupportedException("This program requires Windows 2000, Windows XP or Windows .NET Server!")
        End If
        ' make sure the user is an Administrator
        If Not IsUserAnAdmin() Then
            Throw New NotSupportedException("This program can only be run by administrators!")
        End If
        m_IP = ip
        m_Buffer = New Byte(65534) {}
    End Sub
    ''' <summary>
    ''' Cleans up the unmanaged resources.
    ''' </summary>
    Protected Overrides Sub Finalize()
        Try
            [Stop]()
        Finally
            MyBase.Finalize()
        End Try
    End Sub
    ''' <summary>
    ''' Starts listening on the specified interface.
    ''' </summary>
    ''' <exception cref="SocketException">An error occurs when trying to intercept IP packets.</exception>
    Public Sub Start()
        If m_Monitor Is Nothing Then
            Try
                m_Monitor = New Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP)
                m_Monitor.Bind(New IPEndPoint(IP, 0))
                m_Monitor.IOControl(SIO_RCVALL, BitConverter.GetBytes(CInt(1)), Nothing)
                m_Monitor.BeginReceive(m_Buffer, 0, m_Buffer.Length, SocketFlags.None, New AsyncCallback(AddressOf Me.OnReceive), Nothing)
            Catch
                m_Monitor = Nothing
                Throw New SocketException()
            End Try
        End If
    End Sub
    ''' <summary>
    ''' Stops listening on the specified interface.
    ''' </summary>
    Public Sub [Stop]()
        If m_Monitor IsNot Nothing Then
            m_Monitor.Close()
            m_Monitor = Nothing
        End If
    End Sub
    ''' <summary>
    ''' Called when the socket intercepts an IP packet.
    ''' </summary>
    ''' <param name="ar">The asynchronous result.</param>
    Private Sub OnReceive(ByVal ar As IAsyncResult)
        Try
            Dim received As Integer = m_Monitor.EndReceive(ar)
            Try
                If m_Monitor IsNot Nothing Then
                    Dim packet As Byte() = New Byte(received - 1) {}
                    Array.Copy(Buffer, 0, packet, 0, received)
                    OnNewPacket(New clsPacket(packet))
                End If
            Catch
            End Try
            ' invalid packet; ignore
            m_Monitor.BeginReceive(Buffer, 0, Buffer.Length, SocketFlags.None, New AsyncCallback(AddressOf Me.OnReceive), Nothing)
        Catch
            [Stop]()
        End Try
    End Sub
    ''' <summary>
    ''' The interface used to intercept IP packets.
    ''' </summary>
    ''' <value>An <see cref="IPAddress"/> instance.</value>
    Public ReadOnly Property IP() As IPAddress
        Get
            Return m_IP
        End Get
    End Property
    ''' <summary>
    ''' The buffer used to store incoming IP packets.
    ''' </summary>
    ''' <value>An array of bytes.</value>
    Protected ReadOnly Property Buffer() As Byte()
        Get
            Return m_Buffer
        End Get
    End Property
    ''' <summary>
    ''' Raises an event that indicates a new packet has arrived.
    ''' </summary>
    ''' <param name="p">The arrived <see cref="Packet"/>.</param>
    Protected Sub OnNewPacket(ByVal p As clsPacket)
        NewPacket.Invoke(Me, p)
    End Sub
    ''' <summary>
    ''' Holds all the listeners for the NewPacket event.
    ''' </summary>
    Public NewPacket As NewPacketEventHandler = Nothing
    ' private variables
    Private m_Monitor As Socket
    Private m_IP As IPAddress
    Private m_Buffer As Byte()
    Private Const IOC_VENDOR As Integer = &H18000000
    Private Const IOC_IN As Integer = -2147483648
    '0x80000000; /* copy in parameters */
    Private Const SIO_RCVALL As Integer = IOC_IN Or IOC_VENDOR Or 1
    Private Const SECURITY_BUILTIN_DOMAIN_RID As Integer = &H20
    Private Const DOMAIN_ALIAS_RID_ADMINS As Integer = &H220
    ''' <summary>
    ''' Tests whether the current user is a member of the Administrator's group.
    ''' </summary>
    ''' <returns>Returns <b>true</b> if the user is a member of the Administrator's group, <b>false</b> if not.</returns>
    Private Function IsUserAnAdmin() As Boolean
        Dim NtAuthority As Byte() = New Byte(5) {}
        NtAuthority(5) = 5
        ' SECURITY_NT_AUTHORITY
        Dim AdministratorsGroup As IntPtr
        Dim ret As Integer = AllocateAndInitializeSid(NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, _
         0, 0, 0, 0, AdministratorsGroup)
        If ret <> 0 Then
            If CheckTokenMembership(IntPtr.Zero, AdministratorsGroup, ret) = 0 Then
                ret = 0
            End If
            FreeSid(AdministratorsGroup)
        End If

        Return (ret <> 0)
    End Function

End Class

Download clsPacketMonitor.vb

Back to file list


Back to project page