// This may look like C code, but it is really -*- C++ -*-
// 
// <copyright> 
//  
//  Copyright (c) 1997
//  wer auch immer ...
//  
// </copyright> 
// 
// 
// <file> 
// 
// Name:        tcpmatch.h
// 
// Purpose:     
// 
// Created:     20 Feb 1997   Joerg Faschingbauer
// 
// Modified:    
// 
// Description: 
// 
// $Id: tcpmatch.C,v 1.3 1997/02/26 19:38:40 jfasch Exp $
// 
// $Log: tcpmatch.C,v $
// Revision 1.3  1997/02/26 19:38:40  jfasch
// rewrote match() operation
//
// Revision 1.2  1997/02/21 14:06:25  jfasch
// version2
//
// Revision 1.1  1997/02/21 12:39:59  jfasch
// Initial revision
//
// 
// </file> 
#include "tcpmatch.h"

#include "assert.h"
#include "types.h"

// --------------------------------------------------------------------
const char* TCPMatch :: version2 = "TCPMatch: $Id: tcpmatch.C,v 1.3 1997/02/26 19:38:40 jfasch Exp $" ;

TCPMatch :: TCPMatch (const INETAddress& a, in_addr mask, AddrOp aop, PortOp pop) 
: addr_(a),
  mask_(mask),
  addrop_(aop),
  portop_(pop) {
     addr_.sin_addr.s_addr &= mask_.s_addr ;
}

// bool TCPMatch :: match (const INETAddress& a) const {
//    if ((addr_.sin_addr.s_addr == (a.sin_addr.s_addr & mask_.s_addr))
//        && addrop_ == TA_POS) {
//       // go compare ports
//       switch (portop_) {
//         case TP_G:
//            return a.port() >  addr_.port() ;
//         case TP_L:
//            return a.port() <  addr_.port() ;
//         case TP_GE:
//            return a.port() >= addr_.port() ;
//         case TP_EQ:
//            return a.port() == addr_.port() ;
//         case TP_LE:
//            return a.port() <= addr_.port() ;
//         case TP_NE:
//            return a.port() != addr_.port() ;
//       }
//       hgassert (false, "TCPMatch::match(): sucks") ; // should never get here
//       return false ;
//    }
//    else 
//       return false ;
// }

bool TCPMatch :: match (const INETAddress& a) const {
   if (addr_.sin_addr.s_addr == (a.sin_addr.s_addr & mask_.s_addr) && addrop_ == TA_POS ||
       addr_.sin_addr.s_addr != (a.sin_addr.s_addr & mask_.s_addr) && addrop_ == TA_NEG) {
      // go compare ports
      switch (portop_) {
        case TP_G:
           return a.port() >  addr_.port() ;
        case TP_L:
           return a.port() <  addr_.port() ;
        case TP_GE:
           return a.port() >= addr_.port() ;
        case TP_EQ:
           return a.port() == addr_.port() ;
        case TP_LE:
           return a.port() <= addr_.port() ;
        case TP_NE:
           return a.port() != addr_.port() ;
      }
      hgassert (false, "TCPMatch::match(): sucks") ; // should never get here
      return false ;
   }
   else 
      return false ;
}

const char* TCPMatch :: addrOpAcronym (AddrOp o) {
   switch (o) {
     case TA_NEG: return "TA_NEG" ;
     case TA_POS: return "TA_POS" ;
   }
   hgassert (false, "TCPMatch::addrOpAcronym(): sucks") ; // should never get here
   return nil ; ;
}

const char* TCPMatch :: portOpAcronym (PortOp o) {
   switch (o) {
     case TP_G: return "TP_G" ;
     case TP_L: return "TP_L" ;
     case TP_GE: return "TP_GE" ;
     case TP_EQ: return "TP_EQ" ;
     case TP_LE: return "TP_LE" ;
     case TP_NE: return "TP_NE" ;
   }
   hgassert (false, "TCPMatch::portOpAcronym(): sucks") ; // should never get here
   return nil ;
}
