Initial IPv6 capability
authorvincent@clarinet.u-strasbg.fr
Fri Nov 07 11:36:15 2008 -0800 (2008-11-07)
changeset 38529cf7ad0cac85
parent 3851 cc6a7f93dc3f
child 3853 f04e7f61b1ed
Initial IPv6 capability
AUTHORS
examples/test-ipv6.cc
examples/wscript
src/devices/bridge/bridge-net-device.cc
src/devices/bridge/bridge-net-device.h
src/devices/csma/csma-net-device.cc
src/devices/csma/csma-net-device.h
src/devices/emu/emu-net-device.cc
src/devices/emu/emu-net-device.h
src/devices/point-to-point/point-to-point-net-device.cc
src/devices/point-to-point/point-to-point-net-device.h
src/devices/wifi/wifi-net-device.cc
src/devices/wifi/wifi-net-device.h
src/node/address-utils.cc
src/node/address-utils.h
src/node/icmp-socket.cc
src/node/icmp-socket.h
src/node/inet6-socket-address.cc
src/node/inet6-socket-address.h
src/node/ipv6-address.cc
src/node/ipv6-address.h
src/node/ipv6-header.cc
src/node/ipv6-header.h
src/node/mac48-address.cc
src/node/mac48-address.h
src/node/net-device.h
src/node/simple-net-device.cc
src/node/simple-net-device.h
src/node/wscript
     1.1 --- a/AUTHORS	Thu Nov 06 15:04:25 2008 -0800
     1.2 +++ b/AUTHORS	Fri Nov 07 11:36:15 2008 -0800
     1.3 @@ -9,4 +9,8 @@
     1.4  George F. Riley (riley@ece.gatech.edu)
     1.5  Guillaume Vu-Brugier (gvubrugier@gmail.com)
     1.6  Florian Westphal (fw@strlen.de)
     1.7 +Sebastien Vincent (vincent@lsiit.u-strasbg.fr)
     1.8 +David Gross (gdavid.devel@gmail.com)
     1.9 +Mehdi Benamor (mehdi.benamor@telecom-bretagne.eu)
    1.10 +Angelos Chatzipapas (chatzipa@ceid.upatras.gr)
    1.11  
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/examples/test-ipv6.cc	Fri Nov 07 11:36:15 2008 -0800
     2.3 @@ -0,0 +1,70 @@
     2.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
     2.5 +/*
     2.6 + * Copyright (c) 2008 Louis Pasteur University / Telecom Bretagne
     2.7 + *
     2.8 + * This program is free software; you can redistribute it and/or modify
     2.9 + * it under the terms of the GNU General Public License version 2 as
    2.10 + * published by the Free Software Foundation;
    2.11 + *
    2.12 + * This program is distributed in the hope that it will be useful,
    2.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.15 + * GNU General Public License for more details.
    2.16 + *
    2.17 + * You should have received a copy of the GNU General Public License
    2.18 + * along with this program; if not, write to the Free Software
    2.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.20 + *
    2.21 + * Author: Angelos Chatzipapas <Angelos.CHATZIPAPAS@enst-bretagne.fr> /
    2.22 + * <chatzipa@ceid.upatras.gr>
    2.23 + */
    2.24 +
    2.25 +#include "ns3/log.h"
    2.26 +//#include "ns3/ipv6.h"
    2.27 +#include "ns3/ipv6-address.h"
    2.28 +#include "ns3/node.h"
    2.29 +#include "ns3/mac48-address.h"
    2.30 +
    2.31 +NS_LOG_COMPONENT_DEFINE ("TestIpv6");
    2.32 +
    2.33 +using namespace ns3;
    2.34 +
    2.35 +int 
    2.36 +main (int argc, char *argv[])
    2.37 +{
    2.38 +  LogComponentEnable ("TestIpv6", LOG_LEVEL_ALL);
    2.39 +
    2.40 +  NS_LOG_INFO ("Test Ipv6");
    2.41 +
    2.42 +  Mac48Address m_addresses[10];
    2.43 +
    2.44 +  m_addresses[0]=("00:00:00:00:00:01");
    2.45 +  m_addresses[1]=("00:00:00:00:00:02");
    2.46 +  m_addresses[2]=("00:00:00:00:00:03");
    2.47 +  m_addresses[3]=("00:00:00:00:00:04");
    2.48 +  m_addresses[4]=("00:00:00:00:00:05");
    2.49 +  m_addresses[5]=("00:00:00:00:00:06");
    2.50 +  m_addresses[6]=("00:00:00:00:00:07");
    2.51 +  m_addresses[7]=("00:00:00:00:00:08");
    2.52 +  m_addresses[8]=("00:00:00:00:00:09");
    2.53 +  m_addresses[9]=("00:00:00:00:00:10");
    2.54 +
    2.55 +  Ipv6Address prefix1 ("2001:1::");
    2.56 +  NS_LOG_INFO ("prefix = " << prefix1);
    2.57 +  for (uint32_t i = 0; i < 10 ; ++i)
    2.58 +    {
    2.59 +      NS_LOG_INFO ("address = " <<m_addresses[i]);
    2.60 +      Ipv6Address ipv6address=Ipv6Address::MakeAutoconfiguredAddress(m_addresses[i], prefix1);
    2.61 +      NS_LOG_INFO ("address = " <<ipv6address);
    2.62 +    }
    2.63 +
    2.64 +  Ipv6Address prefix2 ("2002:1:1::");
    2.65 +
    2.66 +  NS_LOG_INFO ("prefix = " << prefix2);
    2.67 +  for (uint32_t i = 0; i < 10 ; ++i)
    2.68 +    {
    2.69 +      Ipv6Address ipv6address=Ipv6Address::MakeAutoconfiguredAddress(m_addresses[i], prefix2);
    2.70 +      NS_LOG_INFO ("address = " <<ipv6address);
    2.71 +    }
    2.72 +}
    2.73 +
     3.1 --- a/examples/wscript	Thu Nov 06 15:04:25 2008 -0800
     3.2 +++ b/examples/wscript	Fri Nov 07 11:36:15 2008 -0800
     3.3 @@ -106,3 +106,7 @@
     3.4      obj = bld.create_ns3_program('csma-ping',
     3.5          ['csma', 'internet-stack', 'v4ping'])
     3.6      obj.source = 'csma-ping.cc'
     3.7 +
     3.8 +    obj = bld.create_ns3_program('test-ipv6',
     3.9 +      ['point-to-point', 'internet-stack'])
    3.10 +    obj.source = 'test-ipv6.cc'
     4.1 --- a/src/devices/bridge/bridge-net-device.cc	Thu Nov 06 15:04:25 2008 -0800
     4.2 +++ b/src/devices/bridge/bridge-net-device.cc	Fri Nov 07 11:36:15 2008 -0800
     4.3 @@ -380,6 +380,10 @@
     4.4    NetDevice::DoDispose ();
     4.5  }
     4.6  
     4.7 -
     4.8 +Address BridgeNetDevice::GetMulticast (Ipv6Address addr) const
     4.9 +{
    4.10 +  NS_LOG_FUNCTION (this << addr);
    4.11 +  return Mac48Address::GetMulticast (addr);
    4.12 +}
    4.13  
    4.14  } // namespace ns3
     5.1 --- a/src/devices/bridge/bridge-net-device.h	Thu Nov 06 15:04:25 2008 -0800
     5.2 +++ b/src/devices/bridge/bridge-net-device.h	Fri Nov 07 11:36:15 2008 -0800
     5.3 @@ -106,6 +106,7 @@
     5.4    virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
     5.5    virtual void SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb);
     5.6    virtual bool SupportsSendFrom () const;
     5.7 +  virtual Address GetMulticast (Ipv6Address addr) const;
     5.8  
     5.9  protected:
    5.10    virtual void DoDispose (void);
     6.1 --- a/src/devices/csma/csma-net-device.cc	Thu Nov 06 15:04:25 2008 -0800
     6.2 +++ b/src/devices/csma/csma-net-device.cc	Fri Nov 07 11:36:15 2008 -0800
     6.3 @@ -600,6 +600,20 @@
     6.4    NS_LOG_FUNCTION (packet << senderDevice);
     6.5    NS_LOG_LOGIC ("UID is " << packet->GetUid ());
     6.6  
     6.7 +  /* IPv6 support*/
     6.8 +  uint8_t mac[6];
     6.9 +  Mac48Address multicast6AllNodes("33:33:00:00:00:01");
    6.10 +  Mac48Address multicast6AllRouters("33:33:00:00:00:02");
    6.11 +  Mac48Address multicast6AllHosts("33:33:00:00:00:03");
    6.12 +  Mac48Address multicast6Node; /* multicast address addressed to our MAC address */
    6.13 +
    6.14 +  /* generate IPv6 multicast ethernet destination that nodes will accept */
    6.15 +  GetAddress().CopyTo(mac);
    6.16 +  mac[0]=0x33;
    6.17 +  mac[1]=0x33;
    6.18 +  /* mac[2]=0xff; */
    6.19 +  multicast6Node.CopyFrom(mac);
    6.20 +
    6.21    //
    6.22    // We never forward up packets that we sent. Real devices don't do this since
    6.23    // their receivers are disabled during send, so we don't. Drop the packet
    6.24 @@ -672,7 +686,11 @@
    6.25            packetType = PACKET_BROADCAST;
    6.26            m_rxTrace (originalPacket);
    6.27          }
    6.28 -      else if (header.GetDestination ().IsMulticast ())
    6.29 +      else if (header.GetDestination ().IsMulticast () ||
    6.30 +          header.GetDestination() == multicast6Node ||
    6.31 +          header.GetDestination() == multicast6AllNodes ||
    6.32 +          header.GetDestination() == multicast6AllRouters ||
    6.33 +          header.GetDestination() == multicast6AllHosts)
    6.34          {
    6.35            packetType = PACKET_MULTICAST;          
    6.36            m_rxTrace (originalPacket);
    6.37 @@ -922,6 +940,14 @@
    6.38    m_rxCallback = cb;
    6.39  }
    6.40  
    6.41 +Address CsmaNetDevice::GetMulticast (Ipv6Address addr) const
    6.42 +{
    6.43 +  Mac48Address ad = Mac48Address::GetMulticast (addr);
    6.44 +
    6.45 +  NS_LOG_LOGIC("MAC IPv6 multicast address is " << ad);
    6.46 +  return ad;
    6.47 +}
    6.48 +
    6.49    void 
    6.50  CsmaNetDevice::SetPromiscReceiveCallback (NetDevice::PromiscReceiveCallback cb)
    6.51  {
     7.1 --- a/src/devices/csma/csma-net-device.h	Thu Nov 06 15:04:25 2008 -0800
     7.2 +++ b/src/devices/csma/csma-net-device.h	Fri Nov 07 11:36:15 2008 -0800
     7.3 @@ -392,6 +392,15 @@
     7.4     */
     7.5    virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
     7.6  
     7.7 +  /**
     7.8 +   * \brief Get the MAC multicast address corresponding
     7.9 +   * to the IPv6 address provided.
    7.10 +   * \param addr IPv6 address
    7.11 +   * \return the MAC multicast address
    7.12 +   * \warning Calling this method is invalid if IsMulticast returns not true.
    7.13 +   */
    7.14 +  virtual Address GetMulticast (Ipv6Address addr) const;
    7.15 +
    7.16  
    7.17    virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
    7.18    virtual bool SupportsSendFrom (void) const;
     8.1 --- a/src/devices/emu/emu-net-device.cc	Thu Nov 06 15:04:25 2008 -0800
     8.2 +++ b/src/devices/emu/emu-net-device.cc	Fri Nov 07 11:36:15 2008 -0800
     8.3 @@ -865,6 +865,17 @@
     8.4    return ad;
     8.5  }
     8.6  
     8.7 +Address
     8.8 +EmuNetDevice::GetMulticast (Ipv6Address addr) const
     8.9 +{
    8.10 +  NS_LOG_FUNCTION(this << addr);
    8.11 +
    8.12 +  Mac48Address ad = Mac48Address::GetMulticast (addr);
    8.13 +  NS_LOG_LOGIC("MAC IPv6 multicast address is " << ad);
    8.14 +
    8.15 +  return ad;
    8.16 +}
    8.17 +
    8.18  bool 
    8.19  EmuNetDevice::IsPointToPoint (void) const
    8.20  {
     9.1 --- a/src/devices/emu/emu-net-device.h	Thu Nov 06 15:04:25 2008 -0800
     9.2 +++ b/src/devices/emu/emu-net-device.h	Fri Nov 07 11:36:15 2008 -0800
     9.3 @@ -151,6 +151,15 @@
     9.4    virtual Address GetMulticast (Ipv4Address multicastGroup) const;
     9.5  
     9.6    /**
     9.7 +   * \brief Get the MAC multicast address corresponding
     9.8 +   * to the IPv6 address provided.
     9.9 +   * \param addr IPv6 address
    9.10 +   * \return the MAC multicast address
    9.11 +   * \warning Calling this method is invalid if IsMulticast returns not true.
    9.12 +   */
    9.13 +  virtual Address GetMulticast (Ipv6Address addr) const;
    9.14 +
    9.15 +  /**
    9.16     * Is this a point to point link?
    9.17     * \returns false.
    9.18     */
    10.1 --- a/src/devices/point-to-point/point-to-point-net-device.cc	Thu Nov 06 15:04:25 2008 -0800
    10.2 +++ b/src/devices/point-to-point/point-to-point-net-device.cc	Fri Nov 07 11:36:15 2008 -0800
    10.3 @@ -378,6 +378,13 @@
    10.4    return Mac48Address ("01:00:5e:00:00:00");
    10.5  }
    10.6  
    10.7 +Address
    10.8 +PointToPointNetDevice::GetMulticast (Ipv6Address addr) const
    10.9 +{
   10.10 +  NS_LOG_FUNCTION(this << addr);
   10.11 +  return Mac48Address ("33:33:00:00:00:00");
   10.12 +}
   10.13 +
   10.14    bool 
   10.15  PointToPointNetDevice::IsPointToPoint (void) const
   10.16  {
    11.1 --- a/src/devices/point-to-point/point-to-point-net-device.h	Thu Nov 06 15:04:25 2008 -0800
    11.2 +++ b/src/devices/point-to-point/point-to-point-net-device.h	Fri Nov 07 11:36:15 2008 -0800
    11.3 @@ -263,6 +263,8 @@
    11.4  
    11.5    virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
    11.6  
    11.7 +  virtual Address GetMulticast (Ipv6Address addr) const;
    11.8 +
    11.9    virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
   11.10    virtual bool SupportsSendFrom (void) const;
   11.11  
    12.1 --- a/src/devices/wifi/wifi-net-device.cc	Thu Nov 06 15:04:25 2008 -0800
    12.2 +++ b/src/devices/wifi/wifi-net-device.cc	Fri Nov 07 11:36:15 2008 -0800
    12.3 @@ -257,6 +257,10 @@
    12.4  {
    12.5    return Mac48Address::GetMulticast (multicastGroup);
    12.6  }
    12.7 +Address WifiNetDevice::GetMulticast (Ipv6Address addr) const
    12.8 +{
    12.9 +  return Mac48Address::GetMulticast (addr);
   12.10 +}
   12.11  bool 
   12.12  WifiNetDevice::IsPointToPoint (void) const
   12.13  {
    13.1 --- a/src/devices/wifi/wifi-net-device.h	Thu Nov 06 15:04:25 2008 -0800
    13.2 +++ b/src/devices/wifi/wifi-net-device.h	Fri Nov 07 11:36:15 2008 -0800
    13.3 @@ -100,6 +100,8 @@
    13.4    virtual bool NeedsArp (void) const;
    13.5    virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
    13.6  
    13.7 +  virtual Address GetMulticast (Ipv6Address addr) const;
    13.8 +
    13.9    virtual bool SendFrom(Ptr<Packet> packet, const Address& source, const Address& dest, uint16_t protocolNumber);
   13.10    virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
   13.11    virtual bool SupportsSendFrom (void) const;
    14.1 --- a/src/node/address-utils.cc	Thu Nov 06 15:04:25 2008 -0800
    14.2 +++ b/src/node/address-utils.cc	Fri Nov 07 11:36:15 2008 -0800
    14.3 @@ -25,6 +25,12 @@
    14.4  {
    14.5    i.WriteHtonU32 (ad.Get ());
    14.6  }
    14.7 +void WriteTo (Buffer::Iterator &i, Ipv6Address ad)
    14.8 +{
    14.9 +  uint8_t buf[16];
   14.10 +  ad.GetBytes(buf);
   14.11 +  i.Write(buf, 16);
   14.12 +}
   14.13  void WriteTo (Buffer::Iterator &i, const Address &ad)
   14.14  {
   14.15    uint8_t mac[Address::MAX_SIZE];
   14.16 @@ -42,6 +48,12 @@
   14.17  {
   14.18    ad.Set (i.ReadNtohU32 ());
   14.19  }
   14.20 +void ReadFrom (Buffer::Iterator &i, Ipv6Address &ad)
   14.21 +{
   14.22 +  uint8_t ipv6[16];
   14.23 +  i.Read(ipv6, 16);
   14.24 +  ad.Set (ipv6);
   14.25 +}
   14.26  void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len)
   14.27  {
   14.28    uint8_t mac[Address::MAX_SIZE];
    15.1 --- a/src/node/address-utils.h	Thu Nov 06 15:04:25 2008 -0800
    15.2 +++ b/src/node/address-utils.h	Fri Nov 07 11:36:15 2008 -0800
    15.3 @@ -22,16 +22,19 @@
    15.4  
    15.5  #include "ns3/buffer.h"
    15.6  #include "ipv4-address.h"
    15.7 +#include "ipv6-address.h"
    15.8  #include "address.h"
    15.9  #include "mac48-address.h"
   15.10  
   15.11  namespace ns3 {
   15.12  
   15.13  void WriteTo (Buffer::Iterator &i, Ipv4Address ad);
   15.14 +void WriteTo (Buffer::Iterator &i, Ipv6Address ad);
   15.15  void WriteTo (Buffer::Iterator &i, const Address &ad);
   15.16  void WriteTo (Buffer::Iterator &i, Mac48Address ad);
   15.17  
   15.18  void ReadFrom (Buffer::Iterator &i, Ipv4Address &ad);
   15.19 +void ReadFrom (Buffer::Iterator &i, Ipv6Address &ad);
   15.20  void ReadFrom (Buffer::Iterator &i, Address &ad, uint32_t len);
   15.21  void ReadFrom (Buffer::Iterator &i, Mac48Address &ad);
   15.22  
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/src/node/icmp-socket.cc	Fri Nov 07 11:36:15 2008 -0800
    16.3 @@ -0,0 +1,58 @@
    16.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
    16.5 +/*
    16.6 + * Copyright (c) 2008 Louis Pasteur University
    16.7 + *
    16.8 + * This program is free software; you can redistribute it and/or modify
    16.9 + * it under the terms of the GNU General Public License version 2 as
   16.10 + * published by the Free Software Foundation;
   16.11 + *
   16.12 + * This program is distributed in the hope that it will be useful,
   16.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   16.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16.15 + * GNU General Public License for more details.
   16.16 + *
   16.17 + * You should have received a copy of the GNU General Public License
   16.18 + * along with this program; if not, write to the Free Software
   16.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   16.20 + *
   16.21 + * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
   16.22 + */
   16.23 +
   16.24 +#include "ns3/object.h"
   16.25 +#include "ns3/log.h"
   16.26 +#include "ns3/uinteger.h"
   16.27 +#include "ns3/trace-source-accessor.h"
   16.28 +#include "icmp-socket.h"
   16.29 +
   16.30 +NS_LOG_COMPONENT_DEFINE ("IcmpSocket");
   16.31 +
   16.32 +namespace ns3 {
   16.33 +
   16.34 +  NS_OBJECT_ENSURE_REGISTERED (IcmpSocket);
   16.35 +
   16.36 +  TypeId IcmpSocket::GetTypeId (void)
   16.37 +  {
   16.38 +    static TypeId tid = TypeId ("ns3::IcmpSocket")
   16.39 +      .SetParent<Socket> ()
   16.40 +      .AddAttribute ("RcvBufSize",
   16.41 +          "IcmpSocket maximum receive buffer size (bytes)",
   16.42 +          UintegerValue (0xffffffffl),
   16.43 +          MakeUintegerAccessor (&IcmpSocket::GetRcvBufSize,
   16.44 +            &IcmpSocket::SetRcvBufSize),
   16.45 +          MakeUintegerChecker<uint32_t> ())
   16.46 +      ;
   16.47 +    return tid;
   16.48 +  }
   16.49 +
   16.50 +  IcmpSocket::IcmpSocket (void)
   16.51 +  {
   16.52 +    NS_LOG_FUNCTION_NOARGS ();
   16.53 +  }
   16.54 +
   16.55 +  IcmpSocket::~IcmpSocket (void)
   16.56 +  {
   16.57 +    NS_LOG_FUNCTION_NOARGS ();
   16.58 +  }
   16.59 +
   16.60 +}; /* namespace ns3 */
   16.61 +
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/src/node/icmp-socket.h	Fri Nov 07 11:36:15 2008 -0800
    17.3 @@ -0,0 +1,177 @@
    17.4 +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    17.5 +/*
    17.6 + * Copyright (c) 2008 Louis Pasteur University
    17.7 + *
    17.8 + * This program is free software; you can redistribute it and/or modify
    17.9 + * it under the terms of the GNU General Public License version 2 as
   17.10 + * published by the Free Software Foundation;
   17.11 + *
   17.12 + * This program is distributed in the hope that it will be useful,
   17.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17.15 + * GNU General Public License for more details.
   17.16 + *
   17.17 + * You should have received a copy of the GNU General Public License
   17.18 + * along with this program; if not, write to the Free Software
   17.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   17.20 + *
   17.21 + * Authors: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
   17.22 + */
   17.23 +
   17.24 +#ifndef ICMP_SOCKET_H
   17.25 +#define ICMP_SOCKET_H
   17.26 +
   17.27 +#include "socket.h"
   17.28 +#include "ns3/traced-callback.h"
   17.29 +#include "ns3/callback.h"
   17.30 +#include "ns3/ptr.h"
   17.31 +#include "ns3/object.h"
   17.32 +
   17.33 +namespace ns3 {
   17.34 +
   17.35 +class Node;
   17.36 +class Packet;
   17.37 +
   17.38 +/**
   17.39 + * \brief (abstract) base class of all IcmpSockets (for IPv4 or IPv6).
   17.40 + *
   17.41 + * This class exists solely for hosting IcmpSocket attributes that can
   17.42 + * be reused across different implementations.
   17.43 + */
   17.44 +class IcmpSocket : public Socket
   17.45 +{
   17.46 +  public:
   17.47 +    /**
   17.48 +     * \brief Get the UID of this class.
   17.49 +     * \return UID
   17.50 +     */
   17.51 +    static TypeId GetTypeId (void);
   17.52 +
   17.53 +    /**
   17.54 +     * \brief Constructor.
   17.55 +     */
   17.56 +    IcmpSocket (void);
   17.57 +
   17.58 +    /**
   17.59 +     * \brief Destructor.
   17.60 +     */
   17.61 +    virtual ~IcmpSocket (void);
   17.62 +
   17.63 +    /**
   17.64 +     * \brief Get the error.
   17.65 +     * \return the error.
   17.66 +     */
   17.67 +    virtual enum Socket::SocketErrno GetErrno (void) const = 0;
   17.68 +
   17.69 +    /**
   17.70 +     * \brief Get the node.
   17.71 +     * \return the node
   17.72 +     */
   17.73 +    virtual Ptr<Node> GetNode (void) const = 0;
   17.74 +
   17.75 +    /**
   17.76 +     * \brief Bind the socket.
   17.77 +     * \return 0 if OK, -1 otherwise
   17.78 +     */
   17.79 +    virtual int Bind (void) = 0;
   17.80 +
   17.81 +    /**
   17.82 +     * \brief Bind the socket on "addr".
   17.83 +     * \param addr address
   17.84 +     * \return 0 if OK, -1 otherwise
   17.85 +     */
   17.86 +    virtual int Bind (const Address &addr) = 0;
   17.87 +
   17.88 +    /**
   17.89 +     * \brief Close the socket.
   17.90 +     * \return 0 if OK, -1 otherwise
   17.91 +     */
   17.92 +    virtual int Close (void) = 0;
   17.93 +
   17.94 +    /**
   17.95 +     * \brief Shutdown the socket on send.
   17.96 +     * \return 0 if OK, -1 otherwise
   17.97 +     */
   17.98 +    virtual int ShutdownSend (void) = 0;
   17.99 +
  17.100 +    /**
  17.101 +     * \brief Shutdown the socket on receive.
  17.102 +     * \return 0 if OK, -1 otherwise
  17.103 +     */
  17.104 +    virtual int ShutdownRecv (void) = 0;
  17.105 +
  17.106 +    /**
  17.107 +     * \brief Connect to another node.
  17.108 +     * \param addr address
  17.109 +     * \return 0 if OK, -1 otherwise
  17.110 +     */
  17.111 +    virtual int Connect (const Address &addr) = 0;
  17.112 +
  17.113 +    /**
  17.114 +     * \brief Send a packet.
  17.115 +     * \param p the packet to send
  17.116 +     * \param flags flags
  17.117 +     * \return 0 if OK, -1 otherwise
  17.118 +     */		
  17.119 +    virtual int Send (Ptr<Packet> p, uint32_t flags) = 0;
  17.120 +
  17.121 +    /**
  17.122 +     * \brief Get the maximum message size available.
  17.123 +     * \return maximum message size
  17.124 +     * \warning size of a message that could be sent is limited by the link MTU.
  17.125 +     */
  17.126 +    virtual uint32_t GetTxAvailable (void) const = 0;
  17.127 +
  17.128 +    /**
  17.129 +     * \brief Send a packet to a node.
  17.130 +     * \param addr the address of the node
  17.131 +     * \param flags flags
  17.132 +     * \param p the packet to send
  17.133 +     * \return 0 if OK, -1 otherwise
  17.134 +     */
  17.135 +    virtual int SendTo (Ptr<Packet> p, uint32_t flags, const Address &addr) = 0;
  17.136 +
  17.137 +    /**
  17.138 +     * \brief Receive method.
  17.139 +     * \param maxSize maximum size we want to return
  17.140 +     * \param flags flags
  17.141 +     * \return a packet with at maximum maxSize size
  17.142 +     */
  17.143 +    virtual Ptr<Packet> Recv (uint32_t maxSize, uint32_t flags) = 0;
  17.144 +
  17.145 +    /**
  17.146 +     * \brief Receive method.
  17.147 +     * \param maxSize maximum size we want to return
  17.148 +     * \param flags flags
  17.149 +     * \param fromAddress sender address
  17.150 +     * \return a packet with at maximum maxSize size
  17.151 +     */
  17.152 +    virtual Ptr<Packet> RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress) = 0;
  17.153 +
  17.154 +    /**
  17.155 +     * \brief Get the size we could receive.
  17.156 +     * \return size we could receive at one moment
  17.157 +     */
  17.158 +    virtual uint32_t GetRxAvailable (void) const = 0;
  17.159 +
  17.160 +  private:
  17.161 +    /**
  17.162 +     * \brief Get the receive buffer size.
  17.163 +     * \return receive buffer size
  17.164 +     */
  17.165 +    virtual uint32_t GetRcvBufSize (void) const = 0;
  17.166 +
  17.167 +    /**
  17.168 +     * \brief Set the receive buffer size.
  17.169 +     * \param rcvBufSize size to set
  17.170 +     */
  17.171 +    virtual void SetRcvBufSize (uint32_t rcvBufSize) = 0;
  17.172 +
  17.173 +    /* FIXME : add ICMP basic attribute for socket */
  17.174 +    /* Indirect the attribute setting and getting through private virtual methods */
  17.175 +};
  17.176 +
  17.177 +} /* namespace ns3 */
  17.178 +
  17.179 +#endif /* ICMP_SOCKET_H */
  17.180 +
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/src/node/inet6-socket-address.cc	Fri Nov 07 11:36:15 2008 -0800
    18.3 @@ -0,0 +1,112 @@
    18.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
    18.5 +/*
    18.6 + * Copyright (c) 2007-2008 Louis Pasteur University
    18.7 + *
    18.8 + * This program is free software; you can redistribute it and/or modify
    18.9 + * it under the terms of the GNU General Public License version 2 as
   18.10 + * published by the Free Software Foundation;
   18.11 + *
   18.12 + * This program is distributed in the hope that it will be useful,
   18.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   18.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18.15 + * GNU General Public License for more details.
   18.16 + *
   18.17 + * You should have received a copy of the GNU General Public License
   18.18 + * along with this program; if not, write to the Free Software
   18.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   18.20 + *
   18.21 + * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
   18.22 + */
   18.23 +
   18.24 +#include "inet6-socket-address.h"
   18.25 +#include "ns3/assert.h"
   18.26 +
   18.27 +namespace ns3 {
   18.28 +
   18.29 +Inet6SocketAddress::Inet6SocketAddress (Ipv6Address ipv6, uint16_t port)
   18.30 +: m_ipv6(ipv6),
   18.31 +  m_port(port)
   18.32 +{
   18.33 +}
   18.34 +
   18.35 +Inet6SocketAddress::Inet6SocketAddress (Ipv6Address ipv6)
   18.36 +: m_ipv6(ipv6),
   18.37 +  m_port(0)
   18.38 +{
   18.39 +}
   18.40 +
   18.41 +  Inet6SocketAddress::Inet6SocketAddress (const char* ipv6, uint16_t port)
   18.42 +: m_ipv6(Ipv6Address(ipv6)),
   18.43 +  m_port(port)
   18.44 +{
   18.45 +}
   18.46 +
   18.47 +  Inet6SocketAddress::Inet6SocketAddress (const char* ipv6)
   18.48 +: m_ipv6(Ipv6Address(ipv6)),
   18.49 +  m_port(0)
   18.50 +{
   18.51 +}
   18.52 +
   18.53 +  Inet6SocketAddress::Inet6SocketAddress (uint16_t port)
   18.54 +: m_ipv6(Ipv6Address::GetAny()),
   18.55 +  m_port(port)
   18.56 +{
   18.57 +}
   18.58 +
   18.59 +uint16_t Inet6SocketAddress::GetPort (void) const
   18.60 +{
   18.61 +  return m_port;
   18.62 +}
   18.63 +
   18.64 +void Inet6SocketAddress::SetPort (uint16_t port)
   18.65 +{
   18.66 +  m_port=port;
   18.67 +}
   18.68 +
   18.69 +Ipv6Address Inet6SocketAddress::GetIpv6 (void) const
   18.70 +{
   18.71 +  return m_ipv6;
   18.72 +}
   18.73 +
   18.74 +void Inet6SocketAddress::SetIpv6 (Ipv6Address ipv6)
   18.75 +{
   18.76 +  m_ipv6=ipv6;
   18.77 +}
   18.78 +
   18.79 +bool Inet6SocketAddress::IsMatchingType (const Address &addr)
   18.80 +{
   18.81 +  return addr.CheckCompatible(GetType(), 18); /* 16 (address) + 2  (port) */
   18.82 +}
   18.83 +
   18.84 +Inet6SocketAddress::operator Address (void) const
   18.85 +{
   18.86 +  return ConvertTo();
   18.87 +}
   18.88 +
   18.89 +Address Inet6SocketAddress::ConvertTo (void) const
   18.90 +{
   18.91 +  uint8_t buf[18];
   18.92 +  m_ipv6.Serialize(buf);
   18.93 +  buf[16]=m_port & 0xff;
   18.94 +  buf[17]=(m_port >> 8) &0xff;
   18.95 +  return Address(GetType(), buf, 18);
   18.96 +}
   18.97 +
   18.98 +Inet6SocketAddress Inet6SocketAddress::ConvertFrom (const Address &addr)
   18.99 +{
  18.100 +  NS_ASSERT(addr.CheckCompatible(GetType(), 18));
  18.101 +  uint8_t buf[18];
  18.102 +  addr.CopyTo(buf);
  18.103 +  Ipv6Address ipv6=Ipv6Address::Deserialize(buf);
  18.104 +  uint16_t port= buf[16] | (buf[17] << 8);
  18.105 +  return Inet6SocketAddress(ipv6, port);
  18.106 +}
  18.107 +
  18.108 +uint8_t Inet6SocketAddress::GetType (void)
  18.109 +{
  18.110 +  static uint8_t type=Address::Register();
  18.111 +  return type;
  18.112 +}
  18.113 +
  18.114 +} /* namespace ns3 */
  18.115 +
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/src/node/inet6-socket-address.h	Fri Nov 07 11:36:15 2008 -0800
    19.3 @@ -0,0 +1,140 @@
    19.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
    19.5 +/*
    19.6 + * Copyright (c) 2007-2008 Louis Pasteur University
    19.7 + *
    19.8 + * This program is free software; you can redistribute it and/or modify
    19.9 + * it under the terms of the GNU General Public License version 2 as
   19.10 + * published by the Free Software Foundation;
   19.11 + *
   19.12 + * This program is distributed in the hope that it will be useful,
   19.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   19.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19.15 + * GNU General Public License for more details.
   19.16 + *
   19.17 + * You should have received a copy of the GNU General Public License
   19.18 + * along with this program; if not, write to the Free Software
   19.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19.20 + *
   19.21 + * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
   19.22 + */
   19.23 +
   19.24 +#ifndef INET6_SOCKET_ADDRESS_H 
   19.25 +#define INET6_SOCKET_ADDRESS_H
   19.26 +
   19.27 +#include "address.h"
   19.28 +#include "ipv6-address.h"
   19.29 +#include <stdint.h>
   19.30 +
   19.31 +namespace ns3 {
   19.32 +
   19.33 +/**
   19.34 + * \class Inet6SocketAddress
   19.35 + * \brief An Inet6 address class.
   19.36 + */
   19.37 +class Inet6SocketAddress
   19.38 +{
   19.39 +  public:
   19.40 +    /**
   19.41 +     * \brief Constructor.
   19.42 +     * \param ipv6 the IPv6 address
   19.43 +     * \param port the port
   19.44 +     */
   19.45 +    Inet6SocketAddress (Ipv6Address ipv6, uint16_t port);
   19.46 +
   19.47 +    /**
   19.48 +     * \brief Constructor (the port is set to zero).
   19.49 +     * \param ipv6 the IPv6 address
   19.50 +     */
   19.51 +    Inet6SocketAddress (Ipv6Address ipv6);
   19.52 +
   19.53 +    /**
   19.54 +     * \brief Constructor (the address is set to "any").
   19.55 +     * \param port the port
   19.56 +     */
   19.57 +    Inet6SocketAddress (uint16_t port);
   19.58 +
   19.59 +    /**
   19.60 +     * \brief Constructor.
   19.61 +     * \param ipv6 string which represents an IPv6 address
   19.62 +     * \param port the port
   19.63 +     */
   19.64 +    Inet6SocketAddress (const char* ipv6, uint16_t port);
   19.65 +
   19.66 +    /**
   19.67 +     * \brief Constructor.
   19.68 +     * \param ipv6 string which represents an IPv6 address
   19.69 +     */
   19.70 +    Inet6SocketAddress (const char* ipv6);
   19.71 +
   19.72 +    /**
   19.73 +     * \brief Get the port.
   19.74 +     * \return the port
   19.75 +     */
   19.76 +    uint16_t GetPort (void) const;
   19.77 +
   19.78 +    /**
   19.79 +     * \brief Set the port
   19.80 +     * \param port the port
   19.81 +     */
   19.82 +    void SetPort (uint16_t port);
   19.83 +
   19.84 +    /**
   19.85 +     * \brief Get the IPv6 address.
   19.86 +     * \return the IPv6 address
   19.87 +     */
   19.88 +    Ipv6Address GetIpv6 (void) const;
   19.89 +
   19.90 +    /**
   19.91 +     * \brief Set the IPv6 address.
   19.92 +     * \param ipv6 the address
   19.93 +     */
   19.94 +    void SetIpv6 (Ipv6Address ipv6);
   19.95 +
   19.96 +    /**
   19.97 +     * \brief If the address match.
   19.98 +     * \param addr the address to test
   19.99 +     * \return true if the address match, false otherwise
  19.100 +     */
  19.101 +    static bool IsMatchingType (const Address &addr);
  19.102 +
  19.103 +    /**
  19.104 +     * \brief Get an Address instance which represents this
  19.105 +     * Inet6SocketAddress instance.
  19.106 +     */
  19.107 +    operator Address (void) const;
  19.108 +
  19.109 +    /**
  19.110 +     * \brief Convert the address to a InetSocketAddress.
  19.111 +     * \param addr the address to convert
  19.112 +     * \return an Inet6SocketAddress instance corresponding to address
  19.113 +     */
  19.114 +    static Inet6SocketAddress ConvertFrom (const Address &addr);
  19.115 +
  19.116 +  private:
  19.117 +    /**
  19.118 +     * \brief Convert to Address.
  19.119 +     * \return Address instance
  19.120 +     */
  19.121 +    Address ConvertTo (void) const;
  19.122 +
  19.123 +    /**
  19.124 +     * \brief Get the type.
  19.125 +     * \return the type of Inet6SocketAddress
  19.126 +     */
  19.127 +    static uint8_t GetType (void);
  19.128 +
  19.129 +    /**
  19.130 +     * \brief The IPv6 address.
  19.131 +     */
  19.132 +    Ipv6Address m_ipv6;
  19.133 +
  19.134 +    /**
  19.135 +     * \brief The port.
  19.136 +     */
  19.137 +    uint16_t m_port;
  19.138 +};
  19.139 +
  19.140 +} /* namespace ns3 */
  19.141 +
  19.142 +#endif /* INET6_SOCKET_ADDRESS_H */
  19.143 +
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/src/node/ipv6-address.cc	Fri Nov 07 11:36:15 2008 -0800
    20.3 @@ -0,0 +1,686 @@
    20.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
    20.5 +/*
    20.6 + * Copyright (c) 2007-2008 Louis Pasteur University
    20.7 + *
    20.8 + * This program is free software; you can redistribute it and/or modify
    20.9 + * it under the terms of the GNU General Public License version 2 as
   20.10 + * published by the Free Software Foundation;
   20.11 + *
   20.12 + * This program is distributed in the hope that it will be useful,
   20.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   20.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   20.15 + * GNU General Public License for more details.
   20.16 + *
   20.17 + * You should have received a copy of the GNU General Public License
   20.18 + * along with this program; if not, write to the Free Software
   20.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   20.20 + *
   20.21 + * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
   20.22 + */
   20.23 +
   20.24 +#include <string.h>
   20.25 +
   20.26 +#include "ns3/log.h"
   20.27 +#include "ipv6-address.h"
   20.28 +#include "ns3/assert.h"
   20.29 +#include "mac48-address.h"
   20.30 +
   20.31 +#include <iomanip>
   20.32 +
   20.33 +NS_LOG_COMPONENT_DEFINE ("Ipv6Address");
   20.34 +
   20.35 +namespace ns3 {
   20.36 +
   20.37 +#ifdef __cplusplus
   20.38 +extern "C"
   20.39 +{
   20.40 +#endif
   20.41 +
   20.42 +  /**
   20.43 +   * \brief Get a hash key.
   20.44 +   * \param k the key
   20.45 +   * \param length the length of the key
   20.46 +   * \param level the previous hash, or an arbitrary value
   20.47 +   * \return hash
   20.48 +   * \note Adpated from Jens Jakobsen implementation (chillispot).
   20.49 +   */
   20.50 +  static uint32_t lookuphash (unsigned char* k, uint32_t length, uint32_t level)
   20.51 +  {
   20.52 +#define mix(a,b,c) \
   20.53 +    { \
   20.54 +      a -= b; a -= c; a ^= (c>>13); \
   20.55 +      b -= c; b -= a; b ^= (a<<8); \
   20.56 +      c -= a; c -= b; c ^= (b>>13); \
   20.57 +      a -= b; a -= c; a ^= (c>>12);  \
   20.58 +      b -= c; b -= a; b ^= (a<<16); \
   20.59 +      c -= a; c -= b; c ^= (b>>5); \
   20.60 +      a -= b; a -= c; a ^= (c>>3);  \
   20.61 +      b -= c; b -= a; b ^= (a<<10); \
   20.62 +      c -= a; c -= b; c ^= (b>>15); \
   20.63 +    }
   20.64 +
   20.65 +    typedef uint32_t  ub4;   /* unsigned 4-byte quantities */
   20.66 +    typedef unsigned  char ub1;   /* unsigned 1-byte quantities */
   20.67 +    uint32_t a,b,c,len;
   20.68 +
   20.69 +    /* Set up the internal state */
   20.70 +    len = length;
   20.71 +    a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
   20.72 +    c = level;           /* the previous hash value */
   20.73 +
   20.74 +    /*---------------------------------------- handle most of the key */
   20.75 +    while (len >= 12)
   20.76 +    {
   20.77 +      a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24));
   20.78 +      b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24));
   20.79 +      c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24));
   20.80 +      mix(a,b,c);
   20.81 +      k += 12; len -= 12;
   20.82 +    }
   20.83 +
   20.84 +    /*------------------------------------- handle the last 11 bytes */
   20.85 +    c += length;
   20.86 +    switch(len)              /* all the case statements fall through */
   20.87 +    {
   20.88 +      case 11: c+=((ub4)k[10]<<24);
   20.89 +      case 10: c+=((ub4)k[9]<<16);
   20.90 +      case 9 : c+=((ub4)k[8]<<8);
   20.91 +               /* the first byte of c is reserved for the length */
   20.92 +      case 8 : b+=((ub4)k[7]<<24);
   20.93 +      case 7 : b+=((ub4)k[6]<<16);
   20.94 +      case 6 : b+=((ub4)k[5]<<8);
   20.95 +      case 5 : b+=k[4];
   20.96 +      case 4 : a+=((ub4)k[3]<<24);
   20.97 +      case 3 : a+=((ub4)k[2]<<16);
   20.98 +      case 2 : a+=((ub4)k[1]<<8);
   20.99 +      case 1 : a+=k[0];
  20.100 +               /* case 0: nothing left to add */
  20.101 +    }
  20.102 +    mix(a,b,c);
  20.103 +    /*-------------------------------------------- report the result */
  20.104 +    return c;
  20.105 +  }
  20.106 +#ifdef __cplusplus
  20.107 +}
  20.108 +#endif
  20.109 +
  20.110 +/**
  20.111 + * \brief Convert an IPv6 C-string into a 128-bit representation.
  20.112 + * \return 1 if OK, 0 if failure (bad format, ...)
  20.113 + * \note This function is strongly inspired by inet_pton6() from Paul Vixie.
  20.114 + * \todo Handle IPv6 address with decimal value for last four bytes.
  20.115 + */
  20.116 +static int AsciiToIpv6Host (char const *address, uint8_t addr[16])
  20.117 +{
  20.118 +  static const char xdigits_l[] = "0123456789abcdef",
  20.119 +               xdigits_u[] = "0123456789ABCDEF";
  20.120 +  unsigned char tmp[16 /*NS_IN6ADDRSZ*/], *tp, *endp, *colonp;
  20.121 +  const char *xdigits, *curtok;
  20.122 +  int ch, seen_xdigits;
  20.123 +  unsigned int val;
  20.124 +
  20.125 +  memset((tp = tmp), '\0', 16 /* NS_IN6ADDRSZ*/);
  20.126 +  endp = tp + 16 /*NS_IN6ADDRSZ*/;
  20.127 +  colonp = NULL;
  20.128 +  /* Leading :: requires some special handling. */
  20.129 +  if (*address == ':')
  20.130 +    if (*++address != ':')
  20.131 +      return (0);
  20.132 +  curtok = address;
  20.133 +  seen_xdigits = 0;
  20.134 +  val = 0;
  20.135 +  while ((ch = *address++) != '\0')
  20.136 +  {
  20.137 +    const char *pch;
  20.138 +
  20.139 +    if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
  20.140 +      pch = strchr((xdigits = xdigits_u), ch);
  20.141 +    if (pch != NULL)
  20.142 +    {
  20.143 +      val <<= 4;
  20.144 +      val |= (pch - xdigits);
  20.145 +      if (++seen_xdigits > 4)
  20.146 +        return (0);
  20.147 +      continue;
  20.148 +    }
  20.149 +    if (ch == ':')
  20.150 +    {
  20.151 +      curtok = address;
  20.152 +      if (!seen_xdigits)
  20.153 +      {
  20.154 +        if (colonp)
  20.155 +          return (0);
  20.156 +        colonp = tp;
  20.157 +        continue;
  20.158 +      }
  20.159 +      if (tp + 2 /*NS_INT16SZ*/ > endp)
  20.160 +        return (0);
  20.161 +      *tp++ = (unsigned char) (val >> 8) & 0xff;
  20.162 +      *tp++ = (unsigned char) val & 0xff;
  20.163 +      seen_xdigits = 0;
  20.164 +      val = 0;
  20.165 +      continue;
  20.166 +    }
  20.167 +
  20.168 +    /* TODO Handle address like 2001::xxx.xxx.xxx.xxxx */
  20.169 +#if 0
  20.170 +    if (ch == '.' && ((tp + 4 /*NS_INADDRSZ*/) <= endp) &&
  20.171 +        inet_pton4(curtok, tp) > 0)
  20.172 +    {
  20.173 +      tp += 4 /*NS_INADDRSZ*/;
  20.174 +      seen_xdigits = 0;
  20.175 +      break;/* '\0' was seen by inet_pton4(). */
  20.176 +    }
  20.177 +#endif
  20.178 +    return (0);
  20.179 +  }
  20.180 +  if (seen_xdigits)
  20.181 +  {
  20.182 +    if (tp + 2/* NS_INT16SZ*/ > endp)
  20.183 +      return (0);
  20.184 +    *tp++ = (unsigned char) (val >> 8) & 0xff;
  20.185 +    *tp++ = (unsigned char) val & 0xff;
  20.186 +  }
  20.187 +  if (colonp != NULL)
  20.188 +  {
  20.189 +    /*
  20.190 +     * Since some memmove()'s erroneously fail to handle
  20.191 +     * overlapping regions, we'll do the shift by hand.
  20.192 +     */
  20.193 +    const int n = tp - colonp;
  20.194 +    int i;
  20.195 +
  20.196 +    if (tp == endp)
  20.197 +      return (0);
  20.198 +    for (i = 1; i <= n; i++)
  20.199 +    {
  20.200 +      endp[- i] = colonp[n - i];
  20.201 +      colonp[n - i] = 0;
  20.202 +    }
  20.203 +    tp = endp;
  20.204 +  }
  20.205 +  if (tp != endp)
  20.206 +    return (0);
  20.207 +
  20.208 +  /* memcpy(dst, tmp, NS_IN6ADDRSZ);  */
  20.209 +  memcpy(addr, tmp, 16);
  20.210 +  return (1);
  20.211 +}
  20.212 +
  20.213 +Ipv6Address::Ipv6Address ()
  20.214 +{
  20.215 +  memset(m_address, 0x00, 16);
  20.216 +}
  20.217 +
  20.218 +Ipv6Address::Ipv6Address (Ipv6Address const& addr)
  20.219 +{
  20.220 +  memcpy(m_address, addr.m_address, 16);
  20.221 +}
  20.222 +
  20.223 +Ipv6Address::Ipv6Address (Ipv6Address const* addr)
  20.224 +{
  20.225 +  memcpy(m_address, addr->m_address, 16);
  20.226 +}
  20.227 +
  20.228 +Ipv6Address::Ipv6Address (char const* address)
  20.229 +{
  20.230 +  AsciiToIpv6Host (address, m_address);
  20.231 +}
  20.232 +
  20.233 +Ipv6Address::Ipv6Address (uint8_t address[16])
  20.234 +{
  20.235 +  /* 128 bit => 16 bytes */
  20.236 +  memcpy(m_address, address, 16);
  20.237 +}
  20.238 +
  20.239 +Ipv6Address::~Ipv6Address ()
  20.240 +{
  20.241 +  /* do nothing */
  20.242 +}
  20.243 +
  20.244 +void Ipv6Address::Set (char const* address)
  20.245 +{
  20.246 +  AsciiToIpv6Host (address, m_address);
  20.247 +}
  20.248 +
  20.249 +void Ipv6Address::Set (uint8_t address[16])
  20.250 +{
  20.251 +  /* 128 bit => 16 bytes */
  20.252 +  memcpy(m_address, address, 16);
  20.253 +}
  20.254 +
  20.255 +void Ipv6Address::Serialize (uint8_t buf[16]) const
  20.256 +{
  20.257 +  memcpy(buf, m_address, 16);
  20.258 +}
  20.259 +
  20.260 +Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
  20.261 +{
  20.262 +  Ipv6Address ipv6((uint8_t*)buf);
  20.263 +  return ipv6;
  20.264 +}
  20.265 +
  20.266 +Ipv6Address Ipv6Address::MakeAutoconfiguredAddress (Mac48Address addr, Ipv6Address prefix)
  20.267 +{
  20.268 +  Ipv6Address ret;
  20.269 +  uint8_t buf[16];
  20.270 +  uint8_t buf2[16];
  20.271 +
  20.272 +  addr.CopyTo(buf);
  20.273 +  prefix.GetBytes(buf2);
  20.274 +
  20.275 +  memcpy(buf2 + 8, buf, 3);
  20.276 +  buf2[11] = 0xff;
  20.277 +  buf2[12] = 0xfe;
  20.278 +  memcpy(buf2 + 13, buf + 3, 3);
  20.279 +  buf2[8] |= 0x02;
  20.280 +
  20.281 +  ret.Set(buf2);
  20.282 +  return ret;
  20.283 +}
  20.284 +
  20.285 +Ipv6Address Ipv6Address::MakeAutoconfiguredLinkLocalAddress (Mac48Address addr)
  20.286 +{
  20.287 +  Ipv6Address ret;
  20.288 +  uint8_t buf[16];
  20.289 +  uint8_t buf2[16];
  20.290 +
  20.291 +  addr.CopyTo(buf);
  20.292 +
  20.293 +  memset(buf2, 0x00, sizeof(buf2));
  20.294 +  buf2[0] = 0xfe;
  20.295 +  buf2[1] = 0x80;
  20.296 +  memcpy(buf2 + 8, buf, 3);
  20.297 +  buf2[11] = 0xff;
  20.298 +  buf2[12] = 0xfe;
  20.299 +  memcpy(buf2 + 13, buf + 3, 3);
  20.300 +  buf2[8] |= 0x02;
  20.301 +
  20.302 +  ret.Set(buf2);
  20.303 +  return ret;
  20.304 +}
  20.305 +
  20.306 +Ipv6Address Ipv6Address::MakeSolicitedAddress (Ipv6Address addr)
  20.307 +{
  20.308 +  uint8_t buf[16];
  20.309 +  uint8_t buf2[16];
  20.310 +  Ipv6Address ret;
  20.311 +
  20.312 +  addr.Serialize(buf2);
  20.313 +
  20.314 +  memset(buf, 0x00, sizeof(buf));
  20.315 +  buf[0] = 0xff;
  20.316 +  buf[1] = 0x02;
  20.317 +  buf[11] = 0x01;
  20.318 +  buf[12] = 0xff;
  20.319 +  buf[13] = buf2[13];
  20.320 +  buf[14] = buf2[14];
  20.321 +  buf[15] = buf2[15];
  20.322 +
  20.323 +  ret.Set(buf);
  20.324 +  return ret;
  20.325 +}
  20.326 +
  20.327 +void Ipv6Address::Print (std::ostream& os) const
  20.328 +{
  20.329 +  os << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[0]
  20.330 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[1] << ":"
  20.331 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[2] 
  20.332 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[3] << ":"
  20.333 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[4]
  20.334 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[5] << ":"
  20.335 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[6]
  20.336 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[7] << ":"
  20.337 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[8]
  20.338 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[9] << ":"
  20.339 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[10]
  20.340 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[11] << ":"
  20.341 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[12]
  20.342 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[13] << ":"
  20.343 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[14]
  20.344 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_address[15];
  20.345 +}
  20.346 +
  20.347 +bool Ipv6Address::IsLocalhost () const
  20.348 +{
  20.349 +  static Ipv6Address localhost("::1");
  20.350 +  return (*this == localhost);
  20.351 +}
  20.352 +
  20.353 +bool Ipv6Address::IsMulticast () const
  20.354 +{
  20.355 +  if(m_address[0] == 0xff)
  20.356 +  {
  20.357 +    return true;
  20.358 +  }
  20.359 +  return false;
  20.360 +}
  20.361 +
  20.362 +Ipv6Address Ipv6Address::CombinePrefix (Ipv6Prefix const & prefix)
  20.363 +{
  20.364 +  Ipv6Address ipv6;
  20.365 +  uint8_t addr[16];
  20.366 +  uint8_t pref[16];
  20.367 +  unsigned int i = 0;
  20.368 +
  20.369 +  memcpy(addr, m_address, 16);
  20.370 +  ((Ipv6Prefix)prefix).GetBytes(pref);
  20.371 +
  20.372 +  /* a little bit ugly... */
  20.373 +  for(i = 0 ; i < 16 ; i++)
  20.374 +  {
  20.375 +    addr[i] = addr[i] & pref[i];
  20.376 +  }
  20.377 +  ipv6.Set(addr);
  20.378 +  return ipv6;
  20.379 +}
  20.380 +
  20.381 +bool Ipv6Address::IsSolicitedMulticast () const
  20.382 +{
  20.383 +  uint8_t buf[16];
  20.384 +
  20.385 +  Serialize(buf);
  20.386 +
  20.387 +  if(buf[0] == 0xff && 
  20.388 +      buf[1] == 0x02 &&
  20.389 +      buf[11] == 0x01 &&
  20.390 +      buf[12] == 0xff)
  20.391 +  {
  20.392 +    return true;
  20.393 +  }
  20.394 +  return false;
  20.395 +}
  20.396 +
  20.397 +bool Ipv6Address::IsAllNodesMulticast () const
  20.398 +{
  20.399 +  static Ipv6Address allnodes("ff02::1");
  20.400 +  return (*this == allnodes);
  20.401 +}
  20.402 +
  20.403 +bool Ipv6Address::IsAllRoutersMulticast () const
  20.404 +{
  20.405 +  static Ipv6Address allrouters("ff02::2");
  20.406 +  return (*this == allrouters);
  20.407 +}
  20.408 +
  20.409 +bool Ipv6Address::IsAllHostsMulticast () const
  20.410 +{
  20.411 +  static Ipv6Address allhosts("ff02::3");
  20.412 +  return (*this == allhosts);
  20.413 +}
  20.414 +
  20.415 +bool Ipv6Address::IsAny () const
  20.416 +{
  20.417 +  static Ipv6Address any("::");
  20.418 +  return (*this == any);
  20.419 +}
  20.420 +
  20.421 +bool Ipv6Address::IsMatchingType (const Address& address)
  20.422 +{
  20.423 +  return address.CheckCompatible(GetType(), 16);
  20.424 +}
  20.425 +
  20.426 +Ipv6Address::operator Address () const
  20.427 +{
  20.428 +  return ConvertTo ();
  20.429 +}
  20.430 +
  20.431 +Address Ipv6Address::ConvertTo (void) const
  20.432 +{
  20.433 +  uint8_t buf[16];
  20.434 +  Serialize (buf);
  20.435 +  return Address(GetType(), buf, 16);
  20.436 +}
  20.437 +
  20.438 +Ipv6Address Ipv6Address::ConvertFrom (const Address &address)
  20.439 +{
  20.440 +  NS_ASSERT (address.CheckCompatible (GetType (), 16));
  20.441 +  uint8_t buf[16];
  20.442 +  address.CopyTo (buf);
  20.443 +  return Deserialize (buf);
  20.444 +}
  20.445 +
  20.446 +uint8_t Ipv6Address::GetType (void)
  20.447 +{
  20.448 +  static uint8_t type = Address::Register();
  20.449 +  return type;
  20.450 +}
  20.451 +
  20.452 +Ipv6Address Ipv6Address::GetZero ()
  20.453 +{
  20.454 +  Ipv6Address zero("::");
  20.455 +  return zero;
  20.456 +}
  20.457 +
  20.458 +Ipv6Address Ipv6Address::GetAny ()
  20.459 +{
  20.460 +  Ipv6Address any("::");
  20.461 +  return any;
  20.462 +}
  20.463 +
  20.464 +Ipv6Address Ipv6Address::GetAllNodesMulticast ()
  20.465 +{
  20.466 +  Ipv6Address nmc("ff02::1");
  20.467 +  return nmc;
  20.468 +}
  20.469 +
  20.470 +Ipv6Address Ipv6Address::GetAllRoutersMulticast ()
  20.471 +{
  20.472 +  Ipv6Address rmc("ff02::2");
  20.473 +  return rmc;
  20.474 +}
  20.475 +
  20.476 +Ipv6Address Ipv6Address::GetAllHostsMulticast ()
  20.477 +{
  20.478 +  Ipv6Address hmc("ff02::3");
  20.479 +  return hmc;
  20.480 +}
  20.481 +
  20.482 +Ipv6Address Ipv6Address::GetLoopback ()
  20.483 +{
  20.484 +  static Ipv6Address loopback("::1");
  20.485 +  return loopback;
  20.486 +}
  20.487 +
  20.488 +void Ipv6Address::GetBytes (uint8_t buf[16]) const
  20.489 +{
  20.490 +  memcpy(buf, m_address, 16);
  20.491 +}
  20.492 +
  20.493 +bool Ipv6Address::IsLinkLocal () const
  20.494 +{
  20.495 +  Ipv6Address linkLocal("fe80::0");
  20.496 +  if(!IsMulticast() && ((Ipv6Address*)this)->CombinePrefix(Ipv6Prefix(64))==linkLocal)
  20.497 +  {
  20.498 +    return true;
  20.499 +  }
  20.500 +  return false;
  20.501 +}
  20.502 +
  20.503 +bool Ipv6Address::IsEqual (const Ipv6Address& other) const
  20.504 +{
  20.505 +  if(!memcmp(m_address, other.m_address, 16))
  20.506 +  {
  20.507 +    return true;
  20.508 +  }
  20.509 +  return false;
  20.510 +}
  20.511 +
  20.512 +std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
  20.513 +{
  20.514 +  address.Print(os);
  20.515 +  return os;
  20.516 +}
  20.517 +
  20.518 +std::istream& operator >> (std::istream& is, Ipv6Address& address)
  20.519 +{
  20.520 +  std::string str;
  20.521 +  is >> str;
  20.522 +  address = Ipv6Address (str.c_str ());
  20.523 +  return is;
  20.524 +}
  20.525 +
  20.526 +Ipv6Prefix::Ipv6Prefix ()
  20.527 +{
  20.528 +  memset(m_prefix, 0x00, 16);
  20.529 +}
  20.530 +
  20.531 +Ipv6Prefix::Ipv6Prefix (char const* prefix)
  20.532 +{
  20.533 +  AsciiToIpv6Host(prefix, m_prefix);
  20.534 +}
  20.535 +
  20.536 +Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
  20.537 +{
  20.538 +  memcpy(m_prefix, prefix, 16);
  20.539 +}
  20.540 +
  20.541 +Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
  20.542 +{
  20.543 +  unsigned int nb=0;
  20.544 +  unsigned int mod=0;
  20.545 +  unsigned int i=0;
  20.546 +
  20.547 +  memset(m_prefix, 0x00, 16);
  20.548 +
  20.549 +  NS_ASSERT(prefix <= 128);
  20.550 +
  20.551 +  nb = prefix / 8;
  20.552 +  mod = prefix % 8;
  20.553 +
  20.554 +  memset(m_prefix, 0xff, nb);
  20.555 +
  20.556 +  if(mod)
  20.557 +  {
  20.558 +    m_prefix[nb] = 0xff << (8-mod);
  20.559 +  }
  20.560 +
  20.561 +  if(nb < 16)
  20.562 +  {
  20.563 +    nb++;
  20.564 +    for(i = nb; i < 16 ; i++)
  20.565 +    {
  20.566 +      m_prefix[i] = 0x00;
  20.567 +    }
  20.568 +  }
  20.569 +}
  20.570 +
  20.571 +Ipv6Prefix::Ipv6Prefix (Ipv6Prefix const& prefix)
  20.572 +{
  20.573 +  memcpy(m_prefix, prefix.m_prefix, 16);
  20.574 +}
  20.575 +
  20.576 +Ipv6Prefix::Ipv6Prefix (Ipv6Prefix const* prefix)
  20.577 +{
  20.578 +  memcpy(m_prefix, prefix->m_prefix, 16);
  20.579 +}
  20.580 +
  20.581 +Ipv6Prefix::~Ipv6Prefix ()
  20.582 +{
  20.583 +  /* do nothing */
  20.584 +}
  20.585 +
  20.586 +bool Ipv6Prefix::IsMatch (Ipv6Address a, Ipv6Address b) const
  20.587 +{
  20.588 +  uint8_t addrA[16];
  20.589 +  uint8_t addrB[16];
  20.590 +  unsigned int i = 0;
  20.591 +
  20.592 +  a.GetBytes(addrA);
  20.593 +  b.GetBytes(addrB);
  20.594 +
  20.595 +  /* a little bit ugly... */
  20.596 +  for(i = 0 ; i < 16 ; i++)
  20.597 +  {
  20.598 +    if((addrA[i] & m_prefix[i]) !=	(addrB[i] & m_prefix[i]))
  20.599 +    {
  20.600 +      return false;
  20.601 +    }
  20.602 +  }
  20.603 +  return true;
  20.604 +}
  20.605 +
  20.606 +void Ipv6Prefix::Print (std::ostream &os) const
  20.607 +{
  20.608 +  os << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[0]
  20.609 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[1] << ":"
  20.610 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[2]
  20.611 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[3] << ":"
  20.612 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[4]
  20.613 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[5] << ":"
  20.614 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[6]
  20.615 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[7] << ":"
  20.616 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[8]
  20.617 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[9] << ":"
  20.618 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[10]
  20.619 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[11] << ":"
  20.620 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[12]
  20.621 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[13] << ":"
  20.622 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[14]
  20.623 +    << std::hex << std::setw(2) << std::setfill('0') << (unsigned int) m_prefix[15];
  20.624 +}
  20.625 +
  20.626 +Ipv6Prefix Ipv6Prefix::GetLoopback ()
  20.627 +{
  20.628 +  Ipv6Prefix prefix((uint8_t)128);
  20.629 +  return prefix;
  20.630 +}
  20.631 +
  20.632 +Ipv6Prefix Ipv6Prefix::GetZero ()
  20.633 +{
  20.634 +  Ipv6Prefix prefix((uint8_t)0);
  20.635 +  return prefix;
  20.636 +}
  20.637 +
  20.638 +void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
  20.639 +{
  20.640 +  memcpy(buf, m_prefix, 16);
  20.641 +}
  20.642 +
  20.643 +bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
  20.644 +{
  20.645 +  if(!memcmp(m_prefix, other.m_prefix, 16))
  20.646 +  {
  20.647 +    return true;
  20.648 +  }
  20.649 +  return false;
  20.650 +}
  20.651 +
  20.652 +std::ostream& operator<< (std::ostream& os, Ipv6Prefix const& prefix)
  20.653 +{
  20.654 +  prefix.Print (os);
  20.655 +  return os;
  20.656 +}
  20.657 +
  20.658 +std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
  20.659 +{
  20.660 +  std::string str;
  20.661 +  is >> str;
  20.662 +  prefix = Ipv6Prefix (str.c_str ());
  20.663 +  return is;
  20.664 +}
  20.665 +
  20.666 +bool operator == (Ipv6Prefix const &a, Ipv6Prefix const &b)
  20.667 +{
  20.668 +  return a.IsEqual (b);
  20.669 +}
  20.670 +
  20.671 +bool operator != (Ipv6Prefix const &a, Ipv6Prefix const &b)
  20.672 +{
  20.673 +  return !a.IsEqual (b);
  20.674 +}
  20.675 +
  20.676 +size_t Ipv6AddressHash::operator() (Ipv6Address const &x) const
  20.677 +{
  20.678 +  uint8_t buf[16];
  20.679 +
  20.680 +  x.GetBytes(buf);
  20.681 +
  20.682 +  return lookuphash(buf, sizeof(buf), 0);
  20.683 +}
  20.684 +
  20.685 +ATTRIBUTE_HELPER_CPP (Ipv6Address);
  20.686 +ATTRIBUTE_HELPER_CPP (Ipv6Prefix);
  20.687 +
  20.688 +} /* namespace ns3 */
  20.689 +
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/src/node/ipv6-address.h	Fri Nov 07 11:36:15 2008 -0800
    21.3 @@ -0,0 +1,427 @@
    21.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
    21.5 +/*
    21.6 + * Copyright (c) 2007-2008 Louis Pasteur University
    21.7 + *
    21.8 + * This program is free software; you can redistribute it and/or modify
    21.9 + * it under the terms of the GNU General Public License version 2 as
   21.10 + * published by the Free Software Foundation;
   21.11 + *
   21.12 + * This program is distributed in the hope that it will be useful,
   21.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   21.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21.15 + * GNU General Public License for more details.
   21.16 + *
   21.17 + * You should have received a copy of the GNU General Public License
   21.18 + * along with this program; if not, write to the Free Software
   21.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   21.20 + *
   21.21 + * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
   21.22 + */
   21.23 +
   21.24 +#ifndef IPV6_ADDRESS_H
   21.25 +#define IPV6_ADDRESS_H
   21.26 +
   21.27 +#include <stdint.h>
   21.28 +#include <string.h>
   21.29 +
   21.30 +#include <ostream>
   21.31 +
   21.32 +#include "address.h"
   21.33 +#include "ns3/attribute-helper.h"
   21.34 +
   21.35 +namespace ns3 { 
   21.36 +
   21.37 +class Ipv6Prefix;
   21.38 +class Mac48Address;
   21.39 +
   21.40 +/**
   21.41 + * \class Ipv6Address
   21.42 + * \brief Describes an IPv6 address.
   21.43 + * \see Ipv6Prefix
   21.44 + */
   21.45 +class Ipv6Address
   21.46 +{
   21.47 +  public :
   21.48 +    /**
   21.49 +     * \brief Default constructor.
   21.50 +     */
   21.51 +    Ipv6Address ();
   21.52 +
   21.53 +    /**
   21.54 +     * \brief Constructs an Ipv6Address by parsing the input C-string.
   21.55 +     * \param address the C-string containing the IPv6 address (e.g. 2001:660:4701::1).
   21.56 +     */
   21.57 +    Ipv6Address (char const* address);
   21.58 +
   21.59 +    /**
   21.60 +     * \brief Constructs an Ipv6Address by using the input 16 bytes.
   21.61 +     * \param address the 128-bit address
   21.62 +     * \warning the parameter must point on a 16 bytes integer array!
   21.63 +     */
   21.64 +    Ipv6Address (uint8_t address[16]);
   21.65 +
   21.66 +    /**
   21.67 +     * \brief Copy constructor.
   21.68 +     * \param addr Ipv6Address object
   21.69 +     */
   21.70 +    Ipv6Address (Ipv6Address const & addr);
   21.71 +
   21.72 +    /**
   21.73 +     * \brief Copy constructor.
   21.74 +     * \param addr Ipv6Address pointer
   21.75 +     */
   21.76 +    Ipv6Address (Ipv6Address const* addr);
   21.77 +
   21.78 +    /**
   21.79 +     * \brief Destructor.
   21.80 +     */
   21.81 +    ~Ipv6Address ();
   21.82 +
   21.83 +    /**
   21.84 +     * \brief Sets an Ipv6Address by parsing the input C-string.
   21.85 +     * \param address the C-string containing the IPv6 address (e.g. 2001:660:4701::1).
   21.86 +     */
   21.87 +    void Set (char const* address);
   21.88 +
   21.89 +    /**
   21.90 +     * \brief Set an Ipv6Address by using the input 16 bytes.
   21.91 +     *
   21.92 +     * \param address the 128-bit address
   21.93 +     * \warning the parameter must point on a 16 bytes integer array!
   21.94 +     */
   21.95 +    void Set (uint8_t address[16]);
   21.96 +
   21.97 +    /**
   21.98 +     * \brief Comparison operation between two Ipv6Addresses.
   21.99 +     *
  21.100 +     * \param other the IPv6 address to which to compare thisaddress
  21.101 +     * \return true if the addresses are equal, false otherwise
  21.102 +     */
  21.103 +    bool IsEqual (const Ipv6Address& other) const;
  21.104 +
  21.105 +    /**
  21.106 +     * \brief Serialize this address to a 16-byte buffer.
  21.107 +     * \param buf the output buffer to which this address gets overwritter with this
  21.108 +     * Ipv6Address
  21.109 +     */
  21.110 +    void Serialize (uint8_t buf[16]) const;
  21.111 +
  21.112 +    /**
  21.113 +     * \brief Deserialize this address.
  21.114 +     * \param buf buffer to read address from
  21.115 +     * \return an Ipv6Address
  21.116 +     */
  21.117 +    static Ipv6Address Deserialize (const uint8_t buf[16]);
  21.118 +
  21.119 +    /**
  21.120 +     * \brief Make the solicited IPv6 address.
  21.121 +     * \param addr the IPv6 address
  21.122 +     * \return Solicited IPv6 address
  21.123 +     */
  21.124 +    static Ipv6Address MakeSolicitedAddress (Ipv6Address addr);
  21.125 +
  21.126 +    /**
  21.127 +     * \brief Make the autoconfigured IPv6 address with Mac48Address.
  21.128 +     * \param addr the MAC address (48 bits).
  21.129 +     * \param prefix the IPv6 prefix
  21.130 +     * \return autoconfigured IPv6 address
  21.131 +     */
  21.132 +    static Ipv6Address MakeAutoconfiguredAddress (Mac48Address addr, Ipv6Address prefix);
  21.133 +
  21.134 +    /**
  21.135 +     * \brief Make the autoconfigured link-local IPv6 address with Mac48Address.
  21.136 +     * \param mac the MAC address (48 bits).
  21.137 +     * \return autoconfigured link-local IPv6 address
  21.138 +     */
  21.139 +    static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Mac48Address mac);
  21.140 +
  21.141 +    /**
  21.142 +     * \brief Print this address to the given output stream.
  21.143 +     *
  21.144 +     * The print format is in the typical "2001:660:4701::1".
  21.145 +     * \param os the output stream to which this Ipv6Address is printed
  21.146 +     */
  21.147 +    void Print (std::ostream& os) const;
  21.148 +
  21.149 +    /**
  21.150 +     * \brief If the IPv6 address is localhost (::1).
  21.151 +     * \return true if localhost, false otherwise
  21.152 +     */
  21.153 +    bool IsLocalhost () const;
  21.154 +
  21.155 +    /**
  21.156 +     * \brief If the IPv6 address is multicast (ff00::/8).
  21.157 +     * \return true if multicast, false otherwise
  21.158 +     */
  21.159 +    bool IsMulticast () const;
  21.160 +
  21.161 +    /**
  21.162 +     * \brief If the IPv6 address is "all nodes multicast" (ff02::1/8).
  21.163 +     * \return true if "all nodes multicast", false otherwise
  21.164 +     */
  21.165 +    bool IsAllNodesMulticast () const;
  21.166 +
  21.167 +    /**
  21.168 +     * \brief If the IPv6 address is "all routers multicast" (ff02::2/8).
  21.169 +     * \return true if "all routers multicast", false otherwise
  21.170 +     */
  21.171 +    bool IsAllRoutersMulticast () const;
  21.172 +
  21.173 +    /**
  21.174 +     * \brief If the IPv6 address is "all hosts multicast" (ff02::3/8).
  21.175 +     * \return true if "all hosts multicast", false otherwise
  21.176 +     */
  21.177 +    bool IsAllHostsMulticast () const;
  21.178 +
  21.179 +    /**
  21.180 +     * \brief If the IPv6 address is a link-local address (fe80::/64).
  21.181 +     * \return true if the address is link-local, false otherwise
  21.182 +     */
  21.183 +    bool IsLinkLocal () const;
  21.184 +
  21.185 +    /**
  21.186 +     * \brief If the IPv6 address is a Solicited multicast address.
  21.187 +     * \return true if it is, false otherwise
  21.188 +     */
  21.189 +    bool IsSolicitedMulticast () const;
  21.190 +
  21.191 +    /**
  21.192 +     * \brief If the IPv6 address is the "Any" address.
  21.193 +     * \return true if it is, false otherwise
  21.194 +     */
  21.195 +    bool IsAny () const;
  21.196 +
  21.197 +    /**
  21.198 +     * \brief Combine this address with a prefix.
  21.199 +     * \param prefix a IPv6 prefix
  21.200 +     * \return an IPv6 address that is this address combined
  21.201 +     * (bitwise AND) with a prefix, yielding an IPv6 network address.
  21.202 +     */
  21.203 +    Ipv6Address CombinePrefix (Ipv6Prefix const & prefix);
  21.204 +
  21.205 +    /**
  21.206 +     * \brief If the Address matches the type.
  21.207 +     * \param address other address
  21.208 +     * \return true if the type matches, false otherwise
  21.209 +     */
  21.210 +    static bool IsMatchingType (const Address& address);
  21.211 +
  21.212 +    /**
  21.213 +     * \brief Convert to Address object
  21.214 +     */
  21.215 +    operator Address () const;
  21.216 +
  21.217 +    /**
  21.218 +     * \brief Convert the Address object into an Ipv6Address one.
  21.219 +     * \return an Ipv6Address
  21.220 +     */
  21.221 +    static Ipv6Address ConvertFrom (const Address& address);
  21.222 +
  21.223 +    /**
  21.224 +     * \brief Get the 0 (::) Ipv6Address.
  21.225 +     * \return the :: Ipv6Address representation
  21.226 +     */
  21.227 +    static Ipv6Address GetZero ();
  21.228 +
  21.229 +    /**
  21.230 +     * \brief Get the "any" (::) Ipv6Address.
  21.231 +     * \return the "any" (::) Ipv6Address
  21.232 +     */
  21.233 +    static Ipv6Address GetAny ();
  21.234 +
  21.235 +    /**
  21.236 +     * \brief Get the "all nodes multicast" address.
  21.237 +     * \return the "ff02::2/8" Ipv6Address representation
  21.238 +     */
  21.239 +    static Ipv6Address GetAllNodesMulticast ();
  21.240 +
  21.241 +    /**
  21.242 +     * \brief Get the "all routers multicast" address.
  21.243 +     * \return the "ff02::2/8" Ipv6Address representation
  21.244 +     */
  21.245 +    static Ipv6Address GetAllRoutersMulticast ();
  21.246 +
  21.247 +    /**
  21.248 +     * \brief Get the "all hosts multicast" address.
  21.249 +     * \return the "ff02::3/8" Ipv6Address representation
  21.250 +     */
  21.251 +    static Ipv6Address GetAllHostsMulticast ();
  21.252 +
  21.253 +    /**
  21.254 +     * \brief Get the loopback address.
  21.255 +     * \return the "::1/128" Ipv6Address representation.
  21.256 +     */
  21.257 +    static Ipv6Address GetLoopback ();
  21.258 +
  21.259 +    /**
  21.260 +     * \brief Get the bytes corresponding to the address.
  21.261 +     * \param buf buffer to store the data
  21.262 +     * \return bytes of the address
  21.263 +     */
  21.264 +    void GetBytes (uint8_t buf[16]) const;
  21.265 +
  21.266 +  private:
  21.267 +    /**
  21.268 +     * \brief convert the IPv6Address object to an Address object.
  21.269 +     * \return the Address object corresponding to this object.
  21.270 +     */
  21.271 +    Address ConvertTo (void) const;
  21.272 +
  21.273 +    /**
  21.274 +     * \brief Return the Type of address.
  21.275 +     * \return type of address
  21.276 +     */
  21.277 +    static uint8_t GetType (void);
  21.278 +
  21.279 +    /**
  21.280 +     * \brief The address representation on 128 bits (16 bytes).
  21.281 +     */
  21.282 +    uint8_t m_address[16];
  21.283 +
  21.284 +    friend bool operator == (Ipv6Address const &a, Ipv6Address const &b);
  21.285 +    friend bool operator != (Ipv6Address const &a, Ipv6Address const &b);
  21.286 +    friend bool operator < (Ipv6Address const &a, Ipv6Address const &b);
  21.287 +};
  21.288 +
  21.289 +/**
  21.290 + * \class Ipv6Prefix
  21.291 + * \brief Describes an IPv6 prefix. It is just a bitmask like Ipv4Mask.
  21.292 + * \see Ipv6Address
  21.293 + */
  21.294 +class Ipv6Prefix
  21.295 +{
  21.296 +  public:
  21.297 +    /**
  21.298 +     * \brief Default constructor.
  21.299 +     */
  21.300 +    Ipv6Prefix ();
  21.301 +
  21.302 +    /**
  21.303 +     * \brief Constructs an Ipv6Prefix by using the input 16 bytes.
  21.304 +     * \param prefix the 128-bit prefix
  21.305 +     */
  21.306 +    Ipv6Prefix (uint8_t prefix[16]);
  21.307 +
  21.308 +    /**
  21.309 +     * \brief Constructs an Ipv6Prefix by using the input string.
  21.310 +     * \param prefix the 128-bit prefix
  21.311 +     */
  21.312 +    Ipv6Prefix (char const* prefix);
  21.313 +
  21.314 +    /**
  21.315 +     * \brief Constructs an Ipv6Prefix by using the input number of bits.
  21.316 +     * \param prefix number of bits of the prefix (0 - 128)
  21.317 +     * \note A valid number of bits is between 0 and 128).
  21.318 +     */
  21.319 +    Ipv6Prefix (uint8_t prefix);
  21.320 +
  21.321 +    /**
  21.322 +     * \brief Copy constructor.
  21.323 +     * \param prefix Ipv6Prefix object
  21.324 +     */
  21.325 +    Ipv6Prefix (Ipv6Prefix const& prefix);
  21.326 +
  21.327 +    /**
  21.328 +     * \brief Copy constructor.
  21.329 +     * \param prefix Ipv6Prefix pointer
  21.330 +     */
  21.331 +    Ipv6Prefix (Ipv6Prefix const* prefix);
  21.332 +
  21.333 +    /**
  21.334 +     * \brief Destructor.
  21.335 +     */
  21.336 +    ~Ipv6Prefix ();
  21.337 +
  21.338 +    /**
  21.339 +     * \brief If the Address match the type.
  21.340 +     * \param a a first address
  21.341 +     * \param b a second address
  21.342 +     * \return true if the type match, false otherwise
  21.343 +     */
  21.344 +    bool IsMatch (Ipv6Address a, Ipv6Address b) const;
  21.345 +
  21.346 +    /**
  21.347 +     * \brief Get the bytes corresponding to the prefix.
  21.348 +     * \param buf buffer to store the data
  21.349 +     */
  21.350 +    void GetBytes (uint8_t buf[16]) const;
  21.351 +
  21.352 +    /**
  21.353 +     * \brief Comparison operation between two Ipv6Prefix.
  21.354 +     * \param other the IPv6 prefix to which to compare this prefix
  21.355 +     * \return true if the prefixes are equal, false otherwise
  21.356 +     */
  21.357 +    bool IsEqual (const Ipv6Prefix& other) const;
  21.358 +
  21.359 +    /**
  21.360 +     * \brief Print this address to the given output stream.
  21.361 +     *
  21.362 +     * The print format is in the typicall "2001:660:4701::1".
  21.363 +     * \param os the output stream to which this Ipv6Address is printed
  21.364 +     */
  21.365 +    void Print (std::ostream &os) const;
  21.366 +
  21.367 +    /**
  21.368 +     * \brief Get the loopback prefix ( /128).
  21.369 +     * \return a Ipv6Prefix corresponding to loopback prefix
  21.370 +     */
  21.371 +    static Ipv6Prefix GetLoopback ();
  21.372 +
  21.373 +    /**
  21.374 +     * \brief Get the zero prefix ( /0).
  21.375 +     * \return an Ipv6Prefix
  21.376 +     */
  21.377 +    static Ipv6Prefix GetZero ();
  21.378 +
  21.379 +  private:
  21.380 +    /**
  21.381 +     * \brief The prefix representation.
  21.382 +     */
  21.383 +    uint8_t m_prefix[16];
  21.384 +};
  21.385 +
  21.386 +/**
  21.387 + * \class ns3::Ipv6AddressValue
  21.388 + * \brief hold objects of type ns3::Ipv6Address
  21.389 + */
  21.390 +ATTRIBUTE_HELPER_HEADER (Ipv6Address);
  21.391 +
  21.392 +/**
  21.393 + * \class ns3::Ipv6PrefixValue
  21.394 + * \brief hold objects of type ns3::Ipv6Prefix
  21.395 + */
  21.396 +ATTRIBUTE_HELPER_HEADER (Ipv6Prefix);
  21.397 +
  21.398 +std::ostream& operator << (std::ostream& os, Ipv6Address const& address);
  21.399 +std::ostream& operator<< (std::ostream& os, Ipv6Prefix const& prefix);
  21.400 +std::istream & operator >> (std::istream &is, Ipv6Address &address);
  21.401 +std::istream & operator >> (std::istream &is, Ipv6Prefix &prefix);
  21.402 +
  21.403 +inline bool operator == (const Ipv6Address& a, const Ipv6Address& b)
  21.404 +{
  21.405 +  return (!memcmp (a.m_address, b.m_address, 16));
  21.406 +}
  21.407 +
  21.408 +inline bool operator != (const Ipv6Address& a, const Ipv6Address& b)
  21.409 +{
  21.410 +  return memcmp (a.m_address, b.m_address, 16);
  21.411 +}
  21.412 +
  21.413 +inline bool operator < (const Ipv6Address& a, const Ipv6Address& b)
  21.414 +{
  21.415 +  return (memcmp (a.m_address, b.m_address, 16) < 0);
  21.416 +}
  21.417 +
  21.418 +class Ipv6AddressHash : public std::unary_function<Ipv6Address, size_t>
  21.419 +{
  21.420 +  public:
  21.421 +    size_t operator() (Ipv6Address const &x) const;
  21.422 +};
  21.423 +
  21.424 +bool operator == (Ipv6Prefix const &a, Ipv6Prefix const &b);
  21.425 +bool operator != (Ipv6Prefix const &a, Ipv6Prefix const &b);
  21.426 +
  21.427 +} /* namespace ns3 */
  21.428 +
  21.429 +#endif /* IPV6_ADDRESS_H */
  21.430 +
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/src/node/ipv6-header.cc	Fri Nov 07 11:36:15 2008 -0800
    22.3 @@ -0,0 +1,187 @@
    22.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
    22.5 +/*
    22.6 + * Copyright (c) 2007-2008 Louis Pasteur University
    22.7 + *
    22.8 + * This program is free software; you can redistribute it and/or modify
    22.9 + * it under the terms of the GNU General Public License version 2 as
   22.10 + * published by the Free Software Foundation;
   22.11 + *
   22.12 + * This program is distributed in the hope that it will be useful,
   22.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   22.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22.15 + * GNU General Public License for more details.
   22.16 + *
   22.17 + * You should have received a copy of the GNU General Public License
   22.18 + * along with this program; if not, write to the Free Software
   22.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   22.20 + *
   22.21 + * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
   22.22 + */
   22.23 +
   22.24 +#include "ns3/assert.h"
   22.25 +#include "ns3/log.h"
   22.26 +#include "ns3/header.h"
   22.27 +#include "address-utils.h"
   22.28 +#include "ipv6-header.h"
   22.29 +
   22.30 +NS_LOG_COMPONENT_DEFINE ("Ipv6Header");
   22.31 +
   22.32 +namespace ns3 {
   22.33 +
   22.34 +NS_OBJECT_ENSURE_REGISTERED (Ipv6Header);
   22.35 +
   22.36 +Ipv6Header::Ipv6Header ()
   22.37 +: m_version (6),
   22.38 +  m_trafficClass (0),
   22.39 +  m_flowLabel (1),
   22.40 +  m_payloadLength (0),
   22.41 +  m_nextHeader (0),
   22.42 +  m_hopLimit (0)
   22.43 +{
   22.44 +
   22.45 +  SetSourceAddress (Ipv6Address("::"));
   22.46 +  SetDestinationAddress(Ipv6Address ("::"));
   22.47 +}
   22.48 +
   22.49 +void Ipv6Header::SetTrafficClass (uint8_t traffic)
   22.50 +{
   22.51 +  m_trafficClass = traffic;
   22.52 +}
   22.53 +
   22.54 +uint8_t Ipv6Header::GetTrafficClass () const
   22.55 +{
   22.56 +  return m_trafficClass;
   22.57 +}
   22.58 +
   22.59 +void Ipv6Header::SetFlowLabel (uint32_t flow)
   22.60 +{
   22.61 +  m_flowLabel = flow;
   22.62 +}
   22.63 +
   22.64 +uint32_t Ipv6Header::GetFlowLabel () const
   22.65 +{
   22.66 +  return m_flowLabel;
   22.67 +}
   22.68 +
   22.69 +void Ipv6Header::SetPayloadLength (uint16_t len)
   22.70 +{
   22.71 +  m_payloadLength = len;
   22.72 +}
   22.73 +
   22.74 +uint16_t Ipv6Header::GetPayloadLength () const
   22.75 +{
   22.76 +  return m_payloadLength;
   22.77 +}
   22.78 +
   22.79 +void Ipv6Header::SetNextHeader (uint8_t next)
   22.80 +{
   22.81 +  m_nextHeader = next;
   22.82 +}
   22.83 +
   22.84 +uint8_t Ipv6Header::GetNextHeader () const
   22.85 +{
   22.86 +  return m_nextHeader;
   22.87 +}
   22.88 +
   22.89 +void Ipv6Header::SetHopLimit (uint8_t limit)
   22.90 +{
   22.91 +  m_hopLimit = limit;
   22.92 +}
   22.93 +
   22.94 +uint8_t Ipv6Header::GetHopLimit () const
   22.95 +{
   22.96 +  return m_hopLimit;
   22.97 +}
   22.98 +
   22.99 +void Ipv6Header::SetSourceAddress (Ipv6Address src)
  22.100 +{
  22.101 +  m_sourceAddress = src;
  22.102 +}
  22.103 +
  22.104 +Ipv6Address Ipv6Header::GetSourceAddress () const
  22.105 +{
  22.106 +  return m_sourceAddress;
  22.107 +}
  22.108 +
  22.109 +void Ipv6Header::SetDestinationAddress (Ipv6Address dst)
  22.110 +{
  22.111 +  m_destinationAddress = dst;
  22.112 +}
  22.113 +
  22.114 +Ipv6Address Ipv6Header::GetDestinationAddress () const
  22.115 +{
  22.116 +  return m_destinationAddress;
  22.117 +}
  22.118 +
  22.119 +TypeId Ipv6Header::GetTypeId (void)
  22.120 +{
  22.121 +  static TypeId tid = TypeId ("ns3::Ipv6Header")
  22.122 +    .SetParent<Header> ()
  22.123 +    .AddConstructor<Ipv6Header> ()
  22.124 +    ;
  22.125 +  return tid;
  22.126 +}
  22.127 +
  22.128 +TypeId Ipv6Header::GetInstanceTypeId (void) const
  22.129 +{
  22.130 +  return GetTypeId ();
  22.131 +}
  22.132 +
  22.133 +void Ipv6Header::Print (std::ostream& os) const
  22.134 +{
  22.135 +  os << "("
  22.136 +    "Version " << m_version << " "
  22.137 +    << "Traffic class 0x" << std::hex << m_trafficClass << std::dec << " "
  22.138 +    << "Flow Label 0x" << std::hex << m_flowLabel << std::dec << " "
  22.139 +    << "Payload Length " << m_payloadLength << " "
  22.140 +    << "Next Header " << std::dec << (uint32_t) m_nextHeader << " "
  22.141 +    << "Hop Limit " << std::dec << (uint32_t)m_hopLimit << " )"
  22.142 +    <<  m_sourceAddress << " > " <<  m_destinationAddress
  22.143 +    ;
  22.144 +}
  22.145 +
  22.146 +uint32_t Ipv6Header::GetSerializedSize () const
  22.147 +{
  22.148 +  return 10 * 4;
  22.149 +}
  22.150 +
  22.151 +void Ipv6Header::Serialize (Buffer::Iterator start) const
  22.152 +{
  22.153 +  Buffer::Iterator i = start;
  22.154 +  uint32_t vTcFl = 0; /* version, Traffic Class and Flow Label fields */
  22.155 +
  22.156 +  vTcFl= (6 << 28) | (m_trafficClass << 20) | (m_flowLabel);
  22.157 +
  22.158 +  i.WriteHtonU32(vTcFl);
  22.159 +  i.WriteHtonU16(m_payloadLength);
  22.160 +  i.WriteU8(m_nextHeader);
  22.161 +  i.WriteU8(m_hopLimit);
  22.162 +
  22.163 +  WriteTo(i, m_sourceAddress);
  22.164 +  WriteTo(i, m_destinationAddress);
  22.165 +}
  22.166 +
  22.167 +uint32_t Ipv6Header::Deserialize (Buffer::Iterator start)
  22.168 +{
  22.169 +  Buffer::Iterator i = start;
  22.170 +  uint32_t vTcFl = 0;
  22.171 +
  22.172 +  vTcFl = i.ReadNtohU32();
  22.173 +  m_version = vTcFl >> 28;
  22.174 +
  22.175 +  NS_ASSERT((m_version) == 6);
  22.176 +
  22.177 +  m_trafficClass = (uint8_t)((vTcFl >> 20) & 0x000000ff);
  22.178 +  m_flowLabel = vTcFl & 0xfff00000;
  22.179 +  m_payloadLength = i.ReadNtohU16();
  22.180 +  m_nextHeader = i.ReadU8();
  22.181 +  m_hopLimit = i.ReadU8();
  22.182 +
  22.183 +  ReadFrom(i, m_sourceAddress);
  22.184 +  ReadFrom(i, m_destinationAddress);
  22.185 +
  22.186 +  return GetSerializedSize();
  22.187 +}
  22.188 +
  22.189 +} /* namespace ns3 */
  22.190 +
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/src/node/ipv6-header.h	Fri Nov 07 11:36:15 2008 -0800
    23.3 @@ -0,0 +1,237 @@
    23.4 +/* -*-  Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */
    23.5 +/*
    23.6 + * Copyright (c) 2007-2008 Louis Pasteur University
    23.7 + *
    23.8 + * This program is free software; you can redistribute it and/or modify
    23.9 + * it under the terms of the GNU General Public License version 2 as
   23.10 + * published by the Free Software Foundation;
   23.11 + *
   23.12 + * This program is distributed in the hope that it will be useful,
   23.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
   23.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   23.15 + * GNU General Public License for more details.
   23.16 + *
   23.17 + * You should have received a copy of the GNU General Public License
   23.18 + * along with this program; if not, write to the Free Software
   23.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23.20 + *
   23.21 + * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
   23.22 + */
   23.23 +
   23.24 +#ifndef IPV6_HEADER_H
   23.25 +#define IPV6_HEADER_H
   23.26 +
   23.27 +#include "ns3/header.h"
   23.28 +#include "ns3/ipv6-address.h"
   23.29 +
   23.30 +namespace ns3 {
   23.31 +
   23.32 +/**
   23.33 + * \class Ipv6Header
   23.34 + * \brief Packet header for IPv6
   23.35 + */
   23.36 +class Ipv6Header : public Header
   23.37 +{
   23.38 +  public:
   23.39 +    /**
   23.40 +     * \enum NextHeader_e
   23.41 +     * \brief IPv6 next-header value
   23.42 +     */
   23.43 +    enum NextHeader_e
   23.44 +    {
   23.45 +      IPV6_EXT_HOP_BY_HOP=0,
   23.46 +      IPV6_IPV4=4,
   23.47 +      IPV6_TCP=6,
   23.48 +      IPV6_UDP=17,
   23.49 +      IPV6_IPV6=41,
   23.50 +      IPV6_EXT_ROUTING=43,
   23.51 +      IPV6_EXT_FRAGMENTATION=44,
   23.52 +      IPV6_EXT_CONFIDENTIALITY=50,
   23.53 +      IPV6_EXT_AUTHENTIFICATION,
   23.54 +      IPV6_ICMPV6=58,
   23.55 +      IPV6_EXT_END,
   23.56 +      IPV6_EXT_DESTINATION,
   23.57 +      IPV6_SCTP=135,
   23.58 +      IPV6_EXT_MOBILITY=135,
   23.59 +      IPV6_UDP_LITE,
   23.60 +    };
   23.61 +
   23.62 +    /**
   23.63 +     * \brief Get the type identifier.
   23.64 +     * \return type identifier
   23.65 +     */
   23.66 +    static TypeId GetTypeId (void);
   23.67 +
   23.68 +    /**
   23.69 +     * \brief Return the instance type identifier.
   23.70 +     * \return instance type ID
   23.71 +     */
   23.72 +    virtual TypeId GetInstanceTypeId (void) const;
   23.73 +
   23.74 +    /**
   23.75 +     * \brief Constructor.
   23.76 +     */
   23.77 +    Ipv6Header (void);
   23.78 +
   23.79 +    /**
   23.80 +     * \brief Set the "Traffic class" field.
   23.81 +     * \param traffic the 8-bit value
   23.82 +     */
   23.83 +    void SetTrafficClass (uint8_t traffic);
   23.84 +
   23.85 +    /**
   23.86 +     * \brief Get the "Traffic class" field.
   23.87 +     * \return the traffic value
   23.88 +     */
   23.89 +    uint8_t GetTrafficClass (void) const;
   23.90 +
   23.91 +    /**
   23.92 +     * \brief Set the "Flow label" field.
   23.93 +     * \param flow the 20-bit value
   23.94 +     */
   23.95 +    void SetFlowLabel (uint32_t flow);
   23.96 +
   23.97 +    /**
   23.98 +     * \brief Get the "Flow label" field.
   23.99 +     * \return the flow label value
  23.100 +     */
  23.101 +    uint32_t GetFlowLabel (void) const;
  23.102 +
  23.103 +    /**
  23.104 +     * \brief Set the "Payload length" field.
  23.105 +     * \param len the length of the payload in bytes
  23.106 +     */
  23.107 +    void SetPayloadLength (uint16_t len);
  23.108 +
  23.109 +    /**
  23.110 +     * \brief Get the "Payload length" field.
  23.111 +     * \return the payload length
  23.112 +     */
  23.113 +    uint16_t GetPayloadLength (void) const;
  23.114 +
  23.115 +    /**
  23.116 +     * \brief Set the "Next header" field.
  23.117 +     * \param next the next header number
  23.118 +     */
  23.119 +    void SetNextHeader (uint8_t next);
  23.120 +
  23.121 +    /**
  23.122 +     * \brief Get the next header.
  23.123 +     * \return the next header number
  23.124 +     */
  23.125 +    uint8_t GetNextHeader (void) const;
  23.126 +
  23.127 +    /**
  23.128 +     * \brief Set the "Hop limit" field (TTL).
  23.129 +     * \param limit the 8-bit value
  23.130 +     */
  23.131 +    void SetHopLimit (uint8_t limit);
  23.132 +
  23.133 +    /**
  23.134 +     * \brief Get the "Hop limit" field (TTL).
  23.135 +     * \return the hop limit value
  23.136 +     */
  23.137 +    uint8_t GetHopLimit (void) const;
  23.138 +
  23.139 +    /**
  23.140 +     * \brief Set the "Source address" field.
  23.141 +     * \param src the source address
  23.142 +     */
  23.143 +    void SetSourceAddress (Ipv6Address src);
  23.144 +
  23.145 +    /**
  23.146 +     * \brief Get the "Source address" field.
  23.147 +     * \return the source address
  23.148 +     */
  23.149 +    Ipv6Address GetSourceAddress (void) const;
  23.150 +
  23.151 +    /**
  23.152 +     * \brief Set the "Destination address" field.
  23.153 +     * \param dst the destination address
  23.154 +     */
  23.155 +    void SetDestinationAddress (Ipv6Address dst);
  23.156 +
  23.157 +    /**
  23.158 +     * \brief Get the "Destination address" field.
  23.159 +     * \return the destination address
  23.160 +     */
  23.161 +    Ipv6Address GetDestinationAddress (void) const;
  23.162 +
  23.163 +    /**
  23.164 +     * \brief Get the name.
  23.165 +     * \return the name
  23.166 +     */
  23.167 +    std::string GetName (void) const;
  23.168 +
  23.169 +    /**
  23.170 +     * \brief Print some informations about the packet.
  23.171 +     * \param os output stream
  23.172 +     * \return info about this packet
  23.173 +     */
  23.174 +    virtual void Print (std::ostream& os) const;
  23.175 +
  23.176 +    /**
  23.177 +     * \brief Get the serialized size of the packet.
  23.178 +     * \return size
  23.179 +     */
  23.180 +    virtual uint32_t GetSerializedSize (void) const;
  23.181 +
  23.182 +    /**
  23.183 +     * \brief Serialize the packet.
  23.184 +     * \param start Buffer iterator
  23.185 +     */
  23.186 +    virtual void Serialize (Buffer::Iterator start) const;
  23.187 +
  23.188 +    /**
  23.189 +     * \brief Deserialize the packet.
  23.190 +     * \param start Buffer iterator
  23.191 +     * \return size of the packet
  23.192 +     */
  23.193 +    virtual uint32_t Deserialize (Buffer::Iterator start);
  23.194 +
  23.195 +  private:
  23.196 +    /**
  23.197 +     * \brief The version (always equal to 6).
  23.198 +     */
  23.199 +    uint32_t m_version : 4;
  23.200 +    /**
  23.201 +     * \brief The traffic class.
  23.202 +     */
  23.203 +    uint32_t m_trafficClass : 8;
  23.204 +
  23.205 +    /**
  23.206 +     * \brief The flow label.
  23.207 +     * \note This is 20-bit value.
  23.208 +     */
  23.209 +    uint32_t m_flowLabel : 20;
  23.210 +
  23.211 +    /**
  23.212 +     * \brief The payload length.
  23.213 +     */
  23.214 +    uint16_t m_payloadLength;
  23.215 +
  23.216 +    /**
  23.217 +     * \brief The Next header number.
  23.218 +     */
  23.219 +    uint8_t m_nextHeader;
  23.220 +
  23.221 +    /**
  23.222 +     * \brief The Hop limit value.
  23.223 +     */
  23.224 +    uint8_t m_hopLimit;
  23.225 +
  23.226 +    /**
  23.227 +     * \brief The source address.
  23.228 +     */
  23.229 +    Ipv6Address m_sourceAddress;
  23.230 +
  23.231 +    /**
  23.232 +     * \brief The destination address.
  23.233 +     */
  23.234 +    Ipv6Address m_destinationAddress;
  23.235 +};
  23.236 +
  23.237 +} /* namespace ns3 */
  23.238 +
  23.239 +#endif /* IPV6_HEADER_H */
  23.240 +
    24.1 --- a/src/node/mac48-address.cc	Thu Nov 06 15:04:25 2008 -0800
    24.2 +++ b/src/node/mac48-address.cc	Fri Nov 07 11:36:15 2008 -0800
    24.3 @@ -170,6 +170,12 @@
    24.4    static Mac48Address multicast = Mac48Address ("01:00:5e:00:00:00");
    24.5    return multicast;
    24.6  }
    24.7 +Mac48Address
    24.8 +Mac48Address::GetMulticast6Prefix (void)
    24.9 +{
   24.10 +  static Mac48Address multicast = Mac48Address ("33:33:00:00:00:00");
   24.11 +  return multicast;
   24.12 +}
   24.13  Mac48Address 
   24.14  Mac48Address::GetMulticast (Ipv4Address multicastGroup)
   24.15  {
   24.16 @@ -206,6 +212,26 @@
   24.17    result.CopyFrom (etherBuffer);
   24.18    return result;
   24.19  }
   24.20 +Mac48Address Mac48Address::GetMulticast(Ipv6Address addr)
   24.21 +{
   24.22 +  Mac48Address etherAddr = Mac48Address::GetMulticast6Prefix();
   24.23 +  uint8_t etherBuffer[6];
   24.24 +  uint8_t ipBuffer[16];
   24.25 +
   24.26 +  /* a MAC multicast IPv6 address is like 33:33 and the four low bytes */
   24.27 +  /* for 2001:db8::2fff:fe11:ac10 => 33:33:FE:11:AC:10 */
   24.28 +  etherAddr.CopyTo (etherBuffer);
   24.29 +  addr.Serialize (ipBuffer);
   24.30 +
   24.31 +  etherBuffer[2] = ipBuffer[12];
   24.32 +  etherBuffer[3] = ipBuffer[13];
   24.33 +  etherBuffer[4] = ipBuffer[14];
   24.34 +  etherBuffer[5] = ipBuffer[15];
   24.35 +
   24.36 +  etherAddr.CopyFrom (etherBuffer);
   24.37 +
   24.38 +  return etherAddr;
   24.39 +}
   24.40  
   24.41  bool operator == (const Mac48Address &a, const Mac48Address &b)
   24.42  {
    25.1 --- a/src/node/mac48-address.h	Thu Nov 06 15:04:25 2008 -0800
    25.2 +++ b/src/node/mac48-address.h	Fri Nov 07 11:36:15 2008 -0800
    25.3 @@ -25,6 +25,7 @@
    25.4  #include "ns3/attribute.h"
    25.5  #include "ns3/attribute-helper.h"
    25.6  #include "ipv4-address.h"
    25.7 +#include "ipv6-address.h"
    25.8  
    25.9  namespace ns3 {
   25.10  
   25.11 @@ -109,9 +110,21 @@
   25.12    static Mac48Address GetMulticast (Ipv4Address address);
   25.13  
   25.14    /**
   25.15 +   * \brief Get multicast address from IPv6 address.
   25.16 +   * \returns a multicast address
   25.17 +   */
   25.18 +  static Mac48Address GetMulticast (Ipv6Address address);
   25.19 +
   25.20 +  /**
   25.21     * \returns the multicast prefix (01:00:5e:00:00:00).
   25.22     */
   25.23    static Mac48Address GetMulticastPrefix (void);
   25.24 +
   25.25 +  /**
   25.26 +   * \brief Get the multicast prefix for IPv6 (33:33:00:00:00:00).
   25.27 +   * \returns a multicast address.
   25.28 +   */
   25.29 +  static Mac48Address GetMulticast6Prefix (void);
   25.30  private:
   25.31    /**
   25.32     * \returns a new Address instance
    26.1 --- a/src/node/net-device.h	Thu Nov 06 15:04:25 2008 -0800
    26.2 +++ b/src/node/net-device.h	Fri Nov 07 11:36:15 2008 -0800
    26.3 @@ -28,6 +28,7 @@
    26.4  #include "ns3/ptr.h"
    26.5  #include "address.h"
    26.6  #include "ipv4-address.h"
    26.7 +#include "ipv6-address.h"
    26.8  
    26.9  namespace ns3 {
   26.10  
   26.11 @@ -173,6 +174,15 @@
   26.12     */
   26.13    virtual Address GetMulticast (Ipv4Address multicastGroup) const = 0;
   26.14    
   26.15 +	/**
   26.16 +   * \brief Get the MAC multicast address corresponding
   26.17 +   * to the IPv6 address provided.
   26.18 +   * \param addr IPv6 address
   26.19 +   * \return the MAC multicast address
   26.20 +   * \warning Calling this method is invalid if IsMulticast returns not true.
   26.21 +   */
   26.22 +  virtual Address GetMulticast (Ipv6Address addr) const = 0;
   26.23 +
   26.24    /**
   26.25     * \return value of m_isPointToPoint flag
   26.26     */
    27.1 --- a/src/node/simple-net-device.cc	Thu Nov 06 15:04:25 2008 -0800
    27.2 +++ b/src/node/simple-net-device.cc	Fri Nov 07 11:36:15 2008 -0800
    27.3 @@ -152,6 +152,12 @@
    27.4  {
    27.5    return Mac48Address::GetMulticast (multicastGroup);
    27.6  }
    27.7 +
    27.8 +Address SimpleNetDevice::GetMulticast (Ipv6Address addr) const
    27.9 +{
   27.10 +	return Mac48Address::GetMulticast (addr);
   27.11 +}
   27.12 +
   27.13  bool 
   27.14  SimpleNetDevice::IsPointToPoint (void) const
   27.15  {
    28.1 --- a/src/node/simple-net-device.h	Thu Nov 06 15:04:25 2008 -0800
    28.2 +++ b/src/node/simple-net-device.h	Fri Nov 07 11:36:15 2008 -0800
    28.3 @@ -67,6 +67,9 @@
    28.4    virtual void SetNode (Ptr<Node> node);
    28.5    virtual bool NeedsArp (void) const;
    28.6    virtual void SetReceiveCallback (NetDevice::ReceiveCallback cb);
    28.7 +
    28.8 +  virtual Address GetMulticast (Ipv6Address addr) const;
    28.9 +
   28.10    virtual void SetPromiscReceiveCallback (PromiscReceiveCallback cb);
   28.11    virtual bool SupportsSendFrom (void) const;
   28.12  
    29.1 --- a/src/node/wscript	Thu Nov 06 15:04:25 2008 -0800
    29.2 +++ b/src/node/wscript	Fri Nov 07 11:36:15 2008 -0800
    29.3 @@ -34,6 +34,10 @@
    29.4          'application.cc',
    29.5          'simple-channel.cc',
    29.6          'simple-net-device.cc',
    29.7 +        'inet6-socket-address.cc',
    29.8 +        'ipv6-address.cc',
    29.9 +        'ipv6-header.cc',
   29.10 +        'icmp-socket.cc',
   29.11          'ipv4-raw-socket-factory.cc',
   29.12          ]
   29.13  
   29.14 @@ -70,5 +74,9 @@
   29.15          'application.h',
   29.16          'simple-channel.h',
   29.17          'simple-net-device.h',
   29.18 +        'inet6-socket-address.h',
   29.19 +        'ipv6-address.h',
   29.20 +        'ipv6-header.h',
   29.21 +        'icmp-socket.h',
   29.22          'ipv4-raw-socket-factory.h',
   29.23          ]