ns-3 Direct Code Execution
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
mip6d-helper.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2010 Hajime Tazaki
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Hajime Tazaki <tazaki@sfc.wide.ad.jp>
19  */
20 
21 #include "ns3/object-factory.h"
22 #include "mip6d-helper.h"
23 #include "ns3/dce-application-helper.h"
24 #include "ns3/names.h"
25 #include "ns3/linux-socket-fd-factory.h"
26 #include <fstream>
27 #include <map>
28 #include <sys/stat.h>
29 
30 namespace ns3 {
31 
32 class Mip6dConfig : public Object
33 {
34 private:
35  static int index;
36  std::string router_id;
37 public:
39  : m_haenable (false),
40  m_mrenable (false),
41  m_magenable (false),
42  m_debug (false),
43  m_usemanualconf (false),
44  m_ha_served_pfx (""),
45  m_dsmip6enable (false),
46  m_binary ("mip6d")
47  {
48  m_mr_mobile_pfx = new std::vector<std::string> ();
49  m_mr_egress_if = new std::vector<std::string> ();
50  m_mag_mn_profiles = new std::vector<Mip6dConfig::pmipMNprofile_t> ();
51  }
53  {
54  }
55 
56  static TypeId
57  GetTypeId (void)
58  {
59  static TypeId tid = TypeId ("ns3::Mip6dConfig")
60  .SetParent<Object> ()
61  .AddConstructor<Mip6dConfig> ()
62  ;
63  return tid;
64  }
65  TypeId
66  GetInstanceTypeId (void) const
67  {
68  return GetTypeId ();
69  }
70 
71  typedef struct
72  {
73  std::string m_mn_id;
74  std::string m_lma_addr;
75  std::string m_home_prefix;
77 
78  bool m_haenable;
79  bool m_mrenable;
81  bool m_debug;
84  std::string m_binary;
85  std::string m_ha_served_pfx;
86  std::vector<std::string> *m_mr_mobile_pfx;
87  std::vector<std::string> *m_mr_egress_if;
88  std::string m_mn_ha_addr;
89  std::string m_mr_home_addr;
90  std::string m_lma_mag_ifname;
91  std::string m_mag_egress_gaddr;
92  std::string m_mag_egress_ifname;
93  std::vector<pmipMNprofile_t> *m_mag_mn_profiles;
94 
95  virtual void
96  Print (std::ostream& os) const
97  {
98  os << "# IPsec configuration - NO IPSEC AT THE MOMENT" << std::endl
99  << "UseMnHaIPsec disabled;" << std::endl
100  << "KeyMngMobCapability disabled;" << std::endl
101  << "# EOF" << std::endl;
102  }
103 };
104 std::ostream& operator << (std::ostream& os, Mip6dConfig const& config)
105 {
106  config.Print (os);
107  return os;
108 }
109 
110 
112 {
113 }
114 
115 void
116 Mip6dHelper::SetAttribute (std::string name, const AttributeValue &value)
117 {
118 }
119 
120 // HomeAgent
121 void
122 Mip6dHelper::EnableHA (NodeContainer nodes)
123 {
124  for (uint32_t i = 0; i < nodes.GetN (); i++)
125  {
126  Ptr<Mip6dConfig> mip6d_conf = nodes.Get (i)->GetObject<Mip6dConfig> ();
127  if (!mip6d_conf)
128  {
129  mip6d_conf = CreateObject<Mip6dConfig> ();
130  nodes.Get (i)->AggregateObject (mip6d_conf);
131  }
132  mip6d_conf->m_haenable = true;
133 
134  Ptr<LinuxSocketFdFactory> kern = nodes.Get (i)->GetObject<LinuxSocketFdFactory>();
135  Simulator::ScheduleWithContext (nodes.Get (i)->GetId (), Seconds (0.1),
136  MakeEvent (&LinuxSocketFdFactory::Set, kern,
137  ".net.ipv6.conf.all.forwarding", "1"));
138  Simulator::ScheduleWithContext (nodes.Get (i)->GetId (), Seconds (0.1),
139  MakeEvent (&LinuxSocketFdFactory::Set, kern,
140  ".net.ipv6.conf.all.proxy_ndp", "1"));
141  }
142 
143  return;
144 }
145 
146 void
148  Ipv6Address prefix, Ipv6Prefix plen)
149 {
150  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig> ();
151  if (!mip6d_conf)
152  {
153  mip6d_conf = CreateObject<Mip6dConfig> ();
154  node->AggregateObject (mip6d_conf);
155  }
156 
157  std::ostringstream oss;
158  prefix.Print (oss);
159  oss << "/" << (uint32_t)plen.GetPrefixLength ();
160 
161  mip6d_conf->m_ha_served_pfx = oss.str ();
162 
163  return;
164 }
165 
166 // MobileRouter
167 void
168 Mip6dHelper::EnableMR (NodeContainer nodes)
169 {
170  // for (uint32_t i = 0; i < nodes.GetN (); i++)
171  for (uint32_t i = 0; i < nodes.GetN (); i++)
172  {
173  Ptr<Mip6dConfig> mip6d_conf = nodes.Get (i)->GetObject<Mip6dConfig> ();
174  if (!mip6d_conf)
175  {
176  mip6d_conf = CreateObject<Mip6dConfig> ();
177  nodes.Get (i)->AggregateObject (mip6d_conf);
178  }
179  mip6d_conf->m_mrenable = true;
180 
181  Ptr<LinuxSocketFdFactory> kern = nodes.Get (i)->GetObject<LinuxSocketFdFactory>();
182  Simulator::ScheduleWithContext (nodes.Get (i)->GetId (), Seconds (0.1),
183  MakeEvent (&LinuxSocketFdFactory::Set, kern,
184  ".net.ipv6.conf.all.forwarding", "1"));
185  }
186 
187  return;
188 }
189 
190 void
192  Ipv6Address prefix, Ipv6Prefix plen)
193 {
194  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig> ();
195  if (!mip6d_conf)
196  {
197  mip6d_conf = CreateObject<Mip6dConfig> ();
198  node->AggregateObject (mip6d_conf);
199  }
200 
201  std::ostringstream oss;
202  prefix.Print (oss);
203  oss << "/" << (uint32_t)plen.GetPrefixLength ();
204 
205  mip6d_conf->m_mr_mobile_pfx->push_back (oss.str ());
206 
207  return;
208 }
209 
210 void
211 Mip6dHelper::AddEgressInterface (Ptr<Node> node, const char *ifname)
212 {
213  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig> ();
214  if (!mip6d_conf)
215  {
216  mip6d_conf = CreateObject<Mip6dConfig> ();
217  node->AggregateObject (mip6d_conf);
218  }
219 
220  mip6d_conf->m_mr_egress_if->push_back (std::string (ifname));
221 
222  return;
223 }
224 
225 void
226 Mip6dHelper::AddHomeAgentAddress (Ptr<Node> node, Ipv6Address addr)
227 {
228  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig> ();
229  if (!mip6d_conf)
230  {
231  mip6d_conf = CreateObject<Mip6dConfig> ();
232  node->AggregateObject (mip6d_conf);
233  }
234 
235  std::ostringstream oss;
236  addr.Print (oss);
237  mip6d_conf->m_mn_ha_addr = oss.str ();
238 
239  return;
240 }
241 
242 void
244  Ipv6Address addr, Ipv6Prefix plen)
245 {
246  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig> ();
247  if (!mip6d_conf)
248  {
249  mip6d_conf = CreateObject<Mip6dConfig> ();
250  node->AggregateObject (mip6d_conf);
251  }
252 
253  std::ostringstream oss;
254  addr.Print (oss);
255  oss << "/" << (uint32_t)plen.GetPrefixLength ();
256  mip6d_conf->m_mr_home_addr = oss.str ();
257 
258  return;
259 }
260 
261 // Local Mobility Anchor (LMA)
262 void
263 Mip6dHelper::EnableLMA (Ptr<Node> node, const char *ifname)
264 {
265  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig>();
266  if (!mip6d_conf)
267  {
268  mip6d_conf = CreateObject<Mip6dConfig> ();
269  node->AggregateObject (mip6d_conf);
270  }
271 
272  mip6d_conf->m_haenable = true;
273  mip6d_conf->m_lma_mag_ifname = ifname;
274 }
275 
276 // Mobile Access Gateway (MAG)
277 void
278 Mip6dHelper::EnableMAG (Ptr<Node> node,
279  const char *ifname, Ipv6Address addr)
280 {
281  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig>();
282  if (!mip6d_conf)
283  {
284  mip6d_conf = CreateObject<Mip6dConfig> ();
285  node->AggregateObject (mip6d_conf);
286  }
287 
288  mip6d_conf->m_magenable = true;
289  std::ostringstream oss;
290  addr.Print (oss);
291  mip6d_conf->m_mag_egress_gaddr = oss.str ();
292  mip6d_conf->m_mag_egress_ifname = ifname;
293 }
294 
295 void
296 Mip6dHelper::AddMNProfileMAG (Ptr<Node> node, Mac48Address mn_id,
297  Ipv6Address lma_addr,
298  Ipv6Address home_pfx, Ipv6Prefix home_plen)
299 {
300  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig>();
301  if (!mip6d_conf)
302  {
303  mip6d_conf = CreateObject<Mip6dConfig> ();
304  node->AggregateObject (mip6d_conf);
305  }
306 
307  std::ostringstream oss;
309 
310  oss << mn_id;
311  profile.m_mn_id = oss.str ();
312 
313  oss.str ("");
314  lma_addr.Print (oss);
315  profile.m_lma_addr = oss.str ();
316 
317  oss.str ("");
318  home_pfx.Print (oss);
319  oss << "/" << (uint32_t)home_plen.GetPrefixLength ();
320  profile.m_home_prefix = oss.str ();
321 
322  mip6d_conf->m_mag_mn_profiles->push_back (profile);
323 
324  return;
325 }
326 
327 // DSMIP
328 void
329 Mip6dHelper::EnableDSMIP6 (NodeContainer nodes)
330 {
331  for (uint32_t i = 0; i < nodes.GetN (); i++)
332  {
333  Ptr<Mip6dConfig> mip6d_conf = nodes.Get (i)->GetObject<Mip6dConfig> ();
334  if (!mip6d_conf)
335  {
336  mip6d_conf = CreateObject<Mip6dConfig> ();
337  nodes.Get (i)->AggregateObject (mip6d_conf);
338  }
339  mip6d_conf->m_dsmip6enable = true;
340  }
341 
342  return;
343 }
344 
345 void
346 Mip6dHelper::EnableDebug (NodeContainer nodes)
347 {
348  for (uint32_t i = 0; i < nodes.GetN (); i++)
349  {
350  Ptr<Mip6dConfig> mip6d_conf = nodes.Get (i)->GetObject<Mip6dConfig> ();
351  if (!mip6d_conf)
352  {
353  mip6d_conf = CreateObject<Mip6dConfig> ();
354  nodes.Get (i)->AggregateObject (mip6d_conf);
355  }
356  mip6d_conf->m_debug = true;
357  }
358  return;
359 }
360 
361 void
362 Mip6dHelper::UseManualConfig (NodeContainer nodes)
363 {
364  for (uint32_t i = 0; i < nodes.GetN (); i++)
365  {
366  Ptr<Mip6dConfig> mip6d_conf = nodes.Get (i)->GetObject<Mip6dConfig> ();
367  if (!mip6d_conf)
368  {
369  mip6d_conf = new Mip6dConfig ();
370  nodes.Get (i)->AggregateObject (mip6d_conf);
371  }
372  mip6d_conf->m_usemanualconf = true;
373  }
374  return;
375 }
376 
377 void
378 Mip6dHelper::SetBinary (NodeContainer nodes, std::string binary)
379 {
380  for (uint32_t i = 0; i < nodes.GetN (); i++)
381  {
382  Ptr<Mip6dConfig> mip6d_conf = nodes.Get (i)->GetObject<Mip6dConfig> ();
383  if (!mip6d_conf)
384  {
385  mip6d_conf = new Mip6dConfig ();
386  nodes.Get (i)->AggregateObject (mip6d_conf);
387  }
388  mip6d_conf->m_binary = binary;
389  }
390  return;
391 }
392 
393 void
395 {
396  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig> ();
397 
398  if (mip6d_conf->m_usemanualconf)
399  {
400  return;
401  }
402 
403  // config generation
404  std::stringstream conf_dir, conf_file;
405  // FIXME XXX
406  conf_dir << "files-" << node->GetId () << "";
407  ::mkdir (conf_dir.str ().c_str (), S_IRWXU | S_IRWXG);
408  conf_dir << "/etc/";
409  ::mkdir (conf_dir.str ().c_str (), S_IRWXU | S_IRWXG);
410 
411  conf_file << conf_dir.str () << "/mip6d.conf";
412  std::ofstream conf;
413  conf.open (conf_file.str ().c_str ());
414 
415  if (mip6d_conf->m_haenable)
416  {
417  conf << "NodeConfig HA;" << std::endl
418  << "Interface \"sim0\";" << std::endl
419  << "HaAcceptMobRtr enabled;" << std::endl
420  << "#BindingAclPolicy 2001:1:2:3::1000 (2001:1:2:5::/64) allow;" << std::endl
421  << "DefaultBindingAclPolicy allow;" << std::endl;
422 
423  if (!mip6d_conf->m_lma_mag_ifname.empty ())
424  conf << "LMAInterfaceMAG \"" << mip6d_conf->m_lma_mag_ifname << "\";" << std::endl;
425 
426  if (!mip6d_conf->m_ha_served_pfx.empty ())
427  conf << "HaServedPrefix " << mip6d_conf->m_ha_served_pfx << ";" << std::endl;
428 
429  if (mip6d_conf->m_dsmip6enable)
430  {
431  conf << "HaAcceptDsmip6 enabled;" << std::endl;
432  }
433  if (mip6d_conf->m_dsmip6enable)
434  {
435  conf << "# The IPv4 address of the HA or the HA name can be given." << std::endl;
436  conf << "HomeAgentV4Address 192.168.10.1;" << std::endl;
437  }
438  }
439  // PMIP MAG
440  else if (mip6d_conf->m_magenable)
441  {
442  conf << "NodeConfig MN;" << std::endl
443  << "DoRouteOptimizationCN disabled;" << std::endl
444  << "DoRouteOptimizationMN disabled;" << std::endl
445  << "UseCnBuAck disabled;" << std::endl
446  << "OptimisticHandoff enabled;" << std::endl
447  << "MnMaxHaBindingLife 60;" << std::endl;
448 
449  conf << "MAGInterfaceLMA \"" << mip6d_conf->m_mag_egress_ifname << "\";" << std::endl;
450  conf << "MAGEgressGlobalAddress " << mip6d_conf->m_mag_egress_gaddr << ";" << std::endl;
451 
452 
453  for (std::vector<Mip6dConfig::pmipMNprofile_t>::iterator i = mip6d_conf->m_mag_mn_profiles->begin ();
454  i != mip6d_conf->m_mag_mn_profiles->end (); ++i)
455  {
456  conf << "MNIdentifier \"" << (*i).m_mn_id <<"\" {" << std::endl;
457  conf << " PMIPEnabled 1;" << std::endl;
458  conf << " LMAAddress " << (*i).m_lma_addr << ";" << std::endl;
459  conf << " HomeNetworkPrefix1 " << (*i).m_home_prefix << ";" << std::endl;
460  conf << " PMIPInterface1 \"sim0(XXX)\";" << std::endl;
461  conf << " HomePrefixLifetime 460.0;" << std::endl;
462  conf << "}" << std::endl;
463  }
464  }
465  // CMIP-MN or MR (NEMO)
466  else
467  {
468  if (mip6d_conf->m_dsmip6enable)
469  {
470  conf << "MnUseDsmip6 enabled;" << std::endl;
471  }
472 
473  conf << "NodeConfig MN;" << std::endl
474  << "DoRouteOptimizationCN enabled;" << std::endl
475  << "DoRouteOptimizationMN disabled;" << std::endl
476  << "UseCnBuAck disabled;" << std::endl
477  << "MnDiscardHaParamProb enabled;" << std::endl
478  << "MobRtrUseExplicitMode enabled;" << std::endl;
479 
480  for (std::vector<std::string>::iterator i = mip6d_conf->m_mr_egress_if->begin ();
481  i != mip6d_conf->m_mr_egress_if->end (); ++i)
482  {
483  if (mip6d_conf->m_dsmip6enable)
484  {
485  conf << "Interface \"" << (*i) << "\"{" << std::endl;
486  conf << " # Specify if this interface should use DHCP to get an IPv4 CoA" << std::endl;
487  conf << " UseDhcp enabled;" << std::endl;
488  conf << "}" << std::endl;
489  }
490  else
491  {
492  conf << "Interface \"" << (*i) << "\";" << std::endl;
493  }
494  }
495 
496 
497  conf << "MnRouterProbes 1;" << std::endl
498  << "MnHomeLink \"sim0\" {" << std::endl;
499  if (mip6d_conf->m_dsmip6enable)
500  {
501  conf << "# The IPv4 address of the HA or the HA name can be given." << std::endl
502  << "# If both are given, the HomeAgentName field is ignored." << std::endl
503  << "HomeAgentV4Address 192.168.10.1;" << std::endl
504  << "# HomeAgentName <FQDN of the Home Agent>;" << std::endl;
505  }
506 
507  if (mip6d_conf->m_mrenable)
508  {
509  conf << " IsMobRtr enabled;" << std::endl;
510  }
511  conf << " HomeAgentAddress " << mip6d_conf->m_mn_ha_addr << ";" << std::endl;
512 
513  conf << " HomeAddress " << mip6d_conf->m_mr_home_addr;
514 
515  if (mip6d_conf->m_mrenable)
516  {
517  conf << "(";
518  for (std::vector<std::string>::iterator i = mip6d_conf->m_mr_mobile_pfx->begin ();
519  i != mip6d_conf->m_mr_mobile_pfx->end (); ++i)
520  {
521  if (i != mip6d_conf->m_mr_mobile_pfx->begin ())
522  {
523  conf << "," ;
524  }
525  conf << (*i);
526  }
527  conf << ")" << std::endl;
528  }
529  conf << ";" << std::endl;
530  conf << "}" << std::endl;
531  }
532 
533  if (mip6d_conf->m_debug)
534  {
535  conf << "DebugLevel 10;" << std::endl;
536  }
537 
538  conf << *mip6d_conf;
539  conf.close ();
540 
541 }
542 
543 
544 ApplicationContainer
545 Mip6dHelper::Install (Ptr<Node> node)
546 {
547  return ApplicationContainer (InstallPriv (node));
548 }
549 
550 ApplicationContainer
551 Mip6dHelper::Install (std::string nodeName)
552 {
553  Ptr<Node> node = Names::Find<Node> (nodeName);
554  return ApplicationContainer (InstallPriv (node));
555 }
556 
557 ApplicationContainer
558 Mip6dHelper::Install (NodeContainer c)
559 {
560  ApplicationContainer apps;
561  for (NodeContainer::Iterator i = c.Begin (); i != c.End (); ++i)
562  {
563  apps.Add (InstallPriv (*i));
564  }
565 
566  return apps;
567 }
568 
569 ApplicationContainer
570 Mip6dHelper::InstallPriv (Ptr<Node> node)
571 {
572  DceApplicationHelper process;
573  ApplicationContainer apps;
574 
575  Ptr<Mip6dConfig> mip6d_conf = node->GetObject<Mip6dConfig> ();
576  if (!mip6d_conf)
577  {
578  mip6d_conf = new Mip6dConfig ();
579  node->AggregateObject (mip6d_conf);
580  }
581  GenerateConfig (node);
582 
583  process.ResetArguments ();
584  process.SetBinary (mip6d_conf->m_binary);
585  process.ParseArguments ("-c /etc/mip6d.conf -d 10");
586  process.SetStackSize (1 << 16);
587  apps.Add (process.Install (node));
588  apps.Get (0)->SetStartTime (Seconds (1.0 + 0.01 * node->GetId ()));
589  node->AddApplication (apps.Get (0));
590 
591  return apps;
592 }
593 
594 } // namespace ns3