<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://wiki.linux360.ro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mad+ady</id>
		<title>linux360 - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://wiki.linux360.ro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mad+ady"/>
		<link rel="alternate" type="text/html" href="http://wiki.linux360.ro/index.php/Special:Contributions/Mad_ady"/>
		<updated>2026-04-19T13:28:10Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.29.2</generator>

	<entry>
		<id>http://wiki.linux360.ro/index.php?title=User:Mad_ady&amp;diff=2404</id>
		<title>User:Mad ady</title>
		<link rel="alternate" type="text/html" href="http://wiki.linux360.ro/index.php?title=User:Mad_ady&amp;diff=2404"/>
				<updated>2006-03-31T19:36:33Z</updated>
		
		<summary type="html">&lt;p&gt;Mad ady: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Nothing to see here... Move along :)&lt;/div&gt;</summary>
		<author><name>Mad ady</name></author>	</entry>

	<entry>
		<id>http://wiki.linux360.ro/index.php?title=Libipq_by_example&amp;diff=2403</id>
		<title>Libipq by example</title>
		<link rel="alternate" type="text/html" href="http://wiki.linux360.ro/index.php?title=Libipq_by_example&amp;diff=2403"/>
				<updated>2006-03-31T19:34:09Z</updated>
		
		<summary type="html">&lt;p&gt;Mad ady: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Am adaugat aici codul sursa al unui proiect facut cu libipq, cu scopul de a servi ca exemplu celor interesati. La inceputul codului sunt si instructiuni de compilare si de rulare + testare. Codul este destul de amplu comentat, asa ca ar trebui sa fie usor de urmarit, daca aveti in fata paginile de manual ale comenzilor din api-ul libipq. Comentariile sunt scrise in engleza pentru a fi de ajutor mai multor persoane...&lt;br /&gt;
&lt;br /&gt;
Multa bafta!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code type=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* netsim.c   29 Mar 2006&lt;br /&gt;
   &lt;br /&gt;
   This code is released under GPL&lt;br /&gt;
   You can modify it and do anything with it, as long as it is released under GPL.&lt;br /&gt;
   &lt;br /&gt;
   A note for people interested in learning how to use libipq: Read this mini documentation before trying to understand the code!&lt;br /&gt;
   * To understand the code, make sure you have the man page of libipq nearby and start reading from the beginning of the &lt;br /&gt;
      main() function; This is because not all functions in this file is relevant to libipq. Follow the comments and you should be fine.&lt;br /&gt;
      This project doesn't use features higher than layer 3 (IP), so I won't look into the TCP/UDP header (although it's possible). &lt;br /&gt;
      Check out this link to see another example that does this: http://www.crhc.uiuc.edu/~grier/projects/libipq.html&lt;br /&gt;
      &lt;br /&gt;
      Here is a copy of the man page: http://www.cs.princeton.edu/~nakao/libipq.htm&lt;br /&gt;
   &lt;br /&gt;
   Authors: Dumitrascu Irina (dumitrascu.irina@gmail.com)&lt;br /&gt;
                 Adrian Popa (adrian.popa.gh@gmail.com)&lt;br /&gt;
   &lt;br /&gt;
   Version: 0.1&lt;br /&gt;
   &lt;br /&gt;
   Purpose: A network simulator (delays, errors, duplicates, reorders and drops packets that are sent to it)&lt;br /&gt;
   &lt;br /&gt;
   How to compile: gcc -o netsim netsim.c -lipq  (requires libipq-dev)&lt;br /&gt;
   &lt;br /&gt;
   How to run: &lt;br /&gt;
      -consider the following network topology:&lt;br /&gt;
      &lt;br /&gt;
      |Host A|----------------------|Router|------------------------|Host B|&lt;br /&gt;
                .2                    .1          .1                     .2&lt;br /&gt;
                  10.0.0.0/24                  192.168.0.0/24&lt;br /&gt;
                  &lt;br /&gt;
      First, set an iptables rule that will send certain packets to IPQ (you need iptable_filter and ip_queue modules loaded): &lt;br /&gt;
            &lt;br /&gt;
            Router# echo &amp;quot;1&amp;quot; &amp;gt;/proc/sys/net/ipv4/ip_forward      # start routing&lt;br /&gt;
            Router# iptables -A FORWARD -p icmp --icmp-type echo-request -j QUEUE  # send all icmp echo requests to IPQ&lt;br /&gt;
            &lt;br /&gt;
      Start netsim with the option(s) you want:&lt;br /&gt;
            &lt;br /&gt;
            Router#./netsim --delay min=0,max=10,percent=30&lt;br /&gt;
            &lt;br /&gt;
      Start a ping from Host A: &lt;br /&gt;
            &lt;br /&gt;
            HostA# ping 192.168.0.2&lt;br /&gt;
      &lt;br /&gt;
      (if you get a Network Unreachable error, make sure that you have a default gw or route information about 192.168 set)&lt;br /&gt;
      You should see the results on the ping output and on the Router's screen.&lt;br /&gt;
   &lt;br /&gt;
   Common errors/troubleshooting:&lt;br /&gt;
      Command:&lt;br /&gt;
            Router$ ./netsim --drop percent=22&lt;br /&gt;
            Received an error message: 1&lt;br /&gt;
      Answer: netsim must run with root privileges&lt;br /&gt;
      &lt;br /&gt;
      Command:&lt;br /&gt;
            Router# ./netsim --drop percent=22&lt;br /&gt;
            Failed to send netlink message: Connection refused&lt;br /&gt;
      Answer: you need to load the ip_queue module (modprobe ip_queue) or set a iptables -j QUEUE rule&lt;br /&gt;
      &lt;br /&gt;
      Command:&lt;br /&gt;
            Router# ./netsim --drop percent=22&lt;br /&gt;
            Failed to create netlink socket&lt;br /&gt;
      Answer: you can't run two instances of netsim at the same time on the same machine. Kill one of them.&lt;br /&gt;
      &lt;br /&gt;
   Known bugs/errors/limitations:&lt;br /&gt;
      - can't create new packets (libipq limitation), so the duplication is done by copying the content of packet i to packet i+1 (and&lt;br /&gt;
        loosing the original content of packet i+1)&lt;br /&gt;
      - if there are multiple iptables -j QUEUE rules active, it's possible to have an unpredictible output for --reorder and --duplicate&lt;br /&gt;
        (can be fixed if you check to see that all packets that are to be reordered or duplicated come from the same iptables rule)&lt;br /&gt;
      - if you modify a packet and want it to go through, you MUST recalculate its CRC sum. Otherwise it MIGHT be dropped by the&lt;br /&gt;
        kernel, and will surely be dropped at the destination. &lt;br /&gt;
      - the percentages set in the command line are not always respected; they are respected only for a very large number of packets.&lt;br /&gt;
      - in the case of excessive delays set by the delay parameter, you might experience packet drops because the packet queue can &lt;br /&gt;
        fill up.&lt;br /&gt;
      - by default, iptables drops all packets that match a -j QUEUE rule if no ipq listener is registered (netsim isn't started)&lt;br /&gt;
        &lt;br /&gt;
   Disclaimer: This program can be DANGEROUS, so make sure that you know what you are doing before using it on a network. It &lt;br /&gt;
      was intended only as an exercise; it shouldn't be used in real life! You were warned... (If you notice network problems after you&lt;br /&gt;
      start netsim, kill it and issue a 'iptables -F' to delete all the rules)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;linux/netfilter.h&amp;gt;  //constants &lt;br /&gt;
#include &amp;lt;linux/ip.h&amp;gt;           //ip header&lt;br /&gt;
#include &amp;lt;libipq/libipq.h&amp;gt;    //libipq API&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;              //general definitions&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;             //for exit()&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;             //for command line parsing&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;               //for srand()&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;            //for usleep()&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt;            //for signal() (ctrl+c)&lt;br /&gt;
&lt;br /&gt;
#define BUFFERSIZE 2048&lt;br /&gt;
&lt;br /&gt;
void showUsage();&lt;br /&gt;
int parseCmdline(int argc, char **argv);&lt;br /&gt;
void showCmdline();&lt;br /&gt;
int validateCmdline();&lt;br /&gt;
void exitWithError(struct ipq_handle *h);&lt;br /&gt;
&lt;br /&gt;
/* A structure holding different variables set based on the command line parameters.&lt;br /&gt;
 */&lt;br /&gt;
struct {&lt;br /&gt;
   unsigned short int delay;&lt;br /&gt;
   unsigned int delay_min;&lt;br /&gt;
   unsigned int delay_max;&lt;br /&gt;
   unsigned short int delay_percent;&lt;br /&gt;
   unsigned short int drop;&lt;br /&gt;
   unsigned short int drop_percent;&lt;br /&gt;
   unsigned short int reorder;&lt;br /&gt;
   unsigned short int reorder_percent;&lt;br /&gt;
   unsigned int reorder_max;&lt;br /&gt;
   unsigned short int duplicate;&lt;br /&gt;
   unsigned short int duplicate_percent;&lt;br /&gt;
   unsigned short int error;&lt;br /&gt;
   unsigned short int error_percent;&lt;br /&gt;
   unsigned short int mangle;&lt;br /&gt;
   unsigned short int mangle_percent;&lt;br /&gt;
} cmdline;&lt;br /&gt;
&lt;br /&gt;
/*Global variables - for statistics*/&lt;br /&gt;
int total_packets=0, \&lt;br /&gt;
      delayed_packets=0, \&lt;br /&gt;
      dropped_packets=0, \&lt;br /&gt;
      duplicated_packets=0, \&lt;br /&gt;
      errored_packets=0, \&lt;br /&gt;
      reordered_packets=0, \&lt;br /&gt;
      mangled_packets=0;&lt;br /&gt;
&lt;br /&gt;
/* Method to parse the command line -&amp;gt; takes argc and argv from main and writes &lt;br /&gt;
 * flags in the structure cmdline. (This is NOT the most efficient way to do this, but hey...)&lt;br /&gt;
 * Returns 0 for success and anything else for failiure.&lt;br /&gt;
 */&lt;br /&gt;
int parseCmdline(int argc, char **argv){&lt;br /&gt;
   int i=0;&lt;br /&gt;
   for ( i = 1; i &amp;lt; argc; i++)&lt;br /&gt;
    {&lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--delay&amp;quot;)!=NULL){  //we found the delay parameter&lt;br /&gt;
          cmdline.delay=1; //set to do delay&lt;br /&gt;
          //the next parameters should contain min,max and percent&lt;br /&gt;
          if((i+1)==argc) return 1; //no more arguments&lt;br /&gt;
          char* min=strstr(argv[i+1], &amp;quot;min&amp;quot;);&lt;br /&gt;
          char* max=strstr(argv[i+1], &amp;quot;max&amp;quot;);&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(min!=NULL &amp;amp;&amp;amp; max!=NULL &amp;amp;&amp;amp; percent!=NULL){&lt;br /&gt;
             //everything is as expected&lt;br /&gt;
             char* temp=min;    //get the first parameter&lt;br /&gt;
             temp = strchr(temp, '='); //extract from '=' to the end&lt;br /&gt;
             temp = strtok(temp, &amp;quot;,&amp;quot;); //cut the first comma&lt;br /&gt;
             temp = temp +1; //cut the equal from the result&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: temp=%s\n &amp;quot;, temp);&lt;br /&gt;
             cmdline.delay_min=atoi(temp);&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: cmdline.delay_min=%d\n &amp;quot;, cmdline.delay_min);&lt;br /&gt;
             //now, for the second parameter&lt;br /&gt;
             temp = max;&lt;br /&gt;
             temp = strchr(temp, '='); //extract from '=' to the end&lt;br /&gt;
             temp = strtok(temp, &amp;quot;,&amp;quot;); //cut the first comma&lt;br /&gt;
             temp = temp +1; //cut the equal from the result&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: temp=%s\n &amp;quot;, temp);&lt;br /&gt;
             cmdline.delay_max=atoi(temp);&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: cmdline.delay_max=%d\n &amp;quot;, cmdline.delay_max);&lt;br /&gt;
             //the last parameter&lt;br /&gt;
             temp = percent;&lt;br /&gt;
             temp = strchr(temp, '='); //extract from '=' to the end&lt;br /&gt;
             temp = temp +1; //cut the equal from the result&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: temp=%s\n &amp;quot;, temp);&lt;br /&gt;
             cmdline.delay_percent=atoi(temp);&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: cmdline.delay_percent=%d\n &amp;quot;, cmdline.delay_percent);&lt;br /&gt;
             i++; //skip a parameter, because it has been parsed&lt;br /&gt;
          }//from all the NULL's&lt;br /&gt;
          else{&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;  //start over&lt;br /&gt;
       }//from --delay&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--drop&amp;quot;)!=NULL){  //we found the --drop parameter&lt;br /&gt;
          cmdline.drop=1; //set to do drop&lt;br /&gt;
          //fprintf(stderr, &amp;quot;DEBUG: i=%d, argc=%d\n &amp;quot;, i, argc);&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(percent!=NULL){&lt;br /&gt;
             percent=strchr(percent, '='); //extract from '=' to the end&lt;br /&gt;
             percent=percent+1; //cut the equal from the result&lt;br /&gt;
             cmdline.drop_percent=atoi(percent);&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: cmdline.drop_percent=%d\n &amp;quot;, cmdline.drop_percent);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --drop&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--duplicate&amp;quot;)!=NULL){  //we found --duplicate&lt;br /&gt;
          cmdline.duplicate=1; //set to do duplicate&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(percent!=NULL){&lt;br /&gt;
             percent=strchr(percent, '='); //extract from '=' to the end&lt;br /&gt;
             percent=percent+1; //cut the equal from the result&lt;br /&gt;
             cmdline.duplicate_percent=atoi(percent);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed already&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --duplicate&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--error&amp;quot;)!=NULL){  //we found --error&lt;br /&gt;
          cmdline.error=1; //set to do some error (as if internal bugs weren't enough! :)&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(percent!=NULL){&lt;br /&gt;
             percent=strchr(percent, '='); //extract from '=' to the end&lt;br /&gt;
             percent=percent+1; //cut the equal from the result&lt;br /&gt;
             cmdline.error_percent=atoi(percent);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --error&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--mangle&amp;quot;)!=NULL){  //we found mangle&lt;br /&gt;
          cmdline.mangle=1; //set to do mangle&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(percent!=NULL){&lt;br /&gt;
             percent=strchr(percent, '='); //extract from '=' to the end&lt;br /&gt;
             percent=percent+1; //cut the equal from the result&lt;br /&gt;
             cmdline.mangle_percent=atoi(percent);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed already&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --mangle&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--reorder&amp;quot;)!=NULL){  //we found reorder&lt;br /&gt;
          cmdline.reorder=1; //set to do reordering&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          char* max=strstr(argv[i+1], &amp;quot;max&amp;quot;);&lt;br /&gt;
          if(percent!=NULL &amp;amp;&amp;amp; max!=NULL){&lt;br /&gt;
             char *temp = percent;&lt;br /&gt;
             temp=strchr(temp, '='); //extract from '=' to the end of the string&lt;br /&gt;
             temp=strtok(temp, &amp;quot;,&amp;quot;); //cut what's after the comma&lt;br /&gt;
             temp=temp+1; //cut the equal from the result&lt;br /&gt;
             cmdline.reorder_percent=atoi(temp);&lt;br /&gt;
             temp=max;&lt;br /&gt;
             temp=strchr(temp, '='); //extract from '=' to the end&lt;br /&gt;
             temp=temp+1; //cut the equal from the result&lt;br /&gt;
             cmdline.reorder_max=atoi(temp);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --reorder&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Debug method, used to test if parameter parsing works as expected.&lt;br /&gt;
 */&lt;br /&gt;
void showCmdline(){&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.delay=%d&amp;quot;,cmdline.delay);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.delay_min=%d&amp;quot;,cmdline.delay_min);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.delay_max=%d&amp;quot;,cmdline.delay_max);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.delay_percent=%d&amp;quot;,cmdline.delay_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.drop=%d&amp;quot;,cmdline.drop);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.drop_percent=%d&amp;quot;,cmdline.drop_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.reorder=%d&amp;quot;,cmdline.reorder);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.reorder_percent=%d&amp;quot;,cmdline.reorder_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.reorder_max=%d&amp;quot;,cmdline.reorder_max);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.duplicate=%d&amp;quot;,cmdline.duplicate);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.duplicate_percent=%d&amp;quot;,cmdline.duplicate_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.error=%d&amp;quot;,cmdline.error);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.error_percent=%d&amp;quot;,cmdline.error_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.mangle=%d&amp;quot;,cmdline.mangle);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.mangle_percent=%d&amp;quot;,cmdline.mangle_percent);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Method that checks that the values in the structure cmdline are relevant &lt;br /&gt;
 * (ex: percent &amp;lt;100)&lt;br /&gt;
 * Returns 0 for success and anything else for failiure.&lt;br /&gt;
 */&lt;br /&gt;
int validateCmdline(){&lt;br /&gt;
   if( (cmdline.delay_min&amp;gt;cmdline.delay_max) || (cmdline.reorder_max&amp;gt;5) || (cmdline.delay_percent&amp;gt;100) \&lt;br /&gt;
      || (cmdline.drop_percent&amp;gt;100) || (cmdline.reorder_percent&amp;gt;100) || (cmdline.duplicate_percent&amp;gt;100) \&lt;br /&gt;
      || (cmdline.error_percent&amp;gt;100) || (cmdline.mangle_percent&amp;gt;100) || (cmdline.reorder_max&amp;lt;=0))&lt;br /&gt;
         return 1;&lt;br /&gt;
   else&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Method that displays the usage information (help)&lt;br /&gt;
 */&lt;br /&gt;
void showUsage(){&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim v0.1\n\nUsage: netsim OPTION...&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nOption list:&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --delay\t\t\tdelays some packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      min=TIME\t\t\tminimum delay time in ms&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      max=TIME\t\t\tmaximum delay time in ms&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be delayed&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --drop\t\t\tdrops some packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be dropped&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --duplicate\t\t\tduplicates some packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be duplicated&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --error\t\t\tcreates bit errors in some packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be errored&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --mangle\t\t\tmodifies TOS in ip header&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be mangled&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --reorder\t\t\tmodifies order of packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      max=NUMBER\t\tnumber of packets to reorder&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be duplicated&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n\nExamples:&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim --delay min=12,max=20,percent=5&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim --drop percent=3&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim --duplicate percent=3&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim --delay min=0,max=12,percent=7 --error percent=3 --duplicate percent=2\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Method used to exit cleanly in case of errors in libipq&lt;br /&gt;
 */&lt;br /&gt;
void exitWithError(struct ipq_handle *h){&lt;br /&gt;
   ipq_perror(&amp;quot;Queue Error:&amp;quot;);&lt;br /&gt;
   ipq_destroy_handle(h);&lt;br /&gt;
   exit(2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Dumps the packet in hex on the screen - used for debug&lt;br /&gt;
 */&lt;br /&gt;
void showPacket(ipq_packet_msg_t *pkt){&lt;br /&gt;
   int i=0;&lt;br /&gt;
   printf(&amp;quot;\n Raw packet: --------------------------\n&amp;quot;);&lt;br /&gt;
   for(i=0;i&amp;lt;pkt-&amp;gt;data_len;i++){&lt;br /&gt;
      printf(&amp;quot;%x &amp;quot;, pkt-&amp;gt;payload[i]);&lt;br /&gt;
   }&lt;br /&gt;
   printf(&amp;quot;\n End of raw packet ------------------&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Checksum for ip header*/&lt;br /&gt;
unsigned short checksum(unsigned short *addr, int len)&lt;br /&gt;
{&lt;br /&gt;
  int nleft=len;&lt;br /&gt;
  int sum=0;&lt;br /&gt;
  unsigned short *w=addr;&lt;br /&gt;
  unsigned short answer=0;&lt;br /&gt;
&lt;br /&gt;
while(nleft&amp;gt;1){&lt;br /&gt;
      sum+=*w++;&lt;br /&gt;
      nleft-=2;&lt;br /&gt;
}&lt;br /&gt;
if(nleft==1){&lt;br /&gt;
      *(unsigned char *)(&amp;amp;answer)=*(unsigned char *)w;&lt;br /&gt;
      sum+=answer;     &lt;br /&gt;
}&lt;br /&gt;
  sum=(sum&amp;gt;&amp;gt;16)+(sum&amp;amp;0xffff);&lt;br /&gt;
  sum+=(sum&amp;gt;&amp;gt;16);&lt;br /&gt;
  answer=~sum;&lt;br /&gt;
  return answer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*Method that calculates the percent*/&lt;br /&gt;
int doPercent(int percent){&lt;br /&gt;
   if (percent&amp;gt;0)&lt;br /&gt;
      return rand()%((int)(100/percent+0.5));&lt;br /&gt;
   else&lt;br /&gt;
      return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Handler for CTRL+C; Displays some statistics when exiting*/&lt;br /&gt;
void ctrlC(int sig){&lt;br /&gt;
   printf(&amp;quot;\nStatistics:&amp;quot;);&lt;br /&gt;
   printf(&amp;quot;\nTotal packets=%d Delayed=%d Dropped=%d\nDuplicated=%d Errored=%d Reordered=%d Mangled=%d\n&amp;quot;, \&lt;br /&gt;
         total_packets,delayed_packets, dropped_packets, duplicated_packets, errored_packets, reordered_packets, \&lt;br /&gt;
         mangled_packets);&lt;br /&gt;
   exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ---Verdict methods--- */&lt;br /&gt;
/* Can return 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *                   1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 *                   2 if the packet is to be dropped.&lt;br /&gt;
&lt;br /&gt;
/* Method that decides whether a packet should be errored */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 */&lt;br /&gt;
int doError(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.error_percent)==0){ //if we need to do error&lt;br /&gt;
      printf(&amp;quot; erroring &amp;quot;);&lt;br /&gt;
      struct iphdr *iph = ((struct iphdr *)pkt-&amp;gt;payload);  //get the ip header&lt;br /&gt;
      iph-&amp;gt;tot_len=iph-&amp;gt;tot_len+1;   //modify the ip packet length field so that the destination receives a bad CRC&lt;br /&gt;
      errored_packets++;&lt;br /&gt;
      return 1;  //send the modified packet (to be forwarded)&lt;br /&gt;
   }&lt;br /&gt;
  return 0; //nothing to do to this packet&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be delayed */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 */&lt;br /&gt;
int doDelay(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.delay_percent)==0){ //if we need to delay the packet&lt;br /&gt;
      printf(&amp;quot; delaying &amp;quot;);&lt;br /&gt;
      int ms = rand()%(cmdline.delay_max - cmdline.delay_min); //calculate this delay (randomly)&lt;br /&gt;
      ms+=cmdline.delay_min;&lt;br /&gt;
      delayed_packets++;&lt;br /&gt;
      usleep(ms*1000); //sleeping 'ms' miliseconds&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   return 0; //forward the packet normally&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be dropped */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              2 if the packet is to be dropped.&lt;br /&gt;
 */&lt;br /&gt;
int doDrop(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.drop_percent)==0){//if we need to drop this packet&lt;br /&gt;
      printf(&amp;quot; dropping &amp;quot;);&lt;br /&gt;
      dropped_packets++;&lt;br /&gt;
      return 2; //notify that it is to be dropped&lt;br /&gt;
      }&lt;br /&gt;
   return 0; //forward normally&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be reordered */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 */&lt;br /&gt;
int doReorder(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.reorder_percent)==0){ //if this packet needs to be reordered&lt;br /&gt;
      printf(&amp;quot; reordering &amp;quot;);&lt;br /&gt;
      &lt;br /&gt;
      /*here it gets tricky. To reorder, one must receive all packets and send them again in the reverse order.&lt;br /&gt;
        This is just what we do. Note that your packets will be delayed (because we're waiting for cmdline.reorder_max&lt;br /&gt;
        packets to arrive first)*/&lt;br /&gt;
      &lt;br /&gt;
      ipq_packet_msg_t *packets[]={ NULL, NULL, NULL, NULL, NULL } ; //an array to hold 5 packets (maximum).&lt;br /&gt;
      unsigned char buffer[5][BUFFERSIZE];  //local buffer&lt;br /&gt;
      int status=0, i=0;&lt;br /&gt;
      &lt;br /&gt;
      packets[0]=pkt; //copy the current (previously obtained) packet to packets[0]; This will be the last to leave&lt;br /&gt;
      reordered_packets++;&lt;br /&gt;
      printf(&amp;quot;.&amp;quot;); //display a '.' for every packet sent from now on&lt;br /&gt;
      for(i=1; i&amp;lt;cmdline.reorder_max;i++){&lt;br /&gt;
         //read the next packet&lt;br /&gt;
         status = ipq_read(h, buffer[i], BUFFERSIZE, 0);  //handle h, destination_buffer, buffer_size, timeout&lt;br /&gt;
         if (status&amp;lt;0)&lt;br /&gt;
            exitWithError(h);&lt;br /&gt;
         &lt;br /&gt;
         //determine the message type -&amp;gt; Packet or error message&lt;br /&gt;
         if(ipq_message_type(buffer[i])==NLMSG_ERROR){&lt;br /&gt;
            fprintf(stderr, &amp;quot;Received an error message in doReorder(): %d&amp;quot;, ipq_get_msgerr(buffer[i]));  //display the error.&lt;br /&gt;
         }&lt;br /&gt;
         if(ipq_message_type(buffer[i])==IPQM_PACKET){&lt;br /&gt;
            //we received an actual packet of data.&lt;br /&gt;
            pkt=ipq_get_packet(buffer[i]); //write the actual packet in pkt   &lt;br /&gt;
            total_packets++;&lt;br /&gt;
            reordered_packets++;&lt;br /&gt;
            packets[i]=pkt; //store this packet into the array, where it will be read later&lt;br /&gt;
            printf(&amp;quot;.&amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //do the reordering and set verdicts&lt;br /&gt;
      &lt;br /&gt;
      for(i=cmdline.reorder_max-1; i&amp;gt;0; i--){ //go backwards&lt;br /&gt;
         pkt=packets[i];&lt;br /&gt;
         status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_ACCEPT, pkt-&amp;gt;data_len, pkt-&amp;gt;payload); //set the verdict for each &lt;br /&gt;
                                                                                                                  //packet, until we get to the last one&lt;br /&gt;
         //fprintf(stderr, &amp;quot;*&amp;quot;);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      pkt=packets[0]; //let the main program set the verdict for the first packet.&lt;br /&gt;
      return 1; //forward the modified packet (it was copied from packets[0])&lt;br /&gt;
   }&lt;br /&gt;
   return 0; //no reordering, nothing special to do&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be duplicated */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 */&lt;br /&gt;
int doDuplicate(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.duplicate_percent)==0){//if we must duplicate this packet&lt;br /&gt;
      printf(&amp;quot; duplicating &amp;quot;);&lt;br /&gt;
      &lt;br /&gt;
      int status = 0;&lt;br /&gt;
      //showPacket(pkt);&lt;br /&gt;
      &lt;br /&gt;
      /*There's a catch about outputting new packets using libipq. Normally, libipq can't create new packets (that weren't&lt;br /&gt;
        captured by the iptables filter. So, in order to do duplication, we have to discard the next packet that arrives and &lt;br /&gt;
        overwrite its content with the content of the original packet. It works, but may hide some bugs (not tested extensivelly)*/&lt;br /&gt;
      &lt;br /&gt;
      //save this packet somewhere;&lt;br /&gt;
      ipq_packet_msg_t *new_pkt=pkt;&lt;br /&gt;
      //allow the original packet to pass (first instance)&lt;br /&gt;
      status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_ACCEPT, 0, NULL); &lt;br /&gt;
      //wait for a new packet.&lt;br /&gt;
      //read an IPQ message into buffer.&lt;br /&gt;
      unsigned char buffer[BUFFERSIZE];&lt;br /&gt;
      status = ipq_read(h, buffer, BUFFERSIZE, 0);  //handle h, destination_buffer, buffer_size, timeout&lt;br /&gt;
      if (status&amp;lt;0)&lt;br /&gt;
         exitWithError(h);&lt;br /&gt;
      &lt;br /&gt;
      //determine the message type -&amp;gt; Packet or error message&lt;br /&gt;
      if(ipq_message_type(buffer)==NLMSG_ERROR){&lt;br /&gt;
         fprintf(stderr, &amp;quot;Received an error message in doDuplicate(): %d&amp;quot;, ipq_get_msgerr(buffer));  //display the error.&lt;br /&gt;
      }&lt;br /&gt;
      if(ipq_message_type(buffer)==IPQM_PACKET){&lt;br /&gt;
         //we received an actual packet of data.&lt;br /&gt;
         total_packets++;&lt;br /&gt;
         duplicated_packets++;&lt;br /&gt;
         //replace its contents with the previous packet (so that this will be the duplicated one)&lt;br /&gt;
         pkt=ipq_get_packet(buffer); //write the actual packet in pkt&lt;br /&gt;
         long id = pkt-&amp;gt;packet_id; //ipq isn't stupid! It knows it has forwarded the packet with the old id, so we must keep &lt;br /&gt;
                                                   //the new packets id (they are unique) (the old id isn't valid after we set the verdict)&lt;br /&gt;
         pkt = new_pkt;  //overwrite the second packet with the first packet&lt;br /&gt;
         pkt-&amp;gt;packet_id = id; //use the second (valid) id&lt;br /&gt;
      }&lt;br /&gt;
      return 1; //send the second, modified packet&lt;br /&gt;
   }&lt;br /&gt;
   return 0; //nothing special to do&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be mangled */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 */&lt;br /&gt;
int doMangle(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.mangle_percent)==0){//mangle this packet?&lt;br /&gt;
   printf(&amp;quot; mangling &amp;quot;);&lt;br /&gt;
   mangled_packets++;&lt;br /&gt;
   struct iphdr *iph = ((struct iphdr *)pkt-&amp;gt;payload); //get the ip header&lt;br /&gt;
   iph-&amp;gt;tos=(__u8)24;  //modify the TOS field (can be any field) to a specific value&lt;br /&gt;
   iph-&amp;gt;check=0; //set the checksum to 0&lt;br /&gt;
   iph-&amp;gt;check=checksum((unsigned short*)iph,iph-&amp;gt;ihl*4); //compute the new checksum&lt;br /&gt;
   return 1;//forward the modified packet&lt;br /&gt;
   }&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
/* ---End of verdict methods--- /*&lt;br /&gt;
&lt;br /&gt;
/* Main method&lt;br /&gt;
 */&lt;br /&gt;
int main(int argc, char **argv){&lt;br /&gt;
   &lt;br /&gt;
   if(argc&amp;lt;3){ //not enough arguments, here's a list&lt;br /&gt;
      showUsage();&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   //register a listener for CTRL+C, so that when we stop, we get a nice statistic&lt;br /&gt;
   (void) signal(SIGINT, ctrlC);&lt;br /&gt;
   &lt;br /&gt;
   memset( &amp;amp;cmdline, 0, sizeof(cmdline)); //initialize cmdline with zeros;&lt;br /&gt;
   cmdline.reorder_max=1;   //can't be zero, or it won't be valid&lt;br /&gt;
   //showCmdline(); //Debug&lt;br /&gt;
   &lt;br /&gt;
   &lt;br /&gt;
   /*If you want to understand how libipq can be used, you shouldn't bother looking over parseCmdline() &lt;br /&gt;
   because it is irrelevant to your goal; it just parses the command line options and populates the cmdline &lt;br /&gt;
   variable.*/&lt;br /&gt;
   if(parseCmdline(argc, argv)!=0){      //write the data to cmdline&lt;br /&gt;
      showUsage();&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
   //showCmdline(); //Debug&lt;br /&gt;
   &lt;br /&gt;
   if(validateCmdline()!=0){   //check that cmdline has reasonable values&lt;br /&gt;
      showUsage();&lt;br /&gt;
      //fprintf(stderr, &amp;quot;DEBUG: Invalid parameter&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
   /*showCmdline(); //Debug&lt;br /&gt;
   exit(1);&lt;br /&gt;
   */&lt;br /&gt;
   &lt;br /&gt;
   //initialize random number generator (needed for --delay)&lt;br /&gt;
   srand( (unsigned int)time( NULL ) );&lt;br /&gt;
   unsigned char buffer[BUFFERSIZE];  //buffer for packages and ipq messages.&lt;br /&gt;
   struct ipq_handle *h;&lt;br /&gt;
   int status;&lt;br /&gt;
   &lt;br /&gt;
   //Register a handle with IPQ.&lt;br /&gt;
   h = ipq_create_handle(0, PF_INET);  //0=Flags (not used); PF_INET -&amp;gt; IPV4 &lt;br /&gt;
   if (!h)&lt;br /&gt;
      exitWithError(h);&lt;br /&gt;
   &lt;br /&gt;
   //Copy entire packets (up to BUFFERSIZE) to user-space&lt;br /&gt;
   status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFFERSIZE);&lt;br /&gt;
   if (status &amp;lt;0)&lt;br /&gt;
      exitWithError(h);&lt;br /&gt;
   &lt;br /&gt;
   //Get the packets and act on them according to the cmdline parameters&lt;br /&gt;
   //Do this in an infinite loop.&lt;br /&gt;
   do{&lt;br /&gt;
      //read an IPQ message into buffer. The IPQ message isn't the packet!!!&lt;br /&gt;
      status = ipq_read(h, buffer, BUFFERSIZE, 0);  //handle h, destination_buffer, buffer_size, timeout&lt;br /&gt;
      if (status&amp;lt;0)&lt;br /&gt;
         exitWithError(h);&lt;br /&gt;
      &lt;br /&gt;
      //determine the message type -&amp;gt; Packet or error message&lt;br /&gt;
      if(ipq_message_type(buffer)==NLMSG_ERROR){&lt;br /&gt;
         fprintf(stderr, &amp;quot;Received an error message: %d&amp;quot;, ipq_get_msgerr(buffer));  //display the error.&lt;br /&gt;
      }&lt;br /&gt;
      if(ipq_message_type(buffer)==IPQM_PACKET){&lt;br /&gt;
         //we received an actual packet of data.&lt;br /&gt;
         ipq_packet_msg_t *pkt=ipq_get_packet(buffer); //write the actual packet in pkt &lt;br /&gt;
         &lt;br /&gt;
         total_packets++;&lt;br /&gt;
         &lt;br /&gt;
         //all we have to do now is set the verdict!&lt;br /&gt;
         int verdict = 0; //allow all by default.&lt;br /&gt;
         int verdictDrop = 0, verdictDelay = 0, verdictError = 0, verdictReorder = 0, verdictDuplicate = 0, verdictMangle = 0;&lt;br /&gt;
         &lt;br /&gt;
         printf(&amp;quot;\n Packet &amp;quot;);&lt;br /&gt;
         if(cmdline.drop==1){ //if we need to drop a percent of  packets&lt;br /&gt;
            verdictDrop = doDrop(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; drop &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; cmdline.error ==1){ //if it was dropped, don't do anything else to the packet&lt;br /&gt;
            verdictError = doError(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; error &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; verdictError !=1 &amp;amp;&amp;amp; cmdline.delay ==1){ //if it was dropped or errored, don't do anything else to it&lt;br /&gt;
            verdictDelay = doDelay(h, pkt);&lt;br /&gt;
            //printf( &amp;quot; delay &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; verdictError !=1 &amp;amp;&amp;amp; cmdline.mangle ==1){&lt;br /&gt;
            verdictMangle = doMangle(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; mangle &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; verdictError !=1 &amp;amp;&amp;amp; cmdline.reorder ==1){&lt;br /&gt;
            verdictReorder = doReorder(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; reorder &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; verdictError !=1 &amp;amp;&amp;amp; cmdline.duplicate ==1){&lt;br /&gt;
            verdictDuplicate = doDuplicate(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; duplicate &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         fflush(stdin); //make sure the output is updated&lt;br /&gt;
         &lt;br /&gt;
         if(verdictDrop ==2) //we really need to drop this packet&lt;br /&gt;
            verdict = 2;&lt;br /&gt;
         else{ //we need to send a modified packet&lt;br /&gt;
            if(verdictError ==1 || verdictMangle ==1 || verdictReorder ==1 || verdictDuplicate ==1)&lt;br /&gt;
               verdict = 1;&lt;br /&gt;
            else&lt;br /&gt;
               verdict = 0; //we will send the original packet&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //we have the verdict, now enforce it!&lt;br /&gt;
         &lt;br /&gt;
         if(verdict == 0){&lt;br /&gt;
            //accept packet without modifications&lt;br /&gt;
            status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_ACCEPT, 0, NULL); &lt;br /&gt;
                                                // handle, packet id, verdict, data_size, buffer to output.&lt;br /&gt;
         }&lt;br /&gt;
         if(verdict == 1){&lt;br /&gt;
            //accept packet with modifications&lt;br /&gt;
            status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_ACCEPT, pkt-&amp;gt;data_len, pkt-&amp;gt;payload); &lt;br /&gt;
                                                // handle, packet id, verdict, data_size, buffer to output.&lt;br /&gt;
         }&lt;br /&gt;
         if(verdict == 2){&lt;br /&gt;
            //drop packet&lt;br /&gt;
            status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_DROP, 0, NULL);&lt;br /&gt;
                                                // handle, packet id, verdict, data_size, buffer to output.&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         if(status &amp;lt; 0)&lt;br /&gt;
            exitWithError(h);&lt;br /&gt;
         &lt;br /&gt;
         /*printf(&amp;quot;\nPacket ok, size=%d&amp;quot;, pkt-&amp;gt;data_len);&lt;br /&gt;
         showPacket(pkt);&lt;br /&gt;
         */&lt;br /&gt;
         &lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   } while(1);&lt;br /&gt;
   &lt;br /&gt;
   //unreachable code.&lt;br /&gt;
   ipq_destroy_handle(h);&lt;br /&gt;
   return 0;&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;/div&gt;</summary>
		<author><name>Mad ady</name></author>	</entry>

	<entry>
		<id>http://wiki.linux360.ro/index.php?title=Libipq_by_example&amp;diff=2402</id>
		<title>Libipq by example</title>
		<link rel="alternate" type="text/html" href="http://wiki.linux360.ro/index.php?title=Libipq_by_example&amp;diff=2402"/>
				<updated>2006-03-31T19:22:05Z</updated>
		
		<summary type="html">&lt;p&gt;Mad ady: Codul sursa, cu comentarii pentru un simulator de retea bazat pe libipq&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Am adaugat aici codul sursa al unui proiect facut cu libipq, cu scopul de a servi ca exemplu celor interesati. La inceputul codului sunt si instructiuni de compilare si de rulare + testare. Codul este destul de amplu comentat, asa ca ar trebui sa fie usor de urmarit, daca aveti in fata paginile de manual ale comenzilor din api-ul libipq. Comentariile sunt scrise in engleza pentru a fi de ajutor mai multor persoane...&lt;br /&gt;
&lt;br /&gt;
Multa bafta!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* netsim.c   29 Mar 2006&lt;br /&gt;
   &lt;br /&gt;
   This code is released under GPL&lt;br /&gt;
   You can modify it and do anything with it, as long as it is released under GPL.&lt;br /&gt;
   &lt;br /&gt;
   A note for people interested in learning how to use libipq: Read this mini documentation before trying to understand the code!&lt;br /&gt;
   * To understand the code, make sure you have the man page of libipq nearby and start reading from the beginning of the &lt;br /&gt;
      main() function; This is because not all functions in this file is relevant to libipq. Follow the comments and you should be fine.&lt;br /&gt;
      This project doesn't use features higher than layer 3 (IP), so I won't look into the TCP/UDP header (although it's possible). &lt;br /&gt;
      Check out this link to see another example that does this: http://www.crhc.uiuc.edu/~grier/projects/libipq.html&lt;br /&gt;
      &lt;br /&gt;
      Here is a copy of the man page: http://www.cs.princeton.edu/~nakao/libipq.htm&lt;br /&gt;
   &lt;br /&gt;
   Authors: Dumitrascu Irina (dumitrascu.irina@gmail.com)&lt;br /&gt;
                 Adrian Popa (adrian.popa.gh@gmail.com)&lt;br /&gt;
   &lt;br /&gt;
   Version: 0.1&lt;br /&gt;
   &lt;br /&gt;
   Purpose: A network simulator (delays, errors, duplicates, reorders and drops packets that are sent to it)&lt;br /&gt;
   &lt;br /&gt;
   How to compile: gcc -o netsim netsim.c -lipq  (requires libipq-dev)&lt;br /&gt;
   &lt;br /&gt;
   How to run: &lt;br /&gt;
      -consider the following network topology:&lt;br /&gt;
      &lt;br /&gt;
      |Host A|----------------------|Router|------------------------|Host B|&lt;br /&gt;
                .2                    .1          .1                     .2&lt;br /&gt;
                  10.0.0.0/24                  192.168.0.0/24&lt;br /&gt;
                  &lt;br /&gt;
      First, set an iptables rule that will send certain packets to IPQ (you need iptable_filter and ip_queue modules loaded): &lt;br /&gt;
            &lt;br /&gt;
            Router# echo &amp;quot;1&amp;quot; &amp;gt;/proc/sys/net/ipv4/ip_forward      # start routing&lt;br /&gt;
            Router# iptables -A FORWARD -p icmp --icmp-type echo-request -j QUEUE  # send all icmp echo requests to IPQ&lt;br /&gt;
            &lt;br /&gt;
      Start netsim with the option(s) you want:&lt;br /&gt;
            &lt;br /&gt;
            Router#./netsim --delay min=0,max=10,percent=30&lt;br /&gt;
            &lt;br /&gt;
      Start a ping from Host A: &lt;br /&gt;
            &lt;br /&gt;
            HostA# ping 192.168.0.2&lt;br /&gt;
      &lt;br /&gt;
      (if you get a Network Unreachable error, make sure that you have a default gw or route information about 192.168 set)&lt;br /&gt;
      You should see the results on the ping output and on the Router's screen.&lt;br /&gt;
   &lt;br /&gt;
   Common errors/troubleshooting:&lt;br /&gt;
      Command:&lt;br /&gt;
            Router$ ./netsim --drop percent=22&lt;br /&gt;
            Received an error message: 1&lt;br /&gt;
      Answer: netsim must run with root privileges&lt;br /&gt;
      &lt;br /&gt;
      Command:&lt;br /&gt;
            Router# ./netsim --drop percent=22&lt;br /&gt;
            Failed to send netlink message: Connection refused&lt;br /&gt;
      Answer: you need to load the ip_queue module (modprobe ip_queue) or set a iptables -j QUEUE rule&lt;br /&gt;
      &lt;br /&gt;
      Command:&lt;br /&gt;
            Router# ./netsim --drop percent=22&lt;br /&gt;
            Failed to create netlink socket&lt;br /&gt;
      Answer: you can't run two instances of netsim at the same time on the same machine. Kill one of them.&lt;br /&gt;
      &lt;br /&gt;
   Known bugs/errors/limitations:&lt;br /&gt;
      - can't create new packets (libipq limitation), so the duplication is done by copying the content of packet i to packet i+1 (and&lt;br /&gt;
        loosing the original content of packet i+1)&lt;br /&gt;
      - if there are multiple iptables -j QUEUE rules active, it's possible to have an unpredictible output for --reorder and --duplicate&lt;br /&gt;
        (can be fixed if you check to see that all packets that are to be reordered or duplicated come from the same iptables rule)&lt;br /&gt;
      - if you modify a packet and want it to go through, you MUST recalculate its CRC sum. Otherwise it MIGHT be dropped by the&lt;br /&gt;
        kernel, and will surely be dropped at the destination. &lt;br /&gt;
      - the percentages set in the command line are not always respected; they are respected only for a very large number of packets.&lt;br /&gt;
      - in the case of excessive delays set by the delay parameter, you might experience packet drops because the packet queue can &lt;br /&gt;
        fill up.&lt;br /&gt;
      - by default, iptables drops all packets that match a -j QUEUE rule if no ipq listener is registered (netsim isn't started)&lt;br /&gt;
        &lt;br /&gt;
   Disclaimer: This program can be DANGEROUS, so make sure that you know what you are doing before using it on a network. It &lt;br /&gt;
      was intended only as an exercise; it shouldn't be used in real life! You were warned... (If you notice network problems after you&lt;br /&gt;
      start netsim, kill it and issue a 'iptables -F' to delete all the rules)&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;linux/netfilter.h&amp;gt;  //constants &lt;br /&gt;
#include &amp;lt;linux/ip.h&amp;gt;           //ip header&lt;br /&gt;
#include &amp;lt;libipq/libipq.h&amp;gt;    //libipq API&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;              //general definitions&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;             //for exit()&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;             //for command line parsing&lt;br /&gt;
#include &amp;lt;time.h&amp;gt;               //for srand()&lt;br /&gt;
#include &amp;lt;unistd.h&amp;gt;            //for usleep()&lt;br /&gt;
#include &amp;lt;signal.h&amp;gt;            //for signal() (ctrl+c)&lt;br /&gt;
&lt;br /&gt;
#define BUFFERSIZE 2048&lt;br /&gt;
&lt;br /&gt;
void showUsage();&lt;br /&gt;
int parseCmdline(int argc, char **argv);&lt;br /&gt;
void showCmdline();&lt;br /&gt;
int validateCmdline();&lt;br /&gt;
void exitWithError(struct ipq_handle *h);&lt;br /&gt;
&lt;br /&gt;
/* A structure holding different variables set based on the command line parameters.&lt;br /&gt;
 */&lt;br /&gt;
struct {&lt;br /&gt;
   unsigned short int delay;&lt;br /&gt;
   unsigned int delay_min;&lt;br /&gt;
   unsigned int delay_max;&lt;br /&gt;
   unsigned short int delay_percent;&lt;br /&gt;
   unsigned short int drop;&lt;br /&gt;
   unsigned short int drop_percent;&lt;br /&gt;
   unsigned short int reorder;&lt;br /&gt;
   unsigned short int reorder_percent;&lt;br /&gt;
   unsigned int reorder_max;&lt;br /&gt;
   unsigned short int duplicate;&lt;br /&gt;
   unsigned short int duplicate_percent;&lt;br /&gt;
   unsigned short int error;&lt;br /&gt;
   unsigned short int error_percent;&lt;br /&gt;
   unsigned short int mangle;&lt;br /&gt;
   unsigned short int mangle_percent;&lt;br /&gt;
} cmdline;&lt;br /&gt;
&lt;br /&gt;
/*Global variables - for statistics*/&lt;br /&gt;
int total_packets=0, \&lt;br /&gt;
      delayed_packets=0, \&lt;br /&gt;
      dropped_packets=0, \&lt;br /&gt;
      duplicated_packets=0, \&lt;br /&gt;
      errored_packets=0, \&lt;br /&gt;
      reordered_packets=0, \&lt;br /&gt;
      mangled_packets=0;&lt;br /&gt;
&lt;br /&gt;
/* Method to parse the command line -&amp;gt; takes argc and argv from main and writes &lt;br /&gt;
 * flags in the structure cmdline. (This is NOT the most efficient way to do this, but hey...)&lt;br /&gt;
 * Returns 0 for success and anything else for failiure.&lt;br /&gt;
 */&lt;br /&gt;
int parseCmdline(int argc, char **argv){&lt;br /&gt;
   int i=0;&lt;br /&gt;
   for ( i = 1; i &amp;lt; argc; i++)&lt;br /&gt;
    {&lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--delay&amp;quot;)!=NULL){  //we found the delay parameter&lt;br /&gt;
          cmdline.delay=1; //set to do delay&lt;br /&gt;
          //the next parameters should contain min,max and percent&lt;br /&gt;
          if((i+1)==argc) return 1; //no more arguments&lt;br /&gt;
          char* min=strstr(argv[i+1], &amp;quot;min&amp;quot;);&lt;br /&gt;
          char* max=strstr(argv[i+1], &amp;quot;max&amp;quot;);&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(min!=NULL &amp;amp;&amp;amp; max!=NULL &amp;amp;&amp;amp; percent!=NULL){&lt;br /&gt;
             //everything is as expected&lt;br /&gt;
             char* temp=min;    //get the first parameter&lt;br /&gt;
             temp = strchr(temp, '='); //extract from '=' to the end&lt;br /&gt;
             temp = strtok(temp, &amp;quot;,&amp;quot;); //cut the first comma&lt;br /&gt;
             temp = temp +1; //cut the equal from the result&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: temp=%s\n &amp;quot;, temp);&lt;br /&gt;
             cmdline.delay_min=atoi(temp);&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: cmdline.delay_min=%d\n &amp;quot;, cmdline.delay_min);&lt;br /&gt;
             //now, for the second parameter&lt;br /&gt;
             temp = max;&lt;br /&gt;
             temp = strchr(temp, '='); //extract from '=' to the end&lt;br /&gt;
             temp = strtok(temp, &amp;quot;,&amp;quot;); //cut the first comma&lt;br /&gt;
             temp = temp +1; //cut the equal from the result&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: temp=%s\n &amp;quot;, temp);&lt;br /&gt;
             cmdline.delay_max=atoi(temp);&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: cmdline.delay_max=%d\n &amp;quot;, cmdline.delay_max);&lt;br /&gt;
             //the last parameter&lt;br /&gt;
             temp = percent;&lt;br /&gt;
             temp = strchr(temp, '='); //extract from '=' to the end&lt;br /&gt;
             temp = temp +1; //cut the equal from the result&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: temp=%s\n &amp;quot;, temp);&lt;br /&gt;
             cmdline.delay_percent=atoi(temp);&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: cmdline.delay_percent=%d\n &amp;quot;, cmdline.delay_percent);&lt;br /&gt;
             i++; //skip a parameter, because it has been parsed&lt;br /&gt;
          }//from all the NULL's&lt;br /&gt;
          else{&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;  //start over&lt;br /&gt;
       }//from --delay&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--drop&amp;quot;)!=NULL){  //we found the --drop parameter&lt;br /&gt;
          cmdline.drop=1; //set to do drop&lt;br /&gt;
          //fprintf(stderr, &amp;quot;DEBUG: i=%d, argc=%d\n &amp;quot;, i, argc);&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(percent!=NULL){&lt;br /&gt;
             percent=strchr(percent, '='); //extract from '=' to the end&lt;br /&gt;
             percent=percent+1; //cut the equal from the result&lt;br /&gt;
             cmdline.drop_percent=atoi(percent);&lt;br /&gt;
             //fprintf(stderr, &amp;quot;DEBUG: cmdline.drop_percent=%d\n &amp;quot;, cmdline.drop_percent);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --drop&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--duplicate&amp;quot;)!=NULL){  //we found --duplicate&lt;br /&gt;
          cmdline.duplicate=1; //set to do duplicate&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(percent!=NULL){&lt;br /&gt;
             percent=strchr(percent, '='); //extract from '=' to the end&lt;br /&gt;
             percent=percent+1; //cut the equal from the result&lt;br /&gt;
             cmdline.duplicate_percent=atoi(percent);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed already&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --duplicate&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--error&amp;quot;)!=NULL){  //we found --error&lt;br /&gt;
          cmdline.error=1; //set to do some error (as if internal bugs weren't enough! :)&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(percent!=NULL){&lt;br /&gt;
             percent=strchr(percent, '='); //extract from '=' to the end&lt;br /&gt;
             percent=percent+1; //cut the equal from the result&lt;br /&gt;
             cmdline.error_percent=atoi(percent);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --error&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--mangle&amp;quot;)!=NULL){  //we found mangle&lt;br /&gt;
          cmdline.mangle=1; //set to do mangle&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          if(percent!=NULL){&lt;br /&gt;
             percent=strchr(percent, '='); //extract from '=' to the end&lt;br /&gt;
             percent=percent+1; //cut the equal from the result&lt;br /&gt;
             cmdline.mangle_percent=atoi(percent);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed already&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --mangle&lt;br /&gt;
       &lt;br /&gt;
       if(strstr(argv[i],&amp;quot;--reorder&amp;quot;)!=NULL){  //we found reorder&lt;br /&gt;
          cmdline.reorder=1; //set to do reordering&lt;br /&gt;
          if((i+1)==argc) return 1; //no more parameters&lt;br /&gt;
          char* percent=strstr(argv[i+1], &amp;quot;percent&amp;quot;);&lt;br /&gt;
          char* max=strstr(argv[i+1], &amp;quot;max&amp;quot;);&lt;br /&gt;
          if(percent!=NULL &amp;amp;&amp;amp; max!=NULL){&lt;br /&gt;
             char *temp = percent;&lt;br /&gt;
             temp=strchr(temp, '='); //extract from '=' to the end of the string&lt;br /&gt;
             temp=strtok(temp, &amp;quot;,&amp;quot;); //cut what's after the comma&lt;br /&gt;
             temp=temp+1; //cut the equal from the result&lt;br /&gt;
             cmdline.reorder_percent=atoi(temp);&lt;br /&gt;
             temp=max;&lt;br /&gt;
             temp=strchr(temp, '='); //extract from '=' to the end&lt;br /&gt;
             temp=temp+1; //cut the equal from the result&lt;br /&gt;
             cmdline.reorder_max=atoi(temp);&lt;br /&gt;
             i++; //skip a parameter because it has been parsed&lt;br /&gt;
          }//from if&lt;br /&gt;
          else{&lt;br /&gt;
             //showUsage();&lt;br /&gt;
             return 1;&lt;br /&gt;
          }&lt;br /&gt;
          continue;&lt;br /&gt;
       }//from --reorder&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Debug method, used to test if parameter parsing works as expected.&lt;br /&gt;
 */&lt;br /&gt;
void showCmdline(){&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.delay=%d&amp;quot;,cmdline.delay);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.delay_min=%d&amp;quot;,cmdline.delay_min);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.delay_max=%d&amp;quot;,cmdline.delay_max);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.delay_percent=%d&amp;quot;,cmdline.delay_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.drop=%d&amp;quot;,cmdline.drop);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.drop_percent=%d&amp;quot;,cmdline.drop_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.reorder=%d&amp;quot;,cmdline.reorder);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.reorder_percent=%d&amp;quot;,cmdline.reorder_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.reorder_max=%d&amp;quot;,cmdline.reorder_max);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.duplicate=%d&amp;quot;,cmdline.duplicate);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.duplicate_percent=%d&amp;quot;,cmdline.duplicate_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.error=%d&amp;quot;,cmdline.error);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.error_percent=%d&amp;quot;,cmdline.error_percent);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.mangle=%d&amp;quot;,cmdline.mangle);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nDEBUG: cmdline.mangle_percent=%d&amp;quot;,cmdline.mangle_percent);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Method that checks that the values in the structure cmdline are relevant &lt;br /&gt;
 * (ex: percent &amp;lt;100)&lt;br /&gt;
 * Returns 0 for success and anything else for failiure.&lt;br /&gt;
 */&lt;br /&gt;
int validateCmdline(){&lt;br /&gt;
   if( (cmdline.delay_min&amp;gt;cmdline.delay_max) || (cmdline.reorder_max&amp;gt;5) || (cmdline.delay_percent&amp;gt;100) \&lt;br /&gt;
      || (cmdline.drop_percent&amp;gt;100) || (cmdline.reorder_percent&amp;gt;100) || (cmdline.duplicate_percent&amp;gt;100) \&lt;br /&gt;
      || (cmdline.error_percent&amp;gt;100) || (cmdline.mangle_percent&amp;gt;100) || (cmdline.reorder_max&amp;lt;=0))&lt;br /&gt;
         return 1;&lt;br /&gt;
   else&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Method that displays the usage information (help)&lt;br /&gt;
 */&lt;br /&gt;
void showUsage(){&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim v0.1\n\nUsage: netsim OPTION...&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nOption list:&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --delay\t\t\tdelays some packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      min=TIME\t\t\tminimum delay time in ms&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      max=TIME\t\t\tmaximum delay time in ms&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be delayed&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --drop\t\t\tdrops some packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be dropped&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --duplicate\t\t\tduplicates some packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be duplicated&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --error\t\t\tcreates bit errors in some packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be errored&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --mangle\t\t\tmodifies TOS in ip header&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be mangled&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n  --reorder\t\t\tmodifies order of packets&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      max=NUMBER\t\tnumber of packets to reorder&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n      percent=PERCENT\t\tpercent of packets to be duplicated&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\n\nExamples:&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim --delay min=12,max=20,percent=5&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim --drop percent=3&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim --duplicate percent=3&amp;quot;);&lt;br /&gt;
   fprintf(stderr, &amp;quot;\nnetsim --delay min=0,max=12,percent=7 --error percent=3 --duplicate percent=2\n&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Method used to exit cleanly in case of errors in libipq&lt;br /&gt;
 */&lt;br /&gt;
void exitWithError(struct ipq_handle *h){&lt;br /&gt;
   ipq_perror(&amp;quot;Queue Error:&amp;quot;);&lt;br /&gt;
   ipq_destroy_handle(h);&lt;br /&gt;
   exit(2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Dumps the packet in hex on the screen - used for debug&lt;br /&gt;
 */&lt;br /&gt;
void showPacket(ipq_packet_msg_t *pkt){&lt;br /&gt;
   int i=0;&lt;br /&gt;
   printf(&amp;quot;\n Raw packet: --------------------------\n&amp;quot;);&lt;br /&gt;
   for(i=0;i&amp;lt;pkt-&amp;gt;data_len;i++){&lt;br /&gt;
      printf(&amp;quot;%x &amp;quot;, pkt-&amp;gt;payload[i]);&lt;br /&gt;
   }&lt;br /&gt;
   printf(&amp;quot;\n End of raw packet ------------------&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Checksum for ip header*/&lt;br /&gt;
unsigned short checksum(unsigned short *addr, int len)&lt;br /&gt;
{&lt;br /&gt;
  int nleft=len;&lt;br /&gt;
  int sum=0;&lt;br /&gt;
  unsigned short *w=addr;&lt;br /&gt;
  unsigned short answer=0;&lt;br /&gt;
&lt;br /&gt;
while(nleft&amp;gt;1){&lt;br /&gt;
      sum+=*w++;&lt;br /&gt;
      nleft-=2;&lt;br /&gt;
}&lt;br /&gt;
if(nleft==1){&lt;br /&gt;
      *(unsigned char *)(&amp;amp;answer)=*(unsigned char *)w;&lt;br /&gt;
      sum+=answer;     &lt;br /&gt;
}&lt;br /&gt;
  sum=(sum&amp;gt;&amp;gt;16)+(sum&amp;amp;0xffff);&lt;br /&gt;
  sum+=(sum&amp;gt;&amp;gt;16);&lt;br /&gt;
  answer=~sum;&lt;br /&gt;
  return answer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*Method that calculates the percent*/&lt;br /&gt;
int doPercent(int percent){&lt;br /&gt;
   if (percent&amp;gt;0)&lt;br /&gt;
      return rand()%((int)(100/percent+0.5));&lt;br /&gt;
   else&lt;br /&gt;
      return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*Handler for CTRL+C; Displays some statistics when exiting*/&lt;br /&gt;
void ctrlC(int sig){&lt;br /&gt;
   printf(&amp;quot;\nStatistics:&amp;quot;);&lt;br /&gt;
   printf(&amp;quot;\nTotal packets=%d Delayed=%d Dropped=%d\nDuplicated=%d Errored=%d Reordered=%d Mangled=%d\n&amp;quot;, \&lt;br /&gt;
         total_packets,delayed_packets, dropped_packets, duplicated_packets, errored_packets, reordered_packets, \&lt;br /&gt;
         mangled_packets);&lt;br /&gt;
   exit(0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ---Verdict methods--- */&lt;br /&gt;
/* Can return 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *                   1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 *                   2 if the packet is to be dropped.&lt;br /&gt;
&lt;br /&gt;
/* Method that decides whether a packet should be errored */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 */&lt;br /&gt;
int doError(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.error_percent)==0){ //if we need to do error&lt;br /&gt;
      printf(&amp;quot; erroring &amp;quot;);&lt;br /&gt;
      struct iphdr *iph = ((struct iphdr *)pkt-&amp;gt;payload);  //get the ip header&lt;br /&gt;
      iph-&amp;gt;tot_len=iph-&amp;gt;tot_len+1;   //modify the ip packet length field so that the destination receives a bad CRC&lt;br /&gt;
      errored_packets++;&lt;br /&gt;
      return 1;  //send the modified packet (to be forwarded)&lt;br /&gt;
   }&lt;br /&gt;
  return 0; //nothing to do to this packet&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be delayed */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 */&lt;br /&gt;
int doDelay(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.delay_percent)==0){ //if we need to delay the packet&lt;br /&gt;
      printf(&amp;quot; delaying &amp;quot;);&lt;br /&gt;
      int ms = rand()%(cmdline.delay_max - cmdline.delay_min); //calculate this delay (randomly)&lt;br /&gt;
      ms+=cmdline.delay_min;&lt;br /&gt;
      delayed_packets++;&lt;br /&gt;
      usleep(ms*1000); //sleeping 'ms' miliseconds&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   return 0; //forward the packet normally&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be dropped */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              2 if the packet is to be dropped.&lt;br /&gt;
 */&lt;br /&gt;
int doDrop(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.drop_percent)==0){//if we need to drop this packet&lt;br /&gt;
      printf(&amp;quot; dropping &amp;quot;);&lt;br /&gt;
      dropped_packets++;&lt;br /&gt;
      return 2; //notify that it is to be dropped&lt;br /&gt;
      }&lt;br /&gt;
   return 0; //forward normally&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be reordered */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 */&lt;br /&gt;
int doReorder(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.reorder_percent)==0){ //if this packet needs to be reordered&lt;br /&gt;
      printf(&amp;quot; reordering &amp;quot;);&lt;br /&gt;
      &lt;br /&gt;
      /*here it gets tricky. To reorder, one must receive all packets and send them again in the reverse order.&lt;br /&gt;
        This is just what we do. Note that your packets will be delayed (because we're waiting for cmdline.reorder_max&lt;br /&gt;
        packets to arrive first)*/&lt;br /&gt;
      &lt;br /&gt;
      ipq_packet_msg_t *packets[]={ NULL, NULL, NULL, NULL, NULL } ; //an array to hold 5 packets (maximum).&lt;br /&gt;
      unsigned char buffer[5][BUFFERSIZE];  //local buffer&lt;br /&gt;
      int status=0, i=0;&lt;br /&gt;
      &lt;br /&gt;
      packets[0]=pkt; //copy the current (previously obtained) packet to packets[0]; This will be the last to leave&lt;br /&gt;
      reordered_packets++;&lt;br /&gt;
      printf(&amp;quot;.&amp;quot;); //display a '.' for every packet sent from now on&lt;br /&gt;
      for(i=1; i&amp;lt;cmdline.reorder_max;i++){&lt;br /&gt;
         //read the next packet&lt;br /&gt;
         status = ipq_read(h, buffer[i], BUFFERSIZE, 0);  //handle h, destination_buffer, buffer_size, timeout&lt;br /&gt;
         if (status&amp;lt;0)&lt;br /&gt;
            exitWithError(h);&lt;br /&gt;
         &lt;br /&gt;
         //determine the message type -&amp;gt; Packet or error message&lt;br /&gt;
         if(ipq_message_type(buffer[i])==NLMSG_ERROR){&lt;br /&gt;
            fprintf(stderr, &amp;quot;Received an error message in doReorder(): %d&amp;quot;, ipq_get_msgerr(buffer[i]));  //display the error.&lt;br /&gt;
         }&lt;br /&gt;
         if(ipq_message_type(buffer[i])==IPQM_PACKET){&lt;br /&gt;
            //we received an actual packet of data.&lt;br /&gt;
            pkt=ipq_get_packet(buffer[i]); //write the actual packet in pkt   &lt;br /&gt;
            total_packets++;&lt;br /&gt;
            reordered_packets++;&lt;br /&gt;
            packets[i]=pkt; //store this packet into the array, where it will be read later&lt;br /&gt;
            printf(&amp;quot;.&amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      //do the reordering and set verdicts&lt;br /&gt;
      &lt;br /&gt;
      for(i=cmdline.reorder_max-1; i&amp;gt;0; i--){ //go backwards&lt;br /&gt;
         pkt=packets[i];&lt;br /&gt;
         status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_ACCEPT, pkt-&amp;gt;data_len, pkt-&amp;gt;payload); //set the verdict for each &lt;br /&gt;
                                                                                                                  //packet, until we get to the last one&lt;br /&gt;
         //fprintf(stderr, &amp;quot;*&amp;quot;);&lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
      pkt=packets[0]; //let the main program set the verdict for the first packet.&lt;br /&gt;
      return 1; //forward the modified packet (it was copied from packets[0])&lt;br /&gt;
   }&lt;br /&gt;
   return 0; //no reordering, nothing special to do&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be duplicated */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 */&lt;br /&gt;
int doDuplicate(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.duplicate_percent)==0){//if we must duplicate this packet&lt;br /&gt;
      printf(&amp;quot; duplicating &amp;quot;);&lt;br /&gt;
      &lt;br /&gt;
      int status = 0;&lt;br /&gt;
      //showPacket(pkt);&lt;br /&gt;
      &lt;br /&gt;
      /*There's a catch about outputting new packets using libipq. Normally, libipq can't create new packets (that weren't&lt;br /&gt;
        captured by the iptables filter. So, in order to do duplication, we have to discard the next packet that arrives and &lt;br /&gt;
        overwrite its content with the content of the original packet. It works, but may hide some bugs (not tested extensivelly)*/&lt;br /&gt;
      &lt;br /&gt;
      //save this packet somewhere;&lt;br /&gt;
      ipq_packet_msg_t *new_pkt=pkt;&lt;br /&gt;
      //allow the original packet to pass (first instance)&lt;br /&gt;
      status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_ACCEPT, 0, NULL); &lt;br /&gt;
      //wait for a new packet.&lt;br /&gt;
      //read an IPQ message into buffer.&lt;br /&gt;
      unsigned char buffer[BUFFERSIZE];&lt;br /&gt;
      status = ipq_read(h, buffer, BUFFERSIZE, 0);  //handle h, destination_buffer, buffer_size, timeout&lt;br /&gt;
      if (status&amp;lt;0)&lt;br /&gt;
         exitWithError(h);&lt;br /&gt;
      &lt;br /&gt;
      //determine the message type -&amp;gt; Packet or error message&lt;br /&gt;
      if(ipq_message_type(buffer)==NLMSG_ERROR){&lt;br /&gt;
         fprintf(stderr, &amp;quot;Received an error message in doDuplicate(): %d&amp;quot;, ipq_get_msgerr(buffer));  //display the error.&lt;br /&gt;
      }&lt;br /&gt;
      if(ipq_message_type(buffer)==IPQM_PACKET){&lt;br /&gt;
         //we received an actual packet of data.&lt;br /&gt;
         total_packets++;&lt;br /&gt;
         duplicated_packets++;&lt;br /&gt;
         //replace its contents with the previous packet (so that this will be the duplicated one)&lt;br /&gt;
         pkt=ipq_get_packet(buffer); //write the actual packet in pkt&lt;br /&gt;
         long id = pkt-&amp;gt;packet_id; //ipq isn't stupid! It knows it has forwarded the packet with the old id, so we must keep &lt;br /&gt;
                                                   //the new packets id (they are unique) (the old id isn't valid after we set the verdict)&lt;br /&gt;
         pkt = new_pkt;  //overwrite the second packet with the first packet&lt;br /&gt;
         pkt-&amp;gt;packet_id = id; //use the second (valid) id&lt;br /&gt;
      }&lt;br /&gt;
      return 1; //send the second, modified packet&lt;br /&gt;
   }&lt;br /&gt;
   return 0; //nothing special to do&lt;br /&gt;
}&lt;br /&gt;
/* Method that decides whether a packet should be mangled */&lt;br /&gt;
/* Returns 0 if the packet is to be accepted without modification, &lt;br /&gt;
 *              1 if the packet is to be accepted with modification(s),&lt;br /&gt;
 */&lt;br /&gt;
int doMangle(struct ipq_handle *h, ipq_packet_msg_t *pkt){&lt;br /&gt;
   if(doPercent(cmdline.mangle_percent)==0){//mangle this packet?&lt;br /&gt;
   printf(&amp;quot; mangling &amp;quot;);&lt;br /&gt;
   mangled_packets++;&lt;br /&gt;
   struct iphdr *iph = ((struct iphdr *)pkt-&amp;gt;payload); //get the ip header&lt;br /&gt;
   iph-&amp;gt;tos=(__u8)24;  //modify the TOS field (can be any field) to a specific value&lt;br /&gt;
   iph-&amp;gt;check=0; //set the checksum to 0&lt;br /&gt;
   iph-&amp;gt;check=checksum((unsigned short*)iph,iph-&amp;gt;ihl*4); //compute the new checksum&lt;br /&gt;
   return 1;//forward the modified packet&lt;br /&gt;
   }&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
/* ---End of verdict methods--- /*&lt;br /&gt;
&lt;br /&gt;
/* Main method&lt;br /&gt;
 */&lt;br /&gt;
int main(int argc, char **argv){&lt;br /&gt;
   &lt;br /&gt;
   if(argc&amp;lt;3){ //not enough arguments, here's a list&lt;br /&gt;
      showUsage();&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
   &lt;br /&gt;
   //register a listener for CTRL+C, so that when we stop, we get a nice statistic&lt;br /&gt;
   (void) signal(SIGINT, ctrlC);&lt;br /&gt;
   &lt;br /&gt;
   memset( &amp;amp;cmdline, 0, sizeof(cmdline)); //initialize cmdline with zeros;&lt;br /&gt;
   cmdline.reorder_max=1;   //can't be zero, or it won't be valid&lt;br /&gt;
   //showCmdline(); //Debug&lt;br /&gt;
   &lt;br /&gt;
   &lt;br /&gt;
   /*If you want to understand how libipq can be used, you shouldn't bother looking over parseCmdline() &lt;br /&gt;
   because it is irrelevant to your goal; it just parses the command line options and populates the cmdline &lt;br /&gt;
   variable.*/&lt;br /&gt;
   if(parseCmdline(argc, argv)!=0){      //write the data to cmdline&lt;br /&gt;
      showUsage();&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
   //showCmdline(); //Debug&lt;br /&gt;
   &lt;br /&gt;
   if(validateCmdline()!=0){   //check that cmdline has reasonable values&lt;br /&gt;
      showUsage();&lt;br /&gt;
      //fprintf(stderr, &amp;quot;DEBUG: Invalid parameter&amp;quot;);&lt;br /&gt;
      exit(1);&lt;br /&gt;
   }&lt;br /&gt;
   /*showCmdline(); //Debug&lt;br /&gt;
   exit(1);&lt;br /&gt;
   */&lt;br /&gt;
   &lt;br /&gt;
   //initialize random number generator (needed for --delay)&lt;br /&gt;
   srand( (unsigned int)time( NULL ) );&lt;br /&gt;
   unsigned char buffer[BUFFERSIZE];  //buffer for packages and ipq messages.&lt;br /&gt;
   struct ipq_handle *h;&lt;br /&gt;
   int status;&lt;br /&gt;
   &lt;br /&gt;
   //Register a handle with IPQ.&lt;br /&gt;
   h = ipq_create_handle(0, PF_INET);  //0=Flags (not used); PF_INET -&amp;gt; IPV4 &lt;br /&gt;
   if (!h)&lt;br /&gt;
      exitWithError(h);&lt;br /&gt;
   &lt;br /&gt;
   //Copy entire packets (up to BUFFERSIZE) to user-space&lt;br /&gt;
   status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFFERSIZE);&lt;br /&gt;
   if (status &amp;lt;0)&lt;br /&gt;
      exitWithError(h);&lt;br /&gt;
   &lt;br /&gt;
   //Get the packets and act on them according to the cmdline parameters&lt;br /&gt;
   //Do this in an infinite loop.&lt;br /&gt;
   do{&lt;br /&gt;
      //read an IPQ message into buffer. The IPQ message isn't the packet!!!&lt;br /&gt;
      status = ipq_read(h, buffer, BUFFERSIZE, 0);  //handle h, destination_buffer, buffer_size, timeout&lt;br /&gt;
      if (status&amp;lt;0)&lt;br /&gt;
         exitWithError(h);&lt;br /&gt;
      &lt;br /&gt;
      //determine the message type -&amp;gt; Packet or error message&lt;br /&gt;
      if(ipq_message_type(buffer)==NLMSG_ERROR){&lt;br /&gt;
         fprintf(stderr, &amp;quot;Received an error message: %d&amp;quot;, ipq_get_msgerr(buffer));  //display the error.&lt;br /&gt;
      }&lt;br /&gt;
      if(ipq_message_type(buffer)==IPQM_PACKET){&lt;br /&gt;
         //we received an actual packet of data.&lt;br /&gt;
         ipq_packet_msg_t *pkt=ipq_get_packet(buffer); //write the actual packet in pkt &lt;br /&gt;
         &lt;br /&gt;
         total_packets++;&lt;br /&gt;
         &lt;br /&gt;
         //all we have to do now is set the verdict!&lt;br /&gt;
         int verdict = 0; //allow all by default.&lt;br /&gt;
         int verdictDrop = 0, verdictDelay = 0, verdictError = 0, verdictReorder = 0, verdictDuplicate = 0, verdictMangle = 0;&lt;br /&gt;
         &lt;br /&gt;
         printf(&amp;quot;\n Packet &amp;quot;);&lt;br /&gt;
         if(cmdline.drop==1){ //if we need to drop a percent of  packets&lt;br /&gt;
            verdictDrop = doDrop(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; drop &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; cmdline.error ==1){ //if it was dropped, don't do anything else to the packet&lt;br /&gt;
            verdictError = doError(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; error &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; verdictError !=1 &amp;amp;&amp;amp; cmdline.delay ==1){ //if it was dropped or errored, don't do anything else to it&lt;br /&gt;
            verdictDelay = doDelay(h, pkt);&lt;br /&gt;
            //printf( &amp;quot; delay &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; verdictError !=1 &amp;amp;&amp;amp; cmdline.mangle ==1){&lt;br /&gt;
            verdictMangle = doMangle(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; mangle &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; verdictError !=1 &amp;amp;&amp;amp; cmdline.reorder ==1){&lt;br /&gt;
            verdictReorder = doReorder(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; reorder &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         if(verdictDrop !=2 &amp;amp;&amp;amp; verdictError !=1 &amp;amp;&amp;amp; cmdline.duplicate ==1){&lt;br /&gt;
            verdictDuplicate = doDuplicate(h, pkt);&lt;br /&gt;
            //printf(&amp;quot; duplicate &amp;quot;);&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         fflush(stdin); //make sure the output is updated&lt;br /&gt;
         &lt;br /&gt;
         if(verdictDrop ==2) //we really need to drop this packet&lt;br /&gt;
            verdict = 2;&lt;br /&gt;
         else{ //we need to send a modified packet&lt;br /&gt;
            if(verdictError ==1 || verdictMangle ==1 || verdictReorder ==1 || verdictDuplicate ==1)&lt;br /&gt;
               verdict = 1;&lt;br /&gt;
            else&lt;br /&gt;
               verdict = 0; //we will send the original packet&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         //we have the verdict, now enforce it!&lt;br /&gt;
         &lt;br /&gt;
         if(verdict == 0){&lt;br /&gt;
            //accept packet without modifications&lt;br /&gt;
            status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_ACCEPT, 0, NULL); &lt;br /&gt;
                                                // handle, packet id, verdict, data_size, buffer to output.&lt;br /&gt;
         }&lt;br /&gt;
         if(verdict == 1){&lt;br /&gt;
            //accept packet with modifications&lt;br /&gt;
            status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_ACCEPT, pkt-&amp;gt;data_len, pkt-&amp;gt;payload); &lt;br /&gt;
                                                // handle, packet id, verdict, data_size, buffer to output.&lt;br /&gt;
         }&lt;br /&gt;
         if(verdict == 2){&lt;br /&gt;
            //drop packet&lt;br /&gt;
            status=ipq_set_verdict(h, pkt-&amp;gt;packet_id, NF_DROP, 0, NULL);&lt;br /&gt;
                                                // handle, packet id, verdict, data_size, buffer to output.&lt;br /&gt;
         }&lt;br /&gt;
         &lt;br /&gt;
         if(status &amp;lt; 0)&lt;br /&gt;
            exitWithError(h);&lt;br /&gt;
         &lt;br /&gt;
         /*printf(&amp;quot;\nPacket ok, size=%d&amp;quot;, pkt-&amp;gt;data_len);&lt;br /&gt;
         showPacket(pkt);&lt;br /&gt;
         */&lt;br /&gt;
         &lt;br /&gt;
      }&lt;br /&gt;
      &lt;br /&gt;
   } while(1);&lt;br /&gt;
   &lt;br /&gt;
   //unreachable code.&lt;br /&gt;
   ipq_destroy_handle(h);&lt;br /&gt;
   return 0;&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;/div&gt;</summary>
		<author><name>Mad ady</name></author>	</entry>

	<entry>
		<id>http://wiki.linux360.ro/index.php?title=User:Mad_ady&amp;diff=2401</id>
		<title>User:Mad ady</title>
		<link rel="alternate" type="text/html" href="http://wiki.linux360.ro/index.php?title=User:Mad_ady&amp;diff=2401"/>
				<updated>2006-03-30T17:25:35Z</updated>
		
		<summary type="html">&lt;p&gt;Mad ady: libipq by example 2&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is another test&lt;/div&gt;</summary>
		<author><name>Mad ady</name></author>	</entry>

	<entry>
		<id>http://wiki.linux360.ro/index.php?title=User_talk:Mad_ady&amp;diff=2400</id>
		<title>User talk:Mad ady</title>
		<link rel="alternate" type="text/html" href="http://wiki.linux360.ro/index.php?title=User_talk:Mad_ady&amp;diff=2400"/>
				<updated>2006-03-30T17:24:19Z</updated>
		
		<summary type="html">&lt;p&gt;Mad ady: libipq by example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is just a test.&lt;/div&gt;</summary>
		<author><name>Mad ady</name></author>	</entry>

	</feed>