|
qasimj@4634
|
1 |
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
qasimj@4634
|
2 |
/*
|
|
qasimj@4634
|
3 |
* Copyright (c) 2009 University of Texas at Dallas
|
|
qasimj@4634
|
4 |
*
|
|
qasimj@4634
|
5 |
* This program is free software; you can redistribute it and/or modify
|
|
qasimj@4634
|
6 |
* it under the terms of the GNU General Public License version 2 as
|
|
qasimj@4634
|
7 |
* published by the Free Software Foundation;
|
|
qasimj@4634
|
8 |
*
|
|
qasimj@4634
|
9 |
* This program is distributed in the hope that it will be useful,
|
|
qasimj@4634
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
qasimj@4634
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
qasimj@4634
|
12 |
* GNU General Public License for more details.
|
|
qasimj@4634
|
13 |
*
|
|
qasimj@4634
|
14 |
* You should have received a copy of the GNU General Public License
|
|
qasimj@4634
|
15 |
* along with this program; if not, write to the Free Software
|
|
qasimj@4634
|
16 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
qasimj@4634
|
17 |
*
|
|
qasimj@4634
|
18 |
* Author: Qasim Javed <qasim@utdallas.edu>
|
|
qasimj@4634
|
19 |
*/
|
|
qasimj@4634
|
20 |
#include "ns3/log.h"
|
|
qasimj@4638
|
21 |
#include "ns3/uinteger.h"
|
|
qasimj@4634
|
22 |
#include "ipv4-netfilter.h"
|
|
qasimj@4634
|
23 |
#include "ip-conntrack-info.h"
|
|
qasimj@4634
|
24 |
#include "ipv4-conntrack-l3-protocol.h"
|
|
qasimj@4634
|
25 |
#include "tcp-conntrack-l4-protocol.h"
|
|
qasimj@4634
|
26 |
#include "udp-conntrack-l4-protocol.h"
|
|
qasimj@4637
|
27 |
#include "icmpv4-conntrack-l4-protocol.h"
|
|
qasimj@4638
|
28 |
#include "tcp-header.h"
|
|
qasimj@4638
|
29 |
#include "udp-header.h"
|
|
qasimj@4634
|
30 |
|
|
qasimj@4634
|
31 |
NS_LOG_COMPONENT_DEFINE ("Ipv4Netfilter");
|
|
qasimj@4634
|
32 |
|
|
qasimj@4634
|
33 |
namespace ns3 {
|
|
qasimj@4638
|
34 |
|
|
qasimj@4638
|
35 |
NS_OBJECT_ENSURE_REGISTERED (Ipv4Netfilter);
|
|
qasimj@4638
|
36 |
|
|
qasimj@4638
|
37 |
TypeId
|
|
qasimj@4638
|
38 |
Ipv4Netfilter::GetTypeId (void)
|
|
qasimj@4638
|
39 |
{
|
|
qasimj@4638
|
40 |
static TypeId tId = TypeId ("ns3::Ipv4Netfilter")
|
|
qasimj@4638
|
41 |
.SetParent<Object> ()
|
|
qasimj@4638
|
42 |
.AddAttribute ("EnableNat", "0 disbales NAT and is the default, 1 enabled NAT",
|
|
qasimj@4638
|
43 |
UintegerValue (0),
|
|
qasimj@4638
|
44 |
MakeUintegerAccessor (&Ipv4Netfilter::m_enableNat),
|
|
qasimj@4638
|
45 |
MakeUintegerChecker <uint8_t> ())
|
|
qasimj@4638
|
46 |
;
|
|
qasimj@4638
|
47 |
|
|
qasimj@4638
|
48 |
return tId;
|
|
qasimj@4638
|
49 |
}
|
|
qasimj@4636
|
50 |
|
|
qasimj@4636
|
51 |
Ipv4Netfilter::Ipv4Netfilter ()
|
|
qasimj@4638
|
52 |
: m_enableNat (0)
|
|
qasimj@4634
|
53 |
{
|
|
qasimj@4634
|
54 |
NS_LOG_FUNCTION_NOARGS();
|
|
qasimj@4634
|
55 |
|
|
qasimj@4634
|
56 |
/* Create callback chains for all of the hooks */
|
|
qasimj@4634
|
57 |
for (int i=0; i < NF_INET_NUMHOOKS; i++)
|
|
qasimj@4636
|
58 |
m_netfilterHooks[i] = NetfilterCallbackChain ();
|
|
qasimj@4634
|
59 |
|
|
qasimj@4634
|
60 |
/* Create and register Ipv4 connection tracking module */
|
|
qasimj@4634
|
61 |
Ptr<Ipv4ConntrackL3Protocol> ipv4 = Create<Ipv4ConntrackL3Protocol> ();
|
|
qasimj@4636
|
62 |
this->RegisterL3Protocol (ipv4);
|
|
qasimj@4634
|
63 |
|
|
qasimj@4634
|
64 |
/* Create and register TCP connection tracking module */
|
|
qasimj@4634
|
65 |
Ptr<TcpConntrackL4Protocol> tcp = Create<TcpConntrackL4Protocol> ();
|
|
qasimj@4636
|
66 |
this->RegisterL4Protocol (tcp);
|
|
qasimj@4634
|
67 |
|
|
qasimj@4634
|
68 |
/* Create and register UDP connection tracking module */
|
|
qasimj@4634
|
69 |
Ptr<UdpConntrackL4Protocol> udp = Create<UdpConntrackL4Protocol> ();
|
|
qasimj@4636
|
70 |
this->RegisterL4Protocol (udp);
|
|
qasimj@4637
|
71 |
|
|
qasimj@4637
|
72 |
/* Create and register ICMP connection tracking module */
|
|
qasimj@4637
|
73 |
Ptr<Icmpv4ConntrackL4Protocol> icmpv4 = Create<Icmpv4ConntrackL4Protocol> ();
|
|
qasimj@4637
|
74 |
this->RegisterL4Protocol (icmpv4);
|
|
qasimj@4638
|
75 |
|
|
qasimj@4638
|
76 |
//Ptr <NetworkAddressTranslation> networkAddressTranslation = Create<NetworkAddressTranslation> (this);
|
|
qasimj@4634
|
77 |
|
|
qasimj@4634
|
78 |
/* Create and register hook callbacks */
|
|
qasimj@4636
|
79 |
NetfilterHookCallback preRouting = MakeCallback (&Ipv4Netfilter::NetfilterConntrackIn, this);
|
|
qasimj@4636
|
80 |
NetfilterHookCallback localIn = MakeCallback (&Ipv4ConntrackL3Protocol::Ipv4Confirm, PeekPointer (ipv4));
|
|
qasimj@4634
|
81 |
|
|
qasimj@4638
|
82 |
Ipv4NetfilterHook nfh = Ipv4NetfilterHook (1, NF_INET_PRE_ROUTING, NF_IP_PRI_CONNTRACK , preRouting);
|
|
qasimj@4638
|
83 |
Ipv4NetfilterHook nfh1 = Ipv4NetfilterHook (1, NF_INET_LOCAL_OUT, NF_IP_PRI_CONNTRACK, preRouting);
|
|
qasimj@4638
|
84 |
Ipv4NetfilterHook nfh2 = Ipv4NetfilterHook (1, NF_INET_POST_ROUTING, NF_IP_PRI_CONNTRACK_CONFIRM, localIn);
|
|
qasimj@4638
|
85 |
Ipv4NetfilterHook nfh3 = Ipv4NetfilterHook (1, NF_INET_LOCAL_IN, NF_IP_PRI_CONNTRACK_CONFIRM, localIn);
|
|
qasimj@4638
|
86 |
|
|
qasimj@4636
|
87 |
this->RegisterNetfilterHook (nfh);
|
|
qasimj@4636
|
88 |
this->RegisterNetfilterHook (nfh1);
|
|
qasimj@4636
|
89 |
this->RegisterNetfilterHook (nfh2);
|
|
qasimj@4636
|
90 |
this->RegisterNetfilterHook (nfh3);
|
|
qasimj@4638
|
91 |
|
|
qasimj@4638
|
92 |
if (m_enableNat)
|
|
qasimj@4638
|
93 |
EnableNat ();
|
|
qasimj@4638
|
94 |
|
|
qasimj@4638
|
95 |
nextAvailablePort = 1024;
|
|
qasimj@4634
|
96 |
}
|
|
qasimj@4634
|
97 |
|
|
qasimj@4634
|
98 |
uint32_t
|
|
qasimj@4638
|
99 |
Ipv4Netfilter::RegisterNetfilterHook (Ipv4NetfilterHook hook)
|
|
qasimj@4634
|
100 |
{
|
|
qasimj@4634
|
101 |
//NS_LOG_FUNCTION (this << hook);
|
|
qasimj@4636
|
102 |
m_netfilterHooks[hook.GetHookNumber ()].Insert (hook);
|
|
qasimj@4634
|
103 |
return 0;
|
|
qasimj@4634
|
104 |
}
|
|
qasimj@4634
|
105 |
|
|
qasimj@4634
|
106 |
uint32_t
|
|
qasimj@4636
|
107 |
Ipv4Netfilter::UnRegisterNetfilterHook (Ipv4NetfilterHook& hook)
|
|
qasimj@4634
|
108 |
{
|
|
qasimj@4636
|
109 |
m_netfilterHooks[hook.GetHookNumber ()].Remove (hook);
|
|
qasimj@4634
|
110 |
return 0;
|
|
qasimj@4634
|
111 |
}
|
|
qasimj@4634
|
112 |
|
|
qasimj@4634
|
113 |
uint32_t
|
|
qasimj@4634
|
114 |
Ipv4Netfilter::ProcessHook(uint8_t protocolFamily, Hooks_t hookNumber, Ptr<Packet> p,
|
|
qasimj@4636
|
115 |
Ptr<NetDevice> in, Ptr<NetDevice> out,
|
|
qasimj@4636
|
116 |
ContinueCallback ccb)
|
|
qasimj@4634
|
117 |
{
|
|
qasimj@4636
|
118 |
return m_netfilterHooks[(uint32_t)hookNumber].IterateAndCallHook (hookNumber, p, in, out, ccb);
|
|
qasimj@4634
|
119 |
}
|
|
qasimj@4634
|
120 |
|
|
qasimj@4634
|
121 |
uint32_t
|
|
qasimj@4634
|
122 |
Ipv4Netfilter::RegisterL3Protocol(Ptr<NetfilterConntrackL3Protocol> l3Protocol)
|
|
qasimj@4634
|
123 |
{
|
|
qasimj@4634
|
124 |
//m_netfilterConntrackL3Protocols.push_back(l3Protocol);
|
|
qasimj@4634
|
125 |
m_netfilterConntrackL3Protocols = l3Protocol;
|
|
qasimj@4634
|
126 |
return 0;
|
|
qasimj@4634
|
127 |
}
|
|
qasimj@4634
|
128 |
|
|
qasimj@4634
|
129 |
uint32_t
|
|
qasimj@4634
|
130 |
Ipv4Netfilter::RegisterL4Protocol(Ptr<NetfilterConntrackL4Protocol> l4Protocol)
|
|
qasimj@4634
|
131 |
{
|
|
qasimj@4634
|
132 |
m_netfilterConntrackL4Protocols.push_back(l4Protocol);
|
|
qasimj@4634
|
133 |
return 0;
|
|
qasimj@4634
|
134 |
}
|
|
qasimj@4634
|
135 |
|
|
qasimj@4634
|
136 |
Ptr<NetfilterConntrackL3Protocol>
|
|
qasimj@4636
|
137 |
Ipv4Netfilter::FindL3ProtocolHelper (uint8_t protocolFamily)
|
|
qasimj@4634
|
138 |
{
|
|
qasimj@4634
|
139 |
/*Ptr<NetfilterConntrackL3Protocol>::iterator it;
|
|
qasimj@4634
|
140 |
|
|
qasimj@4634
|
141 |
for (; it != netfilerConntrackL3Protocols.end(); it++)
|
|
qasimj@4634
|
142 |
{
|
|
qasimj@4634
|
143 |
if (protocolFamily == it->protocol)
|
|
qasimj@4634
|
144 |
return *it;
|
|
qasimj@4634
|
145 |
}*/
|
|
qasimj@4634
|
146 |
|
|
qasimj@4634
|
147 |
return m_netfilterConntrackL3Protocols;
|
|
qasimj@4634
|
148 |
|
|
qasimj@4634
|
149 |
}
|
|
qasimj@4634
|
150 |
|
|
qasimj@4634
|
151 |
Ptr<NetfilterConntrackL4Protocol>
|
|
qasimj@4636
|
152 |
Ipv4Netfilter::FindL4ProtocolHelper (uint8_t protocol)
|
|
qasimj@4634
|
153 |
{
|
|
qasimj@4634
|
154 |
std::vector<Ptr<NetfilterConntrackL4Protocol> >::iterator it;
|
|
qasimj@4634
|
155 |
|
|
qasimj@4636
|
156 |
for (it = m_netfilterConntrackL4Protocols.begin (); it != m_netfilterConntrackL4Protocols.end (); it++)
|
|
qasimj@4634
|
157 |
{
|
|
qasimj@4636
|
158 |
NS_LOG_DEBUG ( "L4 protocol: " << (*it)->GetL4Protocol () << ", This protocol : "<<(int)protocol );
|
|
qasimj@4636
|
159 |
if ((*it)->GetL4Protocol () == protocol) {
|
|
qasimj@4634
|
160 |
NS_LOG_DEBUG ( "Found protocol " <<(int)protocol );
|
|
qasimj@4634
|
161 |
return *it;
|
|
qasimj@4634
|
162 |
}
|
|
qasimj@4634
|
163 |
}
|
|
qasimj@4634
|
164 |
|
|
qasimj@4634
|
165 |
return NULL;
|
|
qasimj@4634
|
166 |
}
|
|
qasimj@4634
|
167 |
|
|
qasimj@4634
|
168 |
int
|
|
qasimj@4638
|
169 |
Ipv4Netfilter::UpdateConntrackInfo (uint8_t info)
|
|
qasimj@4634
|
170 |
{
|
|
qasimj@4638
|
171 |
m_hash[currentOriginalTuple].SetInfo (info);
|
|
qasimj@4638
|
172 |
m_hash[currentReplyTuple].SetInfo (info);
|
|
qasimj@4634
|
173 |
return 0;
|
|
qasimj@4634
|
174 |
}
|
|
qasimj@4634
|
175 |
|
|
qasimj@4634
|
176 |
bool
|
|
qasimj@4636
|
177 |
Ipv4Netfilter::NetfilterConntrackGetTuple (Ptr<Packet> packet, uint16_t l3Number, uint8_t protocolNumber,
|
|
qasimj@4634
|
178 |
NetfilterConntrackTuple& tuple, Ptr<NetfilterConntrackL3Protocol> l3Protocol,
|
|
qasimj@4634
|
179 |
Ptr<NetfilterConntrackL4Protocol> l4Protocol)
|
|
qasimj@4634
|
180 |
{
|
|
qasimj@4636
|
181 |
tuple.SetProtocol (l3Number);
|
|
qasimj@4634
|
182 |
|
|
qasimj@4636
|
183 |
if (l3Protocol->PacketToTuple (packet, tuple) == false)
|
|
qasimj@4634
|
184 |
return false;
|
|
qasimj@4634
|
185 |
|
|
qasimj@4634
|
186 |
//TODO: Do we really need the Protocol Family as well?
|
|
qasimj@4634
|
187 |
//tuple->Set
|
|
qasimj@4635
|
188 |
Ipv4Header ipHeader;
|
|
qasimj@4635
|
189 |
NS_LOG_DEBUG (" :: Remove Ipv4 Header :: ");
|
|
qasimj@4636
|
190 |
packet->RemoveHeader (ipHeader);
|
|
qasimj@4634
|
191 |
|
|
qasimj@4636
|
192 |
tuple.SetDirection (IP_CT_DIR_ORIGINAL);
|
|
qasimj@4635
|
193 |
|
|
qasimj@4636
|
194 |
if (l4Protocol->PacketToTuple (packet, tuple) == false)
|
|
qasimj@4635
|
195 |
return false;
|
|
qasimj@4635
|
196 |
|
|
qasimj@4635
|
197 |
NS_LOG_DEBUG (" :: Add Ipv4 Header :: ");
|
|
qasimj@4635
|
198 |
packet->AddHeader (ipHeader);
|
|
qasimj@4634
|
199 |
|
|
qasimj@4635
|
200 |
return true;
|
|
qasimj@4634
|
201 |
}
|
|
qasimj@4634
|
202 |
|
|
qasimj@4635
|
203 |
TupleHashI
|
|
qasimj@4636
|
204 |
Ipv4Netfilter::NewConnection (NetfilterConntrackTuple& tuple, Ptr<NetfilterConntrackL3Protocol> l3proto,
|
|
qasimj@4634
|
205 |
Ptr<NetfilterConntrackL4Protocol> l4proto, Ptr<Packet> packet)
|
|
qasimj@4634
|
206 |
{
|
|
qasimj@4634
|
207 |
NS_LOG_FUNCTION ( this << packet );
|
|
qasimj@4634
|
208 |
|
|
qasimj@4634
|
209 |
NetfilterConntrackTuple replyTuple;
|
|
qasimj@4634
|
210 |
|
|
qasimj@4636
|
211 |
if (!InvertTuple (replyTuple, tuple, l3proto, l4proto))
|
|
qasimj@4636
|
212 |
return m_hash.end ();
|
|
qasimj@4634
|
213 |
|
|
qasimj@4635
|
214 |
// Invoke l4proto->New
|
|
qasimj@4634
|
215 |
|
|
qasimj@4635
|
216 |
// Find expectatons here
|
|
qasimj@4634
|
217 |
|
|
qasimj@4635
|
218 |
NS_LOG_DEBUG (":: Creating an unconfirmed entry for this tuple ::");
|
|
qasimj@4636
|
219 |
m_unconfirmed[tuple] = IpConntrackInfo ();
|
|
qasimj@4635
|
220 |
|
|
qasimj@4636
|
221 |
TupleHashI it = m_unconfirmed.find (tuple);
|
|
qasimj@4635
|
222 |
|
|
qasimj@4635
|
223 |
return it;
|
|
qasimj@4634
|
224 |
}
|
|
qasimj@4634
|
225 |
|
|
qasimj@4634
|
226 |
uint32_t
|
|
qasimj@4634
|
227 |
Ipv4Netfilter::ResolveNormalConntrack (Ptr<Packet> packet, uint32_t protocolFamily, uint8_t protocol,
|
|
qasimj@4634
|
228 |
Ptr<NetfilterConntrackL3Protocol> l3Protocol, Ptr<NetfilterConntrackL4Protocol> l4Protocol,
|
|
qasimj@4634
|
229 |
int& setReply, ConntrackInfo_t& ctInfo, Ipv4Header ipHeader)
|
|
qasimj@4634
|
230 |
{
|
|
qasimj@4634
|
231 |
NS_LOG_FUNCTION (this << packet);
|
|
qasimj@4634
|
232 |
//NetfilterConntrackTuple tuple (ipHeader.GetSource(), 0, ipHeader.GetDestination(), 0);
|
|
qasimj@4634
|
233 |
NetfilterConntrackTuple tuple;
|
|
qasimj@4638
|
234 |
uint8_t conntrackInfo = 0;
|
|
qasimj@4634
|
235 |
|
|
qasimj@4634
|
236 |
/* Get a tuple from the information in the packet */
|
|
qasimj@4636
|
237 |
if (!NetfilterConntrackGetTuple (packet, protocolFamily, protocol, tuple, l3Protocol, l4Protocol))
|
|
qasimj@4634
|
238 |
{
|
|
qasimj@4634
|
239 |
NS_LOG_DEBUG ("Cannot create a tuple from the packet");
|
|
qasimj@4634
|
240 |
return -1;
|
|
qasimj@4634
|
241 |
}
|
|
qasimj@4634
|
242 |
|
|
qasimj@4636
|
243 |
TupleHashI it = m_hash.find (tuple);
|
|
qasimj@4634
|
244 |
|
|
qasimj@4636
|
245 |
if (it == m_hash.end ())
|
|
qasimj@4634
|
246 |
{
|
|
qasimj@4634
|
247 |
NS_LOG_DEBUG ("No tuple found");
|
|
qasimj@4635
|
248 |
//TupleHashI newIt = NewConnection(tuple, l3Protocol, l4Protocol, packet);
|
|
qasimj@4636
|
249 |
it = NewConnection (tuple, l3Protocol, l4Protocol, packet);
|
|
qasimj@4634
|
250 |
}
|
|
qasimj@4638
|
251 |
|
|
qasimj@4638
|
252 |
NetfilterConntrackTuple replyTuple;
|
|
qasimj@4638
|
253 |
|
|
qasimj@4638
|
254 |
if (!InvertTuple (replyTuple, tuple, l3Protocol, l4Protocol))
|
|
qasimj@4638
|
255 |
return -1;
|
|
qasimj@4638
|
256 |
|
|
qasimj@4638
|
257 |
currentOriginalTuple = tuple;
|
|
qasimj@4638
|
258 |
currentReplyTuple = replyTuple;
|
|
qasimj@4634
|
259 |
|
|
qasimj@4635
|
260 |
/* TODO: Add a pointer to the hashed tuple in IpConntrackInfo()
|
|
qasimj@4635
|
261 |
* and store these tuples somehwere, when you destruct then you
|
|
qasimj@4635
|
262 |
* you have to take care of the tuples stored in the vector as
|
|
qasimj@4635
|
263 |
* well
|
|
qasimj@4635
|
264 |
*/
|
|
qasimj@4636
|
265 |
if ((it->first).GetDirection () == (uint8_t)IP_CT_DIR_REPLY)
|
|
qasimj@4634
|
266 |
{
|
|
qasimj@4635
|
267 |
NS_LOG_DEBUG (":: **** This is a REPLY *** ::");
|
|
qasimj@4634
|
268 |
conntrackInfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
|
|
qasimj@4634
|
269 |
setReply = 1;
|
|
qasimj@4634
|
270 |
} else {
|
|
qasimj@4634
|
271 |
NS_LOG_DEBUG (":: Packet is in the original direction ::");
|
|
qasimj@4638
|
272 |
if ( m_hash[tuple].GetStatus () & IPS_SEEN_REPLY) {
|
|
qasimj@4638
|
273 |
NS_LOG_DEBUG (":: Connection ESTABLISHED! ::");
|
|
qasimj@4634
|
274 |
conntrackInfo = IP_CT_ESTABLISHED;
|
|
qasimj@4634
|
275 |
}
|
|
qasimj@4634
|
276 |
else {
|
|
qasimj@4634
|
277 |
NS_LOG_DEBUG (":: New connection :: ");
|
|
qasimj@4634
|
278 |
conntrackInfo = IP_CT_NEW;
|
|
qasimj@4634
|
279 |
}
|
|
qasimj@4634
|
280 |
|
|
qasimj@4634
|
281 |
}
|
|
qasimj@4638
|
282 |
|
|
qasimj@4638
|
283 |
m_unconfirmed[tuple].SetInfo (conntrackInfo);
|
|
qasimj@4638
|
284 |
//UpdateConntrackInfo (conntrackInfo);
|
|
qasimj@4638
|
285 |
/*NS_LOG_DEBUG ("Adding the conntrack packet tag" );
|
|
qasimj@4635
|
286 |
ConntrackTag ctTag;
|
|
qasimj@4635
|
287 |
bool tagFound = packet->PeekPacketTag (ctTag);
|
|
qasimj@4635
|
288 |
|
|
qasimj@4635
|
289 |
if (!tagFound)
|
|
qasimj@4635
|
290 |
packet->AddPacketTag (ConntrackTag (conntrackInfo));
|
|
qasimj@4635
|
291 |
else
|
|
qasimj@4635
|
292 |
NS_LOG_DEBUG ("Tag already present");
|
|
qasimj@4638
|
293 |
*/
|
|
qasimj@4634
|
294 |
|
|
qasimj@4634
|
295 |
return NF_ACCEPT;
|
|
qasimj@4634
|
296 |
|
|
qasimj@4634
|
297 |
}
|
|
qasimj@4634
|
298 |
|
|
qasimj@4634
|
299 |
uint32_t
|
|
qasimj@4636
|
300 |
Ipv4Netfilter::NetfilterConntrackIn (Hooks_t hook, Ptr<Packet> packet, Ptr<NetDevice> in,
|
|
qasimj@4634
|
301 |
Ptr<NetDevice> out, ContinueCallback& ccb)
|
|
qasimj@4634
|
302 |
{
|
|
qasimj@4634
|
303 |
NS_LOG_DEBUG ("::: Executing Hook Function :::");
|
|
qasimj@4634
|
304 |
int setReply=0;
|
|
qasimj@4634
|
305 |
ConntrackInfo_t ctInfo;
|
|
qasimj@4634
|
306 |
/* If this packet has been seen previously, Ignore. */
|
|
qasimj@4634
|
307 |
|
|
qasimj@4634
|
308 |
/* Find layer 3 helper for this packet */
|
|
qasimj@4636
|
309 |
Ptr<NetfilterConntrackL3Protocol> l3proto = FindL3ProtocolHelper (1);
|
|
qasimj@4634
|
310 |
|
|
qasimj@4634
|
311 |
Ipv4Header ipHeader;
|
|
qasimj@4634
|
312 |
|
|
qasimj@4636
|
313 |
packet->PeekHeader (ipHeader);
|
|
qasimj@4634
|
314 |
|
|
qasimj@4636
|
315 |
NS_LOG_DEBUG ( "IP header protocol: " << (int)ipHeader.GetProtocol ());
|
|
qasimj@4634
|
316 |
|
|
qasimj@4636
|
317 |
Ptr<NetfilterConntrackL4Protocol> l4proto = FindL4ProtocolHelper (ipHeader.GetProtocol ());
|
|
qasimj@4634
|
318 |
|
|
qasimj@4634
|
319 |
/*if (l4proto != NULL) {
|
|
qasimj@4634
|
320 |
}*/
|
|
qasimj@4634
|
321 |
|
|
qasimj@4636
|
322 |
ResolveNormalConntrack (packet, 1 /* PF */, ipHeader.GetProtocol (), l3proto, l4proto, setReply, ctInfo, ipHeader);
|
|
qasimj@4634
|
323 |
|
|
qasimj@4634
|
324 |
// Call layer 4 Packet callback
|
|
qasimj@4634
|
325 |
//uint32_t ret = l4proto->packet(packet, protocolFamily, hookNumber);
|
|
qasimj@4634
|
326 |
|
|
qasimj@4638
|
327 |
if (setReply)
|
|
qasimj@4638
|
328 |
{
|
|
qasimj@4638
|
329 |
NS_LOG_DEBUG ("Setting IPS_SEEN_REPLY");
|
|
qasimj@4638
|
330 |
m_hash[currentOriginalTuple].SetStatus ( IPS_SEEN_REPLY );
|
|
qasimj@4638
|
331 |
m_hash[currentReplyTuple].SetStatus ( IPS_SEEN_REPLY );
|
|
qasimj@4638
|
332 |
}
|
|
qasimj@4638
|
333 |
|
|
qasimj@4634
|
334 |
return NF_ACCEPT;
|
|
qasimj@4634
|
335 |
|
|
qasimj@4634
|
336 |
}
|
|
qasimj@4634
|
337 |
|
|
qasimj@4635
|
338 |
uint32_t
|
|
qasimj@4635
|
339 |
Ipv4Netfilter::NetfilterConntrackConfirm (Ptr<Packet> packet)
|
|
qasimj@4635
|
340 |
//, NetfilterConntrackTuple& orig,
|
|
qasimj@4635
|
341 |
// NetfilterConntrackTuple& reply)
|
|
qasimj@4634
|
342 |
{
|
|
qasimj@4635
|
343 |
NS_LOG_FUNCTION ( this << packet );
|
|
qasimj@4635
|
344 |
/* If this packet has been seen previously, Ignore. */
|
|
qasimj@4635
|
345 |
|
|
qasimj@4635
|
346 |
/* Find layer 3 helper for this packet */
|
|
qasimj@4638
|
347 |
/*Ptr<NetfilterConntrackL3Protocol> l3proto = FindL3ProtocolHelper (1);
|
|
qasimj@4635
|
348 |
|
|
qasimj@4638
|
349 |
Ipv4Header ipHeader;
|
|
qasimj@4635
|
350 |
|
|
qasimj@4635
|
351 |
//packet->RemoveHeader(ipHeader);
|
|
qasimj@4636
|
352 |
packet->PeekHeader (ipHeader);
|
|
qasimj@4635
|
353 |
|
|
qasimj@4636
|
354 |
NS_LOG_DEBUG ( "IP header protocol: " << (int)ipHeader.GetProtocol ());
|
|
qasimj@4638
|
355 |
|
|
qasimj@4636
|
356 |
Ptr<NetfilterConntrackL4Protocol> l4proto = FindL4ProtocolHelper (ipHeader.GetProtocol ());
|
|
qasimj@4638
|
357 |
|
|
qasimj@4638
|
358 |
NetfilterConntrackTuple orig;*/
|
|
qasimj@4638
|
359 |
|
|
qasimj@4635
|
360 |
/* Get a tuple from the information in the packet */
|
|
qasimj@4638
|
361 |
/*if (!NetfilterConntrackGetTuple (packet, 1, ipHeader.GetProtocol (), orig, l3proto, l4proto))
|
|
qasimj@4638
|
362 |
{
|
|
qasimj@4635
|
363 |
NS_LOG_DEBUG ("Cannot create a tuple from the packet");
|
|
qasimj@4635
|
364 |
return -1;
|
|
qasimj@4638
|
365 |
}
|
|
qasimj@4635
|
366 |
|
|
qasimj@4638
|
367 |
NetfilterConntrackTuple reply;
|
|
qasimj@4638
|
368 |
|
|
qasimj@4638
|
369 |
|
|
qasimj@4638
|
370 |
InvertTuple (reply, orig, l3proto, l4proto);
|
|
qasimj@4638
|
371 |
|
|
qasimj@4638
|
372 |
currentOriginalTuple = orig;
|
|
qasimj@4638
|
373 |
currentReplyTuple = reply;
|
|
qasimj@4638
|
374 |
|
|
qasimj@4638
|
375 |
NS_LOG_DEBUG ("Current Original Tuple: " << currentOriginalTuple.GetSource () << ", " << currentOriginalTuple.GetDestination ());
|
|
qasimj@4638
|
376 |
NS_LOG_DEBUG ("Current Reply Tuple: " << currentReplyTuple.GetSource () << ", " << currentReplyTuple.GetDestination ());
|
|
qasimj@4638
|
377 |
//currentTuple[IP_CT_DIR_REPLY] = reply;*/
|
|
qasimj@4635
|
378 |
|
|
qasimj@4635
|
379 |
/**************************/
|
|
qasimj@4635
|
380 |
|
|
qasimj@4638
|
381 |
/*ConntrackTag ctTag;
|
|
qasimj@4634
|
382 |
|
|
qasimj@4638
|
383 |
if (!packet->PeekPacketTag (ctTag))
|
|
qasimj@4638
|
384 |
{
|
|
qasimj@4634
|
385 |
NS_LOG_DEBUG ("ConntrackTag not found");
|
|
qasimj@4634
|
386 |
return 0;
|
|
qasimj@4638
|
387 |
}
|
|
qasimj@4638
|
388 |
else {
|
|
qasimj@4636
|
389 |
if ( CTINFO2DIR (ctTag.GetConntrack ()) != IP_CT_DIR_ORIGINAL)
|
|
qasimj@4638
|
390 |
return 0;
|
|
qasimj@4635
|
391 |
|
|
qasimj@4636
|
392 |
if (m_hash.find (orig) != m_hash.end () && m_hash.find (reply) != m_hash.end () )
|
|
qasimj@4635
|
393 |
{
|
|
qasimj@4638
|
394 |
NS_LOG_DEBUG ("Entries already present!");
|
|
qasimj@4638
|
395 |
return NF_DROP;
|
|
qasimj@4635
|
396 |
}
|
|
qasimj@4635
|
397 |
|
|
qasimj@4635
|
398 |
NS_LOG_DEBUG ("Creating confirmed hash entries");
|
|
qasimj@4638
|
399 |
//m_hash[orig] = IpConntrackInfo().SetStatus(IPS_CONFIRMED);
|
|
qasimj@4638
|
400 |
m_hash[orig] = IpConntrackInfo ();
|
|
qasimj@4638
|
401 |
m_hash[reply] = IpConntrackInfo ();
|
|
qasimj@4635
|
402 |
|
|
qasimj@4638
|
403 |
}*/
|
|
qasimj@4638
|
404 |
|
|
qasimj@4638
|
405 |
if ( CTINFO2DIR (m_unconfirmed[currentOriginalTuple].GetInfo ()) != IP_CT_DIR_ORIGINAL)
|
|
qasimj@4638
|
406 |
{
|
|
qasimj@4638
|
407 |
NS_LOG_DEBUG ("Not a packet in the original direction");
|
|
qasimj@4638
|
408 |
return NF_ACCEPT;
|
|
qasimj@4634
|
409 |
}
|
|
qasimj@4634
|
410 |
|
|
qasimj@4638
|
411 |
/*if (m_hash.find (currentOriginalTuple) != m_hash.end () && m_hash.find (currentReplyTuple) != m_hash.end () )
|
|
qasimj@4638
|
412 |
{
|
|
qasimj@4638
|
413 |
NS_LOG_DEBUG ("Entries already present!");
|
|
qasimj@4638
|
414 |
return NF_DROP;
|
|
qasimj@4638
|
415 |
}*/
|
|
qasimj@4638
|
416 |
|
|
qasimj@4638
|
417 |
NS_LOG_DEBUG ("Creating confirmed hash entries");
|
|
qasimj@4638
|
418 |
m_hash[currentOriginalTuple] = m_unconfirmed[currentOriginalTuple];
|
|
qasimj@4638
|
419 |
m_hash[currentReplyTuple] = m_unconfirmed[currentOriginalTuple];
|
|
qasimj@4635
|
420 |
|
|
qasimj@4634
|
421 |
return 0;
|
|
qasimj@4634
|
422 |
}
|
|
qasimj@4634
|
423 |
|
|
qasimj@4638
|
424 |
uint32_t
|
|
qasimj@4638
|
425 |
Ipv4Netfilter::NetfilterDoNat (Hooks_t hookNumber, Ptr<Packet> p,
|
|
qasimj@4638
|
426 |
Ptr<NetDevice> in, Ptr<NetDevice> out, ContinueCallback& ccb)
|
|
qasimj@4638
|
427 |
{
|
|
qasimj@4638
|
428 |
NS_LOG_FUNCTION ( this << p );
|
|
qasimj@4638
|
429 |
/*ConntrackTag ctTag;
|
|
qasimj@4638
|
430 |
|
|
qasimj@4638
|
431 |
bool found = p->PeekPacketTag (ctTag);
|
|
qasimj@4638
|
432 |
|
|
qasimj@4638
|
433 |
if (!found)
|
|
qasimj@4638
|
434 |
{
|
|
qasimj@4638
|
435 |
NS_LOG_DEBUG ("Conntrack tag not found");
|
|
qasimj@4638
|
436 |
return NF_ACCEPT;
|
|
qasimj@4638
|
437 |
}*/
|
|
qasimj@4638
|
438 |
|
|
qasimj@4638
|
439 |
/* Conntrack has a higher priority so currentOriginalTuple and
|
|
qasimj@4638
|
440 |
* currentReply tuple should always be correct
|
|
qasimj@4638
|
441 |
*/
|
|
qasimj@4638
|
442 |
|
|
qasimj@4638
|
443 |
//std::vector<NatRule>::iterator it = FindNatDevice (out);
|
|
qasimj@4638
|
444 |
|
|
qasimj@4638
|
445 |
/*if (it == m_natRules.end ())
|
|
qasimj@4638
|
446 |
{
|
|
qasimj@4638
|
447 |
NS_LOG_DEBUG ("No NAT rule for device " << out->GetId ());
|
|
qasimj@4638
|
448 |
return NF_ACCEPT;
|
|
qasimj@4638
|
449 |
}*/
|
|
qasimj@4638
|
450 |
|
|
qasimj@4638
|
451 |
NS_LOG_DEBUG ("Current Original Tuple: " << currentOriginalTuple.GetSource () << ", " << currentOriginalTuple.GetDestination ());
|
|
qasimj@4638
|
452 |
NS_LOG_DEBUG ("Current Reply Tuple: " << currentReplyTuple.GetSource () << ", " << currentReplyTuple.GetDestination ());
|
|
qasimj@4638
|
453 |
|
|
qasimj@4638
|
454 |
NS_LOG_DEBUG ("ConntrackInfo: " << (uint16_t)m_unconfirmed[currentOriginalTuple].GetInfo () );
|
|
qasimj@4638
|
455 |
|
|
qasimj@4638
|
456 |
/* TODO: Why are you checking m_hash here when the info is in
|
|
qasimj@4638
|
457 |
* m_unconfirmed. This could be a problem because NAT is sandwiched
|
|
qasimj@4638
|
458 |
* between conntrack hook callbacks
|
|
qasimj@4638
|
459 |
*/
|
|
qasimj@4638
|
460 |
switch (m_unconfirmed[currentOriginalTuple].GetInfo ())
|
|
qasimj@4638
|
461 |
{
|
|
qasimj@4638
|
462 |
case IP_CT_RELATED:
|
|
qasimj@4638
|
463 |
case IP_CT_RELATED + IP_CT_IS_REPLY:
|
|
qasimj@4638
|
464 |
/* This should be updated when "expectations" are added */
|
|
qasimj@4638
|
465 |
break;
|
|
qasimj@4638
|
466 |
|
|
qasimj@4638
|
467 |
case IP_CT_NEW:
|
|
qasimj@4638
|
468 |
|
|
qasimj@4638
|
469 |
if ( hookNumber == NF_INET_POST_ROUTING )
|
|
qasimj@4638
|
470 |
{
|
|
qasimj@4638
|
471 |
NS_LOG_DEBUG ("SRC_NAT: New Connection encountered");
|
|
qasimj@4638
|
472 |
|
|
qasimj@4638
|
473 |
TupleHashI it;
|
|
qasimj@4638
|
474 |
|
|
qasimj@4638
|
475 |
|
|
qasimj@4638
|
476 |
if ( (it = m_hash.find (currentOriginalTuple)) != m_hash.end ())
|
|
qasimj@4638
|
477 |
{
|
|
qasimj@4638
|
478 |
if ( !((it->second).GetStatus () & IPS_SRC_NAT_DONE) )
|
|
qasimj@4638
|
479 |
{
|
|
qasimj@4638
|
480 |
/* Get a unique tuple and create a mapping */
|
|
qasimj@4638
|
481 |
|
|
qasimj@4638
|
482 |
NS_LOG_DEBUG ("Doing rule lookup at device " << out->GetIfIndex ());
|
|
qasimj@4638
|
483 |
std::vector<NatRule>::iterator it =
|
|
qasimj@4638
|
484 |
FindNatRule ( Ipv4Address (currentOriginalTuple.GetSource ()), out );
|
|
qasimj@4638
|
485 |
|
|
qasimj@4638
|
486 |
if ( it == m_natRules.end () )
|
|
qasimj@4638
|
487 |
{
|
|
qasimj@4638
|
488 |
NS_LOG_DEBUG ("No rule matched!");
|
|
qasimj@4638
|
489 |
return NF_ACCEPT;
|
|
qasimj@4638
|
490 |
}
|
|
qasimj@4638
|
491 |
|
|
qasimj@4638
|
492 |
NS_LOG_DEBUG ("Creating a NAT mapping");
|
|
qasimj@4638
|
493 |
|
|
qasimj@4638
|
494 |
/* Create a NULL mapping, which does not contain port numbers */
|
|
qasimj@4638
|
495 |
NetfilterConntrackTuple mapping =
|
|
qasimj@4638
|
496 |
NetfilterConntrackTuple (it->GetMangledSource (), nextAvailablePort,
|
|
qasimj@4638
|
497 |
currentOriginalTuple.GetDestination (), 9);
|
|
qasimj@4638
|
498 |
mapping.SetDirection (IP_CT_DIR_ORIGINAL);
|
|
qasimj@4638
|
499 |
nextAvailablePort++;
|
|
qasimj@4638
|
500 |
|
|
qasimj@4638
|
501 |
NS_LOG_DEBUG ("Creating a NAT mapping for the tuple " << currentOriginalTuple
|
|
qasimj@4638
|
502 |
<< ": " << mapping );
|
|
qasimj@4638
|
503 |
m_natMappings[currentOriginalTuple] = mapping;
|
|
qasimj@4638
|
504 |
m_natReplyLookup[mapping] = currentOriginalTuple;
|
|
qasimj@4638
|
505 |
}
|
|
qasimj@4638
|
506 |
|
|
qasimj@4638
|
507 |
|
|
qasimj@4638
|
508 |
NS_LOG_DEBUG (":: Translating addresses and fixing IP checksum ::");
|
|
qasimj@4638
|
509 |
NetfilterNatPacket (hookNumber, p);
|
|
qasimj@4638
|
510 |
}
|
|
qasimj@4638
|
511 |
else
|
|
qasimj@4638
|
512 |
NS_LOG_DEBUG ("BUG: currentTuple non-existent in hash!");
|
|
qasimj@4638
|
513 |
}
|
|
qasimj@4638
|
514 |
|
|
qasimj@4638
|
515 |
break;
|
|
qasimj@4638
|
516 |
|
|
qasimj@4638
|
517 |
default:
|
|
qasimj@4638
|
518 |
NS_LOG_DEBUG ("SRC_NAT: Connection is established!");
|
|
qasimj@4638
|
519 |
NS_LOG_DEBUG (":: Translating addresses and fixing IP checksum ::");
|
|
qasimj@4638
|
520 |
NetfilterNatPacket (hookNumber, p);
|
|
qasimj@4638
|
521 |
|
|
qasimj@4638
|
522 |
}
|
|
qasimj@4638
|
523 |
|
|
qasimj@4638
|
524 |
|
|
qasimj@4638
|
525 |
return NF_ACCEPT;
|
|
qasimj@4638
|
526 |
}
|
|
qasimj@4638
|
527 |
|
|
qasimj@4634
|
528 |
bool
|
|
qasimj@4634
|
529 |
Ipv4Netfilter::InvertTuple (NetfilterConntrackTuple& inverse, NetfilterConntrackTuple& orig,
|
|
qasimj@4634
|
530 |
Ptr<NetfilterConntrackL3Protocol> l3Protocol,
|
|
qasimj@4634
|
531 |
Ptr<NetfilterConntrackL4Protocol> l4Protocol)
|
|
qasimj@4634
|
532 |
{
|
|
qasimj@4636
|
533 |
inverse.SetProtocol (orig.GetProtocol ());
|
|
qasimj@4634
|
534 |
|
|
qasimj@4636
|
535 |
if (!l3Protocol->InvertTuple (inverse, orig))
|
|
qasimj@4634
|
536 |
return false;
|
|
qasimj@4634
|
537 |
|
|
qasimj@4636
|
538 |
inverse.SetDirection (orig.GetDirection () == IP_CT_DIR_ORIGINAL ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL);
|
|
qasimj@4634
|
539 |
|
|
qasimj@4636
|
540 |
return l4Protocol->InvertTuple (inverse, orig);
|
|
qasimj@4634
|
541 |
|
|
qasimj@4634
|
542 |
}
|
|
qasimj@4638
|
543 |
|
|
qasimj@4638
|
544 |
TupleHash&
|
|
qasimj@4638
|
545 |
Ipv4Netfilter::GetHash ()
|
|
qasimj@4638
|
546 |
{
|
|
qasimj@4638
|
547 |
return m_hash;
|
|
qasimj@4638
|
548 |
}
|
|
qasimj@4638
|
549 |
|
|
qasimj@4638
|
550 |
void
|
|
qasimj@4638
|
551 |
Ipv4Netfilter::AddNatRule (NatRule natRule)
|
|
qasimj@4638
|
552 |
{
|
|
qasimj@4638
|
553 |
m_natRules.push_back (natRule);
|
|
qasimj@4638
|
554 |
}
|
|
qasimj@4634
|
555 |
|
|
qasimj@4638
|
556 |
std::vector<NatRule>::iterator
|
|
qasimj@4638
|
557 |
Ipv4Netfilter::FindNatRule (NatRule natRule)
|
|
qasimj@4635
|
558 |
{
|
|
qasimj@4638
|
559 |
std::vector<NatRule>::iterator it = m_natRules.begin ();
|
|
qasimj@4635
|
560 |
|
|
qasimj@4638
|
561 |
for ( ; it != m_natRules.end (); it++)
|
|
qasimj@4635
|
562 |
{
|
|
qasimj@4638
|
563 |
if ( *it == natRule )
|
|
qasimj@4638
|
564 |
return it;
|
|
qasimj@4635
|
565 |
}
|
|
qasimj@4635
|
566 |
|
|
qasimj@4638
|
567 |
return m_natRules.end ();
|
|
qasimj@4638
|
568 |
}
|
|
qasimj@4635
|
569 |
|
|
qasimj@4638
|
570 |
std::vector<NatRule>::iterator
|
|
qasimj@4638
|
571 |
Ipv4Netfilter::FindNatRule (Ipv4Address orig, Ptr<NetDevice> out)
|
|
qasimj@4638
|
572 |
{
|
|
qasimj@4638
|
573 |
std::vector<NatRule>::iterator it = m_natRules.begin ();
|
|
qasimj@4635
|
574 |
|
|
qasimj@4638
|
575 |
NS_LOG_DEBUG ("Number of rules: " << m_natRules.size () );
|
|
qasimj@4638
|
576 |
NS_LOG_DEBUG ("Orig: " << orig );
|
|
qasimj@4635
|
577 |
|
|
qasimj@4638
|
578 |
for ( ; it != m_natRules.end (); it++)
|
|
qasimj@4638
|
579 |
{
|
|
qasimj@4638
|
580 |
NS_LOG_DEBUG ("Rule source: " << it->GetOriginalSource () << ", passed in source: " << orig);
|
|
qasimj@4638
|
581 |
NS_LOG_DEBUG ("Rule device: " << it->GetDevice () << ", passed in dev: " << out);
|
|
qasimj@4638
|
582 |
if ( it->GetOriginalSource () == orig && it->GetDevice () == out)
|
|
qasimj@4638
|
583 |
{
|
|
qasimj@4638
|
584 |
NS_LOG_DEBUG ("Rule match found!");
|
|
qasimj@4638
|
585 |
return it;
|
|
qasimj@4638
|
586 |
}
|
|
qasimj@4638
|
587 |
}
|
|
qasimj@4635
|
588 |
|
|
qasimj@4638
|
589 |
return m_natRules.end ();
|
|
qasimj@4638
|
590 |
}
|
|
qasimj@4638
|
591 |
|
|
qasimj@4638
|
592 |
void
|
|
qasimj@4638
|
593 |
Ipv4Netfilter::EnableNat ()
|
|
qasimj@4638
|
594 |
{
|
|
qasimj@4638
|
595 |
m_enableNat = 1;
|
|
qasimj@4635
|
596 |
|
|
qasimj@4638
|
597 |
NS_LOG_DEBUG (":: Enabling NAT ::");
|
|
qasimj@4638
|
598 |
|
|
qasimj@4638
|
599 |
NetfilterHookCallback doNat = MakeCallback (&Ipv4Netfilter::NetfilterDoNat, this);
|
|
qasimj@4638
|
600 |
|
|
qasimj@4638
|
601 |
Ipv4NetfilterHook natCallback1 = Ipv4NetfilterHook (1, NF_INET_POST_ROUTING, NF_IP_PRI_NAT_SRC, doNat);
|
|
qasimj@4638
|
602 |
Ipv4NetfilterHook natCallback2 = Ipv4NetfilterHook (1, NF_INET_PRE_ROUTING, NF_IP_PRI_NAT_DST, doNat);
|
|
qasimj@4638
|
603 |
|
|
qasimj@4638
|
604 |
|
|
qasimj@4638
|
605 |
this->RegisterNetfilterHook (natCallback1);
|
|
qasimj@4638
|
606 |
this->RegisterNetfilterHook (natCallback2);
|
|
qasimj@4638
|
607 |
}
|
|
qasimj@4638
|
608 |
|
|
qasimj@4638
|
609 |
uint32_t
|
|
qasimj@4638
|
610 |
Ipv4Netfilter::NetfilterNatPacket (Hooks_t hookNumber, Ptr<Packet> p)
|
|
qasimj@4638
|
611 |
{
|
|
qasimj@4638
|
612 |
NS_LOG_FUNCTION ( this << p );
|
|
qasimj@4638
|
613 |
Ipv4Header ipHeader;
|
|
qasimj@4638
|
614 |
uint16_t dstPort; //, srcPort;
|
|
qasimj@4638
|
615 |
Ipv4Address dstAddress, srcAddress;
|
|
qasimj@4638
|
616 |
|
|
qasimj@4638
|
617 |
p->RemoveHeader (ipHeader);
|
|
qasimj@4638
|
618 |
|
|
qasimj@4638
|
619 |
uint16_t protocol = ipHeader.GetProtocol ();
|
|
qasimj@4638
|
620 |
|
|
qasimj@4638
|
621 |
if (hookNumber == NF_INET_POST_ROUTING)
|
|
qasimj@4638
|
622 |
{
|
|
qasimj@4638
|
623 |
NetfilterConntrackTuple mapped = m_natMappings[currentOriginalTuple];
|
|
qasimj@4638
|
624 |
|
|
qasimj@4638
|
625 |
ipHeader.SetSource (mapped.GetSource ());
|
|
qasimj@4638
|
626 |
|
|
qasimj@4638
|
627 |
if (protocol == IPPROTO_TCP)
|
|
qasimj@4638
|
628 |
{
|
|
qasimj@4638
|
629 |
TcpHeader tcpHeader;
|
|
qasimj@4638
|
630 |
|
|
qasimj@4638
|
631 |
p->RemoveHeader (tcpHeader);
|
|
qasimj@4638
|
632 |
|
|
qasimj@4638
|
633 |
tcpHeader.SetSourcePort (mapped.GetSourcePort ());
|
|
qasimj@4638
|
634 |
|
|
qasimj@4638
|
635 |
p->AddHeader (tcpHeader);
|
|
qasimj@4638
|
636 |
|
|
qasimj@4638
|
637 |
}
|
|
qasimj@4638
|
638 |
else
|
|
qasimj@4638
|
639 |
{
|
|
qasimj@4638
|
640 |
UdpHeader udpHeader;
|
|
qasimj@4638
|
641 |
|
|
qasimj@4638
|
642 |
p->RemoveHeader (udpHeader);
|
|
qasimj@4638
|
643 |
|
|
qasimj@4638
|
644 |
udpHeader.SetSourcePort (mapped.GetSourcePort ());
|
|
qasimj@4638
|
645 |
|
|
qasimj@4638
|
646 |
p->AddHeader (udpHeader);
|
|
qasimj@4638
|
647 |
}
|
|
qasimj@4638
|
648 |
|
|
qasimj@4638
|
649 |
p->AddHeader (ipHeader);
|
|
qasimj@4638
|
650 |
|
|
qasimj@4638
|
651 |
NetfilterConntrackTuple oldOriginalTuple = currentOriginalTuple;
|
|
qasimj@4638
|
652 |
|
|
qasimj@4638
|
653 |
|
|
qasimj@4638
|
654 |
currentOriginalTuple = NetfilterConntrackTuple (mapped.GetSource(), mapped.GetSourcePort (),
|
|
qasimj@4638
|
655 |
currentOriginalTuple.GetDestination (),
|
|
qasimj@4638
|
656 |
currentOriginalTuple.GetDestinationPort ());
|
|
qasimj@4638
|
657 |
|
|
qasimj@4638
|
658 |
currentOriginalTuple.SetDirection (IP_CT_DIR_ORIGINAL);
|
|
qasimj@4638
|
659 |
|
|
qasimj@4638
|
660 |
currentReplyTuple = NetfilterConntrackTuple (currentOriginalTuple.GetDestination (),
|
|
qasimj@4638
|
661 |
currentOriginalTuple.GetDestinationPort (),
|
|
qasimj@4638
|
662 |
mapped.GetSource (), mapped.GetSourcePort ());
|
|
qasimj@4638
|
663 |
|
|
qasimj@4638
|
664 |
currentReplyTuple.SetDirection (IP_CT_DIR_REPLY);
|
|
qasimj@4638
|
665 |
|
|
qasimj@4638
|
666 |
std::cout <<" New Original Tuple: " << currentOriginalTuple << std::endl;
|
|
qasimj@4638
|
667 |
std::cout <<" New Reply Tuple: " << currentReplyTuple << std::endl;
|
|
qasimj@4638
|
668 |
|
|
qasimj@4638
|
669 |
m_unconfirmed[currentOriginalTuple] = m_unconfirmed[oldOriginalTuple];
|
|
qasimj@4638
|
670 |
|
|
qasimj@4638
|
671 |
}
|
|
qasimj@4638
|
672 |
else if (hookNumber == NF_INET_PRE_ROUTING)
|
|
qasimj@4638
|
673 |
{
|
|
qasimj@4638
|
674 |
NS_LOG_DEBUG ("Mapping back to LAN address");
|
|
qasimj@4638
|
675 |
//NetfilterConntrackTuple mapped = m_natMappings[currentReplyTuple];
|
|
qasimj@4638
|
676 |
NetfilterConntrackTuple temp = currentReplyTuple;
|
|
qasimj@4638
|
677 |
temp.SetDirection (IP_CT_DIR_ORIGINAL);
|
|
qasimj@4638
|
678 |
TranslationMapI transIt = m_natReplyLookup.find (temp);
|
|
qasimj@4638
|
679 |
|
|
qasimj@4638
|
680 |
if (transIt == m_natMappings.end ())
|
|
qasimj@4638
|
681 |
{
|
|
qasimj@4638
|
682 |
NS_LOG_DEBUG ("No such mapping found!");
|
|
qasimj@4638
|
683 |
return NF_ACCEPT;
|
|
qasimj@4638
|
684 |
}
|
|
qasimj@4638
|
685 |
|
|
qasimj@4638
|
686 |
dstPort = (transIt->second).GetSourcePort ();
|
|
qasimj@4638
|
687 |
dstAddress = (transIt->second).GetSource ();
|
|
qasimj@4638
|
688 |
|
|
qasimj@4638
|
689 |
currentOriginalTuple = NetfilterConntrackTuple ((transIt->second).GetSource (), (transIt->second).GetSourcePort (), dstAddress, dstPort);
|
|
qasimj@4638
|
690 |
currentReplyTuple = NetfilterConntrackTuple (dstAddress, dstPort, (transIt->second).GetSource (), (transIt->second).GetSourcePort ());
|
|
qasimj@4638
|
691 |
|
|
qasimj@4638
|
692 |
NS_LOG_DEBUG ("Setting Destination IP address to : " << dstAddress);
|
|
qasimj@4638
|
693 |
ipHeader.SetDestination (dstAddress);
|
|
qasimj@4638
|
694 |
|
|
qasimj@4638
|
695 |
if (protocol == IPPROTO_TCP)
|
|
qasimj@4638
|
696 |
{
|
|
qasimj@4638
|
697 |
TcpHeader tcpHeader;
|
|
qasimj@4638
|
698 |
|
|
qasimj@4638
|
699 |
p->RemoveHeader (tcpHeader);
|
|
qasimj@4638
|
700 |
|
|
qasimj@4638
|
701 |
tcpHeader.SetDestinationPort (dstPort);
|
|
qasimj@4638
|
702 |
|
|
qasimj@4638
|
703 |
p->AddHeader (tcpHeader);
|
|
qasimj@4638
|
704 |
|
|
qasimj@4638
|
705 |
}
|
|
qasimj@4638
|
706 |
else
|
|
qasimj@4638
|
707 |
{
|
|
qasimj@4638
|
708 |
UdpHeader udpHeader;
|
|
qasimj@4638
|
709 |
|
|
qasimj@4638
|
710 |
p->RemoveHeader (udpHeader);
|
|
qasimj@4638
|
711 |
|
|
qasimj@4638
|
712 |
udpHeader.SetDestinationPort (dstPort);
|
|
qasimj@4638
|
713 |
NS_LOG_DEBUG ("Setting destination port to: " << dstPort);
|
|
qasimj@4638
|
714 |
|
|
qasimj@4638
|
715 |
p->AddHeader (udpHeader);
|
|
qasimj@4638
|
716 |
}
|
|
qasimj@4638
|
717 |
|
|
qasimj@4638
|
718 |
p->AddHeader (ipHeader);
|
|
qasimj@4638
|
719 |
}
|
|
qasimj@4638
|
720 |
|
|
qasimj@4638
|
721 |
|
|
qasimj@4638
|
722 |
|
|
qasimj@4638
|
723 |
return NF_ACCEPT;
|
|
qasimj@4638
|
724 |
|
|
qasimj@4638
|
725 |
}
|
|
qasimj@4635
|
726 |
|
|
qasimj@4634
|
727 |
} // Namespace ns3
|