Update README and add contrib dir

This commit is contained in:
2025-12-01 15:56:02 +01:00
parent 1b80de2153
commit cd9ba93d58
150 changed files with 25563 additions and 0 deletions

View File

@@ -0,0 +1,27 @@
check_include_file_cxx(stdint.h HAVE_STDINT_H)
if(HAVE_STDINT_H)
add_definitions(-DHAVE_STDINT_H)
endif()
set(examples_as_tests_sources)
if(${ENABLE_EXAMPLES})
set(examples_as_tests_sources
#test/traffic-generator-examples-test-suite.cc
)
endif()
build_lib(
LIBNAME traffic-generator
SOURCE_FILES model/traffic-generator.cc
model/ethernet-generator.cc
model/myCustomApp.cc
helper/traffic-generator-helper.cc
HEADER_FILES model/traffic-generator.h
model/ethernet-generator.h
model/myCustomApp.h
helper/traffic-generator-helper.h
LIBRARIES_TO_LINK ${libcore}
${libethernet}
TEST_SOURCES test/traffic-generator-test-suite.cc
${examples_as_tests_sources}
)

View File

@@ -0,0 +1,7 @@
build_lib_example(
NAME traffic-generator-ethernet
SOURCE_FILES traffic-generator-ethernet.cc
LIBRARIES_TO_LINK ${libcore}
${libnetwork}
${libethernet}
)

View File

@@ -0,0 +1,82 @@
#include "ns3/core-module.h"
#include "ns3/applications-module.h"
#include "ns3/command-line.h"
#include "ns3/simulator.h"
#include "ns3/node.h"
#include "ns3/drop-tail-queue.h"
#include "ns3/ethernet-net-device.h"
#include "ns3/ethernet-channel.h"
#include "ns3/ethernet-generator.h"
#include "ns3/ethernet-header2.h"
/**
* \file
*
* Example of the use of ethernet-generator.cc on a network composed of two
* ethernet end-stations
* ES1 ====== ES2
*/
using namespace ns3;
int
main(int argc, char* argv[])
{
//Enable logging
LogComponentEnable("EthernetGenerator", LOG_LEVEL_INFO);
CommandLine cmd(__FILE__);
cmd.Parse(argc, argv);
//Create two nodes
Ptr<Node> n0 = CreateObject<Node>();
Names::Add("ES1", n0);
Ptr<Node> n1 = CreateObject<Node>();
Names::Add("ES2", n1);
//Create and add a netDevice to each node
Ptr<EthernetNetDevice> net0 = CreateObject<EthernetNetDevice>();
n0->AddDevice(net0);
Names::Add("ES1#01", net0);
Ptr<EthernetNetDevice> net1 = CreateObject<EthernetNetDevice>();
n1->AddDevice(net1);
Names::Add("ES2#01", net1);
//Create a Ethernet Channel and attach it two the two netDevices
Ptr<EthernetChannel> channel = CreateObject<EthernetChannel>();
net0->Attach(channel);
net1->Attach(channel);
//Allocate a Mac address and create two FIFO (for the output port)
//for each netDevice.
net0->SetAddress(Mac48Address::Allocate());
net0->SetQueue(CreateObject<DropTailQueue<Packet>>());
net0->SetQueue(CreateObject<DropTailQueue<Packet>>());
net1->SetAddress(Mac48Address::Allocate());
net1->SetQueue(CreateObject<DropTailQueue<Packet>>());
net1->SetQueue(CreateObject<DropTailQueue<Packet>>());
//Application description
Ptr<EthernetGenerator> app0 = CreateObject<EthernetGenerator>();
app0->Setup(net0);
app0->SetAttribute("Address", AddressValue(net1->GetAddress()));
app0->SetAttribute("BurstSize", UintegerValue(2));
app0->SetAttribute("PayloadSize", UintegerValue(1400));
app0->SetAttribute("Period", TimeValue(Seconds(5)));
app0->SetAttribute("InterFrame", TimeValue(MilliSeconds(200)));
app0->SetAttribute("Offset", TimeValue(MilliSeconds(100)));
app0->SetAttribute("VlanID", UintegerValue(100));
app0->SetAttribute("PCP", UintegerValue(0));
n0->AddApplication(app0);
app0->SetStartTime(Seconds(0));
app0->SetStopTime(Seconds(10));
//Execute the simulation
Simulator::Stop(Seconds(10));
Simulator::Run();
Simulator::Destroy();
return 0;
}

View File

@@ -0,0 +1,8 @@
#include "traffic-generator-helper.h"
namespace ns3
{
/* ... */
}

View File

@@ -0,0 +1,16 @@
#ifndef TRAFFIC_GENERATOR_HELPER_H
#define TRAFFIC_GENERATOR_HELPER_H
#include "ns3/traffic-generator.h"
namespace ns3
{
// Each class should be documented using Doxygen,
// and have an \ingroup traffic-generator directive
/* ... */
}
#endif /* TRAFFIC_GENERATOR_HELPER_H */

View File

@@ -0,0 +1,153 @@
#include "ethernet-generator.h"
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
#include "ns3/socket.h"
#include "ns3/uinteger.h"
#include "ns3/names.h"
#include "ns3/ethernet-net-device.h"
#include <cstdio>
#include <cstdlib>
namespace ns3
{
NS_LOG_COMPONENT_DEFINE("EthernetGenerator");
NS_OBJECT_ENSURE_REGISTERED(EthernetGenerator);
TypeId
EthernetGenerator::GetTypeId()
{
static TypeId tid =
TypeId("ns3::EthernetGenerator")
.SetParent<Application>()
.SetGroupName("Applications")
.AddConstructor<EthernetGenerator>()
.AddAttribute("Address",
"Destination Mac Address",
AddressValue(Mac48Address("ff:ff:ff:ff:ff:ff")),
MakeAddressAccessor(&EthernetGenerator::m_destAddress),
MakeAddressChecker())
.AddAttribute("PayloadSize",
"Payload Size in bytes",
UintegerValue(100),
MakeUintegerAccessor(&EthernetGenerator::m_payload_size),
MakeUintegerChecker<uint16_t>())
.AddAttribute("BurstSize",
"Burst size",
UintegerValue(1),
MakeUintegerAccessor(&EthernetGenerator::m_burst_size),
MakeUintegerChecker<uint16_t>())
.AddAttribute("Period",
"Period between burst",
TimeValue(Seconds(1)),
MakeTimeAccessor(&EthernetGenerator::m_period),
MakeTimeChecker())
.AddAttribute("InterFrame",
"Period between two packet of a burst",
TimeValue(Seconds(0)),
MakeTimeAccessor(&EthernetGenerator::m_interframe),
MakeTimeChecker())
.AddAttribute("Offset",
"Time offset between application start and first packet emission",
TimeValue(Seconds(0)),
MakeTimeAccessor(&EthernetGenerator::m_offset),
MakeTimeChecker())
.AddAttribute("VlanID",
"Vlan ID",
UintegerValue(65535),
MakeUintegerAccessor(&EthernetGenerator::m_vid),
MakeUintegerChecker<uint16_t>())
.AddAttribute("PCP",
"PCP field",
UintegerValue(0),
MakeUintegerAccessor(&EthernetGenerator::m_pcp),
MakeUintegerChecker<uint8_t>())
.AddAttribute("DEI",
"DEI bit",
UintegerValue(0),
MakeUintegerAccessor(&EthernetGenerator::m_dei),
MakeUintegerChecker<uint8_t>())
.AddTraceSource("PktSent",
"Trace source indicating a packet was given to the netDevice"
"by the application",
MakeTraceSourceAccessor(&EthernetGenerator::m_pktSentTrace),
"ns3::EthernetGenerator::PacketVlanTraceCallback");
return tid;
}
EthernetGenerator::EthernetGenerator()
{
NS_LOG_FUNCTION(this);
m_net = nullptr;
}
EthernetGenerator::~EthernetGenerator()
{
NS_LOG_FUNCTION(this);
}
void
EthernetGenerator::Setup(Ptr<EthernetNetDevice> net)
{
m_net = net;
}
void
EthernetGenerator::DoDispose()
{
NS_LOG_FUNCTION(this);
Application::DoDispose();
}
void
EthernetGenerator::StartApplication()
{
NS_LOG_FUNCTION(this);
if (m_vid==65535 && m_payload_size < MIN_PAYLOAD_SIZE + 4){
m_payload_size = MIN_PAYLOAD_SIZE + 4;
}
else if(m_payload_size < MIN_PAYLOAD_SIZE){
m_payload_size = MIN_PAYLOAD_SIZE;
}
m_sendEvent = Simulator::Schedule(m_offset, &EthernetGenerator::SendBurst, this);
}
void
EthernetGenerator::StopApplication()
{
NS_LOG_FUNCTION(this);
Simulator::Cancel(m_sendEvent);
}
void
EthernetGenerator::SendBurst()
{
NS_LOG_FUNCTION(this);
for (int i = 0; i < m_burst_size; i++) {
Simulator::Schedule(m_interframe*i, &EthernetGenerator::Send, this);
}
m_sendEvent = Simulator::Schedule(m_period, &EthernetGenerator::SendBurst, this);
}
void
EthernetGenerator::Send()
{
NS_LOG_FUNCTION(this);
Ptr<Packet> p = Create<Packet>(m_payload_size);
//NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << Names::FindName(m_net->GetNode()) << "/" << Names::FindName(m_net) <<" : Pkt #" << p->GetUid() <<"(vid="<< m_vid <<") given to the netDevice ! " << p->ToString());
if (m_vid==65535){
m_net->Send(p, m_destAddress, 0xEDE1);
}
else{
m_net->Send(p, m_destAddress, 0xEDE1, m_vid, m_pcp, m_dei);
}
m_pktSentTrace(p, m_vid);
}
} // Namespace ns3

View File

@@ -0,0 +1,72 @@
#ifndef ETHERNET_GENERATOR_H
#define ETHERNET_GENERATOR_H
#include "ns3/application.h"
#include "ns3/event-id.h"
#include "ns3/ptr.h"
#include <ns3/traced-callback.h>
#include "ns3/ethernet-net-device.h"
namespace ns3
{
class Socket;
class Packet;
class EthernetGenerator : public Application
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId();
EthernetGenerator();
~EthernetGenerator() override;
/**
* \return the total bytes sent by this app
*/
void Setup(Ptr<EthernetNetDevice> net);
typedef TracedCallback<Ptr<const Packet>, uint16_t> PacketVlanTraceCallback;
protected:
void DoDispose() override;
private:
void StartApplication() override;
void StopApplication() override;
/**
* \brief Send a packet
*/
void SendBurst();
void Send();
Address m_destAddress;
int m_payload_size;
int m_burst_size;
Time m_period;
Time m_interframe;
Time m_offset;
uint16_t m_vid;
uint8_t m_pcp;
uint8_t m_dei;
EventId m_sendEvent; //!< Event to send the next packet
Ptr<EthernetNetDevice> m_net;
PacketVlanTraceCallback m_pktSentTrace;
static const uint16_t MIN_PAYLOAD_SIZE = 42; //Min payload size with VLAN
};
} // namespace ns3
#endif

View File

@@ -0,0 +1,119 @@
#include "myCustomApp.h"
#include "ns3/log.h"
#include "ns3/simulator.h"
#include "ns3/socket-factory.h"
#include "ns3/socket.h"
#include "ns3/uinteger.h"
#include "ns3/names.h"
#include "ns3/point-to-point-net-device.h"
#include <cstdio>
#include <cstdlib>
namespace ns3
{
NS_LOG_COMPONENT_DEFINE("myCustomApp");
NS_OBJECT_ENSURE_REGISTERED(myCustomApp);
TypeId
myCustomApp::GetTypeId()
{
static TypeId tid =
TypeId("ns3::myCustomApp")
.SetParent<Application>()
.SetGroupName("Applications")
.AddConstructor<myCustomApp>();
return tid;
}
myCustomApp::myCustomApp()
{
NS_LOG_FUNCTION(this);
m_sent = 0;
m_totalTx = 0;
m_totalRx = 0;
m_sendEvent = EventId();
}
myCustomApp::~myCustomApp()
{
NS_LOG_FUNCTION(this);
}
void
myCustomApp::Setup(Ptr<PointToPointNetDevice> net, int t)
{
m_net = net;
Packet::EnablePrinting();
m_sendEvent = Simulator::Schedule(Seconds(t), &myCustomApp::Send, this);
m_net->SetReceiveCallback(MakeCallback(&myCustomApp::RxPacket, this));
}
bool
myCustomApp::RxPacket(Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address& sender)
{
m_totalRx = m_totalRx + pkt->GetSize();
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << Names::FindName(m_net->GetNode()) << "/" << Names::FindName(m_net) <<" : Pkt rcvd ! " << pkt->ToString());
return true;
}
void
myCustomApp::DoDispose()
{
NS_LOG_FUNCTION(this);
Application::DoDispose();
}
void
myCustomApp::StartApplication()
{
NS_LOG_FUNCTION(this);
}
void
myCustomApp::StopApplication()
{
NS_LOG_FUNCTION(this);
Simulator::Cancel(m_sendEvent);
NS_LOG_INFO("\tNb bytes rcvd :" << GetTotalRx());
}
void
myCustomApp::Send()
{
NS_LOG_FUNCTION(this);
NS_ASSERT(m_sendEvent.IsExpired());
uint8_t txBuffer[] = "\"Can you tell me where my country lies?\" \\ said the unifaun to his "
"true love's eyes. \\ \"It lies with me!\" cried the Queen of Maybe \\ - "
"for her merchandise, he traded in his prize.";
size_t txBufferSize = sizeof(txBuffer);
Ptr<Packet> p = Create<Packet>(txBuffer, txBufferSize);
NS_LOG_INFO((Simulator::Now()).As(Time::S) << " \t" << Names::FindName(m_net->GetNode()) << "/" << Names::FindName(m_net) <<" : Pkt sent ! " << p->ToString());
m_net->Send(p, m_net->GetBroadcast(), 0x800);
m_sendEvent = Simulator::Schedule(Seconds(2), &myCustomApp::Send, this);
}
uint64_t
myCustomApp::GetTotalTx() const
{
return m_totalTx;
}
uint64_t
myCustomApp::GetTotalRx() const
{
return m_totalRx;
}
} // Namespace ns3

View File

@@ -0,0 +1,66 @@
#ifndef MY_CUSTOM_APP_H
#define MY_CUSTOM_APP_H
#include "ns3/application.h"
#include "ns3/event-id.h"
#include "ns3/ptr.h"
#include <ns3/traced-callback.h>
#include "ns3/point-to-point-net-device.h"
namespace ns3
{
class Socket;
class Packet;
class myCustomApp : public Application
{
public:
/**
* \brief Get the type ID.
* \return the object TypeId
*/
static TypeId GetTypeId();
myCustomApp();
~myCustomApp() override;
/**
* \return the total bytes sent by this app
*/
uint64_t GetTotalTx() const;
uint64_t GetTotalRx() const;
void Setup(Ptr<PointToPointNetDevice> net, int t);
bool RxPacket(Ptr<NetDevice> dev, Ptr<const Packet> pkt, uint16_t mode, const Address& sender);
protected:
void DoDispose() override;
private:
void StartApplication() override;
void StopApplication() override;
/**
* \brief Send a packet
*/
void Send();
uint32_t m_count; //!< Maximum number of packets the application will send
Time m_interval; //!< Packet inter-send time
uint32_t m_size; //!< Size of the sent packet (including the SeqTsHeader)
uint32_t m_sent; //!< Counter for sent packets
uint64_t m_totalRx; //!< Total bytes sent
uint64_t m_totalTx; //!< Total bytes rcvd
Address m_peerAddress; //!< Remote peer address
uint16_t m_peerPort; //!< Remote peer port
EventId m_sendEvent; //!< Event to send the next packet
Ptr<PointToPointNetDevice> m_net;
};
} // namespace ns3
#endif

View File

@@ -0,0 +1,8 @@
#include "traffic-generator.h"
namespace ns3
{
/* ... */
}

View File

@@ -0,0 +1,20 @@
#ifndef TRAFFIC_GENERATOR_H
#define TRAFFIC_GENERATOR_H
// Add a doxygen group for this module.
// If you have more than one file, this should be in only one of them.
/**
* \defgroup traffic-generator Description of the traffic-generator
*/
namespace ns3
{
// Each class should be documented using Doxygen,
// and have an \ingroup traffic-generator directive
/* ... */
}
#endif /* TRAFFIC_GENERATOR_H */

View File

@@ -0,0 +1,19 @@
#! /usr/bin/env python3
# A list of C++ examples to run in order to ensure that they remain
# buildable and runnable over time. Each tuple in the list contains
#
# (example_name, do_run, do_valgrind_run).
#
# See test.py for more information.
cpp_examples = [
("traffic-generator-ethernet", "True", "True"),
]
# A list of Python examples to run in order to ensure that they remain
# runnable over time. Each tuple in the list contains
#
# (example_name, do_run).
#
# See test.py for more information.
python_examples = []

View File

@@ -0,0 +1,86 @@
// Include a header file from your module to test.
#include "ns3/traffic-generator.h"
// An essential include is test.h
#include "ns3/test.h"
// Do not put your test classes in namespace ns3. You may find it useful
// to use the using directive to access the ns3 namespace directly
using namespace ns3;
// Add a doxygen group for tests.
// If you have more than one test, this should be in only one of them.
/**
* \defgroup traffic-generator-tests Tests for traffic-generator
* \ingroup traffic-generator
* \ingroup tests
*/
// This is an example TestCase.
/**
* \ingroup traffic-generator-tests
* Test case for feature 1
*/
class TrafficGeneratorTestCase1 : public TestCase
{
public:
TrafficGeneratorTestCase1();
virtual ~TrafficGeneratorTestCase1();
private:
void DoRun() override;
};
// Add some help text to this case to describe what it is intended to test
TrafficGeneratorTestCase1::TrafficGeneratorTestCase1()
: TestCase("TrafficGenerator test case (does nothing)")
{
}
// This destructor does nothing but we include it as a reminder that
// the test case should clean up after itself
TrafficGeneratorTestCase1::~TrafficGeneratorTestCase1()
{
}
//
// This method is the pure virtual method from class TestCase that every
// TestCase must implement
//
void
TrafficGeneratorTestCase1::DoRun()
{
// A wide variety of test macros are available in src/core/test.h
NS_TEST_ASSERT_MSG_EQ(true, true, "true doesn't equal true for some reason");
// Use this one for floating point comparisons
NS_TEST_ASSERT_MSG_EQ_TOL(0.01, 0.01, 0.001, "Numbers are not equal within tolerance");
}
// The TestSuite class names the TestSuite, identifies what type of TestSuite,
// and enables the TestCases to be run. Typically, only the constructor for
// this class must be defined
/**
* \ingroup traffic-generator-tests
* TestSuite for module traffic-generator
*/
class TrafficGeneratorTestSuite : public TestSuite
{
public:
TrafficGeneratorTestSuite();
};
TrafficGeneratorTestSuite::TrafficGeneratorTestSuite()
: TestSuite("traffic-generator", UNIT)
{
// TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER
AddTestCase(new TrafficGeneratorTestCase1, TestCase::QUICK);
}
// Do not forget to allocate an instance of this TestSuite
/**
* \ingroup traffic-generator-tests
* Static variable for test initialization
*/
static TrafficGeneratorTestSuite strafficGeneratorTestSuite;