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);