{ "nbformat": 4, "nbformat_minor": 0, "metadata": { "colab": { "provenance": [] }, "kernelspec": { "name": "python3", "display_name": "Python 3" }, "language_info": { "name": "python" } }, "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "id": "hQUQuDCwIaNM", "colab": { "base_uri": "https://localhost:8080/", "height": 1000 }, "outputId": "5b0f6673-0de6-4e68-d758-ddfc85b20c89" }, "outputs": [ { "output_type": "stream", "name": "stdout", "text": [ "Node 1 sent DIO message.\n", "Node 1 sent DIS message.\n", "Node 1 trust metric: 0.5915699430806951\n", "Node 1 updated trust metric: 0.47058606864147656\n", "Node 1 energy consumption: 168.08163227966526\n", "Node 1 sent DAO message to destination 3.\n", "Node 2 sent DIO message.\n", "Node 2 sent DIS message.\n", "Node 2 trust metric: 0.9947522517229339\n", "Node 2 updated trust metric: 0.00459716287653817\n", "Node 2 energy consumption: 123.16966032177072\n", "Node 2 is potentially under Sybil attack.\n", "Node 2 sent DAO message to destination 3.\n", "Node 2 prevented sending data packets to a detected malicious node.\n", "Node 2 sent DAO message to destination 3.\n", "Node 3 sent DIO message.\n", "Node 3 sent DIS message.\n", "Node 3 trust metric: 0.062458190026773\n", "Node 3 updated trust metric: 0.2916818051292221\n", "Node 3 energy consumption: 131.65131713135096\n", "Node 3 is potentially under Sybil attack.\n", "Node 3 sent DAO message to destination 3.\n", "Node 4 sent DIO message.\n", "Node 4 sent DIS message.\n", "Node 4 trust metric: 0.6813320428513867\n", "Node 4 updated trust metric: 0.30740301420251104\n", "Node 4 energy consumption: 165.42111454914857\n", "Node 4 is potentially under Sybil attack.\n", "Node 4 sent DAO message to destination 1.\n", "Node 4 prevented sending data packets to a detected malicious node.\n", "Node 4 sent DAO message to destination 1.\n", "Node 5 sent DIO message.\n", "Node 5 sent DIS message.\n", "Node 5 trust metric: 0.7614231020002082\n", "Node 5 updated trust metric: 0.6554527433570884\n", "Node 5 energy consumption: 186.38294104704636\n", "Node 5 sent DAO message to destination 2.\n", "Node 1 sent DIO message.\n", "Node 1 sent DIS message.\n", "Node 1 trust metric: 0.5752206195030178\n", "Node 1 updated trust metric: 0.08265955717699543\n", "Node 1 energy consumption: 194.36348353066595\n", "Node 1 sent DAO message to destination 2.\n", "Node 2 sent DIO message.\n", "Node 2 sent DIS message.\n", "Node 2 trust metric: 0.8606126237968125\n", "Node 2 updated trust metric: 0.5324395652900601\n", "Node 2 energy consumption: 155.32086577789204\n", "Node 2 is potentially under Sybil attack.\n", "Node 2 is potentially under Sybil attack.\n", "Node 2 sent DAO message to destination 1.\n", "Node 2 prevented sending data packets to a detected malicious node.\n", "Node 2 sent DAO message to destination 1.\n", "Node 3 sent DIO message.\n", "Node 3 sent DIS message.\n", "Node 3 trust metric: 0.6035198718846775\n", "Node 3 updated trust metric: 0.7662651373016691\n", "Node 3 energy consumption: 160.55357068925676\n", "Node 3 is potentially under Sybil attack.\n", "Node 3 is potentially under Sybil attack.\n", "Node 3 failed to prevent the attack.\n", "Node 3 sent DAO message to destination 5.\n", "Node 4 sent DIO message.\n", "Node 4 sent DIS message.\n", "Node 4 trust metric: 0.43928806829524647\n", "Node 4 updated trust metric: 0.5055856349029254\n", "Node 4 energy consumption: 127.69715198165113\n", "Node 4 sent DAO message to destination 5.\n", "Node 5 sent DIO message.\n", "Node 5 sent DIS message.\n", "Node 5 trust metric: 0.07005427832126943\n", "Node 5 updated trust metric: 0.21699986961883527\n", "Node 5 energy consumption: 105.16859002515227\n", "Node 5 sent DAO message to destination 3.\n", "Node 1 sent DIO message.\n", "Node 1 sent DIS message.\n", "Node 1 trust metric: 0.4121128675800131\n", "Node 1 updated trust metric: 0.8255637480107487\n", "Node 1 energy consumption: 125.2099884180851\n", "Node 1 is potentially under Sybil attack.\n", "Node 1 sent DAO message to destination 4.\n", "Node 2 sent DIO message.\n", "Node 2 sent DIS message.\n", "Node 2 trust metric: 0.7115679509908989\n", "Node 2 updated trust metric: 0.8497748509223362\n", "Node 2 energy consumption: 171.88820517925558\n", "Node 2 sent DAO message to destination 4.\n", "Node 3 sent DIO message.\n", "Node 3 sent DIS message.\n", "Node 3 trust metric: 0.3473291343989804\n", "Node 3 updated trust metric: 0.1802252392898582\n", "Node 3 energy consumption: 143.78523218748296\n", "Node 3 is potentially under Sybil attack.\n", "Node 3 sent DAO message to destination 5.\n", "Node 4 sent DIO message.\n", "Node 4 sent DIS message.\n", "Node 4 trust metric: 0.7138150083082979\n", "Node 4 updated trust metric: 0.8346425517297587\n", "Node 4 energy consumption: 194.23319206081277\n", "Node 4 is potentially under Sybil attack.\n", "Node 4 sent DAO message to destination 2.\n", "Node 4 prevented sending data packets to a detected malicious node.\n", "Node 4 sent DAO message to destination 2.\n", "Node 5 sent DIO message.\n", "Node 5 sent DIS message.\n", "Node 5 trust metric: 0.1953544260696467\n", "Node 5 updated trust metric: 0.38369708967609417\n", "Node 5 energy consumption: 153.36628501970694\n", "Node 5 sent DAO message to destination 5.\n", "Node 1 sent DIO message.\n", "Node 1 sent DIS message.\n", "Node 1 trust metric: 0.9708848434540234\n", "Node 1 updated trust metric: 0.3480814254751811\n", "Node 1 energy consumption: 195.08000791087892\n", "Node 1 is potentially under Sybil attack.\n", "Node 1 sent DAO message to destination 1.\n", "Node 2 sent DIO message.\n", "Node 2 sent DIS message.\n", "Node 2 trust metric: 0.46299477520533205\n", "Node 2 updated trust metric: 0.8255622433299621\n", "Node 2 energy consumption: 120.9898145103979\n", "Node 2 is potentially under Sybil attack.\n", "Node 2 sent DAO message to destination 3.\n", "Node 3 sent DIO message.\n", "Node 3 sent DIS message.\n", "Node 3 trust metric: 0.11312911058027775\n", "Node 3 updated trust metric: 0.6720566070902226\n", "Node 3 energy consumption: 185.96308854596083\n", "Node 3 sent DAO message to destination 1.\n", "Node 4 sent DIO message.\n", "Node 4 sent DIS message.\n", "Node 4 trust metric: 0.7206354902209795\n", "Node 4 updated trust metric: -0.021779179355242498\n", "Node 4 energy consumption: 101.0602004343761\n", "Node 4 is potentially under Sybil attack.\n", "Node 4 sent DAO message to destination 1.\n", "Node 5 sent DIO message.\n", "Node 5 sent DIS message.\n", "Node 5 trust metric: 0.4933145221619125\n", "Node 5 updated trust metric: 0.8772487575315053\n", "Node 5 energy consumption: 118.933345416841\n", "Node 5 is potentially under Sybil attack.\n", "Node 5 sent DAO message to destination 4.\n", "Node 5 prevented sending data packets to a detected malicious node.\n", "Node 5 sent DAO message to destination 4.\n" ] }, { "output_type": "display_data", "data": { "text/plain": [ "
" ], "image/png": "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8gE3+fbbb+Xt7a2BAwc6tL/00ksyxmjFihW3HSMwMND+b6vVqrNnz6pMmTIKCwu740PJc+fOVaFChVS/fn1Jfx/WjImJ0YIFC5SWlnZHY97g7+8vL6+/f+2kpaXp7NmzCg4OVrly5RzqXbJkicLDwzVgwACnMf73gpVr167pmWee0fLly/Xtt9/qySefdFgfFham33//XQcOHHCp1piYGFmtVvspAZK0evVqXbhwQTExMQ7jb926VSdOnHBp/BsaNWqkiIgIlShRQh06dFBwcLCWLl2qYsWKOfTr06ePw/KiRYuUN29eRUdH68yZM/af6tWrKzg4WOvWrZMk++kSn3/+ucMpIgsXLtSjjz6q++67T5L0xRdfyGazqX379g7jFS5cWFFRUfbxbggODnY4X9rPz081a9bU4cOHb/ucd+7cqQMHDqhTp046e/asfVuXL19Ww4YNtXHjRtlsNqWlpWnVqlVq3bq1vU7p75n5GzPWGTF37lw1a9ZMISEhkqSoqChVr17d6XD+nfjnPnj16lWdOXNGjz76qCTZP9M2m03Lli1TixYtnE6dkJw/03/88Yfq1q0rq9WqjRs3qmTJkg7b8/Pz0/r16x1O2QDuFQRTwE2OHj2qokWL2v9necONw+JHjx697RhXrlzRiBEj7OeohoeHKyIiQhcuXNDFixddriktLU0LFixQ/fr1deTIER08eFAHDx7UI488or/++ktr1651ecx/stlsmjx5sqKiohzq3bVrl0O9hw4dUrly5eTjc/uzjcaNG6dly5Zp8eLF6V4xPXr0aF24cEFly5ZVlSpV9PLLL2vXrl23Hbdq1aoqX768Fi5caG9buHChwsPD7eeBStKECRO0e/dulShRQjVr1lRcXFyGwtkN7733nuLj47Vu3Trt2bNHhw8fdgpdPj4+Kl68uEPbgQMHdPHiRRUsWFAREREOP8nJyTp16pS9b0xMjI4fP64ffvhB0t+v788//+wQsA8cOCBjjKKiopzG27t3r8N4klS8eHGnQJUvX74MhaUbfyTExsY6bWvGjBlKTU3VxYsXdfr0aV25ckVRUVFOY5QrV+6225GkvXv3aseOHapVq5b983zw4EHVq1dPy5cvV1JSUobGuZlz585p0KBBKlSokAIDAxUREaHIyEhJsn+mT58+raSkJFWuXDlDYz777LM6deqUNmzY4PQH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795dTzzxhIwxevvttxUcHJxu3xEjRmSoyOPHj2vQoEGKj49XQEBAhh4zbNgwDR482L6clJSkEiVK6Mknn7ztE80s619vli3buVcZL19dqdZLgTs/ksXGX7t3ot6/v3F3CchCVqtV8fHxio6Olq8vRxaA/8U+kvPcOMKdERkKprNnz9bIkSO1fPlyWSwWrVixQj4+zg+1WCwZDqY///yzTp06pYceesjelpaWpo0bN+rdd99VamqqvL29HR7j7+8vf39/p7F8fX2z7cNpsTl/JStcZ7FZeS3vEL+Ic4fs/L0G5ETsIzmHK+9ThoJpuXLltGDBAkmSl5eX1q5de9eH8hs2bKjffvvNoa179+4qX768Xn31VadQCgAAgHubyzfYt9lsmbLhkJAQVa5c2aEtT548KlCggFM7AAAA7n139M1Phw4d0pQpU7R3715JUsWKFTVo0CCVLl06U4sDAABA7uFyMF21apVatmypatWqqVatWpKkzZs3q1KlSvr6668VHR19x8WsX7/+jh8LAACAnM3lYDp06FC9+OKLevPNN53aX3311bsKpgAAAMi9XP7mp71796pnz55O7T169NCePXsypSgAAADkPi4H04iICO3cudOpfefOnZly030AAADkTi4fyn/++efVq1cvHT58WI8//rikv88xHT9+vMPN7wEAAABXuBxMhw8frpCQEE2cOFHDhg2TJBUtWlRxcXEaOHBgphcIAACA3MHlYGqxWPTiiy/qxRdf1KVLlyT9fU9SAAAA4G7c0X1MbyCQAgAAILO4fPETAAAAkBUIpgAAAPAIBFMAAAB4BJeCqdVqVcOGDXXgwIGsqgcAAAC5lEvB1NfXV7t27cqqWgAAAJCLuXwov0uXLpo5c2ZW1AIAAIBczOXbRV2/fl0ff/yx1qxZo+rVqytPnjwO6ydNmpRpxQEAACD3cDmY7t69Ww899JAkaf/+/Q7rLBZL5lQFAACAXMflYLpu3bqsqAMAAAC53B3fLurgwYNatWqVrly5IkkyxmRaUQAAAMh9XA6mZ8+eVcOGDVW2bFk1bdpUiYmJkqSePXvqpZdeyvQCAQAAkDu4HExffPFF+fr66tixYwoKCrK3x8TEaOXKlZlaHAAAAHIPl88xXb16tVatWqXixYs7tEdFReno0aOZVhgAAAByF5dnTC9fvuwwU3rDuXPn5O/vnylF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NF966SU9/PDDGjNmjGJiYvTDDz/o3Xff1fvvv5/huk+fPq2vv/5aX331ldMtpbp27aqnn35a586dU8mSJWWxWLR8+XI1bdpUgYGBCg4OVqlSpbR161YlJCQoODhY+fPnV1RUlD755BOtWrVKkZGR+vTTT7V9+3ZFRkbax46Li9P//d//qWDBgmrSpIkuXbqkzZs3a8CAAQ41PP300/r000/17LPPysfHR+3atdPy5ct1+PBh1alTR/ny5dO3334rm82mcuXKZfh5A8jl3H2SKwBklv+9+OmGtWvXGknm888/d2i/cfHTvHnzTM2aNY2fn5+pWLGi+e677xz67d+/3zz99NMmLCzMBAYGmvLly5sXXnjB2Gy2m9ayePFiU7FiRePr62vuu+8+89Zbbzmsv93FT2+//bYJCwsz165dc1qXmppqwsLC7Fe8jx492hQuXNhYLBYTGxtrjDFm37595tFHHzWBgYFGkjly5Ii5evWq6datm8mbN68JCwszffr0MUOHDjVVq1Z1GP+DDz4w5cqVM76+vqZIkSJmwIAB9nX6/6/Kv2HhwoUmICDALFmyxHz//fembt26Jl++fCYwMNA88MADDlf8A8DtWIwxxr3RGACy1qeffqoXX3xRJ06csB/6lv6+D2hkZKR27NihatWqua9AAIAkDuUDuIelpKQoMTFRb775pnr37u0QSgEAnoeLnwDcsyZMmKDy5curcOHCGjZsmLvLAQDcBofyAQAA4BGYMQUAAIBHIJgCAADAIxBMAQAA4BEIpgAAAPAIBFMAAAB4BIIpAAAAPALBFAAAAB6BYAoAAACP8P8BccvvnHdbpl4AAAAASUVORK5CYII=\n" }, "metadata": {} } ], "source": [ "import networkx as nx\n", "import matplotlib.pyplot as plt\n", "import random\n", "import numpy as np\n", "\n", "# Step 1: Setup the network\n", "num_nodes = 5 # Number of nodes in the network\n", "G = nx.Graph()\n", "G.add_nodes_from(range(1, num_nodes + 1))\n", "G.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 5), (5, 1)])\n", "\n", "# Step 2: Implement RPL protocol\n", "def send_dio(node):\n", " print(f\"Node {node} sent DIO message.\")\n", "\n", "def send_dao(node, destination):\n", " print(f\"Node {node} sent DAO message to destination {destination}.\")\n", "\n", "def send_dis(node):\n", " print(f\"Node {node} sent DIS message.\")\n", "\n", "# Step 3: Implement MRTS\n", "def calculate_trust_metric(node):\n", " return random.uniform(0, 1)\n", "\n", "def update_trust_metric(node):\n", " trust_metric = calculate_trust_metric(node)\n", " trust_metric += random.uniform(-0.1, 0.1)\n", " return trust_metric\n", "\n", "def calculate_energy_consumption(node):\n", " return random.uniform(100, 200)\n", "\n", "# Step 4: Simulate attacks (Sybil)\n", "def simulate_sybil_attack():\n", " num_attackers = random.randint(1, num_nodes) # Random number of attackers\n", " attacker_ids = range(num_nodes + 1, num_nodes + num_attackers + 1)\n", " for attacker_id in attacker_ids:\n", " G.add_node(attacker_id)\n", "\n", " # Connect attacker nodes to existing nodes\n", " target_nodes = list(G.nodes())\n", " target_nodes.remove(attacker_id)\n", " for _ in range(3): # Each attacker node connects to 3 existing nodes\n", " target = random.choice(target_nodes)\n", " G.add_edge(attacker_id, target)\n", " target_nodes.remove(target)\n", "\n", "# Step 5: Detect attacks\n", "def detect_sybil_attack(node):\n", " trust_threshold = 0.5\n", " trust_metric = calculate_trust_metric(node)\n", " if trust_metric < trust_threshold:\n", " print(f\"Node {node} is potentially under Sybil attack.\")\n", " return True\n", " return False\n", "\n", "def detect_malicious_node(node, destination):\n", " trust_threshold = 0.5\n", " trust_metric = calculate_trust_metric(node)\n", " if trust_metric < trust_threshold:\n", " print(f\"Node {node} detected malicious node {destination}.\")\n", " return True\n", " return False\n", "\n", "# Step 6: Implement attack prevention\n", "def prevent_attack(node, destination):\n", " trust_threshold = 0.5\n", " trust_metric = calculate_trust_metric(node)\n", " if trust_metric >= trust_threshold:\n", " send_dao(node, destination)\n", " print(f\"Node {node} prevented sending data packets to malicious nodes.\")\n", " return True\n", " print(f\"Node {node} failed to prevent the attack.\")\n", " return False\n", "\n", "def prevent_malicious_node(node, destination):\n", " trust_threshold = 0.5\n", " trust_metric = calculate_trust_metric(node)\n", " if trust_metric >= trust_threshold:\n", " send_dao(node, destination)\n", " print(f\"Node {node} prevented sending data packets to a detected malicious node.\")\n", " return True\n", " print(f\"Node {node} failed to prevent the attack.\")\n", " return False\n", "\n", "def prevent_rank_attack(node, destination):\n", " trust_threshold = 0.5\n", " trust_metric = calculate_trust_metric(node)\n", " if trust_metric >= trust_threshold:\n", " send_dao(node, destination)\n", " print(f\"Node {node} prevented sending data packets to a node with lower rank.\")\n", " return True\n", " print(f\"Node {node} failed to prevent the attack.\")\n", " return False\n", "\n", "def prevent_blackhole_attack(node, destination):\n", " trust_threshold = 0.5\n", " trust_metric = calculate_trust_metric(node)\n", " if trust_metric >= trust_threshold:\n", " send_dao(node, destination)\n", " print(f\"Node {node} prevented sending data packets to a Blackhole node.\")\n", " return True\n", " print(f\"Node {node} failed to prevent the attack.\")\n", " return False\n", "\n", "# Step 7: Simulate attacks (Blackhole)\n", "def simulate_blackhole_attack():\n", " attacker_id = random.randint(num_nodes + 1, num_nodes + 100) # Random attacker ID\n", " G.add_node(attacker_id)\n", "\n", " # Connect attacker node to existing nodes\n", " target_nodes = list(G.nodes())\n", " target_nodes.remove(attacker_id)\n", " for target in target_nodes:\n", " G.add_edge(attacker_id, target)\n", "\n", "def detect_blackhole_attack(node):\n", " attacker_ids = [attacker for attacker in G.nodes() if attacker > num_nodes]\n", " if node in attacker_ids:\n", " print(f\"Node {node} is under Blackhole attack.\")\n", " return True\n", " return False\n", "\n", "# Step 8: Simulate attacks (Rank)\n", "def simulate_rank_attack():\n", " attacker_id = random.randint(num_nodes + 1, num_nodes + 100) # Random attacker ID\n", " G.add_node(attacker_id)\n", "\n", " # Connect attacker node to existing nodes\n", " target_nodes = list(G.nodes())\n", " target_nodes.remove(attacker_id)\n", " for _ in range(3): # Each attacker node connects to 3 existing nodes\n", " target = random.choice(target_nodes)\n", " G.add_edge(attacker_id, target)\n", " target_nodes.remove(target)\n", "\n", "def detect_rank_attack(node):\n", " attacker_ids = [attacker for attacker in G.nodes() if attacker > num_nodes]\n", " if node in attacker_ids:\n", " print(f\"Node {node} is potentially under Rank attack.\")\n", " return True\n", " return False\n", "\n", "# Simulation and data collection\n", "num_simulations = 4\n", "total_sybil_attacks = 0\n", "total_blackhole_attacks = 0\n", "total_rank_attacks = 0\n", "\n", "total_prevented_sybil_attacks = 0\n", "total_prevented_blackhole_attacks = 0\n", "total_prevented_rank_attacks = 0\n", "\n", "attack_detected = []\n", "attack_prevented = []\n", "\n", "# Run the simulations\n", "for _ in range(num_simulations):\n", " G = nx.Graph() # Reset the network for each simulation\n", " G.add_nodes_from(range(1, num_nodes + 1))\n", " G.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 5), (5, 1)])\n", "\n", " simulate_sybil_attack()\n", " simulate_blackhole_attack()\n", " simulate_rank_attack()\n", "\n", " # Run the MRTS algorithm for each node in the network\n", " for node in G.nodes():\n", " send_dio(node)\n", " send_dis(node)\n", " trust_metric = calculate_trust_metric(node)\n", " updated_trust_metric = update_trust_metric(node)\n", " energy_consumption = calculate_energy_consumption(node)\n", " print(f\"Node {node} trust metric: {trust_metric}\")\n", " print(f\"Node {node} updated trust metric: {updated_trust_metric}\")\n", " print(f\"Node {node} energy consumption: {energy_consumption}\")\n", "\n", " # Detect Sybil attacks\n", " if detect_sybil_attack(node):\n", " attack_detected.append(node)\n", " total_sybil_attacks += 1\n", "\n", " # Detect Blackhole attacks\n", " if detect_blackhole_attack(node):\n", " attack_detected.append(node)\n", " total_blackhole_attacks += 1\n", "\n", " # Detect Rank attacks\n", " if detect_rank_attack(node):\n", " attack_detected.append(node)\n", " total_rank_attacks += 1\n", "\n", " # Detect and prevent attacks\n", " destination = random.choice(list(G.nodes()))\n", "\n", " # Prevent Sybil attacks\n", " if detect_sybil_attack(node):\n", " if prevent_malicious_node(node, destination):\n", " attack_prevented.append(node)\n", " total_prevented_sybil_attacks += 1\n", "\n", " # Prevent Blackhole attacks\n", " if detect_blackhole_attack(node):\n", " if prevent_blackhole_attack(node, destination):\n", " attack_prevented.append(node)\n", " total_prevented_blackhole_attacks += 1\n", "\n", " # Prevent Rank attacks\n", " if detect_rank_attack(node):\n", " if prevent_rank_attack(node, destination):\n", " attack_prevented.append(node)\n", " total_prevented_rank_attacks += 1\n", "\n", " # Normal operation, no attack detected\n", " send_dao(node, destination)\n", "\n", "# Generate a graph for total attacks vs prevented attacks\n", "x = np.arange(3)\n", "total_attacks = [total_sybil_attacks, total_blackhole_attacks, total_rank_attacks]\n", "total_prevented_attacks = [total_prevented_sybil_attacks, total_prevented_blackhole_attacks, total_prevented_rank_attacks]\n", "\n", "plt.figure(figsize=(8, 6))\n", "plt.bar(x, total_attacks, label='Attacks')\n", "plt.bar(x, total_prevented_attacks, label='Prevented Attacks', alpha=0.7)\n", "plt.xticks(x, ['Sybil', 'Blackhole', 'Rank'])\n", "plt.xlabel('Type of Attacks')\n", "plt.ylabel('Number of Occurrences')\n", "plt.title('Total Attacks vs Prevented Attacks')\n", "plt.legend()\n", "plt.grid(True)\n", "plt.show()\n" ] } ] }