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