25 #include "ns3/socket.h" 
   26 #include "ns3/packet.h" 
   27 #include "ns3/simulator.h" 
   28 #include "ns3/inet-socket-address.h" 
   29 #include "ns3/packet-socket-address.h" 
   30 #include "ns3/packet-socket.h" 
   31 #include "ns3/point-to-point-net-device.h" 
   32 #include "ns3/mac48-address.h" 
   33 #include "ns3/boolean.h" 
   37 #include "ns3/ipv4-packet-info-tag.h" 
   38 #include "ns3/ipv6-packet-info-tag.h" 
   41 #include <netinet/in.h> 
   42 #include <netinet/ip.h> 
   43 #include <linux/types.h> 
   44 #include <linux/errqueue.h> 
   45 #include <arpa/inet.h> 
   46 #include <linux/if_arp.h> 
   77   NS_LOG_FUNCTION (
this);
 
   91                                     uint8_t icmpType, uint8_t icmpCode,
 
   94   NS_LOG_FUNCTION (
this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
 
   95                    (uint32_t)icmpCode << icmpInfo);
 
  100   struct sockaddr_in offender;
 
  102   if (icmpType == Icmpv4Header::DEST_UNREACH
 
  103       && icmpCode == Icmpv4DestinationUnreachable::FRAG_NEEDED)
 
  105       ee.ee_errno = EMSGSIZE;
 
  107   else if (icmpType == Icmpv4Header::DEST_UNREACH
 
  108            && icmpCode == Icmpv4DestinationUnreachable::PORT_UNREACHABLE)
 
  110       ee.ee_errno = EHOSTUNREACH;
 
  112   else if (icmpType == Icmpv4Header::TIME_EXCEEDED
 
  113            && icmpCode == Icmpv4TimeExceeded::TIME_TO_LIVE)
 
  115       ee.ee_errno = EHOSTUNREACH;
 
  117   else if (icmpType == Icmpv4Header::TIME_EXCEEDED
 
  118            && icmpCode == Icmpv4TimeExceeded::FRAGMENT_REASSEMBLY)
 
  120       ee.ee_errno = ETIMEDOUT;
 
  127   ee.ee_origin = SO_EE_ORIGIN_ICMP;
 
  128   ee.ee_type = icmpType;
 
  129   ee.ee_code = icmpCode;
 
  131   ee.ee_info = icmpInfo;
 
  133   offender.sin_family = AF_INET;
 
  134   offender.sin_addr.s_addr = htonl (icmpSource.Get ());
 
  135   offender.sin_port = 0;
 
  136   memset (offender.sin_zero, 0, sizeof (offender.sin_zero));
 
  144   NS_LOG_FUNCTION (
this << current);
 
  145   NS_ASSERT (current != 0);
 
  147   if (flags & MSG_ERRQUEUE)
 
  152           current->
err = EAGAIN;
 
  159           cmsg.
Add (SOL_IP, IP_RECVERR, 
sizeof (
struct Error), (
const uint8_t*)&
m_errQueue.front ());
 
  164           cmsg.
Add (SOL_IP, IP_TTL, 
sizeof (
int), (
const uint8_t*)&tmp);
 
  181   uint32_t count = msg->msg_iov[0].iov_len;
 
  182   uint8_t *buf = (uint8_t *)msg->msg_iov[0].iov_base;
 
  186   Ptr<Packet> packet = 
m_socket->RecvFrom (count, flags, from);
 
  194   if ((PacketSocketAddress::IsMatchingType (from)))
 
  196       if (msg->msg_namelen < sizeof (sockaddr_ll))
 
  198           current->
err = EINVAL;
 
  204       NS_ASSERT (packet->GetSize () + 14 <= count);
 
  206       memset (buf, 0, count);
 
  207       l = packet->CopyData (buf + 14, count - 14) + 14;
 
  209       SocketAddressTag sat;
 
  213       found = packet->PeekPacketTag (pst);
 
  218       found = packet->PeekPacketTag (sat);
 
  221           if (PacketSocketAddress::IsMatchingType (sat.GetAddress ()))
 
  223               PacketSocketAddress psa = PacketSocketAddress::ConvertFrom (sat.GetAddress ());
 
  227       memcpy (buf + 12, &(((
struct sockaddr_ll *)msg->msg_name)->sll_protocol), 2);
 
  233       if (msg->msg_controllen > 0)
 
  238               NS_LOG_DEBUG (
"RecvPktInfo requested");
 
  242               Ipv4PacketInfoTag ipv4Tag;
 
  243               bool isTagPresent = packet->PeekPacketTag (ipv4Tag);
 
  246                   struct in_pktinfo pkt;
 
  247                   Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
 
  248                   pkt.ipi_ifindex = ipv4->GetInterfaceForDevice (node->GetDevice (ipv4Tag.GetRecvIf ()));
 
  251                       memcpy (&pkt.ipi_addr, msg->msg_name, sizeof (pkt.ipi_addr));
 
  253                   cmsg.
Add (SOL_IP, IP_PKTINFO, 
sizeof (
struct in_pktinfo), (
const uint8_t *)&pkt);
 
  255                   NS_LOG_DEBUG (
"ipv4 tag, iface: " <<  pkt.ipi_ifindex);
 
  258               Ipv6PacketInfoTag ipv6Tag;
 
  259               isTagPresent = packet->PeekPacketTag (ipv6Tag);
 
  262                   struct in6_pktinfo pkt6;
 
  263                   Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
 
  264                   pkt6.ipi6_ifindex = ipv6->GetInterfaceForDevice (node->GetDevice (ipv6Tag.GetRecvIf ()));
 
  267                       memcpy (&pkt6.ipi6_addr, msg->msg_name, sizeof (pkt6.ipi6_addr));
 
  269                   cmsg.
Add (SOL_IPV6, IPV6_PKTINFO, 
sizeof (
struct in6_pktinfo), (
const uint8_t *)&pkt6);
 
  277       NS_ASSERT (packet->GetSize ()  <= count);
 
  278       l = packet->CopyData (buf, count);
 
  279       NS_ASSERT (l == packet->GetSize ());
 
  289   NS_LOG_FUNCTION (
this << current);
 
  290   NS_ASSERT (current != 0);
 
  292   BooleanValue isIpHeaderIncluded (
false);
 
  293   m_socket->GetAttributeFailSafe (
"IpHeaderInclude", isIpHeaderIncluded);
 
  297   for (uint32_t i = 0; i < msg->msg_iovlen; ++i)
 
  299       uint8_t *buf = (uint8_t *)msg->msg_iov[i].iov_base;
 
  300       uint32_t len = msg->msg_iov[i].iov_len;
 
  302       if (isIpHeaderIncluded && i == 0)
 
  304           struct ip *iph = (
struct ip *)buf;
 
  305           NS_ASSERT_MSG (
m_socket->GetInstanceTypeId () == TypeId::LookupByName (
"ns3::Ipv4RawSocketImpl"),
 
  306                          "IsIpHdrIncl==TRUE make sense only for Ipv4RawSocketImpl sockets");
 
  308           ipHeader.SetSource (Ipv4Address (htonl (iph->ip_src.s_addr)));
 
  309           ipHeader.SetDestination (Ipv4Address (htonl (iph->ip_dst.s_addr)));
 
  310           ipHeader.SetProtocol (iph->ip_p);
 
  311           ipHeader.SetPayloadSize (ntohs (iph->ip_len) - 20);
 
  312           ipHeader.SetTtl (iph->ip_ttl);
 
  316       Ptr<Packet> packet = Create<Packet> (buf, len);
 
  317       if (isIpHeaderIncluded)
 
  319           packet->AddHeader (ipHeader);
 
  323       if (msg->msg_name != 0 && msg->msg_namelen != 0)
 
  327           if (DynamicCast<PacketSocket> (
m_socket))
 
  329               Ptr<PacketSocket> s = DynamicCast<PacketSocket> (
m_socket);
 
  330               struct sockaddr_ll* addr = (
struct sockaddr_ll*)msg->msg_name;
 
  332               PacketSocketAddress pad;
 
  334               dest.CopyFrom (addr->sll_addr);
 
  335               pad.SetPhysicalAddress (dest);
 
  338               Address binded = pad;
 
  339               s->GetSockName (binded);
 
  340               if (PacketSocketAddress::IsMatchingType (binded))
 
  342                   PacketSocketAddress pad2 = PacketSocketAddress::ConvertFrom (binded);
 
  344                   pad.SetProtocol (pad2.GetProtocol ());
 
  348               if (addr->sll_ifindex > 0)
 
  350                   pad.SetSingleDevice (addr->sll_ifindex - 1);
 
  354                   pad.SetAllDevices ();
 
  358               packet->RemoveAtStart (14);
 
  363                                              (socklen_t)msg->msg_namelen);
 
  369                                           this, &result, packet, flags, ad));
 
  388   NS_LOG_FUNCTION (
this << current);
 
  389   NS_ASSERT (current != 0);
 
  390   current->
err = EOPNOTSUPP;
 
  397   NS_LOG_FUNCTION (
this << current << my_addr << addrlen);
 
  398   NS_ASSERT (current != 0);
 
  399   current->
err = EOPNOTSUPP;
 
  406   NS_LOG_FUNCTION (
this << current << how);
 
  407   NS_ASSERT (current != 0);
 
  410   current->
err = EOPNOTSUPP;
 
  416   if (Mac48Address::IsMatchingType (a))
 
  419       uint32_t l = a.CopyAllTo (addr, 
sizeof (addr));
 
  421       if ((
sizeof (addr) == l)  && (addr[1] == 6))
 
  423           memcpy (buf, addr + 2, 6);