3820
|
1 |
#include "ipv4-raw-socket-impl.h"
|
|
2 |
#include "ipv4-l3-protocol.h"
|
|
3 |
#include "icmpv4.h"
|
|
4 |
#include "ns3/inet-socket-address.h"
|
|
5 |
#include "ns3/node.h"
|
|
6 |
#include "ns3/packet.h"
|
|
7 |
#include "ns3/uinteger.h"
|
|
8 |
#include "ns3/log.h"
|
|
9 |
|
|
10 |
NS_LOG_COMPONENT_DEFINE ("Ipv4RawSocketImpl");
|
|
11 |
|
|
12 |
namespace ns3 {
|
|
13 |
|
|
14 |
NS_OBJECT_ENSURE_REGISTERED (Ipv4RawSocketImpl);
|
|
15 |
|
|
16 |
TypeId
|
|
17 |
Ipv4RawSocketImpl::GetTypeId (void)
|
|
18 |
{
|
|
19 |
static TypeId tid = TypeId ("ns3::Ipv4RawSocketImpl")
|
|
20 |
.SetParent<Socket> ()
|
|
21 |
.AddAttribute ("Protocol", "Protocol number to match.",
|
|
22 |
UintegerValue (0),
|
|
23 |
MakeUintegerAccessor (&Ipv4RawSocketImpl::m_protocol),
|
|
24 |
MakeUintegerChecker<uint16_t> ())
|
|
25 |
.AddAttribute ("IcmpFilter",
|
|
26 |
"Any icmp header whose type field matches a bit in this filter is dropped.",
|
|
27 |
UintegerValue (0),
|
|
28 |
MakeUintegerAccessor (&Ipv4RawSocketImpl::m_icmpFilter),
|
|
29 |
MakeUintegerChecker<uint32_t> ())
|
|
30 |
;
|
|
31 |
return tid;
|
|
32 |
}
|
|
33 |
|
|
34 |
Ipv4RawSocketImpl::Ipv4RawSocketImpl ()
|
|
35 |
{
|
|
36 |
NS_LOG_FUNCTION (this);
|
|
37 |
m_err = Socket::ERROR_NOTERROR;
|
|
38 |
m_node = 0;
|
|
39 |
m_src = Ipv4Address::GetAny ();
|
|
40 |
m_dst = Ipv4Address::GetAny ();
|
|
41 |
m_protocol = 0;
|
|
42 |
m_shutdownSend = false;
|
|
43 |
m_shutdownRecv = false;
|
|
44 |
}
|
|
45 |
|
|
46 |
void
|
|
47 |
Ipv4RawSocketImpl::SetNode (Ptr<Node> node)
|
|
48 |
{
|
|
49 |
m_node = node;
|
|
50 |
}
|
|
51 |
|
|
52 |
void
|
|
53 |
Ipv4RawSocketImpl::DoDispose (void)
|
|
54 |
{
|
|
55 |
NS_LOG_FUNCTION (this);
|
|
56 |
m_node = 0;
|
|
57 |
Socket::DoDispose ();
|
|
58 |
}
|
|
59 |
|
|
60 |
enum Socket::SocketErrno
|
|
61 |
Ipv4RawSocketImpl::GetErrno (void) const
|
|
62 |
{
|
|
63 |
NS_LOG_FUNCTION (this);
|
|
64 |
return m_err;
|
|
65 |
}
|
|
66 |
Ptr<Node>
|
|
67 |
Ipv4RawSocketImpl::GetNode (void) const
|
|
68 |
{
|
|
69 |
NS_LOG_FUNCTION (this);
|
|
70 |
return m_node;
|
|
71 |
}
|
|
72 |
int
|
|
73 |
Ipv4RawSocketImpl::Bind (const Address &address)
|
|
74 |
{
|
|
75 |
NS_LOG_FUNCTION (this << address);
|
|
76 |
if (!InetSocketAddress::IsMatchingType (address))
|
|
77 |
{
|
|
78 |
m_err = Socket::ERROR_INVAL;
|
|
79 |
return -1;
|
|
80 |
}
|
|
81 |
InetSocketAddress ad = InetSocketAddress::ConvertFrom (address);
|
|
82 |
m_src = ad.GetIpv4 ();
|
|
83 |
return 0;
|
|
84 |
}
|
|
85 |
int
|
|
86 |
Ipv4RawSocketImpl::Bind (void)
|
|
87 |
{
|
|
88 |
NS_LOG_FUNCTION (this);
|
|
89 |
m_src = Ipv4Address::GetAny ();
|
|
90 |
return 0;
|
|
91 |
}
|
|
92 |
int
|
|
93 |
Ipv4RawSocketImpl::GetSockName (Address &address) const
|
|
94 |
{
|
|
95 |
address = InetSocketAddress (m_src, 0);
|
|
96 |
return 0;
|
|
97 |
}
|
|
98 |
int
|
|
99 |
Ipv4RawSocketImpl::Close (void)
|
|
100 |
{
|
|
101 |
NS_LOG_FUNCTION (this);
|
|
102 |
Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
|
|
103 |
if (ipv4 != 0)
|
|
104 |
{
|
|
105 |
ipv4->DeleteRawSocket (this);
|
|
106 |
}
|
|
107 |
return 0;
|
|
108 |
}
|
|
109 |
int
|
|
110 |
Ipv4RawSocketImpl::ShutdownSend (void)
|
|
111 |
{
|
|
112 |
NS_LOG_FUNCTION (this);
|
|
113 |
m_shutdownSend = true;
|
|
114 |
return 0;
|
|
115 |
}
|
|
116 |
int
|
|
117 |
Ipv4RawSocketImpl::ShutdownRecv (void)
|
|
118 |
{
|
|
119 |
NS_LOG_FUNCTION (this);
|
|
120 |
m_shutdownRecv = true;
|
|
121 |
return 0;
|
|
122 |
}
|
|
123 |
int
|
|
124 |
Ipv4RawSocketImpl::Connect (const Address &address)
|
|
125 |
{
|
|
126 |
NS_LOG_FUNCTION (this << address);
|
|
127 |
if (!InetSocketAddress::IsMatchingType (address))
|
|
128 |
{
|
|
129 |
m_err = Socket::ERROR_INVAL;
|
|
130 |
return -1;
|
|
131 |
}
|
|
132 |
InetSocketAddress ad = InetSocketAddress::ConvertFrom (address);
|
|
133 |
m_dst = ad.GetIpv4 ();
|
|
134 |
return 0;
|
|
135 |
}
|
|
136 |
int
|
|
137 |
Ipv4RawSocketImpl::Listen (void)
|
|
138 |
{
|
|
139 |
NS_LOG_FUNCTION (this);
|
|
140 |
m_err = Socket::ERROR_OPNOTSUPP;
|
|
141 |
return -1;
|
|
142 |
}
|
|
143 |
uint32_t
|
|
144 |
Ipv4RawSocketImpl::GetTxAvailable (void) const
|
|
145 |
{
|
|
146 |
NS_LOG_FUNCTION (this);
|
|
147 |
return 0xffffffff;
|
|
148 |
}
|
|
149 |
int
|
|
150 |
Ipv4RawSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
|
|
151 |
{
|
|
152 |
NS_LOG_FUNCTION (this << p << flags);
|
|
153 |
InetSocketAddress to = InetSocketAddress (m_dst, m_protocol);
|
|
154 |
return SendTo (p, flags, to);
|
|
155 |
}
|
|
156 |
int
|
|
157 |
Ipv4RawSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags,
|
|
158 |
const Address &toAddress)
|
|
159 |
{
|
|
160 |
NS_LOG_FUNCTION (this << p << flags << toAddress);
|
|
161 |
if (!InetSocketAddress::IsMatchingType (toAddress))
|
|
162 |
{
|
|
163 |
m_err = Socket::ERROR_INVAL;
|
|
164 |
return -1;
|
|
165 |
}
|
|
166 |
if (m_shutdownSend)
|
|
167 |
{
|
|
168 |
return 0;
|
|
169 |
}
|
|
170 |
InetSocketAddress ad = InetSocketAddress::ConvertFrom (toAddress);
|
|
171 |
Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
|
|
172 |
Ipv4Address dst = ad.GetIpv4 ();
|
|
173 |
uint32_t localIfIndex;
|
|
174 |
if (ipv4->GetIfIndexForDestination(dst, localIfIndex))
|
|
175 |
{
|
|
176 |
ipv4->Send (p, ipv4->GetAddress (localIfIndex), dst, m_protocol);
|
|
177 |
}
|
|
178 |
else
|
|
179 |
{
|
|
180 |
NS_LOG_DEBUG ("dropped because no outgoing route.");
|
|
181 |
}
|
|
182 |
return 0;
|
|
183 |
}
|
|
184 |
uint32_t
|
|
185 |
Ipv4RawSocketImpl::GetRxAvailable (void) const
|
|
186 |
{
|
|
187 |
NS_LOG_FUNCTION (this);
|
|
188 |
uint32_t rx = 0;
|
|
189 |
for (std::list<Data>::const_iterator i = m_recv.begin (); i != m_recv.end (); ++i)
|
|
190 |
{
|
|
191 |
rx += (i->packet)->GetSize ();
|
|
192 |
}
|
|
193 |
return rx;
|
|
194 |
}
|
|
195 |
Ptr<Packet>
|
|
196 |
Ipv4RawSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
|
|
197 |
{
|
|
198 |
NS_LOG_FUNCTION (this << maxSize << flags);
|
|
199 |
Address tmp;
|
|
200 |
return RecvFrom (maxSize, flags, tmp);
|
|
201 |
}
|
|
202 |
Ptr<Packet>
|
|
203 |
Ipv4RawSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
|
|
204 |
Address &fromAddress)
|
|
205 |
{
|
|
206 |
NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
|
|
207 |
if (m_recv.empty ())
|
|
208 |
{
|
|
209 |
return 0;
|
|
210 |
}
|
|
211 |
struct Data data = m_recv.front ();
|
|
212 |
m_recv.pop_front ();
|
|
213 |
if (data.packet->GetSize () > maxSize)
|
|
214 |
{
|
|
215 |
Ptr<Packet> first = data.packet->CreateFragment (0, maxSize);
|
|
216 |
data.packet->RemoveAtStart (maxSize);
|
|
217 |
m_recv.push_front (data);
|
|
218 |
return first;
|
|
219 |
}
|
|
220 |
InetSocketAddress inet = InetSocketAddress (data.fromIp, data.fromProtocol);
|
|
221 |
fromAddress = inet;
|
|
222 |
return data.packet;
|
|
223 |
}
|
|
224 |
|
|
225 |
void
|
|
226 |
Ipv4RawSocketImpl::SetProtocol (uint16_t protocol)
|
|
227 |
{
|
|
228 |
NS_LOG_FUNCTION (this << protocol);
|
|
229 |
m_protocol = protocol;
|
|
230 |
}
|
|
231 |
|
|
232 |
bool
|
|
233 |
Ipv4RawSocketImpl::ForwardUp (Ptr<const Packet> p, Ipv4Header ipHeader, Ptr<NetDevice> device)
|
|
234 |
{
|
|
235 |
NS_LOG_FUNCTION (this << *p << ipHeader << device);
|
|
236 |
if (m_shutdownRecv)
|
|
237 |
{
|
|
238 |
return false;
|
|
239 |
}
|
|
240 |
if ((m_src == Ipv4Address::GetAny () || ipHeader.GetDestination () == m_src) &&
|
|
241 |
(m_dst == Ipv4Address::GetAny () || ipHeader.GetSource () == m_dst) &&
|
|
242 |
ipHeader.GetProtocol () == m_protocol)
|
|
243 |
{
|
|
244 |
Ptr<Packet> copy = p->Copy ();
|
|
245 |
if (m_protocol == 1)
|
|
246 |
{
|
|
247 |
Icmpv4Header icmpHeader;
|
|
248 |
copy->PeekHeader (icmpHeader);
|
|
249 |
uint8_t type = icmpHeader.GetType ();
|
|
250 |
if (type < 32 &&
|
|
251 |
((1 << type) & m_icmpFilter))
|
|
252 |
{
|
|
253 |
// filter out icmp packet.
|
|
254 |
return false;
|
|
255 |
}
|
|
256 |
}
|
|
257 |
copy->AddHeader (ipHeader);
|
|
258 |
struct Data data;
|
|
259 |
data.packet = copy;
|
|
260 |
data.fromIp = ipHeader.GetSource ();
|
|
261 |
data.fromProtocol = ipHeader.GetProtocol ();
|
|
262 |
m_recv.push_back (data);
|
|
263 |
NotifyDataRecv ();
|
|
264 |
return true;
|
|
265 |
}
|
|
266 |
return false;
|
|
267 |
}
|
|
268 |
|
|
269 |
} // namespace ns3
|