Making network protocols go crazy - Mot-clé - C2014-01-03T14:20:29+01:00grurn:md5:823289cecb88b10a72ab37a35928e25dDotclearlibdnet, mon amie ... pose ce couteauurn:md5:3280596d5f0b0ef8f9173a74f68793092008-10-26T13:04:00+01:002012-08-09T13:22:12+02:00grProgrammationClibdnetpatch <p>En utilisant <a href="http://libdnet.sourceforge.net/" hreflang="en">libdnet</a> (version 1.11, la dernière) sous votre OS préféré (heu ... Linux ?), vous êtes probablement déjà tombé sur ce message :</p>
<pre>
% 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
</pre>
<p>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 <strong>ifconfig</strong>. 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.</p>
<p>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 <strong>src/intf.c</strong> :</p>
<pre>
if (addr_ston(&ifr.ifr_addr, &entry->intf_link_addr) < 0)
return (-1);
</pre>
<p>La fonction <strong>addr_ston()</strong> 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 <strong>sa_family</strong> 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 <strong>addr_ston()</strong> dans <strong>src/addr.c</strong> de la façon suivante :</p>
<pre>
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;
</pre>
<p>On compile, on installe, et voilà :</p>
<pre>
% 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
</pre>