You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kmyfirewall/kmyfirewall/core/ipaddress.cpp

343 lines
8.2 KiB

//
// C++ Implementation: ipaddress
//
// Description:
//
//
// Author: Christian Hubinger <chubinger@irrsinnig.org>, (C) 2003
//
// Copyright: See COPYING file that comes with this distribution
//
//
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "ipaddress.h"
// TQt includes
// KDE includes
#include <kdebug.h>
// Project includes
#include "kmfcheckinput.h"
#include "kmferror.h"
#include "xmlnames.h"
using namespace std;
namespace KMF {
IPAddress::IPAddress( int fi, int se, int th, int fo ) {
m_checkInput = new KMFCheckInput();
m_err = new KMFError();
for ( int i = 0; i < NUMDIGITS; i++ ) {
m_digits[i] = 0;
}
if ( !setAddress( fi, se, th, fo ) )
kdDebug() << "ERROR: Tried to initialise IPAddress with invalid parameters." << endl;
}
IPAddress::~IPAddress() {
delete m_checkInput;
delete m_err;
}
int IPAddress::getDigit( int num ) const {
if ( num >= 4 || num < 0 )
return -1;
return m_digits[ num ];
}
IPAddress& IPAddress::plus(int num) {
// kdDebug() << "IPAddress& IPAddress::operator+( int " << num << " )" << endl;
if ( m_digits[3] + num < 256 && m_digits[3] + num > -1 ) {
m_digits[3] = m_digits[3] + num;
}
return *this;
}
int IPAddress::operator==( const IPAddress& addr ) {
// kdDebug() << "IPAddress& IPAddress::operator==( const IPAddress& addr " << addr.toString()<< " )" << endl;
bool ident = true;
int first_diff = 0;
for ( int i = 0; i < NUMDIGITS && ident; i++ ) {
if ( m_digits[i] != addr.getDigit(i) ) {
ident = false;
first_diff = i;
}
}
if ( ident )
return EQUAL;
if ( m_digits[ first_diff ] > addr.getDigit( first_diff ) )
return SMALLER;
else
return BIGGER;
}
bool IPAddress::setAddress( int fi, int se, int th, int fo ) {
if ( fi < 0 || fi > 255 || se < 0 || se > 255 || th < 0 || th > 255 || fo < 0 || fo > 255 )
return false;
m_digits[0] = fi;
m_digits[1] = se;
m_digits[2] = th;
m_digits[3] = fo;
return true;
}
bool IPAddress::setAddress( const TQString& input ) {
TQString inp = input;
m_checkInput->checkInput( inp, "IP", m_err );
if ( m_err->errType() != KMFError::OK ) {
kdDebug() << "WARNING: Given wron IP address string: " << inp << endl;
return false;
}
int pos;
TQString str_num;
bool valid = true;
int counter = 0;
while ( !inp.isEmpty() ) {
pos = inp.find( "." );
if ( pos > -1 ) {
str_num = inp.left( pos );
// kdDebug() << "IP Num Part: " << str_num << endl;
inp = inp.right( inp.length() - ( pos + 1 ) );
// kdDebug() << "Digit: " << str_num << endl;
int val = str_num.toInt();
// kdDebug() << "Val: " << val << endl;
if ( val < 0 || val > 255 ) {
valid = false;
} else {
// kdDebug() << "IPAddress: Setting digit: " << counter << " to " << val << endl;
m_digits[ counter ] = val;
counter++;
}
} else {
str_num = inp;
// kdDebug() << "IP Num Part: " << str_num << endl;
inp = "";
// kdDebug() << "Rest: " << inp << endl;
int val = str_num.toInt();
// kdDebug() << "Digit: " << val << endl;
if ( val < 0 || val > 255 ) {
valid = false;
} else {
// kdDebug() << "IPAddress: Setting digit: " << counter << " to " << val << endl;
m_digits[ counter ] = val;
counter++;
}
}
}
return true;
}
const TQString& IPAddress::toString() const {
TQString fi = "";
TQString se = "";
TQString th = "";
TQString fo = "";
return *( new TQString( fi.setNum( m_digits[0] ) + "." + se.setNum( m_digits[1] ) + "." + th.setNum( m_digits[2] ) + "." + fo.setNum( m_digits[3] ) ) );
}
// static stuff
IPAddress& IPAddress::calcNetworkMaskFromLength( int len ) {
TQValueList<int> list;
int nextOne = 0;
int digit1 = IPAddress::calcLenthToMaskDigit( len, &nextOne );
int digit2 = IPAddress::calcLenthToMaskDigit( nextOne, &nextOne );
int digit3 = IPAddress::calcLenthToMaskDigit( nextOne, &nextOne );
int digit4 = IPAddress::calcLenthToMaskDigit( nextOne, &nextOne );
list.append( digit1 );
list.append( digit2 );
list.append( digit3 );
list.append( digit4 );
IPAddress *addr = new IPAddress( digit1,digit2,digit3,digit4 );
return *addr;
}
int IPAddress::calcLenthToMaskDigit( int nMask, int *nextOne ) {
if (nMask < 1 || nMask > 32 ) {
return 0;
}
int nCalc = 0;
for (int nX = 7;nX > -1 ; nX--) {
int total=1;
for ( int j=0; j < nX; j++) {
total*=2;
}
nCalc=nCalc + total;
nMask = nMask -1;
*nextOne=nMask;
if (nMask <1) {
return nCalc;
}
}
return nCalc;
}
int IPAddress::calcLenthToMask( IPAddress& addr) {
// kdDebug() << "calcLenthToMask( " << addr.toString() << " )" << endl;
if ( ! IPAddress::isValidMask( addr ) ) {
kdDebug() << "Netmaks is not Valid!!!" << endl;
return -1;
}
int m[4];
for ( int i = 0; i< 4 ; i++ ) {
m[i] = addr.getDigit( i );
}
int mask = 0;
for (int loop=0; loop<4; loop++) {
int div = 256;
while ( div > 1) {
div = div/2;
int test = m[loop] - div;
if ( test >-1) {
mask=mask+1;
m[loop]=test;
} else {
break;
}
}
}
// kdDebug() << "Returning: " << mask << endl;
return mask;
}
bool IPAddress::isValidAddress( IPAddress& addr) {
int IP1 = addr.getDigit( 0 );
int IP2 = addr.getDigit( 1 );
int IP3 = addr.getDigit( 2 );
int IP4 = addr.getDigit( 3 );
if ((IP1 > 255) || (IP1 < 0)) {
return false;
}
if ((IP2 > 255) || (IP2 < 0)) {
return false;
}
if ((IP3 > 255) || (IP3 < 0)) {
return false;
}
if ((IP4 > 255) || (IP4 < 0)) {
return false;
}
return true;
}
bool IPAddress::isValidMask( IPAddress& addr) {
// alert(IP1+"."+IP2+"."+IP3+"."+IP4)
int IP1 = addr.getDigit( 0 );
int IP2 = addr.getDigit( 1 );
int IP3 = addr.getDigit( 2 );
int IP4 = addr.getDigit( 3 );
if ((IP1 > 255) || (IP1 < 0)) {
return false;
}
if ((IP2 > 255) || (IP2 < 0)) {
return false;
}
if ((IP3 > 255) || (IP3 < 0)) {
return false;
}
if ((IP4 > 255) || (IP4 < 0)) {
return false;
}
int IPX =5;
// find where it changes
if (IP1 < 255) {
if((IP2 > 0) || (IP3 > 0) || (IP4 > 0)) {
return false;
}
IPX = IP1;
} else {
if (IP2 < 255) {
if((IP3 > 0) || (IP4 > 0)) {
return false;
}
IPX = IP2;
} else {
if (IP3 < 255) {
if((IP4 > 0)) {
return false;
}
IPX = IP3;
} else {
IPX = IP4;
}
}
}
// determine if IPX is a good
switch (IPX) {
case 255:
case 128:
case 192:
case 224:
case 240:
case 248:
case 252:
case 254:
case 0:
return true;
default:
return false;
}
return true;
}
bool IPAddress::hostsOnSameNetwork( IPAddress& host1, IPAddress& host2, int len ) {
// kdDebug() << "IPAddress::hostsOnSameNetwork( IPAddress&, IPAddress&, int )" << endl;
IPAddress mask = IPAddress::calcNetworkMaskFromLength( len );
return ( IPAddress::hostsOnSameNetwork( host1, host2, mask ) );
}
bool IPAddress::hostsOnSameNetwork( IPAddress& host1, IPAddress& host2, IPAddress& mask ) {
kdDebug() << "IPAddress::hostsOnSameNetwork( IPAddress&, IPAddress&, int )" << endl;
kdDebug() << "Host 1: " << host1.toString() << endl;
kdDebug() << "Host 2: " << host2.toString() << endl;
kdDebug() << "Mask: " << mask.toString() << endl;
// IPAddress mask = IPAddress::calcNetworkMaskFromLength( len );
int nOctA1=host1.getDigit(0) & mask.getDigit(0);
int nOctA2=host1.getDigit(1) & mask.getDigit(1);
int nOctA3=host1.getDigit(2) & mask.getDigit(2);
int nOctA4=host1.getDigit(3) & mask.getDigit(3);
int nOctB1=host2.getDigit(0) & mask.getDigit(0);
int nOctB2=host2.getDigit(1) & mask.getDigit(1);
int nOctB3=host2.getDigit(2) & mask.getDigit(2);
int nOctB4=host2.getDigit(3) & mask.getDigit(3);
if ((nOctA1==nOctB1) && (nOctA2==nOctB2) && (nOctA3==nOctB3) && (nOctA4==nOctB4)) {
kdDebug() << "Hosts on same net." << endl;
return true;
} else {
kdDebug() << "Hosts NOT on same net." << endl;
return false;
}
}
}