Réseaux de capteurs sans fil: routage et sécurité
Transcription
Réseaux de capteurs sans fil: routage et sécurité
Rapport de Projet de Fin d’Etudes en vue d’obtention du Diplôme d’ingénieur en Informatique de l’INSA de Lyon Sujet: Réseaux de capteurs sans fil: routage et sécurité Réalisé par Mohammed El Mehdi DIOURI Encadré par Marine MINIER Année universitaire: 2009-2010 1 Résumé Souvent déployés dans des environnements hostiles, les réseaux de capteurs sans fil sont sujets à différentes types d’attaques. Parmi elles, il y a l’attaque Sybille, où un même noeud capteur est capable de revendiquer des identités multiples. Ainsi, en se faisant passer pour ces différentes identités, il sera un noeud capteur priviligié dans le réseau, ce qui lui permettra de compromettre plus facilement le fonctionnement général du réseau de capteur. Dans ce rapport de stage, nous présentons une proposition de lutte contre ce type d’attaques dans le contexte des réseaux de capteurs sans fil. Dans cette proposition, nous suggérons d’exploiter les caractéristiques physiques des capteurs pour identifier de façon unique chacun des noeuds capteurs. Dans ce rapport, nous évaluons aussi la pertinence de cette proposition par des expérimentations sur de vrais capteurs et par des simulations sur un environnement de simulation bien adapté. Abstract Often deployed in hostile environments, wireless sensor networks are prone to different types of attacks. Among them, there is the Sybil attack, where a single sensor node may claim multiple identities. Then, by passing for these different identities, it will gain an advantage over the others honest nodes in the sensor network, thus offering him more facilities to compromise the several functionalities of the sensor network. In this report, we suggest a mechanism to defend against such attacks in the context of wireless sensor networks. In this proposal, we suggest to exploit the physical characteristics of sensors to uniquely identify each sensor node. We evaluate the relevance of this proposal with experiments on real sensors and simulations on a suitable environment of simulation. 2 Remerciements A travers ce rapport de PFE effectué au sein du Centre d’Innovation en Télécommcations et Intégration de services (CITI), je présente mes sincères remerciements : – Au directeur du laboratoire CITI, Jean-Marie GORCE, pour m’avoir accueilli au sein de son laboratoire de recherche, – A mon encadrante, Marine MINIER, pour sa disponibilité, son écoute, ses conseils qui m’ont été d’une grande utilité ainsi que pour ses efforts pour que mon stage se déroule dans les meilleures conditions possibles, – A Cedric Lauradoux, chargé de recherches au laboratoire CITI, pour ses conseils très précieux et pour tous ses efforts afin de m’orienter au mieux. – A Wassim ZNAIDI, doctorant au laboratoire CITI, pour ses conseils qui m’ont permis d’avancer plus vite dans mes travaux, – A tous les membres du laboratoire CITI, pour la bonne ambiance qui règne au sein du laboratoire. Table des matières 1 Lutte contre les attaques Sybille 1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.1.1 Réseaux de capteurs sans fil . . . . . . . . . . . . . . . . . 1.1.2 Applications des réseaux de capteurs sans fil . . . . . . . 1.1.3 Principales attaques sur les réseaux de capteurs . . . . . . 1.1.4 L’attaque Sybille . . . . . . . . . . . . . . . . . . . . . . . 1.2 Etat de l’art . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2.1 Certification approuvée . . . . . . . . . . . . . . . . . . . 1.2.2 Test de ressources . . . . . . . . . . . . . . . . . . . . . . 1.2.3 Solutions basées sur la vérification physique . . . . . . . . 1.2.4 Solutions basées sur la vérification de la position . . . . . 1.3 Spécifications générales . . . . . . . . . . . . . . . . . . . . . . . . 1.3.1 Modèle du réseau . . . . . . . . . . . . . . . . . . . . . . . 1.3.2 Modèle d’attaques . . . . . . . . . . . . . . . . . . . . . . 1.4 Proposition du mécanisme de défense . . . . . . . . . . . . . . . . 1.4.1 Conception préliminaire . . . . . . . . . . . . . . . . . . . 1.4.2 Détection des attaques . . . . . . . . . . . . . . . . . . . . 1.5 Etude des capteurs MSP430F2274 . . . . . . . . . . . . . . . . . 1.5.1 Validation du caractère dissymétrique des horloges internes dans les capteurs . . . . . . . . . . . . . . . . . . . 1.5.2 Etude de l’évolution à court terme des temps affichées par les horloges internes des capteurs . . . . . . . . . . . . . . 1.5.3 Etude de l’évolution à long terme des temps affichées par les horloges internes des capteurs . . . . . . . . . . . . . . 1.6 Intégration des résultats des études expérimentales dans la proposition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.6.1 Affinement du calcul de λ . . . . . . . . . . . . . . . . . . 1.6.2 Affinement du calcul de µ . . . . . . . . . . . . . . . . . . 1.7 Implémentation et Simulation sous WSNet . . . . . . . . . . . . 1.7.1 Présentation de la plateforme de simulation WSNet . . . 1.7.2 Implémentation . . . . . . . . . . . . . . . . . . . . . . . . 1.7.3 Paramètres de la simulation . . . . . . . . . . . . . . . . . 1.7.4 Résultats . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.8 Conclusion partielle . . . . . . . . . . . . . . . . . . . . . . . . . 3 6 6 6 6 7 8 9 9 10 12 14 16 16 17 18 19 21 23 24 25 26 27 27 28 28 28 28 30 31 32 TABLE DES MATIÈRES 4 2 Comparaison de VCS 2.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Centroı̈d Virtual Coordinates [29] . . . . . . . . . . . . . . . . . 2.2.1 Calcul des coordonnées virtuelles . . . . . . . . . . . . . 2.2.2 Routage utilisant le système de coordonnées virtuelles . 2.3 Beacon Vector Routing [7] . . . . . . . . . . . . . . . . . . . . . 2.3.1 Calcul des coordonnées virtuelles . . . . . . . . . . . . . 2.3.2 Routage utilisant le système de coordonnées virtuelles . 2.4 Etude comparative des deux systèmes de coordonnées virtuelles 2.4.1 Choix d’implémentation . . . . . . . . . . . . . . . . . . 2.4.2 Métriques et paramètres de simulations . . . . . . . . . 2.4.3 Résultats . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5 Conclusion partielle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 33 34 34 36 36 36 36 38 38 38 39 41 A Détails du calcul de µ 47 B Description technique des capteurs MSP430F2274 48 C Listing de code C.1 Module application . . . . . . . . . . C.2 Module routage . . . . . . . . . . . . C.2.1 Centroid Virtual Coordinates C.2.2 Beacon Vector Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 50 54 54 71 Introduction générale Aujourd’hui, les progrès réalisés dans les domaines de la micro-électronique, et des technologies de communication sans fil permettent de créer de petits systèmes communicants équipés de capteurs à un coût raisonnable. Ces microcomposants communicants appelés capteurs sont équipés d’une unité de mesure, d’une unité de calcul, de mémoires et d’une radio pour communiquer. Les micro-capteurs sont donc de véritables systèmes embarqués. Le déploiement de plusieurs d’entre eux, en vue de collecter et transmettre des données environnementales vers un ou plusieurs points de collecte appelé(s) puits, et de manière autonome, forme un réseau de capteurs sans fil. Ces avancées technologiques rendent possible le déploiement de réseaux de capteurs sans fil. En effet, les domaines d’application des réseaux de capteurs sont très variés : applications militaires, domotique, surveillance industrielle ou de phénomènes naturels, relevé de compteurs. Cependant, du fait que les noeuds des réseaux de capteurs sont dispersés dans des environnements qui peuvent être propices à des hostilités d’un adversaire, le bon fonctionnement du réseau peut être compromis. C’est la raison pour laquelle assurer la sécurité dans ce type de réseaux devient un enjeu très important et ce notamment en ce qui concerne le bon acheminement des données vers le ou les puits. Dans le premier chapitre de ce présent rapport de PFE, nous nous intéresserons à traiter le cas particulier d’une attaque très connue : l’attaque Sybille. Par ailleurs, les besoins en terme de délais d’acheminement de l’information à destination du puits peuvent être très importants notamment si l’on considère des applications environnementales ou militaires. Parmi les solutions proposées dans la littérature scientifique, nombreux sont ceux qui suggèrent de mettre en place des systèmes de coordonnées virtuelles destinés à identifier le chemin le plus rapide parmi toutes les routes possibles pour atteindre le ou les puits. Dans le deuxième chapitre de ce rapport de PFE, nous nous intéresserons à analyser spécifiquement deux systèmes de coordonnées virtuelles différents : – le ”Centroı̈d Virtual Coordinates” [29] – le ”Beacon Vector Routing” [7] 5 Chapitre 1 Proposition d’un mécanisme de lutte contre les attaques Sybille dans les réseaux de capteurs sans fil 1.1 1.1.1 Introduction Réseaux de capteurs sans fil Les réseaux de capteurs sans fil (Wireless Sensor Networks en anglais) sont des réseaux spontanés constitués de noeuds déployés en grand nombre en vue de collecter et de transmettre des données vers un ou plusieurs points de collecte, et ce de façon autonome. Les noeuds capteurs composants le réseau possèdent généralement de faibles capacités de calcul, de mémoire et d’énergie, l’accès au médium radio étant l’élément le plus coûteux. Ainsi diminuer cette consommation (en diminuant le nombre de paquets circulant dans le réseau) et prolonger la durée de vie du réseau représentent un défi permanent pour ce type de réseau. 1.1.2 Applications des réseaux de capteurs sans fil Le champ d’applications des réseaux de capteurs est de plus en plus élargi grâce aux évolutions techniques que connaissent les domaines de l’électronique et des télécommunications. Parmi ces évolutions, on peut citer la diminution de taille et du coût des capteurs, ainsi que l’élargissement des gammes de capteurs disponibles (mouvement, température, ...) et l’évolution des supports de communication sans fil. En effet, les applications des réseaux de capteurs peuvent être militaires, médicales, environnementales, commerciales, etc. 6 CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 7 Applications militaires Un réseau de capteurs déployé dans un secteur straté- gique ou difficile d’accès, permet par exemple d’y surveiller tous les mouvements (alliés ou ennemis), ou d’analyser le champ de bataille avant d’y envoyer du renfort ([13] [23]). Applications médicales Il existe déjà dans le monde médical, des gellules multi-capteurs pouvant être avalées qui permettent, sans avoir recours à la chirurgie, de transmettre des images de l’intérieur du corps humain ([4] [33]). Applications environnementales Des capteurs de température peuvent être dispersés à partir d’avions dans le but de détecter d’éventuels problèmes environnementaux dans le domaine couvert par les capteurs dans une optique d’intervenir à temps afin d’empêcher que d’éventuels incendie, inondation, volcan ou tsunami ne se produisent ([17] [1] [2]). Applications commerciales Des noeuds capteurs peuvent être utilisés pour améliorer les processus de stockage et de livraison. Le réseau peut ainsi être utilisé pour connaı̂tre la position, l’état et la direction d’une marchandise. Un client attendant une marchandise peut alors avoir un avis de livraison en temps réel et connaı̂tre la position des marchandises qu’il a commandées ([27]). 1.1.3 Principales attaques sur les réseaux de capteurs Souvent déployés dans des environnements hostiles, les réseaux de capteurs sans fil peuvent être sujets à plusieurs types d’attaques. Dans cette section, on se propose de présenter un aperçu des attaques les plus connues au niveau de la couche routage. Pour des informations plus approfondies sur ces différentes attaques que ce soit au niveau de la couche routage ou des autres couches, il est vivement conseillé de se reporter au papier [34], dans lequel Znaidi et al. définissent une ontologie pour classer ces différentes attaques dans les réseaux de capteurs. En effet, de nombreux chercheurs se sont particulièrement intéressés aux attaques au niveau de la couche de routage : – Dans une attaque d’expédition sélective, l’attaquant transfère certains paquets qu’il intercepte et en supprime d’autres, engendrant ainsi une perte de donnée. – Dans une attaque par trou de puits (”Sinkhole attack”), un attaquant tente de se faire passer pour un faux puits en se montrant très attractif aux noeuds avoisinants puis crée une topologie erronée du réseau. CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 8 – Dans une attaque Sybille, un noeud malveillant présente plusieurs identités dans le but d’attirer le plus de traffic possible et de gagner plus d’influence par rapport aux noeuds ordinaires. – Dans une attaque d’inondation par paquets Hello, l’attaquant tente de convaincre des noeuds qu’il est dans leur voisinage même pour ceux qui sont hors de portée. Ainsi, le but de cette attaque est de faire en sorte que tous les noeuds redirigent leur paquets vers l’attaquant. – Dans une attaque par trou de ver, un adversaire connecte deux noeuds malveillants distants en utilisant un lien de communication directe à faible latence. Une autre forme de cette attaque est d’utiliser un noeud singulier qui relaie les paquets entre deux noeuds légitimes et distants dans le but de les convaincre qu’ils sont voisins. 1.1.4 L’attaque Sybille Comme nous nous sommes intéressés particulièrement à déjouer les effets des attaques Sybille, nous consacrons cette section à la description plus précise de ce type d’attaques. Fondamentaux sur les attaques Sybille L’attaque Sybille a tout d’abord été introduite et décrite par Douceur dans le contexte des réseaux pair à pair [5]. Dans cette attaque, un noeud malveillant peut revendiquer differentes identités dans le but de prendre de l’avantage sur les noeuds légitimes. Dans [24], Newsome et al. a introduit une taxonomie dans laquelle ils proposent de classer les attaques Sybille selon les trois dimensions suivantes : – communication directe vs communication indirecte : – Dans une communication directe, les noeuds Sybille communiquent directement avec les noeuds légitimes. – Dans une communication indirecte, les noeuds Sybille peuvent communiquer à travers un ou plusieurs noeuds malveillant se proclamant capable de les atteindre. – identités fabriquées vs identités volées : – Un noeud Sybille peut fabriquer une nouvelle identité. – Un noeud Sybille peut voler l’identité d’un noeud légitime. – simultanéité : – L’attaquant peut faire participer toutes ses identités Sybille de façon simultanée dans le réseau. – L’attaquant peut alternativement présenter seulement une partie de ses identités sur une période de temps donné. Applications des attaques Sybille Une attaque Sybille peut être menée dans l’optique d’attaquer plusieurs types de protocoles dans les réseaux de capteurs sans fil [24] : CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 9 – Mémorisation distribuée : un même noeud malveillant peut être capable de stocker autant de données qu’il prétend avoir d’identités différentes. Etant donné que ce noeud malveillant représente un unique point de défaillance, il peut ainsi facilement défaire les mécanismes de fragmentation et de réplication [5]. – Routage : un même noeud malveillant peut être capable de relayer autant de paquets qu’il présente d’identités Sybille. Au lieu de router ces paquets, il peut les supprimer, ou modifier les données qu’ils contiennent [18]. – Aggrégation de données : un noeud malveillant peut affecter l’aggrégat calculé étant donné qu’il peut contribuer autant de fois qu’il prétend avoir d’identités différentes. – Vote : un noeud malveillant peut être capable de déterminer le résultat de n’importe quel vote en faisant voter toutes ses identités Sybille pour une même entité. – Partage équitable de ressources : une attaque Sybille peut être menée dans le but de permettre à un seul noeud de béneficier d’une répartition inéquitable des ressources partagées avec d’autres noeuds. 1.2 Etat de l’art Cette section résume les différentes approches qui ont été proposées dans la littérature dans le but de lutter contre les attaques Sybille. Ces approches peuvent être classées dans les catégories suivantes [19] : – Certification approuvée – Test de ressources – Vérification physique – Vérification de la position 1.2.1 Certification approuvée Selon Douceur [5], dans un envionnement de calcul distribué, un attaquant peut de façon illégitime présenter des identités multiples en se servant de la même entité physique. En revendiquant ces différentes identités, l’entité malveillante est avantagée par rapport aux autres entités. Cela pose une menace de sécurité, particulièrement dans les systèmes pair à pair qui mettent en oeuvre la réplication de contenu, ou dans les schémas de fragmentation sur plusieurs pairs pour assurer de la disponibilité et de la sécurité et qui reposent sur l’existence de pairs indépendants avec des identités différentes. Dans [5], Douceur affirme qu’à moins qu’une certification approuvée soit mise en oeuvre, les systèmes pair à pair seraient exposés aux attaques Sybille. Dans la certification approuvée, une autorité centrale est utilisée dans le but de se porter garante de la correspondance un à un entre chaque entité et chaque identité. Pour soutenir cette thèse, il a d’abord souligné que la seule alternative contre les attaques Sybille dans un environnement de calcul distribué est d’utiliser le test de ressources, et a prouvé ensuite l’inefficacité d’une telle solution (se reporter CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 10 à la section 2.2). Cependant, la certification approuvée repose sur une autorité centrale qui doit garantir que chaque entité est affectée à exactement une seule identité. Dans ce papier, Douceur n’offre aucune méthode pour assurer une telle unicité. Newsome et al. étudient dans [24] les attaques Sybille dans le contexte des réseaux de capteurs et définissent une attaque Sybille comme un capteur malveillant qui prend illégitimement de multiples identités. Les identités additionnelles sont considérées comme étant des noeuds Sybille. Ces noeuds Sybille peuvent soit communiquer directement ou indirectement via un noeud malveillant. Ils peuvent obtenir des identités soit volées soit fabriquées. Ces identités peuvent participer soit simultanément dans le réseau soit de façon non simultanée. Dans [24], Newsome et al. citent aussi la certification approuvée comme un moyen d’éliminer les attaques Sybille. Cette approche est la même que celle proposée dans [5]. La seule différence est que dans [24], Newsome et al. ont étudié les attaques Sybille dans le contexte des réseaux de capteurs. En effet, dans les réseaux de capteurs, il peut y avoir une autorité centrale qui gère le réseau et donc qui connaı̂t toutes les identités des noeuds déployés. Ainsi, l’autorité centrale peut détecter des attaques Sybille en interrogent le réseau et en comparant les résultats des requêtes avec le déploiement connu. Bien que la certification approuvée soit l’approche la plus citée dans la littérature pour lutter contre les attaques Sybille [19], elle présente les désavantages suivants : – La liste des identités connue doit être protégée d’une éventuelle modification malicieuse. En effet, si l’adversaire est capable d’ajouter de nouvelles identités à cette liste, il pourra être capable d’ajouter des noeuds Sybille au réseau. – L’entité qui gère le réseau de capteur doit de façon sécurisée être capable de rajouter de nouveaux noeuds au réseau et doit maintenir et demander à connaı̂tre des informations sur la topologie actuellement connue. – Elle engendre une grande surcharge due aux nombreuses communications requises entre l’autorité centrale et les autres noeuds du réseau. 1.2.2 Test de ressources Le but du test de ressources est d’essayer de déterminer si certaines identités possèdent moins de ressources qu’elles sont supposées avoir si elles étaient indépendantes. Dans [5], Douceur définit le modèle de l’attaquant comme étant un environnement générique de calcul distribué qui manque d’autorité centrale. Dans ce modèle, les entités communiquent via des messages broadcastés. Certaines entités sont honnêtes, d’autres non. Une entité honnête présentera une seule identité légitime alors qu’une malhonnête peut essayer de présenter non seulement l’identité légitime mais aussi une ou plusieurs identités illégitimes. Les messages sont supposés être reçus de la part de toutes les entités et les ressources (mémoire, communication, calcul) de chaque entité physique (qu’elle CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 11 soit honnête ou non) sont supposées être limitées . Pour accepter une identité, un vérifieur peut lancer un défi exigeant en ressources en broadcastant une requête aux identités et valide seulement les identités dont les réponses ont lieu dans un intervalle de temps donné. Ensuite, les entités peuvent mettre en commun les identités qu’elles ont validées séparément. Pour prouver qu’une telle solution est impraticable, Douceur souligne que cette solution peut être possible seulement sous des hypothèses irréalistes de ressources et de coordination parmi les entités. En effet, toutes les entités doivent avoir approximativement les même contraintes de ressources et les identités doivent être validées simultanément par toutes les entités coopérantes. La méthode proposée du test de la communication est inappropriée dans un réseau de capteurs sans fil. En effet, les réponses convergeant vers le vérifieur engendreront une congestion au niveau de cette partie du réseau. Dans [24], Newsome et al. proposent aussi l’utilisation du test de ressources. Dans cette approche, ils supposent que tout capteur physique possède seulement une seule radio et que cette radio est incapable d’envoyer et de recevoir simultanément sur plus d’un canal. Dans ce papier, les auteurs considèrent que chaque vérifieur attribue un canal différent à chacun de ses n voisins afin d’y broadcaster un message. Ensuite, il choisit aléatoirement un canal sur lequel il décide d’écouter. Si le vérifieur arrive à attendre le message sur ce canal, cela signifie que le voisin à qui était attribué ce canal est légitime. Dans le cas échéant, cela signifie que ce voisin est un noeud Sybille. La difficulté de cette approche est que nous n’avons pas toujours autant de canaux que de voisins. Dans ce cas, si nous n’avons pas suffisamment de canaux à attribuer, cela peut prendre beaucoup de temps pour détecter une attaque Sybille. Elle peut même demeurer indetectée si il y a autant ou plus de noeuds Sybille que de canaux. Cependant, nous ne pouvons malheureusement pas envisager d’utiliser une telle approche vu qu’elle ne peut malheureusement convenir à des systèmes distribués dans un réseau de large étendue. En effet, la validation peut nécessiter d’importants coûts en terme d’énergie. Un autre type de test de ressources a été proposé par Yu et al. avec SybilGuard dans [31] et [32]. Ce protocole repose sur le fait qu’il n’existe pas beaucoup de liens d’”amitié” véritable entre les noeuds d’un réseau social. En fait, ils ont basé leur modèle uniquement sur l’idée que dans les réseaux sociaux les identités sont des noeuds et les liens entre eux sont des relations de confiance bâties par les utilisateurs dans le monde réel. La plupart des utilisateurs (n) sont honnêtes et présentent seulement une identité chacun. Quelques utilisateurs sont malveillants et peuvent revendiquer plusieurs identités : les noeuds Sybille. Un lien connectant un noeud de Sybille à un noeud honnête est appelé √ lien d’attaque. Le nombre de liens d’attaque g doit être négligeable devant ( n/ log n)). Dans leur solution, chaque√noeud de degré d calcule des routes aléatoires d’une certaine longueur w (∼ = n log n) au niveau de chacun de ses d liens, et ce en utilisant une table de routage aléatoire pour choisir le prochain saut. Les noeuds pour lesquels des routes aléatoires se croisent au même noeud d’intersection sont rangés dans le même groupe d’équivalence. Un groupe Sybille est un groupe d’équivalence qui contient au moins un noeud de Sybille. De plus, CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 12 SybilGuard exige que chaque noeud s’enregistre auprès de chacun des w noeuds de chacune de ses routes et ce en utilisant la cryptographie à clé publique. Si un noeud V veut vérifier un noeud S, il trouve d’abord les noeuds d’intersection pour toutes ses routes avec toutes celles de S. Puis, il se sert de clés privées pour authentifier ces noeuds et demande à chacun d’entre eux s’ils connaissent la clé publique de S. Une route de V acceptera S seulement si la clé publique de S est trouvée au niveau du noeud d’intersection. Si plus de la moitié des routes de V acceptent S, alors V acceptera S. On peut montrer en utilisant le paradoxe des anniversaires que deux noeuds honnêtes s’accepteront mutuellement avec une grande probabilité. Puisqu’un noeud Sybille doit forcément traverser un lien d’attaque pour croiser une route de V , alors il y a au plus g groupes Sybille. De plus, la taille de chaque groupe Sybille est majorée par w, longueur de chacune des routes aléatoires. Ainsi, SybilGuard garantit que le nombre de noeuds Sybille acceptés est majoré par g ∗ w. L’inconvénient principal de ce protocole est qu’il peut accepter beaucoup de noeuds Sybille. Il souffre aussi des taux élevés de faux négatifs. Dans un autre papier [30], les auteurs présentent un nouveau protocole (SybilLimit) basé sur le même modèle que SybilGuard, mais qui offre de meilleures garanties. En fait, il aspire à réduire le nombre de noeuds Sybille acceptés. Par opposition avec SybilGuard qui utilise peu de très longues routes aléatoires, chaque noeud (qu’il soit un suspect S √ou un verifieur V ) calcule r routes aléatoires d’une longueur w plus courte (∼ = m où m est le nombre de liens entre les n noeuds honnêtes). On peut montrer que tant que g est négligeable devant ( logn n ), alors une route courte aléatoire a beaucoup plus de chance de rester parmi les noeuds honnêtes. Le critère de validation pour accepter un noeud comme étant honnête dans SybilLimit est qu’il devrait y avoir une intersection au niveau du dernier lien (la queue) des routes aléatoires du verifieur et du suspect. Comme dans SybilGuard, on peut montrer en utilisant le paradoxe des anniversaires que deux noeuds honnêtes s’accepteront mutuellement avec une grande probabilité. Notons que si une route aléatoire entre parmi l’ensemble des noeuds Sybille, alors la queue malveillante de cette route pourrait être à l’origine d’intersections avec beaucoup d’identités Sybille. Pour éviter cette attaque, une condition ”d’équilibre” supplémentaire est imposée et assure qu’une même intersection ne peut pas valider un nombre arbitraire d’identités. Ainsi, SybilLimit accepte au plus g ∗ w identités Sybille. Ces solutions (SybilGuard et SybilLimit) ne sont pas appropriées dans le contexte de réseaux de capteurs sans fil puisqu’ils assument l’existence d’un réseau social. Ils échouent aussi si un adversaire réussit à capturer un noeud honnête qui a beaucoup d’amis via de nombreuses relations de confiance. 1.2.3 Solutions basées sur la vérification physique Dans le papier [15], Ben Hamida et al. proposent de générer des clefs secrètes à partir des caractéristisques du canal radio. La génération de ces clefs secrètes repose sur le principe de réciprocité dans lequel deux noeuds sans fils communiquants mesurent les fluctuations du canal et exploitent le fait que personne CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 13 d’autre ne peut mesurer ces fluctuations. Dans la première partie de leurs travaux, ils commencent par valider la réciprocité du canal à très haute fréquence (Ultra Wide Band channel). Pour cela, ils mesurent la réponse du canal hAB (t) où A envoie un signal de sonde à B et la réponse du canal hBA (t) où B envoie le même signal de sonde à A. Ainsi, ils remarquent que le signal reçu par B connaı̂t les même fluctuations et la même puissance que le signal reçu par A. Dans leur algorithme, l’utilisateur A qui désire partager un secret avec un autre utilisateur B estime le canal pendant une période de temps en utilisant un signal connu. Cette estimation est notée b hA . Puis, A détermine deux seuils L+ et L− et examine la séquence b hA pour détecter quelles mesures i dépassent les seuils fixés : si b hA > L+ alors le vecteur binaire BVA (i) est mis à 1 et si b hA < L− alors BVA (i) est mis à 0. Ensuite, A ajuste les valeurs de seuils et ce processus est répété jusqu’à ce que le niveau de bruit soit atteint ou que la longueur du vecteur binaire devienne égale à la longueur de la clef secrète. Puis, A envoie à B le vecteur BVA et B le compare au vecteur binaire BVB qu’il a calculé dans l’optique d’en éliminer les bits qui diffèrent. Ensuite, B envoie à A les positions des bits supprimés et A élimine ces bits au niveau de BVA et vérifie si la clef ainsi générée KA est égale à la clef générée KB . Pour cela, A chiffre un message en utilisant KA et demande à B de le déchiffrer et de le rechiffrer en utilisant KB . Ainsi, A vérifie le message reçu et envoie un accusé de réception (acknowledgement) à B afin de confirmer l’accord ou le désaccord. Dans l’article [12], Hall et al. proposent une solution pour détecter une intrusion sans fil dans laquelle l’attaquant entreprend une usurpation d’adresse MAC dans des réseaux sans fils. Dans l’usurpation d’adresses MAC, un adversaire réussit à se faire passer pour un autre utilisateur légitime en falsifiant ses données et bénéficie donc d’un avantage illégitime. Ainsi, cette attaque peut être assimilé à une attaque Sybille dans laquelle l’adversaire utilise une autre identité pour s’infilter dans le réseau comme étant un autre utilisateur. Dans cette solution, ils proposent l’utilisation des empreintes de fréquence radio ou RF F pour Radio Frequency Fingerprinting. En effet, RFF est une technique qui est utilisée pour identifier de façon unique un transmetteur en se basant sur la portion transitoire du signal qu’il génère. L’idée de ce papier est que l’adresse MAC d’un capteur est associée au profil du transmetteur correspondant. Ainsi, le principe est de vérifier si l’empreinte relevée sur une adresse MAC réclamée est bien conforme au profil du transmetteur correspondant. Pour obtenir l’empreinte du transmetteur, ils convertissent d’abord le signal analogique en un signal numérique en utilisant un convertisseur analogiquenumérique, isolent la partie transitoire du signal converti, et en extraient l’amplitude, la phase et la fréquence. En ce qui concerne le profil du transmetteur, ils le créent en extrayant les empreintes des transmetteurs à partir d’un ensemble de signaux numériques et en stockant dans un profil le centre de gravité correspondant et la matrice de covariance. Puis, ils calculent la probabilité d’une correspondance entre une empreinte de transmetteur donnée et chacun des profils des transmetteurs stockés. Enfin, le filtre bayesien est utilisé pour déterminer si l’empreinte relevée est normale ou anormale. CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 14 Le principal inconvénient de la technique de RFF est qu’elle nécessite un matériel spécialisé pour mesurer avec suffisamment de précision les propriétés nécessaires du signal analogique. Dans [16], Huang et al. proposent d’utiliser le biais d’horloge pour identifier chacun des noeuds d’un réseau de capteurs sans fil. Selon eux, cette identification de noeud réussira à détecter des attaques Sybille et des attaques par réplication de noeud. Ils ne proposent pas un modèle d’attaque spécifique. Ils n’appliquent leur solution qu’à un scénario très particulier d’attaque Sybille. Dans ce scénario, il y a trois noeuds ordinaires, une station de base utilisée pour recueillir les données de chaque noeud, et un noeud malveillant qui prétend avoir quatre identités. Le noeud malveillant utilisent alternativement une identité parmi les quatre qu’il prétend détenir. Dans cet article, Huang et al. profitent du fait que chaque noeud capteur a une unique valeur biaisée d’horloge. En fait, vu que les identités Sybille ont été falsifiées par le même noeud physique, ils ont alors le même biais d’horloge. Ainsi, les identités Sybille peuvent être identifiées. Dans leur scénario, chaque noeud calcule le biais d’horloge de ses voisins en utilisant le protocole FTSP [21]. Ensuite, il calcule la gamme de biais dans le but de différencier les noeuds dans des groupes selon leurs biais d’horloge. Si un seul biais d’horloge fait référence à un noeud dans un seuil fixé, alors ce noeud est considéré comme légitime. Sinon, il compare le biais actuel d’horloge aux trois derniers enregistrements de biais d’horloges pour examiner la continuité de ces enregistrements. Si ils ne sont pas continus, le noeud est considéré comme légitime, sinon, il est détecté comme étant Sybille. Le principal inconvénient de cette approche est qu’elle échouera si l’adversaire tente de mentir sur les valeurs de temps qu’il envoie à ses voisins : il peut ainsi fausser les calculs de biais d’horloge qu’entreprennent ses noeuds voisins. En outre, il peut être très difficile d’appliquer une telle solution à un réseau très dense dans lequel les biais d’horloge calculés ne peuvent pas être facilement discernables. 1.2.4 Solutions basées sur la vérification de la position La vérification de la position vise à détecter les noeuds Sybille qui renvoient à une même position revendiquée par un noeud malveillant [24]. Dans [20], Lv et al. proposent une méthode pour détecter les attaques Sybille dans des réseaux de capteurs statiques et sans fil. Dans cet article, ils n’ont pas donné davantage de précisions sur le modèle d’attaque. Dans leur méthode, chacun des noeuds non-alignés A, B et C mesure la distance qui le sépare du noeud D en utilisant la puissance du signal reçu (RSS). Par conséquent, la position du noeud D est déterminé en effectuant la construction des trois cercles CA (de centre A et de rayon AD), CB (de centre B et de rayon BD) and CC (de centre C et de rayon CD). Ainsi, en utilisant les informations RSS à partir de plusieurs noeuds voisins coopérant, il peut être possible de déterminer les positions relatives des différentes identités du réseau. Dans cette configuration, une attaque Sybille CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 15 est détectée lorsque deux ou plusieurs identités différentes ont quasiment la même position. Malheureusement, cette méthode souffre d’un taux élevé de faux négatifs. Dans [22] et [25], Saha et Mukhopadhyay proposent un mécanisme de lutte contre les attaques Sybille dans les réseaux de capteurs statiques et sans fil. Ce mécanisme repose sur la vérification du positionnement. Contrairement à [24] et [20], cette solution ne nécessite pas de vérifier la position exacte d’un noeud physique, mais uniquement de vérifier si la position physique d’un noeud est située dans une région donnée. Dans leurs hypothèses du réseau, il y a un grand nombre de noeuds capteurs déployés par une seule autorité. En outre, il y a un serveur de configuration qui configure le réseau de capteurs : ainsi, il est conscient de l’emplacement de tous les noeuds capteurs déployés. Dans leur conception, de nouveaux noeuds sont autorisés à rejoindre le réseau que si ils sont dans l’enveloppe convexe de l’ensemble initial des noeuds déployés. Tous les noeuds capteurs sont capables de communiquer en utilisant les canaux de transmission radio et sonore. Ils supposent que ces deux canaux de transmission sont parfaitement sécurisés. Tous les noeuds capteurs font confiance au serveur de configuration et les noeuds capturés ne représenteront qu’un faible pourcentage de l’ensemble du réseau. Leur protocole vise à vérifier en toute sécurité la position de tout nouveau noeud qui rejoint le réseau. Un agent logiciel est conscient de l’emplacement de tous les noeuds capteurs déployés. Lorsque le nouveau noeud X rejoint le réseau, l’agent identifie le triangle T (formé par les noeuds V1 , V2 et V3 ) dans lequel est située la position demandée de X. Puis, chacun des noeuds Vi génère un nombre aléatoire Ri , y greffe sa propre identité et envoie au nouveau noeud X le message Mi = Ri Vi via le canal de transmission radio. Ainsi, X reçoit trois messages Mi , un de chaque Vi , et contruit les messages Mi0 = Ri X qu’il renvoie à chacun des noeuds Vi par le canal de transmission sonore. Chaque noeud Vi mesure le temps écoulé tii et le retourne à l’agent logiciel. Ce dernier détermine ensuite si l’emplacement revendiqué est déjà enregistré. S’il en est ainsi, l’agent rejette le nouveau noeud. Pour ce faire, il compare tii avec tij où tij est le temps total nécessaire pour qu’un message atteigne Vi à partir de Vj et en revienne. Par conséquent, il vérifie que tii < tij pour i = 1, 2, 3. Même si elle semble être très simple à mettre en oeuvre et nécessite peu de communication et peu de calcul, cette solution ne fonctionne pas bien quand un ou plusieurs sommets du triangle T ne sont pas des noeuds honnêtes. En outre, les hypothèses semblent trop fortes et irréalistes. En fait, nous ne pouvons pas être sûr que les canaux de transmission sont parfaitement sécurisées étant donné que dans le réseau de capteurs sans fil il peut y avoir des attaquants capables d’écouter sur ces canaux de transmission et d’altérer l’intégrité des messages échangés. En outre, faire confiance à un serveur de configuration n’est pas particulièrement sûr, car il constitue ainsi un point unique de défaillance dans le réseau. Dans [26] et [28], Wang et Ssu proposent d’utiliser les relations de voisinage pour se défendre contre les attaques Sybille dans les réseaux de capteurs sans fil. Dans leur modèle d’attaque, il y a trois sortes de noeuds dans le système : CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 16 les noeuds légitimes, les noeuds malveillants, et les noeuds Sybille. Les noeuds légitimes et malveillants sont des noeuds physiquement existants tandis que les noeuds Sybil sont virtuels. Chaque noeud malveillant trompe ses voisins par la création d’identités multiples : les noeuds Sybille. Selon la taxonomie de [24], ils ont considéré l’attaque Sybille dans laquelle la communication est directe, et les identités Sybille sont fabriquées et participent de façon simultanée dans le réseau. Le nombre de noeuds Sybille est supposée être supérieur à la densité moyenne. Dans leurs hypothèses, tous les noeuds ne sont pas conscients de leurs emplacements et ne sont pas supposés se déplacer. Pour détecter si un noeud V est victime d’une attaque Sybille, il est proposé dans [26] et [28] de construire des ensembles de voisins communs CN BV,i où i représente chacun des voisins de V . Les noeuds qui sont attaqués par les mêmes noeuds malveillants seront rangés dans le même groupe. Deux noeuds i et j sont considérés comme attaqués par les mêmes noeuds malveillants si | CN Bi,V − CN Bj,V |< D (où D est la densité moyenne) et | CN Bj,V − CN Bi,V |< D. Si i est attaqué par M1 , tous les noeuds Sybille créés par M1 doivent être dans CN Bi,V . Pour deux noeuds a et b qui sont dans le même groupe, nous prenons en considération les CN Bi,V qui ne sont pas à proximité du groupe 0 a, b. Par conséquent, nous obtenons les groupes cibles CN Bi,V en enlevant des ensembles CN Bi,V , tous les noeuds qui ne sont pas dans le voisinage du groupe a, b. Ensuite, nous comptons le nombre d’occurrences de chacun noeud dans ces groupes cibles. Les noeuds qui apparaisent plus d’un certain seuil sont rangés dans l’ensemble critique CS. Désormais, certains noeuds peuvent être rangés dans l’ensemble critiques même si ils sont légitimes. Pour cela, pour chaque i noeud i qui est dans le CS, ils construisent l’ensemble CSmiss dans lequel il y a les noeuds qui sont dans CS et qui ne figurent pas dans le groupe cible i 0 . Enfin, ils fusionnent les ensembles CSmiss pour former des ensembles CN Bi,V suspects et de fusionnent dans des ensembles finaux, les ensembles suspects qui ont au moins un élément en commun. A partir de ces ensembles finaux, ceux dont les cardinaux sont supérieurs à un certain seuil sont considérés comme les ensembles composés de noeuds Sybille et de noeuds malveillants. A moins qu’elles soient capables de vérifier très précisemment les positions des différents noeuds, l’inconvénient principal des solutions basées sur la vérification de la position est qu’elles permettent seulement de limiter le nombre de noeuds Sybille qu’un attaquant peut générer [24]. De plus, comme nous l’avons remarqué dans cette partie, ces solutions génèrent des taux élevés de faux positifs et faux négatifs. 1.3 1.3.1 Spécifications générales Modèle du réseau Dans cette section, on spécifie les hypothèses sur le réseau qu’on considère. On traite des réseaux de capteurs sans fils statiques. Deux types de capteurs sont considérés : les capteurs ordinaires et les puits. On suppose que tous les CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 17 capteurs sont physiquement identiques (même puissance, même portée, ...). Les capteurs sont densément déployés dans une étendue N × N (N exprimé en mètres). D’un côté, les puits collectent des mesures relevés par les capteurs. De plus, ils sont supposés être robustes et dotés de suffisamment de ressources pour supporter les exigences de cryptographie et de routage dans un réseau de capteurs sans fil. En outre, on admet qu’un attaquant ne peut les compromettre en un temps limité. De l’autre côté, les capteurs ordinaires relèvent et transmettent aux puits des mesures du monde physique. Ces capteurs ont des ressources limitées en mémoire, communication, puissance de calcul et en batterie. Ils sont supposés être non fiables étant donné qu’ils peuvent facilement être compromis par un adversaire. On considère qu’un lien de communication peut exister entre deux noeuds si et seulement si la distance euclidienne entre ces deux noeuds est inférieure à la portée de communication fixée r. Les liens sans fil sont supposés être bidirectionnels, ce qui signifie que si le noeud i peut entendre j, alors le noeud j peut entendre i. On désignera par noeuds voisins d’un noeud donné x, l’ensemble des noeuds avec qui x peut partager un lien de communication, i.e. l’ensemble des noeuds qui sont à portée de communication du noeud x. 1.3.2 Modèle d’attaques Selon [6], les attaquants que l’on considère sont des attaquants de type ”atome” (”mote-class”). Dans ce cas, les capteurs ordinaires peuvent être capturés et compromis par un adversaire. Dans notre cas, on considère aussi que les adversaires sont intérieurs (”insider”) au réseau et lance des attaques actives (”active attack”). On rappelle que : – une attaque de type ”atome” affecte seulement quelques capteurs dotés des même capacités que les autres capteurs ordinaires du réseau. Ils ne bénéficient d’aucun avantage sur les capteurs légitimes. – un adversaire intérieur est un attaquant qui lance une attaque en se servant d’entités à l’intérieur du périmètre de sécurité. Cela signifie que ces entités sont autorisées à accéder aux ressources du système mais les utilisent d’une manière non approuvée par l’entité qui a accordé l’autorisation. – une attaque active tente de changer les ressources du système ou d’affecter le bon fonctionnement du système. Soit N l’ensemble des capteurs du réseau et p l’unique puits collecteur. Dans le réseau, deux genres de capteurs coexistent : les capteurs Sybille et les capteurs honnêtes. On note M l’ensemble des capteurs Sybille. Un capteur honnête présente son unique identité légitime, tandis qu’un capteur Sybille a ∈ M apparaı̂t non seulement sous son identité légitime mais aussi sous ka autres identités illégitimes : les identités Sybille. Un capteur Sybille peut être soit naı̈f, soit intelligent. La différence est que le capteur Sybille intelligent est en plus capable CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 18 de mentir à ses voisins en envoyant des informations trafiquées dans une optique de demeurer indétectable. Soit S l’ensemble des capteurs Sybille intelligents du réseau. Le degré (ie. le nombre de voisins) d’un quelconque capteur c est noté dc . On émet les hypothèses suivantes : √ 1. ∀a ∈ M, ka = b da c 2. |M | |N | ≤ 0.2 3. |S| |M | ≤ 1 3 En ce qui concerne la √première hypothèse, on estime qu’il n’est pas judicieux que ka dépasse le seuil b da c. En effet, au delà de cette valeur, le degré de chacun des voisins de a deviendra trop élevé en comparaison avec ceux de leurs voisins qui ne sont pas affectés par l’attaque de a. De plus, parmi la liste des voisins de chacun des noeuds victimes de cette attaque figureront beaucoup d’identités Sybille se référant au même noeud. Par conséquent, en exploitant le paradoxe des anniversaires, il deviendra beaucoup plus facile pour les noeuds victimes de cette attaque de détecter les noeuds Sybille. Selon la taxonomie dans [24], les noeuds Sybille peuvent être des identités soit ”volées” soit ”fabriquées”. Pour présenter des identités ”volées”, un noeud malveillant doit ”voler” les identités d’autres noeuds honnêtes. Si on considère que les noeuds Sybille sont des identités ”volées”, alors une même identité sera utilisée plusieurs fois et existera à plusieurs endroits du réseau. Ainsi, ce type d’attaques Sybille s’apparente à des attaques par réplication de noeuds et on peut utiliser l’algorithme cité dans [35] pour les détecter. Par conséquent, on considère que les noeuds Sybille sont des identités fabriquées. Pour présenter des identités ”fabriquées”, un capteur malveillant doit contrefaire de nouvelles identités. Pour cela, l’attaquant peut avoir besoin de capturer quelques noeuds honnêtes et de compromettre leur systèmes cryptographiques. A partir des clefs qu’il aura obtenues, l’adversaire pourra fabriquer de nouvelles clefs lui permettant d’apparaı̂tre sous de nouvelles identités ”fabriquées”. De plus, on suppose que toutes les identités Sybille d’un noeud malveillant peuvent participer simultanément au réseau. 1.4 Proposition du mécanisme de défense Cette section présente notre proposition de mécanisme de lutte contre les attaques Sybille. Dans notre choix de proposition, nous exploitons les propriétés physiques des capteurs utilisés dans les réseaux de capteurs et notre solution se range donc parmi les solutions basées sur la vérification physique. En effet, elle repose sur la mesure des propriétés physiques qui caractérisent l’horloge interne de chacun des capteurs du réseau. Elle reprend l’idée qui consiste à identifier de façon unique les capteurs du réseau grâce à leurs propres horloges internes [16]. Cependant, nous adaptons cette solution à des réseaux pouvant être très CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 19 denses, comme c’est le cas pour les réseaux de capteurs, et ce en considérant non seulement la dissymétrie de fréquence comme c’est déjà le cas dans [16], mais aussi la différence d’offset avec l’horloge de référence. Par ailleurs, nous prévoyons le cas où certains noeuds Sybille tentent de mentir dans le but de ne pas être détectés. 1.4.1 Conception préliminaire On se place dans le modèle où la valeur affichée par l’horloge interne d’un capteur a suit une représentation affine [10] : τa (t) = λa t + µa (1.1) Dans l’équation 1.1, t est la valeur de l’horloge de référence. λa correpond à la dissymétrie de fréquence (clock skew ) avec l’horloge de référence. µa correspond à la différence d’offset (clock offset) avec l’horloge de référence. L’association de ces deux valeurs est unique pour chacun des noeuds du réseau de capteurs [10]. En reprenant l’égalité (1.1), on peut écrire que : t = τa (t) − µa λa (1.2) Ainsi, la valeur affichée par l’horloge interne d’un autre capteur b, à savoir a . On obtient : τb (t) = λb t + µb peut être réécrite en remplaçant t par τa (t)−µ λa τb (t) = λb τa (t) − µa + µb λa (1.3) Soit : τb (t) = [ µa λb λb ]τa (t) + [µb − ] λa λa (1.4) On note λb,a , la quantité λλab et µb,a , la quantité µb − µλaaλb . λb,a correspond alors à la dissymétrie de fréquence relative (relative clock skew ) en prenant pour référence l’horloge interne du noeud a. De même, µb,a correspond à la différence d’offset relative (relative clock offset) en prenant pour référence l’horloge interne du noeud a. Nous envisageons qu’au niveau de la couche routage, chacun des noeuds du réseau de capteurs envoie périodiquement à ses voisins à un saut des paquets N EIGH V ER. Chaque paquet N EIGH V ER est daté au moment de son envoi par un noeud n et au moment de sa réception par un noeud m. On note Tin , l’instant où le ième paquet N EIGH V ER a été envoyé par le noeud n. De même, on note Rin , l’instant où le ième paquet N EIGH V ER a été reçu en provenance du noeud n. Ainsi, à chaque envoi de ième paquet N EIGH V ER, un noeud donné x y inclue non seulement le temps Tix (moment de l’emission z du paquet), mais aussi le temps Ri−1 , moment où il a reçu le dernier paquet N EIGH V ER de la part d’un autre noeud z CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 20 Figure 1.1 – Envoi de paquets N EIGH V ER entre deux noeuds voisins n et m Calcul du coefficient λ Suite à la réception de deux paquets N EIGH V ER envoyés de la part d’un n noeud n à deux instants différents Tin et Ti+2 , un noeud m peut calculer la dissymétrie de fréquence relative relative clock skew, c’est-à-dire la valeur λm,n . En effet, on la calcule de la manière suivante : λm,n n Ri+2 − Rin n − Tn Ti+2 i = (1.5) En effet, soit δ la somme des délais entre le moment de l’envoi Tin et le moment de réception Rin . On a alors : Rin = τn (Tin + δ) n Ri+2 = n τn (Ti+2 + δ) = λm,n (Tin + δ) + µm,n (1.6) = n λm,n (Ti+2 + δ) + µm,n (1.7) Soit : n Ri+2 − Rin = n λm,n (Ti+2 − Tin ) (1.8) D’où la relation (1.5). Paralallèlement, comme la relation de voisinage est supposée être une relation symétrique, le noeud m est aussi censé répondre à n par des paquets m . Nous précisons à nouveau N EIGH V ER pour y inclure les temps Rin et Ti+1 que ces paquets N EIGH V ER sont datés au moment de l’envoi et au moment de la réception et sont logiquement notés : m – Ti+1 : l’instant où le (i + 1)-ème paquet N EIGH V ER a été envoyé par le noeud m, et ce en réponse au i-ème paquet N EIGH V ER envoyé par le noeud n. m – Ri+1 : l’instant où ce (i + 1)-ème paquet N EIGH V ER a été reçu en provenance du noeud m. Le schéma ci-dessous permet d’illustrer les envois de paquets N EIGH V ER. CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 21 Calcul du coefficient µ Selon [11], l’offset relatif θ entre deux noeuds n et m et le délai de propagation δ sont tels que : θ = δ = m m (Rin − Tin ) − (Ri+1 − Ti+1 ) 2 m m (Rin − Tin ) + (Ri+1 − Ti+1 ) 2 (1.9) (1.10) Cependant dans [11], la relation (1.9) permettant de calculer l’offset relatif θ ne prend pas en considération le fait que les horloges internes des capteurs présentent des dissymétries de fréquence, contrairement à notre hypothèse de départ. On ne peut pas donc appliquer cette relation directement. En reprenant le schéma de la section 1.4.1, on a les relations suivantes : m ri+1 n ri+2 = tm i+1 + δ (1.11) = tni+2 (1.12) +δ n n n où tni+2 et ri+2 correspondent respectivement aux temps absolus Ti+2 et Ri+2 et m m m m où ti+1 et ri+1 correspondent respectivement aux temps absolus Ti+1 et Ri+1 . On obtient grâce à (1.12) - (1.11) : n m ri+2 − ri+1 = tni+2 − tm i+1 (1.13) n m En remplaçant les ri+2 , ri+1 et tni+2 , tm i+1 par leurs expressions en fonction de m n m Ri+1 et Ti+2 , Ti+1 , on obtient (pour plus de détails, se reporter à l’annexe n Ri+2 , 1) : µn µm − λm λn = n m n Ri+2 + Ti+1 Rm + Ti+2 − i+1 2λm 2λn (1.14) En multipliant par λm chacun des membres de l’équation (A.7), on obtient : µm − µn λm λn = n m m n Ri+2 + Ti+1 + Ti+2 λm Ri+1 − 2 λn 2 (1.15) D’où, on identifie clairement la relation suivante qui nous permet de calculer l’offset relatif (relative clock offset) dans notre cas : µm,n 1.4.2 = n m n Ri+2 + Ti+1 Rm + Ti+2 − λm,n i+1 2 2 (1.16) Détection des attaques Détection des noeuds Sybille naı̈fs Grâce à l’échange de paquets N EIGH V ER avec ses voisins, chaque noeud n du réseau de capteurs est capable de calculer pour chacun des ses voisins à un saut les valeurs λn,x et µn,x avec x étant un voisin quelconque de n. A CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 22 tout moment, si le noeud n compare pour deux de ces noeuds voisins x1 , x2 les valeurs λn,x1 , λn,x2 d’une part et les valeurs µn,x1 , µn,x2 d’autre part et détecte que λn,x1 = λn,x2 et µn,x1 = µn,x2 , alors il considère que les noeuds x1 et x2 sont des noeuds Sybille. Pour des raisons d’incertudes sur les valeurs calculées, nous considérerons que deux valeurs de λn,x1 , λn,x2 sont égales si l’une des deux relations suivantes est vérifiée : λn,x1 − λn,x2 |<α λn,x1 λn,x1 − λn,x2 | |<α λn,x2 | (1.17) (1.18) Pour les même raisons, nous considérons que deux valeurs de µn,x1 , µn,x2 sont égales si l’une des deux relations suivantes est vérifiée : µn,x1 − µn,x2 |<β µn,x1 µn,x1 − µn,x2 |<β | µn,x2 | (1.19) (1.20) Nous tenterons de fixer les seuils α et β en réalisant des mesures sur de vrais capteurs (Cf sections 5 et 6). Détection des noeuds Sybille intelligents Dans le cas où le capteur Sybille est intelligent et donc capable de mentir sur les temps qu’il envoie dans les paquets N EIGH V ER, on doit être en mesure de détecter ce mensonge. En exploitant les échanges de temps qui ont lieu au niveau des paquets N EIGH V ER, un noeud vérifieur n tentera de détecter un mensonge en se basant uniquement sur les temps de son horloge interne. Pour cela, tout capteur n du réseau, détectera un mensonge au niveau d’un noeud voisin x1 , dans le cas où il existe un autre noeud voisin x2 pour lequel une des deux propriétés suivantes est vérifiée : R x1 − T n σ[R x1 n = R x2 − T n −T ] > (1.21) (1.22) T n désigne le temps affiché par l’horloge interne de n à l’instant où ce dernier envoie un i-ème paquet N EIGH V ER à ces voisins x1 et x2 . Rx1 et Rx2 désignent les temps affichés par l’horloge interne de n respectivement aux instants où n reçoit un (i + 1)-ème paquet N EIGH V ER de la part de x1 et x2 . Ces différences de temps Rx1 − T n et Rx2 − T n correspondent donc aux temps mis pour un paquet pour aller de n à x1 et x2 et pour y revenir. Ces durées donnent une indication sur la distance qui sépare le noeud vérifieur n de ses voisins. En cas d’égalité confirmée pour deux de ces voisins, le noeud n peut considérer qu’ils mentent sur leurs temps. On a noté par Rx1 − T n et Rx2 − T n les moyennes respectives : CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE Ptxk1 23 x x i=t 1 1 (Ri 1 −Tin ) k Ptxk2 x x i=t 2 1 (Ri 2 −Tin ) k x1 n De même, on a noté par σ[R − T ] l’ écart-type qui y correspond à savoir : s x Ptk1 x1 n x n 2 x ((Ri i=t 1 1 −Ti )−R 1 −T ) k La valeur est un seuil que l’on précisera dans le paramétrage des simulations. Algorithme de détection Dans cette sous-section, nous présentons l’algorithme complet utilisé pour la détection des noeuds Sybille naı̈fs et intelligents. Soit n le noeud qui exécute ce pseudo-code dans une optique de détecter si parmi ses voisins xi (i = 1..d(n)), certains sont naı̈fs et d’autres sont intelligents. 1. Calcul des coefficients : dans une première étape, le noeud n calcule pour tout noeud xi voisin de n, les valeurs λn,xi , µn,xi d’une part et les valeurs Rxi − T n , σ[Rxi − T n ] d’autre part (Cf. sections 1.4.1 et 1.4.3). 2. Détection noeuds Sybille naı̈fs : n teste pour chaque paire de voisins xi et xj (i 6= j) si λn,xi = λn,xj et µn,xi = µn,xj . – Si deux noeuds xi et xj satisfont cette condition alors ils sont marqués comme Sybille naı̈fs. 3. Détection de noeuds Sybille intelligents : n teste pour chaque voisin xi si σ[Rxi − T n ] > – Si tel est le cas xi est considéré comme étant Sybille intelligent. – Sinon il teste s’il existe un voisin xj (j 6= i) tel que Rxi − T n = R xj − T n . – Si il trouve un noeud xj qui vérifie cette condition, alors xi et xj sont considérés comme étant Sybilles intelligents. 1.5 Etude des capteurs MSP430F2274 Dans cette partie, on présente une étude des capteurs MSP430F2274 de Texas Instruments disponibles au laboratoire CITI (INSA Lyon/INRIA). L’eZ430 qui est de la taille d’une clé USB est la plateforme sans fil permettant de programmer simplement les micro-contrôleurs MSP430F2274 avec son interface USB. En effet, cette plateforme sert de programmateur, de débuggeur et de simulateur pour le MSP430F2274. Une description technique plus détaillée de ces capteurs est disponible en annexe (Annexe A) du présent rapport. Cette étude va nous permettre non seulement de valider expérimentalement une partie de notre proposition mais aussi, grâce aux résultats que l’on va en tirer, d’affiner au mieux notre proposition de défense. CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 24 Figure 1.2 – Validation expérimentale de la dissymétrie d’horloge des capteurs 1.5.1 Validation du caractère dissymétrique des horloges internes dans les capteurs Expérimentation Dans cette première étude, nous nous sommes intéressés à valider le caractère dissymétrique que présente les horloges internes des capteurs et qui est à la base de notre proposition. Pour cela, nous avons implémenté le même programme au niveau de 5 capteurs MSP430F2274. Dans ce programme, l’horloge interne est initialisée à la même fréquence F pour les 5 capteurs, puis nous avons exploité la liaison série UART pour afficher périodiquement à l’écran les temps affichés par les timers (timersB) après chaque relevé de température et de tension. Voici le pseudo-code de ce programme : InitialiserClock(F) ; while (1) do MesurerTemperature() ; MesurerTension() ; AfficherSurEcranTempsTimerB() ; end while Résultats Les valeurs affichées par les compteurs des timers sont stockées dans les registres de 16 bits (T BR) des timers B. Par conséquent, les valeurs affichées par ces registres peuvent au maximum être comprises entre 0 et 65535 (#F F F F #). Ainsi, à chaque fois que le compteur arrive au delà de cette valeur maximum (65535), il reprend le compte à partir de la valeur 0 comme une simple addition sur 16 bits ou une addition modulo 216 . Nous obtenons ainsi les courbes suivantes : En abscisse, sont représentés les numéros des valeurs de temps relevées à CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 25 partir des compteurs T BR des timers B. En ordonnée, sont représentées ces valeurs de temps. Conclusions Grâce au graphique de la section 1.5.1, nous pouvons noter visuellement que les temps affichés par les compteurs des timers aux même instants t sont différents pour les 5 capteurs. Ceci nous permet de consolider le caractère dissymétrique caractérisant les horloges internes des capteurs. 1.5.2 Etude de l’évolution à court terme des temps affichées par les horloges internes des capteurs Expérimentation Pour cette étude, nous avons conservé la même expérimentation que précédemment. Cependant, nous avons cherché à savoir si à court terme, les coefficients directeurs des droites que l’on a affichées dans le graphique de la section 1.5.1 restent constants pour chacun des 5 capteurs. Pour cela, nous avons calculé les coefficients directeurs des droites. Ces coefficients directeurs sont proportionnels au λx où x est un des 5 capteurs de l’expérimentation et le coefficient de proportionnalité est le même pour les 5 capteurs étant donné qu’il ne dépend que de l’intervalle de temps entre deux mesures de temps (ce qui équivaut dans notre cas au temps mis pour mesurer la température et la tension). Résultats Voici les résultats que nous avons obtenus pour chacun des 5 capteurs : Capteur 1 79.97 79.87 79.93 80.00 80.07 Capteur 2 70.19 70.15 70.31 70.38 70.44 Capteur 3 65.54 65.39 65.43 65.45 65.45 Capteur 4 82.27 82.24 82.36 82.39 82.52 Capteur 5 77.05 77.00 77.11 77.23 77.29 Conclusions Nous remarquons bien grâce au tableau de la section 1.5.3 que pour chacun des 5 capteurs, l’évolution des coefficients directeurs est stationnaire. Nous pouvons en conclure qu’à court terme, les valeurs des temps affichés par les horloges internes des différents capteurs en plus d’être différents, restent bien constants à court terme. En effet, le tableau ci-dessous permet de remarquer que les écarts entre les coefficients directeurs maximum et minimum restent négligeables. Capteur 1 0.25% Capteur 2 0.36% Capteur 3 0.24% Capteur 4 0.34% Capteur 5 0.38% CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 26 Figure 1.3 – Evolution des coefficients en fonction du temps 1.5.3 Etude de l’évolution à long terme des temps affichées par les horloges internes des capteurs Expérimentation Pour cette étude, nous avons conservé la même expérimentation que précédemment sauf qu’on l’a réalisée sur 4 capteurs. Cependant, nous avons cherché à savoir si à long terme, les coefficients directeurs des droites que l’on a affichées dans le graphique de la section 1.5.1 restent constants pour chacun des 4 capteurs. Pour cela, nous avons calculé pour chacun des 4 capteurs la moyenne ainsi que les valeurs minimale et maximale des 3 coefficients directeurs consécutifs que l’on obtient après chaque 20min de fonctionnement sur batterie. Résultats Nous avons tenu à présenter sous forme graphique l’évolution en fonction du temps des coefficents que l’on obtient : Dans ce graphique, nous avons aussi superposé les courbes de tendances que l’on obtient pour chacun des 4 capteurs. Force est de constater est que les courbes obtenues affichent des valeurs qui oscillent autour d’une valeur moyenne constante. Ceci est consolidé par les courbes de tendances qui restent constantes sur tout l’intervalle de temps de l’expérimentation : 24h. Afin de mieux déterminer les intervalles de variation de ces coefficients, voici sous forme de tableau les résultats que l’on obtient : Valeur minimum Valeur moyenne Valeur maximale Capteur A 76.01 76.64 77.75 Capteur B 82,01 82,51 83,06 Capteur C 64.01 64.83 65.42 Capteur D 78.06 79.35 80.3 CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 27 Ces valeurs minimum, moyenne et maximale sont les valeurs que l’on obtient sur toute la durée de l’expérimentation : 24h. Conclusions Les écarts que l’on obtient entre les valeurs maximale et minimale nous amènent à considérer dans notre proposition des intervalles de confiance nous permettant d’accepter au mieux les coefficients que l’on obtiendrait pour les différents capteurs. Voici un aperçu des écarts en pourcentage que l’on obtient pour les 4 capteurs de l’expérimentation : Capteur A 0.82% 1.45% Ecart minimum/moyenne Ecart maximum/moyenne 1.6 Capteur B 0.61% 0.66% Capteur C 1.27% 0.90% Capteur D 1.63% 1.20% Intégration des résultats des études expérimentales dans la proposition La section précédente nous a permis de valider par l’expérimentation, que les coeffients qui matérialisent l’évolution des temps affichés par les horloges internes des capteurs, restent constants au cours du temps. Cependant, elle nous a aussi amené à se poser des questions sur l’intervalle de confiance dans lequel nous pouvions considérer les valeurs des coefficients λ et µ. 1.6.1 Affinement du calcul de λ Comme nous l’avons noté lors des expérimentations précédentes, les valeurs des coefficients directeurs des courbes donnant les temps d’horloges internes oscillent autour d’une valeur moyenne constante. Or le calcul du coeficient λ est fonction de ces temps. En effet, ces coefficients directeurs sont à l’image du coefficient λm,n dans la mesure où il correspond au rapport des coefficients directeurs de 2 capteurs m et n. Ainsi, pour que le calcul des valeurs λm,n soit le plus précis possible, il sera affiné au fur et à mesure. A l’initialisation, c’est-à-dire à l’instant R2n , il sera égal à : λ0m,n = R2n − R0n T2n − T0n (1.23) Ensuite, il sera défini par la relation de récurrence suivante : λkm,n kλk−1 m,n + = n n Rk+2 −Rk n −T n Tk+2 k k+1 (1.24) Ainsi, nous considérons que des valeurs de λm,x1 et λm,x2 sont égales, si elles sont toutes les deux comprises dans l’intervalle λkm,n ± 1.5%, c’est-à-dire dans l’intervalle [0.985λkm,n ; 1.015λkm,n ]. CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 1.6.2 28 Affinement du calcul de µ Pareil pour le calcul des valeurs µm,n , il est non seulement fonction de ces temps mais aussi de λ. Il sera alors également affiné au fur et à mesure. A l’initialisation, c’est-à-dire à l’instant R2n , il sera égal à : µ0m,n = R2n + T1m Rm + T2n − λm,n 1 2 2 (1.25) Ensuite, il sera défini par la relation de récurrence suivante : µkm,n = kµk−1 m,n + n m Rk+2 +Tk+1 2 − λm,n k+1 m n Rk+1 +Tk+2 2 (1.26) Ainsi, nous considérons que des valeurs de µm,x1 et µm,x2 sont égales, si elles sont toutes les deux comprises dans l’intervalle λkm,n ± 2%, c’est-à-dire dans l’intervalle [0.98µkm,n ; 1.02µkm,n ]. 1.7 1.7.1 Implémentation et Simulation sous WSNet Présentation de la plateforme de simulation WSNet WSNet est un simulateur de réseaux de capteurs à événements discrets développé, à l’origine, au laboratoire CITI ([3]), [8] et [9]). Il reste assez similaire aux autres simulateurs à événements discrets comme NS2, GTNetS ou Omnet++ dans ses objectifs. Cependant, il se différencie des autres dans sa capacité à modéliser très précisément le medium radio sans toutefois empêcher la simulation de réseaux de plusieurs centaines de noeuds. A ce sujet, il est possible de se reporter à l’article [14] de Ben Hamida et al. WSNet fonctionne sous Linux et il a l’avantage d’être gratuit (sous licence CeCILL). Il possède une architecture modulaire et il se caractérise par une très grande extensibilité. Pour une simulation donnée, on doit préciser le choix des modèles et des structures à utiliser. Ceci est fait à l’aide des fichiers de configuration XML qui sont détaillés dans le tutorial disponible sur le page web suivante. 1.7.2 Implémentation Dans notre implémentation, nous avons créé un modèle au niveau de la couche de routage permettant des échanges de paquets HELLO pour la découverte des noeuds voisins, et des échanges de paquets N EIGH V ER pour la détection des noeuds Sybille. Dès qu’un noeud m reçoit le premier paquet HELLO en provenance d’un voisin n, le noeud m initialise l’échange de paquets N EIGH V ER avec le noeud n et ce en envoyant à n le premier paquet N EIGH V ER. A la réception du premier paquet N EIGH V ER, le noeud récepteur enregistre le temps d’émission véhiculé par ce premier paquet reçu puis envoie un paquet N EIGH V ER à destination du noeud émetteur. Au bout du deuxième paquet CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 29 N EIGH V ER reçu, le noeud récepteur calcule les coefficients λ et µ dans le but de pour pouvoir détecter les attaques Sybille et calcule les moyennes et les écarts-types des temps de propagation des aller-retours de paquets avec chacun de ses voisins dans le but de pouvoir détecter les mensonges. Une fois qu’il a calculé ces coefficients pour chacun de ces voisins, il les compare à ceux qu’il a calculé pour ses autres voisins dans le but de détecter soit une attaque Sybille, soit un mensonge. Si pour certains de ces noeuds voisins pourtant avec des identités différentes, le noeud vérifieur détecte que les valeurs de λ et de µ calculées sont égales alors il marque ce noeud comme étant Sybille. Si pour certains de ces noeuds voisins pourtant avec des identités différentes, le noeud vérifieur détecte que les valeurs de Rx − T n sont égales ou que les valeurs σ[Rx − T n ] sont supérieures à un certain seuil , alors il marque ce noeud comme étant Sybille intelligent. Comme précisé dans notre modèle d’attaques (section 3.2), les noeuds Sybille intelligents sont des noeuds Sybille capables de mentir en falsifiant les données qu’ils envoient à leurs voisins, et ce dans le but de ne pas être détectés Sybille. En ce qui concerne les couches inférieures, nous avons fait le choix d’utiliser des couches radio et MAC idéales de sorte qu’on évite les pertes de paquets. Cependant, nous avons dû modifié la couche radio de telle sorte que le temps d’envoi d’un paquet ne soit pas forcément le même pour chacun des noeuds. En effet, avec une couche radio idéale, le temps mis pour un paquet pour aller d’une source à une destination de son voisinage était le même quelque que soit le noeud. Dans le modèle de couche radio idéale modifiée, ce temps est tiré aléatoirement et est spécifique pour chacun des noeuds du réseau. Cette modification a été faite dans une optique de se rapprocher du cas réel où le temps de propagation d’un paquet entre son émission et sa réception dépend de la distance qui sépare l’émetteur du récepteur et ainsi pour pouvoir notamment implémenté correctement notre mécanisme de défense contre les mensonges occasionnés par les noeuds voisins. CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 1.7.3 30 Paramètres de la simulation Dans les simulations que nous avons réalisées, nous avons fixé les paramètres suivants : Surface de déploiement Distance de portée 100m × 100m 20m En ce qui concerne les seuils nous permettant de considérer que deux valeurs de coefficients sont égales, nous avons choisi les plus judicieux, c’est-à-dire ceux qui nous permettent d’avoir la plus grande probabilité de détection mais qui nous permettent d’éviter le maximum de faux positifs. En effet, voici les paramètres que l’on a fixé pour la comparaison de : λ µ Rx − T n σ[Rx − T n ] 1.5 % (C.f section 1.6.1) 2 % (Cf section 1.6.2) 5 × 10−4 % 0.002 % Dans une première partie, nous allons chercher à mesurer les probabilités de détection des : – noeuds Sybille naı̈fs. – noeuds Sybille intelligents. Dans une deuxième partie, nous allons chercher à mesurer les taux de faux positifs des : – noeuds Sybilles naı̈fs – noeuds Sybilles intelligents Voici sous forme de tableau les formules utilisées dans nos calculs : Probabilité de détection Taux de faux positifs noeuds Sybilles naı̈fs N ombre liens N aif s detectes N ombre total liens N aif s N ombre F aux liens N aif s detectes N ombre total liens honnetes noeuds Sybilles intelligents N ombre liens Intelligents detectes N ombre total liens Intelligents N ombre F aux liens Intelligents detectes N ombre total liens honnetes Dans toutes les simulations, nous avons considéré que 1/3 des noeuds Sybille √ étaient des noeuds Sybilles intelligents, et qu’un noeud Sybille présente b dc identités avec d son degré. Nous avons réalisé 2 séries de simulations : Dans la 1ere série, nous avons fixé le nombre à 300 le nombre de noeuds dans le réseau, ce qui a permis d’avoir un degré moyen égal à 30.8. Ensuite sur les 300 noeuds du réseau, nous avons fait varié le nombre de noeuds Sybille : 10, 20, 30, 40, 50 puis 60. Dans la 2eme série, nous avons fixé à 10% le taux total de noeuds Sybilles et nous avons fait varier le nombre de noeuds dans le réseau (100, 200 et 300) de sorte à avoir des degrés moyens égaux à 10, 20, et 30. CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE 1.7.4 31 Résultats Pour plus de précision, les résultats ont été calculés à partir d’une moyenne effectuée sur 100 simulations. 1ère série de simulation Voici sous forme de graphiques, les résultats que nous obtenons : Figure 1.4 – Probabilité de détection Figure 1.5 – Taux de faux positifs Avec les paramètres choisis et quelque soit le nombre de noeuds attaquants considérés dans nos simulations, nous obtenons bien des probabilités de détection très élevées : toujours égales à 100% en ce qui concerne la détection des noeuds Sybilles naı̈fs et toujours supérieures à 97% en ce qui concerne la détection des noeuds Sybille intelligents. Ces résultats viennent confirmer l’efficacité de notre approche pour la détection des attaques Sybille. D’autre part, nous notons que les taux de faux positifs pour les noeuds Sybille naı̈fs sont relativement bas et leur croissance en fonction du nombre de noeuds attaquants considérés reste très faible, voire négligeable. De même, nous remarquons que les taux de faux positifs pour les noeuds Sybille intelligents sont relativement bas et leur croissance en fonction du nombre de noeuds attaquants considérés est faible mais non négligeable. Cependant, nous constatons que les taux de faux positifs pour les noeuds Sybille intelligents sont considérables et ne peuvent pas être considérés comme très satisfaisants. Néanmoins, leur croissance en fonction du nombre de noeuds attaquants considérés reste très faible, voire stationnaire. Ce taux assez élevé s’explique par le fait qu’un nombre assez important de noeuds légitimes est détecté comme étant Sybille intelligents. 2ème série de simulation Voici sous forme de graphiques, les résultats que nous obtenons : Avec les paramètres choisis et quelque soit le degré moyen considéré dans nos simulations, nous obtenons bien des probabilités de détection très élevées : toujours égales à 100% en ce qui concerne la détection des noeuds Sybilles naı̈fs et toujours supérieures à 97% en ce qui concerne la détection des noeuds Sybille intelligents. Ces résultats viennent confirmer l’efficacité de notre approche pour la détection des attaques Sybille. On remarque cependant une décroissance de cette probabilité quand la densité moyenne augmente. CHAPITRE 1. LUTTE CONTRE LES ATTAQUES SYBILLE Figure 1.6 – Probabilité de détection 32 Figure 1.7 – Taux de faux positifs D’autre part, nous notons que les taux de faux positifs pour les noeuds Sybille naı̈fs sont relativement bas et leur croissance en fonction de la densité moyenne reste très faible, voire négligeable. De même, nous remarquons que les taux de faux positifs pour les noeuds Sybille intelligents sont relativement bas pour des densités basses (10) ou moyennes (20). Néanmoins, nous constatons que les taux de faux positifs pour les noeuds Sybille intelligents sont considérables pour les densités élevées (30) et ne peuvent pas être considérés comme très satisfaisants. De plus, leur croissance en fonction du degré moyen considéré est importante. 1.8 Conclusion partielle Dans ce rapport de stage, nous avons proposé un mécanisme pratique pour se prémunir contre les attaques Sybille dans les réseaux de capteurs sans fil. En effet, les effets des attaques Sybille peuvent compromettre le bon fonctionnement des réseaux de capteurs. Notre proposition exploite les propriétés physiques des capteurs qui sont déployés dans ces réseaux. Notre mécanisme de défense a l’avantage de pouvoir être implémenté dans tout type d’application des réseaux de capteurs sans fil. Les résultats de simulations montrent bien que notre proposition est efficace pour détecter les attaques Sybille. En effet, nous réussissons à détecter avec une très grande probabilité, non seulement les noeuds Sybille naı̈fs mais aussi les noeuds Sybille intelligents qui tenteraient de mentir. En outre, les taux des faux positifs pour les noeuds Sybille naı̈fs ou les noeuds Sybille intelligents pour des densités faibles ou moyennes ne sont pas trop élevés contrairement à ce que l’on pouvait craindre. Toutefois, ces taux de faux positifs restent relativement élevés pour les noeuds Sybille intelligents dans des densités de réseau très élevées. Dans la suite de nos travaux, nous tenterons d’améliorer cette approche en tentant d’avoir des taux de faux positifs encore plus bas de sorte que notre approche reste toujours résiliente face aux attaques Sybille. Par ailleurs, nous envisageons d’implémenter cette approche sur la plateforme SensLab, dans le but d’évaluer les performances dans un environnement très proche de la réalité. Chapitre 2 Etude comparative de systèmes de coordonnées virtuelles dans les réseaux de capteurs sans fil 2.1 Introduction Les réseaux de capteurs sans fil sont des réseaux ad hoc avec un grand nombre de noeuds. Chaque noeud de ce réseau est un capteur capable de récolter et de transmettre à destination d’un noeud puits des données environnementales. Le développement des réseaux de capteurs sans fil (WSNs) a été originellement motivé par des applications militaires mais touche aujourd’hui aussi les applications civiles. Les noeuds dans les réseaux de capteurs sont caractérisés par plusieurs contraintes, incluant les faibles capacités de calcul (CPU et mémoire), les ressources limitées en énergie, la possibilité d’être compromis physiquement. Dispersés dans des zones géographiques de large étendue, les noeuds capteurs ne sont capables de transmettre au puits les données captées que s’ils ont recours au routage multi-saut. Or très souvent, la position de ces noeuds n’est pas prédéterminée et encore moins celle des noeuds voisins (on appelle noeuds voisins d’un noeud donné, ceux avec qui ce dernier est à portée de communication). Pour auto-structurer un routage multi-saut efficace dans un réseau de capteurs où l’on ne connaı̂t pas les coordonnées réelles des noeuds, de nombreux travaux de recherche ont eu pour mission de concevoir des systèmes de coordonnées virtuelles (Virtual Coordinates Systems - VCS). Dans le cadre de ce projet de fin d’études, nous nous sommes focalisés spéciquement sur deux systèmes de coordonnées virtuelles particuliers : 33 CHAPITRE 2. COMPARAISON DE VCS 34 – Centroı̈d Virtual Coordinates [29] de T. Watteyne et al. – Beacon Vector Routing [7] de R. Fonseca et al. Les approches utilisées dans ces deux systèmes de coordonnées virtuelles différentes. D’un côté, celle de T. Watteyne et al. se base sur des coordonnées virtuelles aléatoirement initialisées et qui sont régulièrement mis à jour dans une optique de converger vers une topologie virtuelle la plus proche de la topologie réelle. De l’autre côté, celle de R. Fonseca et al. considère l’existence de noeuds capteurs particuliers : des ancres, des noeuds référence à partir desquels les autres noeuds du réseau calcule des coordonnées correspondant à la distance (en nombre de sauts) à chacune de ses ancres. Après avoir détaillé le fonctionnement du système de coordonnées virtuelles proposé par T. Watteyne et al. en section 2.2 puis celui qu’ont proposé de R. Fonseca et al. en section 2.3, nous établirons en section 2.4 l’étude comparative de ces deux systèmes de coordonnées virtuelles. Nous finirons le présent chapitre de PFE par une conclusion partielle et notamment par les perspectives dans lesquelles nos travaux sur ces systèmes de coordonnées virtuelles ont été menées. 2.2 Centroı̈d Virtual Coordinates [29] Contrairement à la majorité des propositions de systèmes de coordonnées, celle de T. Watteyne et al. ne se base ni sur la présence d’ancres dans le réseau, ni sur l’utilisation de GPS. En effet, dans leur proposition, l’accent est mis sur l’attribution aléatoire de coordonnées virtuelles à l’initialisation et une mise à jour progressive de ces coordonnées leur permettant d’atteindre une convergence quasi-optimale. Ensuite, c’est en se basant sur ces coordonnées virtuelles, que le routage fonctionnera. En effet, le routage le plus adéquat serait le routage ”greedy”. 2.2.1 Calcul des coordonnées virtuelles Deux types de noeuds sont considérés dans le réseau : des noeuds capteurs et des puits. Par souci de simplification, nous avons considéré qu’il y avait qu’un seul puits, comme précisé dans l’article [29]. Cependant, cela peut être généralisé à n puits. A chaque fois qu’un nouveau noeud capteur rejoint le réseau, il choisit aléatoirement une paire de coordonnées virtuelles x et y (deux nombres décimaux) choisies dans l’intervalle [0, M axCoord] où M axCoord est la valeur initiale maximum que peut avoir une coordonnée virtuelle. Il mettra à jour ses coordonnées progressivement en se basant sur les coordonnées de ses voisins. Cependant le puits a un comportement légèrement différent par rapport aux noeuds capteurs ordinaires. En effet, il initialise ses coordonnées virtuelles à [0, 0] et ne change jamais ses coordonnées. Par conséquent, les noeuds savent par avance la position virtuelle du puits et ce dernier n’a donc pas besoin de leur transmettre sa position. CHAPITRE 2. COMPARAISON DE VCS 35 Si l’on avait considéré plusieurs puits si avec i ∈ [1, n], alors chacun des noeuds du réseau aura n paires de coordonnées. Dans ce cas, un puits si initialisera à [0, 0]si la ieme paire de coordonnées et choisira aléatoirement aux autres paires de coordonnées (comme s’il était un noeud capteur ordinaire). Il ne changera donc pas la ieme paire de coordonnées de sorte que les autres noeuds du réseau connaissent cette position virtuelle sans avoir à échanger de paquets au préalable. En ce qui concerne les noeuds ordinaires du réseau (différents du puits), ils mettront à jour la ieme paire de coordonnées conformément aux ieme paires de coordonnées des noeuds voisins. A chaque fois qu’un noeud capteur V transmet son propre paquet de données ou qu’il en relaie un, il met à jour ses coordonnées selon la transformation suivante : Etape 1 : Le noeud V récupère les coordonnées virtuelles de ses noeuds voisins. Cette étape n’est pas spécifique à la solution. Pour récupérer les coordonnées virtuelles des voisins, on peut utiliser une approche proactive ou réactive. Soit Wi avec i allant de 1 à n, l’ensemble de ses n voisins. Etape 2 : Le noeud V fixe ses propres coordonnées au point de gravité de ses voisins, c’est-à-dire, qu’il met à jour ses coordonnées avec la moyenne des coordonnées de ses voisins. Cette étape permet de rapprocher virtuellement les noeuds qui sont voisins. Etape 3 : Si après l’étape 2, il s’avère que le noeud V est trop proche virtuellement d’un de ces voisins Wi , c’est-à-dire à une distance virtuelle inférieure au seuil M inV irtual alors V prévient le noeud Wi pour mettre à jour ces coordonnées. Soient Wx∗ et Wy∗ ses nouvelles coordonnées virtuelles et Wx et Wy ses anciennes coordonnées virtuelles. Soit Vx et Vy les coordonnées virtuelles du noeud V . Le noeud Wi mettra à jour alors ses coordonnnées virtuelles comme suit : Wx∗ = Wy∗ = Wx − Vx · M inV irtual) + Vx (Vx − Wx )2 + (Vy − Wy )2 Wy − Vy (p · M inV irtual) + Vy (Vx − Wx )2 + (Vy − Wy )2 (p (2.1) (2.2) Cette étape n’a pas d’impact sur la convergence du système mais permet de faciliter l’implémentation sur de vrais capteurs pour lesquels les coordonnées virtuelles peuvent être des nombres avec une précision limitée. Cela permet d’éviter que deux noeuds se retrouvent affectés à une même position virtuelle. CHAPITRE 2. COMPARAISON DE VCS 2.2.2 36 Routage utilisant le système de coordonnées virtuelles Parallèlement à la mise à jour en continu des coordonnées virtuelles de chacun des noeuds du réseau, l’acheminement des paquets de données à destination du puits se fait moyennant un routage ”greedy” se servant justement de ces coordonnées virtuelles. En effet, si le noeud V veut transmettre ou relayer un paquet à destination du puits s, il va choisir parmi ces voisins celui qui a les coordonnées virtuelles les plus proches de ceux du puits. Or, les coordonnées virtuelles du puits sont fixés à [0; 0] et restent inchangés tout au long de la durée de vie du réseau de capteurs. De ce fait, il choisira le noeud voisin qui a les coordonnées virtuelles les proches de 0. 2.3 Beacon Vector Routing [7] La proposition de R. Fonseca et al. reste assez classique et nécessite la considération de noeuds jouant le rôle d’ancres dans le réseau de capteurs. La mise en place des systèmes de coordonnées est plus simple que celle proposée dans [29]. Cependant, l’accent est mis sur le routage utilisé une fois ce système de coordonnées virtuelles mis en place. 2.3.1 Calcul des coordonnées virtuelles Si on suppose l’existence de k ancres dans le réseau, alors les coordonnées de chaque noeud de ce réseau sont représentées par un vecteur de taille k dans lequel chacune des coordonnées i (allant de 1 à k) est la distance (en nombre de sauts) à l’ancre i. Pour faire connaı̂tre à chaque noeud du réseau, la distance qui le sépare d’une ancre donnée i, cette dernière broadcaste périodiquement un paquet BV R qui est mis à jour à chaque saut. Un noeud qui reçoit un premier paquet BV R met à jour sa coordonnée correspondante avec le nombre de sauts indiqué par ce paquet BV R. S’il ne s’agit pas du premier paquet BV R qu’il reçoit, il s’assure alors qu’il n’indique pas un nombre de sauts inférieur à sa coordonnée correspondante. Si c’est le cas, il met à jour cette coordonnée avec le nombre de sauts indiqué par ce paquet BV R. Deux noeuds peuvent avoir les mêmes coordonnées virtuelles. Pour lever l’ambiguité, on retient aussi un identifiant unique pour chaque noeud du réseau. 2.3.2 Routage utilisant le système de coordonnées virtuelles Pour prendre une décision sur le routage, un noeud courant doit impérativement connaı̂tre les coordonnées virtuelles de ses voisins. Pour cette raison, chaque CHAPITRE 2. COMPARAISON DE VCS 37 noeud du réseau broadcaste périodiquement ses coordonnées virtuelles dans le réseau pour les faire connaı̂tre à ses voisins. Pour router un paquet, Fonseca et al. utilisent une distance δ(p, d) permettant de savoir à quel degré un noeud p est un ”bon” saut pour atteindre la destination d. Ils utilisent les deux sommes suivantes : X δk+ (p, d) = max(pi − di , 0) (2.3) i∈Ck (d) δk− (p, d) = X max(di − pi , 0) (2.4) i∈Ck (d) et on a : δ(p, d) = 10δk+ (p, d) + δk− (p, d) (2.5) Pour transmettre un paquet de données D, ce dernier contient les 3 champs additionnels suivants : – D.dst : l’identifiant unique de la destination – D.P (dst) : la position virtuelle de la destination – D.δimin : δ minimum que ce paquet a vu en utilisant Ci (dst) (les i ancres les plus proches de dst) Soit curr le noeud voulant transmettre un paquet D. Voici l’algorithme qu’il utilise pour transmettre ce paquet. // On met à jour les champs du paquet à transmettre for i = 1 to k do D.δimin ← min(D.δimin ,δi (curr, D.dst)) ; end for // On tente d’abord le routage ”greedy” for i = k to 1 do suivant ← argminx∈N BR(curr) δi (x, D.dst) ; if (δi (suivant, D.dst) < D.δimin ) then unicast D à suivant ; end if end for // Si le routage ”greedy échoue : on utilise le mode ”fallback”. Ici, // on envoie progressivement vers l’ancre la plus proche de D.dst ancre fallback ← ancre la plus proche a D.dst ; if (ancre f allback 6= curr) then unicast D à P ERE(ancre f allback) ; end if // Si le fallback échoue, on inonde le réseau avec le paquet D broadcast D ; CHAPITRE 2. COMPARAISON DE VCS 2.4 38 Etude comparative des deux systèmes de coordonnées virtuelles Afin de comparer l’efficacité de ces deux systèmes de coordonnées virtuelles, nous avons fait le choix de les implémenter sur WSNet, qui est un simulateur à événements discret développé au CITI [9]. Nous exposerons d’abord nos choix d’implémentation sur WSNet. Ensuite, nous décrirons les métriques que nous avons choisies pour évaluer ces deux propositions ainsi que les paramètres choisis pour les simulations. Enfin, nous comparerons les résultats que nous avons obtenus. 2.4.1 Choix d’implémentation Pour pouvoir comparer au mieux ces deux systèmes de coordonnées, nous avons implémenté la même couche application. Dans cette couche application, nous avons imaginé qu’il y a un puits unique vers lequel tous les noeuds du réseau transmettent périodiquement leurs paquets de données. Ce puits est localisé au centre de l’aire de déploiement considérée. Le module permettant de simuler la couche application est joint en annexe C.1 du présent rapport. De plus, nous avons considéré des couches radio et MAC idéales pour les deux systèmes de coordonnées virtuelles implémentés et ce dans une optique d’éviter les pertes de paquets. En ce qui concerne la couche réseau (plus connue sous le nom de couche de routage quand on parle de réseaux de capteurs), nous avons prévu un échange périodique de paquet HELLO permettant à chaque noeud de faire connaı̂tre ses propres coordonnées virtuelles à ses voisins. De cette façon, chaque noeud du réseau connaı̂t les positions virtuelles de chacun de ses voisins. De plus, dans le cas particulier du VCS de R.Fonseca et al., nous avons prévu un deuxième type de paquet BV R qui permettrait de construire périodiquement les systèmes de coordonnées virtuelles en se basant sur les distances en nombre de sauts de chacune des ancres considérés. Les module permettant de simuler les couches réseau du VCS de T. Watteyne et al. et de R. Fonseca et al. sont respectivement joints en annexes C.2.1 et C.2.2 du présent rapport. 2.4.2 Métriques et paramètres de simulations Afin d’évaluer les performances de ces deux systèmes de coordonnées virtuelles, nous avons choisi de calculer les métriques suivantes : – Taux de livraison de paquets = Nombre de paquets reçus / Nombre de paquets envoyés – Rayon moyen théorique = distance moyenne au puits (en nombre de sauts) se basant sur les coordonnées réelles – Rayon moyen virtuel = distance moyenne au puits (en nombre de sauts) se basant sur les coordonnées virtuelles une fois que le système de coordonnées virtuelles a convergé CHAPITRE 2. COMPARAISON DE VCS 39 Figure 2.1 – Evolution des temps de convergence en fonction du nombre de noeuds – Temps de convergence = temps à partir duquel 95 % des noeuds ont vu leurs positions virtuelles converger Dans toutes les simulations, l’aire de déploiement est de 100m × 100m. Le puits est donc localisé à la position [50m, 50m]. La portée de communication est fixée à 20m. Nous avons réalisé les simulations un nombre de noeuds variant de 100, 150, 200, 250 à 300 de sorte à avoir des densités moyennes respectives de 10, 15, 21, 26 et 31. 2.4.3 Résultats Les résultats suivants ont été obtenus à partir de moyennes effectuées sur 100 simulations. En ce qui concerne le système de coordonnées proposé par R. Fonseca et al, nous avons considéré l’existence de 2 ancres choisies aléatoirement parmi tous les noeuds du réseau. Pour les deux systèmes de coordonnées virtuelles étudiés, nous obtenons des taux de livraison égaux à 1 quelque soit le nombre de noeuds considérés dans le réseau. Ceci était évidemment prévisible car nous avons considéré des couches radio et MAC idéales. Temps de convergence Voici sous forme de graphe (voir figure 2.1) les résultats que nous obtenons par rapport aux temps de convergence. Grace au graphe de la figure 2.1, nous constatons que la convergence du système de coordonnées virtuelles proposé par R. Fonseca et al. est bien plus rapide que celui qu’ont proposé T. Watteyne et al.. En effet, ces temps sont de CHAPITRE 2. COMPARAISON DE VCS 40 Figure 2.2 – Evolution des rayons moyens théoriques et virtuels en fonction du nombre de noeuds l’ordre de la seconde pour ce système de coordonnées alors que pour celui de T. Watteyne, il est de l’ordre de la centaine de secondes et al. quand il s’agit de faibles densités (10 et 15) et de l’ordre de la dizaine de secondes quand il s’agit de densités plus élevées (supérieures à 20). Ce résultat était en effet prévisible car l’établissement des coordonnées virtuelles dans le cas de R. Fonseca et al. se fait seulement via un broadcast de paquets dans le réseau par chacune des ancres placées. Et une fois ces paquets reçus par tous les noeuds du réseau, les coordonnées virtuelles sont connues par les noeuds qui les portent. Dans le cas de T. Watteyne, la mise à jour des coordonnées virtuelles nécessite forcément un temps plus important car ces coordonnées virtuelles dépendent du choix aléatoire qu’a effectué chacun des noeuds mais aussi de la densité moyenne considéré. En effet, plus on a de voisins, plus notre position virtuelle calculée à partir de ces voisins est proche de la topologie réelle. Performances du routage Voici sous forme de graphe (voir figure 2.2) les résultats que nous obtenons par rapport aux rayons moyens théoriques et virtuelles. Grâce au graphe de la figure 2.2, nous notons que les rayons moyens virtuels dans le cas de T. Watteyne et al. sont très proches des rayons moyens théoriques contrairement au cas de R. Fonseca ou ils sont en moyenne 50 % plus élevés. Ce résultat était aussi prévisible du fait que le système de coordonnées virtuelles proposé par T. Watteyne et al. permet d’obtenir des coordonnées virtuelles uniques pour chacun des noeuds du réseau alors que celui que propose R. Fonseca et al. ne le permet pas à moins que l’on considère l’existence d’un nombre assez élevé d’ancres dans le réseau. Ce qui engendrera en conséquence une surcharge du réseau. CHAPITRE 2. COMPARAISON DE VCS 2.5 41 Conclusion partielle Grâce à cette deuxième partie du rapport, nous avons pu évaluer les performances de deux systèmes de coordonnées virtuelles (VCS) différents : celui de T. Watteyne et al d’une part et celui de R. Fonseca de l’autre part. Le VCS proposé par R. Fonseca a l’avantage de converger plus rapidement que celui proposé par T. Watteyne mais ne permet malheureusement pas un routage aussi optimisé que celui que l’on retrouve dans le VCS proposé par T. Watteyne. Maintenant que l’on a pu évaluer les performances de ces deux VCS, il nous vient à l’idée de voir le comportement de ces VCS en présence d’attaques. En effet, nos prochaines orientations seront de savoir laquelle des approches est la plus résiliente dans un environnement hostile et peu sécuritaire. Pour cela, nous nous intéresserons par la suite à implémenter différentes attaques sur le réseau et devoir comment cela affecte la convergence du système et les performances du routage. Dans le cas où le comportement de ces VCS s’avère pas suffisamment résilient, nous nous intéresserons alors à proposer un mécanisme permettant d’assurer la sécurité en présence d’attaquants. Conclusion générale Dans ce rapport de PFE, nous avons pu d’une part proposer un mécanisme efficace pour se prémunir contre les attaques Sybille dans les réseaux de capteurs. Dans la suite de nos travaux concernant l’attaque Sybille, nous nous essairons d’optimiser au mieux l’approche que l’on a proposée pour déjouer les effets de cette attaque. D’autre part, nous avons aussi pu étudier les performances de deux systèmes de coordonnées virtuelles. Dans la suite de nos travaux concernant les systèmes de coordonnées virtuelles, nous tenterons aussi d’étudier l’impact de l’introduction d’attaques visant à compromettre le bon fonctionnement d’un système de coordonnées virtuelles donné. Nous essaierons aussi de proposer une alternative pour sécuriser au mieux ces systèmes de coordonnées virtuelles. 42 Bibliographie [1] Guillermo Barrenetxea, François Ingelrest, Yue M. Lu, and Martin Vetterli. Assessing the challenges of environmental signal processing through the sensorscope project. In Proceedings of the IEEE International Conference on Acoustics, Speech, and Signal Processing, ICASSP 2008, March 30 April 4, 2008, Caesars Palace, Las Vegas, Nevada, USA, pages 5149–5152. IEEE, 2008. [2] Guillermo Barrenetxea, François Ingelrest, Gunnar Schaefer, Martin Vetterli, Olivier Couach, and Marc Parlange. Sensorscope : Out-of-the-box environmental monitoring. In Proceedings of the 7th International Conference on Information Processing in Sensor Networks, IPSN 2008, St. Louis, Missouri, USA, April 22-24, 2008, pages 332–343. IEEE Computer Society, 2008. [3] Guillaume Chelius, Antoine Fraboulet, and Eric Fleury. Worldsens : a fast and accurate development framework for sensor network applications. In Proceedings of the 2007 ACM Symposium on Applied Computing, SAC 2007, Seoul, Korea, March 11-15, 2007, pages 222–226. ACM, 2007. [4] David M. Davenport, Budhaditya Deb, and Fergus J. Ross. Wireless propagation and coexistence of medical body sensor networks for ambulatory patient monitoring. In Sixth International Workshop on Wearable and Implantable Body Sensor Networks, BSN 2009, Berkeley, CA, USA, 3-5 June 2009, pages 41–45. IEEE Computer Society, 2009. [5] John R. Douceur. The sybil attack. In Peer-to-Peer Systems, First International Workshop, IPTPS 2002, Cambridge, MA, USA, March 7-8, 2002, Revised Papers, pages 251–260. Springer, 2002. [6] Ochirkhand Erdene-Ochir, Marine Minier, Fabrice Valois, and Apostolos A. Kountouris. Resilient networking in wireless sensor networks. CoRR, abs/1003.5104, 2010. [7] Rodrigo Fonseca, Sylvia Ratnasamy, Jerry Zhao, Cheng Tien Ee, David E. Culler, Scott Shenker, and Ion Stoica. Beacon vector routing : Scalable point-to-point routing in wireless sensornets. In 2nd Symposium on Networked Systems Design and Implementation (NSDI 2005), Boston, Massachusetts, USA, May 2-4, 2007 2005. 43 BIBLIOGRAPHIE 44 [8] Nicolas Fournel, Antoine Fraboulet, Guillaume Chelius, Eric Fleury, Bruno Allard, and Olivier Brevet. Worldsens : from lab to sensor network application development and deployment. In Proceedings of the 6th International Conference on Information Processing in Sensor Networks, IPSN 2007, Cambridge, Massachusetts, USA, April 25-27, 2007, pages 551–552. ACM, 2007. [9] Antoine Fraboulet, Guillaume Chelius, and Eric Fleury. Worldsens : development and prototyping tools for application specific wireless sensors networks. In Proceedings of the 6th International Conference on Information Processing in Sensor Networks, IPSN 2007, Cambridge, Massachusetts, USA, April 25-27, 2007, pages 176–185. ACM, 2007. [10] N.M. Freris and P.R. Kumar. Fundamental limits on synchronization of affine clocks in networks. In 46th IEEE Conference on Decision and Control, pages 921 –926, dec. 2007. [11] S. Ganeriwal, R. Kumar, S. Adlakha, and M. Srivastava. Network-wide time synchronizing in sensor networks. Technical report, Networked and Embedded Systems Lab, Elec. Eng. Dept., UCLA, 2003. [12] Jeyanthi Hall, Michel Barbeau, and Evangelos Kranakis. Enhancing intrusion detection in wireless networks using radio frequency fingerprinting. In International Conference on Communications, Internet, and Information Technology, November 22 - 24, 2004, St. Thomas, US Virgin Islands, pages 201–206. IASTED/ACTA Press, 2004. [13] Mohamed Hamdi, Noureddine Boudriga, and Mohammad S. Obaidat. Whomoves : An optimized broadband sensor network for military vehicle tracking. Int. J. Communication Systems, 21(3) :277–300, 2008. [14] Elyes Ben Hamida, Guillaume Chelius, and Jean-Marie Gorce. Scalable versus accurate physical layer modeling in wireless network simulations. In 22st International Workshop on Principles of Advanced and Distributed Simulation, PADS 2008, June 3-6, 2008, Roma, Italy, pages 127–134. IEEE Computer Society, 2008. [15] Sana Tmar Ben Hamida, Jean-Benoı̂t Pierrot, and Claude Castelluccia. An adaptive quantization algorithm for secret key generation using radio channel measurements. In NTMS 2009, 3rd International Conference on New Technologies, Mobility and Security, 20-23 December 2009, Cairo, Egypt, pages 1–5. IEEE, 2009. [16] Ding-Jie Huang, Wei-Chung Teng, Chih-Yuan Wang, Hsuan-Yu Huang, and Joseph M. Hellerstein. Clock skew based node identification in wireless sensor networks. In Proceedings of the Global Communications Conference, 2008. GLOBECOM 2008, New Orleans, LA, USA, 30 November 4 December 2008, pages 1877–1881. IEEE, 2008. [17] François Ingelrest, Guillermo Barrenetxea, Gunnar Schaefer, Martin Vetterli, Olivier Couach, and Marc Parlange. Sensorscope : Application-specific sensor network for environmental monitoring. ACM Transactions On Sensor Networking, 6(2) :1–32, 2010. BIBLIOGRAPHIE 45 [18] Chris Karlof and David Wagner. Secure routing in wireless sensor networks : attacks and countermeasures. Ad Hoc Networks, 1(2-3) :293–315, 2003. [19] Brian Neil Levine, Clay Shields, and N. Boris Margolin. A survey of solutions to the sybil attack. Tech report 2006-052, University of Massachusetts Amherst, Amherst, MA, October 2006. [20] Shaohe Lv, Xiaodong Wang, Xin Zhao, and Xingming Zhou. Detecting the sybil attack cooperatively in wireless sensor networks. In International Conference on Computational Intelligence and Security, CIS 2008, 13-17 December 2008, Suzhou, China, Volume 1 - Conference Papers, pages 442– 446, Washington, DC, USA, 2008. IEEE Computer Society. [21] Miklós Maróti, Branislav Kusy, Gyula Simon, and Ákos Lédeczi. The flooding time synchronization protocol. In Proceedings of the 2nd International Conference on Embedded Networked Sensor Systems, SenSys 2004, Baltimore, MD, USA, November 3-5, 2004, pages 39–49. ACM, 2004. [22] Debapriyay Mukhopadhyay and Indranil Saha. Location verification based defense against sybil attack in sensor networks. In Distributed Computing and Networking, 8th International Conference, ICDCN 2006, Guwahati, India, December 27-30, 2006, pages 509–521. Springer, 2006. [23] Tibor István Nagy and József Tick. Intelligent sensor networks in the military and civil sectors. In 5th International Symposium on Applied Computational Intelligence and Informatics, SACI 2009, Timisoara, Romania, May 28-29, 2009, pages 471–474. IEEE, 2009. [24] James Newsome, Elaine Shi, Dawn Xiaodong Song, and Adrian Perrig. The sybil attack in sensor networks : analysis & defenses. In Proceedings of the Third International Symposium on Information Processing in Sensor Networks, IPSN 2004, Berkeley, California, USA, April 26-27, 2004, pages 259–268. ACM, 2004. [25] Indranil Saha and Debapriyay Mukhopadhyay. Security against sybil attack in wireless sensor network through location verification. In Distributed Computing and Networking, 10th International Conference, ICDCN 2009, Hyderabad, India, January 3-6, 2009. Proceedings, pages 187–192. Springer, 2009. [26] Kuo-Feng Ssu, Wei-Tong Wang, and Wen-Chung Chang. Detecting sybil attacks in wireless sensor networks using neighboring information. Computer Networks, 53(18) :3042–3056, 2009. [27] Vassileios Tsetsos, George Alyfantis, Tilemahos Hasiotis, Odysseas Sekkas, and Stathes Hadjiefthymiades. Commercial wireless sensor networks : Technical and business issues. In 2nd International Conference on Wireless on Demand Network Systems and Service (WONS 2005), 19-21 January 2005, St. Moritz, Switzerland, pages 166–173. IEEE Computer Society, 2005. [28] Wei-Tong Wang, Kuo-Feng Ssu, and Wen-Chung Chang. Defending sybil attacks based on neighboring relations in wireless sensor networks. Security and Communication Networks, Copyright 2010 John Wiley and Sons., abs/1003.5104, 2010. BIBLIOGRAPHIE 46 [29] Thomas Watteyne, Isabelle Augé-Blum, Mischa Dohler, Stéphane Ubéda, and Dominique Barthel. Centroid virtual coordinates - a novel near-shortest path routing paradigm. Computer Networks, 53(10) :1697–1711, 2009. [30] Haifeng Yu, Phillip B. Gibbons, Michael Kaminsky, and Feng Xiao. Sybillimit : A near-optimal social network defense against sybil attacks. In IEEE Symposium on Security and Privacy, 2008, (S&P 2008), 18-21 May 2008, Oakland, California, USA, pages 3–17. IEEE Computer Society, 2008. [31] Haifeng Yu, Michael Kaminsky, Phillip B. Gibbons, and Abraham Flaxman. Sybilguard : defending against sybil attacks via social networks. In SIGCOMM, Proceedings of the ACM SIGCOMM 2006 Conference on Applications, Technologies, Architectures, and Protocols for Computer Communications, Pisa, Italy, September 11-15, 2006, pages 267–278. ACM, 2006. [32] Haifeng Yu, Michael Kaminsky, Phillip B. Gibbons, and Abraham D. Flaxman. Sybilguard : defending against sybil attacks via social networks. IEEE/ACM TON, Transactions On Networking, 16(3) :576–589, 2008. [33] Mehmet R. Yuce, Peng Choong Ng, and Jamil Y. Khan. Monitoring of physiological parameters from multiple patients using wireless sensor network. J. Medical Systems, 32(5) :433–441, 2008. [34] Wassim Znaidi, Marine Minier, and Jean-Philippe Babau. An Ontology for Attacks in Wireless Sensor Networks. Research Report RR-6704, INRIA, 2008. [35] Wassim Znaidi, Marine Minier, and Jean-Philippe Babau. Detecting wormhole attacks in wireless networks using local neighborhood information. In Proceedings of the IEEE 19th International Symposium on Personal, Indoor and Mobile Radio Communications, PIMRC 2008, 15-18 September 2008, Cannes, French Riviera, France, pages 1–5. IEEE, 2008. Annexe A Détails du calcul de µ Grâce au schéma de la section 1.4.1, on identifie aisément la relation : n m ri+2 − ri+1 et = tni+2 − tm i+1 (A.1) n n n où tni+2 et ri+2 correspondent respectivement aux temps absolus Ti+2 et Ri+2 m m m m où ti+1 et ri+1 correspondent respectivement aux temps absolus Ti+1 et Ri+1 . Or on a : n Ti+2 = λn tni+2 + µn n n Ri+2 = λm ri+2 + µm m Ti+1 = λm tm i+1 + µm m m Ri+1 = λn ri+1 + µn n Ti+2 − µn λn n R − µm n =⇒ ri+2 = i+2 λm m Ti+1 − µm =⇒ tm i+1 = λm Rm − µn m =⇒ ri+1 = i+1 λn =⇒ tni+2 = (A.2) (A.3) (A.4) (A.5) Ainsi, la relation (A.1) devient : n Ri+2 − µm Rm − µn − i+1 = λm λn Soit après réécriture, on obtient : n Ti+2 − µn T m − µm − i+1 λn λm n m n Ri+2 + Ti+1 Rm + Ti+2 µn µm − = − i+1 λm λn 2λm 2λn En multipliant chacun des membres de l’équation A.7, on obtient : (A.6) (A.7) n m m n Ri+2 + Ti+1 + Ti+2 λm λm Ri+1 = − (A.8) λn 2 λn 2 D’où, on identifie clairement la relation suivante qui nous permet de calculer l’offset relatif (relative clock offset) dans notre cas : µm − µn µm,n = n m n Ri+2 + Ti+1 Rm + Ti+2 − λm,n i+1 2 2 47 (A.9) Annexe B Description technique des capteurs MSP430F2274 L’eZ430 qui est de la taille d’une clé USB est une plateforme sans fil permettant de programmer le micro-contrôleur MSP430F2274 de Texas Instruments. Elle comporte un transmetteur sans fil 2,4 GHz : CC2500. En effet, il sert de programmateur, de débuggeur et de simulateur pour le MSP430F2274. C’est un système de développement pas cher : environ une vingtaine d’euros. Construit autour d’un CPU 16 bits, le MSP430 a été conçu pour des applications embarquées à basse consommation et à faible coût. Il est particulièrement adapté aux applications sans-fil fonctionnant sur batteries. L’EZ430-RF2500 se sert de l’IAR Embedded Workbench Integrated Development Environment (IDE) ou de Code Composer Essentials (CCE) pour écrire, Figure B.1 – MSP430F2274 : composition matérielle 48 ANNEXE B. DESCRIPTION TECHNIQUE DES CAPTEURS MSP430F227449 télécharger, et debugger une application. La nouvelle interface USB de programmation et de débogage permet à l’eZ430-RF2500 d’envoyer et de recevoir des données du PC via l’application MSP430 Application. Composition matérielle de la plateforme eZ430-RF2500 : – Une interface USB de programmation et de débogage ne nécessitant aucune installation de pilote. – 18 pins accessibles – Une antenne de la puce – Le micro-contrôleur MSP430 – 2 Timers : Timer A et Timer B – Le transmetteur sans fil CC2500 – 2 pins d’entrée/sortie connectés aux LEDs rouge et verte pour un feedback visuel Annexe C Listing de code C.1 Module application /∗ ∗ ∗ \file ∗ \brief ∗ \ author ∗ \ date ∗ ∗/ vcs application . c V i r t u a l C o o r d i n a t e s System Mohammed El Mehdi DIOURI 2010 #include <s t d i o . h> #include <include / m o d e l u t i l s . h> m o d e l t model = { ” V i r t u a l C o o r d i n a t e s System ” , ”Mohammed El Mehdi DIOURI” , ” 0.1 ” , MODELTYPE APPLICATION, {NULL, 0} }; #define SENSOR 1 #define SINK 0 uint64 t ∗ last received ; struct nodedata { uint64 t start ; uint64 t period ; nodeid t dst ; 50 ANNEXE C. LISTING DE CODE 51 int s i z e ; int type ; // p o s i t i o n t d s t p o s ; int overhead ; /∗ f o r s t a t s ∗/ int p a c k e t t x ; int p a c k e t r x ; }; int p a c k e t t x ; int p a c k e t r x ; struct p a c k e t h e a d e r { int s o u r c e ; u i n t 6 4 t time ; } ; int c a l l m e b a c k ( c a l l t ∗ c , void ∗ a r g s ) ; void tx ( c a l l t ∗ c ) ; int i n i t ( c a l l t ∗ c , void ∗ params ) { p a c k e t r x =0; p a c k e t t x =0; int a ; l a s t r e c e i v e d = ( u i n t 6 4 t ∗) malloc ( get node count ()∗ sizeof ( u i n t 6 4 t ) ) ; f o r ( a =0; a<g e t n o d e c o u n t ( ) ; a++) { l a s t r e c e i v e d [ a ]=0; } return 0 ; } int d e s t r o y ( c a l l t ∗ c ) { p r i n t f ( ”Taux de l i v r a i s o n= %f \n” , ( double ) ( ( ( double ) p a c k e t r x ) / ( ( double ) p a c k e t t x ) ) ) ; return 0 ; } int s e t n o d e ( c a l l t ∗ c , void ∗ params ) { struct nodedata ∗ nodedata = m a l l o c ( s i z e o f ( struct nodedata ) ) ; param t ∗param ; /∗ d e f a u l t v a l u e s ∗/ nodedata−>d s t = 0 ; // nodedata−>d s t p o s . x = 0 ; // nodedata−>d s t p o s . y = 0 ; // nodedata−>d s t p o s . z = 0 ; nodedata−>s t a r t = 0 ; nodedata−>overhead= −1; ANNEXE C. LISTING DE CODE nodedata−>type = nodedata−>p e r i o d nodedata−>s i z e = nodedata−>p a c k e t nodedata−>p a c k e t 52 SENSOR; = 1000000000; 1000; t x =0; r x =0; /∗ g e t p a r a m e t e r s ∗/ d a s i n i t t r a v e r s e ( params ) ; while ( ( param = ( param t ∗ ) d a s t r a v e r s e ( params ) ) != NULL) { i f ( ! strcmp ( param−>key , ” s t a r t ” ) ) { i f ( g e t p a r a m t i m e ( param−>val ue , &(nodedata−>s t a r t ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” p e r i o d ” ) ) { i f ( g e t p a r a m t i m e ( param−>val ue , &(nodedata−>p e r i o d ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” s i z e ” ) ) { i f ( g e t p a r a m i n t e g e r ( param−>val ue , &(nodedata−>s i z e ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” type ” ) ) { i f ( g e t p a r a m i n t e g e r ( param−>val ue , &(nodedata−>type ) ) ) { goto e r r o r ; } } } s e t n o d e p r i v a t e d a t a ( c , nodedata ) ; return 0 ; error : f r e e ( nodedata ) ; return −1; } int u n s e t n o d e ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; f r e e ( nodedata ) ; return 0 ; } ANNEXE C. LISTING DE CODE 53 int b o o t s t r a p ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; a r r a y t ∗down = g e t e n t i t y b i n d i n g s d o w n ( c ) ; c a l l t c0 = {down−>e l t s [ 0 ] , c−>node , c−>e n t i t y } ; /∗ g e t r o u t i n g o v e r h e a d ∗/ nodedata−>overhead = GET HEADER SIZE(&c0 ) ; /∗ e v e n t u a l l y s c h e d u l e c a l l b a c k ∗/ i f ( ( nodedata−>p e r i o d > 0 ) && ( nodedata−>type==SENSOR) ) { u i n t 6 4 t s t a r t = g e t t i m e ( ) + nodedata−>s t a r t + g e t r a n d o m d o u b l e ( ) ∗ nodedata−>p e r i o d ; s c h e d u l e r a d d c a l l b a c k ( s t a r t , c , ca ll m eb ac k , NULL ) ; } return 0 ; } int i o c t l ( c a l l t ∗ c , int o p t i o n , void ∗ in , void ∗∗ out ) { return 0 ; } int c a l l m e b a c k ( c a l l t ∗ c , void ∗ a r g s ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; a r r a y t ∗down = g e t e n t i t y b i n d i n g s d o w n ( c ) ; c a l l t c0 = {down−>e l t s [ 0 ] , c−>node , c−>e n t i t y } ; d e s t i n a t i o n t d e s t i n a t i o n = { nodedata−>dst , {−1, −1, −1}}; p a c k e t t ∗ p a c k e t = p a c k e t a l l o c ( c , nodedata−>overhead + s i z e o f ( struct p a c k e t h e a d e r ) ) ; struct p a c k e t h e a d e r ∗ h e a d e r = ( struct p a c k e t h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; header−>s o u r c e = c−>node ; header−>time = get time ( ) ; i f (SET HEADER(&c0 , packet , &d e s t i n a t i o n ) == −1) { p a c k e t d e a l l o c ( packet ) ; return −1; } // p r i n t f ( ” [SOURCE] Node %d s e n d s a p a c k e t t o s i n k \n ” , c−>node ) ; TX(&c0 , p a c k e t ) ; /∗ f o r s t a t s ∗/ ANNEXE C. LISTING DE CODE 54 nodedata−>p a c k e t t x ++; p a c k e t t x ++; /∗ we s c h e d u l e a new c a l l b a c k a f t e r a c t u a l t i m e+p e r i o d ∗/ s c h e d u l e r a d d c a l l b a c k ( g e t t i m e ( ) + nodedata−>p e r i o d , c , c a ll me ba ck , NULL ) ; return 0 ; } void rx ( c a l l t ∗ c , p a c k e t t ∗ p a c k e t ) { struct nodedata ∗ nodedata=g e t n o d e p r i v a t e d a t a ( c ) ; struct p a c k e t h e a d e r ∗ h e a d e r = ( struct p a c k e t h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; i f ( l a s t r e c e i v e d [ header−>s o u r c e ] < header−>time ) { l a s t r e c e i v e d [ header−>s o u r c e ] = header−>time ; // p r i n t f ( ” [RX] node %d r e c e i v e d a d a t a p a c k e t from %d\n” , c−>node , header−>s o u r c e ) ; nodedata−>p a c k e t r x ++; p a c k e t r x ++; p a c k e t d e a l l o c ( packet ) ; } } a p p l i c a t i o n m e t h o d s t methods = { rx } ; C.2 C.2.1 Module routage Centroid Virtual Coordinates /∗ ∗ ∗ \file vcs routing . c ∗ \brief V i r t u a l C o o r d i n a t e s System ∗ \ a u t h o r Mohammed El Mehdi DIOURI ∗ \ date 2010 ∗ ∗/ #include <s t d i o . h> #include <include / m o d e l u t i l s . h> m o d e l t model = { ” Routing V i r t u a l C o o r d i n a t e s System ” , ”Mohammed El Mehdi DIOURI” , ” 0.1 ” , MODELTYPE ROUTING, {NULL, 0} }; ANNEXE C. LISTING DE CODE #define SINK 0 #define SENSOR 1 #define MINVIRTUAL 1 #define MAXCOORD 100 0 #define HELLO PACKET #define DATA PACKET 1 #define DISCOVERY PACKET 2 const double EPSILON = 1 . 0 ; struct e n t i t y d a t a { p o s i t i o n t ∗ old ; position t ∗ current ; int c o n v e r g e d ; }; struct r o u t i n g h e a d e r { nodeid t dst ; position t dst pos ; nodeid t src ; position t src pos ; int type ; int n hop ; int count ; int nbHops ; }; struct n e i g h b o r { nodeid t id ; position t virtual position ; u i n t 6 4 t time ; }; struct nodedata { void ∗ n e i g h b o r s ; int overhead ; position t virtual position ; position t previous virtual position ; int nbHopsToSink ; int type ; uint64 t start ; uint64 t period ; 55 ANNEXE C. LISTING DE CODE 56 u i n t 6 4 t timeout ; /∗ s t a t s ∗/ int h e l l o t x ; int h e l l o r x ; int d a t a t x ; int d a t a r x ; int d a t a n o r o u t e ; }; double d i f f ; unsigned int n b t x ; int n b c o n v e r g e d ; u i n t 6 4 t t i m e c o n v e r g e d ; u i n t 6 4 t k ; double mean hops ; u i n t 6 4 t rayon moyen ; u i n t 6 4 t degre moyen ; int c a l l m e b a c k ( c a l l t ∗ c , void ∗ a r g s ) ; int i n i t ( c a l l t ∗ c , void ∗ params ) { mean hops = 0 . 0 ; n b t x =0; d i f f =0; n b c o n v e r g e d =0; t i m e c o n v e r g e d =0; rayon moyen =0; degre moyen =0; struct e n t i t y d a t a ∗ e n t i t y d a t a = m a l l o c ( s i z e o f ( struct e n t i t y d a t a ) ) ; int i ; e n t i t y d a t a −>o l d= ( p o s i t i o n t ∗ ) malloc (( get node count ( ) ) ∗ sizeof ( p o s i t i o n t ) ) ; e n t i t y d a t a −>c u r r e n t= ( p o s i t i o n t ∗ ) malloc (( get node count ( ) ) ∗ sizeof ( p o s i t i o n t ) ) ; f o r ( i =0; i <g e t n o d e c o u n t ( ) ; i ++) { p o s i t i o n t i n i t i a l ={0 ,0 ,0}; e n t i t y d a t a −>o l d [ i ]= i n i t i a l ; e n t i t y d a t a −>c u r r e n t [ i ]= i n i t i a l ; } set entity private data (c , entitydata ) ; return 0 ; } int d e s t r o y ( c a l l t ∗ c ) { struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; ANNEXE C. LISTING DE CODE 57 p r i n t f ( ”Le d e g ré moyen e s t : %f \n” , ( ( double ) ( degre moyen ) ) / ( ( double ) ( g e t n o d e c o u n t ( ) ) ) ) ; p r i n t f ( ” c o n v e r g e n c e à l ’ i n s t a n t t : %l l d \n” , t i m e c o n v e r g e d ) ; p r i n t f ( ”Le rayon moyen e s t : %f \n” , ( ( double ) ( rayon moyen ) ) / ( ( double ) ( g e t n o d e c o u n t ( ) ) ) ) ; p r i n t f ( ”Le nombre moyen de s a u t s e s t : %f \n” , mean hops ) ; p r i n t f ( ”Le taux de noeuds ayant c o n v e r gé e s t : %f \n” , ( double ) ( ( ( double ) ( n b c o n v e r g e d ) ) / ( ( double ) ( g e t n o d e c o u n t ( ) ) ) ) ) ; p r i n t f ( ”Le taux de noeuds ayant c o n v e r gé en f i n de s i m u l a t i o n : %f \n” , ( double ) ( ( ( double ) ( e n t i t y d a t a −>c o n v e r g e d ) ) / ( ( double ) ( g e t n o d e c o u n t ( ) ) ) ) ) ; free ( entitydata ) ; return 0 ; } int s e t n o d e ( c a l l t ∗ c , void ∗ params ) { struct nodedata ∗ nodedata = m a l l o c ( s i z e o f ( struct nodedata ) ) ; struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; param t ∗param ; /∗ d e f a u l t v a l u e s ∗/ nodedata−>n e i g h b o r s = d a s c r e a t e ( ) ; nodedata−>overhead = −1; nodedata−>h e l l o t x = 0 ; nodedata−>h e l l o r x = 0 ; nodedata−>d a t a t x = 0 ; nodedata−>d a t a r x = 0 ; nodedata−>d a t a n o r o u t e = 0 ; nodedata−>s t a r t = 0 ; nodedata−>type = SENSOR; nodedata−>p e r i o d = 1 0 0 0 0 0 0 0 0 0 ; nodedata−>t i m e o u t = 2500000000 u l l ; nodedata−>v i r t u a l p o s i t i o n . x=0; nodedata−>v i r t u a l p o s i t i o n . y=0; nodedata−>v i r t u a l p o s i t i o n . z =0; nodedata−>p r e v i o u s v i r t u a l p o s i t i o n . x=0; nodedata−>p r e v i o u s v i r t u a l p o s i t i o n . y=0; nodedata−>p r e v i o u s v i r t u a l p o s i t i o n . z =0; ANNEXE C. LISTING DE CODE 58 /∗ g e t params ∗/ d a s i n i t t r a v e r s e ( params ) ; while ( ( param = ( param t ∗ ) d a s t r a v e r s e ( params ) ) != NULL) { i f ( ! strcmp ( param−>key , ” s t a r t ” ) ) { i f ( g e t p a r a m t i m e ( param−>val ue , &(nodedata−>s t a r t ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” p e r i o d ” ) ) { i f ( g e t p a r a m t i m e ( param−>val ue , &(nodedata−>p e r i o d ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” t i m e o u t ” ) ) { i f ( g e t p a r a m t i m e ( param−>val ue , &(nodedata−>t i m e o u t ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” type ” ) ) { i f ( g e t p a r a m i n t e g e r ( param−>val ue , &(nodedata−>type ) ) ) { goto e r r o r ; } /∗ I n i t i a l i s a t i o n d e s c o o r d o n né e s v i r t u e l l e s ∗/ i f ( nodedata−>type==SENSOR) { nodedata−>v i r t u a l p o s i t i o n . x= g e t r a n d o m d o u b l e r a n g e ( 0 , MAXCOORD) ; nodedata−>v i r t u a l p o s i t i o n . y= g e t r a n d o m d o u b l e r a n g e ( 0 , MAXCOORD) ; nodedata−>v i r t u a l p o s i t i o n . z=0 ; // c a s p l a n ( e n t i t y d a t a −>c u r r e n t [ c−>node ] ) . x= nodedata−>v i r t u a l p o s i t i o n . x ; ( e n t i t y d a t a −>c u r r e n t [ c−>node ] ) . y= nodedata−>v i r t u a l p o s i t i o n . y ; ( e n t i t y d a t a −>c u r r e n t [ c−>node ] ) . z= nodedata−>v i r t u a l p o s i t i o n . z ; } i f ( nodedata−>type==SENSOR) { nodedata−>nbHopsToSink= −1; } else { nodedata−>nbHopsToSink= 0 ; ANNEXE C. LISTING DE CODE 59 } } } s e t n o d e p r i v a t e d a t a ( c , nodedata ) ; return 0 ; error : f r e e ( nodedata ) ; return −1; } int u n s e t n o d e ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; double d ; struct n e i g h b o r ∗ n e i g h b o r ; rayon moyen += nodedata−>nbHopsToSink ; while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) das pop ( nodedata−>n e i g h b o r s ) ) != NULL) { degre moyen++; f r e e ( neighbor ) ; } d a s d e s t r o y ( nodedata−>n e i g h b o r s ) ; d = d i s t a n c e (&( nodedata−>p r e v i o u s v i r t u a l p o s i t i o n ) , &(nodedata−>v i r t u a l p o s i t i o n ) ) ; d i f f+=d ; i f ( d<EPSILON) { n b c o n v e r g e d++; } f r e e ( nodedata ) ; return 0 ; } int b o o t s t r a p ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; /∗ g e t mac h e a d e r o v e r h e a d ∗/ nodedata−>overhead = GET HEADER SIZE(&c0 ) ; ANNEXE C. LISTING DE CODE 60 /∗ send a d i s c o v e r y p a q u e t ∗/ i f ( nodedata−>type==SINK) { d e s t i n a t i o n t d e s t i n a t i o n = {BROADCAST ADDR, {−1, −1, −1}}; packet t ∗ packet = p a c k e t c r e a t e ( c , nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) , −1); struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; /∗ s e t mac h e a d e r ∗/ i f (SET HEADER(&c0 , packet , &d e s t i n a t i o n ) == −1) { p a c k e t d e a l l o c ( packet ) ; } else { /∗ s e t r o u t i n g h e a d e r ∗/ header−>d s t = BROADCAST ADDR; header−>d s t p o s . x = −1; header−>d s t p o s . y = −1; header−>d s t p o s . z = −1; header−>s r c = c−>node ; header−>nbHops=nodedata−>nbHopsToSink ; header−>type = DISCOVERY PACKET; /∗ send d i s c o v e r y ∗/ TX(&c0 , p a c k e t ) ; } } /∗ h e l l o p a c k e t ∗/ i f ( nodedata−>p e r i o d > 0 ) { u i n t 6 4 t s t a r t = g e t t i m e ( ) + nodedata−>s t a r t + g e t r a n d o m d o u b l e ( ) ∗ nodedata−>p e r i o d ; s c h e d u l e r a d d c a l l b a c k ( s t a r t , c , ca ll m eb ac k , NULL ) ; } return 0 ; } int i o c t l ( c a l l t ∗ c , int o p t i o n , void ∗ in , void ∗∗ out ) { return 0 ; } struct n e i g h b o r ∗ g e t n e x t h o p ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct n e i g h b o r ∗ n e i g h b o r = NULL; struct n e i g h b o r ∗ n hop = NULL; uint64 t clock = get time ( ) ; p o s i t i o n t v i r t u a l d s t = {0 , 0 , 0}; ANNEXE C. LISTING DE CODE 61 double d i s t = d i s t a n c e (&( nodedata−>v i r t u a l p o s i t i o n ) , &v i r t u a l d s t ) ; double d = d i s t ; /∗ p a r s e n e i g h b o r s ∗/ d a s i n i t t r a v e r s e ( nodedata−>n e i g h b o r s ) ; while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) d a s t r a v e r s e ( nodedata−>n e i g h b o r s ) ) != NULL) { i f ( ( nodedata−>t i m e o u t > 0 ) && ( c l o c k − n e i g h b o r −>time ) >= nodedata−>t i m e o u t ) { continue ; } /∗ c h o o s e n e x t hop ∗/ i f ( ( d = d i s t a n c e (&( n e i g h b o r −>v i r t u a l p o s i t i o n ) , &v i r t u a l d s t ) ) < d i s t ) dist = d; n hop = n e i g h b o r ; } } return n hop ; } void u p d a t e m y c o o r d i n a t e s ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; i f ( nodedata−>type==SENSOR) { struct n e i g h b o r ∗ n e i g h b o r = NULL; uint64 t clock = get time ( ) ; d a s i n i t t r a v e r s e ( nodedata−>n e i g h b o r s ) ; int i =0; nodedata−>p r e v i o u s v i r t u a l p o s i t i o n . x = nodedata−>v i r t u a l p o s i t i o n . x ; nodedata−>p r e v i o u s v i r t u a l p o s i t i o n . y = nodedata−>v i r t u a l p o s i t i o n . y ; e n t i t y d a t a −>o l d [ c−>node ] . x= nodedata−>v i r t u a l p o s i t i o n . x ; e n t i t y d a t a −>o l d [ c−>node ] . y= nodedata−>v i r t u a l p o s i t i o n . y ; // e n t i t y d a t a −>o l d [ c−>node ] . z= nodedata−>v i r t u a l p o s i t i o n . z ; // nodedata−>p r e v i o u s v i r t u a l p o s i t i o n . z = nodedata−>v i r t u a l p o s i t i o n . z ; nodedata−>v i r t u a l p o s i t i o n . x = 0 ; nodedata−>v i r t u a l p o s i t i o n . y = 0 ; // nodedata−>v i r t u a l p o s i t i o n . z =0; ANNEXE C. LISTING DE CODE 62 while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) d a s t r a v e r s e ( nodedata−>n e i g h b o r s ) ) != NULL) { i f ( ( nodedata−>t i m e o u t > 0 ) && ( c l o c k − n e i g h b o r −>time ) >= nodedata−>t i m e o u t ) { continue ; } nodedata−>v i r t u a l p o s i t i o n . x += n e i g h b o r −> v i r t u a l p o s i t i o n . x ; nodedata−>v i r t u a l p o s i t i o n . y += n e i g h b o r −> v i r t u a l p o s i t i o n . y ; // nodedata−>v i r t u a l p o s i t i o n . z += // n e i g h b o r −> v i r t u a l p o s i t i o n . z ; i ++; } i f ( i >0) { nodedata−>v i r t u a l p o s i t i o n . x = nodedata−>v i r t u a l p o s i t i o n . x / i ; nodedata−>v i r t u a l p o s i t i o n . y = nodedata−>v i r t u a l p o s i t i o n . y / i ; // nodedata−>v i r t u a l p o s i t i o n −>z = // nodedata−>v i r t u a l p o s i t i o n . z / i ; } else { nodedata−>v i r t u a l p o s i t i o n . x = nodedata−>p r e v i o u s v i r t u a l p o s i t i o n . x ; nodedata−>v i r t u a l p o s i t i o n . y = nodedata−>p r e v i o u s v i r t u a l p o s i t i o n . y ; // nodedata−>v i r t u a l p o s i t i o n . z =0; } } e n t i t y d a t a −>c u r r e n t [ c−>node ] . x= nodedata−>v i r t u a l p o s i t i o n . x ; e n t i t y d a t a −>c u r r e n t [ c−>node ] . y= nodedata−>v i r t u a l p o s i t i o n . y ; // e n t i t y d a t a −>c u r r e n t [ c−>node ] . z= nodedata−>v i r t u a l p o s i t i o n . z ; } void u p d a t e t h e i r c o o r d i n a t e s ( c a l l t ∗ c , struct r o u t i n g h e a d e r ∗ header ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; ANNEXE C. LISTING DE CODE double Wx=nodedata−>v i r t u a l double Wy=nodedata−>v i r t u a l nodedata−>p r e v i o u s v i r t u a l nodedata−>p r e v i o u s v i r t u a l 63 position position position position .x; .y; . x = Wx; . y = Wy; e n t i t y d a t a −>o l d [ c−>node ] . x= nodedata−>v i r t u a l p o s i t i o n . x ; e n t i t y d a t a −>o l d [ c−>node ] . y= nodedata−>v i r t u a l p o s i t i o n . y ; // e n t i t y d a t a −>o l d [ c−>node ] . z= nodedata−>v i r t u a l p o s i t i o n . z ; // d o u b l e Wz=nodedata−>v i r t u a l p o s i t i o n . z ; // e v e n t u e l l e m e n t s i 3D double Vx=header−>s r c p o s . x ; double Vy=header−>s r c p o s . y ; // d o u b l e Vz=header−>s r c p o s . z ; // e v e n t u e l l e m e n t s i 3D double d i s t = d i s t a n c e (&( nodedata−>v i r t u a l p o s i t i o n ) , &( header−>s r c p o s ) ) ; i f ( d i s t >0) { nodedata−>v i r t u a l p o s i t i o n . x = MINVIRTUAL∗ ( (Wx−Vx) / d i s t ) + Vx ; nodedata−>v i r t u a l p o s i t i o n . y = MINVIRTUAL∗ ( (Wy−Vy) / d i s t ) + Vy ; // nodedata−>v i r t u a l p o s i t i o n . z = // MINVIRTUAL∗ ( (Wz−Vz )/ d i s t )+ Vz ; } e n t i t y d a t a −>c u r r e n t [ c−>node ] . x= nodedata−>v i r t u a l p o s i t i o n . x ; e n t i t y d a t a −>c u r r e n t [ c−>node ] . y= nodedata−>v i r t u a l p o s i t i o n . y ; // e n t i t y d a t a −>c u r r e n t [ c−>node ] . z= nodedata−>v i r t u a l p o s i t i o n . z ; } int check how many converged ( c a l l t ∗ c ) { struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; double d ; int j ; e n t i t y d a t a −>c o n v e r g e d =0; f o r ( j =0; j <g e t n o d e c o u n t ( ) ; j ++) { d = d i s t a n c e (&( e n t i t y d a t a −>o l d [ j ] ) , &( e n t i t y d a t a −>c u r r e n t [ j ] ) ) ; i f ( d<EPSILON) { e n t i t y d a t a −>c o n v e r g e d++ ; } } return e n t i t y d a t a −>c o n v e r g e d ; } ANNEXE C. LISTING DE CODE 64 void a d d n e i g h b o r ( c a l l t ∗ c , struct r o u t i n g h e a d e r ∗ h e a d e r ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct n e i g h b o r ∗ n e i g h b o r = NULL; /∗ c h e c k w e t h e r n e i g h b o r a l r e a d y e x i s t s ∗/ d a s i n i t t r a v e r s e ( nodedata−>n e i g h b o r s ) ; while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) d a s t r a v e r s e ( nodedata−>n e i g h b o r s ) ) != NULL) { i f ( n e i g h b o r −>i d == header−>s r c ) { n e i g h b o r −>v i r t u a l p o s i t i o n . x = header−>s r c p o s . x ; n e i g h b o r −>v i r t u a l p o s i t i o n . y = header−>s r c p o s . y ; n e i g h b o r −>v i r t u a l p o s i t i o n . z = header−>s r c p o s . z ; n e i g h b o r −>time = g e t t i m e ( ) ; return ; } } n e i g h b o r = ( struct n e i g h b o r ∗ ) m a l l o c ( s i z e o f ( struct n e i g h b o r ) ) ; n e i g h b o r −>i d = header−>s r c ; n e i g h b o r −>v i r t u a l p o s i t i o n . x = header−>s r c p o s . x ; n e i g h b o r −>v i r t u a l p o s i t i o n . y = header−>s r c p o s . y ; n e i g h b o r −>v i r t u a l p o s i t i o n . z = header−>s r c p o s . z ; n e i g h b o r −>time = g e t t i m e ( ) ; d a s i n s e r t ( nodedata−>n e i g h b o r s , ( void ∗ ) n e i g h b o r ) ; return ; } int s e t h e a d e r ( c a l l t ∗ c , p a c k e t t ∗ packet , d e s t i n a t i o n t ∗ virtual dst ) { update my coordinates ( c ) ; struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct n e i g h b o r ∗ n hop = g e t n e x t h o p ( c ) ; /∗ i f no r o u t e , r e t u r n −1 ∗/ i f ( ( v i r t u a l d s t −>i d != BROADCAST ADDR) && ( n hop == NULL) ) { // p r i n t f (” Je ne s u i s j a m a i s c e n sé r e n t r e r i c i 1\n ” ) ; nodedata−>d a t a n o r o u t e ++; return −1; } /∗ e l s e i f ( v i r t u a l d s t −>i d == BROADCAST ADDR) { p r i n t f (” Je ne s u i s j a m a i s c e n sé r e n t r e r i c i 2\n ” ) ; n hop−>i d = BROADCAST ADDR; } ∗/ ANNEXE C. LISTING DE CODE 65 struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; /∗ s e t r o u t i n g h e a d e r ∗/ header−>d s t = n hop−>i d ; header−>d s t p o s . x = n hop−>v i r t u a l p o s i t i o n . x ; header−>d s t p o s . y = n hop−>v i r t u a l p o s i t i o n . y ; header−>d s t p o s . z = n hop−>v i r t u a l p o s i t i o n . z ; header−>s r c header−>s r c header−>s r c header−>s r c = c−>node ; p o s . x = nodedata−>v i r t u a l p o s i t i o n . x ; p o s . y = nodedata−>v i r t u a l p o s i t i o n . y ; p o s . z = nodedata−>v i r t u a l p o s i t i o n . z ; header−>type = DATA PACKET; /∗ S e t mac h e a d e r ∗/ destination t destination ; d e s t i n a t i o n . i d = BROADCAST ADDR; d e s t i n a t i o n . p o s i t i o n . x = −1; d e s t i n a t i o n . p o s i t i o n . y = −1; d e s t i n a t i o n . p o s i t i o n . z = −1; return SET HEADER(&c0 , packet , &d e s t i n a t i o n ) ; } int g e t h e a d e r s i z e ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; i f ( nodedata−>overhead == −1) { c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; nodedata−>overhead = GET HEADER SIZE(&c0 ) ; } return nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) ; } int g e t h e a d e r r e a l s i z e ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; i f ( nodedata−>overhead == −1) { c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; nodedata−>overhead = GET HEADER REAL SIZE(&c0 ) ; } return nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) ; ANNEXE C. LISTING DE CODE 66 } int n e i g h b o r t i m e o u t ( void ∗ data , void ∗ a r g ) { struct n e i g h b o r ∗ n e i g h b o r = ( struct n e i g h b o r ∗ ) data ; c a l l t ∗c = ( c a l l t ∗) arg ; struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; i f ( ( g e t t i m e ( ) − n e i g h b o r −>time ) >= nodedata−>t i m e o u t ) { return 1 ; } return 0 ; } int c a l l m e b a c k ( c a l l t ∗ c , void ∗ a r g s ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; d e s t i n a t i o n t d e s t i n a t i o n = {BROADCAST ADDR, {−1, −1, −1}}; packet t ∗ packet = p a c k e t c r e a t e ( c , nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) , −1); struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; /∗ s e t mac h e a d e r ∗/ i f (SET HEADER(&c0 , packet , &d e s t i n a t i o n ) == −1) { p a c k e t d e a l l o c ( packet ) ; return −1; } /∗ s e t r o u t i n g h e a d e r ∗/ header−>d s t = BROADCAST ADDR; header−>d s t p o s . x = −1; header−>d s t p o s . y = −1; header−>d s t p o s . z = −1; header−>s r c = c−>node ; header−>s r c p o s . x = nodedata−>v i r t u a l p o s i t i o n . x ; header−>s r c p o s . y = nodedata−>v i r t u a l p o s i t i o n . y ; header−>s r c p o s . z = nodedata−>v i r t u a l p o s i t i o n . z ; header−>type = HELLO PACKET; /∗ send h e l l o ∗/ TX(&c0 , p a c k e t ) ; nodedata−>h e l l o t x ++; /∗ c h e c k n e i g h b o r s t i m e o u t ∗/ d a s s e l e c t i v e d e l e t e ( nodedata−>n e i g h b o r s , n e i g h b o r t i m e o u t , ( void ∗ ) c ) ; /∗ s c h e d u l e s h e l l o ∗/ ANNEXE C. LISTING DE CODE 67 s c h e d u l e r a d d c a l l b a c k ( g e t t i m e ( ) + nodedata−>p e r i o d , c , c a ll me ba ck , NULL ) ; return 0 ; } void tx ( c a l l t ∗ c , p a c k e t t ∗ p a c k e t ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; nodedata−>d a t a t x ++; TX(&c0 , p a c k e t ) ; header−>n hop =0; i f ( k>5) { header−>count =1;} e l s e { header−>count =0;} } void f o r w a r d ( c a l l t ∗ c , p a c k e t t ∗ p a c k e t ) { u p d a t e m y c o o r d i n a t e s ( c ) ; // s t e p 1 and 2 struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct n e i g h b o r ∗ n hop = g e t n e x t h o p ( c ) ; // p r i n t f (” i am t h e n e x t hop %d −−−−−−− ” , n hop−>i d ) ; /∗ d e l i v e r s p a c k e t t o a p p l i c a t i o n l a y e r ∗/ i f ( n hop == NULL) { a r r a y t ∗up = g e t e n t i t y b i n d i n g s u p ( c ) ; int i = up−>s i z e ; while ( i −−) { c a l l t c up = {up−>e l t s [ i ] , c−>node } ; packet t ∗ packet up ; i f ( i > 0) { packet up = packet clone ( packet ) ; } else { packet up = packet ; } RX(&c up , p a c k e t u p ) ; } ANNEXE C. LISTING DE CODE 68 return ; } struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; header−>s r c= c−>node ; header−>s r c p o s . x=nodedata−>v i r t u a l p o s i t i o n . x ; header−>s r c p o s . y=nodedata−>v i r t u a l p o s i t i o n . y ; header−>s r c p o s . z=nodedata−>v i r t u a l p o s i t i o n . z ; header−>d s t= n hop−>i d ; header−>d s t p o s . x=n hop−>v i r t u a l p o s i t i o n . x ; header−>d s t p o s . y=n hop−>v i r t u a l p o s i t i o n . y ; header−>d s t p o s . z=n hop−>v i r t u a l p o s i t i o n . z ; /∗ s e t mac h e a d e r ∗/ destination t destination ; d e s t i n a t i o n . i d = BROADCAST ADDR; d e s t i n a t i o n . p o s i t i o n . x = −1; d e s t i n a t i o n . p o s i t i o n . y = −1; d e s t i n a t i o n . p o s i t i o n . z = −1; i f (SET HEADER(&c0 , packet , &d e s t i n a t i o n ) == −1) { p a c k e t d e a l l o c ( packet ) ; return ; } /∗ f o r w a r d i n g p a c k e t ∗/ nodedata−>d a t a t x ++; TX(&c0 , p a c k e t ) ; } void u p d a t e n e i g h b o r ( c a l l t ∗ c , struct r o u t i n g h e a d e r ∗ h e a d e r ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct n e i g h b o r ∗ n e i g h b o r = NULL; d a s i n i t t r a v e r s e ( nodedata−>n e i g h b o r s ) ; while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) d a s t r a v e r s e ( nodedata−>n e i g h b o r s ) ) != NULL) { i f ( n e i g h b o r −>i d == header−>s r c ) { n e i g h b o r −>v i r t u a l p o s i t i o n . x = header−>s r c p o s . x ; n e i g h b o r −>v i r t u a l p o s i t i o n . y = header−>s r c p o s . y ; n e i g h b o r −>v i r t u a l p o s i t i o n . z = header−>s r c p o s . z ; ANNEXE C. LISTING DE CODE 69 n e i g h b o r −>time = g e t t i m e ( ) ; return ; } } } void rx ( c a l l t ∗ c , p a c k e t t ∗ p a c k e t ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; int c o n v e r g e n c e ; switch ( header−>type ) { case DISCOVERY PACKET: i f ( ( nodedata−>nbHopsToSink == −1) | | ( nodedata−>nbHopsToSink > header−>nbHops +1)) { nodedata−>nbHopsToSink=header−>nbHops +1; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; d e s t i n a t i o n t d e s t i n a t i o n = {BROADCAST ADDR, {−1, −1, −1}}; packet t ∗ packet to send = packet create (c , nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) , −1); struct r o u t i n g h e a d e r ∗ h e a d e r t o s e n d = ( struct r o u t i n g h e a d e r ∗ ) ( p a c k e t t o s e n d −>data+ nodedata−>overhead ) ; /∗ s e t mac h e a d e r ∗/ i f (SET HEADER(&c0 , p a c k e t t o s e n d , &d e s t i n a t i o n ) == −1) { packet dealloc ( packet to send ) ; } else { /∗ s e t r o u t i n g h e a d e r ∗/ h e a d e r t o s e n d −>d s t = BROADCAST ADDR; h e a d e r t o s e n d −>d s t p o s . x = −1; h e a d e r t o s e n d −>d s t p o s . y = −1; h e a d e r t o s e n d −>d s t p o s . z = −1; h e a d e r t o s e n d −>s r c = c−>node ; h e a d e r t o s e n d −>nbHops=nodedata−>nbHopsToSink ; h e a d e r t o s e n d −>type = DISCOVERY PACKET; /∗ send d i s c o v e r y ∗/ TX(&c0 , p a c k e t t o s e n d ) ; } } break ; ANNEXE C. LISTING DE CODE 70 case HELLO PACKET: nodedata−>h e l l o r x ++; add neighbor ( c , header ) ; p a c k e t d e a l l o c ( packet ) ; break ; case DATA PACKET : header−>n hop++; i f ( ( c−>node == 0 ) && ( c−>node==header−>d s t ) ) { /∗ Data p a c k e t r e c e i v e d by s i n k ∗/ nodedata−>d a t a r x ++; i f ( header−>count==1) { // p r i n t f (”Nb hops %d \n ” , header−>n hop ) ; mean hops= ( ( ( double ) ( n b t x ) ) / ( ( double ) ( n b t x +1))) ∗ mean hops +((double ) ( header−>n hop ) ) / ( ( double ) ( n b t x + 1 ) ) ; n b t x++; } a r r a y t ∗up = g e t e n t i t y b i n d i n g s u p ( c ) ; int i = up−>s i z e ; while ( i −−) { c a l l t c up = {up−>e l t s [ i ] , c−>node } ; packet t ∗ packet up ; i f ( i > 0) { packet up = packet clone ( packet ) ; } else { packet up = packet ; } RX(&c up , p a c k e t u p ) ; } break ; } e l s e { // r e c e i v e d by an o r d i n a r y s e n s o r node . update neighbor ( c , header ) ; i f ( header−>d s t==c−>node ) { /∗ r e c e i v e d by someone who must f o r w a r d ∗/ forward ( c , packet ) ; break ; } e l s e i f ( d i s t a n c e (&( header−>s r c p o s ) , &(nodedata−>v i r t u a l p o s i t i o n ) ) < MINVIRTUAL) { /∗ r e c e i v e d by someone who must u p d a t e ∗/ ANNEXE C. LISTING DE CODE 71 u p d a t e t h e i r c o o r d i n a t e s ( c , header ) ; } c o n v e r g e n c e = check how many converged ( c ) ; i f ( convergence > get node count ( ) ∗ 0 . 9 5 ) { k++; } i f ( k==5) { p r i n t f ( ” Convergence a c c o m p l i s h e d \n” ) ; t i m e c o n v e r g e d=g e t t i m e ( ) ; } } p a c k e t d e a l l o c ( packet ) ; break ; default : break ; } return ; } r o u t i n g m e t h o d s t methods = { rx , tx , set header , get header size , get header real size }; C.2.2 Beacon Vector Routing /∗ ∗ ∗ \file BVR. c ∗ \ b r i e f BVR r o u t i n g p r o t o c o l ∗ \ a u t h o r Mohammed El Mehdi DIOURI ∗ \ a u t h o r A b d e l b e r i Chaabane ∗ \ date 2010 ∗ ∗/ #include <s t d i o . h> #include <include / m o d e l u t i l s . h> m o d e l t model = { ”BVR p r o t o c o l ” , ”Mohammed El Mehdi DIOURI & A b d e l b e r i Chaabane ” , ” 0.1 ” , MODELTYPE ROUTING, {NULL, 0} }; ANNEXE C. LISTING DE CODE #define MAXLANDM 10 #define SINK 0 //un p u i t s #define LANDM 1 // landmark #define SENSOR 2 // normal s e n s o r #define #define #define #define HELLO PACKET BEACON PACKET DATA PACKET DISCOVERY PACKET 0 1 2 3 s t a t i c int c u r r e n t b e a c o n = 0 ; s t a t i c double crtRnd = 0 . 1 ; int c o r d S i n k [MAXLANDM] ; int c l o s e s t B e a c o n ; unsigned int n b t x ; uint64 t time converged ; uint64 t k ; double mean hops ; u i n t 6 4 t rayon moyen ; u i n t 6 4 t degre moyen ; struct nodedata { void ∗ n e i g h b o r s ; int overhead ; int type ; int c o r d [MAXLANDM] ; int beaconId ; // f o r landmark int nbHopsToSink ; uint64 t start ; uint64 t period ; u i n t 6 4 t timeout ; // i n t l a s t s e q ; // i n t s e q ; // i n t l a s t s e q b e a c o n ; // i n t s e q b e a c o n ; int int int int int int hello tx ; hello rx ; data tx ; data rx ; beacon tx ; beacon rx ; 72 ANNEXE C. LISTING DE CODE }; struct e n t i t y d a t a { double nbbeacon ; double c u r r e n t b e a c o n ; uint64 t period ; int ∗∗ o l d ; int ∗∗ c u r r e n t ; int c o n v e r g e d ; }; struct n e i g h b o r { nodeid t id ; int c o r d [MAXLANDM] ; u i n t 6 4 t time ; int d i s t a n c e ; }; struct r o u t i n g h e a d e r { int type ; nodeid t i n i t i a l s o u r c e ; nodeid t src ; nodeid t dst ; int s r c c o r d [MAXLANDM] ; // i n t d s t c o r d [MAXLANDM] ; int beacon ; // from which beacon int c o r d ; int n hop ; int count ; int nbHops ; int dMin [MAXLANDM] ; int nbBeacons ; // i n t s e q ; int c o o r d o n a t e D e s t ; // i n t s e q b e a c o n ; }; int c a l l m e b a c k ( c a l l t ∗ c , void ∗ a r g s ) ; int callmebackHELLO ( c a l l t ∗ c , void ∗ a r g s ) ; int c a l l m e b a c k C h e c k i n g C o n v e r g e n c e ( c a l l t ∗ c , void ∗ a r g s ) ; int max ( int a , int b ) { i f ( a > b ) { return a ; } e l s e { return b ; } } int min ( int a , int b ) 73 ANNEXE C. LISTING DE CODE 74 { i f ( a < b ) { return a ; } e l s e { return b ; } } int i n i t ( c a l l t ∗ c , void ∗ params ) { mean hops = 0 . 0 ; n b t x =0; t i m e c o n v e r g e d =0; rayon moyen =0; degre moyen =0; closestBeacon = 0; struct e n t i t y d a t a ∗ e n t i t y d a t a = ( struct e n t i t y d a t a ∗ ) m a l l o c ( s i z e o f ( struct e n t i t y d a t a ) ) ; param t ∗param ; unsigned int i , j ; e n t i t y d a t a −>o l d= ( int ∗ ∗ ) get e n t i t y d a t a −>c u r r e n t= ( int get malloc ( n o d e c o u n t ( ) ∗MAXLANDM∗ s i z e o f ( int ) ) ; ∗∗) malloc ( n o d e c o u n t ( ) ∗MAXLANDM∗ s i z e o f ( int ) ) ; f o r ( i = 0 ; i < g e t n o d e c o u n t ( ) ; i ++) { e n t i t y d a t a −>o l d [ i ]= ( int ∗ ) m a l l o c (MAXLANDM∗ s i z e o f ( int ) ) ; e n t i t y d a t a −>c u r r e n t [ i ]= ( int ∗ ) m a l l o c (MAXLANDM∗ s i z e o f ( int ) ) ; f o r ( j = 0 ; j < MAXLANDM; j ++) { e n t i t y d a t a −>o l d [ i ] [ j ]= −1; e n t i t y d a t a −>c u r r e n t [ i ] [ j ]= −1; } } e n t i t y d a t a −>nbbeacon = 1 ; e n t i t y d a t a −>c u r r e n t b e a c o n = 0 ; e n t i t y d a t a −>p e r i o d = 2000000000 ; // s e t d e f a u l t v a l u e t o 2 s d a s i n i t t r a v e r s e ( params ) ; while ( ( param = ( param t ∗ ) d a s t r a v e r s e ( params ) ) != NULL) { i f ( ! strcmp ( param−>key , ” nbBeacon ” ) ) { i f ( g e t p a r a m d o u b l e ( param−>val ue , &( e n t i t y d a t a −>nbbeacon ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” p e r i o d ” ) ) { i f ( g e t p a r a m t i m e ( param−>val ue , &( e n t i t y d a t a −>p e r i o d ) ) ) { ANNEXE C. LISTING DE CODE 75 goto e r r o r ; } } } set entity private data (c , entitydata ) ; return 0 ; error : free ( entitydata ) ; return −1; } int d e s t r o y ( c a l l t ∗ c ) { int i ; struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; p r i n t f ( ”Le d e g ré moyen e s t : %f \n” , ( ( double ) ( degre moyen ) ) / ( ( double ) ( g e t n o d e c o u n t ( ) ) ) ) ; p r i n t f ( ” c o n v e r g e n c e à l ’ i n s t a n t t : %l l d \n” , t i m e c o n v e r g e d ) ; p r i n t f ( ”Le rayon moyen e s t : %f \n” , ( ( double ) ( rayon moyen ) ) / ( ( double ) ( g e t n o d e c o u n t ( ) ) ) ) ; p r i n t f ( ”Le nombre moyen de s a u t s e s t : %f \n” , mean hops ) ; p r i n t f ( ”Le taux de noeuds ayant c o n v e r gé en f i n de s i m u l a t i o n : %f \n” , ( double ) ( ( ( double ) ( e n t i t y d a t a −>c o n v e r g e d ) ) / ( ( double ) ( g e t n o d e c o u n t ( ) ) ) ) ) ; f o r ( i = 0 ; i < g e t n o d e c o u n t ( ) ; i ++) { f r e e ( e n t i t y d a t a −>o l d [ i ] ) ; f r e e ( e n t i t y d a t a −>c u r r e n t [ i ] ) ; } f r e e ( e n t i t y d a t a −>o l d ) ; f r e e ( e n t i t y d a t a −>c u r r e n t ) ; free ( entitydata ) ; return 0 ; } int s e t n o d e ( c a l l t ∗ c , void ∗ params ) { struct nodedata ∗ nodedata = ( struct nodedata ∗ ) m a l l o c ( s i z e o f ( struct nodedata ) ) ; struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; param t ∗param ; /∗ d e f a u l t v a l u e s ∗/ nodedata−>n e i g h b o r s = d a s c r e a t e ( ) ; ANNEXE C. LISTING DE CODE 76 nodedata−>overhead = −1; nodedata−>h e l l o t x = 0 ; nodedata−>h e l l o r x = 0 ; nodedata−>d a t a t x = 0 ; nodedata−>d a t a r x = 0 ; nodedata−>s t a r t = 0 ; nodedata−>type = SENSOR; nodedata−>p e r i o d = 1 0 0 0 0 0 0 0 0 0 ; nodedata−>t i m e o u t = 2500000000 u l l ; nodedata−>beaconId = −1; nodedata−>b e a c o n t x = 0 ; nodedata−>b e a c o n r x = 0 ; // nodedata−>s e q = 0; // nodedata−>l a s t s e q = −1; // nodedata−>s e q b e a c o n= 0 ; // nodedata−>l a s t s e q b e a c o n = −1; int count ; f o r ( count =0; count <MAXLANDM; count++) { nodedata−>c o r d [ count ]= −1;} d a s i n i t t r a v e r s e ( params ) ; while ( ( param = ( param t ∗ ) d a s t r a v e r s e ( params ) ) != NULL) { i f ( ! strcmp ( param−>key , ” s t a r t ” ) ) { i f ( g e t p a r a m t i m e ( param−>val ue , &(nodedata−>s t a r t ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” p e r i o d ” ) ) { i f ( g e t p a r a m t i m e ( param−>val ue , &(nodedata−>p e r i o d ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” t i m e o u t ” ) ) { i f ( g e t p a r a m t i m e ( param−>val ue , &(nodedata−>t i m e o u t ) ) ) { goto e r r o r ; } } i f ( ! strcmp ( param−>key , ” type ” ) ) { i f ( g e t p a r a m i n t e g e r ( param−>val ue , &(nodedata−>type ) ) ) { goto e r r o r ; } i f ( nodedata−>type !=SINK) { ANNEXE C. LISTING DE CODE 77 nodedata−>nbHopsToSink= −1; } else { nodedata−>nbHopsToSink= 0 ; } } } i f ( nodedata−>type !=SINK) { // s e t t i n g node t y p e w i t h random c h o i c e i f ( ( c u r r e n t b e a c o n < e n t i t y d a t a −>nbbeacon ) && ( g e t r a n d o m d o u b l e r a n g e ( 0 . 0 , 1 . 0 ) < crtRnd ) ) { nodedata−>beaconId = ( c u r r e n t b e a c o n ) ; // s e t t h e i d o f t h e beacon nodedata−>type = LANDM; nodedata−>c o r d [ c u r r e n t b e a c o n ] = 0 ; c u r r e n t b e a c o n ++; } else { i f ( crtRnd < 0 . 8 ) { crtRnd +=0.1;} } } s e t n o d e p r i v a t e d a t a ( c , nodedata ) ; return 0 ; error : f r e e ( nodedata ) ; return −1; } int u n s e t n o d e ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct n e i g h b o r ∗ n e i g h b o r ; rayon moyen += nodedata−>nbHopsToSink ; while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) das pop ( nodedata−>n e i g h b o r s ) ) != NULL) { degre moyen++; f r e e ( neighbor ) ; } d a s d e s t r o y ( nodedata−>n e i g h b o r s ) ; f r e e ( nodedata ) ; return 0 ; ANNEXE C. LISTING DE CODE 78 } struct n e i g h b o r ∗ g e t n e x t h o p ( c a l l t ∗ c , struct r o u t i n g h e a d e r ∗ header ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct n e i g h b o r ∗ n e i g h b o r = NULL; struct n e i g h b o r ∗ n hop = NULL; uint64 t clock = get time ( ) ; int i , dMoins , dPlus , d ; int d i s t = 1 0 0 0 0 0 0 0 ; /∗ p a r s e n e i g h b o r s ∗/ d a s i n i t t r a v e r s e ( nodedata−>n e i g h b o r s ) ; while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) d a s t r a v e r s e ( nodedata−>n e i g h b o r s ) ) != NULL) { i f ( ( ( nodedata−>t i m e o u t > 0 ) && ( c l o c k − n e i g h b o r −>time ) >= nodedata−>t i m e o u t ) | | ( n e i g h b o r −>i d == h e a d e r −> s r c ) ) { continue ; } i f ( n e i g h b o r −>i d == 0 ) { return n e i g h b o r ; } dMoins = 0 ; dPlus = 0 ; i f ( h e a d e r −> nbBeacons !=1) { f o r ( i = header−> nbBeacons ; i >0; i −−) { dPlus += max ( ( n e i g h b o r −>c o r d [ i −1] − c o r d S i n k [ i − 1 ] ) , 0 ) ; dMoins += max ( ( c o r d S i n k [ i −1] − n e i g h b o r −>c o r d [ i − 1 ] ) , 0 ) ; } } else { dPlus = max ( ( n e i g h b o r −>c o r d [ c l o s e s t B e a c o n ] − cordSink [ closestBeacon ] ) , 0 ) ; dMoins = max ( ( c o r d S i n k [ c l o s e s t B e a c o n ] − n e i g h b o r −>c o r d [ c l o s e s t B e a c o n ] ) , 0 ) ; } d = ( 1 0 ∗ dPlus ) + dMoins ; /∗ c h o o s e n e x t hop ∗/ i f (d < dist ) { dist = d; n hop = n e i g h b o r ; ANNEXE C. LISTING DE CODE 79 n hop −> d i s t a n c e =d ; } } return n hop ; } int check how many converged ( c a l l t ∗ c ) { struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; double d ; int j , p ; e n t i t y d a t a −>c o n v e r g e d =0; f o r ( j =0; j <g e t n o d e c o u n t ( ) ; j ++) { d=0; f o r ( p=0; p<MAXLANDM; p++) { d += ( e n t i t y d a t a −>o l d [ j ] [ p ] − e n t i t y d a t a −>c u r r e n t [ j ] [ p ] ) ; d= d∗d ; } d=s q r t ( d ) ; i f ( d==0) { e n t i t y d a t a −>c o n v e r g e d++ ; } } return e n t i t y d a t a −>c o n v e r g e d ; } void a d d n e i g h b o r ( c a l l t ∗ c , struct r o u t i n g h e a d e r ∗ h e a d e r ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct n e i g h b o r ∗ n e i g h b o r = NULL; int i ; /∗ c h e c k w h e t h e r n e i g h b o r a l r e a d y e x i s t s ∗/ d a s i n i t t r a v e r s e ( nodedata−>n e i g h b o r s ) ; while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) d a s t r a v e r s e ( nodedata−>n e i g h b o r s ) ) != NULL) { i f ( n e i g h b o r −>i d == header−>s r c ) { f o r ( i =0; i <MAXLANDM; i ++) { n e i g h b o r −>c o r d [ i ]= header−>s r c c o r d [ i ] ; } n e i g h b o r −>time = g e t t i m e ( ) ; return ; } } n e i g h b o r = ( struct n e i g h b o r ∗ ) m a l l o c ( s i z e o f ( struct n e i g h b o r ) ) ; ANNEXE C. LISTING DE CODE 80 n e i g h b o r −>i d = header−>s r c ; f o r ( i =0; i <MAXLANDM; i ++) { n e i g h b o r −>c o r d [ i ]= header−>s r c c o r d [ i ] ; } n e i g h b o r −>time = g e t t i m e ( ) ; d a s i n s e r t ( nodedata−>n e i g h b o r s , ( void ∗ ) n e i g h b o r ) ; return ; } int s e t h e a d e r ( c a l l t ∗ c , p a c k e t t ∗ packet , d e s t i n a t i o n t ∗ virtual dst ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; int i , j , u ; int dMoins , dPlus ; header−>nbBeacons=e n t i t y d a t a −>nbbeacon ; header−>c o o r d o n a t e D e s t = 0 ; header−>i n i t i a l s o u r c e = c−>node ; header−>s r c = c−>node ; header−>type = DATA PACKET; f o r ( u=0; u<MAXLANDM; u++) { header−>s r c c o r d [ u]= nodedata−>c o r d [ u ] ; } f o r ( i =0; i <header−>nbBeacons ; i ++) { dMoins =0; dPlus =0; f o r ( j =0; j<=i ; j++ ) { dPlus += max ( ( nodedata−>c o r d [ j ] − c o r d S i n k [ j ] ) , 0 ) ; dMoins += max ( ( c o r d S i n k [ j ] − nodedata−>c o r d [ j ] ) , 0 ) ; } header−>dMin [ i ]= 10 ∗ dPlus + dMoins ; } struct n e i g h b o r ∗ n hop = g e t n e x t h o p ( c , h e a d e r ) ; if ( ( n hop−>i d == 0 ) | | ( n hop−>d i s t a n c e < header−>dMin [ 1 ] ) ) { goto t x d a t a ; } else { header−>nbBeacons =1; n hop = g e t n e x t h o p ( c , h e a d e r ) ; i f ( n hop−>d i s t a n c e < header−>dMin [ 0 ] ) { goto t x d a t a ; } e l s e { // g r e e d y f a i l e d i f ( nodedata−>beaconId != c l o s e s t B e a c o n ) { ANNEXE C. LISTING DE CODE 81 n hop = NULL; struct n e i g h b o r ∗ n e i g h b o r = NULL; uint64 t clock = get time ( ) ; d a s i n i t t r a v e r s e ( nodedata−>n e i g h b o r s ) ; while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) d a s t r a v e r s e ( nodedata−>n e i g h b o r s ) ) != NULL) { i f ( ( nodedata−>t i m e o u t > 0 ) && ( c l o c k − n e i g h b o r −>time ) >= nodedata−>t i m e o u t ) { continue ; } i f ( n e i g h b o r −>c o r d [ c l o s e s t B e a c o n ] == nodedata−>c o r d [ c l o s e s t B e a c o n ] − 1 ) { n hop = n e i g h b o r ; break ; } } i f ( n hop != NULL) { goto t x d a t a ; } } else { header−>d s t = BROADCAST ADDR; d e s t i n a t i o n t d e s t i n a t i o n= {BROADCAST ADDR, {−1, −1, −1}}; return SET HEADER(&c0 , packet , &d e s t i n a t i o n ) ; } } } return −1; tx data : header−>d s t = n hop−>i d ; d e s t i n a t i o n t d e s t i n a t i o n= {BROADCAST ADDR, {−1, −1, −1}}; return SET HEADER(&c0 , packet , &d e s t i n a t i o n ) ; } int g e t h e a d e r s i z e ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; i f ( nodedata−>overhead == −1) { c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; nodedata−>overhead = GET HEADER SIZE(&c0 ) ; } return nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) ; } int g e t h e a d e r r e a l s i z e ( c a l l t ∗ c ) { ANNEXE C. LISTING DE CODE 82 struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; i f ( nodedata−>overhead == −1) { c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; nodedata−>overhead = GET HEADER REAL SIZE(&c0 ) ; } return nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) ; } int n e i g h b o r t i m e o u t ( void ∗ data , void ∗ a r g ) { struct n e i g h b o r ∗ n e i g h b o r = ( struct n e i g h b o r ∗ ) data ; c a l l t ∗c = ( c a l l t ∗) arg ; struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; i f ( ( g e t t i m e ( ) − n e i g h b o r −>time ) >= nodedata−>t i m e o u t ) { return 1 ; } return 0 ; } int b o o t s t r a p ( c a l l t ∗ c ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; nodedata−>overhead = GET HEADER SIZE(&c0 ) ; i f ( nodedata−>type==SINK) { d e s t i n a t i o n t d e s t i n a t i o n = {BROADCAST ADDR, {−1, −1, −1}}; p a c k e t t ∗ p a c k e t = p a c k e t c r e a t e ( c , nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) , −1); struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; /∗ s e t mac h e a d e r ∗/ i f (SET HEADER(&c0 , packet , &d e s t i n a t i o n ) == −1) { p a c k e t d e a l l o c ( packet ) ; } else { header−>d s t = BROADCAST ADDR; header−>s r c = c−>node ; header−>nbHops=nodedata−>nbHopsToSink ; header−>type = DISCOVERY PACKET; TX(&c0 , p a c k e t ) ; } } /∗ i f t h e node t y p e i s landmark , we s c h e d u l e a new c a l l b a c k ∗/ e l s e i f ( nodedata−>type == LANDM) { scheduler add callback (( uint64 t ) ( get time () + 100000000 ∗ g e t r a n d o m d o u b l e ( ) ) , c , c a ll me ba ck , NULL ) ; ANNEXE C. LISTING DE CODE 83 } i f ( nodedata−>p e r i o d > 0 ) { uint64 t start = get time () + nodedata−>s t a r t + g e t r a n d o m d o u b l e ( ) ∗ nodedata−>p e r i o d ; s c h e d u l e r a d d c a l l b a c k ( s t a r t , c , callmebackHELLO , NULL ) ; } uint64 t start = get time () + g e t r a n d o m d o u b l e ( ) ∗ ( e n t i t y d a t a −>p e r i o d / 1 0 0 0 ) ; s c h e d u l e r a d d c a l l b a c k ( s t a r t , c , callmebackCheckingConvergence , NULL ) ; return 0 ; } int i o c t l ( c a l l t ∗ c , int o p t i o n , void ∗ in , void ∗∗ out ) { return 0 ; } int c a l l m e b a c k C h e c k i n g C o n v e r g e n c e ( c a l l t ∗ c , void ∗ a r g s ) { struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; int j ; f o r ( j =0; j <MAXLANDM; j ++) { e n t i t y d a t a −>o l d [ c−>node ] [ j ] = e n t i t y d a t a −>c u r r e n t [ c−>node ] [ j ] ; } i f ( k <= 5 ) { u i n t 6 4 t s t a r t = g e t t i m e ( ) + ( e n t i t y d a t a −>p e r i o d / 1 0 0 0 ) ; scheduler add callback ( start , c , callmebackCheckingConvergence , NULL ) ; } return 0 ; } int c a l l m e b a c k ( c a l l t ∗ c , void ∗ a r g s ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; e n t i t y i d t ∗down = g e t e n t i t y l i n k s d o w n ( c ) ; c a l l t c0 = {down [ 0 ] , c−>node } ; d e s t i n a t i o n t d e s t i n a t i o n = {BROADCAST ADDR, {−1, −1, −1}}; p a c k e t t ∗ p a c k e t = p a c k e t c r e a t e ( c , nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) , −1); struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; i f (SET HEADER(&c0 , packet , &d e s t i n a t i o n ) == −1) { p a c k e t d e a l l o c ( packet ) ; return −1; ANNEXE C. LISTING DE CODE 84 } header−>s r c = c−>node ; header−>d s t= BROADCAST ADDR; = nodedata−>s e q b e a c o n ++; // header−>s e q b e a c o n header−>beacon = nodedata−>beaconId ; header−>c o r d = 0 ; header−>type = BEACON PACKET; TX(&c0 , p a c k e t ) ; nodedata−>b e a c o n t x ++; s c h e d u l e r a d d c a l l b a c k ( g e t t i m e ( ) + e n t i t y d a t a −>p e r i o d , c , ca ll me ba c k , NULL ) ; return 0 ; } int callmebackHELLO ( c a l l t ∗ c , void ∗ a r g s ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; d e s t i n a t i o n t d e s t i n a t i o n = {BROADCAST ADDR, {−1, −1, −1}}; p a c k e t t ∗ p a c k e t = p a c k e t c r e a t e ( c , nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) , −1); struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; i f (SET HEADER(&c0 , packet , &d e s t i n a t i o n ) == −1) { p a c k e t d e a l l o c ( packet ) ; return −1; } header−>d s t = BROADCAST ADDR; header−>s r c = c−>node ; header−>type = HELLO PACKET; int i ; f o r ( i =0; i <MAXLANDM; i ++) { header−>s r c c o r d [ i ] = nodedata−>c o r d [ i ] ; } TX(&c0 , p a c k e t ) ; nodedata−>h e l l o t x ++; /∗ c h e c k n e i g h b o r s t i m e o u t ∗/ d a s s e l e c t i v e d e l e t e ( nodedata−>n e i g h b o r s , n e i g h b o r t i m e o u t , ( void ∗ ) c ) ; /∗ s c h e d u l e s h e l l o ∗/ ANNEXE C. LISTING DE CODE 85 s c h e d u l e r a d d c a l l b a c k ( g e t t i m e ( ) + nodedata−>p e r i o d , c , callmebackHELLO , NULL ) ; return 0 ; } void tx ( c a l l t ∗ c , p a c k e t t ∗ p a c k e t ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; nodedata−>d a t a t x ++; TX(&c0 , p a c k e t ) ; header−>n hop =0; i f ( k>5) { header−>count =1;} e l s e { header−>count =0;} } void f o r w a r d ( c a l l t ∗ c , p a c k e t t ∗ p a c k e t ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct e n t i t y d a t a ∗ e n t i t y d a t a = g e t e n t i t y p r i v a t e d a t a ( c ) ; struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; int i , j , u ; int dMoins , dPlus ; header−>nbBeacons=e n t i t y d a t a −>nbbeacon ; struct n e i g h b o r ∗ n hop = NULL; i f ( header−>c o o r d o n a t e D e s t == 1 ) { n hop=g e t n e x t h o p ( c , h e a d e r ) ; i f ( n hop !=NULL) { // normalement c ’ e s t t o u j o u r s l e c a s header−>d s t = n hop−>i d ; goto f o r w a r d d a t a ; } } i f ( header−> c o o r d o n a t e D e s t > 0 ) { header−>d s t = BROADCAST ADDR; goto f o r w a r d d a t a ; } f o r ( i =0; i <header−>nbBeacons ; i ++) { dMoins =0; dPlus =0; f o r ( j =0; j<=i ; j++ ) { dPlus += max ( ( nodedata−>c o r d [ j ] − c o r d S i n k [ j ] ) , 0 ) ; ANNEXE C. LISTING DE CODE 86 dMoins += max ( ( c o r d S i n k [ j ] − nodedata−>c o r d [ j ] ) , 0 ) ; } header−>dMin [ i ]= min ( header−>dMin [ i ] , ( 1 0 ∗ dPlus + dMoins ) ) ; } n hop = g e t n e x t h o p ( c , h e a d e r ) ; i f ( ( n hop−>i d == 0 ) | | ( n hop−>d i s t a n c e < header−>dMin [ 1 ] ) ) { header−>d s t = n hop−>i d ; goto f o r w a r d d a t a ; } else { header−>nbBeacons =1; n hop = g e t n e x t h o p ( c , h e a d e r ) ; i f ( n hop−>d i s t a n c e < header−>dMin [ 0 ] ) { header−>d s t = n hop−>i d ; goto f o r w a r d d a t a ; } e l s e { // g r e e d y f a i l e d i f ( nodedata−>beaconId != c l o s e s t B e a c o n ) { n hop = NULL; struct n e i g h b o r ∗ n e i g h b o r = NULL; uint64 t clock = get time ( ) ; d a s i n i t t r a v e r s e ( nodedata−>n e i g h b o r s ) ; while ( ( n e i g h b o r = ( struct n e i g h b o r ∗ ) d a s t r a v e r s e ( nodedata−>n e i g h b o r s ) ) != NULL) { i f ( ( ( nodedata−>t i m e o u t > 0 ) && ( c l o c k − n e i g h b o r −>time ) >= nodedata−>t i m e o u t ) | | ( n e i g h b o r −>i d == header−> s r c ) ) { continue ; } i f ( n e i g h b o r −>c o r d [ c l o s e s t B e a c o n ] == nodedata−>c o r d [ c l o s e s t B e a c o n ] − 1 ) { n hop = n e i g h b o r ; break ; } } i f ( n hop != NULL) { header−>d s t = n hop−>i d ; goto f o r w a r d d a t a ; } else { // p r i n t f (”A p r i o r i , on e s t pas c e n sé r e n t r é par l à \n ” ) ; header−>d s t = BROADCAST ADDR; ANNEXE C. LISTING DE CODE 87 goto f o r w a r d d a t a ; } } else { header−> c o o r d o n a t e D e s t = c o r d S i n k [ nodedata−>beaconId ] ; header−>d s t = BROADCAST ADDR; goto f o r w a r d d a t a ; } } } forward data : header−>s r c = c−>node ; header−>type = DATA PACKET; f o r ( u=0; u<MAXLANDM; u++) { header−>s r c c o r d [ u]= nodedata−>c o r d [ u ] ; } d e s t i n a t i o n t d e s t i n a t i o n= {BROADCAST ADDR, {−1, −1, −1}}; i f (SET HEADER(&c0 , packet , &d e s t i n a t i o n ) == −1) { p a c k e t d e a l l o c ( packet ) ; return ; } nodedata−>d a t a t x ++; TX(&c0 , p a c k e t ) ; return ; } void rx ( c a l l t ∗ c , p a c k e t t ∗ p a c k e t ) { struct nodedata ∗ nodedata = g e t n o d e p r i v a t e d a t a ( c ) ; struct r o u t i n g h e a d e r ∗ h e a d e r = ( struct r o u t i n g h e a d e r ∗ ) ( packet−>data + nodedata−>overhead ) ; int c o n v e r g e n c e ; switch ( header−>type ) { case HELLO PACKET: nodedata−>h e l l o r x ++; add neighbor ( c , header ) ; p a c k e t d e a l l o c ( packet ) ; break ; case DISCOVERY PACKET: i f ( ( nodedata−>nbHopsToSink == −1) | | ( nodedata−>nbHopsToSink > header−>nbHops +1)) { nodedata−>nbHopsToSink=header−>nbHops +1; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; packet t ∗ packet to send = packet create (c , ANNEXE C. LISTING DE CODE 88 nodedata−>overhead + s i z e o f ( struct r o u t i n g h e a d e r ) , −1); struct r o u t i n g h e a d e r ∗ h e a d e r t o s e n d = ( struct r o u t i n g h e a d e r ∗ ) ( p a c k e t t o s e n d −>data + nodedata−>overhead ) ; d e s t i n a t i o n t d e s t i n a t i o n = {BROADCAST ADDR, {−1, −1, −1}}; i f (SET HEADER(&c0 , p a c k e t t o s e n d , &d e s t i n a t i o n ) == −1) { packet dealloc ( packet to send ) ; } else { h e a d e r t o s e n d −>d s t = BROADCAST ADDR; h e a d e r t o s e n d −>s r c = c−>node ; h e a d e r t o s e n d −>nbHops=nodedata−>nbHopsToSink ; h e a d e r t o s e n d −>type = DISCOVERY PACKET; TX(&c0 , p a c k e t t o s e n d ) ; } } p a c k e t d e a l l o c ( packet ) ; break ; case BEACON PACKET: nodedata−>b e a c o n r x ++; int c u r r e n t C o r d = nodedata−>c o r d [ header−>beacon ] ; c a l l t c0 = { g e t e n t i t y b i n d i n g s d o w n ( c)−> e l t s [ 0 ] , c−>node } ; i f ( ( c u r r e n t C o r d < 0 ) | | ( c u r r e n t C o r d > header−>c o r d ) ) { nodedata−>c o r d [ header−>beacon ] = ( header−>c o r d +1); // nodedata−>l a s t s e q b e a c o n = header−>s e q b e a c o n ; d e s t i n a t i o n t d e s t i n a t i o n = {BROADCAST ADDR, {−1, −1, −1}}; i f (SET HEADER(&c0 , packet , &d e s t i n a t i o n ) == −1) { p a c k e t d e a l l o c ( packet ) ; } else { header−>s r c = c−>node ; header−>d s t = BROADCAST ADDR; header−>c o r d = header−>c o r d + 1 ; header−>type = BEACON PACKET; // header−>s e q b e a c o n = nodedata−>s e q b e a c o n ++; i f ( c−>node == 0 ) { //SINK int z ; f o r ( z =0; z<MAXLANDM; z++) { c o r d S i n k [ z ]= nodedata−>c o r d [ z ] ; } i f (( cordSink [0]) <( cordSink [ 1 ] ) ) { closestBeacon = 0;} e l s e { c l o s e s t B e a c o n =1;} } ANNEXE C. LISTING DE CODE 89 nodedata−>b e a c o n t x ++; TX(&c0 , p a c k e t ) ; break ; } } else { i f ( c−>node == 0 ) { //SINK int p ; f o r ( p=0; p<MAXLANDM; p++) { c o r d S i n k [ p]= nodedata−>c o r d [ p ] ; } i f (( cordSink [0]) <( cordSink [ 1 ] ) ) { closestBeacon = 0;} e l s e { c l o s e s t B e a c o n =1;} } p a c k e t d e a l l o c ( packet ) ; } break ; case DATA PACKET : header−>n hop++; i f ( ( c−>node == 0 ) && ( c−>node==header−>d s t ) ) { /∗ Data p a c k e t r e c e i v e d by s i n k ∗/ nodedata−>d a t a r x ++; i f ( header−>count==1) { mean hops= ( ( ( double ) ( n b t x ) ) / ( ( double ) ( n b t x +1)))∗ mean hops+ ( ( double ) ( header−>n hop ) ) / ( ( double ) ( n b t x + 1 ) ) ; n b t x++; } a r r a y t ∗up = g e t e n t i t y b i n d i n g s u p ( c ) ; int i = up−>s i z e ; while ( i −−) { c a l l t c up = {up−>e l t s [ i ] , c−>node } ; packet t ∗ packet up ; i f ( i > 0) { packet up = packet clone ( packet ) ; } else { packet up = packet ; } RX(&c up , p a c k e t u p ) ; } break ; ANNEXE C. LISTING DE CODE 90 } else { i f ( ( header−>d s t == c−>node ) | | ( header−> d s t == BROADCAST ADDR) ) { header−>c o o r d o n a t e D e s t −−; i f ( header−>c o o r d o n a t e D e s t != 0 ) { forward ( c , packet ) ; break ; } } } c o n v e r g e n c e = check how many converged ( c ) ; i f ( convergence > get node count ( ) ∗ 0 . 9 5 ) { k++; } i f ( k==5) { p r i n t f ( ” Convergence a c c o m p l i s h e d \n” ) ; t i m e c o n v e r g e d=g e t t i m e ( ) ; } p a c k e t d e a l l o c ( packet ) ; break ; default : break ; } return ; } r o u t i n g m e t h o d s t methods = { rx , tx , set header , get header size , get header real size };