Sub Main()
        ListenForRawData()
end sub
Dim RAWSocket As System.Net.Sockets.Socket
    Private Const IOC_VENDOR As Integer = &H18000000
    Private Const IOC_IN As Integer = -2147483648
    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
    Dim MyIPAddr As String = vbNullString
    Dim MyStateObject As StateObject
    Public Class StateObject
        Public workSocket As System.Net.Sockets.Socket = Nothing
        Public Const BUFFER_SIZE As Integer = 65535
        Public buffer(BUFFER_SIZE) As Byte
        Public sb As New System.Text.StringBuilder()
    End Class 'StateObject

    Private Sub ListenForRawData()
        'To get local address
        Dim sHostName As String
        sHostName = System.Net.Dns.GetHostName()
        Dim ipE As System.Net.IPHostEntry = System.Net.Dns.GetHostByName(sHostName)
        Dim IpA() As System.Net.IPAddress = ipE.AddressList
        MyIPAddr = IpA(0).ToString()

        MyStateObject = New StateObject()
        RAWSocket = New System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Raw, System.Net.Sockets.ProtocolType.IP)
        Dim OptionIn() As Byte = BitConverter.GetBytes(1)
        Dim OptionOut() As Byte = Nothing

        Dim InByte() As Byte = {1, 0, 0, 0}
        Dim outByte(4) As Byte

        'RAWSocket.Bind(New System.Net.IPEndPoint(Net.IPAddress.Any, 0))
        RAWSocket.Bind(New System.Net.IPEndPoint(System.Net.IPAddress.Parse(MyIPAddr), 0)) 'must be bound to a IP
        '
        RAWSocket.IOControl(SIO_RCVALL, InByte, outByte)
        RAWSocket.BeginReceive(MyStateObject.buffer, 0, StateObject.BUFFER_SIZE, System.Net.Sockets.SocketFlags.Peek, New AsyncCallback(AddressOf SockCallBack), Nothing)
        Debug.WriteLine("Listening On: " & MyIPAddr)
    End Sub

    Private Sub SockCallBack(ByVal ar As System.IAsyncResult)
        Dim BytesReturned = RAWSocket.EndReceive(ar)

        Dim ListboxData As String = vbNullString
            Select Case MyStateObject.buffer(9)
            Case &H1 'Protocol ICMP
            Case &H2
                    'Debug.WriteLine("IGAP,IGMP,RGMP")
            Case &H6 'TCP
                'MyThreadToCall.TypeOfData = TypeOfPacket.TCP
                'MyThreadToCall.STRData = DumpTCP(MyStateObject.buffer, BytesReturned, MyThreadToCall.TypeOfData)
            Case &H11 'UDP
            Case Else
                    'Debug.Write("Protocol Unknown - " & Hex$(MyStateObject.buffer(9)))
            End Select

        'For i = 0 To BytesReturned - 1
        ' Debug.Write(Hex$(MyStateObject.buffer(i)) & " ")
        ' If i = 9 Or i = 19 Or i = 29 Or i = 39 Or i = 49 Then Debug.WriteLine("")
        ' Next
        ' Debug.WriteLine("")
        ' Debug.WriteLine("")
        '

        Select Case MyStateObject.buffer(9)
            Case &H1
                Dim FROMIP As String = MyStateObject.buffer(12) & "." & MyStateObject.buffer(13) & "." & MyStateObject.buffer(14) & "." & MyStateObject.buffer(15)
                Dim DESTIP As String = MyStateObject.buffer(16) & "." & MyStateObject.buffer(17) & "." & MyStateObject.buffer(18) & "." & MyStateObject.buffer(19)

                If FROMIP = MyIPAddr Then
                    If MyStateObject.buffer(20) = 0 Then 'Ping Reply
                        Debug.WriteLine("You sent a Ping Reply to: " & DESTIP)
                    Else
                        Debug.WriteLine("You sent a Ping Request to: " & DESTIP)
                    End If
                    RAWSocket.BeginReceive(MyStateObject.buffer, 0, MyStateObject.BUFFER_SIZE, System.Net.Sockets.SocketFlags.None, New AsyncCallback(AddressOf SockCallBack), Nothing)
                    Exit Sub
                End If

                If MyStateObject.buffer(20) = 0 Then 'Ping Reply
                    Debug.WriteLine("Ping Reply: " & FROMIP)
                    RAWSocket.BeginReceive(MyStateObject.buffer, 0, MyStateObject.BUFFER_SIZE, System.Net.Sockets.SocketFlags.None, New AsyncCallback(AddressOf SockCallBack), Nothing)
                    Exit Sub
                End If

                Debug.WriteLine("Ping Request From - " & FROMIP & " | Bytes: " & (BytesReturned - 28) & " | TTL=" & MyStateObject.buffer(8)) '-28 shows the ping payload


                'If TempClass.STRData <> vbNullString Then
                'Me.Invoke(New MyDelPtr(AddressOf TempClass.ADDTOLISTBOX)) 'Invoke on main thread
                'End If
                'For i = 0 To BytesReturned - 1
                ' Debug.Write(Hex$(MyStateObject.buffer(i)) & " ")
                ' If i = 9 Or i = 19 Or i = 29 Or i = 39 Or i = 49 Then Debug.WriteLine("")
                ' Next
            Case &H2
                'Debug.WriteLine("IGAP,IGMP,RGMP")
            Case &H6
                Debug.WriteLine("TCP ")
                Dim DestPort As UInteger = MyStateObject.buffer(22)
                DestPort <<= 8
                DestPort += MyStateObject.buffer(23)

                Dim SrcPort As UInteger = MyStateObject.buffer(20)
                SrcPort <<= 8
                SrcPort += MyStateObject.buffer(21)

                Dim FROMIP As String = MyStateObject.buffer(12) & "." & MyStateObject.buffer(13) & "." & MyStateObject.buffer(14) & "." & MyStateObject.buffer(15)

                Dim Data As String = vbNullString '= System.Text.ASCIIEncoding.ASCII.GetString(MyStateObject.buffer)

                For Each MyByte As Byte In MyStateObject.buffer
                    If MyByte >= 32 AndAlso MyByte <= 126 Then
                        Data &= Chr(MyByte)
                    End If
                Next

                If DestPort = 5060 Or SrcPort = 5060 Then
                    Debug.WriteLine("Phone!")
                    Debug.WriteLine("Data: " & SrcPort & " -> " & DestPort & " | " & Data)
                End If

                If (Data.Contains("INVITE sip:")) Then
                    'From: "IS Sys Ops 1" <sip:1549@10.1.20.42>
                    'To: <sip:6588@ccm-02.emc.org>

                End If

                Dim myTo As String
                Dim myFrom As String

                Dim matches As MatchCollection = Regex.Matches(Data, "(To|From):.*?<sip:[\d]{1,4}@.*?>")
                ' Loop over matches.
                For Each m As Match In matches
                    ' Loop over captures.
                    For Each c As Capture In m.Captures
                        ' Display.
                        'Console.WriteLine("Index={0}, Value={1}", c.Index, c.Value)
                        If c.Value.Contains("From:") Then
                            myFrom = c.Value
                        End If
                        If c.Value.Contains("To:") Then
                            myTo = c.Value
                        End If
                    Next
                Next

                If Data.Contains("INVITE sip") Then
                    Console.WriteLine("Incomming call: " & myFrom & " -> " & myTo)

                    'RaiseEvent CallIncomming()
                End If

                If Data.Contains("Request Cancelled") Then
                    Console.WriteLine("Request Canceled: " & myFrom & " -> " & myTo)
                    'RaiseEvent CallMissed()
                End If

                If Data.Contains("RingingVia") Then
                    Console.WriteLine("Rining Phone: " & myFrom & " -> " & myTo)
                    'RaiseEvent CallMissed()
                End If

                If Data.Contains("CANCEL sip") Then
                    Console.WriteLine("CANCEL sip: " & myFrom & " -> " & myTo)
                    'RaiseEvent CallMissed()
                End If

                If Data.Contains("UPDATE sip") Then
                    Console.WriteLine("UPDATE sip: " & myFrom & " -> " & myTo)
                    'RaiseEvent CallMissed()
                End If

                If Data.Contains("BYE sip") Then
                    Console.WriteLine("Call ending: " & myFrom & " -> " & myTo)
                    ' RaiseEvent CallEnded()
                End If

                If Data.Contains("Accepted") Then
                    Console.WriteLine("Accepted: " & myFrom & " -> " & myTo)
                    'RaiseEvent CallStarted()
                End If

                Select Case MyStateObject.buffer(33)
                    Case &H2
                        'Debug.Write("[SYN] - ")
                    Case &H10
                        'Debug.Write("[ACK] - ")
                    Case &H11
                        'Debug.Write("[FIN, ACK] - ")
                    Case &H12
                        'Debug.Write("[SYN, ACK] - ")
                    Case &H14
                        'Debug.Write("[RST, ACK] - ")
                    Case &H18
                        Debug.Write("[PSH, ACK] - ")
                    Case Else
                        'Debug.Write("[Unknown] - ")
                End Select
                'DumpLayer4(MyStateObject.buffer)
            Case &H11
                'Debug.Write("UDP - ")
                'Debug.WriteLine("")
            Case Else
                'Debug.Write("Protocol Unknown - " & Hex$(MyStateObject.buffer(9)))
        End Select

        'For i = 0 To BytesReturned - 1
        ' Debug.Write(Hex$(MyStateObject.buffer(i)) & " ")
        ' If i = 9 Or i = 19 Or i = 29 Or i = 39 Or i = 49 Then Debug.WriteLine("")
        ' Next
        ' Debug.WriteLine("")
        ' Debug.WriteLine("")
        '
        RAWSocket.BeginReceive(MyStateObject.buffer, 0, MyStateObject.BUFFER_SIZE, System.Net.Sockets.SocketFlags.None, New AsyncCallback(AddressOf SockCallBack), Nothing)

    End Sub

Now I had to do a conversion to C# to add to my VSTO plugin. This is a translations but also includes removing duped packets based on session id’s to prevent duplicate events being kicked off on the same pickup / hangup.

ArrayList ByeServerList = new ArrayList();
        ArrayList ByeSipList = new ArrayList();


        private System.Net.Sockets.Socket RAWSocket;
        private const int IOC_VENDOR = 0x18000000;
        private const int IOC_IN = -2147483648;
        private const int SIO_RCVALL = IOC_IN | IOC_VENDOR | 1;
        private const int SECURITY_BUILTIN_DOMAIN_RID = 0x20;
        private const int DOMAIN_ALIAS_RID_ADMINS = 0x220;
        private string MyIPAddr = "";
        private StateObject MyStateObject;
        public class StateObject
        {
            public System.Net.Sockets.Socket workSocket = null;
            public const int BUFFER_SIZE = 65535;
            public byte[] buffer = new byte[65536];
            public System.Text.StringBuilder sb = new System.Text.StringBuilder();
        } // StateObject

        private void ListenForRawData()
        {
            // To get local address
            string sHostName;
            sHostName = System.Net.Dns.GetHostName();
            System.Net.IPHostEntry ipE = System.Net.Dns.GetHostByName(sHostName);
            System.Net.IPAddress[] IpA = ipE.AddressList;
            MyIPAddr = IpA[0].ToString();

            MyStateObject = new StateObject();
            RAWSocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Raw, System.Net.Sockets.ProtocolType.IP);
            byte[] OptionIn = BitConverter.GetBytes(1);
            byte[] OptionOut = null;

            byte[] InByte = new byte[] { 1, 0, 0, 0 };
            byte[] outByte = new byte[5];

            // RAWSocket.Bind(New System.Net.IPEndPoint(Net.IPAddress.Any, 0))
            RAWSocket.Bind(new System.Net.IPEndPoint(System.Net.IPAddress.Parse(MyIPAddr), 0)); // must be bound to a IP
                                                                                                // 
            RAWSocket.IOControl(SIO_RCVALL, InByte, outByte);
            RAWSocket.BeginReceive(MyStateObject.buffer, 0, StateObject.BUFFER_SIZE, System.Net.Sockets.SocketFlags.Peek, new AsyncCallback(SockCallBack), null);
            Debug.WriteLine("Listening On: " + MyIPAddr);
        }

        private void SockCallBack(System.IAsyncResult ar)
        {
            var BytesReturned = RAWSocket.EndReceive(ar);

            string ListboxData = null;
            switch (MyStateObject.buffer[9])
            {
                case 0x1 // Protocol ICMP
               :
                    {
                        break;
                    }

                case 0x2:
                    {
                        break;
                    }

                case 0x6 // TCP
       :
                    {
                        break;
                    }

                case 0x11 // UDP
       :
                    {
                        break;
                    }

                default:
                    {
                        break;
                    }
            }

            // For i = 0 To BytesReturned - 1
            // Debug.Write(Hex$(MyStateObject.buffer(i)) & " ")
            // If i = 9 Or i = 19 Or i = 29 Or i = 39 Or i = 49 Then Debug.WriteLine("")
            // Next
            // Debug.WriteLine("")
            // Debug.WriteLine("")
            // 

            switch (MyStateObject.buffer[9])
            {
                case 0x1:
                    {
                        string FROMIP = MyStateObject.buffer[12] + "." + MyStateObject.buffer[13] + "." + MyStateObject.buffer[14] + "." + MyStateObject.buffer[15];
                        string DESTIP = MyStateObject.buffer[16] + "." + MyStateObject.buffer[17] + "." + MyStateObject.buffer[18] + "." + MyStateObject.buffer[19];

                        if (FROMIP == MyIPAddr)
                        {
                            if (MyStateObject.buffer[20] == 0)
                                Debug.WriteLine("You sent a Ping Reply to: " + DESTIP);
                            else
                                Debug.WriteLine("You sent a Ping Request to: " + DESTIP);
                            RAWSocket.BeginReceive(MyStateObject.buffer, 0, 65535, System.Net.Sockets.SocketFlags.None, new AsyncCallback(SockCallBack), null);
                            return;
                        }

                        if (MyStateObject.buffer[20] == 0)
                        {
                            Debug.WriteLine("Ping Reply: " + FROMIP);
                            RAWSocket.BeginReceive(MyStateObject.buffer, 0, 65535, System.Net.Sockets.SocketFlags.None, new AsyncCallback(SockCallBack), null);
                            return;
                        }

                        Debug.WriteLine("Ping Request From - " + FROMIP + " | Bytes: " + (BytesReturned - 28) + " | TTL=" + MyStateObject.buffer[8]); // -28 shows the ping payload
                        break;
                    }

                case 0x2:
                    {
                        break;
                    }

                case 0x6:
                    {
                        //Debug.WriteLine("TCP ");
                        uint DestPort = MyStateObject.buffer[22];
                        DestPort <<= 8;
                        DestPort += MyStateObject.buffer[23];

                        uint SrcPort = MyStateObject.buffer[20];
                        SrcPort <<= 8;
                        SrcPort += MyStateObject.buffer[21];

                        string FROMIP = MyStateObject.buffer[12] + "." + MyStateObject.buffer[13] + "." + MyStateObject.buffer[14] + "." + MyStateObject.buffer[15];

                        string Data = null; // = System.Text.ASCIIEncoding.ASCII.GetString(MyStateObject.buffer)

                        foreach (byte MyByte in MyStateObject.buffer)
                        {
                            if (MyByte >= 32 && MyByte <= 126)
                                Data += System.Text.ASCIIEncoding.ASCII.GetString(new[] { MyByte });
                        }

                        if (DestPort == 5060 | SrcPort == 5060)
                        {
                            Debug.WriteLine("Data: " + SrcPort + " -> " + DestPort + " | " + Data);
                        }

                        if ((Data.Contains("INVITE sip:")))
                        {
                        }

                        string myTo = null;
                        string myFrom = null;
                        string myDuration = null;

                        MatchCollection matches = Regex.Matches(Data, @"(To|From):.*?<sip:[\d]{1,4}@.*?>");
                        // Loop over matches.
                        foreach (Match m in matches)
                        {
                            // Loop over captures.
                            foreach (Capture c in m.Captures)
                            {
                                // Display.
                                // Console.WriteLine("Index={0}, Value={1}", c.Index, c.Value)
                                if (c.Value.Contains("From:"))
                                    myFrom = c.Value;
                                if (c.Value.Contains("To:"))
                                    myTo = c.Value;
                            }
                        }

                        if (Data.Contains("INVITE sip"))
                            Debug.WriteLine("Incomming call: " + myFrom + " -> " + myTo);

                        if (Data.Contains("Request Cancelled"))
                            Debug.WriteLine("Request Canceled: " + myFrom + " -> " + myTo);

                        if (Data.Contains("RingingVia"))
                            Debug.WriteLine("Rining Phone: " + myFrom + " -> " + myTo);

                        if (Data.Contains("CANCEL sip"))
                            Debug.WriteLine("CANCEL sip: " + myFrom + " -> " + myTo);

                        if (Data.Contains("UPDATE sip"))
                            Debug.WriteLine("UPDATE sip: " + myFrom + " -> " + myTo);

                        if (Data.Contains("BYE sip"))
                        {




                            MatchCollection matches3 = Regex.Matches(Data, @"Session-ID: [[0-9a-fA-F]+;");
                            // Loop over matches.
                            foreach (Match m in matches3)
                            {
                                if (ByeSipList.Contains(m.Value))
                                {
                                    //Debug.WriteLine("Call Concluded");
                                    return;
                                }
                                ByeSipList.Add(m.Value);
                            }

                            Debug.WriteLine("Call ending: " + myFrom + " -> " + myTo);

                            MatchCollection matches2 = Regex.Matches(Data, @"RTP-RxStat: Dur=[\d]+,");
                            // Loop over matches.
                            foreach (Match m in matches2)
                            {
                                myDuration = m.Value.ToString().Replace("RTP-RxStat: Dur=", "").Replace(",", "");
                                Debug.WriteLine("BYE sip: Duration of call in seconds: " + myDuration);
                            }

                            if (myDuration != null)
                            {
                                if (!AddCallLog(" " + myFrom + " -> " + myTo, Convert.ToDouble(myDuration +60))) //Add a minute to each call. Each call takes at least a minute of our day right?
                                {
                                    Debug.WriteLine("Failed to write calllog");
                                    //break;
                                }
                            }  
                        }

                        if (Data.Contains("BYEServer: Cisco-CSF") && Data.Contains("RTP-TxStat:")) //OKVia: SIP
                        {

                            MatchCollection matches3 = Regex.Matches(Data, @"Session-ID: [[0-9a-fA-F]+;");
                            // Loop over matches.
                            foreach (Match m in matches3)
                            {
                                if (ByeServerList.Contains(m.Value))
                                {
                                    //Debug.WriteLine("Call Concluded");
                                    return;
                                }
                                ByeServerList.Add(m.Value);
                            }

                            Debug.WriteLine("Call ending from Callee: " + myFrom + " -> " + myTo);

                            MatchCollection matches2 = Regex.Matches(Data, @"RTP-RxStat: Dur=[\d]+,");
                            // Loop over matches.
                            foreach (Match m in matches2)
                            {
                                myDuration = m.Value.ToString().Replace("RTP-RxStat: Dur=", "").Replace(",", "");
                                Debug.WriteLine("BYEServer: Duration of call in seconds: " + myDuration);
                            }

                            if (myDuration != null)
                            {
                                if (!AddCallLog(" " + myFrom + " -> " + myTo, Convert.ToDouble(myDuration + 60))) //Add a minute to each call. Each call takes at least a minute of our day right?
                                {
                                    Debug.WriteLine("Failed to write calllog");
                                    //break;
                                }
                            }
                        }


                        if (Data.Contains("Accepted"))
                            Debug.WriteLine("Accepted: " + myFrom + " -> " + myTo);

                        switch (MyStateObject.buffer[33])
                        {
                            case 0x2:
                                {
                                    break;
                                }

                            case 0x10:
                                {
                                    break;
                                }

                            case 0x11:
                                {
                                    break;
                                }

                            case 0x12:
                                {
                                    break;
                                }

                            case 0x14:
                                {
                                    break;
                                }

                            case 0x18:
                                {
                                    //Debug.Write("[PSH, ACK] - ");
                                    break;
                                }

                            default:
                                {
                                    break;
                                }
                        }

                        break;
                    }

                case 0x11:
                    {
                        break;
                    }

                default:
                    {
                        break;
                    }
            }

            // For i = 0 To BytesReturned - 1
            // Debug.Write(Hex$(MyStateObject.buffer(i)) & " ")
            // If i = 9 Or i = 19 Or i = 29 Or i = 39 Or i = 49 Then Debug.WriteLine("")
            // Next
            // Debug.WriteLine("")
            // Debug.WriteLine("")
            // 
            RAWSocket.BeginReceive(MyStateObject.buffer, 0, 65535, System.Net.Sockets.SocketFlags.None, new AsyncCallback(SockCallBack), null);
        }

Leave a Reply

Your email address will not be published. Required fields are marked *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax