Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
Récupération d'une adresse IP en C
Envoyé par: ptit_riton

Bonjour à tous,

Je travaille actuellement sur un projet qui a besoin d'utiliser les fonctionnalités réseaux de base ( socket ), mais je souhaite gérer un fichier de configuration afin que l'utilisateur final puisse choisir sur quelle interface mon daemon va écouter ( eth0, eth1, etc ... )

Ma première idée a été d'essayer de recuperer l'adresse IP associée à ethX et la passer lors de ma creation de socket.
Seul petit problème, je ne vois absolument pas comment récuper cette adresse IP en C.

La seule solution que je voyais était de passer par un popen de ifconfig ou ip addr show, bref, pas très élégant.

Ma question est donc la suivante :

Comment peut-on faire, sous Linux, pour récuper l'adresse IP associée à une interface ?


Je vous remercie d'avance.

Poste le Saturday 27 December 2008 18:06:26
Répondre     Citer    
Re: Récupération d'une adresse IP en C

En général, pour savoir comment fait une commande, on peut en tracer les appels systèmes (avec strace ou ltrace), donc ici
strace /sbin/ifconfig

On s'aperçoit alors qu'il y a des tas de ioctl pertinents et aussi le fichier /proc/net/if_inet6

Par ailleurs, l'intérêt du logiciel libre, c'est précisément d'avoir la possibilité d'étudier le code source. Donc le plus simple, c'est de décortiquer le code de ifconfig

On tombe alors sur les net-tools qui sont obsolètes et remplacés par iproute2

Moi je n'ai jamais eu besoin d'attaquer Ethernet directement. Donc je n'en sais pas plus.

----

Basile STARYNKEVITCH

Membre de l'APRIL « promouvoir et défendre le logiciel libre » - adhérez vous aussi à l'APRIL!

Projet logiciel libre: RefPerSys

Poste le Saturday 27 December 2008 18:27:03
Répondre     Citer    
Re: Récupération d'une adresse IP en C
Envoyé par: ptit_riton

Salut à tous,

Après lecture des pages de man et re-lecture du code source du serveur dhcp3-server, je suis finalement arrivé à mes fins, alors voici le code source, pour ceux que ça pourrait intéresser :

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include<errno.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

int main(void){

        char buf [2048];
        struct ifconf ic;
        int i;
        int sock;
	struct ifreq *ifp;
        struct sockaddr_in *s; 
	char if_name[32];
	char if_addr[32];

	/* Creation de notre socket permettant d'utiliser notre IOCTL */
	if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
		fprintf(stderr,"Erreur lors de la creation de la socket pour l'ioctl : %s\n",strerror(errno));
		exit(EXIT_FAILURE);
	}

	/* On fournit un buffer vide afin de savoir de combien de place il aura besoin */
	ic.ifc_len = 0;
	ic.ifc_ifcu.ifcu_buf = (caddr_t)NULL;

getif_again:
	i = ioctl(sock, SIOCGIFCONF, &ic);

	if(i<0){
		fprintf(stderr,"Erreur lors de l'appel a IOCTL : %s\n",strerror(errno));
		exit(EXIT_FAILURE);
	}

	/* On verifie qu'il n'y a pas eu de bug */
	if(ic.ifc_ifcu.ifcu_buf == 0 && ic.ifc_len == 0){
		fprintf(stderr,"Bug trouve\n");
		/* On passe par le buffer que l'on a cree */
		ic.ifc_len = sizeof buf;
		ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
		goto getif_again;
	}

	/* On verifie que toutes les donnees ont pu tenir dans notre buffer
	 * Sinon on en alloue un plus grand
	 * Cf page de man de netdevice pour les conseils
	 * */
	if ((ic.ifc_ifcu.ifcu_buf == buf || ic.ifc_ifcu.ifcu_buf == 0) && ic.ifc_len > sizeof buf){
		if( (ic.ifc_ifcu.ifcu_buf = malloc ((size_t)ic.ifc_len)) == NULL ){
			fprintf(stderr,"Erreur lors du malloc pour la definition du buffer : %s\n",strerror(errno));
			exit(EXIT_FAILURE);
		}
		/* On refait notre IOCTL */
		goto getif_again;
	}else if(ic.ifc_ifcu.ifcu_buf == 0){
		ic.ifc_ifcu.ifcu_buf = (caddr_t)buf;
		ic.ifc_len = sizeof buf;
		goto getif_again;
	}

	for(i=0;i<ic.ifc_lenwinking smiley{
		/* Notre pointeur sur notre tableau d'elements ifreq */ 
		ifp = (struct ifreq *)((caddr_t)ic.ifc_req + i);

		/* On se deplace pour sauter au prochain element */
		i += sizeof *ifp;
		
		/* Notre pointeur sur notre structure de type sockaddr_in */
		//interface = (struct sockaddr *) &ifp->ifr_addr;

		/* On recupere les infos qui nous interessent */
		/* Nom de l'interface */
		strcpy(if_name,ifp->ifr_name);

		/* Adresse de l'interface */
		s = (struct sockaddr_in *) &(ifp->ifr_addr);
		strcpy(if_addr,inet_ntoa(s->sin_addr));

		fprintf(stdout,"Informations sur l'interface %s :\n\tAddresse : %s\n\n",if_name,if_addr);
	}

	return(EXIT_SUCCESS);
}

Voilà voilà

A la prochaine

Poste le Sunday 28 December 2008 18:35:02
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
Récupération d'une adresse IP en C
Pour poser vos questions sur les scripts shell, le Perl, le C, etc... Attention : nous ne sommes pas des spécialistes du dev, ce forum est juste pour de petites aides ponctuelles concernant le développement et les outils de développement.

Sauf mention contraire, les documentations publiées sont sous licence Creative-Commons