I write a shell script in bash today in order to limit the upload bandwidth of P2P software in the localhost. The netfilter framework allows me to set the filter rules by process id. Therefore, we just need to search the process id of P2P software and to limit the bandwidth of the process. However, iptables tutorial [1] said "pid, sid and command matching is broken in SMP kernels since they use different process lists for each processor". The Linux kernel version is 2.6.24-16 in my box, and the function of --pid-owner is not runable in SMP mode. If you want to use this script to limit the upload bandwidth of P2P in the localhost, you should add the file path of this script to the /etc/crontab to let the script run periodically.\
#!/bin/bash## You need to install the package - sysvutilsecho"---------------------------------------------------------------------";echo"* Limit the upload bandwidth of indicated programs in localhost";echo"* Date: Feb. 21, 2009";echo"* GNU License";echo"* Author: Aaron Liao (http://applezulab.netdpi.net)";echo"---------------------------------------------------------------------";# environment testingpidof="/bin/pidof";iptables="/sbin/iptables";DEBUG=0;ret=0;# set programs you want to limit their upload bandwidthprogs_name=( [0]="amule" [1]="emule");progs_argv=( [0]=10 [1]=15 );progs_flag=( [0]=0 [1]=0);pid_list=([0]="-1" [1]="-1");declare-a pid_list;# test pidofif [ !-e"$pidof" ]; thenecho"ERR: Program $pidof not found, you should install the packages - sysutils.";exit-1;fi# test ipt_ownermodprobeipt_ownerret=$?if [ $ret -ne0 ]; thenecho">> ipt_owner not supported by kernel";exit $ret;fi# initial$iptables -D OUTPUT -j P2P$iptables -N P2P$iptables -F P2P$iptables -I OUTPUT -j P2P# search the process idfor index in $(seq0 $((${#progs_name[@]} -1)))doif [ $DEBUG -eq1 ]; thenecho"DEBUG >> progs_name:progs_argv=${progs_name[$index]}: ${progs_argv[$index]}";fi pid_list[$index]=`$pidof ${progs_name[$index]}`; ret=$?if [ $ret -eq0 ]; thenecho"FOUND ${progs_name[$index]} pid: ${pid_list[@]}" progs_flag[$index]=1;else progs_flag[$index]=0;continue;fidoneret=0;# limit the bwfor index in $(seq0 $((${#progs_name[@]} -1)))doif [ ${progs_flag[$index]} -eq0 ]; thencontinue;fi tmp_pid=(${pid_list[$index]});for offset in $(seq0 $((${#tmp_pid[@]} -1)))do $iptables -I P2P -m owner --pid-owner ${tmp_pid[$offset]} -m limit --limit ${progs_argv[$index]}/second -j ACCEPT;
$iptables -AP2P-mowner--pid-owner ${tmp_pid[$offset]} -jDROP;donedoneexit $ret;