src/internet-stack/ipv4-netfilter.h
author Qasim Javed <qasimj@gmail.com>
Thu Aug 06 01:55:49 2009 +0600 (2009-08-06)
changeset 4638 19aa5f9b4bdf
parent 4636 be76844f7b75
permissions -rw-r--r--
Source NAT working! Run (examples/netfilter-example.cc)
     1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     2 /* 
     3  * Copyright (c) 2009 University of Texas at Dallas
     4  * 
     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;
     8  *
     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.
    13  *
    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
    17  * 
    18  * Author: Qasim Javed <qasim@utdallas.edu>
    19  */
    20 
    21 #ifndef IPV4_NETFILTER_H
    22 #define IPV4_NETFILTER_H
    23 
    24 #include <stdint.h>
    25 #include <limits.h>
    26 #include "ns3/ptr.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"
    39 #include "nat-rule.h"
    40 //#include "network-address-translation.h"
    41 
    42 #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL)
    43 
    44 namespace ns3 {
    45 
    46 class Packet;
    47 class NetDevice;
    48 
    49 typedef enum {
    50   NF_IP_PRI_FIRST = INT_MIN,
    51   NF_IP_PRI_CONNTRACK_DEFRAG = -400,
    52   NF_IP_PRI_RAW = -300,
    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,
    57   NF_IP_PRI_FILTER = 0,
    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;
    64 
    65 static Callback<uint32_t, Ptr<Packet> > defaultContinueCallback = MakeNullCallback<uint32_t, Ptr<Packet> > ();
    66 
    67 /**
    68   * \brief Implementation of netfilter
    69   * 
    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.
    74   */
    75 
    76 class Ipv4Netfilter  : public Object {
    77   public:
    78     static TypeId GetTypeId (void);
    79 
    80     Ipv4Netfilter ();
    81 
    82     /**
    83       * \param hook The hook function to be registered
    84       * \returns 0 on success
    85       * 
    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
    90       * that hook.
    91       */
    92     uint32_t RegisterNetfilterHook (Ipv4NetfilterHook hook);
    93 
    94     /**
    95       * \param hook The hook function to be registered
    96       * \returns 0 on success
    97       * 
    98       * Unregisters the hook function from the specified hook 
    99       * The hook function is removed from the callback chain for
   100       * that hook.
   101       */
   102     uint32_t UnRegisterNetfilterHook (Ipv4NetfilterHook& hook);
   103 
   104     /**
   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.
   113       *
   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.
   117       */
   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> ());
   122 
   123     /**
   124       * \param l3Protocol Layer 3 protocol
   125       * \returns 0 on success
   126       *
   127       * Registers a layer 3 protocol with the netfilter framework. Packets
   128       * that conform to the registered protocols can be processed by netfilter.
   129       */
   130     uint32_t RegisterL3Protocol (Ptr<NetfilterConntrackL3Protocol> l3Protocol);
   131     
   132     /**
   133       * \param l4Protocol Layer 4 protocol
   134       * \returns 0 on success
   135       *
   136       * Registers a layer 4 protocol with the netfilter framework. Packets
   137       * that conform to the registered protocols can be processed by netfilter.
   138       */
   139     uint32_t RegisterL4Protocol (Ptr<NetfilterConntrackL4Protocol> l4Protocol);
   140 
   141     /**
   142       * \param protocolFamily Protocol Family e.g., PF_INET
   143       * \returns Pointer to the helper object
   144       *
   145       * Searches for a matching Layer 3 protocol helper among the ones that
   146       * have been registered using RegisterL3Protocol.
   147       */
   148     Ptr<NetfilterConntrackL3Protocol> FindL3ProtocolHelper (uint8_t protocolFamily);
   149     
   150     /**
   151       * \param protocol Layer 4 protocol e.g., IPPROTO_TCP
   152       * \returns Pointer to the helper object
   153       *
   154       * Searches for a matching Layer 4 protocol helper among the ones that
   155       * have been registered using RegisterL4Protocol.
   156       */
   157     Ptr<NetfilterConntrackL4Protocol> FindL4ProtocolHelper (uint8_t protocol);
   158 
   159     /**
   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
   169       *
   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
   174       */
   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);
   178 
   179     /**
   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
   187       *
   188       * Extracts information from the packet to create a corresponding tuple
   189       */
   190 
   191     bool NetfilterConntrackGetTuple (Ptr<Packet> packet, uint16_t l3Number, uint8_t protocolNumber, 
   192          NetfilterConntrackTuple& tuple, Ptr<NetfilterConntrackL3Protocol> l3Protocol, 
   193          Ptr<NetfilterConntrackL4Protocol> l4Protocol);
   194 
   195     /**
   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 
   201       *
   202       * Updates the hash table to create an entry for the new connection
   203       */
   204 
   205     TupleHashI NewConnection (NetfilterConntrackTuple& tuple, Ptr<NetfilterConntrackL3Protocol> l3proto, 
   206             Ptr<NetfilterConntrackL4Protocol> l4proto, Ptr<Packet> packet);
   207 
   208 
   209     int UpdateConntrackInfo (uint8_t info);
   210 
   211     uint32_t NetfilterConntrackIn (Hooks_t hook, Ptr <Packet> packet, Ptr<NetDevice> in, 
   212              Ptr<NetDevice> out, ContinueCallback& ccb);
   213 
   214     uint32_t NetfilterConntrackConfirm (Ptr<Packet> p);
   215     
   216     uint32_t NetfilterDoNat (Hooks_t hookNumber, Ptr<Packet> p, 
   217                              Ptr<NetDevice> in, Ptr<NetDevice> out, ContinueCallback& ccb);
   218 
   219     /**
   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
   224       *
   225       * Inverses the passed tuple. This is needed to track reply packets.
   226       */
   227       
   228     bool InvertTuple (NetfilterConntrackTuple& inverse, NetfilterConntrackTuple& orig,
   229                     Ptr<NetfilterConntrackL3Protocol> l3Protocol,
   230                     Ptr<NetfilterConntrackL4Protocol> l4Protocol);
   231 
   232     TupleHash& GetHash ();
   233 
   234     void AddNatRule (NatRule natRule);
   235 
   236     std::vector<NatRule>::iterator FindNatRule (NatRule natRule);
   237 
   238     std::vector<NatRule>::iterator FindNatRule (Ipv4Address orig, Ptr<NetDevice> out);
   239     //static NetfilterConntrackTuple currentTuple[IP_CT_DIR_MAX];
   240 
   241     void EnableNat ();
   242 
   243     uint32_t NetfilterNatPacket (Hooks_t hookNumber, Ptr<Packet> p);
   244 
   245   private:
   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;
   250     TupleHash m_hash;
   251 
   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;
   255 
   256     TranslationMap m_natMappings;
   257     
   258     NetfilterConntrackTuple currentOriginalTuple;
   259     NetfilterConntrackTuple currentReplyTuple;
   260 
   261     uint8_t m_enableNat;
   262     std::vector <NatRule> m_natRules;
   263 
   264     uint16_t nextAvailablePort;
   265 
   266     TranslationMap m_natReplyLookup;
   267 };
   268 
   269 //uint16_t Ipv4Netfilter::nextAvailablePort = 1024;
   270     
   271 //NetfilterConntrackTuple Ipv4Netfilter::currentTuple = NetfilterConntrackTuple ();
   272 //NetfilterConntrackTuple Ipv4Netfilter::currentTuple[IP_CT_DIR_ORIGINAL] = NetfilterConntrackTuple ();
   273 
   274 } // Namespace ns3
   275 #endif /* IPV4_NETFILTER_H */