src/internet-stack/netfilter-conntrack-tuple.cc
author Qasim Javed <qasimj@gmail.com>
Thu Aug 06 01:55:49 2009 +0600 (2009-08-06)
changeset 4638 19aa5f9b4bdf
parent 4637 0882bb6eac0b
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
#include "netfilter-conntrack-tuple.h"
qasimj@4634
    22
qasimj@4634
    23
NS_LOG_COMPONENT_DEFINE ("ConntrackTupleHash");
qasimj@4634
    24
qasimj@4634
    25
namespace ns3 {
qasimj@4634
    26
qasimj@4636
    27
NetfilterConntrackTuple::NetfilterConntrackTuple ()
qasimj@4634
    28
{
qasimj@4637
    29
  m_l4Source = 0;
qasimj@4637
    30
  m_l4Destination = 0;
qasimj@4634
    31
}
qasimj@4634
    32
qasimj@4636
    33
NetfilterConntrackTuple::NetfilterConntrackTuple (Ipv4Address src, uint16_t srcPort, Ipv4Address dst, uint16_t dstPort)
qasimj@4634
    34
{
qasimj@4637
    35
  m_l3Source = src;
qasimj@4637
    36
  m_l4Source = srcPort;
qasimj@4637
    37
  m_l3Destination = dst;
qasimj@4637
    38
  m_l4Destination = dstPort;
qasimj@4634
    39
}
qasimj@4634
    40
qasimj@4634
    41
bool 
qasimj@4636
    42
NetfilterConntrackTuple::operator== (const NetfilterConntrackTuple t) const
qasimj@4634
    43
{
qasimj@4637
    44
  return (m_l3Source == t.m_l3Source) &&
qasimj@4637
    45
    (m_l4Source == t.m_l4Source) &&
qasimj@4637
    46
      (m_l3Destination == t.m_l3Destination) &&
qasimj@4637
    47
        (m_l4Destination == t.m_l4Destination);
qasimj@4634
    48
}
qasimj@4634
    49
qasimj@4634
    50
bool 
qasimj@4636
    51
NetfilterConntrackTuple::SourceEqual (NetfilterConntrackTuple t1, NetfilterConntrackTuple t2)
qasimj@4634
    52
{
qasimj@4637
    53
  return (t1.m_l3Source == t2.m_l3Source) &&
qasimj@4637
    54
    (t1.m_l4Source == t2.m_l4Source);
qasimj@4634
    55
}
qasimj@4634
    56
qasimj@4634
    57
bool 
qasimj@4636
    58
NetfilterConntrackTuple::DestinationEqual (NetfilterConntrackTuple t1, NetfilterConntrackTuple t2)
qasimj@4634
    59
{
qasimj@4637
    60
  return (t1.m_l3Destination == t2.m_l3Destination) &&
qasimj@4637
    61
    (t1.m_l4Destination == t2.m_l4Destination);
qasimj@4634
    62
}
qasimj@4634
    63
qasimj@4634
    64
qasimj@4634
    65
Ipv4Address 
qasimj@4636
    66
NetfilterConntrackTuple::GetSource () const
qasimj@4634
    67
{
qasimj@4637
    68
  return m_l3Source;
qasimj@4634
    69
}
qasimj@4634
    70
qasimj@4634
    71
void 
qasimj@4636
    72
NetfilterConntrackTuple::SetSource (Ipv4Address source) 
qasimj@4634
    73
{
qasimj@4637
    74
  m_l3Source = source;
qasimj@4634
    75
}
qasimj@4634
    76
qasimj@4634
    77
void 
qasimj@4636
    78
NetfilterConntrackTuple::SetSourcePort (uint16_t port)
qasimj@4634
    79
{
qasimj@4637
    80
  m_l4Source = port;
qasimj@4634
    81
}
qasimj@4634
    82
qasimj@4634
    83
void 
qasimj@4636
    84
NetfilterConntrackTuple::SetDestination (Ipv4Address destination) 
qasimj@4634
    85
{
qasimj@4637
    86
  m_l3Destination = destination;
qasimj@4634
    87
}
qasimj@4634
    88
qasimj@4634
    89
void 
qasimj@4636
    90
NetfilterConntrackTuple::SetDestinationPort (uint16_t destination) 
qasimj@4634
    91
{
qasimj@4637
    92
  m_l4Destination = destination;
qasimj@4634
    93
}
qasimj@4634
    94
qasimj@4634
    95
Ipv4Address 
qasimj@4636
    96
NetfilterConntrackTuple::GetDestination () const
qasimj@4634
    97
{
qasimj@4637
    98
  return m_l3Destination;
qasimj@4634
    99
}
qasimj@4634
   100
qasimj@4634
   101
uint16_t 
qasimj@4636
   102
NetfilterConntrackTuple::GetSourcePort () const
qasimj@4634
   103
{
qasimj@4637
   104
  return m_l4Source;
qasimj@4634
   105
}
qasimj@4634
   106
qasimj@4634
   107
uint16_t 
qasimj@4636
   108
NetfilterConntrackTuple::GetDestinationPort () const
qasimj@4634
   109
{
qasimj@4637
   110
  return m_l4Destination;
qasimj@4634
   111
}
qasimj@4634
   112
qasimj@4634
   113
uint16_t 
qasimj@4636
   114
NetfilterConntrackTuple::GetDestinationProtocol () const
qasimj@4634
   115
{
qasimj@4637
   116
  return m_protocolNumber;
qasimj@4634
   117
}
qasimj@4634
   118
qasimj@4634
   119
void 
qasimj@4636
   120
NetfilterConntrackTuple::SetProtocol (uint16_t protocol) 
qasimj@4634
   121
{
qasimj@4637
   122
  m_l3Protocol = protocol;
qasimj@4634
   123
}
qasimj@4634
   124
qasimj@4636
   125
uint16_t NetfilterConntrackTuple::GetProtocol ()
qasimj@4634
   126
{
qasimj@4637
   127
  return m_l3Protocol;
qasimj@4634
   128
}
qasimj@4634
   129
qasimj@4634
   130
void 
qasimj@4636
   131
NetfilterConntrackTuple::SetDirection (ConntrackDirection_t direction)
qasimj@4634
   132
{
qasimj@4634
   133
  m_direction = (uint8_t)direction;
qasimj@4634
   134
}
qasimj@4634
   135
qasimj@4634
   136
uint8_t 
qasimj@4636
   137
NetfilterConntrackTuple::GetDirection () const
qasimj@4634
   138
{
qasimj@4634
   139
  return m_direction;
qasimj@4634
   140
}
qasimj@4634
   141
qasimj@4634
   142
char* 
qasimj@4636
   143
NetfilterConntrackTuple::ToString () const
qasimj@4634
   144
{
qasimj@4634
   145
  return (char *)this;
qasimj@4634
   146
}
qasimj@4634
   147
qasimj@4634
   148
NetfilterConntrackTuple 
qasimj@4636
   149
NetfilterConntrackTuple::Invert ()
qasimj@4634
   150
{
qasimj@4636
   151
  NetfilterConntrackTuple inverse (GetDestination (), GetDestinationPort (), GetSource (), GetSourcePort ());
qasimj@4636
   152
  inverse.SetDirection (this->GetDirection () == IP_CT_DIR_ORIGINAL ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL);
qasimj@4634
   153
  return inverse;
qasimj@4634
   154
}
qasimj@4634
   155
qasimj@4634
   156
void 
qasimj@4634
   157
NetfilterConntrackTuple::Print (std::ostream &os) const
qasimj@4634
   158
{
qasimj@4636
   159
  os << "( " << GetSource () << "," << GetSourcePort () << "," << GetDestination () << "," << GetDestinationPort () << (int)GetDirection () << ")";
qasimj@4634
   160
}
qasimj@4634
   161
qasimj@4638
   162
NetfilterConntrackTuple&
qasimj@4638
   163
NetfilterConntrackTuple::operator= (const NetfilterConntrackTuple&  tuple)
qasimj@4638
   164
{
qasimj@4638
   165
  if (this != &tuple)
qasimj@4638
   166
  {
qasimj@4638
   167
    m_l3Source = tuple.m_l3Source;
qasimj@4638
   168
    m_l4Source = tuple.m_l4Source;
qasimj@4638
   169
    m_l3Destination = tuple.m_l3Destination;
qasimj@4638
   170
    m_l4Destination = tuple.m_l4Destination;
qasimj@4638
   171
qasimj@4638
   172
    m_l3Protocol = tuple.m_l3Protocol;
qasimj@4638
   173
    m_protocolNumber = tuple.m_protocolNumber;
qasimj@4638
   174
    m_direction = tuple.m_direction;
qasimj@4638
   175
  }
qasimj@4638
   176
qasimj@4638
   177
  return *this;
qasimj@4638
   178
}
qasimj@4638
   179
qasimj@4638
   180
std::ostream& operator << (std::ostream& os, NetfilterConntrackTuple const& tuple)
qasimj@4638
   181
{
qasimj@4638
   182
  os << "( " << tuple.GetSource () << "," << tuple.GetSourcePort () << "," << tuple.GetDestination () << "," << tuple.GetDestinationPort () << ", " << (int)tuple.GetDirection () << ")";
qasimj@4638
   183
  return os;
qasimj@4638
   184
}
qasimj@4638
   185
qasimj@4634
   186
#define JHASH_GOLDEN_RATIO  0x9e3779b9
qasimj@4634
   187
qasimj@4634
   188
void 
qasimj@4636
   189
JHashMix (uint32_t a, uint32_t b, uint32_t c)
qasimj@4634
   190
{
qasimj@4634
   191
  a -= b; a -= c; a ^= (c>>13);
qasimj@4634
   192
  b -= c; b -= a; b ^= (a<<8);
qasimj@4634
   193
  c -= a; c -= b; c ^= (b>>13);
qasimj@4634
   194
  a -= b; a -= c; a ^= (c>>12);
qasimj@4634
   195
  b -= c; b -= a; b ^= (a<<16);
qasimj@4634
   196
  c -= a; c -= b; c ^= (b>>5);
qasimj@4634
   197
  a -= b; a -= c; a ^= (c>>3);
qasimj@4634
   198
  b -= c; b -= a; b ^= (a<<10);
qasimj@4634
   199
  c -= a; c -= b; c ^= (b>>15);
qasimj@4634
   200
}
qasimj@4634
   201
qasimj@4634
   202
uint32_t 
qasimj@4636
   203
JHash2 (const uint32_t *k, uint32_t length, uint32_t initval)
qasimj@4634
   204
{
qasimj@4634
   205
  uint32_t a, b, c, len;
qasimj@4634
   206
qasimj@4634
   207
  a = b = JHASH_GOLDEN_RATIO;
qasimj@4634
   208
  c = initval;
qasimj@4634
   209
  len = length;
qasimj@4634
   210
qasimj@4634
   211
  while (len >= 3) {
qasimj@4634
   212
    a += k[0];
qasimj@4634
   213
    b += k[1];
qasimj@4634
   214
    c += k[2];
qasimj@4636
   215
    JHashMix (a, b, c);
qasimj@4634
   216
    k += 3; len -= 3;
qasimj@4634
   217
  }
qasimj@4634
   218
qasimj@4634
   219
  c += length * 4;
qasimj@4634
   220
qasimj@4634
   221
  switch (len) {
qasimj@4634
   222
    case 2 : b += k[1];
qasimj@4634
   223
    case 1 : a += k[0];
qasimj@4634
   224
  };
qasimj@4634
   225
qasimj@4636
   226
  JHashMix (a,b,c);
qasimj@4634
   227
  return c;
qasimj@4634
   228
    
qasimj@4634
   229
}
qasimj@4634
   230
qasimj@4634
   231
size_t 
qasimj@4636
   232
ConntrackTupleHash::operator() (const NetfilterConntrackTuple &x) const
qasimj@4634
   233
{
qasimj@4634
   234
  uint32_t n;
qasimj@4634
   235
  uint32_t h;
qasimj@4634
   236
  uint16_t rnd = 2;
qasimj@4634
   237
  uint32_t size = 12;
qasimj@4634
   238
qasimj@4636
   239
  n = (sizeof (x.GetSource ())+ sizeof (x.GetSourcePort ()) +
qasimj@4636
   240
        sizeof (x.GetDestination())+ sizeof (x.GetDestinationPort ()))/sizeof (uint32_t);
qasimj@4634
   241
qasimj@4636
   242
  h = JHash2 ((uint32_t*)(x.ToString ()), n, rnd ^ (((x.GetDestinationPort ()) << 16) | x.GetDestinationProtocol ()));
qasimj@4634
   243
qasimj@4636
   244
  NS_LOG_DEBUG ("Hashing ==> Tuple " <<  "( " << x.GetSource () << "," << x.GetSourcePort () << "," << x.GetDestination () << "," << x.GetDestinationPort () << "," << (int)x.GetDirection () << ")" << " Hash: " << (((uint64_t)h * size) >> 32));
qasimj@4634
   245
qasimj@4634
   246
  return ((uint64_t)h * size) >> 32;
qasimj@4634
   247
}
qasimj@4634
   248
qasimj@4634
   249
}