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