ifconfig <IP> mit ioctl(2) - wie geht das?

Herakles

Profifragensteller
Moin!

Ich möchte gern den Systembefehl

Code:
ifconfig rl0 192.168.1.1

in ein C-Programm einfügen. Hierbei möchte ich NICHT system(3) nutzen, sondern das Ganze selbst mit ioctl(2) programmmieren.

Das request, welches ich hierfür verwenden muss ist SIOCSIFADDR und der Datentyp des Pointers für das dritte Argument von ioctl(2) ist struct ifreq.

Ich definiere also ein

Code:
struct ifreq request

und setze den Namen des Interfaces in dieses struct ein:

Code:
strcpy( request.ifr_ifrn.ifrn_name, "rl0" );

Mein anschließender ioctl(2)-Befehl sieht dann folgendermaßen aus:

Code:
if( ioctl( fd_udp, SIOCSIFADDR, &request) != 0 ) {
      perror(Failed to set IP-Address");
      exit(-1);
}

Kompilieren will das Ganze prima, lediglich bei Ausführung des Codes bekomme ich Probleme. Die Software steigt genau an der "exit(-1)"-Stelle aus und zwar mit dem Fehler "Invalid argument".

Hat jemand dazu eine Lösung parat? Wie kann ich meine IP-Adresse eines Interfaces mit ioctl(2) setzen?

Vielen Dank an jeden, der bis hierher gelesen hat! :)

Herakles
 
Frage explizit nach "-1" ab, also

Code:
if( ioctl( fd_udp, SIOCSIFADDR, &request) != 0 )

So las ich in einer OpenBSD-manpage und so verfahre ich auch seitdem.

man ioctl (dort stands nicht) sagt dazu:

RETURN VALUES
If an error has occurred, a value of -1 is returned and errno is set to
indicate the error.

Gruß
Baseballbatboy
 
Hi Baseballbatboy!

Ich verstehe die Antwort nicht. Wo ist der Unterschied zu meiner Frage bei Deiner Lösung?

Ich meine, schreibst Du nicht genau das als Antwort, was ich schon gemacht habe?

Herakles
 
@.align64: erstmal vielen dank.

Prinzipiell ist der Code schon hilfreich, sowas hatte ich bereits zuvor auch gesehen. Interessant im speziellen ist nun die folgende Zeile:

Code:
addrp->sin_addr.s_addr = ip.toInetAddr();

s_addr ist vom Typ struct in_addr, welcher wie folgt definiert ist:

Code:
struct in_addr {
       __u32 s_addr;
};

Wie genau ist denn nun die Datenstruktur, die ip.toInetAddr() zurückgibt? Sprich: mit welchen Daten muss ich addrp->sin_addr.s_addr füttern? Ich denke, das ist meine letzte Hürde...

Herakles
 
Hoppala, da hab ich doch tatsächlich vergessen, die if-Bedingung abzuändern. Scheiß copy & paste!

So ist es richtig:

Code:
if( ioctl( fd_udp, SIOCSIFADDR, &request) !=-1)

Das Codebeispiel fragt nach <0, das ist streng genommen auch nicht richtig, da ioctl() nur bei Fehler -1 ausgibt, und ansonsten jede andere Zahl zurückgeben kann, auch Werte kleiner -1.

Gruß
Baseballbatboy
 
GEEEEEEEEEEEEEEEEEEEIIIIIIIIIIIIIIIIIIIIIIIIIIIIIILLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL!!!!!

Danke, Baseballbatboy, DANKEEEEEEEEEEEEE!

Geil, danke.

Herakles
 
Kleine Ergänzung:

GANZ richtig ist eigentlich dieser Code:

Code:
if( ioctl( fd_udp, SIOCSIFADDR, &request) ==-1) {
      perror(Failed to set IP-Address");
      exit(-1);
}

Der Grund? Nun, es soll ja nur in einem Fehlerfall mit perror ein Fehler geschrieben werden und mit exit das Programm verlassen werden. Dieser Fehlerfall tritt nur bei ioctl() == -1 auf.

Bei Baseballbatboys Lösung " != -1 " wird dann in die if-Abfrage gesprungen, wenn die Ausführung korrekt war. Wenn man sich ansieht, was nach der if-Abfrage zu tun sein soll, wäre das natürlich blödsinnig.

Baseballbatboy, nochmals vielen, vielen Dank. Ich habe zwei Tage lang immer mal wieder zwischendurch auf dieses kleine Problemchen geschaut und den Fehler nie gesehen. Das hat mich echt voran gebracht. Sehr geil.

Herakles
 
Natürlich ioctl() == -1, man, was bin ich schusselig. Ich bin auch noch auf der Suche nach der man-page, in der extra nochmal erwähnt wurde, das man unbedingt auf "-1" überprüfen soll und nicht auf "<0" oder "!=0". Kann auch in einer aus der Kategorie open(), write() etc. gewesen sein.

Gruß
Baseballbatboy
 
Zurück
Oben