1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
3 * Copyright (c) 2009 University of Texas at Dallas
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Author: Qasim Javed <qasim@utdallas.edu>
21 #include "ns3/uinteger.h"
22 #include "ipv4-netfilter.h"
23 #include "ip-conntrack-info.h"
24 #include "ipv4-conntrack-l3-protocol.h"
25 #include "tcp-conntrack-l4-protocol.h"
26 #include "udp-conntrack-l4-protocol.h"
27 #include "icmpv4-conntrack-l4-protocol.h"
28 #include "tcp-header.h"
29 #include "udp-header.h"
31 NS_LOG_COMPONENT_DEFINE ("Ipv4Netfilter");
35 NS_OBJECT_ENSURE_REGISTERED (Ipv4Netfilter);
38 Ipv4Netfilter::GetTypeId (void)
40 static TypeId tId = TypeId ("ns3::Ipv4Netfilter")
42 .AddAttribute ("EnableNat", "0 disbales NAT and is the default, 1 enabled NAT",
44 MakeUintegerAccessor (&Ipv4Netfilter::m_enableNat),
45 MakeUintegerChecker <uint8_t> ())
51 Ipv4Netfilter::Ipv4Netfilter ()
54 NS_LOG_FUNCTION_NOARGS();
56 /* Create callback chains for all of the hooks */
57 for (int i=0; i < NF_INET_NUMHOOKS; i++)
58 m_netfilterHooks[i] = NetfilterCallbackChain ();
60 /* Create and register Ipv4 connection tracking module */
61 Ptr<Ipv4ConntrackL3Protocol> ipv4 = Create<Ipv4ConntrackL3Protocol> ();
62 this->RegisterL3Protocol (ipv4);
64 /* Create and register TCP connection tracking module */
65 Ptr<TcpConntrackL4Protocol> tcp = Create<TcpConntrackL4Protocol> ();
66 this->RegisterL4Protocol (tcp);
68 /* Create and register UDP connection tracking module */
69 Ptr<UdpConntrackL4Protocol> udp = Create<UdpConntrackL4Protocol> ();
70 this->RegisterL4Protocol (udp);
72 /* Create and register ICMP connection tracking module */
73 Ptr<Icmpv4ConntrackL4Protocol> icmpv4 = Create<Icmpv4ConntrackL4Protocol> ();
74 this->RegisterL4Protocol (icmpv4);
76 //Ptr <NetworkAddressTranslation> networkAddressTranslation = Create<NetworkAddressTranslation> (this);
78 /* Create and register hook callbacks */
79 NetfilterHookCallback preRouting = MakeCallback (&Ipv4Netfilter::NetfilterConntrackIn, this);
80 NetfilterHookCallback localIn = MakeCallback (&Ipv4ConntrackL3Protocol::Ipv4Confirm, PeekPointer (ipv4));
82 Ipv4NetfilterHook nfh = Ipv4NetfilterHook (1, NF_INET_PRE_ROUTING, NF_IP_PRI_CONNTRACK , preRouting);
83 Ipv4NetfilterHook nfh1 = Ipv4NetfilterHook (1, NF_INET_LOCAL_OUT, NF_IP_PRI_CONNTRACK, preRouting);
84 Ipv4NetfilterHook nfh2 = Ipv4NetfilterHook (1, NF_INET_POST_ROUTING, NF_IP_PRI_CONNTRACK_CONFIRM, localIn);
85 Ipv4NetfilterHook nfh3 = Ipv4NetfilterHook (1, NF_INET_LOCAL_IN, NF_IP_PRI_CONNTRACK_CONFIRM, localIn);
87 this->RegisterNetfilterHook (nfh);
88 this->RegisterNetfilterHook (nfh1);
89 this->RegisterNetfilterHook (nfh2);
90 this->RegisterNetfilterHook (nfh3);
95 nextAvailablePort = 1024;
99 Ipv4Netfilter::RegisterNetfilterHook (Ipv4NetfilterHook hook)
101 //NS_LOG_FUNCTION (this << hook);
102 m_netfilterHooks[hook.GetHookNumber ()].Insert (hook);
107 Ipv4Netfilter::UnRegisterNetfilterHook (Ipv4NetfilterHook& hook)
109 m_netfilterHooks[hook.GetHookNumber ()].Remove (hook);
114 Ipv4Netfilter::ProcessHook(uint8_t protocolFamily, Hooks_t hookNumber, Ptr<Packet> p,
115 Ptr<NetDevice> in, Ptr<NetDevice> out,
116 ContinueCallback ccb)
118 return m_netfilterHooks[(uint32_t)hookNumber].IterateAndCallHook (hookNumber, p, in, out, ccb);
122 Ipv4Netfilter::RegisterL3Protocol(Ptr<NetfilterConntrackL3Protocol> l3Protocol)
124 //m_netfilterConntrackL3Protocols.push_back(l3Protocol);
125 m_netfilterConntrackL3Protocols = l3Protocol;
130 Ipv4Netfilter::RegisterL4Protocol(Ptr<NetfilterConntrackL4Protocol> l4Protocol)
132 m_netfilterConntrackL4Protocols.push_back(l4Protocol);
136 Ptr<NetfilterConntrackL3Protocol>
137 Ipv4Netfilter::FindL3ProtocolHelper (uint8_t protocolFamily)
139 /*Ptr<NetfilterConntrackL3Protocol>::iterator it;
141 for (; it != netfilerConntrackL3Protocols.end(); it++)
143 if (protocolFamily == it->protocol)
147 return m_netfilterConntrackL3Protocols;
151 Ptr<NetfilterConntrackL4Protocol>
152 Ipv4Netfilter::FindL4ProtocolHelper (uint8_t protocol)
154 std::vector<Ptr<NetfilterConntrackL4Protocol> >::iterator it;
156 for (it = m_netfilterConntrackL4Protocols.begin (); it != m_netfilterConntrackL4Protocols.end (); it++)
158 NS_LOG_DEBUG ( "L4 protocol: " << (*it)->GetL4Protocol () << ", This protocol : "<<(int)protocol );
159 if ((*it)->GetL4Protocol () == protocol) {
160 NS_LOG_DEBUG ( "Found protocol " <<(int)protocol );
169 Ipv4Netfilter::UpdateConntrackInfo (uint8_t info)
171 m_hash[currentOriginalTuple].SetInfo (info);
172 m_hash[currentReplyTuple].SetInfo (info);
177 Ipv4Netfilter::NetfilterConntrackGetTuple (Ptr<Packet> packet, uint16_t l3Number, uint8_t protocolNumber,
178 NetfilterConntrackTuple& tuple, Ptr<NetfilterConntrackL3Protocol> l3Protocol,
179 Ptr<NetfilterConntrackL4Protocol> l4Protocol)
181 tuple.SetProtocol (l3Number);
183 if (l3Protocol->PacketToTuple (packet, tuple) == false)
186 //TODO: Do we really need the Protocol Family as well?
189 NS_LOG_DEBUG (" :: Remove Ipv4 Header :: ");
190 packet->RemoveHeader (ipHeader);
192 tuple.SetDirection (IP_CT_DIR_ORIGINAL);
194 if (l4Protocol->PacketToTuple (packet, tuple) == false)
197 NS_LOG_DEBUG (" :: Add Ipv4 Header :: ");
198 packet->AddHeader (ipHeader);
204 Ipv4Netfilter::NewConnection (NetfilterConntrackTuple& tuple, Ptr<NetfilterConntrackL3Protocol> l3proto,
205 Ptr<NetfilterConntrackL4Protocol> l4proto, Ptr<Packet> packet)
207 NS_LOG_FUNCTION ( this << packet );
209 NetfilterConntrackTuple replyTuple;
211 if (!InvertTuple (replyTuple, tuple, l3proto, l4proto))
212 return m_hash.end ();
214 // Invoke l4proto->New
216 // Find expectatons here
218 NS_LOG_DEBUG (":: Creating an unconfirmed entry for this tuple ::");
219 m_unconfirmed[tuple] = IpConntrackInfo ();
221 TupleHashI it = m_unconfirmed.find (tuple);
227 Ipv4Netfilter::ResolveNormalConntrack (Ptr<Packet> packet, uint32_t protocolFamily, uint8_t protocol,
228 Ptr<NetfilterConntrackL3Protocol> l3Protocol, Ptr<NetfilterConntrackL4Protocol> l4Protocol,
229 int& setReply, ConntrackInfo_t& ctInfo, Ipv4Header ipHeader)
231 NS_LOG_FUNCTION (this << packet);
232 //NetfilterConntrackTuple tuple (ipHeader.GetSource(), 0, ipHeader.GetDestination(), 0);
233 NetfilterConntrackTuple tuple;
234 uint8_t conntrackInfo = 0;
236 /* Get a tuple from the information in the packet */
237 if (!NetfilterConntrackGetTuple (packet, protocolFamily, protocol, tuple, l3Protocol, l4Protocol))
239 NS_LOG_DEBUG ("Cannot create a tuple from the packet");
243 TupleHashI it = m_hash.find (tuple);
245 if (it == m_hash.end ())
247 NS_LOG_DEBUG ("No tuple found");
248 //TupleHashI newIt = NewConnection(tuple, l3Protocol, l4Protocol, packet);
249 it = NewConnection (tuple, l3Protocol, l4Protocol, packet);
252 NetfilterConntrackTuple replyTuple;
254 if (!InvertTuple (replyTuple, tuple, l3Protocol, l4Protocol))
257 currentOriginalTuple = tuple;
258 currentReplyTuple = replyTuple;
260 /* TODO: Add a pointer to the hashed tuple in IpConntrackInfo()
261 * and store these tuples somehwere, when you destruct then you
262 * you have to take care of the tuples stored in the vector as
265 if ((it->first).GetDirection () == (uint8_t)IP_CT_DIR_REPLY)
267 NS_LOG_DEBUG (":: **** This is a REPLY *** ::");
268 conntrackInfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY;
271 NS_LOG_DEBUG (":: Packet is in the original direction ::");
272 if ( m_hash[tuple].GetStatus () & IPS_SEEN_REPLY) {
273 NS_LOG_DEBUG (":: Connection ESTABLISHED! ::");
274 conntrackInfo = IP_CT_ESTABLISHED;
277 NS_LOG_DEBUG (":: New connection :: ");
278 conntrackInfo = IP_CT_NEW;
283 m_unconfirmed[tuple].SetInfo (conntrackInfo);
284 //UpdateConntrackInfo (conntrackInfo);
285 /*NS_LOG_DEBUG ("Adding the conntrack packet tag" );
287 bool tagFound = packet->PeekPacketTag (ctTag);
290 packet->AddPacketTag (ConntrackTag (conntrackInfo));
292 NS_LOG_DEBUG ("Tag already present");
300 Ipv4Netfilter::NetfilterConntrackIn (Hooks_t hook, Ptr<Packet> packet, Ptr<NetDevice> in,
301 Ptr<NetDevice> out, ContinueCallback& ccb)
303 NS_LOG_DEBUG ("::: Executing Hook Function :::");
305 ConntrackInfo_t ctInfo;
306 /* If this packet has been seen previously, Ignore. */
308 /* Find layer 3 helper for this packet */
309 Ptr<NetfilterConntrackL3Protocol> l3proto = FindL3ProtocolHelper (1);
313 packet->PeekHeader (ipHeader);
315 NS_LOG_DEBUG ( "IP header protocol: " << (int)ipHeader.GetProtocol ());
317 Ptr<NetfilterConntrackL4Protocol> l4proto = FindL4ProtocolHelper (ipHeader.GetProtocol ());
319 /*if (l4proto != NULL) {
322 ResolveNormalConntrack (packet, 1 /* PF */, ipHeader.GetProtocol (), l3proto, l4proto, setReply, ctInfo, ipHeader);
324 // Call layer 4 Packet callback
325 //uint32_t ret = l4proto->packet(packet, protocolFamily, hookNumber);
329 NS_LOG_DEBUG ("Setting IPS_SEEN_REPLY");
330 m_hash[currentOriginalTuple].SetStatus ( IPS_SEEN_REPLY );
331 m_hash[currentReplyTuple].SetStatus ( IPS_SEEN_REPLY );
339 Ipv4Netfilter::NetfilterConntrackConfirm (Ptr<Packet> packet)
340 //, NetfilterConntrackTuple& orig,
341 // NetfilterConntrackTuple& reply)
343 NS_LOG_FUNCTION ( this << packet );
344 /* If this packet has been seen previously, Ignore. */
346 /* Find layer 3 helper for this packet */
347 /*Ptr<NetfilterConntrackL3Protocol> l3proto = FindL3ProtocolHelper (1);
351 //packet->RemoveHeader(ipHeader);
352 packet->PeekHeader (ipHeader);
354 NS_LOG_DEBUG ( "IP header protocol: " << (int)ipHeader.GetProtocol ());
356 Ptr<NetfilterConntrackL4Protocol> l4proto = FindL4ProtocolHelper (ipHeader.GetProtocol ());
358 NetfilterConntrackTuple orig;*/
360 /* Get a tuple from the information in the packet */
361 /*if (!NetfilterConntrackGetTuple (packet, 1, ipHeader.GetProtocol (), orig, l3proto, l4proto))
363 NS_LOG_DEBUG ("Cannot create a tuple from the packet");
367 NetfilterConntrackTuple reply;
370 InvertTuple (reply, orig, l3proto, l4proto);
372 currentOriginalTuple = orig;
373 currentReplyTuple = reply;
375 NS_LOG_DEBUG ("Current Original Tuple: " << currentOriginalTuple.GetSource () << ", " << currentOriginalTuple.GetDestination ());
376 NS_LOG_DEBUG ("Current Reply Tuple: " << currentReplyTuple.GetSource () << ", " << currentReplyTuple.GetDestination ());
377 //currentTuple[IP_CT_DIR_REPLY] = reply;*/
379 /**************************/
381 /*ConntrackTag ctTag;
383 if (!packet->PeekPacketTag (ctTag))
385 NS_LOG_DEBUG ("ConntrackTag not found");
389 if ( CTINFO2DIR (ctTag.GetConntrack ()) != IP_CT_DIR_ORIGINAL)
392 if (m_hash.find (orig) != m_hash.end () && m_hash.find (reply) != m_hash.end () )
394 NS_LOG_DEBUG ("Entries already present!");
398 NS_LOG_DEBUG ("Creating confirmed hash entries");
399 //m_hash[orig] = IpConntrackInfo().SetStatus(IPS_CONFIRMED);
400 m_hash[orig] = IpConntrackInfo ();
401 m_hash[reply] = IpConntrackInfo ();
405 if ( CTINFO2DIR (m_unconfirmed[currentOriginalTuple].GetInfo ()) != IP_CT_DIR_ORIGINAL)
407 NS_LOG_DEBUG ("Not a packet in the original direction");
411 /*if (m_hash.find (currentOriginalTuple) != m_hash.end () && m_hash.find (currentReplyTuple) != m_hash.end () )
413 NS_LOG_DEBUG ("Entries already present!");
417 NS_LOG_DEBUG ("Creating confirmed hash entries");
418 m_hash[currentOriginalTuple] = m_unconfirmed[currentOriginalTuple];
419 m_hash[currentReplyTuple] = m_unconfirmed[currentOriginalTuple];
425 Ipv4Netfilter::NetfilterDoNat (Hooks_t hookNumber, Ptr<Packet> p,
426 Ptr<NetDevice> in, Ptr<NetDevice> out, ContinueCallback& ccb)
428 NS_LOG_FUNCTION ( this << p );
429 /*ConntrackTag ctTag;
431 bool found = p->PeekPacketTag (ctTag);
435 NS_LOG_DEBUG ("Conntrack tag not found");
439 /* Conntrack has a higher priority so currentOriginalTuple and
440 * currentReply tuple should always be correct
443 //std::vector<NatRule>::iterator it = FindNatDevice (out);
445 /*if (it == m_natRules.end ())
447 NS_LOG_DEBUG ("No NAT rule for device " << out->GetId ());
451 NS_LOG_DEBUG ("Current Original Tuple: " << currentOriginalTuple.GetSource () << ", " << currentOriginalTuple.GetDestination ());
452 NS_LOG_DEBUG ("Current Reply Tuple: " << currentReplyTuple.GetSource () << ", " << currentReplyTuple.GetDestination ());
454 NS_LOG_DEBUG ("ConntrackInfo: " << (uint16_t)m_unconfirmed[currentOriginalTuple].GetInfo () );
456 /* TODO: Why are you checking m_hash here when the info is in
457 * m_unconfirmed. This could be a problem because NAT is sandwiched
458 * between conntrack hook callbacks
460 switch (m_unconfirmed[currentOriginalTuple].GetInfo ())
463 case IP_CT_RELATED + IP_CT_IS_REPLY:
464 /* This should be updated when "expectations" are added */
469 if ( hookNumber == NF_INET_POST_ROUTING )
471 NS_LOG_DEBUG ("SRC_NAT: New Connection encountered");
476 if ( (it = m_hash.find (currentOriginalTuple)) != m_hash.end ())
478 if ( !((it->second).GetStatus () & IPS_SRC_NAT_DONE) )
480 /* Get a unique tuple and create a mapping */
482 NS_LOG_DEBUG ("Doing rule lookup at device " << out->GetIfIndex ());
483 std::vector<NatRule>::iterator it =
484 FindNatRule ( Ipv4Address (currentOriginalTuple.GetSource ()), out );
486 if ( it == m_natRules.end () )
488 NS_LOG_DEBUG ("No rule matched!");
492 NS_LOG_DEBUG ("Creating a NAT mapping");
494 /* Create a NULL mapping, which does not contain port numbers */
495 NetfilterConntrackTuple mapping =
496 NetfilterConntrackTuple (it->GetMangledSource (), nextAvailablePort,
497 currentOriginalTuple.GetDestination (), 9);
498 mapping.SetDirection (IP_CT_DIR_ORIGINAL);
501 NS_LOG_DEBUG ("Creating a NAT mapping for the tuple " << currentOriginalTuple
502 << ": " << mapping );
503 m_natMappings[currentOriginalTuple] = mapping;
504 m_natReplyLookup[mapping] = currentOriginalTuple;
508 NS_LOG_DEBUG (":: Translating addresses and fixing IP checksum ::");
509 NetfilterNatPacket (hookNumber, p);
512 NS_LOG_DEBUG ("BUG: currentTuple non-existent in hash!");
518 NS_LOG_DEBUG ("SRC_NAT: Connection is established!");
519 NS_LOG_DEBUG (":: Translating addresses and fixing IP checksum ::");
520 NetfilterNatPacket (hookNumber, p);
529 Ipv4Netfilter::InvertTuple (NetfilterConntrackTuple& inverse, NetfilterConntrackTuple& orig,
530 Ptr<NetfilterConntrackL3Protocol> l3Protocol,
531 Ptr<NetfilterConntrackL4Protocol> l4Protocol)
533 inverse.SetProtocol (orig.GetProtocol ());
535 if (!l3Protocol->InvertTuple (inverse, orig))
538 inverse.SetDirection (orig.GetDirection () == IP_CT_DIR_ORIGINAL ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL);
540 return l4Protocol->InvertTuple (inverse, orig);
545 Ipv4Netfilter::GetHash ()
551 Ipv4Netfilter::AddNatRule (NatRule natRule)
553 m_natRules.push_back (natRule);
556 std::vector<NatRule>::iterator
557 Ipv4Netfilter::FindNatRule (NatRule natRule)
559 std::vector<NatRule>::iterator it = m_natRules.begin ();
561 for ( ; it != m_natRules.end (); it++)
563 if ( *it == natRule )
567 return m_natRules.end ();
570 std::vector<NatRule>::iterator
571 Ipv4Netfilter::FindNatRule (Ipv4Address orig, Ptr<NetDevice> out)
573 std::vector<NatRule>::iterator it = m_natRules.begin ();
575 NS_LOG_DEBUG ("Number of rules: " << m_natRules.size () );
576 NS_LOG_DEBUG ("Orig: " << orig );
578 for ( ; it != m_natRules.end (); it++)
580 NS_LOG_DEBUG ("Rule source: " << it->GetOriginalSource () << ", passed in source: " << orig);
581 NS_LOG_DEBUG ("Rule device: " << it->GetDevice () << ", passed in dev: " << out);
582 if ( it->GetOriginalSource () == orig && it->GetDevice () == out)
584 NS_LOG_DEBUG ("Rule match found!");
589 return m_natRules.end ();
593 Ipv4Netfilter::EnableNat ()
597 NS_LOG_DEBUG (":: Enabling NAT ::");
599 NetfilterHookCallback doNat = MakeCallback (&Ipv4Netfilter::NetfilterDoNat, this);
601 Ipv4NetfilterHook natCallback1 = Ipv4NetfilterHook (1, NF_INET_POST_ROUTING, NF_IP_PRI_NAT_SRC, doNat);
602 Ipv4NetfilterHook natCallback2 = Ipv4NetfilterHook (1, NF_INET_PRE_ROUTING, NF_IP_PRI_NAT_DST, doNat);
605 this->RegisterNetfilterHook (natCallback1);
606 this->RegisterNetfilterHook (natCallback2);
610 Ipv4Netfilter::NetfilterNatPacket (Hooks_t hookNumber, Ptr<Packet> p)
612 NS_LOG_FUNCTION ( this << p );
614 uint16_t dstPort; //, srcPort;
615 Ipv4Address dstAddress, srcAddress;
617 p->RemoveHeader (ipHeader);
619 uint16_t protocol = ipHeader.GetProtocol ();
621 if (hookNumber == NF_INET_POST_ROUTING)
623 NetfilterConntrackTuple mapped = m_natMappings[currentOriginalTuple];
625 ipHeader.SetSource (mapped.GetSource ());
627 if (protocol == IPPROTO_TCP)
631 p->RemoveHeader (tcpHeader);
633 tcpHeader.SetSourcePort (mapped.GetSourcePort ());
635 p->AddHeader (tcpHeader);
642 p->RemoveHeader (udpHeader);
644 udpHeader.SetSourcePort (mapped.GetSourcePort ());
646 p->AddHeader (udpHeader);
649 p->AddHeader (ipHeader);
651 NetfilterConntrackTuple oldOriginalTuple = currentOriginalTuple;
654 currentOriginalTuple = NetfilterConntrackTuple (mapped.GetSource(), mapped.GetSourcePort (),
655 currentOriginalTuple.GetDestination (),
656 currentOriginalTuple.GetDestinationPort ());
658 currentOriginalTuple.SetDirection (IP_CT_DIR_ORIGINAL);
660 currentReplyTuple = NetfilterConntrackTuple (currentOriginalTuple.GetDestination (),
661 currentOriginalTuple.GetDestinationPort (),
662 mapped.GetSource (), mapped.GetSourcePort ());
664 currentReplyTuple.SetDirection (IP_CT_DIR_REPLY);
666 std::cout <<" New Original Tuple: " << currentOriginalTuple << std::endl;
667 std::cout <<" New Reply Tuple: " << currentReplyTuple << std::endl;
669 m_unconfirmed[currentOriginalTuple] = m_unconfirmed[oldOriginalTuple];
672 else if (hookNumber == NF_INET_PRE_ROUTING)
674 NS_LOG_DEBUG ("Mapping back to LAN address");
675 //NetfilterConntrackTuple mapped = m_natMappings[currentReplyTuple];
676 NetfilterConntrackTuple temp = currentReplyTuple;
677 temp.SetDirection (IP_CT_DIR_ORIGINAL);
678 TranslationMapI transIt = m_natReplyLookup.find (temp);
680 if (transIt == m_natMappings.end ())
682 NS_LOG_DEBUG ("No such mapping found!");
686 dstPort = (transIt->second).GetSourcePort ();
687 dstAddress = (transIt->second).GetSource ();
689 currentOriginalTuple = NetfilterConntrackTuple ((transIt->second).GetSource (), (transIt->second).GetSourcePort (), dstAddress, dstPort);
690 currentReplyTuple = NetfilterConntrackTuple (dstAddress, dstPort, (transIt->second).GetSource (), (transIt->second).GetSourcePort ());
692 NS_LOG_DEBUG ("Setting Destination IP address to : " << dstAddress);
693 ipHeader.SetDestination (dstAddress);
695 if (protocol == IPPROTO_TCP)
699 p->RemoveHeader (tcpHeader);
701 tcpHeader.SetDestinationPort (dstPort);
703 p->AddHeader (tcpHeader);
710 p->RemoveHeader (udpHeader);
712 udpHeader.SetDestinationPort (dstPort);
713 NS_LOG_DEBUG ("Setting destination port to: " << dstPort);
715 p->AddHeader (udpHeader);
718 p->AddHeader (ipHeader);