//
//
// C++ Implementation: $MODULE$
//
// Description:
//
//
// Author: Christian Hubinger <chubinger@gmail.com>, (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 "kmfgenericdoc.h"

// QT includes
#include <qfile.h>
#include <qdom.h>
#include <qstring.h>
#include <qstringlist.h>

// KDE includes
#include <kdebug.h>
#include <kstandarddirs.h>
#include <klocale.h>
#include <kio/netaccess.h>
#include <kio/job.h>
#include <ktrader.h>
#include <klibloader.h>

// Project includes
#include "../interfaces/kmfcompilerinterface.h"
#include "../interfaces/kmfplugin.h"
#include "kmfpluginfactory.h"
#include "kmferror.h"
#include "kmfprotocol.h"
#include "kmfnetzone.h"
#include "kmfconfig.h"
#include "ipaddress.h"


KMFGenericDoc::KMFGenericDoc( QObject* parent, const char* name ) : KMFDoc( parent, name ) {
	kdDebug() << "KMFGenericDoc::KMFGenericDoc( QObject *parent, const char *name ) : KMFDoc( parent, name )" << endl;
	m_zones.setAutoDelete( true );
	m_zone_incoming = 0;
	m_zone_outgoing = 0;
	m_zone_trusted= 0 ;
	m_zone_malicious= 0 ;
	m_zone_badClients= 0 ;
	m_zone_badServers= 0 ;
	m_allowIncomingConnections  = false;
	m_restrictOutgoingConnections = false;
	m_allowPingReply = true;
	m_limitPingReply = true;
	m_useNat = false;
	m_useMasquerade = false;
	m_logDropped  = true;
	m_limitLog  = true;
	m_logPrefix = "KMF: ";
	m_natAddress = new IPAddress(0,0,0,0);
	m_outgoingInterface = "bool:off";
	initDoc();
}


KMFGenericDoc::~KMFGenericDoc() {}

void KMFGenericDoc::clear() {
	kdDebug() << "void KMFGenericDoc::clear()" << endl;
	m_zone_incoming->clear();
	m_zone_outgoing->clear();
	m_zone_trusted->clear();
	m_zone_malicious->clear();
	m_zone_badClients->clear();
	m_zone_badServers->clear();
	m_allowIncomingConnections  = false;
	m_restrictOutgoingConnections = false;
	m_allowPingReply = true;
	m_limitPingReply = true;
	m_useNat = false;
	m_useMasquerade = false;
	m_logDropped  = true;
	m_limitLog  = true;
	m_logPrefix = "KMF: ";
	m_natAddress->setAddress( 0, 0, 0, 0 );
	m_outgoingInterface = "bool:off";
	m_name = i18n("Unamed Ruleset");
	m_description = i18n("No description available");
}

void KMFGenericDoc::initDoc() {
	kdDebug() << "void KMFGenericDoc::initDoc()" << endl;
	m_err = new KMFError;
	m_url.setFileName( i18n( "Untitled" ) );

	if ( ! loadProtocolLibrary() )
		kdDebug() << "ERROR: Couldn't load protocol Library" << endl;

	if ( ! loadCustomProtocolLibrary() )
		kdDebug() << "ERROR: Couldn't load custom protocol Library" << endl;

	m_zone_incoming = new KMFNetZone( this,  "incoming_world" );
	m_zone_outgoing = new KMFNetZone( this,  "outgoing_world" );
	m_zone_trusted= new KMFNetZone( this,  "trusted_hosts" );
	m_zone_malicious= new KMFNetZone( this,  "malicious_hosts" );
	m_zone_badClients= new KMFNetZone( this,  "badClients_hosts" );
	m_zone_badServers= new KMFNetZone( this,  "badServers_hosts" );


	m_zone_incoming->setGuiName(  i18n( "Incoming Connections" ) );
	m_zone_outgoing->setGuiName( i18n( "Outgoing Connections" )  );
	m_zone_trusted->setGuiName( i18n( "Trusted Hosts" )  );
	m_zone_malicious->setGuiName( i18n( "Malicious Hosts" )  );
	m_zone_badClients->setGuiName( i18n( "Forbidden Clients" )  );
	m_zone_badServers->setGuiName( i18n( "Forbidden Servers" )  );

	m_zone_incoming->setZone( IPAddress( 0, 0, 0, 0 ), 0 );
	m_zone_outgoing->setZone( IPAddress( 0, 0, 0, 0 ), 0 );
	m_zone_trusted->setZone( IPAddress( 0, 0, 0, 0 ), 0 );
	m_zone_malicious->setZone( IPAddress( 0, 0, 0, 0 ), 0 );
	m_zone_badClients->setZone( IPAddress( 0, 0, 0, 0 ),0 );
	m_zone_badServers->setZone( IPAddress( 0, 0, 0, 0 ), 0 );

	m_zone_incoming->setDescription( i18n( "This is the global zone that contains\n"
																"all valid IP addresses." ) );
	m_zone_outgoing->setDescription( i18n( "This is the global zone that contains\n"
																"all valid IP addresses." ) );
	m_zone_trusted->setDescription( i18n(   "Traffic coming from and going to hosts\n"
																"will  be accepted always.\n"
																"Only add really trusted Hosts to this Zone" ) );
	m_zone_malicious->setDescription( i18n("Traffic coming from and going to hosts\n"
																"will  be dropped always." ) );
	m_zone_badClients->setDescription( i18n( 	"Hosts in this zone will not be able\n"
																	"to use services your computer provides." ) );
	m_zone_badServers->setDescription( i18n( "You will not be able to use the services\n"
																	"of the hosts in that list." ) );


}
void KMFGenericDoc::setRestrictOutgoingConnections( bool onoff ) {
	m_restrictOutgoingConnections = onoff;
}

void KMFGenericDoc::setAllowIncomingConnections( bool onoff ) {
	m_allowIncomingConnections = onoff;
}

void KMFGenericDoc::setLogDropped( bool onoff ) {
	m_logDropped = onoff;
}

void KMFGenericDoc::setLimitLog( bool onoff ) {
	m_limitLog = onoff;
}

void KMFGenericDoc::setLogPrefix( const QString& pre ) {
	if ( ! pre.isNull() )
		m_logPrefix = pre;
	else
		m_logPrefix = "";
}



bool KMFGenericDoc::isEmpty() {
// 	kdDebug() << "bool KMFGenericDoc::isEmpty()" << endl;
	return false;
}

void KMFGenericDoc::setAllowPingReply( bool onoff ) {
	m_allowPingReply = onoff;
}
void KMFGenericDoc::setLimitPingReply( bool onoff ){
	m_limitPingReply = onoff;
}

void KMFGenericDoc::setUseNat( bool onoff ) {
	m_useNat = onoff;
}

void KMFGenericDoc::setUseMasquerade( bool onoff ) {
	m_useMasquerade = onoff;
}

// void KMFGenericDoc::setRestrictNat( bool onoff ) {
// 	m_restrictNat = onoff;
// }

void KMFGenericDoc::setNatAddress( const QString& addr ) {
	m_natAddress->setAddress( addr );
}

// void KMFGenericDoc::setAllowedIncomingInterfaces( const QString& str ) {
// 	m_allowedIncomingInterfaces.clear();
// 	m_allowedIncomingInterfaces = QStringList::split("|",str,false );
// }

// bool KMFGenericDoc::isAllowedIncomingInterface( const QString& interf ) {
// 	for ( QStringList::Iterator it = m_allowedIncomingInterfaces.begin(); it != m_allowedIncomingInterfaces.end(); ++it ) {
// 		if ( *it  == interf ) {
// // 			kdDebug() << "KMFGenericDoc::isAllowedIncomingInterface( const QString& interf ): Found Interface: " << interf << endl;
// 			return true;
// 		}
//     }
// 	return false;
// }

// void KMFGenericDoc::addAllowedIncomingInterface( const QString& interf ) {
// 	bool found = false;
// 	for ( QStringList::Iterator it = m_allowedIncomingInterfaces.begin(); it != m_allowedIncomingInterfaces.end() && ! found; ++it ) {
// 
// 		if ( *it  == interf )
// 			found = true;
//     }
// 
// 	if ( !found ) {
// // 			kdDebug() << "KMFGenericDoc::addAllowedIncomingInterface( const QString& interf ): Adding Interface: " << interf << endl;
// 		m_allowedIncomingInterfaces << interf;
// 	}
// }


// // void KMFGenericDoc::delAllowedIncomingInterface( const QString& interf ) {
// // 	bool found = false;
// // 	for ( QStringList::Iterator it = m_allowedIncomingInterfaces.begin(); it != m_allowedIncomingInterfaces.end() && ! found; ++it ) {
// // 
// // 		if ( *it  == interf ) {
// // // 			kdDebug() << "KMFGenericDoc::delAllowedIncomingInterface( const QString& interf ): Removeing Interface: " << interf << endl;
// // 			m_allowedIncomingInterfaces.remove( *it );
// // 			found = true;
// // 		}
// //     }
// // }

void KMFGenericDoc::setOutgoingInterface( const QString& str ) {
	m_outgoingInterface = str;
}


QPtrList<KMFNetZone>& KMFGenericDoc::zones() const {
	QPtrList<KMFNetZone>* ret_val = new QPtrList<KMFNetZone>;
	*ret_val = m_zones;
	return *ret_val;
}

KMFNetZone* KMFGenericDoc::addZone( const QString& name, KMFError* err ) {
// 	kdDebug() << "KMFNetZone* addZone( const QString& name, KMFError* err )" << endl;
	bool found = false;
	QPtrListIterator<KMFNetZone> it ( m_zones );
	while ( it.current() && ! found ) {
		KMFNetZone * zone = it.current();
		++it;
		if ( zone->name() == name )
			found = true;
	}
	if ( found ) {
		err->setErrType( KMFError::NORMAL );
		err->setErrMsg( i18n( "<qt>Sorry, cannot create Zone with name '<b>%1</b>':<br>"
		                        "there already exists a zone with that name. Please try again"
		                        " with another name that is unique within your configuration.</qt>" ).arg(name) );
		return 0;
	}

	KMFNetZone * new_zone = new KMFNetZone( this, name );
	m_zones.append( new_zone );
	err->setErrType( KMFError::OK );
	changed();
	return new_zone;
}

KMFError* KMFGenericDoc::delZone( KMFNetZone* zone ) {
// 	kdDebug() << "KMFError* delZone( const QString& name )" << endl;
	bool found = false;
	QPtrListIterator<KMFNetZone> it ( m_zones );
	while ( it.current() && ! found ) {
		KMFNetZone * z = it.current();
		++it;
		if ( zone->name() == z->name() ) {
			found = true;
			m_zones.remove( zone );
			m_err->setErrType( KMFError::OK );
			changed();
		}
	}
	if ( ! found ) {
		m_err->setErrType( KMFError::NORMAL );
		m_err->setErrMsg( i18n( "<qt>Sorry, cannot create Zone with name: <b>%1</b>.<br>"
		                        "There already exists a zone with that name; please try again"
		                        " with another name that is unique within your configuration.</qt>" ).arg( zone->name() ) );
	}
	return m_err;
}

KMFNetZone* KMFGenericDoc::findZone( const QString& name ) const {
// 	kdDebug() << "KMFNetZone* KMFGenericDoc::findZone( const QString& name ) const" << endl;
	QPtrListIterator<KMFNetZone> it ( m_zones );
	while ( it.current() ) {
		KMFNetZone *z = it.current();
		++it;
		if ( z->name() == name )
			return z;
	}
	return 0;
}

bool KMFGenericDoc::loadProtocolLibrary() {
// 	kdDebug() << "bool KMFGenericDoc::loadProtocolLibrary()" << endl;
	KStandardDirs std_dir;
	QString file = std_dir.findResource( "data", "kmyfirewall/protocols/kmfprotocollibrary.xml" );
// 	kdDebug () << "Found Library at:" << file << endl;
	QFile kmfrsFile( file );
	QDomDocument domTree;
	if ( !kmfrsFile.open( IO_ReadOnly ) ) {
		kdDebug() << "Couldn't open file" << endl;
		return false;
	}
	if ( !domTree.setContent( &kmfrsFile ) ) {
		kdDebug() << "Couldn't set DomDocument content" << endl;
		kmfrsFile.close();
		return false;
	}
	kmfrsFile.close();

	QDomElement root = domTree.documentElement();
	QDomNode curr = root.firstChild();
	while ( !curr.isNull() ) {
// 		kdDebug() << "Parsing Node: " << curr.nodeName() << endl;
		if ( curr.isElement() && curr.nodeName() == "protocol" ) {
			KMFProtocol * prot = new KMFProtocol( this );
			QDomDocument protocol;
			protocol.appendChild( curr.cloneNode( true ) );
			prot->loadXML( protocol );
			m_protocol_library.append( prot );
		} else if ( curr.isElement() && curr.nodeName() == "abstract" ) {
			kdDebug() << "Parsing Abstract not implemented" << endl;
		}
		curr = curr.nextSibling();
	}
// 	kdDebug() << "Finished Parsing Protocol Library" << endl;
	return true;
}

bool KMFGenericDoc::loadCustomProtocolLibrary() {
	// FIXME: NOT IMPLEMENTED YET
// 	kdDebug() << "bool KMFGenericDoc::loadCustomProtocolLibrary()" << endl;
	KStandardDirs std_dir;
	QString file = std_dir.findResource( "data", "kmyfirewall/protocols/kmfcustomprotocollibrary.xml" );
	kdDebug () << "Found Library at:" << file << endl;
	if ( file.isEmpty() ) {
		kdDebug() << "INFORMATION: Creating file $KDEHOME/share/apps/kmyfirewall/protocols/kmfcustomprotocollibrary.xml" << endl;
		QString path = std_dir.findResourceDir( "data", "$KDEHOME/share/apps" );
		kdDebug() << "KDEHome dir: " << path << endl;
	}

// 	QFile kmfrsFile( file );
// 	QDomDocument domTree;
// 	if ( !kmfrsFile.open( IO_ReadOnly ) ) {
// 		kdDebug() << "Couldn't open file" << endl;
// 		return false;
// 	}
// 	if ( !domTree.setContent( &kmfrsFile ) ) {
// 		kdDebug() << "Couldn't set DomDocument content" << endl;
// 		kmfrsFile.close();
// 		return false;
// 	}
// 	kmfrsFile.close();
//
// 	QDomElement root = domTree.documentElement();
// 	QDomNode curr = root.firstChild();
// 	while ( !curr.isNull() ) {
// 		kdDebug() << "Parsing Node: " << curr.nodeName() << endl;
// 		if ( curr.isElement() && curr.nodeName() == "protocol" ) {
// 			KMFProtocol * prot = new KMFProtocol( this );
// 			QDomDocument protocol;
// 			protocol.appendChild( curr.cloneNode( true ) );
// 			prot->loadXML( protocol );
// 			m_protocol_library.append( prot );
// 		} else if ( curr.isElement() && curr.nodeName() == "abstract" ) {
// 			kdDebug() << "Parsing Abstract not implemented" << endl;
// 		}
// 		curr = curr.nextSibling();
// 	}
// 	kdDebug() << "Finished Parsing Protocol Library" << endl;
	return true;
}

const QString& KMFGenericDoc::compile() {
// 	kdDebug() << "const QString& KMFGenericDoc::compile()" << endl;
	KMFCompilerInterface* compiler = KMFPluginFactory::KMFCompiler( KMFConfig::oS(), KMFConfig::backend()   /* "linux", "iptables" */, parent() );
	if ( ! compiler ) {
		return *( new QString("ERROR") );
	}
	return compiler->compile( this );
}

KMFDoc* KMFGenericDoc::parseXMLRuleset( const KURL& url ) {
// 	kdDebug() << "KMFDoc* KMFGenericDoc::parseXMLRuleset( const KURL& )" << endl;
	QString xmlfile;
	if ( ! KIO::NetAccess::download( url, xmlfile, 0 ) ) {
		clear();
		m_url.setFileName( i18n( "Untitled" ) );
		return this;
	}

	if ( !xmlfile.isEmpty() ) {
// 		kdDebug() << "Found xmlfile: " << xmlfile << endl;
		// delete old chainsets if there
		clear();
		QFile kmfrsFile( xmlfile );
		QDomDocument domTree;
		if ( !kmfrsFile.open( IO_ReadOnly ) ) {
			return 0;
		}
		if ( !domTree.setContent( &kmfrsFile ) ) {
			kmfrsFile.close();
			return 0;
		}
		kmfrsFile.close();

		kdDebug() << "############ Start Parsing ############" << endl;
		loadXML( domTree );
		kdDebug() << "########## Finished Parsing ###########" << endl;

		setUrl( url );
		emit documentChanged();
		KIO::NetAccess::removeTempFile( xmlfile );
		return this;
	}
	KIO::NetAccess::removeTempFile( xmlfile );
	return this;
}

const QDomDocument& KMFGenericDoc::getDOMTree() {
	kdDebug() << "const QDomDocument& KMFGenericDoc::getDOMTree()" << endl;
	QDomDocument doc( "kmyfirewall-ruleset" );
	QDomElement root = doc.createElement( "kmfgrs" );

	root.appendChild( m_zone_incoming->getDOMTree() );
	root.appendChild( m_zone_outgoing->getDOMTree() );
	root.appendChild( m_zone_badClients->getDOMTree() );
	root.appendChild( m_zone_badServers->getDOMTree() );
	root.appendChild( m_zone_malicious->getDOMTree() );
	root.appendChild( m_zone_trusted->getDOMTree() );
	QDomElement abstract = doc.createElement( "abstract" );
	if ( restrictOutgoingConnections() )
		abstract.setAttribute( "restrictOutgoingConnections" ,"bool:on" );
	else
		abstract.setAttribute( "restrictOutgoingConnections" ,"bool:off" );
	if ( allowIncomingConnections() )
		abstract.setAttribute( "allowIncomingConnections" ,"bool:on" );
	else
		abstract.setAttribute( "allowIncomingConnections" ,"bool:offf" );
	
	abstract.setAttribute( "description", description() );
	abstract.setAttribute( "name", name() );
	
	root.appendChild( abstract );

	QDomElement logging = doc.createElement( "logging" );
	if ( logDropped() )
		logging.setAttribute( "logDropped", "bool:on" );
	else
		logging.setAttribute( "logDropped", "bool:off" );

	if ( limitLog() )
		logging.setAttribute( "limitLog", "bool:on" );
	else
		logging.setAttribute( "limitLog", "bool:off" );

	logging.setAttribute( "logPrefix", logPrefix() );
	root.appendChild( logging );

	QDomElement icmp = doc.createElement( "icmp" );
	if ( allowPingReply() )
		icmp.setAttribute( "allowPingReply", "bool:on" );
	else
		icmp.setAttribute( "allowPingReply", "bool:off" );

	if ( limitPingReply() )
		icmp.setAttribute( "limitPingReply", "bool:on" );
	else
		icmp.setAttribute( "limitPingReply", "bool:off" );
	root.appendChild( icmp );

	QDomElement nat = doc.createElement( "nat" );
	if ( useNat() )
		nat.setAttribute( "useNat", "bool:on" );
	else
		nat.setAttribute( "useNat", "bool:off" );

	if ( useMasquerade() )
		nat.setAttribute( "useMasquerade", "bool:on" );
	else
		nat.setAttribute( "useMasquerade", "bool:off" );

// 	if ( restrictNat() )
// 		nat.setAttribute( "restrictNat", "bool:on" );
// 	else
// 		nat.setAttribute( "restrictNat", "bool:off" );

	nat.setAttribute( "natAddress", m_natAddress->toString() );
	QString allowedIn = "";

/*	for ( QStringList::Iterator it = m_allowedIncomingInterfaces.begin(); it != m_allowedIncomingInterfaces.end(); ++it ) {
        allowedIn += *it + "|";
    }*/
// 	allowedIn = allowedIn.left( allowedIn.length() - 1 );
// 	nat.setAttribute( "allowedIncomingInterfaces", allowedIn );
	nat.setAttribute( "outgoingInterface", m_outgoingInterface );

	root.appendChild( nat );

	doc.appendChild( root );
	return *( new QDomDocument( doc ) );
}

void KMFGenericDoc::loadXML( const QDomDocument& doc ) {
// 	kdDebug() << "void KMFGenericDoc::loadXML( const QDomDocument& )" << endl;
	QDomElement root = doc.documentElement();
	QDomNode curr = root.firstChild();
	while ( !curr.isNull() ) {
		kdDebug() << "Parsing Node: " << curr.nodeName() << endl;
		if ( curr.isElement() && curr.nodeName() == "netzone" ) {
			kdDebug() << "" << endl;
			QString name = "";
			name = curr.toElement().attribute( "name" );
			QDomDocument zone_doc;
			zone_doc.appendChild( curr.cloneNode(true) );
			if ( name == "incoming_world" ) {
// 				kdDebug() << "\nKMFIPTDoc: Start Parsing INCOMMING ZONES" << endl;
				m_zone_incoming->loadXML( zone_doc );
// 				kdDebug() << "KMFIPTDoc: Finished Parsing INCOMMING ZONES" << endl;
			}
			if ( name == "outgoing_world" ) {
// 				kdDebug() << "\nKMFIPTDoc: Start Parsing OUTGOING ZONES" << endl;
				m_zone_outgoing->loadXML( zone_doc );
// 				kdDebug() << "KMFIPTDoc: Finished Parsing OUTGOING ZONES" << endl;
			}
			if ( name == "trusted_hosts" ) {
// 				kdDebug() << "\nKMFIPTDoc: Start Parsing TRUSTED HOSTS" << endl;
				m_zone_trusted->loadXML( zone_doc );
// 				kdDebug() << "KMFIPTDoc: Finished Parsing TRUSTED HOSTS" << endl;
			}
			if ( name == "malicious_hosts" ) {
// 				kdDebug() << "\nKMFIPTDoc: Start Parsing MALICIOUS HOSTS" << endl;
				m_zone_malicious->loadXML( zone_doc );
// 				kdDebug() << "KMFIPTDoc: Finished Parsing MALICIOUS HOSTS" << endl;
			}
			if ( name == "badClients_hosts" ) {
// 				kdDebug() << "\nKMFIPTDoc: Start Parsing BADCLIENTS HOSTS" << endl;
				m_zone_badClients->loadXML( zone_doc );
// 				kdDebug() << "KMFIPTDoc: Finished Parsing BADCLIENTS HOSTS" << endl;
			}
			if ( name == "badServers_hosts" ) {
// 				kdDebug() << "\nKMFIPTDoc: Start Parsing BADSERVERS HOSTS" << endl;
				m_zone_badServers->loadXML( zone_doc );
// 				kdDebug() << "KMFIPTDoc: Finished Parsing BADSERVERS HOSTS" << endl;
			}
		} else if ( curr.isElement() && curr.nodeName() == "logging" ) {
// 			kdDebug() << "\nKMFIPTDoc: Start Parsing Logging" << endl;
			QString logDropped = "";
			QString limitLog = "";
			QString logPrefix = "";

			logDropped = curr.toElement().attribute( "logDropped" );
			limitLog = curr.toElement().attribute( "limitLog" );
			logPrefix = curr.toElement().attribute( "logPrefix" );

			if ( logDropped == "bool:on")
				setLogDropped( true );
			else
				setLogDropped( false );

			if ( limitLog == "bool:on")
				setLimitLog( true );
			else
				setLimitLog( false );

			setLogPrefix( logPrefix );
// 			kdDebug() << "KMFIPTDoc: Finished Parsing Logging" << endl;
		} else if ( curr.isElement() && curr.nodeName() == "icmp" ) {
// 			kdDebug() << "\nKMFIPTDoc: Start Parsing ICMP" << endl;
			QString allowPing = "";
			QString limitPing = "";
			allowPing = curr.toElement().attribute( "allowPingReply" );
			limitPing = curr.toElement().attribute( "limitPingReply" );

			if ( allowPing == "bool:on")
				setAllowPingReply( true );
			else
				setAllowPingReply( false );

			if ( limitPing == "bool:on")
				setLimitPingReply( true );
			else
				setLimitPingReply( false );

// 			kdDebug() << "KMFIPTDoc: Finished Parsing ICMP" << endl;
		} else if ( curr.isElement() && curr.nodeName() == "nat" ) {
// 			kdDebug() << "\nKMFIPTDoc: Start Parsing NAT" << endl;
			QString useNat = "";
			QString useMasquerade = "";
// 			QString restrictNat = "";
			QString natAddress = "";
// 			QString allowedIncoming = "";
			QString outgoingInterface = "";
			useNat = curr.toElement().attribute( "useNat" );
			useMasquerade = curr.toElement().attribute( "useMasquerade" );
// 			restrictNat = curr.toElement().attribute( "restrictNat" );
			natAddress = curr.toElement().attribute( "natAddress" );
// 			allowedIncoming = curr.toElement().attribute( "allowedIncomingInterfaces" );
			outgoingInterface = curr.toElement().attribute( "outgoingInterface" );



			if ( useNat == "bool:on")
				setUseNat( true );
			else
				setUseNat( false );

			if ( useMasquerade == "bool:on")
				setUseMasquerade( true );
			else
				setUseMasquerade( false );

// 			if ( restrictNat == "bool:on")
// 				setRestrictNat( true );
// 			else
// 				setRestrictNat( false );

// 			m_allowedIncomingInterfaces.clear();

// 			kdDebug() << "Loading interfaces string: " <<  allowedIncoming << endl;
/*			m_allowedIncomingInterfaces = QStringList::split("|", allowedIncoming,false);
			QString s = "";
			for ( QStringList::Iterator it = m_allowedIncomingInterfaces.begin(); it != m_allowedIncomingInterfaces.end(); ++it ) {
				s += *it + " ";
 			}*/
// 			kdDebug() << "Stored Allowed NAT interfaces: "  << s << endl;


			m_outgoingInterface = outgoingInterface;
			m_natAddress->setAddress( natAddress );
// 			kdDebug() << "Stored NAT address: " << m_natAddress->toString() << endl;
// 			kdDebug() << "KMFIPTDoc: Finished Parsing NAT" << endl;
		}else if ( curr.isElement() && curr.nodeName() == "abstract" ) {
			kdDebug() << "KMFIPTDoc: Start Parsing Abstract" << endl;
			QString allowIncomingConnections = "";
			QString restrictOutgoingConnections = "";
			QString description = "";
			QString name = "";
			allowIncomingConnections =curr.toElement().attribute( "allowIncomingConnections" );
			restrictOutgoingConnections =curr.toElement().attribute( "restrictOutgoingConnections" );
			
			description += curr.toElement().attribute( "description" );
			if ( ! description.isNull() )
				setDescription( *( new QString( description ) ) );
			
			name += curr.toElement().attribute( "name" );
			if ( ! name.isNull() )
				setName( *( new QString( name ) ) );
			
				
			if ( allowIncomingConnections == "bool:on" )
				setAllowIncomingConnections( true );
			else
				setAllowIncomingConnections( false );

			if ( restrictOutgoingConnections == "bool:on" )
				setRestrictOutgoingConnections( true );
			else
				setRestrictOutgoingConnections( false );
 			kdDebug() << "KMFIPTDoc: Finished Parsing Abstract" << endl;
		}
		curr = curr.nextSibling();
	}
}



