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.
343 lines
8.2 KiB
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"
|
|
|
|
// QT 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;
|
|
}
|
|
}
|
|
}
|