// // C++ Implementation: ipaddress // // Description: // // // Author: Christian Hubinger , (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 // 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 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; } } }