2013-07-27 3 views
2

Je suis en train d'écrire un programme C pour la tunnellisation à l'aide d'un tuner Linux. Je suis en train de créer un appareil tun, en définissant son propriétaire, son groupe et sa persistance en utilisant les appels ioctl(). Cependant, pour faire le tunneling, j'ai besoin de définir l'adresse IP de l'appareil et configurer le lien. Je suis actuellement en utilisant ceComment paramétrer l'adresse IP du tuner et établir la liaison UP par le biais du programme C

# ip addr add 
# ip link set 

Je veux définir l'adresse, masque et définissez le lien sous up. Y at-il un moyen de le faire à travers le programme sans invoquer ip commande?

J'ai essayé d'utiliser ioctl() avec la commande SIOCSIFADDR, mais cela ne fonctionne pas pour le périphérique tun et fonctionne pour eth0. J'obtiens l'erreur ioctl() - Invalid argument.

Voici le code qui fonctionne sur eth0 mais pas sur quelque chose comme tun2:

280 void setip (int fd) { 
281 
282  struct ifreq ifr; 
283  struct sockaddr_in addr; 
284  int stat; 
285  
286  memset(&ifr, 0, sizeof(ifr)); 
287  memset(&addr, 0, sizeof(addr)); 
288  strncpy(ifr.ifr_name, in.dev.device, IFNAMSIZ);  // device name: eg. tun2 
289  
290  addr.sin_family = AF_INET; 
291  stat = inet_pton(addr.sin_family, in.dev.ip_addr, &addr.sin_addr); // ip string 
292  if (stat == 0) 
293   raise_error("inet_pton() - invalid ip"); 
294  if (stat == -1) 
295   raise_error("inet_pton() - invalid family"); 
296   
297  if (stat == 1); 
298  else 
299   raise_error("inet_pton()"); 
300   
301  ifr.ifr_addr = *(struct sockaddr *) &addr; 
302  /* This is just to test if address conversion happened properly */ 
303  char buff[BUFF_SIZE]; 
304  char * foo; 
305  foo = inet_ntop(AF_INET, &addr.sin_addr, buff, BUFF_SIZE); 
306  if (foo == NULL) 
307   raise_error("inet_ntop()"); 
308  else 
309   printf("main = %s, addr = %s\n",in.dev.ip_addr, buff); 
310   
311  if (ioctl(fd, SIOCSIFADDR, (caddr_t) &ifr) == -1) 
312   raise_error("ioctl() - SIOCSIFADDR"); 
313 } 

J'ai cherché des méthodes pour le faire pour les appareils tun mais n'a pas pu trouver. Tous les messages que j'ai eu à utiliser ip ou ifconfig ou quelque chose du genre.

Existe-t-il un moyen de le faire via le programme? Merci

+0

la bonne façon d'y parvenir est d'utiliser IOCTL. Comme spécifié dans la documentation http://man7.org/linux/man-pages/man7/netdevice.7.html, IOCTL permet de configurer tous les périphériques de socket. Etes-vous sûr, ce code fonctionne avec eth0? Comment créez-vous l'appareil tun0? Désolé, je n'ai pas pu tester le code. –

+0

Salut, merci pour la réponse. J'ai testé le code pour eth0 et cela a bien fonctionné. (J'ai fait quelques modifications dans la fonction car cela fait partie d'un programme plus important). J'ai dû ajouter un appel 'socket()' pour obtenir le descripteur de fichier 'fd'. Le 'fd' dans ce code est un descripteur de périphérique tun. J'utilise à peu près le même code que celui donné sur cette [page de documentation Linux] (https://www.kernel.org/doc/Documentation/networking/tuntap.txt) Section 3.1 pour créer le dispositif tun. – aoak

Répondre

1

J'ai trouvé le problème. Dans le cas de eth0, j'utilise un descripteur de socket comme argument à ioctl(), dans le cas de tun dispositif, j'utilise un descripteur de périphérique tun. J'ai créé une prise en cas de dispositif de tun aussi et le ioctl() travaillé. Voici le code:

280 void setip (int fd) { 
281 
282  struct ifreq ifr; 
283  struct sockaddr_in addr; 
284  int stat, s; 
285 
286  memset(&ifr, 0, sizeof(ifr)); 
287  memset(&addr, 0, sizeof(addr)); 
288  strncpy(ifr.ifr_name, in.dev.device, IFNAMSIZ); 
289 
290  addr.sin_family = AF_INET; 
291  s = socket(addr.sin_family, SOCK_DGRAM, 0); 
292  stat = inet_pton(addr.sin_family, in.dev.ip_addr, &addr.sin_addr); 
293  if (stat == 0) 
294   raise_error("inet_pton() - invalid ip"); 
295  if (stat == -1) 
296   raise_error("inet_pton() - invalid family"); 
297  
298  if (stat == 1); 
299  else 
300   raise_error("inet_pton()"); 
301  
302  ifr.ifr_addr = *(struct sockaddr *) &addr; 
303  /* This is just to test if address conversion happened properly */ 
304  char buff[BUFF_SIZE]; 
305  char * foo; 
306  foo = inet_ntop(AF_INET, &addr.sin_addr, buff, BUFF_SIZE); 
307  if (foo == NULL) 
308   raise_error("inet_ntop()"); 
309  else 
310   printf("main = %s, addr = %s\n",in.dev.ip_addr, buff); 
311 
312  //if (ioctl(fd, SIOCSIFADDR, (caddr_t) &ifr) == -1) 
313  if (ioctl(s, SIOCSIFADDR, (caddr_t) &ifr) == -1) 
314   raise_error("ioctl() - SIOCSIFADDR"); 
315 } 

Merci Giuseppe Pes pour votre réponse :)

+0

ce programme utilise une même méthode avec vous: http: //linuxgazette.net/149/misc/melinte/udptun.c – xjdrew

Questions connexes