73 #include "ns3/point-to-point-module.h"
74 #include "ns3/internet-module.h"
75 #include "ns3/onion-routing.h"
76 #include "ns3/applications-module.h"
81 #define ONION_NO_CONTENT 0
82 #define ONION_ENDCONTENT 1
83 #define ONION_LAYERCONTENT 2
84 #define ONION_LAYERCONTENT_ENDCONTENT 3
91 NS_LOG_COMPONENT_DEFINE (
"OnionRoutingExample");
95 uint8_t * IpToBuff (Ipv4Address in)
97 uint8_t * out =
new uint8_t[4];
98 in.Serialize (&out[0]);
103 Ipv4Address ConstructIpv4 (uint8_t * buf)
115 return Ipv4Address (ip);
121 uint8_t * StringToUchar (std::string in)
123 uint8_t * out =
new uint8_t[in.length ()];
124 memcpy (&out[0], &in[0], in.length ());
129 std::string UcharToString (uint8_t* seq,
int len)
131 std::string strForm (&seq[0], &seq[0] + len);
153 uint8_t * GetPublicKey ();
155 uint8_t * GetSecretKey ();
158 virtual void EncryptLayer (uint8_t * ciphertext, uint8_t* message,
int len, uint8_t * key)
const;
160 virtual void DecryptLayer (uint8_t * innerLayer, uint8_t* onion, uint16_t onionLen, uint8_t * pk, uint8_t * sk)
const;
172 static TypeId tid = TypeId (
"ns3::OnionManager")
174 .SetGroupName (
"OnionRouting");
183 :
OnionRouting (crypto_box_SEALBYTES,Ipv4L3Protocol::PROT_NUMBER)
188 OnionManager::~OnionManager ()
197 uint8_t * OnionManager::GetPublicKey ()
202 uint8_t * OnionManager::GetSecretKey ()
210 if (crypto_box_seal (ciphertext, message, len, key) != 0)
212 NS_LOG_WARN (
"Error during encryption");
221 if (crypto_box_seal_open (innerLayer, onion, onionLen, pk, sk) != 0)
223 NS_LOG_WARN (
"Messge corrupted or not for this node");
233 class MyApp :
public Application
237 MyApp (uint8_t onionMode,uint16_t layerContentLen);
240 static TypeId GetTypeId (
void);
243 uint8_t * GetPublicKey ();
245 Ipv4Address GetAddress ();
248 void SetRoute (uint16_t routeLen, uint8_t ** ipRoute, uint8_t ** keys, uint8_t ** layerContent, uint8_t layerContentLen);
251 virtual void StartApplication (
void);
252 virtual void StopApplication (
void);
255 void RecvOnion (Ptr<Socket> socket);
257 Ptr<Socket> m_socket;
260 Ipv4Address m_address;
264 uint8_t ** m_ipRoute;
266 uint8_t ** m_layerContent;
267 uint16_t m_layerContentLen;
280 MyApp::MyApp (uint8_t onionMode,uint16_t layerContentLen)
284 m_onionMode (onionMode),
286 m_layerContentLen (layerContentLen)
298 uint8_t * MyApp::GetPublicKey ()
300 return m_onionManager.GetPublicKey ();
303 Ipv4Address MyApp::GetAddress ()
314 m_onionManager.GenerateNewKeyPair ();
318 Ptr<Node> PtrNode = this->GetNode ();
319 Ptr<Ipv4> ipv4 = PtrNode->GetObject<Ipv4> ();
320 Ipv4InterfaceAddress iaddr = ipv4->GetAddress (1, 0);
321 m_address = iaddr.GetLocal ();
327 void MyApp::SetRoute (uint16_t routeLen, uint8_t ** ipRoute, uint8_t ** keys, uint8_t ** layerContent, uint8_t layerContentLen)
329 m_routeLen = routeLen;
332 m_layerContent = layerContent;
333 m_layerContentLen = layerContentLen;
339 TypeId MyApp::GetTypeId (
void)
341 static TypeId tid = TypeId (
"MyApp")
342 .SetParent<Application> ()
343 .SetGroupName (
"ORexample")
344 .AddConstructor<MyApp> ()
356 std::string s (
"Some content to send anonymously.");
357 uint8_t * content = StringToUchar (s);
358 uint16_t contentLen = s.length ();
364 if (m_onionMode == ONION_NO_CONTENT)
366 cipherLen = m_onionManager.OnionLength (m_routeLen,0,0);
367 cipher =
new uint8_t[cipherLen];
369 m_onionManager.BuildOnion (cipher, m_ipRoute, m_keys, m_routeLen);
371 else if (m_onionMode == ONION_ENDCONTENT)
373 cipherLen = m_onionManager.OnionLength (m_routeLen,0,contentLen);
374 cipher =
new uint8_t[cipherLen];
376 m_onionManager.BuildOnion (cipher, m_ipRoute, m_keys, m_routeLen,content,contentLen);
378 else if (m_onionMode == ONION_LAYERCONTENT)
380 cipherLen = m_onionManager.OnionLength (m_routeLen,m_layerContentLen,0);
381 cipher =
new uint8_t[cipherLen];
383 m_onionManager.BuildOnion (cipher, m_ipRoute, m_keys, m_layerContent, m_layerContentLen, m_routeLen);
387 cipherLen = m_onionManager.OnionLength (m_routeLen,m_layerContentLen,contentLen);
388 cipher =
new uint8_t[cipherLen];
390 m_onionManager.BuildOnion (cipher, m_ipRoute, m_keys, m_layerContent, m_layerContentLen, m_routeLen,content,contentLen);
395 uint8_t
const * buff = cipher;
396 Ptr<Packet> p = Create<Packet> (buff,cipherLen);
397 m_socket->SendTo (p, 0, InetSocketAddress (ConstructIpv4 (m_ipRoute[0]),m_port));
398 NS_LOG_INFO (
"Onion construction--Onion sent to: " << ConstructIpv4 (m_ipRoute[0]) <<
" of size: " << p->GetSize () <<
" bytes" );
404 MyApp::RecvOnion (Ptr<Socket> socket)
407 Ptr<Packet> p = socket->RecvFrom (from);
410 uint32_t cipherLen = p->GetSize ();
414 NS_LOG_INFO (
"Onion reveal--Empty onion sent from: " << InetSocketAddress::ConvertFrom (from).GetIpv4 () <<
" received at: " << m_address );
418 uint8_t cipher[cipherLen];
419 p->CopyData (cipher, cipherLen);
422 orLayer * onionLayer = m_onionManager.PeelOnion (cipher,cipherLen,m_onionManager.GetPublicKey (),m_onionManager.GetSecretKey ());
425 if (ConstructIpv4 (onionLayer->
nextHopIP).Get () == 0)
427 NS_LOG_INFO (
"Onion reveal--Onion sent from: " << InetSocketAddress::ConvertFrom (from).GetIpv4 () <<
" received at: " << m_address <<
" of size: " << p->GetSize () <<
" bytes, containing the end content:" << UcharToString (onionLayer->
innerLayer,onionLayer->
innerLayerLen));
431 if (m_onionMode == ONION_LAYERCONTENT || m_onionMode == ONION_LAYERCONTENT_ENDCONTENT)
433 uint8_t
const * buff = &onionLayer->
innerLayer[m_layerContentLen];
434 Ptr<Packet> np = Create<Packet> (buff,onionLayer->
innerLayerLen - m_layerContentLen);
435 m_socket->SendTo (np, 0, InetSocketAddress (ConstructIpv4 (onionLayer->
nextHopIP),m_port));
436 NS_LOG_INFO (
"Onion routing--Onion sent from: " << InetSocketAddress::ConvertFrom (from).GetIpv4 () <<
" received at: " << m_address <<
" of size: " << p->GetSize () <<
" bytes, containing the layer content: " << UcharToString (onionLayer->
innerLayer,m_layerContentLen) <<
", sent to: " << ConstructIpv4 (onionLayer->
nextHopIP));
441 uint8_t
const * buff = onionLayer->
innerLayer;
442 Ptr<Packet> np = Create<Packet> (buff,onionLayer->
innerLayerLen);
443 m_socket->SendTo (np, 0, InetSocketAddress (ConstructIpv4 (onionLayer->
nextHopIP),m_port));
444 NS_LOG_INFO (
"Onion routing--Onion sent from: " << InetSocketAddress::ConvertFrom (from).GetIpv4 () <<
" received at: " << m_address <<
" of size: " << p->GetSize () <<
" bytes, sent to: " << ConstructIpv4 (onionLayer->
nextHopIP));
453 MyApp::StartApplication (
void)
457 m_socket = Socket::CreateSocket (this->GetNode (), TypeId::LookupByName (
"ns3::UdpSocketFactory"));
458 m_socket->Bind (InetSocketAddress (Ipv4Address::GetAny (), m_port));
459 m_socket->SetRecvCallback (MakeCallback (&MyApp::RecvOnion,
this));
465 Simulator::Schedule (Seconds (2), &MyApp::SendOnion,
this);
471 MyApp::StopApplication (
void)
486 main (
int argc,
char *argv[])
489 uint8_t onionMode = ONION_ENDCONTENT;
491 CommandLine cmd (__FILE__);
492 cmd.AddValue (
"verbose",
"Tell application to log if true", verbose);
493 cmd.AddValue (
"onionMode",
"Select the mode of operation", onionMode);
495 cmd.Parse (argc,argv);
499 LogComponentEnable (
"OnionRoutingExample", LOG_LEVEL_INFO);
500 LogComponentEnable (
"onionrouting", LOG_LEVEL_INFO);
506 NS_FATAL_ERROR (
"Wrong mode of operation selected, select one in range 0 to 3");
515 NodeContainer n0n1 = NodeContainer(nc.Get(0),nc.Get(1));
516 NodeContainer n1n2 = NodeContainer(nc.Get(1),nc.Get(2));
517 NodeContainer n2n3 = NodeContainer(nc.Get(2),nc.Get(3));
518 NodeContainer n2n4 = NodeContainer(nc.Get(2),nc.Get(4));
519 NodeContainer n3n4 = NodeContainer(nc.Get(3),nc.Get(4));
520 NodeContainer n4n5 = NodeContainer(nc.Get(4),nc.Get(5));
524 InternetStackHelper stack;
528 NS_LOG_INFO (
"Create channels.");
529 PointToPointHelper p2p;
530 p2p.SetDeviceAttribute (
"DataRate",StringValue (
"5Mbps"));
531 p2p.SetChannelAttribute(
"Delay",StringValue(
"2ms"));
532 NetDeviceContainer d0d1 = p2p.Install (n0n1);
534 NetDeviceContainer d1d2 = p2p.Install (n1n2);
536 NetDeviceContainer d4d5 = p2p.Install (n4n5);
538 p2p.SetDeviceAttribute (
"DataRate",StringValue (
"1Mbps"));
539 p2p.SetChannelAttribute(
"Delay",StringValue(
"3ms"));
540 NetDeviceContainer d2d3 = p2p.Install (n2n3);
541 NetDeviceContainer d3d4 = p2p.Install (n3n4);
542 NetDeviceContainer d2d4 = p2p.Install (n2n4);
547 Ipv4AddressHelper address;
549 address.SetBase (
"10.1.1.0",
"255.255.255.0");
550 Ipv4InterfaceContainer i0i1 = address.Assign (d0d1);
552 address.SetBase (
"10.1.2.0",
"255.255.255.0");
553 Ipv4InterfaceContainer i1i2 = address.Assign (d1d2);
555 address.SetBase (
"10.1.3.0",
"255.255.255.0");
556 Ipv4InterfaceContainer i2i3 = address.Assign (d2d3);
558 address.SetBase (
"10.1.4.0",
"255.255.255.0");
559 Ipv4InterfaceContainer i3i4 = address.Assign (d3d4);
561 address.SetBase (
"10.1.5.0",
"255.255.255.0");
562 Ipv4InterfaceContainer i2i4 = address.Assign (d2d4);
564 address.SetBase (
"10.1.6.0",
"255.255.255.0");
565 Ipv4InterfaceContainer i4i5 = address.Assign (d4d5);
568 Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
572 uint16_t routeLen = 5;
573 uint8_t * ipRoute[routeLen];
574 uint8_t * keys[routeLen];
575 uint16_t layerContentLen = 27;
576 uint8_t * layerContent[routeLen];
580 ApplicationContainer applications (CreateObject<MyApp> (onionMode,layerContentLen));
581 applications.Add (CreateObject<MyApp> (onionMode,layerContentLen));
582 applications.Add (CreateObject<MyApp> (onionMode,layerContentLen));
583 applications.Add (CreateObject<MyApp> (onionMode,layerContentLen));
584 applications.Add (CreateObject<MyApp> (onionMode,layerContentLen));
585 applications.Add (CreateObject<MyApp> (onionMode,layerContentLen));
587 nc.Get (0)->AddApplication (applications.Get (0));
588 nc.Get (1)->AddApplication (applications.Get (1));
589 nc.Get (2)->AddApplication (applications.Get (2));
590 nc.Get (3)->AddApplication (applications.Get (3));
591 nc.Get (4)->AddApplication (applications.Get (4));
592 nc.Get (5)->AddApplication (applications.Get (5));
596 for (uint32_t i = 0; i < applications.GetN (); ++i)
599 applications.Get (i)->GetObject<MyApp> ()->Setup ();
604 ipRoute[0] = IpToBuff (applications.Get (2)->GetObject<MyApp> ()->GetAddress ());
605 ipRoute[1] = IpToBuff (applications.Get (3)->GetObject<MyApp> ()->GetAddress ());
606 ipRoute[2] = IpToBuff (applications.Get (1)->GetObject<MyApp> ()->GetAddress ());
607 ipRoute[3] = IpToBuff (applications.Get (4)->GetObject<MyApp> ()->GetAddress ());
608 ipRoute[4] = IpToBuff (applications.Get (5)->GetObject<MyApp> ()->GetAddress ());
611 keys[0] = applications.Get (2)->GetObject<MyApp> ()->GetPublicKey ();
612 keys[1] = applications.Get (3)->GetObject<MyApp> ()->GetPublicKey ();
613 keys[2] = applications.Get (1)->GetObject<MyApp> ()->GetPublicKey ();
614 keys[3] = applications.Get (4)->GetObject<MyApp> ()->GetPublicKey ();
615 keys[4] = applications.Get (5)->GetObject<MyApp> ()->GetPublicKey ();
618 layerContent[0] = StringToUchar (
"OnionLayer 4 secret content");
619 layerContent[1] = StringToUchar (
"OnionLayer 3 secret content");
620 layerContent[2] = StringToUchar (
"OnionLayer 2 secret content");
621 layerContent[3] = StringToUchar (
"OnionLayer 1 secret content");
622 layerContent[4] = StringToUchar (
"OnionLayer 0 secret content");
626 applications.Get (0)->GetObject<MyApp> ()->SetRoute (routeLen,ipRoute,keys,layerContent,layerContentLen);
629 applications.Start (Seconds (1));
630 applications.Stop (Seconds (20));
633 Simulator::Stop (Seconds (20));
635 Simulator::Destroy ();