Linux: Eigener DHCP Client

OP #5814200
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.
#5814233
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.
OP #5814263
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.
OP #5814272
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 von einem Moderator gelöscht.
#5814277
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.
#5814304
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.
#5814338
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.
#5814387
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?
OP #5814408
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
Angehängte Dateien:
#5814475
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".
OP #5814894
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.
OP #5822917
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.
OP #6807637
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.
#6808689
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren