Forum: PC-Programmierung Linux: Eigener DHCP Client


von Rainer S. (rsonline)


Lesenswert?

Programmiere gerade für Linux einen eigenen DHCP Client.

DHCPDISCOVER des eigenen Programms funktioniert, wenn vorher der Linux 
eigene Client an gewesen ist und ich den per kill deaktiviere. Ich 
bekomme dann eine Rückmeldung vom Router. Eine IP ist aber zu der Zeit 
schon vom Linux eigenen DHCP Client zugeordnet gewesen. Als Rückmeldung 
vom Router bekomme ich dann auch genau diese IP, die schon zugeordnet 
gewesen ist.

Schalte ich den Linux eigenen DHCP Client von vorn herein komplett aus 
und boote neu passiert nichts. Mein eigener DHCP Client bekommt einen 
socket und bind wird auch fehlerfrei ausgeführt.

ifconfig bringt für enp1s0 erst mal nichs.

Gebe ich in der Kommendozeile "ifconfig enp1s0 up" ein kommt die 
Meldung:

 r8169 0000:01:00.0: firmware: failed to load rtl_nic/rtl8168g-2.fw (-2)

Beim 2. Mal "ifconfig enp1s0 up" kommt die Fehlermeldung nicht mehr.

Nach dem UP Befehl wird enp1s0 aber bei "ifconfig" aufgelistet.


Beim Befehl "route" kommen keine Eintragungen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Hast Du Dir genau angesehen, wie die vom Standard-DHCP-Client 
verwendeten Netzwerkpakete aussehen? In so einem DHCP-Request können 
diverse Zusatzinformationen untergebracht werden, vielleicht genügen die 
von Deinem selbstgebastelten Client nicht, und reichen dem DHCP-Server 
nur dann aus, wenn er schon mal mit der MAC-Adresse zu tun hatte?

von (prx) A. K. (prx)


Lesenswert?

Wäre sinnvoll, wenn du dein DHCP Verfahren ein wenig beschreibst. 
Immerhin muss gewöhnliches DHCP mit Ethernet-Broadcast anfangen, weil ja 
normalerweise weder MAC noch IP vom DHCP-Server vorliegen.

Bissel interessanter wird es dann noch, wenn sich der DHCP-Server nicht 
in der Broadcast-Domain befindet, weil dann der Router mitspielen muss.

: Bearbeitet durch User
von Rainer S. (rsonline)


Lesenswert?

Rufus Τ. F. schrieb:
> Hast Du Dir genau angesehen, wie die vom Standard-DHCP-Client
> verwendeten Netzwerkpakete aussehen?

Habe mir bis jetzt nur angeschaut ob überhaupt Pakete gesendet werden.

thcpdump registriert aus- und eingehende Pakete vom eigenen Client mit 
korrekter Länge, Port, IP Nr., usw. im ersten Fall (Standard-Client war 
an und dann kill).

Das UDP Paket vom eigenen Client wird aber gar nicht erst gesendet, wenn 
der Standard-DHCP-Client von vorn herein ausgeschaltet war. Die LED An 
der Netzwerkbuchse geht auch nicht an.

Ich gehe davon aus, dass die Daten, wenn sie denn gesendet werden ok 
sind. Habe das Programm nicht komplett selbst geschrieben, sondern 
übernommen.

Beim DISCOVER Paket habe ich mal die falsche MAC Adresse angegeben. Es 
kommt dann keine Rückmeldung (Standard-Client war an und dann kill), 
während sonst eine Rückmeldung da ist, wenn die MAC ok ist. Ich gehe 
davon aus, dass mein gesendetes Paket in Ordnung ist.

Ich vermute, dass die Schnittstelle enp1s0 noch nicht richtig 
konfiguriert ist (auch wegen der Fehlermeldung beim Befehl UP, s.o.).
Oder es ist was mit der Routingtabelle.

von Rainer S. (rsonline)


Lesenswert?

A. K. schrieb:
> Wäre sinnvoll, wenn du dein DHCP Verfahren ein wenig beschreibst.
> Immerhin muss gewöhnliches DHCP mit Ethernet-Broadcast anfangen, weil ja
> normalerweise weder MAC noch IP vom DHCP-Server vorliegen.

Broadcast ist verwendet worden. Das ist mir schon bekannt.
Im 1. Szenario ist ja soweit vom Paket alles in Ordnung meiner Meinung 
nach. Und die Fritzbox bietet ja auch eine IP Nr. an.

> Bissel interessanter wird es dann noch, wenn sich der DHCP-Server nicht
> in der Broadcast-Domain befindet, weil dann der Router mitspielen muss.

?
Da ist eine (einfache) Fritzbox dran.

Beitrag #5814274 wurde vom Autor gelöscht.
von (prx) A. K. (prx)


Lesenswert?

Rainer S. schrieb:
>> Bissel interessanter wird es dann noch, wenn sich der DHCP-Server nicht
>> in der Broadcast-Domain befindet, weil dann der Router mitspielen muss.
>
> ?
> Da ist eine (einfache) Fritzbox dran.

Das bezog sich auf Netze mit mehreren IP-Segmenten (Broadcast-Domains), 
aber zentralem DHCP. Nicht auf einfache Heimnetze, die nur aus einer 
Fritzbox ohne zusätzlichem Router bestehen.

von Pandur S. (jetztnicht)


Lesenswert?

Erst mal muss der DHCP server mit ARP packeten klarkommen. Etwas im 
Sinne von "MAC 76:23:23:56:67:88 sucht DHCP"

von (prx) A. K. (prx)


Lesenswert?

Zitronen F. schrieb:
> Erst mal muss der DHCP server mit ARP packeten klarkommen. Etwas im
> Sinne von "MAC 76:23:23:56:67:88 sucht DHCP"

ARP-Frames sind dafür eigentlich nicht zwingend nötig.

Der Server sieht den DHCP-Broadcast und hat damit bereits die MAC des 
DHCP-Clients und in der eigenen Antwort die IP. Die kann direkt so raus.

Der Client kriegt die DHCP-Antwort bereits mit MAC und IP des 
DHCP-Servers, und das landet in dessen ARP-Table.

ARP wird nur nötig, wenn es im DHCP keine Verbindung zum ARP gibt, d.h. 
wenn auf Client und/oder Server die MAC/IP Information nicht schon im 
DHCP-Verfahren in der ARP-Table landet.

: Bearbeitet durch User
von Gerd E. (robberknight)


Lesenswert?

Rainer S. schrieb:
> Die LED An
> der Netzwerkbuchse geht auch nicht an.
[...]
> Ich vermute, dass die Schnittstelle enp1s0 noch nicht richtig
> konfiguriert ist (auch wegen der Fehlermeldung beim Befehl UP, s.o.).

Ja, danach sieht es mir auch aus.

Klappt es, wenn Du den normalen DHCP-Client nicht automatisch beim Boot 
starten lässt, sondern hinterher von Hand aufrufst?

Wenn ja, dann würde ich das mal mit strace machen. Dann siehst Du was 
für Syscalls der macht um die Schnittstelle zum Laufen zu bekommen.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Rainer S. schrieb:
> Programmiere gerade für Linux einen eigenen DHCP Client.

Ja, kann man machen wenn man sich langweilt.

Rainer S. schrieb:
> Ich gehe davon aus, dass die Daten, wenn sie denn gesendet werden ok
> sind. Habe das Programm nicht komplett selbst geschrieben, sondern
> übernommen.

Also doch kein eigener Client sondern was zusammenkopiertes.

Egal,

> Ich vermute, dass die Schnittstelle enp1s0 noch nicht richtig
> konfiguriert ist (auch wegen der Fehlermeldung beim Befehl UP, s.o.).
> Oder es ist was mit der Routingtabelle.

Der unter Linux übliche DHCP Client vom ISC verwendet zur Interaktion 
mit dem Rest des Betriebssystems ein Script /etc/dhclient-script bzw. 
/sbin/dhclient-script

Alles was dort passiert muss dein eigener Client zur gegebenen Zeit 
selber machen. Da wird die vom Server empfangene Route zum Gateway 
(Router) konfiguriert, der Resolver (DNS) konfiguriert, der Rechnername 
und die Zeitzone gesetzt und ein Haufen anderes Zeug.

Wenn ich raten soll warum du eine unvollständige Netzwerkkonfiguration 
hast, dann würde ich sagen weil dein zusammenkopierter Client die 
benötigten Konfigurationen nicht ausführt. Wetten nach Eingabe von sudo 
dhclient -r enp1s0 ist "plötzlich" alles da?

von Rainer S. (rsonline)


Angehängte Dateien:

Lesenswert?

Gerd E. schrieb:
> Klappt es, wenn Du den normalen DHCP-Client nicht automatisch beim Boot
> starten lässt, sondern hinterher von Hand aufrufst?

Ja, das klappt!

Ich habe die Holzhammer Methode angewendet und /sbin/dhclient in 
dhclient2 umbenannt, damit dieser nicht gestartet werden kann.

Rufe ich dann nach dem Booten in der Terminalconsole /sbin/dhclient2 auf 
kommt erst mal die gleiche Fehlermeldung wie oben, als ich "ifconfig 
enp1s0 up" eingegeben habe.

 r8169 0000:01:00.0: firmware: failed to load rtl_nic/rtl8168g-2.fw (-2)

Das hat also damit nicht direkt was zu tun. Linux hat wohl einen 
Standard, bzw. Ersatztreiber für die Netzwerkkarte.

> Wenn ja, dann würde ich das mal mit strace machen. Dann siehst Du was
> für Syscalls der macht um die Schnittstelle zum Laufen zu bekommen.

https://linuxwiki.de/strace

Ausgabe im Anhang

von Gerd E. (robberknight)


Lesenswert?

Rainer S. schrieb:
>  r8169 0000:01:00.0: firmware: failed to load rtl_nic/rtl8168g-2.fw (-2)
>
> Das hat also damit nicht direkt was zu tun. Linux hat wohl einen
> Standard, bzw. Ersatztreiber für die Netzwerkkarte.

Vermutlich wird gar keine Firmware für die Karte benötigt. Sehr gut.

>> Wenn ja, dann würde ich das mal mit strace machen. Dann siehst Du was
>> für Syscalls der macht um die Schnittstelle zum Laufen zu bekommen.
>
> Ausgabe im Anhang

Mist, der spannende Teil geht wohl per Netlink. Das sieht man zwar, 
müsste man allerdings erst aufwendig von Hand decodieren.

Ich würde jetzt einen anderen Ansatz versuchen und schauen auf welcher 
Ebene etwas falsch konfiguriert ist.

Das "ip" Utility bietet in die Richtung recht viele Möglichkeiten. Bei 
aktuellen Distributionen (und mit installiertem jq) bekommst Du so 
relativ viele Details heraus:
1
ip --json --detail link show | jq

Das könntest Du vor und nach dem Aufruf des DHCP-Clients machen und die 
Ausgabe diffen. Dann siehst Du was der verändert.

Bei älteren Versionen von ip kannst Du auch das --json und den 
json-pretty-printer jq weglassen, dann ist die Ausgabe halt nicht so 
schön lesbar.

Außer dem "link show" gibt es auch noch "addr show".

von Rainer S. (rsonline)


Lesenswert?

1
socket(AF_PACKET, SOCK_RAW, 768)        = 5
2
ioctl(5, SIOCGIFINDEX, {ifr_name="enp1s0", }) = 0
3
bind(5, {sa_family=AF_PACKET, sll_protocol=htons(0 /* ETH_P_??? */), sll_ifindex=if_nametoindex("enp1s0"), sll_hatype=ARPHRD_NETROM, sll_pkttype=PACKET_HOST, sll_halen=0}, 20) = 0
4
socket(AF_INET, SOCK_DGRAM, IPPROTO_IP) = 6
5
ioctl(6, SIOCGIFHWADDR, {ifr_name="enp1s0", ifr_hwaddr=00:22:4d:b7:26:b5}) = 0
6
close(6)                                = 0
7
setsockopt(5, SOL_PACKET, PACKET_AUXDATA, [1], 4) = 0
8
setsockopt(5, SOL_SOCKET, SO_ATTACH_FILTER, "\v\0\0\0`\30S\0", 8) = 0
9
fcntl64(5, F_SETFD, FD_CLOEXEC)         = 0
10
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) = 6
11
setsockopt(6, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
12
bind(6, {sa_family=AF_INET, sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
13
fcntl64(6, F_SETFD, FD_CLOEXEC)         = 0

Hier fängt es wohl an.
Ich denke, das geht nur mit dem SOCK_RAW Typ.
Der kann dann wohl auch alle Pakete empfangen und so alles mögliche 
senden. Allerdings ist man dann auch für die Headerdaten mit 
verantwortlich.

Was ist Netlink?

Falls die Rohdaten der Pakete irgendwie abgefragt werden können würde 
mich das schon interessieren.

von Rainer S. (rsonline)


Lesenswert?

Mit einem raw socket und die Bindung an der Ethernet Schnittstelle kann 
ich senden und empfangen, ohne dass die Schnittstelle eine IP Adresse 
hat. Die Daten haben aber wohl jetzt ein anderes Format.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Den Fehler mit der nicht gefundenen Firmware kannst du voellig 
ignorieren. Oder halt auch abstellen, wenn du dir die entsprechenden 
Firmwarefiles dahinkopierst, wo sie der Treiber haben moechte. Macht 
aber iirc keinen Unterschied.

Gruss
WK

von Rainer S. (rsonline)


Lesenswert?

Es läuft jetzt mit AF_PACKET und SOCK_RAW.
Allerdings ist man dann für alle Protokolle selbst verantwortlich

Ethernet Header -> IP Header -> UDP Header -> DHCP Anfrage (BootP 
Record)

Ich bekomme jetzt Antwort vom Router mit IP Adresse und Adresse vom DHCP 
Server (FritzBox).

Allerdings steht bei der Antwort von der FB bei Gateway immer 0.0.0.0.
Was hat das zu bedeuten?

Auch mit der Routing Tabelle kenne ich mich (noch) nicht aus.
Da steht noch nichts drin.

Ganz normaler Rechner mit Anschluss an die FritzBox.

von Rainer S. (rsonline)


Lesenswert?

Es lief doch nicht richtig mit dem RAW Socket. So kompliziert war das 
auch gar nicht nötig. Ich bin ja unnötigerweise bis in die IP Pakete 
gegangen, weil das bei der strace Ausgabe von Linux so drin stand. Habe 
mir da total einen abgebrochen.

Nachdem ich ein Beispiel Code von der W5500 Library gesehen habe geht es 
jetzt seit 2 Tagen einwandfrei.

Hier
https://www.wiznet.io/product-item/w5500/
Und hier
https://github.com/Wiznet/ioLibrary_Driver

Allerdings muss ich es schon in gewisser Weise selbst (um-) schreiben, 
da ich in Pascal programmiere.

Das W5500 Teil ist richtig gut für einfache Anwendungen am 
Mikrocontroller.

Die Sache ist aber noch, dass bei der DHCP Abfrage kein Gateway 
zurückgegeben wird. Weder von Fritzboxen noch vom Telekom Router.

Wenn ich unter Linux jetzt die zugewiesene Netzwerkadresse einstelle 
brauche ich ja auch ein Gateway. Ist das dann die Router (Server) 
Adresse? Ich denke ja.
Netzmaske bekomme ich.

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Rainer S. schrieb:
> Die Sache ist aber noch, dass bei der DHCP Abfrage kein Gateway
> zurückgegeben wird. Weder von Fritzboxen noch vom Telekom Router.

Hab' grad mal geguckt; also meine Fritzbox gibt bei der DHCP Offer in 
der Option 3 einen "Router" an. Das ist der Gateway.

Gruss
WK

von Rainer S. (rsonline)


Lesenswert?

Ja ok, das macht meine auch. Ich wusste nicht, dass das dann die 
Gatewayadresse ist. Ich dachte eigentlich, dass die Gatewayadresse im 
oberen Feld 'giaddr' eingetragen wird. Doch da steht 0.0.0.0

https://techhub.hpe.com/eginfolib/networking/docs/switches/5120si/cg/5998-8491_l3-ip-svcs_cg/content/436042653.htm

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Rainer S. schrieb:
> Ja ok, das macht meine auch. Ich wusste nicht, dass das dann die
> Gatewayadresse ist. Ich dachte eigentlich, dass die Gatewayadresse im
> oberen Feld 'giaddr' eingetragen wird. Doch da steht 0.0.0.0
>
> 
https://techhub.hpe.com/eginfolib/networking/docs/switches/5120si/cg/5998-8491_l3-ip-svcs_cg/content/436042653.htm

Du schraubst jetzt über zwei Jahre an deinem DHCP-Client aber hast die 
entsprechenden DHCP Standards (RFC2131, RFC2132, ...) nicht auf einem 
Tastenkürzel, um nicht sagen auswendig gelernt?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.