1.1 --- a/scratch/first.cc Fri Jul 31 00:57:33 2009 +0600
1.2 +++ b/scratch/first.cc Thu Aug 06 01:55:49 2009 +0600
1.3 @@ -32,8 +32,6 @@
1.4 NodeContainer nodes;
1.5 nodes.Create (2);
1.6
1.7 - Packet::EnablePrinting();
1.8 -
1.9 PointToPointHelper pointToPoint;
1.10 pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
1.11 pointToPoint.SetChannelAttribute ("Delay", StringValue ("2ms"));
1.12 @@ -56,15 +54,15 @@
1.13 serverApps.Stop (Seconds (10.0));
1.14
1.15 UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
1.16 - echoClient.SetAttribute ("MaxPackets", UintegerValue (1));
1.17 + echoClient.SetAttribute ("MaxPackets", UintegerValue (2));
1.18 echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.)));
1.19 echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
1.20
1.21 ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
1.22 clientApps.Start (Seconds (2.0));
1.23 clientApps.Stop (Seconds (10.0));
1.24 -
1.25 - PointToPointHelper::EnablePcapAll ("first");
1.26 +
1.27 + PointToPointHelper::EnablePcapAll ("netfilter");
1.28
1.29 Simulator::Run ();
1.30 Simulator::Destroy ();
2.1 --- a/src/internet-stack/ip-conntrack-info.cc Fri Jul 31 00:57:33 2009 +0600
2.2 +++ b/src/internet-stack/ip-conntrack-info.cc Thu Aug 06 01:55:49 2009 +0600
2.3 @@ -34,7 +34,7 @@
2.4 void
2.5 IpConntrackInfo::SetStatus (uint32_t status)
2.6 {
2.7 - m_status = status;
2.8 + m_status |= status;
2.9 }
2.10
2.11 uint32_t
2.12 @@ -43,6 +43,18 @@
2.13 return m_status;
2.14 }
2.15
2.16 +void
2.17 +IpConntrackInfo::SetInfo (uint8_t info)
2.18 +{
2.19 + m_info = info;
2.20 +}
2.21 +
2.22 +uint8_t
2.23 +IpConntrackInfo::GetInfo ()
2.24 +{
2.25 + return m_info;
2.26 +}
2.27 +
2.28 bool
2.29 IpConntrackInfo::IsConfirmed ()
2.30 {
3.1 --- a/src/internet-stack/ip-conntrack-info.h Fri Jul 31 00:57:33 2009 +0600
3.2 +++ b/src/internet-stack/ip-conntrack-info.h Thu Aug 06 01:55:49 2009 +0600
3.3 @@ -86,10 +86,14 @@
3.4 bool IsDying ();
3.5 void SetDying ();
3.6
3.7 + void SetInfo (uint8_t info);
3.8 + uint8_t GetInfo ();
3.9 +
3.10 ConntrackDirection_t ConntrackInfoToDirection (ConntrackInfo_t ctinfo);
3.11
3.12 private:
3.13 uint32_t m_status;
3.14 + uint8_t m_info;
3.15 };
3.16
3.17 }
4.1 --- a/src/internet-stack/ipv4-conntrack-l3-protocol.cc Fri Jul 31 00:57:33 2009 +0600
4.2 +++ b/src/internet-stack/ipv4-conntrack-l3-protocol.cc Thu Aug 06 01:55:49 2009 +0600
4.3 @@ -36,14 +36,14 @@
4.4 Ptr<NetDevice> out, ContinueCallback& ccb)
4.5 {
4.6 NS_LOG_DEBUG (":: Executing hook function Ipv4Confirm ::");
4.7 - ConntrackTag ctinfo;
4.8 + /*ConntrackTag ctinfo;
4.9 bool tagFound = packet->PeekPacketTag (ctinfo);
4.10
4.11 if (!tagFound || ctinfo.GetConntrack () == IP_CT_RELATED + IP_CT_IS_REPLY)
4.12 {
4.13 NS_LOG_DEBUG ("Conntrack tag not found");
4.14 return 0;
4.15 - }
4.16 + }*/
4.17
4.18 // Call conntrack helper here
4.19
5.1 --- a/src/internet-stack/ipv4-l3-protocol.cc Fri Jul 31 00:57:33 2009 +0600
5.2 +++ b/src/internet-stack/ipv4-l3-protocol.cc Thu Aug 06 01:55:49 2009 +0600
5.3 @@ -114,12 +114,12 @@
5.4 m_identification (0)
5.5 {
5.6 NS_LOG_FUNCTION_NOARGS ();
5.7 - NetfilterHookCallback nhc = MakeCallback(&NfPreRoutingHookFunction);
5.8 + /*NetfilterHookCallback nhc = MakeCallback(&NfPreRoutingHookFunction);
5.9 NetfilterHookCallback nhc2 = MakeCallback(&NfPostRoutingHookFunction);
5.10 Ipv4NetfilterHook nfh = Ipv4NetfilterHook(1, NF_INET_PRE_ROUTING, 2, nhc);
5.11 Ipv4NetfilterHook nfh2 = Ipv4NetfilterHook(1, NF_INET_POST_ROUTING, 2, nhc2);
5.12 netfilter.RegisterNetfilterHook(nfh);
5.13 - netfilter.RegisterNetfilterHook(nfh2);
5.14 + netfilter.RegisterNetfilterHook(nfh2);*/
5.15 }
5.16
5.17 Ipv4L3Protocol::~Ipv4L3Protocol ()
5.18 @@ -1003,6 +1003,12 @@
5.19 NS_LOG_LOGIC ("Route input failure-- dropping packet to " << ipHeader << " with errno " << sockErrno);
5.20 m_dropTrace (p);
5.21 }
5.22 +
5.23 +Ipv4Netfilter*
5.24 +Ipv4L3Protocol::GetNetfilter()
5.25 +{
5.26 + return &netfilter;
5.27 +}
5.28
5.29
5.30 }//namespace ns3
6.1 --- a/src/internet-stack/ipv4-l3-protocol.h Fri Jul 31 00:57:33 2009 +0600
6.2 +++ b/src/internet-stack/ipv4-l3-protocol.h Thu Aug 06 01:55:49 2009 +0600
6.3 @@ -157,7 +157,7 @@
6.4 void SetForwarding (uint32_t i, bool val);
6.5
6.6 Ptr<NetDevice> GetNetDevice (uint32_t i);
6.7 - Ipv4Netfilter& GetNetfilter();
6.8 + Ipv4Netfilter* GetNetfilter();
6.9
6.10 protected:
6.11
7.1 --- a/src/internet-stack/ipv4-netfilter.cc Fri Jul 31 00:57:33 2009 +0600
7.2 +++ b/src/internet-stack/ipv4-netfilter.cc Thu Aug 06 01:55:49 2009 +0600
7.3 @@ -18,18 +18,38 @@
7.4 * Author: Qasim Javed <qasim@utdallas.edu>
7.5 */
7.6 #include "ns3/log.h"
7.7 +#include "ns3/uinteger.h"
7.8 #include "ipv4-netfilter.h"
7.9 #include "ip-conntrack-info.h"
7.10 #include "ipv4-conntrack-l3-protocol.h"
7.11 #include "tcp-conntrack-l4-protocol.h"
7.12 #include "udp-conntrack-l4-protocol.h"
7.13 #include "icmpv4-conntrack-l4-protocol.h"
7.14 +#include "tcp-header.h"
7.15 +#include "udp-header.h"
7.16
7.17 NS_LOG_COMPONENT_DEFINE ("Ipv4Netfilter");
7.18
7.19 namespace ns3 {
7.20 +
7.21 +NS_OBJECT_ENSURE_REGISTERED (Ipv4Netfilter);
7.22 +
7.23 +TypeId
7.24 +Ipv4Netfilter::GetTypeId (void)
7.25 +{
7.26 + static TypeId tId = TypeId ("ns3::Ipv4Netfilter")
7.27 + .SetParent<Object> ()
7.28 + .AddAttribute ("EnableNat", "0 disbales NAT and is the default, 1 enabled NAT",
7.29 + UintegerValue (0),
7.30 + MakeUintegerAccessor (&Ipv4Netfilter::m_enableNat),
7.31 + MakeUintegerChecker <uint8_t> ())
7.32 + ;
7.33 +
7.34 + return tId;
7.35 +}
7.36
7.37 Ipv4Netfilter::Ipv4Netfilter ()
7.38 + : m_enableNat (0)
7.39 {
7.40 NS_LOG_FUNCTION_NOARGS();
7.41
7.42 @@ -52,23 +72,31 @@
7.43 /* Create and register ICMP connection tracking module */
7.44 Ptr<Icmpv4ConntrackL4Protocol> icmpv4 = Create<Icmpv4ConntrackL4Protocol> ();
7.45 this->RegisterL4Protocol (icmpv4);
7.46 +
7.47 + //Ptr <NetworkAddressTranslation> networkAddressTranslation = Create<NetworkAddressTranslation> (this);
7.48
7.49 /* Create and register hook callbacks */
7.50 NetfilterHookCallback preRouting = MakeCallback (&Ipv4Netfilter::NetfilterConntrackIn, this);
7.51 NetfilterHookCallback localIn = MakeCallback (&Ipv4ConntrackL3Protocol::Ipv4Confirm, PeekPointer (ipv4));
7.52
7.53 - Ipv4NetfilterHook nfh = Ipv4NetfilterHook (1, NF_INET_PRE_ROUTING, 1, preRouting);
7.54 - Ipv4NetfilterHook nfh1 = Ipv4NetfilterHook (1, NF_INET_LOCAL_OUT, 1, preRouting);
7.55 - Ipv4NetfilterHook nfh2 = Ipv4NetfilterHook (1, NF_INET_POST_ROUTING, 1, localIn);
7.56 - Ipv4NetfilterHook nfh3 = Ipv4NetfilterHook (1, NF_INET_LOCAL_IN, 1, localIn);
7.57 + Ipv4NetfilterHook nfh = Ipv4NetfilterHook (1, NF_INET_PRE_ROUTING, NF_IP_PRI_CONNTRACK , preRouting);
7.58 + Ipv4NetfilterHook nfh1 = Ipv4NetfilterHook (1, NF_INET_LOCAL_OUT, NF_IP_PRI_CONNTRACK, preRouting);
7.59 + Ipv4NetfilterHook nfh2 = Ipv4NetfilterHook (1, NF_INET_POST_ROUTING, NF_IP_PRI_CONNTRACK_CONFIRM, localIn);
7.60 + Ipv4NetfilterHook nfh3 = Ipv4NetfilterHook (1, NF_INET_LOCAL_IN, NF_IP_PRI_CONNTRACK_CONFIRM, localIn);
7.61 +
7.62 this->RegisterNetfilterHook (nfh);
7.63 this->RegisterNetfilterHook (nfh1);
7.64 this->RegisterNetfilterHook (nfh2);
7.65 this->RegisterNetfilterHook (nfh3);
7.66 +
7.67 + if (m_enableNat)
7.68 + EnableNat ();
7.69 +
7.70 + nextAvailablePort = 1024;
7.71 }
7.72
7.73 uint32_t
7.74 -Ipv4Netfilter::RegisterNetfilterHook (Ipv4NetfilterHook& hook)
7.75 +Ipv4Netfilter::RegisterNetfilterHook (Ipv4NetfilterHook hook)
7.76 {
7.77 //NS_LOG_FUNCTION (this << hook);
7.78 m_netfilterHooks[hook.GetHookNumber ()].Insert (hook);
7.79 @@ -138,13 +166,10 @@
7.80 }
7.81
7.82 int
7.83 -Ipv4Netfilter::UpdateConntrackStatus (NetfilterConntrackTuple tuple, uint32_t status)
7.84 +Ipv4Netfilter::UpdateConntrackInfo (uint8_t info)
7.85 {
7.86 - uint32_t curStatus1 = m_netfilterTupleHash[IP_CT_DIR_ORIGINAL][tuple].GetStatus ();
7.87 - m_netfilterTupleHash[IP_CT_DIR_ORIGINAL][tuple].SetStatus (curStatus1 | status);
7.88 - uint32_t curStatus2 = m_netfilterTupleHash[IP_CT_DIR_REPLY][tuple].GetStatus ();
7.89 - m_netfilterTupleHash[IP_CT_DIR_REPLY][tuple].SetStatus (curStatus2 | status);
7.90 -
7.91 + m_hash[currentOriginalTuple].SetInfo (info);
7.92 + m_hash[currentReplyTuple].SetInfo (info);
7.93 return 0;
7.94 }
7.95
7.96 @@ -206,7 +231,7 @@
7.97 NS_LOG_FUNCTION (this << packet);
7.98 //NetfilterConntrackTuple tuple (ipHeader.GetSource(), 0, ipHeader.GetDestination(), 0);
7.99 NetfilterConntrackTuple tuple;
7.100 - uint8_t conntrackInfo;
7.101 + uint8_t conntrackInfo = 0;
7.102
7.103 /* Get a tuple from the information in the packet */
7.104 if (!NetfilterConntrackGetTuple (packet, protocolFamily, protocol, tuple, l3Protocol, l4Protocol))
7.105 @@ -223,6 +248,14 @@
7.106 //TupleHashI newIt = NewConnection(tuple, l3Protocol, l4Protocol, packet);
7.107 it = NewConnection (tuple, l3Protocol, l4Protocol, packet);
7.108 }
7.109 +
7.110 + NetfilterConntrackTuple replyTuple;
7.111 +
7.112 + if (!InvertTuple (replyTuple, tuple, l3Protocol, l4Protocol))
7.113 + return -1;
7.114 +
7.115 + currentOriginalTuple = tuple;
7.116 + currentReplyTuple = replyTuple;
7.117
7.118 /* TODO: Add a pointer to the hashed tuple in IpConntrackInfo()
7.119 * and store these tuples somehwere, when you destruct then you
7.120 @@ -236,7 +269,8 @@
7.121 setReply = 1;
7.122 } else {
7.123 NS_LOG_DEBUG (":: Packet is in the original direction ::");
7.124 - if ( m_hash[tuple].GetStatus () & IPS_SEEN_REPLY_BIT) {
7.125 + if ( m_hash[tuple].GetStatus () & IPS_SEEN_REPLY) {
7.126 + NS_LOG_DEBUG (":: Connection ESTABLISHED! ::");
7.127 conntrackInfo = IP_CT_ESTABLISHED;
7.128 }
7.129 else {
7.130 @@ -245,7 +279,10 @@
7.131 }
7.132
7.133 }
7.134 - NS_LOG_DEBUG ("Adding the conntrack packet tag" );
7.135 +
7.136 + m_unconfirmed[tuple].SetInfo (conntrackInfo);
7.137 + //UpdateConntrackInfo (conntrackInfo);
7.138 + /*NS_LOG_DEBUG ("Adding the conntrack packet tag" );
7.139 ConntrackTag ctTag;
7.140 bool tagFound = packet->PeekPacketTag (ctTag);
7.141
7.142 @@ -253,6 +290,7 @@
7.143 packet->AddPacketTag (ConntrackTag (conntrackInfo));
7.144 else
7.145 NS_LOG_DEBUG ("Tag already present");
7.146 + */
7.147
7.148 return NF_ACCEPT;
7.149
7.150 @@ -286,6 +324,13 @@
7.151 // Call layer 4 Packet callback
7.152 //uint32_t ret = l4proto->packet(packet, protocolFamily, hookNumber);
7.153
7.154 + if (setReply)
7.155 + {
7.156 + NS_LOG_DEBUG ("Setting IPS_SEEN_REPLY");
7.157 + m_hash[currentOriginalTuple].SetStatus ( IPS_SEEN_REPLY );
7.158 + m_hash[currentReplyTuple].SetStatus ( IPS_SEEN_REPLY );
7.159 + }
7.160 +
7.161 return NF_ACCEPT;
7.162
7.163 }
7.164 @@ -299,61 +344,187 @@
7.165 /* If this packet has been seen previously, Ignore. */
7.166
7.167 /* Find layer 3 helper for this packet */
7.168 - Ptr<NetfilterConntrackL3Protocol> l3proto = FindL3ProtocolHelper (1);
7.169 + /*Ptr<NetfilterConntrackL3Protocol> l3proto = FindL3ProtocolHelper (1);
7.170
7.171 - Ipv4Header ipHeader;
7.172 + Ipv4Header ipHeader;
7.173
7.174 //packet->RemoveHeader(ipHeader);
7.175 packet->PeekHeader (ipHeader);
7.176
7.177 NS_LOG_DEBUG ( "IP header protocol: " << (int)ipHeader.GetProtocol ());
7.178 -
7.179 +
7.180 Ptr<NetfilterConntrackL4Protocol> l4proto = FindL4ProtocolHelper (ipHeader.GetProtocol ());
7.181 -
7.182 - NetfilterConntrackTuple orig;
7.183 -
7.184 +
7.185 + NetfilterConntrackTuple orig;*/
7.186 +
7.187 /* Get a tuple from the information in the packet */
7.188 - if (!NetfilterConntrackGetTuple (packet, 1, ipHeader.GetProtocol (), orig, l3proto, l4proto))
7.189 - {
7.190 + /*if (!NetfilterConntrackGetTuple (packet, 1, ipHeader.GetProtocol (), orig, l3proto, l4proto))
7.191 + {
7.192 NS_LOG_DEBUG ("Cannot create a tuple from the packet");
7.193 return -1;
7.194 - }
7.195 -
7.196 - NetfilterConntrackTuple reply;
7.197 + }
7.198
7.199 - InvertTuple (reply, orig, l3proto, l4proto);
7.200 + NetfilterConntrackTuple reply;
7.201 +
7.202 +
7.203 + InvertTuple (reply, orig, l3proto, l4proto);
7.204 +
7.205 + currentOriginalTuple = orig;
7.206 + currentReplyTuple = reply;
7.207 +
7.208 + NS_LOG_DEBUG ("Current Original Tuple: " << currentOriginalTuple.GetSource () << ", " << currentOriginalTuple.GetDestination ());
7.209 + NS_LOG_DEBUG ("Current Reply Tuple: " << currentReplyTuple.GetSource () << ", " << currentReplyTuple.GetDestination ());
7.210 + //currentTuple[IP_CT_DIR_REPLY] = reply;*/
7.211
7.212 /**************************/
7.213
7.214 - ConntrackTag ctTag;
7.215 + /*ConntrackTag ctTag;
7.216
7.217 - if (!packet->PeekPacketTag (ctTag))
7.218 - {
7.219 + if (!packet->PeekPacketTag (ctTag))
7.220 + {
7.221 NS_LOG_DEBUG ("ConntrackTag not found");
7.222 return 0;
7.223 - }
7.224 - else {
7.225 + }
7.226 + else {
7.227 if ( CTINFO2DIR (ctTag.GetConntrack ()) != IP_CT_DIR_ORIGINAL)
7.228 - return 0;
7.229 + return 0;
7.230
7.231 if (m_hash.find (orig) != m_hash.end () && m_hash.find (reply) != m_hash.end () )
7.232 {
7.233 - NS_LOG_DEBUG ("Entries already present!");
7.234 - return NF_DROP;
7.235 + NS_LOG_DEBUG ("Entries already present!");
7.236 + return NF_DROP;
7.237 }
7.238
7.239 NS_LOG_DEBUG ("Creating confirmed hash entries");
7.240 - //m_hash[orig] = IpConntrackInfo().SetStatus(IPS_CONFIRMED);
7.241 - m_hash[orig] = IpConntrackInfo ();
7.242 - m_hash[reply] = IpConntrackInfo ();
7.243 + //m_hash[orig] = IpConntrackInfo().SetStatus(IPS_CONFIRMED);
7.244 + m_hash[orig] = IpConntrackInfo ();
7.245 + m_hash[reply] = IpConntrackInfo ();
7.246
7.247 + }*/
7.248 +
7.249 + if ( CTINFO2DIR (m_unconfirmed[currentOriginalTuple].GetInfo ()) != IP_CT_DIR_ORIGINAL)
7.250 + {
7.251 + NS_LOG_DEBUG ("Not a packet in the original direction");
7.252 + return NF_ACCEPT;
7.253 }
7.254
7.255 - //packet->AddHeader(ipHeader);
7.256 + /*if (m_hash.find (currentOriginalTuple) != m_hash.end () && m_hash.find (currentReplyTuple) != m_hash.end () )
7.257 + {
7.258 + NS_LOG_DEBUG ("Entries already present!");
7.259 + return NF_DROP;
7.260 + }*/
7.261 +
7.262 + NS_LOG_DEBUG ("Creating confirmed hash entries");
7.263 + m_hash[currentOriginalTuple] = m_unconfirmed[currentOriginalTuple];
7.264 + m_hash[currentReplyTuple] = m_unconfirmed[currentOriginalTuple];
7.265
7.266 return 0;
7.267 }
7.268
7.269 +uint32_t
7.270 +Ipv4Netfilter::NetfilterDoNat (Hooks_t hookNumber, Ptr<Packet> p,
7.271 + Ptr<NetDevice> in, Ptr<NetDevice> out, ContinueCallback& ccb)
7.272 +{
7.273 + NS_LOG_FUNCTION ( this << p );
7.274 + /*ConntrackTag ctTag;
7.275 +
7.276 + bool found = p->PeekPacketTag (ctTag);
7.277 +
7.278 + if (!found)
7.279 + {
7.280 + NS_LOG_DEBUG ("Conntrack tag not found");
7.281 + return NF_ACCEPT;
7.282 + }*/
7.283 +
7.284 + /* Conntrack has a higher priority so currentOriginalTuple and
7.285 + * currentReply tuple should always be correct
7.286 + */
7.287 +
7.288 + //std::vector<NatRule>::iterator it = FindNatDevice (out);
7.289 +
7.290 + /*if (it == m_natRules.end ())
7.291 + {
7.292 + NS_LOG_DEBUG ("No NAT rule for device " << out->GetId ());
7.293 + return NF_ACCEPT;
7.294 + }*/
7.295 +
7.296 + NS_LOG_DEBUG ("Current Original Tuple: " << currentOriginalTuple.GetSource () << ", " << currentOriginalTuple.GetDestination ());
7.297 + NS_LOG_DEBUG ("Current Reply Tuple: " << currentReplyTuple.GetSource () << ", " << currentReplyTuple.GetDestination ());
7.298 +
7.299 + NS_LOG_DEBUG ("ConntrackInfo: " << (uint16_t)m_unconfirmed[currentOriginalTuple].GetInfo () );
7.300 +
7.301 + /* TODO: Why are you checking m_hash here when the info is in
7.302 + * m_unconfirmed. This could be a problem because NAT is sandwiched
7.303 + * between conntrack hook callbacks
7.304 + */
7.305 + switch (m_unconfirmed[currentOriginalTuple].GetInfo ())
7.306 + {
7.307 + case IP_CT_RELATED:
7.308 + case IP_CT_RELATED + IP_CT_IS_REPLY:
7.309 + /* This should be updated when "expectations" are added */
7.310 + break;
7.311 +
7.312 + case IP_CT_NEW:
7.313 +
7.314 + if ( hookNumber == NF_INET_POST_ROUTING )
7.315 + {
7.316 + NS_LOG_DEBUG ("SRC_NAT: New Connection encountered");
7.317 +
7.318 + TupleHashI it;
7.319 +
7.320 +
7.321 + if ( (it = m_hash.find (currentOriginalTuple)) != m_hash.end ())
7.322 + {
7.323 + if ( !((it->second).GetStatus () & IPS_SRC_NAT_DONE) )
7.324 + {
7.325 + /* Get a unique tuple and create a mapping */
7.326 +
7.327 + NS_LOG_DEBUG ("Doing rule lookup at device " << out->GetIfIndex ());
7.328 + std::vector<NatRule>::iterator it =
7.329 + FindNatRule ( Ipv4Address (currentOriginalTuple.GetSource ()), out );
7.330 +
7.331 + if ( it == m_natRules.end () )
7.332 + {
7.333 + NS_LOG_DEBUG ("No rule matched!");
7.334 + return NF_ACCEPT;
7.335 + }
7.336 +
7.337 + NS_LOG_DEBUG ("Creating a NAT mapping");
7.338 +
7.339 + /* Create a NULL mapping, which does not contain port numbers */
7.340 + NetfilterConntrackTuple mapping =
7.341 + NetfilterConntrackTuple (it->GetMangledSource (), nextAvailablePort,
7.342 + currentOriginalTuple.GetDestination (), 9);
7.343 + mapping.SetDirection (IP_CT_DIR_ORIGINAL);
7.344 + nextAvailablePort++;
7.345 +
7.346 + NS_LOG_DEBUG ("Creating a NAT mapping for the tuple " << currentOriginalTuple
7.347 + << ": " << mapping );
7.348 + m_natMappings[currentOriginalTuple] = mapping;
7.349 + m_natReplyLookup[mapping] = currentOriginalTuple;
7.350 + }
7.351 +
7.352 +
7.353 + NS_LOG_DEBUG (":: Translating addresses and fixing IP checksum ::");
7.354 + NetfilterNatPacket (hookNumber, p);
7.355 + }
7.356 + else
7.357 + NS_LOG_DEBUG ("BUG: currentTuple non-existent in hash!");
7.358 + }
7.359 +
7.360 + break;
7.361 +
7.362 + default:
7.363 + NS_LOG_DEBUG ("SRC_NAT: Connection is established!");
7.364 + NS_LOG_DEBUG (":: Translating addresses and fixing IP checksum ::");
7.365 + NetfilterNatPacket (hookNumber, p);
7.366 +
7.367 + }
7.368 +
7.369 +
7.370 + return NF_ACCEPT;
7.371 +}
7.372 +
7.373 bool
7.374 Ipv4Netfilter::InvertTuple (NetfilterConntrackTuple& inverse, NetfilterConntrackTuple& orig,
7.375 Ptr<NetfilterConntrackL3Protocol> l3Protocol,
7.376 @@ -369,31 +540,188 @@
7.377 return l4Protocol->InvertTuple (inverse, orig);
7.378
7.379 }
7.380 +
7.381 +TupleHash&
7.382 +Ipv4Netfilter::GetHash ()
7.383 +{
7.384 + return m_hash;
7.385 +}
7.386 +
7.387 +void
7.388 +Ipv4Netfilter::AddNatRule (NatRule natRule)
7.389 +{
7.390 + m_natRules.push_back (natRule);
7.391 +}
7.392
7.393 -/*uint32_t
7.394 -Ipv4Netfilter::Ipv4Confirm(Hooks_t hookNumber, Ptr<Packet> packet, Ptr<NetDevice> in,
7.395 - Ptr<NetDevice> out, ContinueCallback& ccb)
7.396 +std::vector<NatRule>::iterator
7.397 +Ipv4Netfilter::FindNatRule (NatRule natRule)
7.398 {
7.399 - NS_LOG_DEBUG (":: Executing hook function Ipv4Confirm ::");
7.400 - ConntrackTag ctinfo;
7.401 - bool tagFound = packet->PeekPacketTag(ctinfo);
7.402 + std::vector<NatRule>::iterator it = m_natRules.begin ();
7.403
7.404 - if (!tagFound || ctinfo.GetConntrack() == IP_CT_RELATED + IP_CT_IS_REPLY)
7.405 + for ( ; it != m_natRules.end (); it++)
7.406 {
7.407 - NS_LOG_DEBUG ("Conntrack tag not found");
7.408 - return 0;
7.409 + if ( *it == natRule )
7.410 + return it;
7.411 }
7.412
7.413 - // Call conntrack helper here
7.414 + return m_natRules.end ();
7.415 +}
7.416
7.417 - // NetfilterConntrackConfirm
7.418 - NS_LOG_DEBUG ("Invoking the ContinueCallback");
7.419 - ccb (packet);
7.420 +std::vector<NatRule>::iterator
7.421 +Ipv4Netfilter::FindNatRule (Ipv4Address orig, Ptr<NetDevice> out)
7.422 +{
7.423 + std::vector<NatRule>::iterator it = m_natRules.begin ();
7.424
7.425 + NS_LOG_DEBUG ("Number of rules: " << m_natRules.size () );
7.426 + NS_LOG_DEBUG ("Orig: " << orig );
7.427
7.428 + for ( ; it != m_natRules.end (); it++)
7.429 + {
7.430 + NS_LOG_DEBUG ("Rule source: " << it->GetOriginalSource () << ", passed in source: " << orig);
7.431 + NS_LOG_DEBUG ("Rule device: " << it->GetDevice () << ", passed in dev: " << out);
7.432 + if ( it->GetOriginalSource () == orig && it->GetDevice () == out)
7.433 + {
7.434 + NS_LOG_DEBUG ("Rule match found!");
7.435 + return it;
7.436 + }
7.437 + }
7.438
7.439 + return m_natRules.end ();
7.440 +}
7.441 +
7.442 +void
7.443 +Ipv4Netfilter::EnableNat ()
7.444 +{
7.445 + m_enableNat = 1;
7.446
7.447 - return 0;
7.448 -}*/
7.449 + NS_LOG_DEBUG (":: Enabling NAT ::");
7.450 +
7.451 + NetfilterHookCallback doNat = MakeCallback (&Ipv4Netfilter::NetfilterDoNat, this);
7.452 +
7.453 + Ipv4NetfilterHook natCallback1 = Ipv4NetfilterHook (1, NF_INET_POST_ROUTING, NF_IP_PRI_NAT_SRC, doNat);
7.454 + Ipv4NetfilterHook natCallback2 = Ipv4NetfilterHook (1, NF_INET_PRE_ROUTING, NF_IP_PRI_NAT_DST, doNat);
7.455 +
7.456 +
7.457 + this->RegisterNetfilterHook (natCallback1);
7.458 + this->RegisterNetfilterHook (natCallback2);
7.459 +}
7.460 +
7.461 +uint32_t
7.462 +Ipv4Netfilter::NetfilterNatPacket (Hooks_t hookNumber, Ptr<Packet> p)
7.463 +{
7.464 + NS_LOG_FUNCTION ( this << p );
7.465 + Ipv4Header ipHeader;
7.466 + uint16_t dstPort; //, srcPort;
7.467 + Ipv4Address dstAddress, srcAddress;
7.468 +
7.469 + p->RemoveHeader (ipHeader);
7.470 +
7.471 + uint16_t protocol = ipHeader.GetProtocol ();
7.472 +
7.473 + if (hookNumber == NF_INET_POST_ROUTING)
7.474 + {
7.475 + NetfilterConntrackTuple mapped = m_natMappings[currentOriginalTuple];
7.476 +
7.477 + ipHeader.SetSource (mapped.GetSource ());
7.478 +
7.479 + if (protocol == IPPROTO_TCP)
7.480 + {
7.481 + TcpHeader tcpHeader;
7.482 +
7.483 + p->RemoveHeader (tcpHeader);
7.484 +
7.485 + tcpHeader.SetSourcePort (mapped.GetSourcePort ());
7.486 +
7.487 + p->AddHeader (tcpHeader);
7.488 +
7.489 + }
7.490 + else
7.491 + {
7.492 + UdpHeader udpHeader;
7.493 +
7.494 + p->RemoveHeader (udpHeader);
7.495 +
7.496 + udpHeader.SetSourcePort (mapped.GetSourcePort ());
7.497 +
7.498 + p->AddHeader (udpHeader);
7.499 + }
7.500 +
7.501 + p->AddHeader (ipHeader);
7.502 +
7.503 + NetfilterConntrackTuple oldOriginalTuple = currentOriginalTuple;
7.504 +
7.505 +
7.506 + currentOriginalTuple = NetfilterConntrackTuple (mapped.GetSource(), mapped.GetSourcePort (),
7.507 + currentOriginalTuple.GetDestination (),
7.508 + currentOriginalTuple.GetDestinationPort ());
7.509 +
7.510 + currentOriginalTuple.SetDirection (IP_CT_DIR_ORIGINAL);
7.511 +
7.512 + currentReplyTuple = NetfilterConntrackTuple (currentOriginalTuple.GetDestination (),
7.513 + currentOriginalTuple.GetDestinationPort (),
7.514 + mapped.GetSource (), mapped.GetSourcePort ());
7.515 +
7.516 + currentReplyTuple.SetDirection (IP_CT_DIR_REPLY);
7.517 +
7.518 + std::cout <<" New Original Tuple: " << currentOriginalTuple << std::endl;
7.519 + std::cout <<" New Reply Tuple: " << currentReplyTuple << std::endl;
7.520 +
7.521 + m_unconfirmed[currentOriginalTuple] = m_unconfirmed[oldOriginalTuple];
7.522 +
7.523 + }
7.524 + else if (hookNumber == NF_INET_PRE_ROUTING)
7.525 + {
7.526 + NS_LOG_DEBUG ("Mapping back to LAN address");
7.527 + //NetfilterConntrackTuple mapped = m_natMappings[currentReplyTuple];
7.528 + NetfilterConntrackTuple temp = currentReplyTuple;
7.529 + temp.SetDirection (IP_CT_DIR_ORIGINAL);
7.530 + TranslationMapI transIt = m_natReplyLookup.find (temp);
7.531 +
7.532 + if (transIt == m_natMappings.end ())
7.533 + {
7.534 + NS_LOG_DEBUG ("No such mapping found!");
7.535 + return NF_ACCEPT;
7.536 + }
7.537 +
7.538 + dstPort = (transIt->second).GetSourcePort ();
7.539 + dstAddress = (transIt->second).GetSource ();
7.540 +
7.541 + currentOriginalTuple = NetfilterConntrackTuple ((transIt->second).GetSource (), (transIt->second).GetSourcePort (), dstAddress, dstPort);
7.542 + currentReplyTuple = NetfilterConntrackTuple (dstAddress, dstPort, (transIt->second).GetSource (), (transIt->second).GetSourcePort ());
7.543 +
7.544 + NS_LOG_DEBUG ("Setting Destination IP address to : " << dstAddress);
7.545 + ipHeader.SetDestination (dstAddress);
7.546 +
7.547 + if (protocol == IPPROTO_TCP)
7.548 + {
7.549 + TcpHeader tcpHeader;
7.550 +
7.551 + p->RemoveHeader (tcpHeader);
7.552 +
7.553 + tcpHeader.SetDestinationPort (dstPort);
7.554 +
7.555 + p->AddHeader (tcpHeader);
7.556 +
7.557 + }
7.558 + else
7.559 + {
7.560 + UdpHeader udpHeader;
7.561 +
7.562 + p->RemoveHeader (udpHeader);
7.563 +
7.564 + udpHeader.SetDestinationPort (dstPort);
7.565 + NS_LOG_DEBUG ("Setting destination port to: " << dstPort);
7.566 +
7.567 + p->AddHeader (udpHeader);
7.568 + }
7.569 +
7.570 + p->AddHeader (ipHeader);
7.571 + }
7.572 +
7.573 +
7.574 +
7.575 + return NF_ACCEPT;
7.576 +
7.577 +}
7.578
7.579 } // Namespace ns3
8.1 --- a/src/internet-stack/ipv4-netfilter.h Fri Jul 31 00:57:33 2009 +0600
8.2 +++ b/src/internet-stack/ipv4-netfilter.h Thu Aug 06 01:55:49 2009 +0600
8.3 @@ -28,6 +28,7 @@
8.4 #include "ns3/packet.h"
8.5 #include "ns3/conntrack-tag.h"
8.6 #include "ns3/ipv4-header.h"
8.7 +#include "ns3/object.h"
8.8 #include "ipv4-netfilter-hook.h"
8.9 #include "netfilter-callback-chain.h"
8.10 #include "netfilter-conntrack-tuple.h"
8.11 @@ -35,6 +36,8 @@
8.12 #include "netfilter-conntrack-l3-protocol.h"
8.13 #include "netfilter-conntrack-l4-protocol.h"
8.14 #include "ip-conntrack-info.h"
8.15 +#include "nat-rule.h"
8.16 +//#include "network-address-translation.h"
8.17
8.18 #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
8.19
8.20 @@ -70,8 +73,10 @@
8.21 * Address Translation.
8.22 */
8.23
8.24 -class Ipv4Netfilter {
8.25 +class Ipv4Netfilter : public Object {
8.26 public:
8.27 + static TypeId GetTypeId (void);
8.28 +
8.29 Ipv4Netfilter ();
8.30
8.31 /**
8.32 @@ -84,7 +89,7 @@
8.33 * that hook and is called whenever a packet traverses
8.34 * that hook.
8.35 */
8.36 - uint32_t RegisterNetfilterHook (Ipv4NetfilterHook& hook);
8.37 + uint32_t RegisterNetfilterHook (Ipv4NetfilterHook hook);
8.38
8.39 /**
8.40 * \param hook The hook function to be registered
8.41 @@ -200,13 +205,16 @@
8.42 TupleHashI NewConnection (NetfilterConntrackTuple& tuple, Ptr<NetfilterConntrackL3Protocol> l3proto,
8.43 Ptr<NetfilterConntrackL4Protocol> l4proto, Ptr<Packet> packet);
8.44
8.45 - int UpdateConntrackStatus (NetfilterConntrackTuple tuple, uint32_t status);
8.46 +
8.47 + int UpdateConntrackInfo (uint8_t info);
8.48 +
8.49 uint32_t NetfilterConntrackIn (Hooks_t hook, Ptr <Packet> packet, Ptr<NetDevice> in,
8.50 Ptr<NetDevice> out, ContinueCallback& ccb);
8.51
8.52 uint32_t NetfilterConntrackConfirm (Ptr<Packet> p);
8.53 - //, NetfilterConntrackTuple& orig,
8.54 - // NetfilterConntrackTuple& reply);
8.55 +
8.56 + uint32_t NetfilterDoNat (Hooks_t hookNumber, Ptr<Packet> p,
8.57 + Ptr<NetDevice> in, Ptr<NetDevice> out, ContinueCallback& ccb);
8.58
8.59 /**
8.60 * \param inverse The inverse of the tuple should be stored here
8.61 @@ -221,8 +229,18 @@
8.62 Ptr<NetfilterConntrackL3Protocol> l3Protocol,
8.63 Ptr<NetfilterConntrackL4Protocol> l4Protocol);
8.64
8.65 - //uint32_t Ipv4Confirm(Hooks_t hookNumber, Ptr<Packet> packet, Ptr<NetDevice> in,
8.66 - // Ptr<NetDevice> out, ContinueCallback& ccb);
8.67 + TupleHash& GetHash ();
8.68 +
8.69 + void AddNatRule (NatRule natRule);
8.70 +
8.71 + std::vector<NatRule>::iterator FindNatRule (NatRule natRule);
8.72 +
8.73 + std::vector<NatRule>::iterator FindNatRule (Ipv4Address orig, Ptr<NetDevice> out);
8.74 + //static NetfilterConntrackTuple currentTuple[IP_CT_DIR_MAX];
8.75 +
8.76 + void EnableNat ();
8.77 +
8.78 + uint32_t NetfilterNatPacket (Hooks_t hookNumber, Ptr<Packet> p);
8.79
8.80 private:
8.81 NetfilterCallbackChain m_netfilterHooks[NF_INET_NUMHOOKS];
8.82 @@ -234,7 +252,24 @@
8.83 /* TODO: Should be a table once we have more L3/L4 Protocols */
8.84 Ptr<NetfilterConntrackL3Protocol> m_netfilterConntrackL3Protocols;
8.85 std::vector<Ptr<NetfilterConntrackL4Protocol> > m_netfilterConntrackL4Protocols;
8.86 +
8.87 + TranslationMap m_natMappings;
8.88 +
8.89 + NetfilterConntrackTuple currentOriginalTuple;
8.90 + NetfilterConntrackTuple currentReplyTuple;
8.91 +
8.92 + uint8_t m_enableNat;
8.93 + std::vector <NatRule> m_natRules;
8.94 +
8.95 + uint16_t nextAvailablePort;
8.96 +
8.97 + TranslationMap m_natReplyLookup;
8.98 };
8.99
8.100 +//uint16_t Ipv4Netfilter::nextAvailablePort = 1024;
8.101 +
8.102 +//NetfilterConntrackTuple Ipv4Netfilter::currentTuple = NetfilterConntrackTuple ();
8.103 +//NetfilterConntrackTuple Ipv4Netfilter::currentTuple[IP_CT_DIR_ORIGINAL] = NetfilterConntrackTuple ();
8.104 +
8.105 } // Namespace ns3
8.106 #endif /* IPV4_NETFILTER_H */
9.1 --- a/src/internet-stack/netfilter-conntrack-tuple.cc Fri Jul 31 00:57:33 2009 +0600
9.2 +++ b/src/internet-stack/netfilter-conntrack-tuple.cc Thu Aug 06 01:55:49 2009 +0600
9.3 @@ -159,6 +159,30 @@
9.4 os << "( " << GetSource () << "," << GetSourcePort () << "," << GetDestination () << "," << GetDestinationPort () << (int)GetDirection () << ")";
9.5 }
9.6
9.7 +NetfilterConntrackTuple&
9.8 +NetfilterConntrackTuple::operator= (const NetfilterConntrackTuple& tuple)
9.9 +{
9.10 + if (this != &tuple)
9.11 + {
9.12 + m_l3Source = tuple.m_l3Source;
9.13 + m_l4Source = tuple.m_l4Source;
9.14 + m_l3Destination = tuple.m_l3Destination;
9.15 + m_l4Destination = tuple.m_l4Destination;
9.16 +
9.17 + m_l3Protocol = tuple.m_l3Protocol;
9.18 + m_protocolNumber = tuple.m_protocolNumber;
9.19 + m_direction = tuple.m_direction;
9.20 + }
9.21 +
9.22 + return *this;
9.23 +}
9.24 +
9.25 +std::ostream& operator << (std::ostream& os, NetfilterConntrackTuple const& tuple)
9.26 +{
9.27 + os << "( " << tuple.GetSource () << "," << tuple.GetSourcePort () << "," << tuple.GetDestination () << "," << tuple.GetDestinationPort () << ", " << (int)tuple.GetDirection () << ")";
9.28 + return os;
9.29 +}
9.30 +
9.31 #define JHASH_GOLDEN_RATIO 0x9e3779b9
9.32
9.33 void
10.1 --- a/src/internet-stack/netfilter-conntrack-tuple.h Fri Jul 31 00:57:33 2009 +0600
10.2 +++ b/src/internet-stack/netfilter-conntrack-tuple.h Thu Aug 06 01:55:49 2009 +0600
10.3 @@ -60,6 +60,9 @@
10.4
10.5 void Print (std::ostream &os) const;
10.6
10.7 + NetfilterConntrackTuple& operator= (const NetfilterConntrackTuple& tuple);
10.8 + friend std::ostream& operator << (std::ostream& os, NetfilterConntrackTuple const& tuple);
10.9 +
10.10 private:
10.11 Ipv4Address m_l3Source;
10.12 uint16_t m_l3Protocol;
11.1 --- a/src/internet-stack/netfilter-tuple-hash.h Fri Jul 31 00:57:33 2009 +0600
11.2 +++ b/src/internet-stack/netfilter-tuple-hash.h Thu Aug 06 01:55:49 2009 +0600
11.3 @@ -28,7 +28,9 @@
11.4 typedef sgi::hash_map<NetfilterConntrackTuple, IpConntrackInfo, ConntrackTupleHash> TupleHash;
11.5 typedef sgi::hash_map<NetfilterConntrackTuple, IpConntrackInfo, ConntrackTupleHash>::iterator TupleHashI;
11.6
11.7 -
11.8 + typedef sgi::hash_map<NetfilterConntrackTuple, NetfilterConntrackTuple, ConntrackTupleHash> TranslationMap;
11.9 + typedef sgi::hash_map<NetfilterConntrackTuple, NetfilterConntrackTuple, ConntrackTupleHash>::iterator TranslationMapI;
11.10 +
11.11 class NetfilterTupleHash {
11.12 public:
11.13
12.1 --- a/src/internet-stack/wscript Fri Jul 31 00:57:33 2009 +0600
12.2 +++ b/src/internet-stack/wscript Thu Aug 06 01:55:49 2009 +0600
12.3 @@ -109,6 +109,8 @@
12.4 'tcp-conntrack-l4-protocol.cc',
12.5 'udp-conntrack-l4-protocol.cc',
12.6 'icmpv4-conntrack-l4-protocol.cc',
12.7 + 'nat-rule.cc',
12.8 +#'network-address-translation.cc',
12.9 ]
12.10
12.11 headers = bld.new_task_gen('ns3header')
12.12 @@ -130,6 +132,9 @@
12.13 'tcp-conntrack-l4-protocol.h',
12.14 'udp-conntrack-l4-protocol.h',
12.15 'icmpv4-conntrack-l4-protocol.h',
12.16 +# 'network-address-translation.h',
12.17 + 'nat-rule.h',
12.18 + 'ipv4-l3-protocol.h',
12.19 #'jhash.h',
12.20 ]
12.21