libdnet, mon amie ... pose ce couteau
Par GR le dimanche, octobre 26 2008, 13:04 - Programmation - Lien permanent
En utilisant libdnet (version 1.11, la dernière) sous votre OS préféré (heu ... Linux ?), vous êtes probablement déjà tombé sur ce message :
% dnet intf show lo: flags=0x3<UP,LOOPBACK> mtu 16436 inet 127.0.0.1/8 alias ::1 eth0: flags=0x31<UP,BROADCAST,MULTICAST> mtu 1500 link 00:13:a9:2c:5b:a3 dnet: intf_loop: Invalid argument
Cette situation ne doit pas être une fatalité. Alors ce dimanche, comme j'avais du temps à perdre, et surtout grâce au droit opposable au code incomplet et/ou vieillissant, j'ai pu chercher d'où venait le problème. Premier élément de réponse : la carte suivante devrait être la carte wireless de mon laptop, étant donné que c'est le cas avec ifconfig. En essayant sur une machine sans carte wireless, pas de problème ; toutes les interfaces sont affichées. Il y a de fortes chances que l'erreur soit provoquée lors de la lecture des informations de ma carte wireless.
Deuxième élément de réponse (je vous passe mes sessions de debug du source de libdnet), je finis par tomber la dessus, dans src/intf.c :
if (addr_ston(&ifr.ifr_addr, &entry->intf_link_addr) < 0)
return (-1);
La fonction addr_ston() retourne -1 lorsqu'elle tombe sur une interface IEEE 802.11. Le problème est du au fait qu'une interface IEEE 802.11 n'est pas pareil qu'une interface ethernet (doh!), par exemple. En effet, la sa_family pour une interface 802.11 possède sa propre valeur (sous Linux, c'est la valeur 801, alors qu'ethernet possède la valeur 1). Reste plus qu'à patcher addr_ston() dans src/addr.c de la façon suivante :
case AF_UNSPEC:
case ARP_HRD_ETH: /* XXX- Linux arp(7) */
+ /* Also defined in net/if_arp.h as ARPHRD_IEEE80211 */
+ case 801:
a->addr_type = ADDR_TYPE_ETH;
a->addr_bits = ETH_ADDR_BITS;
memcpy(&a->addr_eth, sa->sa_data, ETH_ADDR_LEN);
break;
On compile, on installe, et voilà :
% dnet intf show lo: flags=0x3<UP,LOOPBACK> mtu 16436 inet 127.0.0.1/8 alias ::1 eth0: flags=0x31<UP,BROADCAST,MULTICAST> mtu 1500 link 00:13:a9:2c:5b:a3 wmaster0: flags=0x31<UP,BROADCAST,MULTICAST> mtu 1500 link 00:13:02:44:63:2b eth1: flags=0x31<UP,BROADCAST,MULTICAST> mtu 1500 link 00:13:02:44:63:2b wifi0: flags=0x31<UP,BROADCAST,MULTICAST> mtu 1500 link 00:1e:2a:02:ea:de ath0: flags=0x31<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.0.101/24 link 00:1e:2a:02:ea:de alias fe80::21e:2aff:fe02:eade/64