Frage

ich eine SIP-Anwendung, die UDP-Pakete senden muss, um die SIP-Anrufe einzurichten. SIP besitzt einen Timeout-Mechanismus mit Übermittlungsfehlern zu bewältigen. Eine weitere Sache Ich mag wäre in der Lage sein, zu tun ist, zu erkennen, ob ein UDP-Socket geschlossen wird, um die 32s erneut übertragen Intervall SIP verwendet warten.

Die Fälle, die ich meine, sind, wenn ein Versuch, ein UDP-Sockets führt zu einem ICMP Destination Unreachable-Paket senden von der Remote-Host erzeugt wurde. Wenn ich ein UDP-Paket an einen Host zu senden versuchen, nach oben ist aber, dass der Port nicht zuhört ich die ICMP-Nachricht sehen kann wieder mit einem Paket Tracer ankommen, aber die Frage ist, wie kann ich den Zugriff auf das bekommen von meinem C # -Code?

Ich spiele um mit Raw Sockets aber bisher noch nicht gelungen, die ICMP-Paketen durch mein Programm aufgenommen werden, zu erhalten. Das folgende Beispiel nie ein Paket empfängt, obwohl ICMP-Nachrichten auf meinem PC ankommen.

Socket icmpListener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
icmpListener.Bind(new IPEndPoint(IPAddress.Any, 0));

byte[] buffer = new byte[4096];
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
int bytesRead = icmpListener.ReceiveFrom(buffer, ref remoteEndPoint);
logger.Debug("ICMPListener received " + bytesRead + " from " + remoteEndPoint.ToString());

Hier ist eine wireshark Spur der ICMP-Antworten in meinen PC zeigt, die von einem Versuch, aus Richtung 10.0.0.100 ein UDP-Paket zu senden (mein PC) bis 10.0.0.138 (mein Router) auf einem Port Ich weiß es ist nicht abhört. Mein Problem ist, wie die Verwendung dieser ICMP-Pakete an, um die UDP-Sende zu erkennen, hat eher ausgefallen als nur für die Anwendung warten, nach einer beliebigen Zeit Timeout?

ICMP-Antworten auf UDP senden

War es hilfreich?

Lösung

Fast 3 Jahre später, und ich stolperte über http://www.codeproject.com / Artikel / 17031 / A-Netzwerk-Sniffer-in-C , die mir genug von einem Hauch gab mir eine Lösung zu empfangen ICMP-Pakete auf Windows 7 (weiß nicht über Vista, die die ursprüngliche Frage finden helfen diese Lösung wurde über aber ich vermute, funktionieren würde).

Die beiden wichtigsten Punkte sind, dass die Buchse auf eine einzige bestimmte IP-Adresse gebunden werden muss, anstatt IPAddress.Any und der IOControl Anruf, der die SIO_RCVALL Flag setzt.

Socket icmpListener = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
icmpListener.Bind(new IPEndPoint(IPAddress.Parse("10.1.1.2"), 0));
icmpListener.IOControl(IOControlCode.ReceiveAll, new byte[] { 1, 0, 0, 0 }, new byte[] { 1, 0, 0, 0 });

byte[] buffer = new byte[4096];
EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
int bytesRead = icmpListener.ReceiveFrom(buffer, ref remoteEndPoint);
Console.WriteLine("ICMPListener received " + bytesRead + " from " + remoteEndPoint);
Console.ReadLine();

Ich musste auch eine Firewall-Regel festgelegt ICMP Port Unreachable Pakete empfangen werden, zu ermöglichen.

netsh advfirewall firewall add rule name="All ICMP v4" dir=in action=allow protocol=icmpv4:any,any

Andere Tipps

Icmp wird mit einer Kennung , das für jede icmp "Session" (für jeden icmp-Buchse), anders zu sein scheint. So ist die Antwort auf ein ICMP-Paket nicht durch den gleichen Socket gesendet ist hilfreich gefiltert für Sie. Aus diesem Grunde ist das Stück Code funktioniert nicht. (Ich bin darüber nicht sicher. Es ist nur eine Annahme, nach einem bestimmten ICMP-Datenverkehr an.)

Sie könnten einfach die Host-ping und sehen, ob Sie es erreichen können oder nicht und dann SIP Sache versuchen. Allerdings, die nicht funktionieren, wenn der andere Host icmp Ausfiltern.

Eine hässliche (aber funktionierende) Lösung wird mit winpcap . (Mit diesem als die einzigen funktionierende Lösungen scheint einfach zu schlecht, um wahr zu sein.)

Was ich damit meine winpcap verwendet, ist das könnten Sie capture ICMP-Verkehr und dann auf sehen, ob das erfasste Paket über Ihre UDP-Paket ist unzustellbar oder nicht ist.

Hier ist ein Beispiel für die Erfassung von TCP-Paketen: http://www.tamirgal.com/home/ SourceView.aspx? Item = SharpPcap & Datei = Example6.DumpTCP.cs (Es sollte nicht allzu schwer sein, das gleiche mit ICMP zu tun.)

UPDATE: Ich glaube, ich werde verrückt .... Das Stück Code, den Sie auch für mich geschrieben arbeitet ...

Das folgende Stück Code funktioniert für mich (xp sp3) fein:

using System;
using System.Net;
using System.Net.Sockets;

namespace icmp_capture
{
    class Program
    {
        static void Main(string[] args)
        {            
            IPEndPoint ipMyEndPoint = new IPEndPoint(IPAddress.Any, 0);
            EndPoint myEndPoint = (ipMyEndPoint);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);            
            socket.Bind(myEndPoint);
            while (true)
            {

                /*                
                //SEND SOME BS (you will get a nice infinite loop if you uncomment this)
                var udpClient = new UdpClient("192.168.2.199", 666);   //**host must exist if it's in the same subnet (if not routed)**              
                Byte[] messagebyte = Encoding.Default.GetBytes("hi".ToCharArray());                
                int s = udpClient.Send(messagebyte, messagebyte.Length);
                */

                Byte[] ReceiveBuffer = new Byte[256];
                var nBytes = socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref myEndPoint);
                if (ReceiveBuffer[20] == 3)// ICMP type = Delivery failed
                {
                    Console.WriteLine("Delivery failed");
                    Console.WriteLine("Returned by: " + myEndPoint.ToString());
                    Console.WriteLine("Destination: " + ReceiveBuffer[44] + "." + ReceiveBuffer[45] + "." + ReceiveBuffer[46] + "." + ReceiveBuffer[47]);
                    Console.WriteLine("---------------");
                }
                else {
                    Console.WriteLine("Some (not delivery failed) ICMP packet ignored");
                }
            }

        }
    }
}

Verwenden Sie einfach angeschlossenes UDP-Sockets und das Betriebssystem wird das ICMP nicht erreichbar entsprechen und einen Fehler in den UDP-Sockets zurück.

Google für angeschlossene UDP-Sockets.

Es gibt eine Reihe von Stellen auf dem Netz, das Problems der ICMP Port Unreachable Pakete nicht mehr erwähnen zugänglich ist auf Vista.

Der Stapel sollten Sie eine Ausnahme zurück, wenn er die ICMP empfängt. Aber es funktioniert nicht, zumindest auf Vista. Und damit Sie versuchen, eine Abhilfe.

Ich mag keine Antworten, die sagen, dass es nicht möglich ist, aber es scheint so. Deshalb schlage ich Ihnen einen Schritt zum ursprünglichen Problem zurückgehen, die in SIP lange Timeouts war.

  • Sie könnte der Benutzer lassen konfigurieren die timeout (also eine Art Einhaltung die spec).
  • Sie können mit anderen Dingen beginnen (wie andere Proxies Überprüfung) vor das Timeout endet.
  • Sie könnten bekannte cache bad Ziele (aber das müssten gute Verwaltung des Cache.
  • Wenn ICMP und UDP nicht korrekte Fehlermeldungen geben, versuchen Sie tcp oder ein anderes Protokoll. Einfach die gewünschten Informationen zu entlocken.

(Alles ist möglich, es ist nur eine Menge von Ressourcen in Anspruch nehmen.)

Ich schreibe dies als separate Antwort, da die Details von der einen ganz anderen, die ich früher geschrieben haben.

So auf der Grundlage der Kommentar von Kalmi über die Session-ID, es hat mich darüber nachzudenken, warum ich zwei Ping-Programme auf demselben Computer öffnen können, und die Antworten nicht überqueren. Sie sind beide ICMP, daher beide über Port-weniger Raw Sockets. Das bedeutet, dass etwas in dem IP-Stack, muss wissen, was die Buchse wurden diese Antworten bestimmt ist. Für Ping stellt sich heraus, es eine ID in den Daten des ICMP-Paket im Rahmen der ECHO-REQUEST und ECHO REPLY.

verwendet wird,

Dann lief ich über diesen Kommentar auf Wikipedia über ICMP :

  

Obwohl ICMP-Nachrichten enthalten sind   innerhalb von Standard-IP-Datagramme, ICMP   Nachrichten werden in der Regel als ein verarbeitetes   Sonderfall unterschieden von   normale IP-Verarbeitung, anstatt   verarbeitet, wie ein normales Unterprotokoll von   IP. In vielen Fällen ist es notwendig,   inspizieren den Inhalt der ICMP   Nachricht und liefern die entsprechende   Fehlermeldung an die Anwendung,   erzeugt, um das ursprüngliche IP-Paket, das   eine, die aufgefordert, die von dem send   ICMP-Nachricht.

, die auf (indirekt) erarbeitet hier :

  

Das Internet-Header sowie die ersten 64   Bits der Daten des Original-Datagramm.   Diese Daten werden von dem Host verwendet übereinstimmen   die Nachricht an den entsprechenden   Prozess. Wenn ein höheres Protokoll   verwendet Portnummern, werden sie angenommen   werden in den ersten 64 Datenbits der   Original-Datagramm Daten.

Da Sie UDP verwenden, welche Ports verwendet, ist es möglich, das Netzwerk-Stack wird das Routing der ICMP-Nachricht zurück in die ursprüngliche Fassung. Deshalb ist Ihre neue und separate, Buchse wird nie diese Nachrichten zu empfangen. Ich stelle mir vor UDP die ICMP-Nachricht isst.

Wenn ich richtig bin, eine Lösung für dieses Problem ist es, einen Raw-Socket zu öffnen und manuell UDP-Pakete erstellen, für die nichts hören zurückkommen, und behandelt UDP und ICMP-Nachrichten als angemessen. Ich bin nicht sicher, was das wie in Code aussehen würde, aber ich glaube nicht, es wäre zu schwierig, und kann mehr in Betracht gezogen werden „elegant“ als die winpcap Lösung.

Zusätzlich Link http://www.networksorcery.com/enp/default1003.htm , erscheint eine große Ressource für geringe Netzwerkprotokolle zu sein.

Ich hoffe, das hilft.

So ermitteln Sie den dest nicht erreichbar Rückkehr ICMP-Paket programmatisch abholen wollen? Eine schwierige Frage. Ich würde der Netzwerk-Stack sagen, dass bis tränkt, bevor Sie irgendwo in der Nähe bekommen.

Ich glaube nicht ein reiner C # Ansatz hier funktionieren wird. Sie werden eine Treiberebene abfangen verwenden müssen, um in einen Haken zu bekommen. Schauen Sie sich diese App Nehmen Sie die Fenster ipfiltdrv.sys abzufangen Pakete verwendet (ICMP, TCP, UDP etc.) und Lesen / mit ihnen verwalteten Code spielen ( c #).

http://www.codeproject.com/KB/IP /firewall_sniffer.aspx?display=Print

  • Oisin
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top