Empfangendes Interface bei UDP-Kommunikation finden

By dose | October 31, 2008
Under: technical stuff, Uncategorized

Ich schreibe zur Zeit privat an einer kleinen RIS (Remote-Installation)-Lösung, mit der man übe rPXE ein Betriebssystem bequem und einfach übers Netzwerk installieren kann.
Dafür wollte ich auch ein kleines Feature einbauen, mit welchem man Tokens (derzeit nur einen Token) im Textfile, welches die Menüstruktur des PXE-Menüs beschreibt, hinterlegen kann, welche dann entsprechend ersetzt werden.
Konkret handelte es sich um einen Token, welcher die IP-Adresse des TFTP-Servers angeben soll.
Um Knoppix über PXE zu booten, habe ich das gepatchte Koppix verwendet, welches statt über NFS auch über SMB booten kann. Hier der entsprechend gepatchte Knoppix-Kern.
Leider benötigt dieser bei der Pfadangabe des zu bootenden Servers unbedingt die IP und kann den Namen scheinbar nicht auflösen. Da ich den Server aber möglichst flexibel halten will, dachte ich mir, ich lasse meinen TFTPD einfach die IP des Interfaces einsetzen, über den der TFTP-Server den Client bedient.
Doch das herauszufinden gestaltet sich leider alles Andere als einfach.
Ich binde den TFTPD auf alle Interfaces (INADDR_ANY). Danach verwende ich recvfrom und sendto, um Requests zu erhalten bzw. zu beantworten. Damit funktioniert das Ganze ja recht einfach, beim recvfrom erhalte ich die CLIENT-Adresse, die ich bei sendto wieder angeben muss. Doch wie bekomme ich die IP des Interfaces?
Die erste Idee war, getsockname nach dem ersten recvfrom zu verwenden. Unter BSD-Artigen Systemen ist in der resultierenden Strutur dann die jeweils verwendete Adresse zu finden (sockaddr_in). Groß war die Ernüchterung, als unter Windows jedoch 0.0.0.0 drinnen stand. Warum das so ist erklärt der Artikel Q129065 der Microsoft Knowledge Base.
Na prima, dort steht eindeutig: Applications should not assume that they can get the IP address of the interface. . Damit wollte ich mich aber nicht zufrieden geben. Irgendwie muss es doch möglich sein, trotzdem das zuständige interface herauszufinden.
Schließlich kam ich auf folgende Idee, die als Workaround ganz gut funktioniert:
Von recvfrom ist ja die IP des Clients bekannt. Also müssen wir Winsock einfach fragen, welches Interface die beste Route dorthin hat.
Mein Workaround:
DWORD br;
WSAIoctl (sock, SIO_ROUTING_INTERFACE_QUERY, &client, sizeof(client),
&server, sizeof(server), &br, 0, 0);

Gewinnt zwar keinen Schönheitspreis, aber mir ist auch keine bessere Lösung dafür bekannt.

Leave a Comment

Name:

E-Mail :

Subscribe :
Website :

Comments :