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 #ifndef IPV4_NETFILTER_H
22 #define IPV4_NETFILTER_H
27 #include "ns3/net-device.h"
28 #include "ns3/packet.h"
29 #include "ns3/conntrack-tag.h"
30 #include "ns3/ipv4-header.h"
31 #include "ns3/object.h"
32 #include "ipv4-netfilter-hook.h"
33 #include "netfilter-callback-chain.h"
34 #include "netfilter-conntrack-tuple.h"
35 #include "netfilter-tuple-hash.h"
36 #include "netfilter-conntrack-l3-protocol.h"
37 #include "netfilter-conntrack-l4-protocol.h"
38 #include "ip-conntrack-info.h"
40 //#include "network-address-translation.h"
42 #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
50 NF_IP_PRI_FIRST = INT_MIN,
51 NF_IP_PRI_CONNTRACK_DEFRAG = -400,
53 NF_IP_PRI_SELINUX_FIRST = -225,
54 NF_IP_PRI_CONNTRACK = -200,
55 NF_IP_PRI_MANGLE = -150,
56 NF_IP_PRI_NAT_DST = -100,
58 NF_IP_PRI_SECURITY = 50,
59 NF_IP_PRI_NAT_SRC = 100,
60 NF_IP_PRI_SELINUX_LAST = 225,
61 NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
62 NF_IP_PRI_LAST = INT_MAX,
63 } NetfilterIpv4HookPriorities;
65 static Callback<uint32_t, Ptr<Packet> > defaultContinueCallback = MakeNullCallback<uint32_t, Ptr<Packet> > ();
68 * \brief Implementation of netfilter
70 * This implements functionality similar to netfilter
71 * in the Linux Kernel. As of now, it supports limited
72 * connection tracking (without expectations), and Network
73 * Address Translation.
76 class Ipv4Netfilter : public Object {
78 static TypeId GetTypeId (void);
83 * \param hook The hook function to be registered
84 * \returns 0 on success
86 * Registers the hook function at the specified hook
87 * using the priority given in the hook datastructure.
88 * The hook function is added to the callback chain for
89 * that hook and is called whenever a packet traverses
92 uint32_t RegisterNetfilterHook (Ipv4NetfilterHook hook);
95 * \param hook The hook function to be registered
96 * \returns 0 on success
98 * Unregisters the hook function from the specified hook
99 * The hook function is removed from the callback chain for
102 uint32_t UnRegisterNetfilterHook (Ipv4NetfilterHook& hook);
105 * \param protocolFamily The protocol family e.g., PF_INET
106 * \param hookNumber The hook number e.g., NF_INET_PRE_ROUTING
107 * \param p Packet that is handed over to the callback chain for this hook
108 * \param in NetDevice which received the packet
109 * \param out The outgoing NetDevice
110 * \param ccb If not NULL, this callback will be invoked once the hook
111 * callback chain has finished processing
112 * \returns Netfilter verdict for the Packet. e.g., NF_ACCEPT, NF_DROP etc.
114 * Various invocations of this method are used to implement hooks within the
115 * ns-3 IP stack. When a packet "traverses" a hook, it is handed over to the
116 * callback chain for that hook by this method.
118 uint32_t ProcessHook (uint8_t protocolFamily, Hooks_t hookNumber, Ptr<Packet> p,
119 Ptr<NetDevice> in, Ptr<NetDevice> out ,
120 ContinueCallback ccb = defaultContinueCallback);
121 //ContinueCallback ccb = MakeNullCallback <uint32_t, Ptr<Packet> ());
124 * \param l3Protocol Layer 3 protocol
125 * \returns 0 on success
127 * Registers a layer 3 protocol with the netfilter framework. Packets
128 * that conform to the registered protocols can be processed by netfilter.
130 uint32_t RegisterL3Protocol (Ptr<NetfilterConntrackL3Protocol> l3Protocol);
133 * \param l4Protocol Layer 4 protocol
134 * \returns 0 on success
136 * Registers a layer 4 protocol with the netfilter framework. Packets
137 * that conform to the registered protocols can be processed by netfilter.
139 uint32_t RegisterL4Protocol (Ptr<NetfilterConntrackL4Protocol> l4Protocol);
142 * \param protocolFamily Protocol Family e.g., PF_INET
143 * \returns Pointer to the helper object
145 * Searches for a matching Layer 3 protocol helper among the ones that
146 * have been registered using RegisterL3Protocol.
148 Ptr<NetfilterConntrackL3Protocol> FindL3ProtocolHelper (uint8_t protocolFamily);
151 * \param protocol Layer 4 protocol e.g., IPPROTO_TCP
152 * \returns Pointer to the helper object
154 * Searches for a matching Layer 4 protocol helper among the ones that
155 * have been registered using RegisterL4Protocol.
157 Ptr<NetfilterConntrackL4Protocol> FindL4ProtocolHelper (uint8_t protocol);
160 * \param packet The packet being processed by a hook
161 * \param protocolFamily Protocol Family e.g., PF_INET
162 * \param protocol The value in the protocol field of the IP header
163 * \param l3Protocol Layer 3 protocol helper
164 * \param l4Protocol Layer 4 protocol helper
165 * \param setReply Set to 1 if this is a reply
166 * \param ctInfo Connection tracking information e.g., IP_CT_ESTABLISHED
167 * \param ipHeader IP header of the packet
168 * \returns 0 on success
170 * This method checks whether this is a new connection and if so creates an
171 * entry for it in the hash table. If this connection already exists in the
172 * hash table then the state of the connection is updated depending on the
173 * information inside the packet
175 uint32_t ResolveNormalConntrack (Ptr<Packet> packet, uint32_t protocolFamily, uint8_t protocol,
176 Ptr<NetfilterConntrackL3Protocol> l3Protocol, Ptr<NetfilterConntrackL4Protocol> l4Protocol,
177 int& setReply, ConntrackInfo_t& ctInfo, Ipv4Header ipHeader);
180 * \param packet Packet that should be converted to a tuple
181 * \param l3Number Layer 3 protocol
182 * \param protocolNumber Layer 4 protocol
183 * \param tuple Stores the created tuple
184 * \param Layer 3 protocol helper
185 * \param Layer 4 protocol helper
186 * \returns true if a tuple was created successfully, false otherwise
188 * Extracts information from the packet to create a corresponding tuple
191 bool NetfilterConntrackGetTuple (Ptr<Packet> packet, uint16_t l3Number, uint8_t protocolNumber,
192 NetfilterConntrackTuple& tuple, Ptr<NetfilterConntrackL3Protocol> l3Protocol,
193 Ptr<NetfilterConntrackL4Protocol> l4Protocol);
196 * \param tuple Tuple representing the new connection
197 * \param l3proto Layer 3 protocol helper
198 * \param l4proto Layer 4 protocol helper
199 * \param packet Packet
200 * \returns TupleHash Iterator
202 * Updates the hash table to create an entry for the new connection
205 TupleHashI NewConnection (NetfilterConntrackTuple& tuple, Ptr<NetfilterConntrackL3Protocol> l3proto,
206 Ptr<NetfilterConntrackL4Protocol> l4proto, Ptr<Packet> packet);
209 int UpdateConntrackInfo (uint8_t info);
211 uint32_t NetfilterConntrackIn (Hooks_t hook, Ptr <Packet> packet, Ptr<NetDevice> in,
212 Ptr<NetDevice> out, ContinueCallback& ccb);
214 uint32_t NetfilterConntrackConfirm (Ptr<Packet> p);
216 uint32_t NetfilterDoNat (Hooks_t hookNumber, Ptr<Packet> p,
217 Ptr<NetDevice> in, Ptr<NetDevice> out, ContinueCallback& ccb);
220 * \param inverse The inverse of the tuple should be stored here
221 * \param orig The tuple that should be inverted
222 * \param l3Protocol Layer 3 protocol helper
223 * \param l4Protocol Layer 4 protocol helper
225 * Inverses the passed tuple. This is needed to track reply packets.
228 bool InvertTuple (NetfilterConntrackTuple& inverse, NetfilterConntrackTuple& orig,
229 Ptr<NetfilterConntrackL3Protocol> l3Protocol,
230 Ptr<NetfilterConntrackL4Protocol> l4Protocol);
232 TupleHash& GetHash ();
234 void AddNatRule (NatRule natRule);
236 std::vector<NatRule>::iterator FindNatRule (NatRule natRule);
238 std::vector<NatRule>::iterator FindNatRule (Ipv4Address orig, Ptr<NetDevice> out);
239 //static NetfilterConntrackTuple currentTuple[IP_CT_DIR_MAX];
243 uint32_t NetfilterNatPacket (Hooks_t hookNumber, Ptr<Packet> p);
246 NetfilterCallbackChain m_netfilterHooks[NF_INET_NUMHOOKS];
247 //std::vector<Ptr<NetfilterConntrackL3Protocol> > m_netfilterConntrackL3Protocols;
248 TupleHash m_netfilterTupleHash[IP_CT_DIR_MAX];
249 TupleHash m_unconfirmed;
252 /* TODO: Should be a table once we have more L3/L4 Protocols */
253 Ptr<NetfilterConntrackL3Protocol> m_netfilterConntrackL3Protocols;
254 std::vector<Ptr<NetfilterConntrackL4Protocol> > m_netfilterConntrackL4Protocols;
256 TranslationMap m_natMappings;
258 NetfilterConntrackTuple currentOriginalTuple;
259 NetfilterConntrackTuple currentReplyTuple;
262 std::vector <NatRule> m_natRules;
264 uint16_t nextAvailablePort;
266 TranslationMap m_natReplyLookup;
269 //uint16_t Ipv4Netfilter::nextAvailablePort = 1024;
271 //NetfilterConntrackTuple Ipv4Netfilter::currentTuple = NetfilterConntrackTuple ();
272 //NetfilterConntrackTuple Ipv4Netfilter::currentTuple[IP_CT_DIR_ORIGINAL] = NetfilterConntrackTuple ();
275 #endif /* IPV4_NETFILTER_H */