2

My objective is to list all the ip cameras in a given network by C# code.

I am able to list all the ip addresses on my network using the GetIpNetTable(C# code) here.

Can sharppcap be of any help in this regard?

Note I am absolutely new to networking, so please bear with me.

Or is there any other way by which given an ip address, I could first verify if its an ip cam and then get its details. Note that ip-camera could be of any make.

Community
  • 1
  • 1
VivekDev
  • 20,868
  • 27
  • 132
  • 202

1 Answers1

4

IP Cameras uses onvif standard. According to that you can list all ip cameras on your network by sending a xml soap message to broadcasting ip address on port 3702 using UDP protocol.

So if you are on single level network then your broadcast address will be 192.168.1.255. Please google about broadcasting address as I am not a network person and cannot explain it better.

So here is what you need to do.

  1. Create a UdpClient and connect to IP 192.168.1.255 on port 3702
  2. Create a SOAP message to request network cameras to give their ip address
  3. Send this soap message using your UdpClient.
  4. Wait for responses
  5. Once a response is arrived, convert that byte data into string
  6. This string contains IP address which you need.
  7. Read onvif specs and see what you can do. or read this

I am pasting code for your reference.

private static async Task<List<string>> GetSoapResponsesFromCamerasAsync()
        {
            var result = new List<string>();

            using ( var client = new UdpClient() )
            {
                var ipEndpoint = new IPEndPoint( IPAddress.Parse( "192.168.1.255" ), 3702 );
                client.EnableBroadcast = true;
                try
                {
                    var soapMessage = GetBytes( CreateSoapRequest() );
                    var timeout = DateTime.Now.AddSeconds( TimeoutInSeconds );
                    await client.SendAsync( soapMessage, soapMessage.Length, ipEndpoint );

                    while ( timeout > DateTime.Now )
                    {
                        if ( client.Available > 0 )
                        {
                            var receiveResult = await client.ReceiveAsync();
                            var text = GetText( receiveResult.Buffer );
                            result.Add( text );
                        }
                        else
                        {
                            await Task.Delay( 10 );
                        }
                    }
                }
                catch ( Exception exception )
                {
                    Console.WriteLine( exception.Message );
                }
            }

            return result;
        }

        private static string CreateSoapRequest()
        {
            Guid messageId = Guid.NewGuid();
            const string soap = @"
            <?xml version=""1.0"" encoding=""UTF-8""?>
            <e:Envelope xmlns:e=""http://www.w3.org/2003/05/soap-envelope""
            xmlns:w=""http://schemas.xmlsoap.org/ws/2004/08/addressing""
            xmlns:d=""http://schemas.xmlsoap.org/ws/2005/04/discovery""
            xmlns:dn=""http://www.onvif.org/ver10/device/wsdl"">
            <e:Header>
            <w:MessageID>uuid:{0}</w:MessageID>
            <w:To e:mustUnderstand=""true"">urn:schemas-xmlsoap-org:ws:2005:04:discovery</w:To>
            <w:Action a:mustUnderstand=""true"">http://schemas.xmlsoap.org/ws/2005/04/discovery/Probe</w:Action>
            </e:Header>
            <e:Body>
            <d:Probe>
            <d:Types>dn:Device</d:Types>
            </d:Probe>
            </e:Body>
            </e:Envelope>
            ";

            var result = string.Format( soap, messageId );
            return result;
        }

        private static byte[] GetBytes( string text )
        {
            return Encoding.ASCII.GetBytes( text );
        }

        private static string GetText( byte[] bytes )
        {
            return Encoding.ASCII.GetString( bytes, 0, bytes.Length );
        }

        private string GetAddress( string soapMessage )
        {
            var xmlNamespaceManager = new XmlNamespaceManager( new NameTable() );
            xmlNamespaceManager.AddNamespace( "g", "http://schemas.xmlsoap.org/ws/2005/04/discovery" );

            var element = XElement.Parse( soapMessage ).XPathSelectElement( "//g:XAddrs[1]", xmlNamespaceManager );
            return element?.Value ?? string.Empty;
        }
adeel41
  • 3,123
  • 1
  • 29
  • 25
  • I am getting the count as 0 for List, which means there are no cams found. Also GetAddress method is not referenced any where, am I missing something? – VivekDev Apr 21 '16 at 10:10
  • 1
    GetAddress is the last method in the code snippet which I pasted. If you are getting 0 result then make sure there are camera ips on same network or otherwise change the broadcast ip address to a different range. Try this ip address 239.255.255.250 – adeel41 Apr 21 '16 at 10:24
  • I had discovered that the broadcast address is 192.168.7.255. I used the info avaialbe at http://stackoverflow.com/q/18551686/1977871. Now my I am getting 45 which seems to be correct. Let me analyze a bit further. Thanks once again. – VivekDev Apr 21 '16 at 11:06
  • @VivekDev if you think it is the appropriate answer then can you mark it as an answer. – adeel41 Apr 23 '16 at 20:29
  • The following is also a good reference. But I have not tried it. http://stackoverflow.com/questions/13416193/how-to-discover-onvif-devices-in-c-sharp. But here I see that the SOAP is a bit different. Instead of dn:Device, its dn:NetworkVideoTransmitter. Also instead of xmlns:dn=""http://www.onvif.org/ver10/device/wsdl"">, its xmlns:dn="http://www.onvif.org/ver10/network/wsdl">. Not clear what these differences mean – VivekDev Apr 26 '16 at 01:15
  • 1
    The soap message which I used in my example is a probe request which is defined in device.wsdl and the NetworkVideoTransmitter request which is defined in network.wsdl is used to retrieve the url of RTSP stream which is basically the video stream url. You can then use VLC player or anything else to watch the stream or use ffmpeg to transcode it to mp4 – adeel41 Apr 26 '16 at 10:12
  • 1
    If you want to know what you can do then read the wsdl specs on this page http://www.onvif.org/Documents/Specifications.aspx – adeel41 Apr 26 '16 at 10:18