not able to send the spoofed packet(MAC ID spoofinng) to the RSU

61 views
Skip to first unread message

Vinit Kumar Patel

unread,
Sep 30, 2024, 9:04:26 PM9/30/24
to ns-3-users
I am trying to simulate the sybil attack and detection in ns3. i can't send the  mac ID spoofed packets to the RSU, can someone help?
i am providing you the code and the output below

#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/mobility-module.h"
#include "ns3/wave-module.h"
#include "ns3/netanim-module.h"
#include <iostream>
#include <map>
#include <string>
#include <random>

using namespace ns3;
using namespace std;

// Custom data structure to hold group signature information.
struct GroupSignature {
string signature; // Simulated group signature (Boneh-Shacham)
string vehicleId; // Vehicle ID (e.g., V1, A1, S1)
string macAddress; // MAC Address (actual or spoofed, without prefix)
};

// Global maps to store signatures and sybil detection status
// RSU will maintain the signature store
map<pair<string, string>, GroupSignature> signatureStore; // Map (Vehicle ID, MAC Address) -> GroupSignature

// Map to detect attacker and sybil nodes: (MAC ID, Vehicle ID, attacker/sybil)
map<pair<string, string>, string> Detected; // (MAC ID, Vehicle ID) -> "attacker" or "sybil"

void LogSignatureStore() {
for (const auto& entry : signatureStore) {
cout << "Vehicle ID: " << entry.first.first
<< " | MAC Address: " << entry.first.second
<< " | Signature: " << entry.second.signature << endl;
}
cout<<"*******************"<<endl;
for (const auto& entry : Detected) {
cout << "MAC Address: " << entry.first.first
<< " | Vehicle ID: " << entry.first.second
<< " | Type: " << entry.second << endl;
}
}

// Utility function to simulate group signature generation
string GenerateGroupSignature(string privateKey, string message) {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<> dis(0, 100);
int randomNumber = dis(gen);
// Create the group signature with privateKey, randomNumber, and message
ostringstream oss;
oss << privateKey << "_SIGN_" << randomNumber << "_" << message;
return oss.str();
}

// Function to check if two signatures are linked cryptographically
bool AreSignaturesLinked(GroupSignature sig1, GroupSignature sig2) {
return sig1.signature.substr(0, sig1.signature.find("_SIGN_")) ==
sig2.signature.substr(0, sig2.signature.find("_SIGN_"));
}

// Sybil detection based on group signature comparison and MAC spoofing detection at RSU
bool DetectSybilAttack(string vehicleId, string receivedMac, GroupSignature newSignature) {
for (const auto& entry : signatureStore) {
// Check if the same group signature is being used by different MAC addresses or vehicle IDs
if (AreSignaturesLinked(entry.second, newSignature)) {
if (entry.first.second != receivedMac) { // Compare MAC addresses
// Entry found with linked signature but different MAC: Sybil attack!
cout << "[SYBIL DETECTED] Vehicle ID: " << vehicleId << " is using multiple MAC addresses!" << endl;

// Mark the matched entry as attacker
Detected[make_pair(entry.first.second, entry.first.first)] = "attacker";

// Mark the current vehicle as Sybil
Detected[make_pair(receivedMac, vehicleId)] = "sybil";

return true;
}
}
}
return false;
}


// Callback to handle Wave Short Messages (WSMs) received by RSU
bool ReceivePacketForRSU(Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address& from) {
Ptr<Node> receivingNode = device->GetNode();
uint32_t receiverNodeId = receivingNode->GetId(); // Get the node ID

ostringstream receiverNodeNameStream;
receiverNodeNameStream << "Node-" << receiverNodeId;
string receiverNodeName = receiverNodeNameStream.str();

if (Mac48Address::IsMatchingType(from)) {
Mac48Address macAddr = Mac48Address::ConvertFrom(from); // Handle MAC address
ostringstream oss;
oss << macAddr;
string receivedMac = oss.str(); // Full MAC with prefix
string macWithoutPrefix = receivedMac.substr(6, 17); // Remove prefix for comparison

uint8_t buffer[100];
packet->CopyData(buffer, packet->GetSize());
string packetContent = string(buffer, buffer + packet->GetSize());

// Extract vehicle ID, signature, and message from the packet content
string vehicleId = packetContent.substr(0, 2); // First 2 chars are Vehicle ID
size_t space1 = packetContent.find(" ", 3); // Find the first space after the vehicle ID
string signature = packetContent.substr(3, space1 - 3); // Extract the signature
string message = packetContent.substr(space1 + 1); // The rest is the message

// Log detailed packet content
cout << "[RECEIVE] RSU " << receiverNodeName << " received packet details:"
<< "\n Vehicle ID: " << vehicleId
<< "\n Signature: " << signature
<< "\n Message: " << message
<< "\n MAC Address: " << receivedMac << endl;

// Check for linked signature in store
GroupSignature newSignature = {signature, vehicleId, macWithoutPrefix};

// Sybil detection
bool sybilDetected = DetectSybilAttack(vehicleId, macWithoutPrefix, newSignature);
if (!sybilDetected) {
// First-time communication or repeated communication with the same MAC
bool found = false;
for (auto& entry : signatureStore) {
if (AreSignaturesLinked(entry.second, newSignature)) {
// Found a linked signature: Check MAC
found = true;
if (entry.first.second == macWithoutPrefix) {
// Same vehicle communicating again, update the entry
signatureStore.erase(entry.first); // Remove old entry
signatureStore[make_pair(vehicleId, macWithoutPrefix)] = newSignature; // Add updated entry
cout << "[UPDATE] RSU updated signature for Vehicle ID: " << vehicleId << endl;
}
}
}

if (!found) {
// No linked signature found, add a new entry for first-time communication
signatureStore[make_pair(vehicleId, macWithoutPrefix)] = newSignature;
cout << "[NEW] RSU created new entry for Vehicle ID: " << vehicleId << endl;
}
} else {
// Sybil detected, do not add to signature store
cout << "[IGNORE] Sybil packet detected, not added to signature store." << endl;
}
} else {
cout << "[RECEIVE] RSU received a packet with non-MAC address type" << endl;
}

return true;
}

// Callback function for promiscuous packet reception
bool PromiscReceivePacket(Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address& sender, const Address& receiver, NetDevice::PacketType packetType) {
cout << "[PROMISC-RECEIVE] RSU received a packet in promiscuous mode." << endl;
cout << "Sender MAC: " << Mac48Address::ConvertFrom(sender) << endl;
cout << "Receiver MAC: " << Mac48Address::ConvertFrom(receiver) << endl;
cout << "Packet Type: " << packetType << endl;

// You can now pass the packet to your existing ReceivePacketForRSU logic if desired.
return ReceivePacketForRSU(device, packet, protocol, sender);
}

// Simple packet receive handler for vehicles (no Sybil detection for vehicles)
bool ReceivePacketForVehicle(Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address& from) {
Ptr<Node> receivingNode = device->GetNode();
uint32_t receiverNodeId = receivingNode->GetId(); // Get the node ID

ostringstream receiverNodeNameStream;
receiverNodeNameStream << "Node-" << receiverNodeId;
string receiverNodeName = receiverNodeNameStream.str();
if (Mac48Address::IsMatchingType(from)) {
uint8_t buffer[100];
packet->CopyData(buffer, packet->GetSize());
string packetContent = string(buffer, buffer + packet->GetSize());
string vehicleId = packetContent.substr(0, 2); // First 2 chars are Vehicle ID
string message = packetContent.substr(3); // Rest is the message content

if (message == "beacon") {
cout << "[RECEIVE] " << receiverNodeName << " processed beacon packet from node " << vehicleId << endl;
} else {
cout << "[RECEIVE] " << receiverNodeName << " processed normal packet from node " << vehicleId << endl;
}
} else {
cout << "Received packet with non-MAC address type" << endl;
}

return true;
}

// Function to send a Wave Short Message (WSM) with the signature included in the message
void SendWavePacket(Ptr<WaveNetDevice> device, string vehicleId, string message, string privateKey, Ipv4Address destination) {
// Generate signature based on private key and message
string signature = GenerateGroupSignature(privateKey, message);
ostringstream oss;
oss << device->GetAddress(); // Get MAC address of the device
string actualMac = oss.str().substr(6, 17); // Get MAC address without prefix
string formattedMacWithPrefix = oss.str(); // MAC address with prefix
if (vehicleId == "S1") {
// Spoof the MAC address for vehicle ID 'S1'
string spoofedMac = "00:00:00:00:00:12"; // Example spoofed MAC address
Mac48Address spoofedMacAddr(spoofedMac.c_str());
formattedMacWithPrefix.replace(0, 23, spoofedMac); // Maintain prefix, replace MAC part
cout << "[SPOOFED] Vehicle ID: " << vehicleId << " using spoofed MAC: " << formattedMacWithPrefix << endl;
// Include vehicle ID, message, and signature in the packet content
string packetContent = vehicleId + " " + signature + " " + message;
Ptr<Packet> packet = Create<Packet>(reinterpret_cast<const uint8_t*>(packetContent.c_str()), packetContent.size());

// Use SendFrom with the spoofed MAC address
if (device->SendFrom(packet, spoofedMacAddr, Mac48Address::GetBroadcast(), 0x88DC)) {
cout << "[SEND] Node " << vehicleId << " transmitted " << message << " with signature " << signature << " and spoofed MAC " << spoofedMac << endl;
} else {
cout << "[ERROR] Failed to send packet from Node " << vehicleId << " with spoofed MAC " << spoofedMac << endl;
}

} else {
// Normal case: Use actual MAC (without prefix)
string packetContent = vehicleId + " " + signature + " " + message;
Ptr<Packet> packet = Create<Packet>(reinterpret_cast<const uint8_t*>(packetContent.c_str()), packetContent.size());

// Send normally with the actual MAC using SendX
TxInfo txInfo;
txInfo.channelNumber = CCH; // Control Channel for WAVE
txInfo.priority = 7;
cout<<device->SendX(packet, Mac48Address::GetBroadcast(), 0x88DC, txInfo);
cout << "[SEND] Node " << vehicleId << " transmitted " << message << " with signature " << signature << " and actual MAC " << formattedMacWithPrefix << endl;
}
}


// Function to simulate the TRSU assigning private keys
string RegisterVehicleAtTRSU(string vehicleId) {
cout << "[REGISTER] TRSU T1 assigned private key to node " << vehicleId << endl;
return "PrivateKey_" + vehicleId; // Simulated private key generation
}

int main(int argc, char* argv[]) {
// LogComponentEnable("WaveNetDevice", LOG_LEVEL_ALL);
// LogComponentEnable("YansWifiPhy", LOG_LEVEL_ALL);
// LogComponentEnable("WifiMac", LOG_LEVEL_ALL);

uint32_t simTime = 20;
uint32_t vehCount = 2; // 2 vehicles: V1 and A1

NodeContainer vehicles;
vehicles.Create(vehCount); // V1 and A1

NodeContainer rsuNodes;
rsuNodes.Create(2); // TRSU (T1) and RSU (R1)

// Install mobility
MobilityHelper mobility;
mobility.SetPositionAllocator("ns3::GridPositionAllocator",
"MinX", DoubleValue(0.0),
"MinY", DoubleValue(0.0),
"DeltaX", DoubleValue(5.0),
"DeltaY", DoubleValue(10.0),
"GridWidth", UintegerValue(2),
"LayoutType", StringValue("RowFirst"));
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
mobility.Install(vehicles);
mobility.Install(rsuNodes);

// Install WAVE devices on RSU and vehicles
YansWifiChannelHelper waveChannel = YansWifiChannelHelper::Default();
YansWavePhyHelper wavePhy = YansWavePhyHelper::Default();
wavePhy.SetChannel(waveChannel.Create());

QosWaveMacHelper waveMac = QosWaveMacHelper::Default();
WaveHelper waveHelper = WaveHelper::Default();

NetDeviceContainer vehicleDevices = waveHelper.Install(wavePhy, waveMac, vehicles);
NetDeviceContainer rsuDevices = waveHelper.Install(wavePhy, waveMac, rsuNodes);

// Assign IP addresses
InternetStackHelper internet;
internet.Install(vehicles);
internet.Install(rsuNodes);

Ipv4AddressHelper ipv4;
ipv4.SetBase("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer vehicleInterfaces = ipv4.Assign(vehicleDevices);
Ipv4InterfaceContainer rsuInterfaces = ipv4.Assign(rsuDevices);

// Set RSU to receive Wave Short Messages (WSM)
Ptr<WaveNetDevice> rsuWaveDevice = DynamicCast<WaveNetDevice>(rsuDevices.Get(1));
rsuWaveDevice->SetReceiveCallback(MakeCallback(&ReceivePacketForRSU));
// Enable promiscuous mode by setting the promiscuous receive callback
rsuWaveDevice->SetPromiscReceiveCallback(MakeCallback(&PromiscReceivePacket)); // Enable promiscuous mode

// Vehicle Registration (Private Key Distribution)
string privateKeyV1 = RegisterVehicleAtTRSU("V1");
string privateKeyA1 = RegisterVehicleAtTRSU("A1");

// Schedule beacon and normal message transmissions with signatures
Ptr<WaveNetDevice> v1WaveDevice = DynamicCast<WaveNetDevice>(vehicleDevices.Get(0));
Ptr<WaveNetDevice> a1WaveDevice = DynamicCast<WaveNetDevice>(vehicleDevices.Get(1));
Simulator::Schedule(Seconds(2.0), &SendWavePacket, v1WaveDevice, "V1", "beacon", privateKeyV1, Ipv4Address("255.255.255.255"));
Simulator::Schedule(Seconds(4.0), &SendWavePacket, a1WaveDevice, "A1", "beacon", privateKeyA1, Ipv4Address("255.255.255.255"));

// Attacker A1 sends packets on behalf of Sybil node S1 with spoofed MAC
Simulator::Schedule(Seconds(6.0), &SendWavePacket, a1WaveDevice, "S1", "beacon", privateKeyA1, Ipv4Address("255.255.255.255"));

Simulator::Schedule(Seconds(8.0), &SendWavePacket, v1WaveDevice, "V1", "normal", privateKeyV1, Ipv4Address("255.255.255.255"));
Simulator::Schedule(Seconds(10.0), &SendWavePacket, a1WaveDevice, "A1", "normal", privateKeyA1, Ipv4Address("255.255.255.255"));

// Attacker A1 sends packets on behalf of Sybil node S1 with spoofed MAC
Simulator::Schedule(Seconds(12.0), &SendWavePacket, a1WaveDevice, "S1", "normal", privateKeyA1, Ipv4Address("255.255.255.255"));

// Run the simulation
Simulator::Stop(Seconds(simTime));
Simulator::Run();
Simulator::Destroy();


return 0;
}

================OUTPUT===========
[REGISTER] TRSU T1 assigned private key to node V1
[REGISTER] TRSU T1 assigned private key to node A1
1[SEND] Node V1 transmitted beacon with signature PrivateKey_V1_SIGN_71_beacon and actual MAC 02-06-00:00:00:00:00:08
[RECEIVE] RSU Node-3 received packet details:
  Vehicle ID: V1
  Signature: PrivateKey_V1_SIGN_71_beacon
  Message: beacon
  MAC Address: 00:00:00:00:00:08
[NEW] RSU created new entry for Vehicle ID: V1
[PROMISC-RECEIVE] RSU received a packet in promiscuous mode.
Sender MAC: 00:00:00:00:00:08
Receiver MAC: ff:ff:ff:ff:ff:ff
Packet Type: 2
[RECEIVE] RSU Node-3 received packet details:
  Vehicle ID: V1
  Signature: PrivateKey_V1_SIGN_71_beacon
  Message: beacon
  MAC Address: 00:00:00:00:00:08
[UPDATE] RSU updated signature for Vehicle ID: V1
1[SEND] Node A1 transmitted beacon with signature PrivateKey_A1_SIGN_89_beacon and actual MAC 02-06-00:00:00:00:00:10
[RECEIVE] RSU Node-3 received packet details:
  Vehicle ID: A1
  Signature: PrivateKey_A1_SIGN_89_beacon
  Message: beacon
  MAC Address: 00:00:00:00:00:10
[NEW] RSU created new entry for Vehicle ID: A1
[PROMISC-RECEIVE] RSU received a packet in promiscuous mode.
Sender MAC: 00:00:00:00:00:10
Receiver MAC: ff:ff:ff:ff:ff:ff
Packet Type: 2
[RECEIVE] RSU Node-3 received packet details:
  Vehicle ID: A1
  Signature: PrivateKey_A1_SIGN_89_beacon
  Message: beacon
  MAC Address: 00:00:00:00:00:10
[UPDATE] RSU updated signature for Vehicle ID: A1
[SPOOFED] Vehicle ID: S1 using spoofed MAC: 00:00:00:00:00:12
[ERROR] Failed to send packet from Node S1 with spoofed MAC 00:00:00:00:00:12
1[SEND] Node V1 transmitted normal with signature PrivateKey_V1_SIGN_3_normal and actual MAC 02-06-00:00:00:00:00:08
[RECEIVE] RSU Node-3 received packet details:
  Vehicle ID: V1
  Signature: PrivateKey_V1_SIGN_3_normal
  Message: normal
  MAC Address: 00:00:00:00:00:08
[UPDATE] RSU updated signature for Vehicle ID: V1
[PROMISC-RECEIVE] RSU received a packet in promiscuous mode.
Sender MAC: 00:00:00:00:00:08
Receiver MAC: ff:ff:ff:ff:ff:ff
Packet Type: 2
[RECEIVE] RSU Node-3 received packet details:
  Vehicle ID: V1
  Signature: PrivateKey_V1_SIGN_3_normal
  Message: normal
  MAC Address: 00:00:00:00:00:08
[UPDATE] RSU updated signature for Vehicle ID: V1
1[SEND] Node A1 transmitted normal with signature PrivateKey_A1_SIGN_40_normal and actual MAC 02-06-00:00:00:00:00:10
[RECEIVE] RSU Node-3 received packet details:
  Vehicle ID: A1
  Signature: PrivateKey_A1_SIGN_40_normal
  Message: normal
  MAC Address: 00:00:00:00:00:10
[UPDATE] RSU updated signature for Vehicle ID: A1
[PROMISC-RECEIVE] RSU received a packet in promiscuous mode.
Sender MAC: 00:00:00:00:00:10
Receiver MAC: ff:ff:ff:ff:ff:ff
Packet Type: 2
[RECEIVE] RSU Node-3 received packet details:
  Vehicle ID: A1
  Signature: PrivateKey_A1_SIGN_40_normal
  Message: normal
  MAC Address: 00:00:00:00:00:10
[UPDATE] RSU updated signature for Vehicle ID: A1
[SPOOFED] Vehicle ID: S1 using spoofed MAC: 00:00:00:00:00:12
[ERROR] Failed to send packet from Node S1 with spoofed MAC 00:00:00:00:00:12

Tommaso Pecorella

unread,
Oct 2, 2024, 6:05:10 PM10/2/24
to ns-3-users
You have to check the function NetDevice::SupportsSendFrom().
If it does return false, the NetDevice (or the MAC) can't use any MAC address other than the one the NetDevice is currently set to. I.e., SendFrom will work, but only if you use the MAC address of the NetDevice (i.e, it's useless because it's equivalent to Send).

What you can do (if needed) is to create a NetDeive and force its MAC address to the one you want to spoof, and then use Send.

Vinit Kumar Patel

unread,
Oct 2, 2024, 8:43:51 PM10/2/24
to ns-3-users
Thanks, i did the same and it's working.

Vinit Kumar Patel

unread,
Jun 16, 2025, 6:14:47 AM6/16/25
to ns-3-users
Hello,

how to changethe txpowerstart at the runtime in Ptr<WifiPhy>?
actually i am making it using yanswifiphyhelper,
YansWifiPhyHelper wifiPhy;
wifiPhy.Set("TxPowerStart", DoubleValue(txStart));
wifiPhy.Set("TxPowerEnd", DoubleValue(txEnd));
wifiPhy.Set("TxPowerLevels", UintegerValue(levels));
wifiPhy.SetChannel(channel.Create());

Actually, i am working on sybil attack detection using rssi. i needed to make changes at runtime on transmission power to fabricate the sybil attack.
I noticed that no matter what txpowerlevel i choose the transmission only happen at the powerstart dbm which was set initially, which very strange to me.
so i thought let me chnage the powerstart at runtime but i couldn't.

can someone give suggestion on how can i transmit packet on desired power and not on txpowerstart bydefault?
or can you give me advice on how to change txpowerstart at runtime?
or some other way which can work in this scenario.
Reply all
Reply to author
Forward
0 new messages