src/devices/bridge/bridge-net-device.cc
changeset 3439 a64d1da0d6bf
child 3443 9bb81eb18fed
equal deleted inserted replaced
3438:86e262420fbf 3439:a64d1da0d6bf
       
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
       
     2 /*
       
     3  * This program is free software; you can redistribute it and/or modify
       
     4  * it under the terms of the GNU General Public License version 2 as
       
     5  * published by the Free Software Foundation;
       
     6  *
       
     7  * This program is distributed in the hope that it will be useful,
       
     8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
     9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    10  * GNU General Public License for more details.
       
    11  *
       
    12  * You should have received a copy of the GNU General Public License
       
    13  * along with this program; if not, write to the Free Software
       
    14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    15  *
       
    16  * Author: Gustavo Carneiro  <gjc@inescporto.pt>
       
    17  */
       
    18 #include "bridge-net-device.h"
       
    19 #include "ns3/node.h"
       
    20 #include "ns3/channel.h"
       
    21 #include "ns3/packet.h"
       
    22 #include "ns3/log.h"
       
    23 
       
    24 NS_LOG_COMPONENT_DEFINE ("BridgeNetDevice");
       
    25 
       
    26 namespace ns3 {
       
    27 
       
    28 
       
    29 TypeId
       
    30 BridgeNetDevice::GetTypeId (void)
       
    31 {
       
    32   static TypeId tid = TypeId ("ns3::BridgeNetDevice")
       
    33     .SetParent<NetDevice> ()
       
    34     .AddConstructor<BridgeNetDevice> ()
       
    35     ;
       
    36   return tid;
       
    37 }
       
    38 
       
    39 
       
    40 BridgeNetDevice::BridgeNetDevice ()
       
    41   : m_node (0),
       
    42     m_mtu (0xffff),
       
    43     m_name (""),
       
    44     m_ifIndex (0)
       
    45 {}
       
    46 
       
    47 void
       
    48 BridgeNetDevice::PromiscReceive (Ptr<NetDevice> incomingPort, Ptr<Packet> packet, uint16_t protocol,
       
    49                                  Address const &src, Address const &dst, bool forMe)
       
    50 {
       
    51   NS_LOG_FUNCTION_NOARGS ();
       
    52   NS_LOG_LOGIC ("UID is " << packet->GetUid ());
       
    53 
       
    54   Mac48Address src48 = Mac48Address::ConvertFrom (src);
       
    55   Mac48Address dst48 = Mac48Address::ConvertFrom (dst);
       
    56 
       
    57 //
       
    58 // We never forward up packets that we sent.  Real devices don't do this since
       
    59 // their receivers are disabled during send, so we don't.  Drop the packet 
       
    60 // silently (no tracing) since it would really never get here in a real device.
       
    61 //
       
    62   if (src48 == m_address)
       
    63     {
       
    64       NS_LOG_LOGIC ("Ignoring packet sourced by this device");
       
    65       return;
       
    66     }
       
    67 
       
    68 //
       
    69 // An IP host group address is mapped to an Ethernet multicast address
       
    70 // by placing the low-order 23-bits of the IP address into the low-order
       
    71 // 23 bits of the Ethernet multicast address 01-00-5E-00-00-00 (hex).
       
    72 //
       
    73 // We are going to receive all packets destined to any multicast address,
       
    74 // which means clearing the low-order 23 bits the header destination 
       
    75 //
       
    76   Mac48Address mcDest;
       
    77   uint8_t      mcBuf[6];
       
    78 
       
    79   dst48.CopyTo (mcBuf);
       
    80   mcBuf[3] &= 0x80;
       
    81   mcBuf[4] = 0;
       
    82   mcBuf[5] = 0;
       
    83   mcDest.CopyFrom (mcBuf);
       
    84 
       
    85   Mac48Address multicast = Mac48Address::ConvertFrom (GetMulticast ());
       
    86   Mac48Address broadcast = Mac48Address::ConvertFrom (GetBroadcast ());
       
    87 
       
    88   // decide whether this node should receive the packet for itself
       
    89   
       
    90   NS_LOG_DEBUG ("incomingPort: "  << incomingPort->GetName ()
       
    91                 << "; my address: " << m_address
       
    92                 << "; broadcast: " << broadcast
       
    93                 << "; dst48: " << dst48);
       
    94 
       
    95   if ((dst48 == broadcast) ||
       
    96       (mcDest == multicast) ||
       
    97       (dst48 == m_address))
       
    98     {
       
    99       m_rxCallback (this, packet, protocol, src);
       
   100       // m_rxTrace (originalPacket);
       
   101     }
       
   102 
       
   103   // decide whether the packet should be forwarded
       
   104   if ((dst48 == broadcast) ||
       
   105       (mcDest == multicast) ||
       
   106       (dst48 != m_address))
       
   107     {
       
   108       LearningBridgeForward (incomingPort, packet, protocol, src48, dst48);
       
   109     }
       
   110 }
       
   111 
       
   112 void
       
   113 BridgeNetDevice::LearningBridgeForward (Ptr<NetDevice> incomingPort, Ptr<Packet> packet,
       
   114                                         uint16_t protocol, Mac48Address src, Mac48Address dst)
       
   115 {
       
   116   NS_LOG_DEBUG ("LearningBridgeForward (incomingPort=" << incomingPort->GetName ()
       
   117                 << ", packet=" << packet << ", protocol="<<protocol
       
   118                 << ", src=" << src << ", dst=" << dst << ")");
       
   119   // TODO: add the "learning" part
       
   120 
       
   121   for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
       
   122          iter != m_ports.end (); iter++)
       
   123     {
       
   124       Ptr<NetDevice> port = *iter;
       
   125       if (port != incomingPort)
       
   126         {
       
   127           // TODO: port->SendFrom (packet, protocol, dst, src);
       
   128           port->Send (packet->Copy (), dst, protocol);
       
   129         }
       
   130     }
       
   131 }
       
   132 
       
   133 
       
   134 void 
       
   135 BridgeNetDevice::AddBridgePort (Ptr<NetDevice> bridgePort)
       
   136 {
       
   137   if (m_address == Mac48Address ())
       
   138     {
       
   139       m_address = Mac48Address::ConvertFrom (bridgePort->GetAddress ());
       
   140     }
       
   141 
       
   142   m_node->RegisterPromiscuousProtocolHandler (MakeCallback (&BridgeNetDevice::PromiscReceive, this),
       
   143                                               0, bridgePort);
       
   144   m_ports.push_back (bridgePort);
       
   145 }
       
   146 
       
   147 void 
       
   148 BridgeNetDevice::SetName(const std::string name)
       
   149 {
       
   150   m_name = name;
       
   151 }
       
   152 
       
   153 std::string 
       
   154 BridgeNetDevice::GetName(void) const
       
   155 {
       
   156   return m_name;
       
   157 }
       
   158 
       
   159 void 
       
   160 BridgeNetDevice::SetIfIndex(const uint32_t index)
       
   161 {
       
   162   m_ifIndex = index;
       
   163 }
       
   164 
       
   165 uint32_t 
       
   166 BridgeNetDevice::GetIfIndex(void) const
       
   167 {
       
   168   return m_ifIndex;
       
   169 }
       
   170 
       
   171 Ptr<Channel> 
       
   172 BridgeNetDevice::GetChannel (void) const
       
   173 {
       
   174   return 0;
       
   175 }
       
   176 
       
   177 Address 
       
   178 BridgeNetDevice::GetAddress (void) const
       
   179 {
       
   180   return m_address;
       
   181 }
       
   182 
       
   183 bool 
       
   184 BridgeNetDevice::SetMtu (const uint16_t mtu)
       
   185 {
       
   186   m_mtu = mtu;
       
   187   return true;
       
   188 }
       
   189 
       
   190 uint16_t 
       
   191 BridgeNetDevice::GetMtu (void) const
       
   192 {
       
   193   return m_mtu;
       
   194 }
       
   195 
       
   196 
       
   197 bool 
       
   198 BridgeNetDevice::IsLinkUp (void) const
       
   199 {
       
   200   return true;
       
   201 }
       
   202 
       
   203 
       
   204 void 
       
   205 BridgeNetDevice::SetLinkChangeCallback (Callback<void> callback)
       
   206 {}
       
   207 
       
   208 
       
   209 bool 
       
   210 BridgeNetDevice::IsBroadcast (void) const
       
   211 {
       
   212   return true;
       
   213 }
       
   214 
       
   215 
       
   216 Address
       
   217 BridgeNetDevice::GetBroadcast (void) const
       
   218 {
       
   219   return Mac48Address ("ff:ff:ff:ff:ff:ff");
       
   220 }
       
   221 
       
   222 bool
       
   223 BridgeNetDevice::IsMulticast (void) const
       
   224 {
       
   225   return true;
       
   226 }
       
   227 
       
   228 
       
   229 Address
       
   230 BridgeNetDevice::GetMulticast (void) const
       
   231 {
       
   232   return Mac48Address ("01:00:5e:00:00:00");
       
   233 }
       
   234 
       
   235 
       
   236 Address
       
   237 BridgeNetDevice::MakeMulticastAddress (Ipv4Address multicastGroup) const
       
   238 {
       
   239  NS_LOG_FUNCTION (this << multicastGroup);
       
   240 //
       
   241 // First, get the generic multicast address.
       
   242 //
       
   243   Address hardwareDestination = GetMulticast ();
       
   244 
       
   245   NS_LOG_LOGIC ("Device multicast address: " << hardwareDestination);
       
   246 //
       
   247 // It's our address, and we know we're playing with an EUI-48 address here
       
   248 // primarily since we know that by construction, but also since the parameter
       
   249 // is an Ipv4Address.
       
   250 //
       
   251   Mac48Address etherAddr = Mac48Address::ConvertFrom (hardwareDestination);
       
   252 //
       
   253 // We now have the multicast address in an abstract 48-bit container.  We 
       
   254 // need to pull it out so we can play with it.  When we're done, we have the 
       
   255 // high order bits in etherBuffer[0], etc.
       
   256 //
       
   257   uint8_t etherBuffer[6];
       
   258   etherAddr.CopyTo (etherBuffer);
       
   259 //
       
   260 // Now we need to pull the raw bits out of the Ipv4 destination address.
       
   261 //
       
   262   uint8_t ipBuffer[4];
       
   263   multicastGroup.Serialize (ipBuffer);
       
   264 //
       
   265 // RFC 1112 says that an Ipv4 host group address is mapped to an EUI-48
       
   266 // multicast address by placing the low-order 23-bits of the IP address into 
       
   267 // the low-order 23 bits of the Ethernet multicast address 
       
   268 // 01-00-5E-00-00-00 (hex). 
       
   269 //
       
   270   etherBuffer[3] |= ipBuffer[1] & 0x7f;
       
   271   etherBuffer[4] = ipBuffer[2];
       
   272   etherBuffer[5] = ipBuffer[3];
       
   273 //
       
   274 // Now, etherBuffer has the desired ethernet multicast address.  We have to
       
   275 // suck these bits back into the Mac48Address,
       
   276 //
       
   277   etherAddr.CopyFrom (etherBuffer);
       
   278 //
       
   279 // Implicit conversion (operator Address ()) is defined for Mac48Address, so
       
   280 // use it by just returning the EUI-48 address which is automagically converted
       
   281 // to an Address.
       
   282 //
       
   283   NS_LOG_LOGIC ("multicast address is " << etherAddr);
       
   284 
       
   285   return etherAddr;
       
   286 }
       
   287 
       
   288 
       
   289 bool 
       
   290 BridgeNetDevice::IsPointToPoint (void) const
       
   291 {
       
   292   return false;
       
   293 }
       
   294 
       
   295 
       
   296 bool 
       
   297 BridgeNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
       
   298 {
       
   299   Mac48Address to = Mac48Address::ConvertFrom (dest);
       
   300 
       
   301   for (std::vector< Ptr<NetDevice> >::iterator iter = m_ports.begin ();
       
   302          iter != m_ports.end (); iter++)
       
   303     {
       
   304       Ptr<NetDevice> port = *iter;
       
   305       // TODO: port->SendFrom (packet, protocolNumber, to, m_address);
       
   306       port->Send (packet->Copy (), to, protocolNumber);
       
   307     }
       
   308 
       
   309   return true;
       
   310 }
       
   311 
       
   312 
       
   313 Ptr<Node> 
       
   314 BridgeNetDevice::GetNode (void) const
       
   315 {
       
   316   return m_node;
       
   317 }
       
   318 
       
   319 
       
   320 void 
       
   321 BridgeNetDevice::SetNode (Ptr<Node> node)
       
   322 {
       
   323   m_node = node;
       
   324 }
       
   325 
       
   326 
       
   327 bool 
       
   328 BridgeNetDevice::NeedsArp (void) const
       
   329 {
       
   330   return true;
       
   331 }
       
   332 
       
   333 
       
   334 void 
       
   335 BridgeNetDevice::SetReceiveCallback (NetDevice::ReceiveCallback cb)
       
   336 {
       
   337   m_rxCallback = cb;
       
   338 }
       
   339 
       
   340 
       
   341 void 
       
   342 BridgeNetDevice::SetPromiscuousReceiveCallback (NetDevice::PromiscuousReceiveCallback cb)
       
   343 {
       
   344   m_promiscRxCallback = cb;
       
   345 }
       
   346 
       
   347 
       
   348 void
       
   349 BridgeNetDevice::DoDispose (void)
       
   350 {
       
   351   m_node = 0;
       
   352   NetDevice::DoDispose ();
       
   353 }
       
   354 
       
   355 
       
   356 
       
   357 } // namespace ns3