/* packet_dropper.c * * This program provides an example of how to install a module into a * slightly modified kernel that will randomly drop packets for a specific * (hard-coded) host. * * See linux/drivers/char/random.c for details of get_random_bytes(). * * Usage (must be root to use): * /sbin/insmod packet_dropper * /sbin/rmmod packet_dropper */ #define MODULE #define MAX_UNSIGNED_SHORT 65535 #include #include /* for struct sk_buff */ #include /* for struct iphdr */ extern int (*xmit_test_function)(struct sk_buff *); /* calling function */ unsigned short cutoff; /* drop cutoff */ float rate = 0.14; /* drop percentage */ __u32 target = 0x0202A8C0; /* dst address 192.168.2.2 */ /* ************** added by lin begin ( ***********/ inline unsigned short getUnsignedShortRandom() { unsigned l, h; unsigned short low, high; __asm__ volatile("rdtsc": "=a" (l), "=d" (h)); /* get the lower 16 bits */ low = (unsigned short) l & 0xFFFF; /* cyclicly right shift 6 bits */ high = low << 6; low = low >> 10; low = low | high; return low; } /* ************** added by lin end ) ***********/ /************************************************************ packet_dropper * this is what dev_queue_xmit will call while this module is installed */ int packet_dropper(struct sk_buff *skb) { unsigned short t; if (skb->nh.iph->daddr == target) { /* the following code is modified by lin : begin (*/ t = getUnsignedShortRandom(); if (t < cutoff) return 1; /* drop this packet */ /* modified by lin : end ) */ } return 0; /* continue with normal routine */ } /* packet_dropper */ /*************************************************************** init_module * this function replaces the null pointer with a real one */ int init_module() { /***************** modified by lin begin **************** */ //EXPORT_NO_SYMBOLS; //cutoff = rate * MAX_UNSIGNED_SHORT; /* experimnts on UDP test shows that the number of packets lost is always * greater than the number we expect. So here we low down the cutoff a little * bit. */ cutoff = rate*(1-rate)*MAX_UNSIGNED_SHORT; /***************** modified by lin end ) *****************/ xmit_test_function = packet_dropper; printk("<1> packet_dropper: now dropping packets below %u\n",cutoff); return 0; } /* init_module */ /************************************************************ cleanup_module * this function resets the function pointer back to null */ void cleanup_module() { xmit_test_function = 0; printk("<1> packet_dropper: uninstalled\n"); } /* cleanup_module */