To implement an Internet Message Access Protocol (IMAP) and Post Office Protocol (POP3)are the email protocols in ns3 environment that contains to make a modules for both client and server applications, to describe the protocol logic and incorporated it with ns3 existing network simulation.
The given below are the procedures to follow how to implement the IMAP POP3 Email Protocols in ns3.
Prerequisites
- ns3 Installation: make sure ns3 is installed in the computer.
- C++ Programming: Basic understanding of C++ is essential.
- Understanding of ns-3: knowledge with ns3 modules and basic simulation scripts.
Steps to Implement IMAP and POP3 in ns3
- Set Up the Development Environment
Make certain that you have installed ns3 in the computer.
- Create a New Email Protocols Module
Navigate to the src directory in ns3 and create a new directory for your email protocols module.
cd ns-3.XX/src
mkdir email
cd email
mkdir model helper test
3. Define IMAP and POP3 Classes and Headers
imap-server.h
#ifndef IMAP_SERVER_H
#define IMAP_SERVER_H
#include “ns3/application.h”
#include “ns3/address.h”
#include “ns3/ptr.h”
#include “ns3/socket.h”
#include “ns3/traced-callback.h”
namespace ns3 {
class ImapServer : public Application {
public:
static TypeId GetTypeId (void);
ImapServer ();
virtual ~ImapServer ();
protected:
virtual void StartApplication (void);
virtual void StopApplication (void);
private:
void HandleRead (Ptr<Socket> socket);
void SendResponse (Ptr<Socket> socket, const std::string &response);
Ptr<Socket> m_socket;
Address m_local;
};
} // namespace ns3
#endif // IMAP_SERVER_H
imap-server.cc
#include “imap-server.h”
#include “ns3/log.h”
#include “ns3/simulator.h”
#include “ns3/inet-socket-address.h”
#include “ns3/uinteger.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“ImapServer”);
NS_OBJECT_ENSURE_REGISTERED (ImapServer);
TypeId ImapServer::GetTypeId (void) {
static TypeId tid = TypeId (“ns3::ImapServer”)
.SetParent<Application> ()
.SetGroupName (“Applications”)
.AddConstructor<ImapServer> ()
.AddAttribute (“Local”, “The Address on which to Bind the rx socket.”,
AddressValue (),
MakeAddressAccessor (&ImapServer::m_local),
MakeAddressChecker ());
return tid;
}
ImapServer::ImapServer () {
NS_LOG_FUNCTION (this);
}
ImapServer::~ImapServer () {
NS_LOG_FUNCTION (this);
}
void ImapServer::StartApplication () {
NS_LOG_FUNCTION (this);
if (m_socket == 0) {
m_socket = Socket::CreateSocket (GetNode (), TcpSocketFactory::GetTypeId ());
m_socket->Bind (m_local);
m_socket->Listen ();
m_socket->SetRecvCallback (MakeCallback (&ImapServer::HandleRead, this));
}
}
void ImapServer::StopApplication () {
NS_LOG_FUNCTION (this);
if (m_socket) {
m_socket->Close ();
m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
}
}
void ImapServer::HandleRead (Ptr<Socket> socket) {
NS_LOG_FUNCTION (this << socket);
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom (from))) {
NS_LOG_INFO (“Received request from ” << InetSocketAddress::ConvertFrom (from).GetIpv4 ());
// Process IMAP commands and send responses
std::string response = “* OK IMAP4rev1 Service Ready\r\n”;
SendResponse (socket, response);
}
}
void ImapServer::SendResponse (Ptr<Socket> socket, const std::string &response) {
NS_LOG_FUNCTION (this << socket << response);
Ptr<Packet> packet = Create<Packet> ((const uint8_t *)response.c_str (), response.size ());
socket->Send (packet);
NS_LOG_INFO (“Sent response: ” << response);
}
} // namespace ns3
imap-client.h
#ifndef IMAP_CLIENT_H
#define IMAP_CLIENT_H
#include “ns3/application.h”
#include “ns3/address.h”
#include “ns3/ptr.h”
#include “ns3/socket.h”
#include “ns3/traced-callback.h”
namespace ns3 {
class ImapClient : public Application {
public:
static TypeId GetTypeId (void);
ImapClient ();
virtual ~ImapClient ();
protected:
virtual void StartApplication (void);
virtual void StopApplication (void);
private:
void SendRequest ();
void HandleRead (Ptr<Socket> socket);
Ptr<Socket> m_socket;
Address m_peer;
EventId m_sendEvent;
};
} // namespace ns3
#endif // IMAP_CLIENT_H
imap-client.cc
#include “imap-client.h”
#include “ns3/log.h”
#include “ns3/simulator.h”
#include “ns3/inet-socket-address.h”
#include “ns3/uinteger.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“ImapClient”);
NS_OBJECT_ENSURE_REGISTERED (ImapClient);
TypeId ImapClient::GetTypeId (void) {
static TypeId tid = TypeId (“ns3::ImapClient”)
.SetParent<Application> ()
.SetGroupName (“Applications”)
.AddConstructor<ImapClient> ()
.AddAttribute (“Remote”, “The Address of the IMAP server.”,
AddressValue (),
MakeAddressAccessor (&ImapClient::m_peer),
MakeAddressChecker ());
return tid;
}
ImapClient::ImapClient () {
NS_LOG_FUNCTION (this);
}
ImapClient::~ImapClient () {
NS_LOG_FUNCTION (this);
}
void ImapClient::StartApplication () {
NS_LOG_FUNCTION (this);
if (m_socket == 0) {
m_socket = Socket::CreateSocket (GetNode (), TcpSocketFactory::GetTypeId ());
m_socket->Connect (m_peer);
m_socket->SetRecvCallback (MakeCallback (&ImapClient::HandleRead, this));
m_sendEvent = Simulator::Schedule (Seconds (1.0), &ImapClient::SendRequest, this);
}
}
void ImapClient::StopApplication () {
NS_LOG_FUNCTION (this);
if (m_socket) {
m_socket->Close ();
}
Simulator::Cancel (m_sendEvent);
}
void ImapClient::SendRequest () {
NS_LOG_FUNCTION (this);
std::string request = “a001 LOGIN user password\r\n”;
Ptr<Packet> packet = Create<Packet> ((const uint8_t *)request.c_str (), request.size ());
m_socket->Send (packet);
NS_LOG_INFO (“Sent request to server: ” << request);
}
void ImapClient::HandleRead (Ptr<Socket> socket) {
NS_LOG_FUNCTION (this << socket);
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom (from))) {
uint8_t *buffer = new uint8_t[packet->GetSize ()];
packet->CopyData (buffer, packet->GetSize ());
std::string response = std::string ((char *)buffer, packet->GetSize ());
NS_LOG_INFO (“Received response from server: ” << response);
delete[] buffer;
}
}
} // namespace ns3
pop3-server.h
#ifndef POP3_SERVER_H
#define POP3_SERVER_H
#include “ns3/application.h”
#include “ns3/address.h”
#include “ns3/ptr.h”
#include “ns3/socket.h”
#include “ns3/traced-callback.h”
namespace ns3 {
class Pop3Server : public Application {
public:
static TypeId GetTypeId (void);
Pop3Server ();
virtual ~Pop3Server ();
protected:
virtual void StartApplication (void);
virtual void StopApplication (void);
private:
void HandleRead (Ptr<Socket> socket);
void SendResponse (Ptr<Socket> socket, const std::string &response);
Ptr<Socket> m_socket;
Address m_local;
};
} // namespace ns3
#endif // POP3_SERVER_H
pop3-server.cc
#include “pop3-server.h”
#include “ns3/log.h”
#include “ns3/simulator.h”
#include “ns3/inet-socket-address.h”
#include “ns3/uinteger.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“Pop3Server”);
NS_OBJECT_ENSURE_REGISTERED (Pop3Server);
TypeId Pop3Server::GetTypeId (void) {
static TypeId tid = TypeId (“ns3::Pop3Server”)
.SetParent<Application> ()
.SetGroupName (“Applications”)
.AddConstructor<Pop3Server> ()
.AddAttribute (“Local”, “The Address on which to Bind the rx socket.”,
AddressValue (),
MakeAddressAccessor (&Pop3Server::m_local),
MakeAddressChecker ());
return tid;
}
Pop3Server::Pop3Server () {
NS_LOG_FUNCTION (this);
}
Pop3Server::~Pop3Server () {
NS_LOG_FUNCTION (this);
}
void Pop3Server::StartApplication () {
NS_LOG_FUNCTION (this);
if (m_socket == 0) {
m_socket = Socket::CreateSocket (GetNode (), TcpSocketFactory::GetTypeId ());
m_socket->Bind (m_local);
m_socket->Listen ();
m_socket->SetRecvCallback (MakeCallback (&Pop3Server::HandleRead, this));
}
}
void Pop3Server::StopApplication () {
NS_LOG_FUNCTION (this);
if (m_socket) {
m_socket->Close ();
m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
}
}
void Pop3Server::HandleRead (Ptr<Socket> socket) {
NS_LOG_FUNCTION (this << socket);
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom (from))) {
NS_LOG_INFO (“Received request from ” << InetSocketAddress::ConvertFrom (from).GetIpv4 ());
// Process POP3 commands and send responses
std::string response = “+OK POP3 server ready\r\n”;
SendResponse (socket, response);
}
}
void Pop3Server::SendResponse (Ptr<Socket> socket, const std::string &response) {
NS_LOG_FUNCTION (this << socket << response);
Ptr<Packet> packet = Create<Packet> ((const uint8_t *)response.c_str (), response.size ());
socket->Send (packet);
NS_LOG_INFO (“Sent response: ” << response);
}
} // namespace ns3
pop3-client.h
#ifndef POP3_CLIENT_H
#define POP3_CLIENT_H
#include “ns3/application.h”
#include “ns3/address.h”
#include “ns3/ptr.h”
#include “ns3/socket.h”
#include “ns3/traced-callback.h”
namespace ns3 {
class Pop3Client : public Application {
public:
static TypeId GetTypeId (void);
Pop3Client ();
virtual ~Pop3Client ();
protected:
virtual void StartApplication (void);
virtual void StopApplication (void);
private:
void SendRequest ();
void HandleRead (Ptr<Socket> socket);
Ptr<Socket> m_socket;
Address m_peer;
EventId m_sendEvent;
};
} // namespace ns3
#endif // POP3_CLIENT_H
pop3-client.cc
#include “pop3-client.h”
#include “ns3/log.h”
#include “ns3/simulator.h”
#include “ns3/inet-socket-address.h”
#include “ns3/uinteger.h”
namespace ns3 {
NS_LOG_COMPONENT_DEFINE (“Pop3Client”);
NS_OBJECT_ENSURE_REGISTERED (Pop3Client);
TypeId Pop3Client::GetTypeId (void) {
static TypeId tid = TypeId (“ns3::Pop3Client”)
.SetParent<Application> ()
.SetGroupName (“Applications”)
.AddConstructor<Pop3Client> ()
.AddAttribute (“Remote”, “The Address of the POP3 server.”,
AddressValue (),
MakeAddressAccessor (&Pop3Client::m_peer),
MakeAddressChecker ());
return tid;
}
Pop3Client::Pop3Client () {
NS_LOG_FUNCTION (this);
}
Pop3Client::~Pop3Client () {
NS_LOG_FUNCTION (this);
}
void Pop3Client::StartApplication () {
NS_LOG_FUNCTION (this);
if (m_socket == 0) {
m_socket = Socket::CreateSocket (GetNode (), TcpSocketFactory::GetTypeId ());
m_socket->Connect (m_peer);
m_socket->SetRecvCallback (MakeCallback (&Pop3Client::HandleRead, this));
m_sendEvent = Simulator::Schedule (Seconds (1.0), &Pop3Client::SendRequest, this);
}
}
void Pop3Client::StopApplication () {
NS_LOG_FUNCTION (this);
if (m_socket) {
m_socket->Close ();
}
Simulator::Cancel (m_sendEvent);
}
void Pop3Client::SendRequest () {
NS_LOG_FUNCTION (this);
std::string request = “USER user\r\n”;
Ptr<Packet> packet = Create<Packet> ((const uint8_t *)request.c_str (), request.size ());
m_socket->Send (packet);
NS_LOG_INFO (“Sent request to server: ” << request);
}
void Pop3Client::HandleRead (Ptr<Socket> socket) {
NS_LOG_FUNCTION (this << socket);
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom (from))) {
uint8_t *buffer = new uint8_t[packet->GetSize ()];
packet->CopyData (buffer, packet->GetSize ());
std::string response = std::string ((char *)buffer, packet->GetSize ());
NS_LOG_INFO (“Received response from server: ” << response);
delete[] buffer;
}
}
} // namespace ns3
4. Create Email Protocols Helper Classes
Create helper classes to facilitate the use and testing of IMAP and POP3.
email-helper.h
#ifndef EMAIL_HELPER_H
#define EMAIL_HELPER_H
#include “ns3/application-container.h”
#include “ns3/node-container.h”
#include “ns3/imap-server.h”
#include “ns3/imap-client.h”
#include “ns3/pop3-server.h”
#include “ns3/pop3-client.h”
namespace ns3 {
class ImapServerHelper {
public:
ImapServerHelper (Address address);
ApplicationContainer Install (NodeContainer c);
private:
Ptr<Application> InstallPriv (Ptr<Node> node);
Address m_address;
};
class ImapClientHelper {
public:
ImapClientHelper (Address address);
ApplicationContainer Install (NodeContainer c);
private:
Ptr<Application> InstallPriv (Ptr<Node> node);
Address m_address;
};
class Pop3ServerHelper {
public:
Pop3ServerHelper (Address address);
ApplicationContainer Install (NodeContainer c);
private:
Ptr<Application> InstallPriv (Ptr<Node> node);
Address m_address;
};
class Pop3ClientHelper {
public:
Pop3ClientHelper (Address address);
ApplicationContainer Install (NodeContainer c);
private:
Ptr<Application> InstallPriv (Ptr<Node> node);
Address m_address;
};
} // namespace ns3
#endif // EMAIL_HELPER_H
email-helper.cc
#include “email-helper.h”
#include “ns3/uinteger.h”
#include “ns3/names.h”
namespace ns3 {
ImapServerHelper::ImapServerHelper (Address address)
: m_address (address) {
}
ApplicationContainer ImapServerHelper::Install (NodeContainer c) {
ApplicationContainer apps;
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) {
Ptr<Node> node = *i;
Ptr<Application> app = InstallPriv (node);
apps.Add (app);
}
return apps;
}
Ptr<Application> ImapServerHelper::InstallPriv (Ptr<Node> node) {
Ptr<ImapServer> server = CreateObject<ImapServer> ();
server->SetAttribute (“Local”, AddressValue (m_address));
node->AddApplication (server);
return server;
}
ImapClientHelper::ImapClientHelper (Address address)
: m_address (address) {
}
ApplicationContainer ImapClientHelper::Install (NodeContainer c) {
ApplicationContainer apps;
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) {
Ptr<Node> node = *i;
Ptr<Application> app = InstallPriv (node);
apps.Add (app);
}
return apps;
}
Ptr<Application> ImapClientHelper::InstallPriv (Ptr<Node> node) {
Ptr<ImapClient> client = CreateObject<ImapClient> ();
client->SetAttribute (“Remote”, AddressValue (m_address));
node->AddApplication (client);
return client;
}
Pop3ServerHelper::Pop3ServerHelper (Address address)
: m_address (address) {
}
ApplicationContainer Pop3ServerHelper::Install (NodeContainer c) {
ApplicationContainer apps;
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) {
Ptr<Node> node = *i;
Ptr<Application> app = InstallPriv (node);
apps.Add (app);
}
return apps;
}
Ptr<Application> Pop3ServerHelper::InstallPriv (Ptr<Node> node) {
Ptr<Pop3Server> server = CreateObject<Pop3Server> ();
server->SetAttribute (“Local”, AddressValue (m_address));
node->AddApplication (server);
return server;
}
Pop3ClientHelper::Pop3ClientHelper (Address address)
: m_address (address) {
}
ApplicationContainer Pop3ClientHelper::Install (NodeContainer c) {
ApplicationContainer apps;
for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i) {
Ptr<Node> node = *i;
Ptr<Application> app = InstallPriv (node);
apps.Add (app);
}
return apps;
}
Ptr<Application> Pop3ClientHelper::InstallPriv (Ptr<Node> node) {
Ptr<Pop3Client> client = CreateObject<Pop3Client> ();
client->SetAttribute (“Remote”, AddressValue (m_address));
node->AddApplication (client);
return client;
}
} // namespace ns3
5. Integrate Email Protocols with ns-3 Build System
Update the wscript file in the src directory to include your new email protocols module.
src/email/wscript
def build(bld):
module = bld.create_ns3_module(’email’, [‘core’, ‘network’, ‘internet’, ‘applications’])
module.source = [
‘model/imap-server.cc’,
‘model/imap-client.cc’,
‘model/pop3-server.cc’,
‘model/pop3-client.cc’,
‘helper/email-helper.cc’,
]
headers = bld(features=’ns3header’)
headers.module = ’email’
headers.source = [
‘model/imap-server.h’,
‘model/imap-client.h’,
‘model/pop3-server.h’,
‘model/pop3-client.h’,
‘helper/email-helper.h’,
]
- Build and Test
- Rebuild ns-3 to include your new email protocols module.
./waf configure
./waf build
- Create test scripts to verify the implementation of your IMAP and POP3 protocols.
scratch/test-email.cc
#include “ns3/core-module.h”
#include “ns3/network-module.h”
#include “ns3/internet-module.h”
#include “ns3/point-to-point-module.h”
#include “ns3/email-helper.h”
using namespace ns3;
int main (int argc, char *argv[])
{
CommandLine cmd;
cmd.Parse (argc, argv);
NodeContainer nodes;
nodes.Create (2);
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute (“DataRate”, StringValue (“5Mbps”));
pointToPoint.SetChannelAttribute (“Delay”, StringValue (“2ms”));
NetDeviceContainer devices;
devices = pointToPoint.Install (nodes);
InternetStackHelper stack;
stack.Install (nodes);
Ipv4AddressHelper address;
address.SetBase (“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer interfaces = address.Assign (devices);
// IMAP
ImapServerHelper imapServer (InetSocketAddress (Ipv4Address::GetAny (), 143));
ApplicationContainer imapServerApps = imapServer.Install (nodes.Get (1));
imapServerApps.Start (Seconds (1.0));
imapServerApps.Stop (Seconds (10.0));
ImapClientHelper imapClient (InetSocketAddress (interfaces.GetAddress (1), 143));
ApplicationContainer imapClientApps = imapClient.Install (nodes.Get (0));
imapClientApps.Start (Seconds (2.0));
imapClientApps.Stop (Seconds (10.0));
// POP3
Pop3ServerHelper pop3Server (InetSocketAddress (Ipv4Address::GetAny (), 110));
ApplicationContainer pop3ServerApps = pop3Server.Install (nodes.Get (1));
pop3ServerApps.Start (Seconds (1.0));
pop3ServerApps.Stop (Seconds (10.0));
Pop3ClientHelper pop3Client (InetSocketAddress (interfaces.GetAddress (1), 110));
ApplicationContainer pop3ClientApps = pop3Client.Install (nodes.Get (0));
pop3ClientApps.Start (Seconds (2.0));
pop3ClientApps.Stop (Seconds (10.0));
Simulator::Run ();
Simulator::Destroy ();
return 0;
}
7. Run and Debug
Run your test script and debug any issues that arise.
./waf –run scratch/test-email
Overall, we had implemented and executed IMAP POP3 protocol in ns3 simulation and we also provide related information about IMAP POP3 protocol.
Implementation of the IMAP POP3 Email Protocols in ns3 with practical explanation support are shared by ns3simulation.com