  /*

  knetfilter v 1.2.0

  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"
 

// interlaced facilities

// mangle rules

void knetfilter::startmangleRules() {

    QString firstmanglenet, firstmanglenetmask, firstmangleport, firstmanglenetwork, secondmanglenet, secondmanglenetmask, secondmangleport, secondmanglenetwork, manglesyn, manglemark, manglelogname, manglerulepos; 
    // let's check everything

    firstmanglenet.sprintf((const char *)(firstmangleNet->text()));
    firstmanglenetmask.sprintf((const char *)(firstmangleNetMask->text()));
    firstmangleport.sprintf((const char *)(firstmanglePort->text()));
    secondmanglenet.sprintf((const char *)(secondmangleNet->text()));
    secondmanglenetmask.sprintf((const char *)(secondmangleNetMask->text()));
    secondmangleport.sprintf((const char *)(secondmanglePort->text()));
    manglerulepos.sprintf((const char *)(addmangleRuleNumber->text()));
    manglemark.sprintf((const char *)(mangleMark->text()));
    manglelogname.sprintf((const char*)(logName->text()));

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

    firstmanglenetwork.sprintf("%s/%s",(const char *)(firstmangleNet->text()), (const char *)(firstmanglenetmask)); 
    secondmanglenetwork.sprintf("%s/%s",(const char *)(secondmangleNet->text()), (const char *)(secondmanglenetmask)); 

    if(firstmanglenet.length()==0)
      {
	firstmanglenetwork.sprintf("0.0.0.0/0");
      }

    if(secondmanglenet.length()==0)
      {
	secondmanglenetwork.sprintf("0.0.0.0/0");
      }

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

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

    if(manglerulepos.length()==0)
      {
	mangleruleaction="-A";
	manglerulepos.sprintf("-v");
      }
    else
      {
	mangleruleaction="-I";
      }

    if (strcmp(mangleSyn,"--syn")==0)
      {
	manglesyn.sprintf("--syn");
      }
    else
      {
	manglesyn.sprintf("-v");
      }

// basically every kind of mangling should be possible
 
    addmangle.clearArguments();

    if (strcmp(mangleactionChoice,"TOS")==0)
      { 
	if (strcmp(mangleprotocolChoice,"icmp")==0)
	  {
	    if(firstmangleport.length()==0) // fp=n
	      {
		addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "TOS" << "--set-tos" << mangletosChoice;
	      }
	    else
	      {
		addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "--icmp-type" << firstmangleport << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "TOS" << "--set-tos" << mangletosChoice;
	      }
	  }	
	else
	  {
	    if(firstmangleport.length()==0) // fp=n
	      {	
		if(secondmangleport.length()==0) // fp=n sp=n
		  {
		    addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << manglesyn << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		      }
	    else // fp=n sp!=n
	      { 
		addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << manglesyn << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		  }
	      }
	    else //fp!=n
	      {	    
	    if(secondmangleport.length()==0) // fp!=n sp=n
	      {
		addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << manglesyn << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		  }
	    else // fp!=n sp!=n
	      {
		addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << manglesyn << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		  }	
	      }	
	  }
      };

    if (strcmp(mangleactionChoice,"MARK")==0)
      {
	if (manglemark.length()==0)
	  {
	    QMessageBox::critical(0, "Error",
				  "You have to supply a MARK to set.\n");
	  }
	else
	  {
	    if (strcmp(mangleprotocolChoice,"icmp")==0)
	      {
		if(firstmangleport.length()==0)
		  {
		    addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "MARK" << "--set-mark"  << manglemark; 
		  }
		else
		  {
		    addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "--icmp-type" << firstmangleport << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "MARK" << "--set-mark"  << manglemark; 
		  }
	      }
	    else
	      {
		if(firstmangleport.length()==0) // fp=n
		  {	
		    if(secondmangleport.length()==0) // fp=n sp=n
		      {
			addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "MARK" << "--set-mark"  << manglemark; 
		      }
		    else // fp=n sp!=n
		      { 
			addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "MARK" << "--set-mark"  << manglemark; 
		      }
		  }
		else // fp!=n
		  {	    
		    if(secondmangleport.length()==0) // fp!=n sp=n
		      {
			addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "-j" << "MARK" << "--set-mark"  << manglemark; 
		      }
		    else // fp!=n sp!=n
		      {
			addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "MARK" << "--set-mark"  << manglemark; 
		      }	
		  }	
	      }
	  }
      };

    if (strcmp(mangleactionChoice,"LOG")==0)
      {
	if (strcmp(mangleprotocolChoice,"icmp")==0)
	  {
	    if(firstmangleport.length()==0) // fp=n
	      {
		addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
	      }
	    else // fp!=n
	      {
		addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "--icmp-type" << firstmangleport << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
	      }
	  }
	else
	  {
	    if(firstmangleport.length()==0) // fp=n
	      {	
		if(secondmangleport.length()==0) // fp=n sp=n
		  {
		    addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		  }
		else // fp=n sp!=n
		  { 
		    addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		  }
	      }
	    else // fp!=n
	      {	    
		if(secondmangleport.length()==0) // fp!=n sp=n
		  {
		    addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		  }
		else // fp!=n sp!=n
		  {
		    addmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		  }	
	      }	
	  }	
      };

    bool success=addmangle.start();
    if(success)
      statusbar->message(i18n("Running..."), 2000);
    else
      statusbar->message(i18n("Couldn't start iptables"), 2000);

    if (success) {
      statusbar->message(i18n("MANGLE operated"), 2000);
      QString msg;
      msg.sprintf("operated %s mangle for %s to %s protocol",mangleactionChoice, manglechainChoice, mangleprotocolChoice);
      messageLog->insertItem(msg);
      firstmangleNet->clear();
      firstmangleNetMask->clear();
      firstmanglePort->clear();
      secondmangleNet->clear();
      secondmangleNetMask->clear();
      secondmanglePort->clear();
      mangleMark->clear();
      addmangleRuleNumber->clear();
      logName->setText("mangleLog");
    } else
      {
	statusbar->message(i18n("iptables died"), 2000);
      firstmangleNet->setFocus();
      firstmangleNetMask->setFocus();
      firstmanglePort->setFocus();
      secondmangleNet->setFocus();
      secondmangleNetMask->setFocus();
      secondmanglePort->setFocus();
      mangleMark->setFocus();
      addmangleRuleNumber->setFocus();
      logName->setFocus();
      }
};

void knetfilter::stopmangleRules(){

    QString firstmanglenet, firstmanglenetmask, firstmangleport, firstmanglenetwork, secondmanglenet, secondmanglenetmask, secondmangleport, secondmanglenetwork, manglesyn, manglemark, manglelogname, manglerulepos; 
    // let's check everything

    firstmanglenet.sprintf((const char *)(firstmangleNet->text()));
    firstmanglenetmask.sprintf((const char *)(firstmangleNetMask->text()));
    firstmangleport.sprintf((const char *)(firstmanglePort->text()));
    secondmanglenet.sprintf((const char *)(secondmangleNet->text()));
    secondmanglenetmask.sprintf((const char *)(secondmangleNetMask->text()));
    secondmangleport.sprintf((const char *)(secondmanglePort->text()));
    manglerulepos.sprintf((const char *)(addmangleRuleNumber->text()));
    manglemark.sprintf((const char *)(mangleMark->text()));
    manglelogname.sprintf((const char*)(logName->text()));

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

    firstmanglenetwork.sprintf("%s/%s",(const char *)(firstmangleNet->text()), (const char *)(firstmanglenetmask)); 
    secondmanglenetwork.sprintf("%s/%s",(const char *)(secondmangleNet->text()), (const char *)(secondmanglenetmask)); 

    if(firstmanglenet.length()==0)
      {
	firstmanglenetwork.sprintf("0.0.0.0/0");
      }

    if(secondmanglenet.length()==0)
      {
	secondmanglenetwork.sprintf("0.0.0.0/0");
      }

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

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

    if (strcmp(mangleSyn,"--syn")==0)
      {
	manglesyn.sprintf("--syn");
      }
    else
      {
	manglesyn.sprintf("-v");
      }

// basically every kind of mangling should be possible
 
    delmangle.clearArguments();

    if (manglerulepos.length()!=0)
      {
	delmangle << "iptables" << "-t" << "mangle" << "-D" << manglechainChoice << manglerulepos;
      }
    else
      {
	mangleruleaction="-D";
	manglerulepos="-v";
	if (strcmp(mangleactionChoice,"TOS")==0)
	  { 
	    if (strcmp(mangleprotocolChoice,"icmp")==0)
	      {
		if(firstmangleport.length()==0) // fp=n
		  {
		    delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		  }
		else
		  {
		    delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "--icmp-type" << firstmangleport << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		  }
	      }	
	    else
	      {
		if(firstmangleport.length()==0) // fp=n
		  {	
		    if(secondmangleport.length()==0) // fp=n sp=n
		      {
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << manglesyn << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		      }
		    else // fp=n sp!=n
		      { 
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << manglesyn << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		      }
		  }
		else //fp!=n
		  {	    
		    if(secondmangleport.length()==0) // fp!=n sp=n
		      {
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << manglesyn << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		      }
		    else // fp!=n sp!=n
		      {
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << manglesyn << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "TOS" << "--set-tos" << mangletosChoice;
		      }	
		  }	
	      }	    
	  };

	if (strcmp(mangleactionChoice,"MARK")==0)
	  {
	    if (manglemark.length()==0)
	      {
		QMessageBox::critical(0, "Error",
				      "You have to supply a MARK to set.\n");
	      }
	    else
	      {
		if (strcmp(mangleprotocolChoice,"icmp")==0)
		  {
		    if(firstmangleport.length()==0)
		      {
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "MARK" << "--set-mark"  << manglemark; 
		      }
		    else
		      {
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "--icmp-type" << firstmangleport << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "MARK" << "--set-mark"  << manglemark; 
		      }
		  }
		else
		  {
		    if(firstmangleport.length()==0) // fp=n
		      {	
			if(secondmangleport.length()==0) // fp=n sp=n
			  {
			    delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "MARK" << "--set-mark"  << manglemark; 
			  }
			else // fp=n sp!=n
			  { 
			    delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "MARK" << "--set-mark"  << manglemark; 
			  }
		      }
		    else // fp!=n
		      {	    
			if(secondmangleport.length()==0) // fp!=n sp=n
			  {
			    delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "-j" << "MARK" << "--set-mark"  << manglemark; 
			  }
			else // fp!=n sp!=n
			  {
			    delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "MARK" << "--set-mark"  << manglemark; 
			  }	
		      }	
		  }
	      }
	  };
	
	if (strcmp(mangleactionChoice,"LOG")==0)
	  {
	    if (strcmp(mangleprotocolChoice,"icmp")==0)
	      {
		if(firstmangleport.length()==0) // fp=n
		  {
		    delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		  }
		else // fp!=n
		  {
		    delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "--icmp-type" << firstmangleport << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		  }
	      }
	    else
	      {
		if(firstmangleport.length()==0) // fp=n
		  {	
		    if(secondmangleport.length()==0) // fp=n sp=n
		      {
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		      }
		    else // fp=n sp!=n
		      { 
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		      }
		  }
		else // fp!=n
		  {	    
		    if(secondmangleport.length()==0) // fp!=n sp=n
		      {
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		      }
		    else // fp!=n sp!=n
		      {
			delmangle << "iptables" << "-t" << "mangle" << mangleruleaction << manglechainChoice << manglerulepos << "-p" << mangleprotocolChoice << "-s" << firstmanglenetwork << "--source-port" << firstmangleport << "-d" << secondmanglenetwork << "--destination-port" << secondmangleport << "-j" << "LOG" << "--log-level" << logLevel << "--log-prefix" << manglelogname << log1 << log2 << log3;  
		      }	
		  }	
	      }	
	  }
      };

    bool success=delmangle.start();
    if(success)
      statusbar->message(i18n("Running..."), 2000);
    else
      statusbar->message(i18n("Couldn't start iptables"), 2000);

    if (success) {
      statusbar->message(i18n("MANGLE operated"), 2000);
      QString msg;
      msg.sprintf("operated %s mangle for %s to %s protocol",mangleactionChoice, manglechainChoice, mangleprotocolChoice);
      messageLog->insertItem(msg);
      firstmangleNet->clear();
      firstmangleNetMask->clear();
      firstmanglePort->clear();
      secondmangleNet->clear();
      secondmangleNetMask->clear();
      secondmanglePort->clear();
      mangleMark->clear();
      addmangleRuleNumber->clear();
      logName->setText("mangleLog");
    } else
      {
	statusbar->message(i18n("iptables died"), 2000);
      firstmangleNet->setFocus();
      firstmangleNetMask->setFocus();
      firstmanglePort->setFocus();
      secondmangleNet->setFocus();
      secondmangleNetMask->setFocus();
      secondmanglePort->setFocus();
      mangleMark->setFocus();
      addmangleRuleNumber->setFocus();
      logName->setFocus();
      }
};

void knetfilter::mangleRules() {
  if ( mangleList == NULL )
    {

      setupConnect();
      
      mangleList = new KNFWidget();
      mangleList->resize(640,380);
      mangleList->setCaption("Set Mangle Policy");

      QBoxLayout *top = new QBoxLayout(mangleList,  QBoxLayout::LeftToRight, 10);
      QGridLayout *grid = new QGridLayout(10,10);
      top->addLayout(grid,10);

      QLabel *labelChainmangle = new QLabel(mangleList);
      labelChainmangle->setText("Action:");
      grid->addMultiCellWidget(labelChainmangle,0,0,0,2);
      
      manglechain = new QComboBox( FALSE, mangleList, "Action");
      manglechain->insertItem("PREROUTING");
      manglechain->insertItem("OUTPUT");
      manglechain->setFixedHeight(manglechain->sizeHint().height());
      connect(manglechain,SIGNAL(activated(int)), SLOT(manglechainActivated(int)));

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

      QLabel *labelmangleProto = new QLabel(mangleList);
      labelmangleProto->setText("Protocol :");
      grid->addMultiCellWidget(labelmangleProto,1,1,0,2);

      mangleprotocol = new QComboBox( FALSE, mangleList, "protocol");
      mangleprotocol->insertItem("TCP");
      mangleprotocol->insertItem("TCP (SYN packets)");
      mangleprotocol->insertItem("UDP");
      mangleprotocol->insertItem("ICMP");
      connect(mangleprotocol,SIGNAL(activated(int)), SLOT(mangleprotocolActivated(int))); 
      grid->addMultiCellWidget(mangleprotocol,1,1,2,3);

      QLabel *labelmangleRuleNumber = new QLabel(mangleList);
      labelmangleRuleNumber->setText("Rule Position:");
      addmangleRuleNumber = new QLineEdit(mangleList);
      addmangleRuleNumber->setFixedHeight(addmangleRuleNumber->sizeHint().height());
      addmangleRuleNumber->setText("");
      
      grid->addMultiCellWidget(labelmangleRuleNumber,1,1,5,6);
      grid->addMultiCellWidget(addmangleRuleNumber,1,1,7,7);

      QLabel *labelfirstmangleNet = new QLabel(mangleList);
      labelfirstmangleNet->setText("source address:");

      QLabel *labelfirstmangleNetMask = new QLabel(mangleList);
      labelfirstmangleNetMask->setText("netmask");

      QLabel *labelfirstmanglePort = new QLabel(mangleList);
      labelfirstmanglePort->setText("port (ICMP type):");

      grid->addMultiCellWidget(labelfirstmangleNet,2,2,0,2);
      grid->addMultiCellWidget(labelfirstmangleNetMask,2,2,4,5);
      grid->addMultiCellWidget(labelfirstmanglePort,2,2,7,8);

      firstmangleNet = new QLineEdit(mangleList);
      firstmangleNetMask = new QLineEdit(mangleList);
      firstmanglePort = new QLineEdit(mangleList);

      firstmangleNet->setFixedHeight(firstmangleNet->sizeHint().height());
      firstmangleNetMask->setFixedHeight(firstmangleNetMask->sizeHint().height());
      firstmanglePort->setFixedHeight(firstmanglePort->sizeHint().height());

      grid->addMultiCellWidget(firstmangleNet,2,2,2,3);
      grid->addMultiCellWidget(firstmangleNetMask,2,2,5,6);
      grid->addMultiCellWidget(firstmanglePort,2,2,9,9);

      QLabel *labelsecondmangleNet = new QLabel(mangleList);
      labelsecondmangleNet->setText("destination address:");

      QLabel *labelsecondmangleNetMask = new QLabel(mangleList);
      labelsecondmangleNetMask->setText("netmask");

      QLabel *labelsecondmanglePort = new QLabel(mangleList);
      labelsecondmanglePort->setText("port:");

      grid->addMultiCellWidget(labelsecondmangleNet,3,3,0,2);
      grid->addMultiCellWidget(labelsecondmangleNetMask,3,3,4,5);
      grid->addMultiCellWidget(labelsecondmanglePort,3,3,7,8);

      secondmangleNet = new QLineEdit(mangleList);
      secondmangleNetMask = new QLineEdit(mangleList);
      secondmanglePort = new QLineEdit(mangleList);

      secondmangleNet->setFixedHeight(secondmangleNet->sizeHint().height());
      secondmangleNetMask->setFixedHeight(secondmangleNetMask->sizeHint().height());
      secondmanglePort->setFixedHeight(secondmanglePort->sizeHint().height());

      grid->addMultiCellWidget(secondmangleNet,3,3,2,3);
      grid->addMultiCellWidget(secondmangleNetMask,3,3,5,6);
      grid->addMultiCellWidget(secondmanglePort,3,3,9,9);


      QLabel *labelmangleAction = new QLabel(mangleList);
      labelmangleAction->setText("Flag to modify:");
      grid->addMultiCellWidget(labelmangleAction,4,4,0,1);

      mangleaction = new QComboBox (FALSE, mangleList, "Flag to modify");
      mangleaction->insertItem("TOS");
      mangleaction->insertItem("MARK");
      mangleaction->insertItem("LOG");
      mangleaction->setFixedHeight(mangleaction->sizeHint().height());
      connect(mangleaction,SIGNAL(activated(int)), SLOT(mangleactionActivated(int))); 
      grid->addMultiCellWidget(mangleaction,4,4,2,3);

      QLabel *labeladvise = new QLabel(mangleList);
      labeladvise->setText("Set the choose Flag related options, others will be ignored ");
      grid->addMultiCellWidget(labeladvise,5,5,1,9);      

      QLabel *labelmangleTos = new QLabel(mangleList);
      labelmangleTos->setText("TOS:");
      grid->addMultiCellWidget(labelmangleTos,6,6,0,1);

      mangletos = new QComboBox( FALSE, mangleList, "TOS");
      mangletos->insertItem("Normal-Service");
      mangletos->insertItem("Minimize-Delay");
      mangletos->insertItem("Maximize-Throughput");
      mangletos->insertItem("Maximize-Reliability");
      mangletos->insertItem("Minimize-Cost");
      mangletos->setFixedHeight(mangletos->sizeHint().height());
      connect(mangletos,SIGNAL(activated(int)), SLOT(mangletosActivated(int)));
      grid->addMultiCellWidget(mangletos,6,6,1,3);

      QLabel *labelmangleMark = new QLabel(mangleList);
      labelmangleMark->setText("MARK:");
      grid->addMultiCellWidget(labelmangleMark,6,6,5,6);

      mangleMark = new QLineEdit(mangleList);

      mangleMark->setFixedHeight(mangleMark->sizeHint().height());

      grid->addMultiCellWidget(mangleMark,6,6,6,7);

      QLabel *labelLog = new QLabel(mangleList);
      labelLog->setText("LOG rules:  level:");
      grid->addMultiCellWidget(labelLog,7,7,0,1);

      loglevel= new QComboBox( FALSE, mangleList, "LOG level:");
      loglevel->insertItem("0");
      loglevel->insertItem("1");
      loglevel->insertItem("2");
      loglevel->insertItem("3");
      loglevel->insertItem("4");
      loglevel->insertItem("5");
      loglevel->insertItem("6");
      loglevel->insertItem("7");
      loglevel->setFixedHeight(loglevel->sizeHint().height());
      connect(loglevel,SIGNAL(activated(int)), SLOT(manglelogLevel(int)));
      grid->addMultiCellWidget(loglevel,7,7,2,2);

      QLabel *labellogName = new QLabel(mangleList);
      labellogName->setText("LOG prefix:");
      grid->addMultiCellWidget(labellogName,7,7,4,5);

      logName = new QLineEdit(mangleList);
      logName->setText("mangleLog");
      grid->addMultiCellWidget(logName,7,7,6,7);

      QLabel *labelLog2 = new QLabel(mangleList);
      labelLog2->setText("log:");
      grid->addMultiCellWidget(labelLog2,8,8,1,1);

      manglelog1 = new QCheckBox( mangleList, "CheckBox_1" );
      manglelog1->setGeometry(8,8,8,8);
      manglelog1->setText("TCP sequence");
      manglelog1->setAutoRepeat( FALSE );
      manglelog1->setAutoResize( FALSE );
      connect(manglelog1,SIGNAL(clicked()), SLOT(log1Mode()));
      grid->addMultiCellWidget(manglelog1,8,8,2,3);
      
      manglelog2 = new QCheckBox( mangleList, "CheckBox_2" );
      manglelog2->setGeometry(8,8,8,8);
      manglelog2->setText("TCP options");
      manglelog2->setAutoRepeat( FALSE );
      manglelog2->setAutoResize( FALSE );
      connect(manglelog2,SIGNAL(clicked()), SLOT(log2Mode()));
      grid->addMultiCellWidget(manglelog2,8,8,5,6);
      
      manglelog3 = new QCheckBox( mangleList, "CheckBox_3" );
      manglelog3->setGeometry(8,8,8,8);
      manglelog3->setText("IP options");
      manglelog3->setAutoRepeat( FALSE );
      manglelog3->setAutoResize( FALSE );
      connect(manglelog3,SIGNAL(clicked()), SLOT(log3Mode()));
      grid->addMultiCellWidget(manglelog3,8,8,8,9);
      
	
      QPushButton *btnRules = new QPushButton(mangleList);
      btnRules->setText("Commit");
      btnRules->setFixedHeight(btnRules->sizeHint().height());
      connect(btnRules,SIGNAL(clicked()), this, SLOT(startmangleRules()));
      grid->addWidget(btnRules,9,1);

      QPushButton *btnDelete = new QPushButton(mangleList);
      btnDelete->setText("Delete");
      btnDelete->setFixedHeight(btnDelete->sizeHint().height());
      connect(btnDelete,SIGNAL(clicked()), this, SLOT(stopmangleRules()));
      grid->addWidget(btnDelete,9,5);

      QPushButton *btnClose = new QPushButton(mangleList);
      btnClose->setText("Close");
      btnClose->setFixedHeight(btnClose->sizeHint().height());
      connect(btnClose,SIGNAL(clicked()), this, SLOT(closemangleRules()));
      grid->addWidget(btnClose,9,7);



      mangleList->show();
      setView(mangleList);
    }
  else
    {
      if( !mangleList->isVisible() )
	{
	  mangleList->show();
	}
      else
	{
	  QMessageBox::critical(0,"Warning", "Already Running\n");
	}
    }
};

void knetfilter::manglechainActivated(int index) {
  switch(index) {
  default:
    manglechainChoice = "PREROUTING";
  case 0: 
    manglechainChoice = "PREROUTING";
    break;
  case 1:
    manglechainChoice = "OUTPUT";
    break;
  };
};

void knetfilter::mangleprotocolActivated(int index) {
  switch(index) {
  default:
    mangleprotocolChoice = "tcp";
    mangleSyn = " ";
  case 0:
    mangleprotocolChoice = "tcp";
    mangleSyn = " ";
    break;
  case 1:
    mangleprotocolChoice = "tcp";
    mangleSyn = "--syn";
    break;
  case 2:
    mangleprotocolChoice = "udp";
    mangleSyn = " ";
    break;
  case 3:
    mangleprotocolChoice = "icmp";
    mangleSyn = " ";
    break;
  };
};

void knetfilter::mangleactionActivated(int index) {
  switch(index) {
  default:
    mangleactionChoice = "TOS";
  case 0:
    mangleactionChoice = "TOS";
    break;
  case 1:
    mangleactionChoice = "MARK";
    break;
  case 2:
    mangleactionChoice = "LOG";
    break;
  };
};

void knetfilter::mangletosActivated(int index) {
  switch(index) {
  default:
    mangletosChoice = "0";
  case 0:
    mangletosChoice = "0";
    break;
  case 1:
    mangletosChoice = "16";
    break;
  case 2:
    mangletosChoice = "8";
    break;
  case 3:
    mangletosChoice = "4";
    break;
  case 4:
    mangletosChoice = "2";
    break;
  };
};

void knetfilter::manglelogLevel(int index) {
  switch(index) {
  default:
    logLevel = "0";
  case 0:
    logLevel = "0";
    break;
  case 1:
    logLevel = "1";
    break;
  case 2:
    logLevel = "2";
    break;
  case 3:
    logLevel = "3";
    break;
  case 4:
    logLevel = "4";
    break;
  case 5:
    logLevel = "5";
    break;
  case 6:
    logLevel = "6";
    break;
  case 7:
    logLevel = "7";
    break;
  };
};

void knetfilter::log1Mode() {
  if (manglelog1->isChecked())
    {
      log1="--log-tcp-sequence";
    }
  else
    {
      log1="-v";
    }
};

void knetfilter::log2Mode() {
  if (manglelog2->isChecked())
    {
      log2="--log-tcp-options";
    }
  else
    {
      log2="-v";
    }
};

void knetfilter::log3Mode() {
  if (manglelog3->isChecked())
    {
      log3="--log-ip-options";
    }
  else
    {
      log3="-v";
    }  
};

void knetfilter::setmangleRules(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::closemangleRules() {

  mangleList->close();

};


// mangle chain policy rules

void knetfilter::startmanglepolRules() {

  manglepolrules.clearArguments();
  
  manglepolrules << "iptables" << "-t" << "mangle" << "-P" << manglepolchainChoice << manglechainpolicyChoice;

  bool success=manglepolrules.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",manglepolchainChoice,manglechainpolicyChoice);
    }
  else
    {
      statusbar->message(i18n("Couldn't start iptables"), 2000);
    }

};

void knetfilter::manglepolRules() {
  if ( manglepolList == NULL )
    {

      setupConnect();

      manglepolList = new KNFWidget();
      manglepolList->resize(350,120);
      manglepolList->setCaption("set MANGLE Chains policy");
      
      QBoxLayout *top = new QBoxLayout(manglepolList, QBoxLayout::LeftToRight, 5);
      QGridLayout *grid = new QGridLayout(7,5);
      top->addLayout(grid,5);

      QLabel *labelmangleChainpol = new QLabel(manglepolList);
      labelmangleChainpol->setText("Chain :");
      grid->addMultiCellWidget(labelmangleChainpol,0,0,0,2);

      manglepolchain = new QComboBox( FALSE, manglepolList, "Chain");
      manglepolchain->insertItem("PREROUTING");
      manglepolchain->insertItem("OUTPUT");
      manglepolchain->setFixedHeight(manglepolchain->sizeHint().height());
      connect(manglepolchain,SIGNAL(activated(int)), SLOT(manglepolchainActivated(int))); 
      grid->addMultiCellWidget(manglepolchain,0,0,2,3);

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

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

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

      manglepolBox = new QListBox(manglepolList);
      grid->addMultiCellWidget(manglepolBox,3,4,0,4);

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

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

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

};

void knetfilter::setmanglepolRules(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)
  {
    manglepolBox->insertStrList(&lines);
    manglepolBox->insertItem(remainder.data());
    manglepolBox->setTopItem(manglepolBox->count()-manglepolBox->numItemsVisible()); 
  }
};

void knetfilter::manglepolchainActivated(int index) {
  switch(index) {
  default:
    manglepolchainChoice = "PREROUTING";
  case0: 
    manglepolchainChoice = "PREROUTING";
    break;
  case1:
    manglepolchainChoice = "POSTROUTING";
    break;
  };

};

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

void knetfilter::closemanglepolRules() {

  manglepolList->close();

};
