  /*

  knetfilter v 1.1.3

  Copyright (C) 2000 Luigi Genoni
  		     venom@DarkStar.sns.it
  */
  

#include <qlayout.h>
#include <qmultilinedit.h>
#include <qkeycode.h>
#include <qbuttongroup.h>
#include <qlabel.h>
#include <qstring.h>
#include <qstrlist.h>
#include <strings.h>

#include <kmsgbox.h>
#include <kiconloader.h>
#include <klocale.h>

#include "knat.h"

//#include "version.h"

// interlaced facilities

// nat rules

void knetfilter::startnatRules() {

    QString firstnet, firstnetmask, firstport, firstnetwork, secondnet, secondnetmask, secondport, secondnetwork, thirdnet, thirdnetmask, thirdport, thirdnetwork, redirection, natrulepos; 

// let's check everything
    firstnet.sprintf((const char *)(firstNet->text()));
    firstnetmask.sprintf((const char *)(firstNetMask->text()));
    firstport.sprintf((const char *)(firstPort->text()));
    secondnet.sprintf((const char *)(secondNet->text()));
    secondnetmask.sprintf((const char *)(secondNetMask->text()));
    secondport.sprintf((const char *)(secondPort->text()));
    thirdnet.sprintf((const char *)(thirdNet->text()));
    thirdnetmask.sprintf((const char *)(thirdNetMask->text()));
    thirdport.sprintf((const char *)(thirdPort->text()));
    natrulepos.sprintf((const char *)(addnatRuleNumber->text()));

    if(firstnetmask.length()==0)
      {
	firstnetmask.sprintf("255.255.255.255");
      }

    if(secondnetmask.length()==0)
      {
	secondnetmask.sprintf("255.255.255.255");
      }

    if(thirdnetmask.length()==0)
      {
	thirdnetmask.sprintf("255.255.255.255");
      }

    firstnetwork.sprintf("%s/%s",(const char *)(firstNet->text()), (const char *)(firstnetmask)); 
    secondnetwork.sprintf("%s/%s",(const char *)(secondNet->text()), (const char *)(secondnetmask)); 
    thirdnetwork.sprintf("%s/%s",(const char *)(thirdNet->text()), (const char *)(thirdnetmask)); 
    
    firstport.sprintf((const char *)(firstPort->text()));
    secondport.sprintf((const char *)(secondPort->text()));
    thirdport.sprintf((const char *)(thirdPort->text()));

    redirection.sprintf("%s:%s",(const char *)(thirdnet), (const char *)(thirdport)); 

    if(thirdport.length()==0)
      {
	redirection.sprintf("%s",(const char *)(thirdnet)); 
      }
    
    
    addredirect.clearArguments();

    if(firstnet.length()==0)
      {
	firstnetwork.sprintf("0.0.0.0/0");
      }

    if(secondnet.length()==0)
      {
	secondnetwork.sprintf("0.0.0.0/0");
      }

    if((strcmp((const char *)(firstNet->text()),"0.0.0.0")==0))
      {
	firstnetwork.sprintf("0.0.0.0/0");
      }

    if((strcmp((const char *)(secondNet->text()),"0.0.0.0")==0))
      {
	secondnetwork.sprintf("0.0.0.0/0");
      }
    
    if(natrulepos.length()==0)
      {
	natruleaction="-A";
	natrulepos.sprintf("-v");
      }
    else
      {
	natruleaction="-I";
      }

// it has no meaning to privide error messages, since every NAT 
// should be possible 

      if(strcmp(natchainResult,"REDIRECT")==0)
	{
	  if(thirdnet.length()!=0)
	    { 
	      QMessageBox::critical(0, "Error",
				    "You have to supply just redirection port\nfor REDIRECT NAT.\n Leave redirection address empty!\n");
	    }
	  else
	    {
	      if(firstport.length()==0) //fp=n
		{
		  if(secondport.length()==0) //fp=n sp=n
		    {
		      addredirect << "iptables" << "-t" << "nat" << natruleaction << natchainChoice << natrulepos << "-p" << natprotocolChoice << "-s" << firstnetwork << "-d" << secondnetwork << "-j" << natchainResult << "--to" << thirdport;
		    }
		  else //fp=n sp!=n
		    {
		      addredirect << "iptables" << "-t" << "nat" << natruleaction << natchainChoice << natrulepos << "-p" << natprotocolChoice << "-s" << firstnetwork << "-d" << secondnetwork << "--destination-port" << secondport << "-j" << natchainResult << "--to" << thirdport;
		    }
		}      
	      if(firstport.length()!=0) //fp!=n
		{
		  if(secondport.length()!=0) //fp!=n sp!=n
		    {
		      addredirect << "iptables" << "-t" << "nat" << natruleaction << natchainChoice << natrulepos << "-p" << natprotocolChoice << "-s" << firstnetwork << "--source-port" << firstport << "-d" << secondnetwork << "--destination-port" << secondport << "-j" << natchainResult << "--to" << thirdport;
		    }
		  else //fp!=n sp=n 
		    {
		      addredirect << "iptables" << "-t" << "nat" << natruleaction << natchainChoice << natrulepos << "-p" << natprotocolChoice << "-s" << firstnetwork << "--source-port" << firstport << "-d" << secondnetwork << "-j" << natchainResult << "--to" << thirdport; 
		    }
		}
	    }
	}
      else
	{	  
	  if(thirdnet.length()==0)
	    { 
	      QMessageBox::critical(0, "Error",
				    "You have to supply a redirection address\nfor Destination NAT and Source NAT");
	    }
	  else
	    {
	      if(firstport.length()==0) //fp=n
		{
		  if(secondport.length()==0) //fp=n sp=n
		    {
		      addredirect << "iptables" << "-t" << "nat" << natruleaction << natchainChoice << natrulepos << "-p" << natprotocolChoice << "-s" << firstnetwork << "-d" << secondnetwork << "-j" << natchainResult << "--to" << redirection;
		    }
		  else //fp=n sp!=n
		    {
		      addredirect << "iptables" << "-t" << "nat" << natruleaction << natchainChoice << natrulepos << "-p" << natprotocolChoice << "-s" << firstnetwork << "-d" << secondnetwork << "--destination-port" << secondport << "-j" << natchainResult << "--to" << redirection;
		    }
		}      
	      if(firstport.length()!=0) //fp!=n
		{
		  if(secondport.length()!=0) //fp!=n sp!=n
		    {
		      addredirect << "iptables" << "-t" << "nat" << natruleaction << natchainChoice << natrulepos << "-p" << natprotocolChoice << "-s" << firstnetwork << "--source-port" << firstport << "-d" << secondnetwork << "--destination-port" << secondport << "-j" << natchainResult << "--to" << redirection;
		    }
		  else //fp!=n sp=n 
		    {
		      addredirect << "iptables" << "-t" << "nat" << natruleaction << natchainChoice << natrulepos << "-p" << natprotocolChoice << "-s" << firstnetwork << "--source-port" << firstport << "-d" << secondnetwork << "-j" << natchainResult << "--to" << redirection; 
		    }
		}
	    }	  
	}
      bool success=addredirect.start();
      if(success)
	statusbar->message(i18n("Running..."), 2000);
      else
	statusbar->message(i18n("Couldn't start iptables"), 2000);

  if (success) {
  statusbar->message(i18n("NAT operated"), 2000);
  QString msg;
  msg.sprintf("operated %s for %s packets",natchainResult, natprotocolChoice);
  messageLog->insertItem(msg);
  firstNet->clear();
  firstNetMask->clear();
  firstPort->clear();
  secondNet->clear();
  secondNetMask->clear();
  secondPort->clear();
  thirdNet->clear();
  thirdNetMask->clear();
  thirdPort->clear();
  addnatRuleNumber->clear();
  } else
    statusbar->message(i18n("iptables died"), 2000);
  firstNet->setFocus();
  firstNetMask->setFocus();
  firstPort->setFocus();
  secondNet->setFocus();
  secondNetMask->setFocus();
  secondPort->setFocus();
  thirdNet->setFocus();
  thirdNetMask->setFocus();
  thirdPort->setFocus();
  addnatRuleNumber->setFocus();

  }   
  
void knetfilter::stopnatRules() {

    QString firstnet, firstnetmask, firstport, firstnetwork, secondnet, secondnetmask, secondport, secondnetwork, thirdnet, thirdnetmask, thirdport, thirdnetwork, redirection, natrulepos; 

// let's check everything
    firstnet.sprintf((const char *)(firstNet->text()));
    firstnetmask.sprintf((const char *)(firstNetMask->text()));
    firstport.sprintf((const char *)(firstPort->text()));
    secondnet.sprintf((const char *)(secondNet->text()));
    secondnetmask.sprintf((const char *)(secondNetMask->text()));
    secondport.sprintf((const char *)(secondPort->text()));
    thirdnet.sprintf((const char *)(thirdNet->text()));
    thirdnetmask.sprintf((const char *)(thirdNetMask->text()));
    thirdport.sprintf((const char *)(thirdPort->text()));
    natrulepos.sprintf((const char *)(addnatRuleNumber->text()));

    if(firstnetmask.length()==0)
      {
	firstnetmask.sprintf("255.255.255.255");
      }

    if(secondnetmask.length()==0)
      {
	secondnetmask.sprintf("255.255.255.255");
      }

    if(thirdnetmask.length()==0)
      {
	thirdnetmask.sprintf("255.255.255.255");
      }

    firstnetwork.sprintf("%s/%s",(const char *)(firstNet->text()), (const char *)(firstnetmask)); 
    secondnetwork.sprintf("%s/%s",(const char *)(secondNet->text()), (const char *)(secondnetmask)); 
    thirdnetwork.sprintf("%s/%s",(const char *)(thirdNet->text()), (const char *)(thirdnetmask)); 
    
    firstport.sprintf((const char *)(firstPort->text()));
    secondport.sprintf((const char *)(secondPort->text()));
    thirdport.sprintf((const char *)(thirdPort->text()));

    redirection.sprintf("%s:%s",(const char *)(thirdnet), (const char *)(thirdport)); 

    if(thirdport.length()==0)
      {
	redirection.sprintf("%s",(const char *)(thirdnet)); 
      }
    
    
    delredirect.clearArguments();

    if(firstnet.length()==0)
      {
	firstnetwork.sprintf("0.0.0.0/0");
      }

    if(secondnet.length()==0)
      {
	secondnetwork.sprintf("0.0.0.0/0");
      }

    if((strcmp((const char *)(firstNet->text()),"0.0.0.0")==0))
      {
	firstnetwork.sprintf("0.0.0.0/0");
      }

    if((strcmp((const char *)(secondNet->text()),"0.0.0.0")==0))
      {
	secondnetwork.sprintf("0.0.0.0/0");
      }

// it has no meaning to privide error messages, since every NAT 
// should be possible 

    if(natrulepos.length()!=0)
      { 
	delredirect << "iptables" << "-t" << "nat" << "-D" << natchainChoice << natrulepos; 
      }
    else
      {
	if(strcmp(natchainResult,"REDIRECT")==0)
	  {
	    if(thirdnet.length()!=0)
	      { 
		QMessageBox::critical(0, "Error",
				      "You have to supply just redirection port\nfor REDIRECT NAT.\n Leave redirection address empty!\n");
	      }
	    else
	      {
		if(firstport.length()==0) //fp=n
		  {
		    if(secondport.length()==0) //fp=n sp=n
		      {
			delredirect << "iptables" << "-t" << "nat" << "-D" << natchainChoice << "-p" << natprotocolChoice << "-s" << firstnetwork << "-d" << secondnetwork << "-j" << natchainResult << "--to" << thirdport;
		      }
		    else //fp=n sp!=n
		      {
			delredirect << "iptables" << "-t" << "nat" << "-D" << natchainChoice << "-p" << natprotocolChoice << "-s" << firstnetwork << "-d" << secondnetwork << "--destination-port" << secondport << "-j" << natchainResult << "--to" << thirdport;
		      }
		  }      
		if(firstport.length()!=0) //fp!=n
		  {
		    if(secondport.length()!=0) //fp!=n sp!=n
		      {
			delredirect << "iptables" << "-t" << "nat" << "-D" << natchainChoice << "-p" << natprotocolChoice << "-s" << firstnetwork << "--source-port" << firstport << "-d" << secondnetwork << "--destination-port" << secondport << "-j" << natchainResult << "--to" << thirdport;
		      }
		    else //fp!=n sp=n 
		      {
			addredirect << "iptables" << "-t" << "nat" << "-D" << natchainChoice << "-p" << natprotocolChoice << "-s" << firstnetwork << "--source-port" << firstport << "-d" << secondnetwork << "-j" << natchainResult << "--to" << thirdport; 
		      }
		  }
	      }
	  }
	else
	  {	  
	    if(thirdnet.length()==0)
	      { 
		QMessageBox::critical(0, "Error",
				      "You have to supply a redirection address\nfor Destination NAT and Source NAT");
	      }
	    else
	      {
		if(firstport.length()==0) //fp=n
		  {
		    if(secondport.length()==0) //fp=n sp=n
		      {
			delredirect << "iptables" << "-t" << "nat" << "-D" << natchainChoice << "-p" << natprotocolChoice << "-s" << firstnetwork << "-d" << secondnetwork << "-j" << natchainResult << "--to" << redirection;
		      }
		    else //fp=n sp!=n
		      {
			delredirect << "iptables" << "-t" << "nat" << "-D" << natchainChoice << "-p" << natprotocolChoice << "-s" << firstnetwork << "-d" << secondnetwork << "--destination-port" << secondport << "-j" << natchainResult << "--to" << redirection;
		      }
		  }      
		if(firstport.length()!=0) //fp!=n
		  {
		    if(secondport.length()!=0) //fp!=n sp!=n
		      {
			delredirect << "iptables" << "-t" << "nat" << "-D" << natchainChoice << "-p" << natprotocolChoice << "-s" << firstnetwork << "--source-port" << firstport << "-d" << secondnetwork << "--destination-port" << secondport << "-j" << natchainResult << "--to" << redirection;
		      }
		    else //fp!=n sp=n 
		      {
			delredirect << "iptables" << "-t" << "nat" << "-D" << natchainChoice << "-p" << natprotocolChoice << "-s" << firstnetwork << "--source-port" << firstport << "-d" << secondnetwork << "-j" << natchainResult << "--to" << redirection; 
		      }
		  }
	      }	  
	  }
      };
      bool success=delredirect.start();
      if(success)
	statusbar->message(i18n("Running..."), 2000);
      else
	statusbar->message(i18n("Couldn't start iptables"), 2000);            

  if (success) {
  statusbar->message(i18n("NAT deleted"), 2000);
  QString msg;
  msg.sprintf("deleted %s for %s packets, source address %s, port %s, redirection port %s",natchainResult, natprotocolChoice, firstNet, firstPort, thirdPort);
  messageLog->insertItem(msg);
  firstNet->clear();
  firstNetMask->clear();
  firstPort->clear();
  secondNet->clear();
  secondNetMask->clear();
  secondPort->clear();
  thirdNet->clear();
  thirdNetMask->clear();
  thirdPort->clear();
  addnatRuleNumber->clear();
  } else
    statusbar->message(i18n("iptables died"), 2000);
  firstNet->setFocus();
  firstNetMask->setFocus();
  firstPort->setFocus();
  secondNet->setFocus();
  secondNetMask->setFocus();
  secondPort->setFocus();
  thirdNet->setFocus();
  thirdNetMask->setFocus();
  thirdPort->setFocus();
  addnatRuleNumber->setFocus();

}   

  
void knetfilter::natRules() {
  if ( natList == NULL )
    {
      //	  DBG(KNFDEBUG, "Creating natList");
      setupConnect();

      natList = new KNFWidget();
      natList->resize(650,260);
      natList->setCaption("Set Chains policy");

      QBoxLayout *top = new QBoxLayout(natList, QBoxLayout::LeftToRight, 10);
      QGridLayout *grid = new QGridLayout(10,10);
      top->addLayout(grid,10);
      
      QLabel *labelChainpol = new QLabel(natList);
      labelChainpol->setText("Action :");
      grid->addMultiCellWidget(labelChainpol,0,0,0,2);

      natchain = new QComboBox( FALSE, natList, "Action"); 
      natchain->insertItem("DNAT PREROUTING");
      natchain->insertItem("DNAT OUTPUT");
      natchain->insertItem("SNAT POSTROUTING");
      natchain->insertItem("REDIRECT");
      natchain->insertItem("REDIRECT OUTPUT");
      natchain->setFixedHeight(natchain->sizeHint().height());
      connect(natchain,SIGNAL(activated(int)), SLOT(natchainActivated(int)));

      grid->addMultiCellWidget(natchain,0,0,2,4);

      QLabel *labelnatProto = new QLabel(natList);
      labelnatProto->setText("Protocol :");
      grid->addMultiCellWidget(labelnatProto,2,2,0,2);

      natprotocol = new QComboBox( FALSE, natList, "protocol");
      natprotocol->insertItem("TCP Only");
      natprotocol->insertItem("UDP Only");
      connect(natprotocol,SIGNAL(activated(int)), SLOT(natprotocolActivated(int))); 
      grid->addMultiCellWidget(natprotocol,2,2,2,3);

      QLabel *labelnatRuleNumber = new QLabel(natList);
      labelnatRuleNumber->setText("Rule Position:");
      addnatRuleNumber = new QLineEdit(natList);
      addnatRuleNumber->setFixedHeight(addnatRuleNumber->sizeHint().height());
      addnatRuleNumber->setText("");

      grid->addMultiCellWidget(labelnatRuleNumber,2,2,5,6);
      grid->addMultiCellWidget(addnatRuleNumber,2,2,7,7);
      
      QLabel *labelfirstNet = new QLabel(natList);
      labelfirstNet->setText("source address:");

      QLabel *labelfirstNetMask = new QLabel(natList);
      labelfirstNetMask->setText("netmask");

      QLabel *labelfirstPort = new QLabel(natList);
      labelfirstPort->setText("port:");

      grid->addMultiCellWidget(labelfirstNet,3,3,0,2);
      grid->addMultiCellWidget(labelfirstNetMask,3,3,4,5);
      grid->addMultiCellWidget(labelfirstPort,3,3,7,7);

      firstNet = new QLineEdit(natList);
      firstNetMask = new QLineEdit(natList);
      firstPort = new QLineEdit(natList);

      firstNet->setFixedHeight(firstNet->sizeHint().height());
      firstNetMask->setFixedHeight(firstNetMask->sizeHint().height());
      firstPort->setFixedHeight(firstPort->sizeHint().height());

      grid->addMultiCellWidget(firstNet,3,3,2,3);
      grid->addMultiCellWidget(firstNetMask,3,3,5,6);
      grid->addMultiCellWidget(firstPort,3,3,8,9);

      QLabel *labelsecondNet = new QLabel(natList);
      labelsecondNet->setText("destination address:");

      QLabel *labelsecondNetMask = new QLabel(natList);
      labelsecondNetMask->setText("netmask");

      QLabel *labelsecondPort = new QLabel(natList);
      labelsecondPort->setText("port:");

      grid->addMultiCellWidget(labelsecondNet,4,4,0,2);
      grid->addMultiCellWidget(labelsecondNetMask,4,4,4,5);
      grid->addMultiCellWidget(labelsecondPort,4,4,7,7);

      secondNet = new QLineEdit(natList);
      secondNetMask = new QLineEdit(natList);
      secondPort = new QLineEdit(natList);

      secondNet->setFixedHeight(secondNet->sizeHint().height());
      secondNetMask->setFixedHeight(secondNetMask->sizeHint().height());
      secondPort->setFixedHeight(secondPort->sizeHint().height());

      grid->addMultiCellWidget(secondNet,4,4,2,3);
      grid->addMultiCellWidget(secondNetMask,4,4,5,6);
      grid->addMultiCellWidget(secondPort,4,4,8,9);

      QLabel *labelthirdNet = new QLabel(natList);
      labelthirdNet->setText("NAT address:");

      QLabel *labelthirdNetMask = new QLabel(natList);
      labelthirdNetMask->setText("netmask");

      QLabel *labelthirdPort = new QLabel(natList);
      labelthirdPort->setText("port:");

      grid->addMultiCellWidget(labelthirdNet,6,6,0,2);
      grid->addMultiCellWidget(labelthirdNetMask,6,6,4,5);
      grid->addMultiCellWidget(labelthirdPort,6,6,7,7);

      thirdNet = new QLineEdit(natList);
      thirdNetMask = new QLineEdit(natList);
      thirdPort = new QLineEdit(natList);

      thirdNet->setFixedHeight(thirdNet->sizeHint().height());
      thirdNetMask->setFixedHeight(thirdNetMask->sizeHint().height());
      thirdPort->setFixedHeight(thirdPort->sizeHint().height());

      grid->addMultiCellWidget(thirdNet,6,6,2,3);
      grid->addMultiCellWidget(thirdNetMask,6,6,5,6);
      grid->addMultiCellWidget(thirdPort,6,6,8,9);

      QPushButton *btnRules = new QPushButton(natList);
      btnRules->setText("Commit");
      btnRules->setFixedHeight(btnRules->sizeHint().height());
      connect(btnRules,SIGNAL(clicked()), this, SLOT(startnatRules()));
      grid->addWidget(btnRules,9,1);

      QPushButton *btnDelRules = new QPushButton(natList);
      btnDelRules->setText("Delete");
      btnDelRules->setFixedHeight(btnRules->sizeHint().height());
      connect(btnDelRules,SIGNAL(clicked()), this, SLOT(stopnatRules()));
      grid->addWidget(btnDelRules,9,3);

      QPushButton *btnClose = new QPushButton(natList);
      btnClose->setText("Close");
      btnClose->setFixedHeight(btnClose->sizeHint().height());
      connect(btnClose,SIGNAL(clicked()), this, SLOT(closenatRules()));
      grid->addWidget(btnClose,9,6);
      
      natList->show();
      setView(natList);
    }
  else 
    {
      if( !natList->isVisible() )
	{
	  natList->show();
	} 
      else
	{
	  QMessageBox::critical(0,"Warning", "Already Running\n");
	}
    }  
};

void knetfilter::natchainActivated(int index) {
  switch(index) {
  default:
    natchainChoice = "PREROUTING";
    natchainResult = "DNAT";
  case 0:
    natchainChoice = "PREROUTING";
    natchainResult = "DNAT";
    break;
  case 1:
    natchainChoice = "OUTPUT";
    natchainResult = "DNAT";
    break;
  case 2:
    natchainChoice = "POSTROUTING";
    natchainResult = "SNAT"; 
    break;
  case 3:
    natchainChoice = "PREROUTING";
    natchainResult = "REDIRECT";
    break;
  case 4:
    natchainChoice = "OUTPUT";
    natchainResult = "REDIRECT";
    break;
  };
};


void knetfilter::natprotocolActivated(int index) {
  switch(index) {
  default:
    natprotocolChoice = "tcp";
  case 0:
    natprotocolChoice = "tcp";
    break;
  case 1:
    natprotocolChoice = "udp";
    break;
  };
};


void knetfilter::setnatRules(KProcess *, char *data, int len) {
  if (len<0)
    return;
  static QString remainder;
  QString list;

  char dst[len+1];
  memmove(dst,data,len);
  dst[len]=0;

  list=remainder+dst;
  QStrList lines;
  int index=0;
  int newindex=0;

  while (1)
  {
    newindex=list.find('\n',index);
    if(newindex==-1) {
      remainder=list.right(list.length()-index);
      break;
    } else {
      lines.append(list.mid(index,newindex-index));
      index=newindex+1;
    };
  };
};


void knetfilter::closenatRules() {

  natList->close();

};


// nat chain policy rules
void knetfilter::startnatpolRules() {

  natpolrules.clearArguments();
  
  natpolrules << "iptables" << "-t" << "nat" << "-P" << natpolchainChoice << natchainpolicyChoice;
  
  bool success=natpolrules.start(KProcess::NotifyOnExit,
				 KProcess::AllOutput);
  if (success)     
    {
      statusbar->message(i18n("Running..."), 2000);
      QString msg; 
      msg.sprintf("Setting policy for Nat chain %s to %s\n",natpolchainChoice,natchainpolicyChoice);
    }
  else
    {
      statusbar->message(i18n("Couldn't start iptables"), 2000);
    }
};


void knetfilter::natpolRules() {
  if ( natpolList == NULL )
    {
      
      setupConnect();
      
      natpolList = new KNFWidget();
      natpolList->resize(350,120);
      natpolList->setCaption("Set NAT Chains policy");
      
      QBoxLayout *top = new QBoxLayout(natpolList, QBoxLayout::LeftToRight, 5);
      QGridLayout *grid = new QGridLayout(7,5);
      top->addLayout(grid,5);
      
      QLabel *labelChainpol = new QLabel(natpolList);
      labelChainpol->setText("Chain :");
      grid->addMultiCellWidget(labelChainpol,0,0,0,2);

      natpolchain = new QComboBox( FALSE, natpolList, "Chain"); 
      natpolchain->insertItem("PREROUTING");
      natpolchain->insertItem("POSTROUTING");
      natpolchain->insertItem("OUTPUT");
      natpolchain->setFixedHeight(natpolchain->sizeHint().height());
      connect(natpolchain,SIGNAL(activated(int)), SLOT(natpolchainActivated(int)));

      grid->addMultiCellWidget(natpolchain,0,0,2,3);

      QLabel *labelChaindef = new QLabel(natpolList);
      labelChaindef->setText("Policy :");
      grid->addMultiCellWidget(labelChaindef,1,1,0,2);

      natpolchainpolicy = new QComboBox( FALSE, natpolList, "Policy");
      natpolchainpolicy->insertItem("ACCEPT");
      natpolchainpolicy->insertItem("DROP");
      natpolchainpolicy->setFixedHeight(natpolchainpolicy->sizeHint().height());
      connect(natpolchainpolicy,SIGNAL(activated(int)), SLOT(natpolicyActivated(int))); 

      grid->addMultiCellWidget(natpolchainpolicy,1,1,2,3);

      natpolBox = new QListBox(natpolList);
      grid->addMultiCellWidget(natpolBox,3,4,0,4);

      QPushButton *btnRules = new QPushButton(natpolList);
      btnRules->setText("Commit");
      btnRules->setFixedHeight(btnRules->sizeHint().height());
      connect(btnRules,SIGNAL(clicked()), this, SLOT(startnatpolRules()));
      grid->addWidget(btnRules,6,0);

      QPushButton *btnClose = new QPushButton(natpolList);
      btnClose->setText("Close");
      btnClose->setFixedHeight(btnClose->sizeHint().height());
      connect(btnClose,SIGNAL(clicked()), this, SLOT(closenatpolRules()));
      grid->addWidget(btnClose,6,2);
      
      natpolList->show();
      setView(natpolList);
    }
  else 
    {
      if ( !natpolList->isVisible() )
	{
	  natpolList->show();
	}
      else
	{
	  QMessageBox::critical(0,"Warning", "Already Running\n");
    	}
    }
  
};

void knetfilter::natpolRulesDone() {
  if (natpolrules.normalExit() && (natpolrules.exitStatus()==0))
    statusbar->message(i18n("Setting Nat Chain Policy..."), 2000);
  else
    statusbar->message(i18n("Couldn't set Nat Chain Policy"), 2000);

};


void knetfilter::setnatpolRules(KProcess *, char *data, int len) {
  
  if (len<0)
    return;
  static QString remainder;
  QString list;

  char dst[len+1];
  memmove(dst,data,len);
  dst[len]=0;

  list=remainder+dst;
  QStrList lines;
  int index=0;
  int newindex=0;

  while (1)
  {
    newindex=list.find('\n',index);
    if(newindex==-1) {
      remainder=list.right(list.length()-index);
      break;
    } else {
      lines.append(list.mid(index,newindex-index));
      index=newindex+1;
    };
  };
 
  if(lines.count()>0)
  natpolBox->insertStrList(&lines);
  natpolBox->insertItem(remainder.data());
  natpolBox->setTopItem(natpolBox->count()-natpolBox->numItemsVisible()); 

};


void knetfilter::natpolchainActivated(int index) {
  switch(index) {
  default:
    natpolchainChoice = "PREROUTING";
  case 0:
    natpolchainChoice = "PREROUTING";
    break;
  case 1:
    natpolchainChoice = "POSTROUTING";
    break;
  case 2:
    natpolchainChoice = "OUTPUT";
    break;
  };
};


void knetfilter::natpolicyActivated(int index) {
  switch(index) {
  default:
    natchainpolicyChoice = "ACCEPT";
  case 0:
     natchainpolicyChoice = "ACCEPT";
    break;
  case 1:
     natchainpolicyChoice = "DROP";
    break;
  };
};


void knetfilter::closenatpolRules() {

  natpolList->close();

};






