├── CREDITS ├── README.patches ├── CHANGELOG ├── fairnat.config ├── fairnat_wrt.sh ├── GPL ├── README └── fairnat.sh /CREDITS: -------------------------------------------------------------------------------- 1 | Thanks to... 2 | * www.lartc.org for the great HOWTO. Without it, I could never 3 | have managed to even start writing this script. 4 | * www.docum.org for great overall FAQ and Hints, as well as the KPTD. 5 | * the LARTC mailing list where all sorts of people discussed methods, 6 | published their scripts, and helped me out. 7 | * all those people who sent mails with suggestions, feature requests, 8 | and other stuff. It's their fault that Fair NAT contains tons of 9 | features I don't need nor use myself. ;-) 10 | -------------------------------------------------------------------------------- /README.patches: -------------------------------------------------------------------------------- 1 | Patches to use with Fair NAT 2 | ---------------------------- 3 | 4 | Since Fair NAT 0.80, I decided not to include patches anymore, 5 | for several reasons: 6 | 7 | - Fair NAT does not actually require any patches 8 | (except perhaps P2P). 9 | - The kernel patches were not made by me anyway. 10 | - I don't have much time to work on the script anymore, 11 | so patches tend to get outdated very fast. 12 | - It's impossible for me to provide patches for kernel 13 | versions I was never and will never be using. 14 | - Some patches made it into the software ages ago, 15 | which means they were obsolete. 16 | 17 | Patches required for P2P 18 | ------------------------ 19 | 20 | If you want Fair NAT to block P2P, you need to install IPP2P. 21 | You can get it from www.ipp2p.org. Additionally, if you don't 22 | want to just block, but instead shape P2P, you need CONNMARK. 23 | If it's not part of the kernel yet, you'll have to get the 24 | patch from www.netfilter.org (patch-o-matic-ng). 25 | 26 | Actually, patch-o-matic-ng contains a lot of patches that might 27 | be useful for you. Have a look at it. 28 | 29 | Patches required for Hacks 30 | -------------------------- 31 | 32 | TTL_SET requires the TTL patch. Otherwise you won't be able to change 33 | the Time-To-Live value of a packet. The patch is part of pom-ng which 34 | you can obtain from www.netfilter.org 35 | 36 | Some Tweaks I'm using 37 | --------------------- 38 | 39 | In linux/include/net/pkt_sched.h, change 40 | #define PSCHED_CLOCK_SOURCE PSCHED_JIFFIES 41 | to 42 | #define PSCHED_CLOCK_SOURCE PSCHED_CPU 43 | unless the clock source can already be selected in the kernel 44 | config (I heard it was planned to allow that some time ago.) 45 | 46 | In linux/net/sched/sch_htb.c, change 47 | #define HTB_HYSTERESIS 1 48 | to 49 | #define HTB_HYSTERESIS 0 50 | It's supposed to improve accuracy at loss of speed. 51 | 52 | In linux/net/sched/sch_sfq.c, change 53 | #define SFQ_DEPTH 128 54 | to 55 | #define SFQ_DEPTH 16 56 | Fair NAT uses at least two SFQ queues per user, so it's a good 57 | idea to reduce queue size in order to avoid lag. 58 | 59 | 60 | Old kernels and iptables 61 | ------------------------ 62 | 63 | One or two years or so ago you had to patch kernel and tc 64 | for HTB support. Fair NAT even came with a tc-htb binary. 65 | If you still use such old software, don't even bother with 66 | patching - just get the up-to-date stable releases. 67 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | ---- 2003-08-01 ---- Andreas Klauer ---- 2 | did some modifications based on Stef Coene's suggestions: 3 | corrected prio values, removed qdisc burst, normalized child rates, 4 | lowered total rate values, added quantums. Thanks, Stef! 5 | ---- 2003-10-22 ---- Andreas Klauer ---- 6 | new class structure, because the old one grew too big 7 | and having too many classes proved to perform really, really bad 8 | ---- 2004-02-19 ---- Andreas Klauer ---- 9 | replaced $BIN_BC/echo calculations with $((a*b/c)) syntax for readability 10 | added REAL_RATE_UP, REAL_RATE_DOWN for easier rate manipulation 11 | added sfq and tbf for prio qdisc classes 12 | ---- 2004-04-30 ---- Andreas Klauer ---- 13 | removed tbf since it didn't do anything useful anyway. 14 | straightened out sfq qdiscs. 15 | prioritizing ACK packets; modifying TOS; as shown by Stef Coene 16 | on www.docum.org (great page, thanks, actually I use loads of 17 | hints from there and got great results!) 18 | ---- 2004-04-30 ---- Andreas Klauer ---- 19 | Added ingress queue again 20 | Stupid me, forgot the 'bps' after rate values here and there. 21 | This messed everything up :-) 22 | ---- 2004-05-01 ---- Andreas Klauer ---- 23 | Added much more flexible user and port forwarding handling. 24 | The script now supports any number of users (as long as they 25 | are in the same subnet) and complex port forwarding rules. 26 | The downside to this is that the script looks more complicated 27 | now. I tried to compensate this effect by adding lots of hopefully 28 | helpful comments. 29 | ---- 2004-05-03 ---- Andreas Klauer ---- 30 | For better readability, moved all variables that are used for basic 31 | configuration into a separate file. Now people who don't want to 32 | change the script itself don't even need to take a look at it. 33 | ---- 2004-05-03 ---- Andreas Klauer ---- 34 | Moved Change-Entries from the Script into a separate file CHANGELOG. 35 | Looks like there already was another project/script called ipshape. 36 | I renamed the script from ipshape to fairnat to avoid confusion. 37 | ---- 2004-05-03 ---- v0.69 ---- Andreas Klauer ---- 38 | Nothing big, just a small bugfix and some typos. 39 | Included some of the kernel patches I use. 40 | ---- 2004-05-05 ---- v0.70 ---- Andreas Klauer ---- 41 | Restructured the whole script. I use subroutines now. Means less C&P. 42 | Added command line arguments stop, info and . 43 | Added User grouping. Lets you treat multiple IPs as single user. 44 | New kernel-patch: htb removes HTB_HYSTERIES. May be good for pings on 45 | slow lines like mine. 46 | ---- 2004-05-06 ---- v0.71 ---- Andreas Klauer ---- 47 | Class numbers are now derived from user IP instead of array index. 48 | This makes reading tc statistics much easier. 49 | ---- 2004-05-08 ---- v0.72 ---- Andreas Klauer ---- 50 | Added experimental support for IPP2P. If you use it, you can either 51 | disable all P2P traffic in general or allow it with lowest priority. 52 | ---- 2004-05-10 ---- v0.73 ---- Andreas Klauer ---- 53 | User upload rates were not calculated correctly (rate was set far 54 | too high, even heigher than ceil) since v0.69 and nobody noticed. 55 | This bug caused a lot of unnecessary packet drops. 56 | ---- 2004-05-12 ---- v0.74 ---- Andreas Klauer ---- 57 | Improved 'tc' binary detection. Now looks for both tc-htb and tc. 58 | Moved code from start_fairnat to new function parent_class for easier 59 | class structure (shaping method) replacement. Normalized iptables calls. 60 | 61 | New features to be enabled in the config file: 62 | - Turn bandwidth borrowing/lending off. (BORROW) 63 | - MSS Clamping hack. (MSS_CLAMP) 64 | - Drop previously marked IPP2P connections. (IPP2P_DROP_MARKED) 65 | - Use different class structures. (CLASS_MODE) 66 | 67 | Added 'Wondershaper'-alike class structure (CLASS_MODE="wonder"). 68 | ---- 2004-05-13 ---- v0.75 ---- Andreas Klauer ---- 69 | New hacks: HTB_MPU and HTB_OVERHEAD 70 | I label them hacks because these require a special patched tc binary. 71 | ---- 2004-08-07 ---- v0.76 ---- Andreas Klauer ---- 72 | Mini-Update: Forgot to remove some debug stuff. 73 | ---- 2004-10-22 ---- v0.77 ---- Andreas Klauer ---- 74 | Added USER_CEIL_UP and USER_CEIL_DOWN. You can use it to set all users 75 | to a ceil rate lower than total available bandwidth. 76 | ---- 2004-11-15 ---- v0.78 ---- Andreas Klauer ---- 77 | The IP address wasn't detected correctly for localized 'ifconfig's. 78 | Made the previously hardcoded TTL setting configurable. 79 | ---- 2005-04-19 ---- v0.79 ---- Andreas Klauer ---- 80 | You can now specify rates other than kbit (Syntax like tc) 81 | You can specify a ceil rate using @[|]. 82 | ---- 2005-08-21 ---- v0.80 ---- Andreas Klauer ---- 83 | Added selectable FEATURES for even more customizability. 84 | Moved all iptables rules into separate chains exclusive to Fair NAT 85 | in order to avoid collision with already existing rules (Firewalls). 86 | Added IPP2P_UDP setting to enable this recently added IPP2P feature. 87 | Kernel patches are no longer included. See README.patches. 88 | -------------------------------------------------------------------------------- /fairnat.config: -------------------------------------------------------------------------------- 1 | # ---------------------------------------------------------------------------- 2 | # File: /etc/ppp/fairnat.config 3 | # Description: Example configuration file for the fairnat.sh Script 4 | # You should be able to do pretty much everything here. 5 | # Change FAIRNAT_CONFIG in fairnat.sh if you want another default 6 | # location for this configuration file. This variable is at the 7 | # beginning of the script. 8 | # Version: 0.80 9 | # ---------------------------------------------------------------------------- 10 | 11 | # --- Features --- 12 | 13 | # Specify what you want Fair NAT to do here. 14 | # Leave things you don't want out. See below for a list. 15 | # If you don't know what to do here, leave as is. 16 | # Order does not matter. 17 | FEATURES="PROC MODULES RESET NAT FORWARD QOS_DOWN QOS_UP TOS" 18 | 19 | # PROC: 20 | # Allow Fair NAT to change some system variables in /proc, 21 | # like setting /proc/sys/net/ipv4/ip_forward to 1. 22 | # 23 | # MODULES: 24 | # Try to load kernel modules for QoS first. 25 | # 26 | # RESET: 27 | # Fair NAT will replace all existing iptables rules with 28 | # a very basic configuration. Not healthy for firewalls. 29 | # See README for details on firewall compatibility. 30 | # (Even without this, Fair NAT will reset it's own rules.) 31 | # 32 | # NAT: 33 | # Fair NAT will configure NAT. 34 | # 35 | # FORWARD: 36 | # Fair NAT will configure port forwarding. 37 | # 38 | # QOS_DOWN: 39 | # Configure LAN device for download shaping. 40 | # Existing shaping rules for the LAN device will be removed. 41 | # 42 | # QOS_UP: 43 | # Configure Internet device for upload shaping. 44 | # Existing shaping rules for the Internet device will be removed. 45 | # 46 | # TOS: 47 | # Allow Fair NAT to change TOS (type-of-service) flag of packets. 48 | # Right now, Fair NAT heavily relies on this TOS field for shaping, 49 | # so using this feature is highly recommended. 50 | 51 | # --- LAN --- 52 | 53 | # Specify the network device which is connected with your clients. 54 | # The script assumes that this device has one static IP. 55 | DEV_LAN=eth1 56 | 57 | # Please tell me how fast your local area network is in kbit/s. 58 | # It must be higher than your internet connection speed. 59 | # 60 | # If your internet connection is the same speed as your LAN, use 61 | # a higher value here anyway - collisions between download and 62 | # local traffic can't be avoided then. 63 | # 64 | # Default is 2MBit. Please keep in mind that even on 65 | # a 10Mbit/100MBit LAN you rarely can use the full rate (because 66 | # of overhead, collisions, etc.). 67 | RATE_LAN=2mbit 68 | 69 | # --- Internet --- 70 | 71 | # Specify the network device that is connected to the internet. 72 | # If you are a dialup user, you have to re-run the script every 73 | # time you redial. 74 | DEV_NET=ppp0 75 | 76 | # Specify the upload speed of your internet connection in kbit/s. 77 | # Since ISPs tend to overestimate the speeds they offer, it would 78 | # probably be best if you measure this on a free line. 79 | RATE_UP=128kbit # 128 kbit (common value for DSL in germany) 80 | 81 | # Specify the download speed of your internet connection in kbit/s. 82 | # Same as RATE_UP, you probably should measure this. 83 | RATE_DOWN=768kbit # 768 kbit (common value for DSL in germany) 84 | 85 | # In order to prevent traffic queuing at the ISP side or in your modem, 86 | # we shape to a slightly lower rate. This way the bottleneck is the router, 87 | # not the ISP or modem, which allows us more direct control of shaping. 88 | # Per default, we sub 5% of bandwidth for this. If you do not have the 89 | # bottleneck problem, set it to 0. 90 | RATE_SUB_PERCENT=5 91 | 92 | # How much % of the bandwidth should be allowed for the router? 93 | # Use a minimum of 1 here, since the router usually always needs 94 | # some bandwidth, for example for DNS queries to the outer world, 95 | # or SSH sessions from the outer world. 96 | RATE_LOCAL_PERCENT=5 97 | 98 | # --- Clients: --- 99 | 100 | # Specify the clients for which we do Masquerading and Shaping. 101 | # The script assumes that all clients have static IPs in the 102 | # same subnet as your LAN device. 103 | # 104 | # Example: If the IP of DEV_LAN is 192.168.100.42, the line above 105 | # means that 192.168.100.2, 192.168.100.5, etc., are 106 | # the IPs of your clients. 107 | # 6:23:25 is a group of 3 IPs that all belong to the same user. 108 | # Use this notation if a single person has more than one machine 109 | # /IP connected to the router. 110 | # 111 | # New: You can also specify a custom ceil rate per user. 112 | # Syntax: @[|] 113 | # However, ceil has to be bigger than the guaranteed rate, 114 | # otherwise you will get weird results. 115 | USERS="2 5 6:23:25 183@1mbit|100kbit" 116 | 117 | # If you have clients which need certain port (ranges) to be forwarded, 118 | # specify them here. The format is "client port client port ...". 119 | # The example below will forward ports 4000-6999 to 192.168.100.2 and 120 | # ports 2000-3999 to 192.168.100.183. 121 | PORTS="2 4000:6999 183 2000:3999" 122 | # PORTS="" # this disables port forwarding. 123 | 124 | # This setting affects the class structure set for each user. 125 | # "default": one HTB class per user and puts PRIO and SFQ on top of it. 126 | # "wonder": uses ~3 HTB classes per user and uses HTB prio parameter. 127 | # Very similar to the structure used in Bert Hubert's Wondershaper. 128 | CLASS_MODE="default" 129 | 130 | # Are users allowed to 'borrow' other user's bandwidth if they don't use them? 131 | # Usually this is a good thing, even if you never have inactive clients. 132 | # Set to 0 if you don't want to allow users to borrow other users bandwidth. 133 | BORROW=1 134 | 135 | # Usually, each user may use up to $RATE_UP / $RATE_DOWN (see above), e.g. all 136 | # available bandwidth, as long as the line is free. If you want a lower limit, 137 | # you can set it here. 138 | # 139 | # For example, you have a 500kbit line but don't want a single client to use 140 | # more than 300kbit for himself. Then you set RATE_DOWN above to 500 and 141 | # this variable here to 300. 142 | # 143 | # CEIL_USER_UP=0 144 | # CEIL_USER_DOWN=0 145 | 146 | # --- Support for IPP2P (Experimental) --- 147 | 148 | # If you want to use IPP2P (marking & tracking P2P connections), set to 1. 149 | # To use IPP2P, you need a patched kernel and iptables. Unless you activate 150 | # dropping below, you also need the CONNMARK patch. 151 | # Learn more about IPP2P here: 152 | # http://rnvs.informatik.uni-leipzig.de/ipp2p/index_en.html (english) 153 | # or http://rnvs.informatik.uni-leipzig.de/ipp2p/index.html (german) 154 | IPP2P_ENABLE=0 155 | 156 | # Tell us which options to use for IPP2P: 157 | # Default: Cover all P2P protocols. 158 | # See IPP2P documentation for details. 159 | IPP2P_OPTIONS="--ipp2p --apple --bit" 160 | 161 | # Let IPP2P check UDP packets also? Set to 1 if you want that feature. 162 | # An up-to-date IPP2P version is required for this. 163 | IPP2P_UDP=0 164 | 165 | # If P2P traffic should be forbidden in general, set to 1. 166 | # Otherwise P2P will be allowed with lowest priority. 167 | # This only has an effect if IPP2P_ENABLE=1 168 | # Please note that only new connections will be affected. 169 | IPP2P_DROP_ALL=0 170 | 171 | # Together with IPP2P_DROP_ALL=1, this setting will allow dropping 172 | # of already existing & marked connections. Use this only if you 173 | # sometimes switch from allowing P2P to dropping P2P. 174 | IPP2P_DROP_MARKED=0 175 | 176 | # --- Hacks --- 177 | 178 | # This section is for all the bloody stuff. Well, it's not as bad as it sounds, 179 | # but you should read a bit of external documentation before using these. 180 | # No, I'm not explaining them here. You should know what you're doing. 181 | 182 | # * MSS Clamping 183 | # Work around bad MTU settings. 184 | # See also http://www.lartc.org/lartc.html#LARTC.COOKBOOK.MTU-MSS) 185 | MSS_CLAMPING=0 186 | # MSS_CLAMPING="--clamp-mss-to-pmtu" 187 | # MSS_CLAMPING="--set-mss 128" 188 | 189 | # * Set Time To Live (TTL) of outgoing packets 190 | # Specify the maximum number of hops to the clients here. A too low value will 191 | # effectively break your internet connection. 192 | # See also http://iptables-tutorial.frozentux.net/iptables-tutorial.html#TTLTARGET 193 | TTL_SET=0 194 | # TTL_SET=64 195 | 196 | # * Specify overhead for HTB 197 | # From the LARTC Howto on MPU: 198 | # "A zero-sized packet does not use zero bandwidth. For ethernet, no packet 199 | # uses less than 64 bytes. The Minimum Packet Unit determines the minimal 200 | # token usage for a packet." 201 | HTB_MPU=0 202 | # HTB_MPU=64 # Ethernet 203 | # HTB_MPU=106 # According to Andy Furniss, this value is suited for DSL users 204 | 205 | # Specify overhead per packet for HTB. 206 | HTB_OVERHEAD=0 207 | # I don't use this myself yet. :-P Tell me some good values. 208 | 209 | # The following is in the hacks section because it could allow running 210 | # multiple instances of Fair NAT on a single server (whatever you'd want 211 | # that for). The prefix is used for iptables chains used by Fair NAT. 212 | FAIRNAT_PREFIX="FAIRNAT" 213 | 214 | 215 | # --- Binaries --- 216 | 217 | # For this script, you need a tc-tool that supports HTB. 218 | # Per default, the script looks first for tc-htb, then for tc. 219 | # Set name directly if your HTB-enabled tc is called something else. 220 | 221 | # BIN_TC=`which tc` use this if your binary is called tc 222 | # BIN_TC="/root/bin/my_tc" or set the full path directly like this. 223 | 224 | # All binarys used by Fair NAT can be configured like BIN_TC above: 225 | # 226 | # BIN_IPT: iptables (with support for HTB and probably IPP2P) 227 | # BIN_TC: tc (with support for HTB, see above) 228 | # BIN_IFC: ifconfig 229 | # BIN_GREP: grep 230 | # BIN_SED: sed 231 | # BIN_ECHO: echo 232 | # BIN_MODPROBE modprobe 233 | # 234 | # If you don't specify these, the first binary found in your PATH 235 | # will be used, which should work for most people. 236 | 237 | # ---------------------------------------------------------------------------- 238 | -------------------------------------------------------------------------------- /fairnat_wrt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Simplified version of the FairNAT script for OpenWRT. 5 | # Install qos-scripts (this will take care of the dependencies), 6 | # but make it execute this script instead - after you customized 7 | # it to your needs of course. 8 | # 9 | # Author: Andreas Klauer (Andreas.Klauer@metamorpher.de) 10 | # Version: 0.2 (2009-07-21) 11 | # URL: http://www.metamorpher.de/fairnat 12 | # License: GPL 13 | # 14 | 15 | # ---- Variables: ---- 16 | 17 | DEBUG=1 18 | RATE_UP=600 19 | RATE_DOWN=14000 20 | RATE_SUB_PERCENT=10 21 | RATE_LOCAL_PERCENT=1 22 | RATE_TO_QUANTUM=20 23 | OVERHEAD=64 24 | MPU=128 25 | 26 | # ---- Helper functions: ---- 27 | 28 | rate() 29 | { 30 | RATE=0 31 | R_RATE=$1 32 | R_NUMBER=`echo "$R_RATE" | sed -e "s/[^0-9]//g"` 33 | R_UNIT=`echo "$R_RATE" | sed -e "s/[0-9]//g"` 34 | 35 | if [ "$R_UNIT" == "" ]; 36 | then 37 | R_UNIT="kbit" 38 | fi 39 | 40 | # Let's see which unit we have... 41 | if [ "$R_UNIT" == "kbps" ] 42 | then 43 | R_RATE=$(($R_NUMBER * 1024)) 44 | elif [ "$R_UNIT" == "mbps" ] 45 | then 46 | R_RATE=$(($R_NUMBER * 1024 * 1024)) 47 | elif [ "$R_UNIT" == "mbit" ] 48 | then 49 | R_RATE=$(($R_NUMBER * 1024 * 1024 / 8)) 50 | elif [ "$R_UNIT" == "kbit" ] 51 | then 52 | R_RATE=$(($R_NUMBER * 1024 / 8)) 53 | elif [ "$R_UNIT" == "bps" ] 54 | then 55 | R_RATE=$R_NUMBER 56 | else 57 | echo "Unknown unit '$R_UNIT'. I only know mbps, mbit, kbit, bps." 58 | fi 59 | 60 | RATE="$R_RATE" 61 | } 62 | 63 | load_modules() 64 | { 65 | insmod imq numdevs=1 >&- 2>&- 66 | insmod cls_fw >&- 2>&- 67 | insmod sch_hfsc >&- 2>&- 68 | insmod sch_sfq >&- 2>&- 69 | insmod sch_red >&- 2>&- 70 | insmod sch_htb >&- 2>&- 71 | insmod sch_prio >&- 2>&- 72 | insmod ipt_multiport >&- 2>&- 73 | insmod ipt_CONNMARK >&- 2>&- 74 | insmod ipt_length >&- 2>&- 75 | insmod ipt_IMQ >&- 2>&- 76 | } 77 | 78 | reset() 79 | { 80 | ifconfig ppp0 up txqueuelen 5 >&- 2>&- 81 | ifconfig imq0 up txqueuelen 5 >&- 2>&- 82 | tc qdisc del dev ppp0 root >&- 2>&- 83 | tc qdisc del dev imq0 root >&- 2>&- 84 | iptables -t mangle -F 85 | iptables -t mangle -X 86 | iptables -t mangle -N FairNAT >&- 2>&- 87 | iptables -t mangle -N FairNAT_connmark >&- 2>&- 88 | iptables -t mangle -N FairNAT_tos >&- 2>&- 89 | iptables -t mangle -N FairNAT_tos_ack >&- 2>&- 90 | iptables -t mangle -N FairNAT_tos_chk >&- 2>&- 91 | 92 | # For acquiring DSL data from SpeedTouch modem that is connected to WAN: 93 | # ifconfig eth0.1 192.168.1.42 94 | } 95 | 96 | tc_class_add_htb() 97 | { 98 | t_parent=$1 99 | t_classid=$2 100 | t_rate=$3 101 | t_ceil=$4 102 | 103 | t_quantum=$(($t_rate/$RATE_TO_QUANTUM)) 104 | 105 | if [ $t_quantum -lt 1500 ]; 106 | then 107 | if [ "$DEBUG" == "1" ] 108 | then 109 | echo $DEVICE $t_classid quantum $t_quantum small: increasing to 1500 110 | fi 111 | 112 | t_quantum=1500 113 | fi 114 | 115 | if [ $t_quantum -gt 60000 ]; 116 | then 117 | if [ "$DEBUG" == "1" ] 118 | then 119 | echo $DEVICE $t_classid quantum $t_quantum big: reducing to 60000 120 | fi 121 | 122 | t_quantum=60000 123 | fi 124 | 125 | if [ "$DEBUG" == "1" ] 126 | then 127 | echo tc class add dev $DEVICE parent $t_parent classid $t_classid htb rate "$t_rate"bps ceil "$t_ceil"bps quantum "$t_quantum" overhead $OVERHEAD mpu $MPU 128 | fi 129 | 130 | tc class add dev $DEVICE parent $t_parent classid $t_classid htb rate "$t_rate"bps ceil "$t_ceil"bps quantum "$t_quantum" overhead $OVERHEAD mpu $MPU 131 | } 132 | 133 | # ---- Generic: ---- 134 | 135 | mangle() 136 | { 137 | # -- Correcting TOS for known services: -- 138 | # (This is useful only if you prioritize packets by TOS later) 139 | iptables -t mangle -A FairNAT_tos -p icmp -j TOS --set-tos Minimize-Delay 140 | iptables -t mangle -A FairNAT_tos -p tcp --sport 23 -j TOS --set-tos Minimize-Delay 141 | iptables -t mangle -A FairNAT_tos -p tcp --sport 22 -j TOS --set-tos Minimize-Delay 142 | iptables -t mangle -A FairNAT_tos -p tcp --sport 21 -j TOS --set-tos Minimize-Delay 143 | iptables -t mangle -A FairNAT_tos -p tcp --sport 20 -j TOS --set-tos Maximize-Throughput 144 | iptables -t mangle -A FairNAT_tos -p tcp --dport 23 -j TOS --set-tos Minimize-Delay 145 | iptables -t mangle -A FairNAT_tos -p tcp --dport 22 -j TOS --set-tos Minimize-Delay 146 | iptables -t mangle -A FairNAT_tos -p tcp --dport 21 -j TOS --set-tos Minimize-Delay 147 | iptables -t mangle -A FairNAT_tos -p tcp --dport 20 -j TOS --set-tos Maximize-Throughput 148 | 149 | # Correcting TOS for large packets with Minimize-Delay-TOS 150 | iptables -t mangle -A FairNAT_tos_chk -p tcp -m length --length 0:512 -j RETURN 151 | iptables -t mangle -A FairNAT_tos_chk -p udp -m length --length 0:1024 -j RETURN 152 | iptables -t mangle -A FairNAT_tos_chk -j TOS --set-tos Maximize-Throughput 153 | 154 | iptables -t mangle -A FairNAT_tos -m tos --tos Minimize-Delay -j FairNAT_tos_chk 155 | 156 | # Modifying TOS for TCP control packets: (from www.docum.org / Stef Coene) 157 | iptables -t mangle -A FairNAT_tos_ack -m tos --tos ! Normal-Service -j RETURN 158 | iptables -t mangle -A FairNAT_tos_ack -p tcp -m length --length 0:256 -j TOS --set-tos Minimize-Delay 159 | iptables -t mangle -A FairNAT_tos_ack -p tcp -m length --length 256: -j TOS --set-tos Maximize-Throughput 160 | 161 | iptables -t mangle -A FairNAT_tos -p tcp -m tcp --tcp-flags SYN,RST,ACK ACK -j FairNAT_tos_ack 162 | 163 | # Calling TOS chain from PREROUTING chain 164 | iptables -t mangle -A PREROUTING -j FairNAT_tos 165 | 166 | # -- Marking packets: -- 167 | iptables -t mangle -A FairNAT -j CONNMARK --restore-mark 168 | iptables -t mangle -A FairNAT -m mark ! --mark 0 -j RETURN 169 | iptables -t mangle -A FairNAT -j FairNAT_connmark 170 | iptables -t mangle -A FairNAT -j CONNMARK --save-mark 171 | 172 | # Linking FairNAT chains with standard chains: 173 | iptables -t mangle -A FORWARD -m mark --mark 0 -o ppp0 -j FairNAT 174 | iptables -t mangle -A FORWARD -m mark --mark 0 -i ppp0 -j FairNAT 175 | iptables -t mangle -A POSTROUTING -m mark --mark 0 -o ppp0 -j FairNAT 176 | iptables -t mangle -A PREROUTING -m mark --mark 0 -i ppp0 -j FairNAT 177 | iptables -t mangle -A FORWARD -m mark --mark 0 -j FairNAT 178 | iptables -t mangle -A PREROUTING -i ppp0 -j IMQ --todev 0 179 | 180 | # Adding user specific rules: 181 | mangle_alexander 182 | mangle_andreas 183 | } 184 | 185 | qos() 186 | { 187 | if [ "$DEBUG" == "1" ] 188 | then 189 | echo -------- 190 | fi 191 | 192 | DEVICE=$1 193 | rate $2 194 | TOTAL_RATE=$((($RATE*(100-$RATE_SUB_PERCENT))/100)) 195 | USER_RATE=$((($TOTAL_RATE*(100-$RATE_LOCAL_PERCENT))/100)) 196 | LOCAL_RATE=$(($TOTAL_RATE-$USER_RATE)) 197 | 198 | tc qdisc add dev $DEVICE root handle 1: htb default 30 r2q 5 199 | tc_class_add_htb 1: 1:1 $TOTAL_RATE $TOTAL_RATE 200 | tc_class_add_htb 1:1 1:30 $LOCAL_RATE $TOTAL_RATE 201 | tc qdisc add dev $DEVICE parent 1:30 handle 300: prio 202 | 203 | qos_alexander $DEVICE $((USER_RATE/2)) $TOTAL_RATE 204 | qos_andreas $DEVICE $((USER_RATE/2)) $TOTAL_RATE 205 | 206 | if [ "$DEBUG" == "1" ] 207 | then 208 | echo -------- 209 | fi 210 | } 211 | 212 | # ---- Alexander: ---- 213 | 214 | qos_alexander() 215 | { 216 | DEVICE="$1" 217 | RATE="$2" 218 | CEIL="$3" 219 | 220 | tc_class_add_htb 1:1 1:20 $RATE $CEIL 221 | tc_class_add_htb 1:20 1:210 $(($RATE*9/10)) $CEIL 222 | tc_class_add_htb 1:20 1:220 $(($RATE/10)) $CEIL 223 | tc_class_add_htb 1:220 1:221 $(($RATE/20)) $CEIL 224 | tc_class_add_htb 1:220 1:222 $(($RATE/20)) $CEIL 225 | 226 | tc qdisc add dev $DEVICE parent 1:210 handle 210: prio 227 | 228 | tc filter add dev $DEVICE parent 1: prio 1 protocol ip handle 0x20 fw flowid 1:210 229 | tc filter add dev $DEVICE parent 1: prio 1 protocol ip handle 0x21 fw flowid 1:221 230 | tc filter add dev $DEVICE parent 1: prio 1 protocol ip handle 0x22 fw flowid 1:222 231 | } 232 | 233 | mangle_alexander() 234 | { 235 | # reserved mark values: 0x20-0x2F 236 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0 -s 192.168.0.2 -j MARK --set-mark 0x20 237 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0x20 -m tos --tos Maximize-Throughput -j MARK --set-mark 0x21 238 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0x20 -m tos --tos Minimize-Cost -j MARK --set-mark 0x22 239 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0 -d 192.168.0.2 -j MARK --set-mark 0x20 240 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0 -i ppp0 -p tcp --dport 22 -j MARK --set-mark 0x20 241 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0 -i ppp0 -p tcp --dport 47252 -j MARK --set-mark 0x22 242 | } 243 | 244 | # ---- Andreas: ---- 245 | 246 | qos_andreas() 247 | { 248 | DEVICE="$1" 249 | RATE="$2" 250 | CEIL="$3" 251 | 252 | tc_class_add_htb 1:1 1:10 $RATE $CEIL 253 | 254 | tc qdisc add dev $DEVICE parent 1:10 handle 100: prio 255 | 256 | tc filter add dev $DEVICE parent 1: prio 1 protocol ip handle 0x10 fw flowid 1:10 257 | } 258 | 259 | mangle_andreas() 260 | { 261 | # reserved mark values: 0x10-0x1F 262 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0 -s 192.168.0.3 -j MARK --set-mark 0x10 263 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0 -d 192.168.0.3 -j MARK --set-mark 0x10 264 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0 -s 192.168.0.66 -j MARK --set-mark 0x10 265 | iptables -t mangle -A FairNAT_connmark -m mark --mark 0 -d 192.168.0.66 -j MARK --set-mark 0x10 266 | } 267 | 268 | # ---- Main program ---- 269 | 270 | load_modules 271 | reset 272 | mangle 273 | 274 | # Acquire actual rate from SpeedTouch modem: 275 | # BANDWIDTH=`echo -e "root\r\npassword\r\nadsl info\r\nexit\r\n" | nc 192.168.1.254 23 | grep Bandwidth | sed -e s/[^0-9]/\ /g` 276 | # 277 | # for word in $BANDWIDTH 278 | # do 279 | # RATE_DOWN=$RATE_UP 280 | # RATE_UP=$word 281 | # done; 282 | 283 | if [ "$DEBUG" == "1" ] 284 | then 285 | echo Setting up Fair NAT with $RATE_UP kbit up / $RATE_DOWN kbit down. 286 | fi 287 | 288 | qos ppp0 "$RATE_UP"kbit 289 | qos imq0 "$RATE_DOWN"kbit 290 | 291 | # ---- End of file. ---- 292 | -------------------------------------------------------------------------------- /GPL: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | 342 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Fair NAT for Linux Routers 2 | 3 | last updated: 2005-08-21 01:10 CEST 4 | 5 | What's this? 6 | 7 | This is the home of my linux router shaper script which allows 8 | something like fair bandwidth sharing among clients in the local 9 | network. The script is not great or anything - please don't expect the 10 | holy grail here - I just thought I'd publish it because many people 11 | helped me write it and maybe someone has some use for it. I bet there 12 | are still lots of things that can be improved. Sorry about the crappy 13 | design of this page, I don't have time to put more effort in better 14 | looks. 15 | 16 | Network 17 | 18 | Here's a very basic ASCII-art which shows my network situation: 19 | +-----+ 20 | +--------+ | S | 21 | | User A |---+ W | 22 | +--------+ | I | 23 | +--------+ | T | +--------+ +----------+ 24 | | User B |---+ C +-----| Router |--------| Internet | 25 | +--------+ | H | +--------+ +----------+ 26 | .... ... / ... 27 | +--------+ | H | 28 | | User N |---+ U | 29 | +--------+ | B | 30 | +-----+ 31 | 32 | In words, it's a common setup. You have one internet connection, one 33 | router and several people in your LAN (family, roommates, neighbours, 34 | ...) who all want to use the internet. 35 | 36 | Problem 37 | 38 | You have a certain number of Clients (User A - User N) in your LAN 39 | which are connected by a Switch (or a Hub or BNC) to the Linux Router 40 | which is supposed to act as a gateway to the internet. The trouble now 41 | is, User B has a lot of downloads running and User C uploads stuff day 42 | and night, which leaves User A who only wants to use an interactive 43 | SSH shell in the rain, since B and C already use up all bandwidth the 44 | internet connection offers. 45 | 46 | Solution 47 | 48 | What we need to do is to share available bandwidth fairly among 49 | clients. In order to achieve this, I first tried several searches at 50 | [1]Google and [2]Freshmeat. This turned up quite a lot of results, 51 | like the [3]Linux Advanced Routing & Traffic Control HOWTO which is a 52 | must-read and also contains great scripts, like the Wondershaper for 53 | single users. Another great general purpose script I found was 54 | [4]HTB.init, which doesn't do anything by default, but gives you an 55 | easy way to setup HTB queues. In case you prefer CBQ, there's a 56 | CBQ.init too. If you don't know what I'm talking about, read the HOWTO 57 | above or continue reading here. 58 | 59 | Script 60 | 61 | Since I never found a script that did exactly what I wanted, I decided 62 | to write my own. It's designed to be an all-I-need script, therefore 63 | it does not just setup Traffic Shaping, but Masquerading and Port 64 | Forwarding too. In short, it does everything that has to do with 65 | IPTables and Traffic Control. I use HTB (Hierarchical Token Bucket) to 66 | share bandwidth among clients (one class per client). On top of that I 67 | added a PRIO queue to prioritize interactive traffic on a per-user 68 | basis. On top of PRIO I set SFQ to treat connections fairly. In 69 | version 0.72, experimental support for IPP2P to recognize peer-to-peer 70 | traffic was added. 71 | 72 | This is the simplified class setup for per user Fair NAT uses per 73 | default: 74 | HTB class (for bandwidth sharing) 75 | | 76 | \-- PRIO (for prioritizing interactive traffic) 77 | | 78 | \--- Interactive: SFQ (to treat concurrent connections fairly) 79 | \--- Normal: SFQ 80 | \--- High-Traffic: SFQ 81 | [ \--- P2P: SFQ (if IPP2P support is enabled only) ] 82 | 83 | I bet this can still be improved and I'm always interested in ways to 84 | do so. In case you want another class structure, this can be done by 85 | replacing the parent_class and user_class functions in the script. See 86 | CLASS_MODE in Configuration section and the function documentation in 87 | the script for details. Feel free to send me your own functions with a 88 | short explanation, if you want me to make them available for 89 | everybody. 90 | 91 | Here's a "real" graphic, which shows the complete qdisc/class 92 | structure on $DEV_LAN if you use the unmodified example configuration 93 | file. This graphic was created using a hacked version of Stef Coene's 94 | show.pl script and GraphViz. Click [5]here to see it, but I warn you: 95 | it's quite big. Here's a [6]similar picture, which includes IPP2P 96 | support. Note that there are more filter rules (the blue arrows) now 97 | which put the filesharing traffic into the user's prio band 4. 98 | 99 | What you can and what you can't expect 100 | 101 | Without traffic shaping, users with low-traffic, interactive 102 | connections experience ping times between 2-5 seconds, when other 103 | users have up- and downloads running. This is of course deadly for SSH 104 | connections. You can't work on remote machines like that. With my 105 | script, I get much lower pings, at about 100-200ms. Compared to the 106 | 2000-5000ms before, this is a huge improvement. However, considering 107 | that the ping on a free line would be at around 50ms, the connection 108 | still feels laggy. It's nearly impossible to make perfect interactive 109 | connections if the line is maxed out in both directions. 110 | 111 | Requirements 112 | 113 | For this script, you need iptables, tc and a QoS-enabled kernel. All 114 | these binaries must support HTB (usually the case unless you got a 115 | really old installation, in which case you ought to update anyway). I 116 | also use several kernel patches, none of which are actually required 117 | (unless if you want P2P shaping and some other Hacks). See 118 | README.patches in the tarball. 119 | 120 | Configuration 121 | 122 | Wheee, configuration. At first, my script didn't even have a 123 | configuration file. Now that it has one, a whole load of options were 124 | added to it. An example configuration file with lots of comments is 125 | included in the package. The stuff you most likely will have to change 126 | is the devices, the rates and the user settings. Otherwise the script 127 | won't work. The other stuff is mainly for people who know what they're 128 | doing. 129 | * FEATURES 130 | + This is a variable with a space-separated list of features 131 | that should be enabled. Default is all enabled if you dont 132 | set this variable. 133 | + PROC: 134 | Allow Fair NAT to change some system variables in /proc, like 135 | setting /proc/sys/net/ipv4/ip_forward to 1. 136 | + MODULES: 137 | Try to load kernel modules for QoS first. 138 | + RESET: 139 | Fair NAT will replace all existing iptables rules with a very 140 | basic (empty) configuration. Not healthy for firewalls. You 141 | can disable this feature to keep the original rules in place. 142 | See Firewall Support below. 143 | + NAT: 144 | Allow Fair NAT to configure NAT. You could disable this if 145 | you prefer to set this up yourself / let your firewall do it. 146 | + FORWARD: 147 | Allow Fair NAT to configure Port Forwarding. Same as NAT, you 148 | can disable this if you don't need it. 149 | + QOS_DOWN: 150 | Shape download traffic. If you know a little bit about 151 | traffic shaping and believe that download shaping is 152 | completely useless, feel free to disable this. 153 | + QOS_UP: 154 | Shaping upload traffic can be disabled also. If you disable 155 | this and QOS_DOWN also, you could use Fair NAT for setting up 156 | NAT and Port Forwarding only, although that's not really the 157 | purpose of the script ;-) 158 | + TOS: 159 | Allow Fair NAT to modify the TOS (type-of-service) field of 160 | packets. Right now, Fair NAT relies on this TOS field for 161 | shaping, so using this feature is highly recommended. 162 | * LAN 163 | + DEV_LAN: 164 | The network device your local clients are connected to. For 165 | example eth1. 166 | + RATE_LAN: 167 | The transfer rate in kbit/s of your LAN. This should be 168 | faster than your internet connection speed. Use a realistic 169 | value here. Don't blindly use 10/100Mbit on a 10/100Mbit 170 | network - you usually don't get those speeds because of 171 | overhead, collisions and such. 172 | * Internet 173 | + DEV_NET: 174 | The network device of your internet connection. For example 175 | ppp0. 176 | + RATE_UP: 177 | Your internet upload connection speed in kbit/s. Since ISPs 178 | tend to overestimate their rates, you should use a realistic 179 | value here (measure it on a completely free line). 180 | NEW: Now you can also specify a unit for a rate. Supported 181 | units are kbps, mbps, mbit, kbit, and bps (same as 'tc'). If 182 | no unit is specified, kbit will be used per default. 183 | + RATE_DOWN: 184 | Your internet download connection speed in kbit/s. Just like 185 | RATE_UP, you should use a realistic value here. 186 | NEW: Now you can also specify a unit for a rate. Supported 187 | units are kbps, mbps, mbit, kbit, and bps (same as 'tc'). If 188 | no unit is specified, kbit will be used per default. 189 | + RATE_SUB_PERCENT: 190 | If your modem or your ISP has queues, you should make your 191 | router the bottleneck to avoid packet queueing which is bad 192 | for latency. Per default, 5% of bandwidth are subbed to 193 | achieve this. Read more about the bottleneck problem in the 194 | LARTC Howto mentioned above. 195 | + RATE_LOCAL_PERCENT: 196 | How much of your internet bandwidth should the router get? 197 | Usually, the machine requires some bandwidth for DNS requests 198 | (if it does act as an DNS cacher), for SSH access from the 199 | outside and similar. Per default, 5% of bandwidth are used 200 | here, which should be fine for most setups, where the router 201 | does not actively produce traffic (unlike webservers and 202 | such). It's not a hard limit, therefore this setting mainly 203 | ensures low latency for low traffic caused by the router. 204 | * Clients 205 | + USERS: 206 | Specify who to do NAT for (who is allowed to use this machine 207 | as a gateway to the internet). Users are specified per IP and 208 | must be in the same subnet as your LAN device. Therefore only 209 | the last number of the client's machine is needed. For 210 | example, if your gateway is 192.168.100.42, the number 183 211 | would expand to 192.168.100.183. It is also possible to group 212 | IPs (for users with more than one machine on the LAN) using 213 | ':'. So for example "3 4 7:9:12 42 128" stands for 5 users, 214 | one of which has 3 IPs. 215 | NEW: In Fair NAT 0.79, you can also specify a custom ceil 216 | download / upload rate per user. For example 17@300 limits IP 217 | 192.168.100.17 to 300kbit/s download rate. 17@300|50 adds a 218 | 50kbit/s upload limit, and 17@|50 limits upload only. 219 | + PORTS: 220 | Specify which ports are to be forwarded to which user (DNAT). 221 | The syntax is "user port user port ...", whereas user is the 222 | last number of the user's IP (e.g. 42) and port is either a 223 | port number (e.g. 3333) or a port range (e.g. 3000:4000). For 224 | multiple port ranges, the same IP can be specified multiple 225 | times. So for example "3 5000 9 6000:6100 9 6300:6400 42 226 | 7000" means that port 5000 is forwarded to IP 3, ports 227 | 6000-6100 and 6300-6400 are forwarded to IP 9, and port 7000 228 | is forwarded to IP 42. Please note that ports can't be 229 | forwarded to multiple machines, therefore defining 230 | overlapping port ranges won't work. Of course you can also 231 | disable port forwarding in general by setting PORTS to "". 232 | + CLASS_MODE: 233 | There are some other class structures available, in case you 234 | don't like the one described above. Usually, this is set to 235 | "default". If you set it to "wonder" instead, every user will 236 | get a class structure that is pretty similar to what the 237 | Wondershaper script does. There may be others, check the 238 | example configuration file for a detailed list. Of course, if 239 | you have the know-how, you could also add your own by adding 240 | a new parent_class and user_class function to the script. 241 | Send your function to me and I'll include it here. 242 | + BORROW: 243 | Usually, users are allowed to borrow other users' bandwidth, 244 | as long as they don't use it themselves. This way, all 245 | available bandwidth is distributed among currently active 246 | users. If you don't want that for any reason, you can turn it 247 | off by setting this variable to 0. Then every user can only 248 | use the bandwidth that was reserved for him, even if the line 249 | is free. 250 | + USER_CEIL_UP: 251 | With this variable, you can set a lower maximum upload rate 252 | for all users. Default value is $RATE_UP. Useful if you don't 253 | want anyone to have more than, say, 300kbit at all times, on 254 | a 500kbit line. 255 | + USER_CEIL_DOWN: 256 | Allows lowering the maximum download rate for all users. 257 | Explanation see USER_CEIL_UP. 258 | * IPP2P 259 | + IPP2P_ENABLE: 260 | Set to 0 (default), if IPP2P should be disabled. Otherwise 261 | set to 1. The following IPP2P settings only have an effect if 262 | IPP2P_ENABLE is set to 1. 263 | + IPP2P_OPTIONS: 264 | Set IPP2P options. See IPP2P documentation for details. 265 | Basically, you can specify here which P2P protocols should be 266 | detected. Default is "--ipp2p --apple --bit" (detect all 267 | protocols). 268 | + IPP2P_UDP: 269 | Newer versions of IPP2P also support UDP packet matching. Set 270 | this variable to 1 if you want to support it. 271 | + IPP2P_DROP_ALL: 272 | Set to 1, if P2P traffic should be dropped in general. 273 | Otherwise set to 0 (default). Please note that this applies 274 | only to new connections. Already established connections 275 | probably won't be affected. 276 | + IPP2P_DROP_MARKED: 277 | This option has only an effect when you change IPP2P_DROP_ALL 278 | from 0 to 1 while being connected to the internet. If you 279 | enable this, packages of already marked connections will be 280 | dropped, too. 281 | * Hacks 282 | + MSS_CLAMP: 283 | With this, you can enable the MSS Clamping as described in 284 | the LARTC Howto. Please read the appropriate section of the 285 | Howto for further information. 286 | + TTL_SET: 287 | Set the maximum TTL (Time-To-Live) for outgoing packets to a 288 | specific value. This option requires a kernel patch. [7]Click 289 | here for a more detailed description. 290 | + HTB_MPU: 291 | Use MPU for HTB. From the LARTC Howto on MPU: "A zero-sized 292 | packet does not use zero bandwidth. For ethernet, no packet 293 | uses less than 64 bytes. The Minimum Packet Unit determines 294 | the minimal token usage for a packet." This feature requires 295 | a patched tc binary. This binary is included in the package. 296 | Go to the [8]official HTB homepage if you want to patch it 297 | yourself (can be troublesome). Download both HTB and MPU 298 | patches there. 299 | + HTB_OVERHEAD: 300 | Per-packet size overhead used in HTB's rate computations. 301 | According to the HTB page, "overhead implementation is a bit 302 | hack", but I guess that's why this is in the Hacks section of 303 | my script. ;-) 304 | + FAIRNAT_PREFIX: 305 | The prefix is used for Fair NAT's iptables chains. The 306 | default value "FAIRNAT" causes created chains to be called 307 | FAIRNAT_PREROUTING, FAIRNAT_FORWARD, and so on. This is in 308 | the hacks section because changing this could allow running 309 | multiple instances of Fair NAT on a single server (whatever 310 | you'd want that for). 311 | * Binaries 312 | + BIN_TC: 313 | tc binary which supports HTB. Fair NAT will no longer check 314 | for 'tc-htb', since the times when we had to patch the kernel 315 | to obtain HTB support are long gone. 316 | + BIN_IPT: 317 | iptables 318 | + BIN_IFC: 319 | ifconfig 320 | + BIN_GREP: 321 | grep 322 | + BIN_SED: 323 | sed 324 | + BIN_ECHO: 325 | echo 326 | + BIN_MODPROBE: 327 | modprobe 328 | 329 | Command line arguments 330 | 331 | Currently, the following arguments are understood: 332 | * help: 333 | Gives a short overview over the available command line options. 334 | * version: 335 | Prints the version of your script. 336 | * stop: 337 | Resets IPTables and Traffic Shaping to zero. 338 | * info: 339 | Shows information about your current configuration. 340 | * : 341 | This file will be used instead of the default configuration file. 342 | Please note that if you use this feature, you have to specify the 343 | file when using the stop and info parameters too. (It's probably 344 | easier to change the FAIRNAT_CONFIG variable directly in the 345 | script) 346 | 347 | IPP2P support 348 | 349 | Let me add some notes about the IPP2P support introduced in Fair NAT 350 | v0.72. IPP2P provides a (more or less) reliable means to detect 351 | traffic of peer-to-peer (filesharing) applications. To use it, you 352 | first have to patch the kernel and the iptables program. You can get 353 | the patches at the [9]Official IPP2P Homepage along with plenty 354 | documentation. When that's done, you have to enable IPP2P in the Fair 355 | NAT configuration file, too. See the example configuration file for 356 | details. 357 | 358 | Please note that IPP2P also requires the CONNMARK patch, unless you 359 | intend to drop all P2P packets in general. Applying this patch can be 360 | a pain in the ..., it took me several days to do it properly. If you 361 | use the newest version of the CONNMARK patch, you also need a new 362 | version of iptables - at least version 1.2.10 (at the moment, you need 363 | iptables-cvs). Otherwise CONNMARK won't work - you'll get an 'Invalid 364 | Argument' error. Another solution would be using an OLD version of the 365 | CONNMARK patch, but I haven't found any that worked together with 366 | kernel 2.4.26 so far. The patch is part of patch-o-matic-ng which you 367 | can get on the [10]Official Netfilter Homepage . 368 | 369 | If IPP2P is enabled, Fair NAT uses it like this. If P2P traffic is 370 | forbidden in general, all packets recognized by IPP2P are dropped. End 371 | of story. Bye bye. However, if P2P traffic is allowed, Fair NAT does 372 | the following: 373 | * Mark and remember all P2P connections using CONNMARK. 374 | * Mark all packets of P2P-marked connections 375 | * Use 4 instead of 3 prio bands per user. 376 | * If a packet is marked as P2P, use $USER_MARK+1 as new package mark 377 | instead of $USER_MARK 378 | * Put all $USER_MARK+1 packages into prio band 4. Bands 1-3 still 379 | depend on TOS. 380 | 381 | This way, P2P traffic is not limited at all, but gets an even lower 382 | priority than HTTP traffic or FTP transfers. If you don't know what 383 | all this marking stuff is, don't bother. It's just the identifier that 384 | tells the Traffic Shaping mechanism which packet belongs to which 385 | user. 386 | 387 | Firewall Support (Experimental) 388 | 389 | With Fair NAT 0.80, I've started taking the first steps towards 390 | Firewall support (which is one of the most requested features). In 391 | order not to collide with Firewall iptables rules, Fair NAT now 392 | creates it's very own private iptables chains. These can be flushed 393 | without risking to lose something the Firewall might have set up. 394 | 395 | However, there are at least three things about Firewall Support I need 396 | to point out: 397 | * For backward compatibility, Fair NAT will still reset all iptables 398 | rules unless you remove the RESET feature from the FEATURES list 399 | in fairnat.config. 400 | * You will have to modify your Firewall to make it put packets into 401 | the Fair NAT chains - otherwise Fair NAT will not be able to do 402 | anything. See below for the rules you have to add. 403 | * I still don't use a firewall myself, so this implementation is 404 | just an untested theory and might not work at all. 405 | 406 | For Firewall Support, it has to put packets into the Fair NAT chains 407 | at some point. Ideally this is after the Firewall dropped unwanted 408 | packets, but that's just a guess. The best spot to put the rules in 409 | depends on the Firewall. Here's the rules: 410 | 411 | iptables -t nat -A PREROUTING -j FAIRNAT_PREROUTING 412 | iptables -t mangle -A PREROUTING -j FAIRNAT_PREROUTING 413 | iptables -A FORWARD -j FAIRNAT_FORWARD 414 | iptables -t mangle -A FORWARD -j FAIRNAT_FORWARD 415 | iptables -t nat -A POSTROUTING -j FAIRNAT_POSTROUTING 416 | iptables -t mangle -A POSTROUTING -j FAIRNAT_POSTROUTING 417 | 418 | Of course, that's just a suggestion. You can modify these rules any 419 | way you like. However, don't forget that packets that don't go into 420 | the Fair NAT chains, will not be seen by Fair NAT rules, which could 421 | have side effects like packets not being shaped properly and so on. 422 | 423 | Please send me some feedback if this solution works for you. 424 | 425 | Download 426 | 427 | WARNING: Use this script at your own risk only. It may remove all 428 | existing firewall rules, it may have critical bugs that are lethal to 429 | your system, it will set your duck on fire and many more bad things 430 | may happen to you. I'm not responsible for any damage caused by this 431 | script. Handle with care. Thanks. 432 | 433 | The script can be found here: (use 0.79 if you have issues with 0.80) 434 | * [11]fairnat-0.80 (Firewall "support", selectable Features) 435 | * [12]fairnat-0.79 (Custom download / upload ceil per user, support 436 | rate units other than kbit.) 437 | * [13]fairnat-0.78 (Replaced hardcoded TTL setting with the 438 | configuration option TTL_SET. Workaround for localized (i18ned) 439 | ifconfigs where the IP address wasn't detected. Thanks to Simon 440 | for pointing these out.) 441 | * [14]fairnat-0.77 (Just a small feature I was asked for. If you 442 | want all your users to have a lower ceil than total available 443 | bandwidth, set CEIL_USER_UP and CEIL_USER_DOWN. See above for 444 | documentation.) 445 | * [15]fairnat-0.76 (Mini-Update: Forgot to remove some debug rules 446 | in 0.75.) 447 | * [16]fairnat-0.75 (Added HTB hacks: HTB_MPU and HTB_OVERHEAD. These 448 | require a special tc patch available from the [17]HTB homepage. I 449 | included an already patched tc-htb binary into the package.) 450 | * [18]fairnat-0.74 (New config options BORROW, IPP2P_DROP_MARKED, 451 | CLASS_MODE, CLAMP_MSS) 452 | * [19]fairnat-0.73 (Bugfix: user upload rates were totally boggled 453 | which caused traffic to be dropped instead of being shaped 454 | correctly.) 455 | * [20]fairnat-0.72 (minor bugfixes, experimental IPP2P support) 456 | * [21]fairnat-0.71 (Class numbers are now derived from user IP 457 | instead of array index. This makes it much easier to read 458 | class-based statistics. Thanks to Udo for the suggestion.) 459 | * [22]fairnat-0.70 (User grouping allows multiple IPs per user. 460 | Thanks to Tomasz for the suggestion. Added command line arguments 461 | stop, info, ) 462 | * [23]fairnat-0.69 463 | * [24]fairnat-0.68 464 | 465 | Please take the time to read the comments directly in the script, 466 | especially in the sample configuration file, too. I tried to add loads 467 | of comments in case you want to modify some parts of the script. 468 | 469 | Contact 470 | 471 | If you find bugs, please report them. If you have ideas for 472 | improvements, please tell me. If you need more features, ask me to 473 | implement them. If you decide to (not) use the script, drop me a note. 474 | If the script works particularly well (or bad) for you, I want to hear 475 | about it. If you can't get it to work, I'll see what I can do to help 476 | you. No, really. Give me some feedback. I'm tired of having nothing 477 | but spam in my mailbox. Thanks. 478 | 479 | My mail address is: [25]Andreas.Klauer@metamorpher.de 480 | 481 | Credits 482 | 483 | Thanks to all those people who helped me write this script. Special 484 | thanks to the authors of the LARTC Howto and the people on the LARTC 485 | mailing list. And of course to Stef Coene for his great Docum page. 486 | Thanks to everyone who sent me bug reports, suggestions, feature 487 | requests and so on. 488 | 489 | TODO 490 | 491 | Sorry about the inactivity lately. I'm experimenting with some new 492 | features I was asked for, including, but not limited to: 493 | * Support for multiple subnets, not only one 494 | * Compatibility with alien iptables-rules (Firewalls) 495 | * Custom rates per user 496 | * Fair Sharing among multiple IPs per user 497 | * Dynamic addition/removal of users (e.g. DHCP support) 498 | * Support for more than one internet link (load balancing) 499 | 500 | It's still an experiment, so I can't guarantee yet that Fair NAT will 501 | ever support all this stuff. If I succeed, this script will be quite 502 | powerful :-) and if I don't, well, it's still fun to try. 503 | 504 | In short: As long as there are no critical bug reports for the current 505 | version of the script, there won't be any updates for a while because 506 | I'm working on these experimental features. 507 | _________________________________________________________________ 508 | 509 | Other projects 510 | 511 | * [26]tc-graph.pl : Inspired by Stef Coene's [27]show.pl , I wrote 512 | this script. It generates GraphViz .dot files (see 513 | [28]http://www.graphviz.org for details on GraphViz) from 514 | tc-output. You can use it to create qdisc/class/filter structure 515 | visualizations like [29]this one. It should be able to show any 516 | qdisc/class properly, but it's still bad with filters; it's really 517 | hard to parse output for matches etc, so only mark filters are 518 | supported so far. 519 | * [30]burn-dvd-image.sh : Simple script that uses a combination of 520 | growisofs, pipebuf and nice to make high speed DVD image burning 521 | under heavy load conditions possible. If you use growisofs, and 522 | experience speed breakdowns (reported writing speed is not 523 | constant), this is probably the right script for you. 524 | * [31]genkouyoushi.ps: A generator for Japanese calligraphy paper 525 | written in PostScript. It prints squares, circles, centerlines, 526 | and characters. Here's an [32]example (big). Customizable by 527 | changing variables at the beginning of the file. 528 | 529 | References 530 | 531 | 1. http://www.google.com/ 532 | 2. http://www.freshmeat.net/ 533 | 3. http://www.lartc.org/ 534 | 4. http://freshmeat.net/redir/htb.init/21951/url_homepage/htbinit 535 | 5. http://www.metamorpher.de/files/fairnat.png 536 | 6. http://www.metamorpher.de/files/fairnat_ipp2p.png 537 | 7. http://iptables-tutorial.frozentux.net/iptables-tutorial.html#TTLTARGET 538 | 8. http://luxik.cdi.cz/~devik/qos/htb/ 539 | 9. http://www.ipp2p.org/ 540 | 10. http://www.netfilter.org/ 541 | 11. http://www.metamorpher.de/files/fairnat-0.80.tar.gz 542 | 12. http://www.metamorpher.de/files/fairnat-0.79.tar.gz 543 | 13. http://www.metamorpher.de/files/fairnat-0.78.tar.gz 544 | 14. http://www.metamorpher.de/files/fairnat-0.77.tar.gz 545 | 15. http://www.metamorpher.de/files/fairnat-0.76.tar.gz 546 | 16. http://www.metamorpher.de/files/fairnat-0.75.tar.gz 547 | 17. http://luxik.cdi.cz/~devik/qos/htb/ 548 | 18. http://www.metamorpher.de/files/fairnat-0.74.tar.gz 549 | 19. http://www.metamorpher.de/files/fairnat-0.73.tar.gz 550 | 20. http://www.metamorpher.de/files/fairnat-0.72.tar.gz 551 | 21. http://www.metamorpher.de/files/fairnat-0.71.tar.gz 552 | 22. http://www.metamorpher.de/files/fairnat-0.70.tar.gz 553 | 23. http://www.metamorpher.de/files/fairnat-0.69.tar.gz 554 | 24. http://www.metamorpher.de/files/fairnat-0.68.tar.gz 555 | 25. mailto:Andreas.Klauer@metamorpher.de 556 | 26. http://www.metamorpher.de/files/tc-graph.pl.txt 557 | 27. http://www.docum.org/stef.coene/qos/show_qos/index.html 558 | 28. http://www.graphviz.org/ 559 | 29. http://www.metamorpher.de/files/fairnat.png 560 | 30. http://www.metamorpher.de/files/burn-dvd-image.sh 561 | 31. http://www.metamorpher.de/files/genkouyoushi.ps 562 | 32. http://www.metamorpher.de/files/genkouyoushi.gif 563 | -------------------------------------------------------------------------------- /fairnat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Use !/bin/bash -x instead if you want to know what the script does. 3 | # ------------------------------------------------------------------------- 4 | # File: fairnat.sh 5 | # Version: v0.80 (2005-08-21 01:09 CEST) 6 | # Description: Traffic Shaping for multiple users on a dedicated linux router 7 | # using a HTB queue. Please note that this script cannot be run 8 | # before the internet connection is available (for dialup users) 9 | # Licence: GPL-2 10 | # Author: Andreas Klauer 11 | # Project page: http://www.metamorpher.de/fairnat/ 12 | # 13 | 14 | # === Variables: === 15 | 16 | # Change this if your file is located elsewhere. 17 | FAIRNAT_CONFIG="/etc/ppp/fairnat.config" 18 | 19 | # Please note: There are much more variables, but they are defined in 20 | # the FAIRNAT_CONFIG file. See example file. 21 | 22 | # Workaround for localized (i18ned) binaries: 23 | LC_ALL=C 24 | LANG=C 25 | 26 | # === Functions: === 27 | 28 | # ----------------------------------------------------------------------------- 29 | # FUNCTION: rate 30 | # DESCRIPTION: 31 | # This function takes a rate argument () and converts it 32 | # to bps which is used internally for rate calculations. If no unit is 33 | # specified, 'kbit' is assumed to be compatible with older versions of 34 | # Fair NAT, where you could specify rates as kbit/s only. 35 | # SEE ALSO: 36 | # ----------------------------------------------------------------------------- 37 | function rate 38 | { 39 | RATE=0 40 | R_RATE=$1 41 | R_NUMBER=`$BIN_ECHO "$R_RATE" | $BIN_SED -e "s/[^0-9]//g"` 42 | R_UNIT=`$BIN_ECHO "$R_RATE" | $BIN_SED -e "s/[0-9]//g"` 43 | 44 | if [ "$R_UNIT" == "" ]; 45 | then 46 | R_UNIT="kbit" 47 | fi 48 | 49 | # Let's see which unit we have... 50 | if [ "$R_UNIT" == "kbps" ] 51 | then 52 | R_RATE=$(($R_NUMBER * 1024)) 53 | elif [ "$R_UNIT" == "mbps" ] 54 | then 55 | R_RATE=$(($R_NUMBER * 1024 * 1024)) 56 | elif [ "$R_UNIT" == "mbit" ] 57 | then 58 | R_RATE=$(($R_NUMBER * 1024 * 1024 / 8)) 59 | elif [ "$R_UNIT" == "kbit" ] 60 | then 61 | R_RATE=$(($R_NUMBER * 1024 / 8)) 62 | elif [ "$R_UNIT" == "bps" ] 63 | then 64 | R_RATE=$R_NUMBER 65 | else 66 | echo "Unknown unit '$R_UNIT'. I only know mbps, mbit, kbit, bps." 67 | fi 68 | 69 | RATE="$R_RATE" 70 | } 71 | 72 | # ----------------------------------------------------------------------------- 73 | # FUNCTION: configure 74 | # DESCRIPTION: 75 | # This function sets default values for all variables. 76 | # It has only one parameter: The path/filename for the configuration file. 77 | # If this configuration file exists, it will be loaded afterwards to replace 78 | # the default values with the user's own settings. 79 | # 80 | # The variables are explained in the example fairnat configuration file. 81 | # Do not modify values here, do it in the config file instead. 82 | # 83 | # There are also some variables which can't be configured - stuff like your 84 | # current IP (especially for dynamic IP dialups), subnet, MTU, etc. will be 85 | # configured automatically. This is done after the config file was loaded. 86 | # SEE ALSO: 87 | # ----------------------------------------------------------------------------- 88 | function configure 89 | { 90 | C_CONFIG_FILE=$1 91 | 92 | # System settings: 93 | BIN_TC=`which tc` 94 | BIN_IPT=`which iptables` 95 | BIN_IFC=`which ifconfig` 96 | BIN_GREP=`which grep` 97 | BIN_SED=`which sed` 98 | BIN_ECHO=`which echo` 99 | BIN_MODPROBE=`which modprobe` 100 | 101 | # FEATURES settings: 102 | FEATURES="PROC MODULES IPT_RESET IPT_NAT IPT_FORWARD QOS_DOWN QOS_UP" 103 | 104 | # LAN settings: 105 | DEV_LAN=eth0 106 | RATE_LAN=5000 107 | 108 | # User settings: 109 | USERS="1 2 3" 110 | PORTS="" 111 | CLASS_MODE="default" 112 | BORROW=1 113 | CEIL_USER_UP=0 114 | CEIL_USER_DOWN=0 115 | 116 | # Internet settings: 117 | DEV_NET=ppp0 118 | RATE_UP=128 119 | RATE_DOWN=768 120 | RATE_SUB_PERCENT=5 121 | RATE_LOCAL_PERCENT=5 122 | 123 | # IPP2P support (experimental) 124 | IPP2P_ENABLE=0 125 | IPP2P_DROP_ALL=0 126 | IPP2P_DROP_MARKED=0 127 | IPP2P_OPTIONS="--ipp2p --apple --bit" 128 | IPP2P_UDP=0 129 | 130 | # Hacks 131 | MSS_CLAMPING=0 132 | TTL_SET=0 133 | HTB_MPU=0 134 | HTB_OVERHEAD=0 135 | FAIRNAT_PREFIX="FAIRNAT" 136 | 137 | # Now that all variables have default values set, replace the ones 138 | # defined by the user in the configuration file: 139 | [ -f $C_CONFIG_FILE ] && source $C_CONFIG_FILE 140 | 141 | # Enable desired features 142 | for f in $FEATURES; 143 | do 144 | eval FEATURE_$f=1 145 | done; 146 | 147 | # Now comes the part that can't be configured by the user: 148 | 149 | # Get size of USERS and PORTS. Temporarily convert to Array to do this. 150 | NUM_USERS=($USERS) 151 | NUM_USERS=${#NUM_USERS[*]} 152 | NUM_PORTS=($PORTS) 153 | NUM_PORTS=${#NUM_PORTS[*]} 154 | 155 | # Get some additional stuff from the devices: 156 | DEV_LAN_IP=`$BIN_IFC $DEV_LAN | \ 157 | $BIN_GREP 'inet addr' | \ 158 | $BIN_SED -e s/^.*inet\ addr://g -e s/\ .*$//g` 159 | DEV_LAN_SUBNET=`$BIN_ECHO $DEV_LAN_IP | $BIN_SED -e s/\.[0-9]*$//g` 160 | DEV_NET_IP=`$BIN_IFC $DEV_NET | \ 161 | $BIN_GREP 'inet addr:' | \ 162 | $BIN_SED -e s/^.*inet\ addr://g -e s/\ .*$//g` 163 | DEV_NET_MTU=`$BIN_IFC $DEV_NET | \ 164 | $BIN_GREP 'MTU:' | \ 165 | $BIN_SED -e s/^.*MTU://g -e s/\ .*$//g` 166 | 167 | # Convert all rates from KBit to bps. 168 | # Also substract the percentage defined. 169 | rate "$RATE_UP" 170 | RATE_UP=$RATE 171 | RATE_UP=$(($RATE_UP * (100-$RATE_SUB_PERCENT) / 100)) 172 | rate "$RATE_DOWN" 173 | RATE_DOWN=$RATE 174 | RATE_DOWN=$(($RATE_DOWN * (100-$RATE_SUB_PERCENT) / 100)) 175 | rate "$RATE_LAN" 176 | RATE_LAN=$RATE 177 | 178 | # Rates per User / Local. 179 | # RATE_LOCAL_PERCENT of bandwidth reserved for local upload. 180 | # We don't shape local download as of yet, so no reservation here. 181 | RATE_USER_DOWN=$(($RATE_DOWN/$NUM_USERS)) 182 | RATE_USER_UP=$((((100-$RATE_LOCAL_PERCENT)*$RATE_UP)/($NUM_USERS*100))) 183 | RATE_LOCAL_UP=$(($RATE_LOCAL_PERCENT*$RATE_UP/100)) 184 | 185 | # Calculate ceiling rate per user. 186 | if [ "$CEIL_USER_UP" == "0" ]; 187 | then 188 | CEIL_USER_UP=$RATE_UP; 189 | else 190 | rate "$CEIL_USER_UP" 191 | CEIL_USER_UP=$RATE 192 | fi 193 | 194 | if [ "$CEIL_USER_DOWN" == "0" ]; 195 | then 196 | CEIL_USER_DOWN=$RATE_DOWN; 197 | else 198 | rate "$CEIL_USER_DOWN" 199 | CEIL_USER_DOWN=$RATE 200 | fi 201 | 202 | # If the CEIL_USERs are lower than the RATE_USERs, lower the rates. 203 | # This is bad because the user class rates will not add up anymore. 204 | # If this happens the line will never be fully utilized by the users. 205 | if [ $CEIL_USER_UP -lt $RATE_USER_UP ] 206 | then 207 | echo "Warning: Specified CEIL_USER_UP is lower than RATE_UP / Number of Users. Underfull link." 208 | RATE_USER_UP=$CEIL_USER_UP; 209 | fi 210 | 211 | if [ $CEIL_USER_DOWN -lt $RATE_USER_DOWN ] 212 | then 213 | echo "Warning: Specified CEIL_USER_DOWN is lower than RATE_DOWN / Number of Users. Underfull link." 214 | RATE_USER_DOWN=$CEIL_USER_DOWN; 215 | fi 216 | 217 | # MARK offset: 218 | # Makes sure that class names per user are unique. Leave this value alone 219 | # unless you really have to create 10 or more subclasses per user. Currently, 220 | # the script uses about 5. Since TC does not accept handles above 4 digits 221 | # and I'm too lazy to implement hexadecimal notation, using values >= 40 may 222 | # lead to weird error messages. 223 | MARK_OFFSET=10 224 | 225 | # Hacks: 226 | if [ $HTB_MPU != 0 ]; 227 | then 228 | HTB_OPT="$HTB_OPT mpu $HTB_MPU" 229 | fi 230 | 231 | if [ $HTB_OVERHEAD != 0 ]; 232 | then 233 | HTB_OPT="$HTB_OPT overhead $HTB_OVERHEAD" 234 | fi 235 | 236 | # Some abbreviations: 237 | FN_FORWARD="$FAIRNAT_PREFIX"_FORWARD 238 | FN_PREROUTING="$FAIRNAT_PREFIX"_PREROUTING 239 | FN_POSTROUTING="$FAIRNAT_PREFIX"_POSTROUTING 240 | FN_CHK_TOS="$FAIRNAT_PREFIX"_CHK_TOS 241 | FN_ACK_TOS="$FAIRNAT_PREFIX"_ACK_TOS 242 | FN_IPP2PMARK="$FAIRNAT_PREFIX"_IPP2PMARK 243 | FN_ALL="$FN_FORWARD $FN_PREROUTING $FN_POSTROUTING $FN_CHK_TOS $FN_ACK_TOS $FN_IPP2PMARK" 244 | } 245 | 246 | # ----------------------------------------------------------------------------- 247 | # FUNCTION: modules 248 | # DESCRIPTION: 249 | # This function loads some modules. We don't need them all. But I'm too 250 | # lazy to sort them out right now. But anyway, nobody in their right mind 251 | # would use modules for traffic shaping on a router that requires the 252 | # functionality 24/7. 253 | # SEE ALSO: 254 | # ----------------------------------------------------------------------------- 255 | function modules 256 | { 257 | # Load some modules... 258 | # TODO: Most of them are not required. Needs a cleanup. 259 | $BIN_MODPROBE ip_tables 2> /dev/null > /dev/null 260 | $BIN_MODPROBE ip_conntrack 2> /dev/null > /dev/null 261 | $BIN_MODPROBE iptable_nat 2> /dev/null > /dev/null 262 | $BIN_MODPROBE ipt_MASQUERADE 2> /dev/null > /dev/null 263 | $BIN_MODPROBE iptable_filter 2> /dev/null > /dev/null 264 | $BIN_MODPROBE ipt_state 2> /dev/null > /dev/null 265 | $BIN_MODPROBE ipt_limit 2> /dev/null > /dev/null 266 | $BIN_MODPROBE ip_conntrack_ftp 2> /dev/null > /dev/null 267 | $BIN_MODPROBE ip_conntrack_irc 2> /dev/null > /dev/null 268 | $BIN_MODPROBE ip_nat_ftp 2> /dev/null > /dev/null 269 | $BIN_MODPROBE ip_nat_irc 2> /dev/null > /dev/null 270 | $BIN_MODPROBE ip_queue 2> /dev/null > /dev/null 271 | $BIN_MODPROBE sch_api 2> /dev/null > /dev/null 272 | $BIN_MODPROBE sch_atm 2> /dev/null > /dev/null 273 | $BIN_MODPROBE sch_cbq 2> /dev/null > /dev/null 274 | $BIN_MODPROBE sch_csz 2> /dev/null > /dev/null 275 | $BIN_MODPROBE sch_dsmark 2> /dev/null > /dev/null 276 | $BIN_MODPROBE sch_fifo 2> /dev/null > /dev/null 277 | $BIN_MODPROBE sch_generic 2> /dev/null > /dev/null 278 | $BIN_MODPROBE sch_gred 2> /dev/null > /dev/null 279 | $BIN_MODPROBE sch_htb 2> /dev/null > /dev/null 280 | $BIN_MODPROBE sch_ingress 2> /dev/null > /dev/null 281 | $BIN_MODPROBE sch_sfq 2> /dev/null > /dev/null 282 | $BIN_MODPROBE sch_red 2> /dev/null > /dev/null 283 | $BIN_MODPROBE sch_sfq 2> /dev/null > /dev/null 284 | $BIN_MODPROBE sch_tbf 2> /dev/null > /dev/null 285 | $BIN_MODPROBE sch_teql 2> /dev/null > /dev/null 286 | 287 | # Experimental IPP2P support: 288 | if [ "$IPP2P_ENABLE" == "1" ]; 289 | then 290 | $BIN_MODPROBE ipt_ipp2p 2> /dev/null > /dev/null 291 | fi 292 | } 293 | 294 | # ----------------------------------------------------------------------------- 295 | # FUNCTION: iptables 296 | # DESCRIPTION: 297 | # This sets all IPTables rules that are not user-specific. 298 | # So all the general IPTables stuff goes here. 299 | # SEE ALSO: 300 | # ----------------------------------------------------------------------------- 301 | function iptables 302 | { 303 | # Set TOS for several stuff. 304 | if [ "$FEATURE_TOS" == "1" ] 305 | then 306 | # TODO: Anything missing here? Tell me about it. 307 | $BIN_IPT -t mangle -A $FN_PREROUTING -p icmp -j TOS --set-tos Minimize-Delay 308 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp --sport telnet -j TOS --set-tos Minimize-Delay 309 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp --sport ssh -j TOS --set-tos Minimize-Delay 310 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp --sport ftp -j TOS --set-tos Minimize-Delay 311 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp --sport ftp-data -j TOS --set-tos Maximize-Throughput 312 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp --dport telnet -j TOS --set-tos Minimize-Delay 313 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp --dport ssh -j TOS --set-tos Minimize-Delay 314 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp --dport ftp -j TOS --set-tos Minimize-Delay 315 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp --dport ftp-data -j TOS --set-tos Maximize-Throughput 316 | 317 | # Correcting TOS for large packets with Minimize-Delay-TOS 318 | $BIN_IPT -t mangle -A $FN_CHK_TOS -p tcp -m length --length 0:512 -j RETURN 319 | $BIN_IPT -t mangle -A $FN_CHK_TOS -p udp -m length --length 0:1024 -j RETURN 320 | $BIN_IPT -t mangle -A $FN_CHK_TOS -j TOS --set-tos Maximize-Throughput 321 | $BIN_IPT -t mangle -A $FN_CHK_TOS -j RETURN 322 | 323 | $BIN_IPT -t mangle -A $FN_PREROUTING -m tos --tos Minimize-Delay -j $FN_CHK_TOS 324 | 325 | # Modifying TOS for TCP control packets: (from www.docum.org / Stef Coene) 326 | $BIN_IPT -t mangle -A $FN_ACK_TOS -m tos --tos ! Normal-Service -j RETURN 327 | $BIN_IPT -t mangle -A $FN_ACK_TOS -p tcp -m length --length 0:256 -j TOS --set-tos Minimize-Delay 328 | $BIN_IPT -t mangle -A $FN_ACK_TOS -p tcp -m length --length 256: -j TOS --set-tos Maximize-Throughput 329 | $BIN_IPT -t mangle -A $FN_ACK_TOS -j RETURN 330 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp -m tcp --tcp-flags SYN,RST,ACK ACK -j $FN_ACK_TOS 331 | fi 332 | 333 | # Hacks. 334 | # Read about MSS Clamping in the LARTC Howto. 335 | if [ "$MSS_CLAMPING" != "0" ]; 336 | then 337 | $BIN_IPT -A $FN_FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS $MSS_CLAMPING 338 | fi 339 | 340 | # Set TTL to a specific value. This hack requires a kernel patch. 341 | # See fairnat.config, Hacks section for details. 342 | if [ "$TTL_SET" != "0" ] 343 | then 344 | $BIN_IPT -t mangle -A $FN_PREROUTING -j TTL --ttl-set $TTL_SET 345 | fi 346 | 347 | # IPP2P support (experimental) 348 | if [ "$IPP2P_ENABLE" == "1" ]; 349 | then 350 | if [ "$IPP2P_DROP_ALL" == "1" ]; 351 | then 352 | # P2P traffic should be forbidden in general. 353 | if [ "$IPP2P_UDP" == "1" ] 354 | then 355 | $BIN_IPT -A $FN_FORWARD -m ipp2p $IPP2P_OPTIONS -j DROP 356 | else 357 | $BIN_IPT -A $FN_FORWARD -p tcp -m ipp2p $IPP2P_OPTIONS -j DROP 358 | fi 359 | 360 | if [ "$IPP2P_DROP_MARKED" == "1" ]; 361 | then 362 | # Drop previously marked connections, too. 363 | $BIN_IPT -t mangle -A $FN_PREROUTING -j CONNMARK --restore-mark 364 | $BIN_IPT -t mangle -A $FN_PREROUTING -m mark --mark 1 -j DROP 365 | fi 366 | else 367 | # P2P should be allowed, but with low prio. 368 | 369 | # Create a new chain for IPP2P connection marking: 370 | $BIN_IPT -t mangle -A $FN_IPP2PMARK -j CONNMARK --restore-mark 371 | $BIN_IPT -t mangle -A $FN_IPP2PMARK -m mark --mark 1 -j RETURN 372 | $BIN_IPT -t mangle -A $FN_IPP2PMARK -m ipp2p $IPP2P_OPTIONS -j MARK --set-mark 1 373 | $BIN_IPT -t mangle -A $FN_IPP2PMARK -m mark --mark 1 -j CONNMARK --save-mark 374 | 375 | # Let all tcp packets run through the IPP2P chain: 376 | $BIN_IPT -t mangle -A $FN_PREROUTING -p tcp -j $FN_IPP2PMARK 377 | 378 | # UDP packets as well if enabled: 379 | if [ "$IPP2P_UDP" == "1" ] 380 | then 381 | $BIN_IPT -t mangle -A $FN_PREROUTING -p udp -j $FN_IPP2PMARK 382 | fi 383 | 384 | # NOTE: The mark will be modified again later in the user rules. 385 | fi 386 | fi 387 | # End of experimental IPP2P support. 388 | } 389 | # End of iptables. 390 | 391 | # ----------------------------------------------------------------------------- 392 | # FUNCTION: parent_class(dev, rate, user_rate, user_ceil, local_rate, local_ceil) 393 | # DESCRIPTION: 394 | # This function sets up the parent qdisc / class / filter structure. 395 | # In short, it does everything that does not depend on users. 396 | # 397 | # Parameters: 398 | # 399 | # dev: The device to attach the parent qdisc/class structure to. 400 | # rate: The maximum rate the device can do. 401 | # user_rate: The rate that should be reserved for users. 402 | # user_ceil: The maximum rate users should be allowed to use. 403 | # local_rate: The rate that should be reserved for local traffic. 404 | # local_ceil: The maximum rate that the local box should be allowed to use. 405 | # 406 | # The default function creates this structure: 407 | # 408 | # HTB qdisc 409 | # | 410 | # \--- 1:2 Main HTB class ($dev_rate $dev_rate), default 3 411 | # | 412 | # \--- 1:3 Local class ($local_rate $dev_rate) 413 | # \--- 1:1 User class ($net_rate $dev_rate) 414 | # 415 | # The function user_class will later add further child classes to 1:1. 416 | # 417 | # If you want a different class structure, you can replace this function 418 | # by writing a new one (parent_class_foobar). Set CLASS_MODE to "foobar" 419 | # in fairnat.config and your function will be used instead of the default 420 | # one. You also need a user_class_foobar function then. Look below for 421 | # some examples. 422 | # 423 | # SEE ALSO: user_class 424 | # ----------------------------------------------------------------------------- 425 | 426 | function parent_class_default 427 | { 428 | PC_DEV=$1 429 | PC_RATE=$2 430 | PC_USER_RATE=$3 431 | PC_CEIL_USER=$4 432 | PC_LOCAL_RATE=$5 433 | PC_LOCAL_CEIL=$6 434 | 435 | # Root QDisc: 436 | $BIN_TC qdisc add dev $PC_DEV root handle 1: htb default 3 437 | 438 | # Main (fat) device class: 439 | $BIN_TC class add dev $PC_DEV parent 1: classid 1:2 \ 440 | htb rate $(($PC_RATE))bps ceil $(($PC_RATE))bps \ 441 | quantum $DEV_NET_MTU $HTB_OPT 442 | 443 | # Local traffic class with lower prio: 444 | $BIN_TC class add dev $PC_DEV parent 1:2 classid 1:3 \ 445 | htb rate $(($PC_LOCAL_RATE))bps ceil $(($PC_LOCAL_CEIL))bps \ 446 | quantum $DEV_NET_MTU $HTB_OPT prio 5 447 | 448 | # Put PRIO and SFQ on top of local traffic class: 449 | $BIN_TC qdisc add dev $PC_DEV parent 1:3 handle 2: prio 450 | $BIN_TC qdisc add dev $PC_DEV parent 2:1 handle 3: sfq perturb 9 451 | $BIN_TC qdisc add dev $PC_DEV parent 2:2 handle 4: sfq perturb 10 452 | $BIN_TC qdisc add dev $PC_DEV parent 2:3 handle 5: sfq perturb 11 453 | 454 | # Parent class for user classes: 455 | $BIN_TC class add dev $PC_DEV parent 1:2 classid 1:1 \ 456 | htb rate $(($PC_USER_RATE))bps ceil $(($PC_CEIL_USER))bps \ 457 | quantum $DEV_NET_MTU $HTB_OPT 458 | } 459 | 460 | # Wondershaper uses the default parent class structure. 461 | function parent_class_wonder 462 | { 463 | parent_class_default $* 464 | } 465 | 466 | # ----------------------------------------------------------------------------- 467 | # FUNCTION: user_class(device, mark, rate, ceil) 468 | # DESCRIPTION: 469 | # This function creates the class structure for a single user. 470 | # All users have the same class structure for up- and download. 471 | # This ensures that the sharing is fair between users. 472 | # 473 | # At the moment, the class setup looks about like this: 474 | # 475 | # HTB class (for bandwidth sharing) 476 | # | 477 | # \-- PRIO (for prioritizing interactive traffic) 478 | # | 479 | # \--- Interactive: SFQ (to treat concurrenct connections fairly) 480 | # \--- Normal: SFQ 481 | # \--- High-Traffic: SFQ 482 | # [ \--- Filesharing: SFQ (only if IPP2P is enabled) ] 483 | # 484 | # However, it is possible to treat multiple IPs as a single user (if one 485 | # guy got more than one machine). So, one user class does not necessarily 486 | # serve just one IP. See example config file for details. 487 | # 488 | # SEE ALSO: parent_class 489 | # ----------------------------------------------------------------------------- 490 | 491 | # The default structure, as described above. 492 | function user_class_default 493 | { 494 | # Make the positional parameters more readable. 495 | # Use UC_ prefix to make sure that these variables belong to User_Class. 496 | UC_DEV=$1 497 | UC_MARK=$2 498 | UC_RATE=$3 499 | UC_CEIL=$4 500 | 501 | # Add filter for this user. 502 | $BIN_TC filter add dev $UC_DEV parent 1: protocol ip \ 503 | handle $UC_MARK fw flowid 1:$UC_MARK 504 | 505 | 506 | # Add HTB class: 507 | $BIN_TC class add dev $UC_DEV parent 1:1 classid 1:$UC_MARK \ 508 | htb rate $(($UC_RATE))bps ceil $(($UC_CEIL))bps \ 509 | quantum $DEV_NET_MTU $HTB_OPT 510 | 511 | # Add PRIO qdisc on top of HTB: 512 | if [ "$IPP2P_ENABLE" == "0" -o "$IPP2P_DROP_ALL" == "1" ]; 513 | then 514 | # Default: IPP2P disabled. Create 3 bands. 515 | $BIN_TC qdisc add dev $UC_DEV parent 1:$UC_MARK handle $UC_MARK: prio 516 | else 517 | # Experimental IPP2P support: 518 | 519 | # Add another filter to parent QDisc if IPP2P is active: 520 | $BIN_TC filter add dev $UC_DEV parent 1: protocol ip \ 521 | handle $(($UC_MARK+1)) fw flowid 1:$UC_MARK 522 | 523 | # Create a prio qdisc with 4 classes. All P2P traffic goes into class 4. 524 | $BIN_TC qdisc add dev $UC_DEV parent 1:$UC_MARK handle $UC_MARK: prio \ 525 | bands 4 526 | 527 | # Add a filter for IPP2P to this qdisc. The rest depends on TOS. 528 | $BIN_TC filter add dev $UC_DEV parent $UC_MARK: protocol ip \ 529 | handle $(($UC_MARK+1)) fw flowid $UC_MARK:4 530 | 531 | # Add SFQ QDisc on 4th Prio band. 532 | $BIN_TC qdisc add dev $UC_DEV parent $UC_MARK:4 handle $(($UC_MARK+4)): \ 533 | sfq perturb 12 534 | 535 | # End of experimental IPP2P support 536 | fi 537 | 538 | # Put SFQ qdisc on top of the prio classes: 539 | $BIN_TC qdisc add dev $UC_DEV parent $UC_MARK:1 handle $(($UC_MARK+1)): \ 540 | sfq perturb 9 541 | $BIN_TC qdisc add dev $UC_DEV parent $UC_MARK:2 handle $(($UC_MARK+2)): \ 542 | sfq perturb 10 543 | $BIN_TC qdisc add dev $UC_DEV parent $UC_MARK:3 handle $(($UC_MARK+3)): \ 544 | sfq perturb 11 545 | } 546 | 547 | function user_class_wonder 548 | { 549 | # Make the positional parameters more readable. 550 | # Use UC_ prefix to make sure that these variables belong to User_Class. 551 | UC_DEV=$1 552 | UC_MARK=$2 553 | UC_RATE=$3 554 | UC_CEIL=$4 555 | 556 | # Add filter for this user. 557 | $BIN_TC filter add dev $UC_DEV parent 1: protocol ip \ 558 | handle $UC_MARK fw flowid 1:$UC_MARK 559 | 560 | 561 | # Add HTB class: 562 | $BIN_TC class add dev $UC_DEV parent 1:1 classid 1:$UC_MARK \ 563 | htb rate $(($UC_RATE))bps ceil $(($UC_CEIL))bps \ 564 | quantum $DEV_NET_MTU $HTB_OPT 565 | 566 | # Wonder-Shaper classes are following: 567 | 568 | # high prio class 1:10: 569 | 570 | $BIN_TC class add dev $UC_DEV parent 1:$UC_MARK classid 1:$(($UC_MARK+1)) \ 571 | htb rate $(($UC_CEIL))bps burst 6k prio 1 \ 572 | quantum $DEV_NET_MTU $HTB_OPT 573 | $BIN_TC class add dev $UC_DEV parent 1:$UC_MARK classid 1:$(($UC_MARK+2)) \ 574 | htb rate $((9*$UC_CEIL/10))bps burst 6k prio 2 \ 575 | quantum $DEV_NET_MTU $HTB_OPT 576 | 577 | # all get Stochastic Fairness: 578 | $BIN_TC qdisc add dev $UC_DEV parent 1:$(($UC_MARK+1)) handle $(($UC_MARK+1)): \ 579 | sfq perturb 10 580 | $BIN_TC qdisc add dev $UC_DEV parent 1:$(($UC_MARK+2)) handle $(($UC_MARK+2)): \ 581 | sfq perturb 10 582 | 583 | # TOS Minimum Delay (ssh, NOT scp) in 1:10: 584 | 585 | $BIN_TC filter add dev $UC_DEV parent 1:$UC_MARK protocol ip prio 10 \ 586 | u32 match ip tos 0x10 0xff flowid 1:$(($UC_MARK+1)) 587 | 588 | # ICMP (ip protocol 1) in the interactive class 1:10 so we 589 | # can do measurements & impress our friends: 590 | 591 | $BIN_TC filter add dev $UC_DEV parent 1:$UC_MARK protocol ip prio 10 \ 592 | u32 match ip protocol 1 0xff flowid 1:$(($UC_MARK+1)) 593 | 594 | 595 | # To speed up downloads while an upload is going on, put ACK packets in 596 | # the interactive class: 597 | 598 | $BIN_TC filter add dev $UC_DEV parent 1:$UC_MARK protocol ip prio 10 \ 599 | u32 match ip protocol 6 0xff \ 600 | match u8 0x05 0x0f at 0 \ 601 | match u16 0x0000 0xffc0 at 2 \ 602 | match u8 0x10 0xff at 33 \ 603 | flowid 1:$(($UC_MARK+1)) 604 | 605 | # Default: Put stuff in class 2. 606 | 607 | $BIN_TC filter add dev $UC_DEV parent 1:$UC_MARK prio 100 \ 608 | protocol ip handle $UC_MARK fw flowid 1:$(($UC_MARK+2)) 609 | 610 | # In case of IPP2P: Put it in class 3. 611 | 612 | if [ "$IPP2P_ENABLE" == "1" -a "$IPP2P_DROP_ALL" == "0" ]; 613 | then 614 | $BIN_TC class add dev $UC_DEV parent 1:$UC_MARK classid 1:$(($UC_MARK+3)) \ 615 | htb rate $((8*$UC_CEIL/10))bps burst 6k prio 3 \ 616 | quantum $DEV_NET_MTU $HTB_OPT 617 | $BIN_TC qdisc add dev $UC_DEV parent 1:$(($UC_MARK+3)) handle $(($UC_MARK+3)): \ 618 | sfq perturb 10 619 | $BIN_TC filter add dev $UC_DEV parent 1: prio 1 \ 620 | protocol ip handle $(($UC_MARK+1)) fw flowid 1:$(($UC_MARK+3)) 621 | fi 622 | } 623 | 624 | # ----------------------------------------------------------------------------- 625 | # FUNCTION: fair_nat(ip, mark) 626 | # DESCRIPTION: 627 | # This function sets up Fair NAT for this ip. 628 | # mark is the identifier for the user's class this ip belongs to. 629 | # Packages of this user are marked, so that the Traffic Shaping knows to 630 | # which User this traffic belongs to. 631 | # SEE ALSO: forward 632 | # ----------------------------------------------------------------------------- 633 | function fair_nat 634 | { 635 | # make positional parameters more readable 636 | FN_IP=$1 637 | 638 | # Add IPTables rules for NAT: 639 | if [ "$FEATURE_NAT" == "1" ] 640 | then 641 | $BIN_IPT -t nat -A $FN_POSTROUTING -o $DEV_NET -s $FN_IP -j MASQUERADE 642 | fi 643 | 644 | # Mark packages (if IPP2P is disabled) 645 | if [ "$IPP2P_ENABLE" == "0" -o "$IPP2P_DROP_ALL" == "1" ]; 646 | then 647 | if [ "$FEATURE_QOS_UP" == "1" ] 648 | then 649 | $BIN_IPT -t mangle -A $FN_FORWARD -i $DEV_LAN -o $DEV_NET -s $FN_IP \ 650 | -j MARK --set-mark $MARK 651 | fi 652 | 653 | if [ "$FEATURE_QOS_DOWN" == "1" ] 654 | then 655 | $BIN_IPT -t mangle -A $FN_FORWARD -i $DEV_NET -o $DEV_LAN -d $FN_IP \ 656 | -j MARK --set-mark $MARK 657 | fi 658 | 659 | # Mark packages (if IPP2P is enabled) 660 | # IPP2P packages will get MARK+1. 661 | # Too bad that there's no --add-mark, it would've made things so much easier. 662 | else 663 | if [ "$FEATURE_QOS_UP" == "1" ] 664 | then 665 | $BIN_IPT -t mangle -A $FN_FORWARD -i $DEV_LAN -o $DEV_NET -s $FN_IP \ 666 | -m mark --mark 0 -j MARK --set-mark $MARK 667 | $BIN_IPT -t mangle -A $FN_FORWARD -i $DEV_LAN -o $DEV_NET -s $FN_IP \ 668 | -m mark --mark 1 -j MARK --set-mark $(($MARK+1)) 669 | fi 670 | 671 | if [ "$FEATURE_QOS_DOWN" == "1" ] 672 | then 673 | $BIN_IPT -t mangle -A $FN_FORWARD -i $DEV_NET -o $DEV_LAN -d $FN_IP \ 674 | -m mark --mark 0 -j MARK --set-mark $MARK 675 | $BIN_IPT -t mangle -A $FN_FORWARD -i $DEV_NET -o $DEV_LAN -d $FN_IP \ 676 | -m mark --mark 1 -j MARK --set-mark $(($MARK+1)) 677 | fi 678 | fi 679 | } 680 | 681 | # ----------------------------------------------------------------------------- 682 | # FUNCTION: forward(ip, port) 683 | # DESCRIPTION: 684 | # This function sets up port forwarding (DNAT). 685 | # port is either a single port (a number) or a port range like 1000:2000. 686 | # Multiple port ranges (like 1000-2000,3100-3200) require multiple calls. 687 | # Port forwarding will always be done for TCP and UDP. 688 | # SEE ALSO: nat 689 | # ----------------------------------------------------------------------------- 690 | function forward 691 | { 692 | # make positional parameters more readable 693 | F_IP=$1 694 | F_PORT=$2 695 | 696 | # Add IPTables rules for DNAT: 697 | $BIN_IPT -t nat -A $FN_PREROUTING -i $DEV_NET -p tcp --dport $PORT -j DNAT --to-destination $F_IP 698 | $BIN_IPT -t nat -A $FN_PREROUTING -i $DEV_NET -p udp --dport $PORT -j DNAT --to-destination $F_IP 699 | 700 | # Marking these packets: 701 | 702 | } 703 | 704 | # ----------------------------------------------------------------------------- 705 | # FUNCTION: stop_fairnat 706 | # DESCRIPTION: 707 | # This function will stop everything. It will delete all IPTables rules, 708 | # all TC qdiscs and classes. 709 | # SEE ALSO: start_fairnat 710 | # ----------------------------------------------------------------------------- 711 | function stop_fairnat 712 | { 713 | # reset qdisc 714 | 715 | if [ "$FEATURE_QOS_UP" == "1" ] 716 | then 717 | $BIN_TC qdisc del dev $DEV_NET root 2> /dev/null > /dev/null 718 | $BIN_TC qdisc del dev $DEV_NET ingress 2> /dev/null > /dev/null 719 | fi 720 | 721 | if [ "$FEATURE_QOS_DOWN" == "1" ] 722 | then 723 | $BIN_TC qdisc del dev $DEV_LAN root 2> /dev/null > /dev/null 724 | $BIN_TC qdisc del dev $DEV_LAN ingress 2> /dev/null > /dev/null 725 | fi 726 | 727 | # reset iptables: 728 | if [ "$FEATURE_RESET" == "1" ] 729 | then 730 | # reset the default policies in the filter table. 731 | $BIN_IPT -P INPUT ACCEPT 732 | $BIN_IPT -P FORWARD ACCEPT 733 | $BIN_IPT -P OUTPUT ACCEPT 734 | 735 | # reset the default policies in the nat table. 736 | $BIN_IPT -t nat -P PREROUTING ACCEPT 737 | $BIN_IPT -t nat -P POSTROUTING ACCEPT 738 | $BIN_IPT -t nat -P OUTPUT ACCEPT 739 | 740 | # reset the default policies in the mangle table. 741 | $BIN_IPT -t mangle -P PREROUTING ACCEPT 742 | $BIN_IPT -t mangle -P OUTPUT ACCEPT 743 | 744 | # flush all the rules in the filter and nat tables. 745 | $BIN_IPT -F 746 | $BIN_IPT -t nat -F 747 | $BIN_IPT -t mangle -F 748 | 749 | # erase all chains that's not default in filter and nat table. 750 | $BIN_IPT -X 751 | $BIN_IPT -t nat -X 752 | $BIN_IPT -t mangle -X 753 | fi 754 | 755 | # reset only Fair NAT rules here. 756 | for table in "" "-t nat" "-t mangle"; 757 | do 758 | for chain in $FN_ALL; 759 | do 760 | # create chain 761 | $BIN_IPT $table -N $chain 2> /dev/null > /dev/null 762 | 763 | # flush chain (in case it already existed) 764 | $BIN_IPT $table -F $chain 2> /dev/null > /dev/null 765 | done; 766 | done; 767 | 768 | # If we just reset, add required references to Fair NAT chains. 769 | if [ "$FEATURE_RESET" == "1" ] 770 | then 771 | $BIN_IPT -t nat -A PREROUTING -j $FN_PREROUTING 772 | $BIN_IPT -t mangle -A PREROUTING -j $FN_PREROUTING 773 | $BIN_IPT -A FORWARD -j $FN_FORWARD 774 | $BIN_IPT -t mangle -A FORWARD -j $FN_FORWARD 775 | $BIN_IPT -t nat -A POSTROUTING -j $FN_POSTROUTING 776 | $BIN_IPT -t mangle -A POSTROUTING -j $FN_POSTROUTING 777 | fi 778 | } 779 | 780 | # ----------------------------------------------------------------------------- 781 | # FUNCTION: start_fairnat 782 | # DESCRIPTION: 783 | # This function starts Fair NAT. It configures your linux box to act as 784 | # router for the users you specified and sets up Traffic Shaping accordingly. 785 | # Various subroutines are called to accomplish that. 786 | # SEE ALSO: stop_fairnat 787 | # ----------------------------------------------------------------------------- 788 | function start_fairnat 789 | { 790 | # Fair NAT only works if devices and iptables are 'clean'. 791 | # The function stop_fairnat takes care of that. 792 | stop_fairnat 793 | 794 | # Load some modules. 795 | if [ "$FEATURE_MODULES" == "1" ] 796 | then 797 | modules 798 | fi 799 | 800 | # Make sure /proc is set up all right. 801 | if [ "$FEATURE_PROC" == "1" ] 802 | then 803 | # TODO: Anything else required? 804 | echo 1 > /proc/sys/net/ipv4/ip_forward 805 | fi 806 | 807 | # --- Basic IPTables Setup: --- 808 | iptables 809 | 810 | # --- Traffic Shaping: --- 811 | 812 | # User independent class structure for DEV_NET: 813 | if [ "$FEATURE_QOS_UP" == "1" ] 814 | then 815 | parent_class_$CLASS_MODE $DEV_NET $RATE_UP \ 816 | $(($RATE_USER_UP*$NUM_USERS)) $RATE_UP \ 817 | $RATE_LOCAL_UP $RATE_UP 818 | fi 819 | 820 | # User independent class structure for DEV_LAN: 821 | if [ "$FEATURE_QOS_DOWN" == "1" ] 822 | then 823 | parent_class_$CLASS_MODE $DEV_LAN $RATE_LAN \ 824 | $(($RATE_USER_DOWN*$NUM_USERS)) $RATE_DOWN \ 825 | $(($RATE_LAN-($RATE_USER_DOWN*$NUM_USERS))) $RATE_LAN 826 | fi 827 | 828 | # Please see parent_class documentation above for explanation of the parameters 829 | # the first line gives the function name, the device and the device rate 830 | # the second line gives user rate and user ceil 831 | # the third line gives local rate and local ceil. 832 | 833 | # --- Fair NAT: --- 834 | 835 | # We have to parse a list like "1 2 3 5:6:7 8:9" whereas 1 2 3 are users 836 | # with single IPs and 5 6 7 belong to a single user and 8 9 belong to 837 | # another single user. 838 | 839 | MARK=0 840 | for user in $USERS; 841 | do 842 | # user = "1", "2", "3", "5:6:7", "8:9", "1@500kbit", "5:6:7@400kbit|80kbit" 843 | 844 | # Set MARK to $user*$MARK_OFFSET. For groups (5:6:7), use the first IP (5). 845 | # This makes it easier to create per-user statistics, since the class numbers 846 | # now resemble the User IPs. Thanks to Udo for this suggestion. 847 | MARK=`$BIN_ECHO $user | $BIN_SED -e "s/[^0-9].*//g"` 848 | MARK=$(($MARK*$MARK_OFFSET)); 849 | 850 | # Check for custom ceil settings of this user 851 | CUSTOM_USER_DOWN=$CEIL_USER_DOWN 852 | CUSTOM_USER_UP=$CEIL_USER_UP 853 | CUSTOM_TEST=`$BIN_ECHO $user | $BIN_SED -e "s/[^@]//g"` 854 | 855 | if [ "$CUSTOM_TEST" != "" ]; 856 | then 857 | # a custom rate is set, we need to evaluate this now... 858 | CUSTOM_CHECK=`$BIN_ECHO $user | $BIN_SED -e "s/.*@//"` 859 | 860 | CUSTOM_CHECK_DOWN=`$BIN_ECHO $CUSTOM_CHECK | $BIN_SED -e "s/|.*//"` 861 | CUSTOM_CHECK_UP=`$BIN_ECHO $CUSTOM_CHECK | $BIN_SED -e "s/.*|//"` 862 | 863 | if [ "$CUSTOM_CHECK_DOWN" != "" ]; 864 | then 865 | rate $CUSTOM_CHECK_DOWN 866 | CUSTOM_USER_DOWN=$RATE 867 | fi 868 | 869 | if [ "$CUSTOM_CHECK_UP" != "" ]; 870 | then 871 | rate $CUSTOM_CHECK_UP 872 | CUSTOM_USER_UP=$RATE 873 | fi 874 | fi 875 | 876 | # Create classes for this user: 877 | if [ "$BORROW" == "1" ]; 878 | then 879 | if [ "$FEATURE_QOS_UP" == "1" ] 880 | then 881 | user_class_$CLASS_MODE $DEV_NET $MARK $RATE_USER_UP $CUSTOM_USER_UP 882 | fi 883 | 884 | if [ "$FEATURE_QOS_DOWN" == "1" ] 885 | then 886 | user_class_$CLASS_MODE $DEV_LAN $MARK $RATE_USER_DOWN $CUSTOM_USER_DOWN 887 | fi 888 | else 889 | if [ "$FEATURE_QOS_UP" == "1" ] 890 | then 891 | user_class_$CLASS_MODE $DEV_NET $MARK $RATE_USER_UP $RATE_USER_UP 892 | fi 893 | 894 | if [ "$FEATURE_QOS_DOWN" == "1" ] 895 | then 896 | user_class_$CLASS_MODE $DEV_LAN $MARK $RATE_USER_DOWN $RATE_USER_DOWN 897 | fi 898 | fi 899 | 900 | # If a user has more than one IP, get the single IPs now. 901 | # This sed converts "5:6:7" to "5 6 7" and removes rate-addons (@) and other junk. 902 | IP_LIST=`$BIN_ECHO $user | $BIN_SED -e "s/:/ /g" -e "s/[^0-9 ].*//"` 903 | 904 | # This can now be used in for loop: 905 | for ip in $IP_LIST; 906 | do 907 | # Expand IP by adding subnet: 908 | ip=$DEV_LAN_SUBNET.$ip 909 | 910 | # Subroutine fair_nat does the rest. 911 | fair_nat $ip $MARK 912 | done; 913 | done; 914 | 915 | # --- Port Forwarding: --- 916 | if [ "$FEATURE_FORWARD" == 1 ] 917 | then 918 | PORT_ARRAY=($PORTS) 919 | 920 | for ((i=0; i<$NUM_PORTS; i+=2)); 921 | do 922 | IP=$DEV_LAN_SUBNET.${PORT_ARRAY[$i]}; 923 | PORT=${PORT_ARRAY[$i+1]} 924 | 925 | forward $IP $PORT 926 | done; 927 | fi 928 | } 929 | # end of start_fairnat 930 | 931 | # === Main: === 932 | 933 | # First, we need to configure our script: 934 | CONFIG_CALLED=0 935 | 936 | # Maybe the user gave us some config parameter: 937 | for arg in $* 938 | do 939 | # Is the argument a file? Load it as configuration. 940 | if [ -f $arg ]; 941 | then 942 | configure $arg 943 | CONFIG_CALLED=1 944 | break 945 | fi 946 | done; 947 | 948 | # Otherwise just use the standard config. 949 | if [ "$CONFIG_CALLED" == "0" ]; 950 | then 951 | configure $FAIRNAT_CONFIG 952 | fi 953 | 954 | # Does the user want something special? 955 | for arg in $* 956 | do 957 | case "${arg}" in 958 | help) 959 | echo "usage: fairnat.sh [] [info|stop|version]" 960 | echo " : alternative configuration file to use" 961 | echo " info: give info about configuration file" 962 | echo " stop: stop Fair NAT iptables + shaping rules" 963 | echo " version: print version" 964 | exit 0 965 | ;; 966 | 967 | version) 968 | echo "Fair NAT v0.80 maintained by ." 969 | exit 0 970 | ;; 971 | 972 | stop) 973 | # The user wants us to stop fairnat and exit. 974 | stop_fairnat 975 | echo "Fair NAT stopped." 976 | exit 0 977 | ;; 978 | 979 | info) 980 | # Give some information about our config. 981 | echo "--- FEATURES ---" 982 | echo "$FEATURES" 983 | echo "--- LAN ---" 984 | echo "DEV: $DEV_LAN" 985 | echo "IP: $DEV_LAN_IP" 986 | echo "SUBNET: $DEV_LAN_SUBNET" 987 | echo "RATE: $RATE_LAN" 988 | echo "USERS: $USERS" 989 | echo "NUM_USERS: $NUM_USERS" 990 | echo "PORTS: $PORTS" 991 | echo "NUM_PORTS: $NUM_PORTS" 992 | echo "CLASS_MODE: $CLASS_MODE" 993 | echo "--- NET ---" 994 | echo "DEV: $DEV_NET" 995 | echo "IP: $DEV_NET_IP" 996 | echo "RATE_SUB_PERCENT: $RATE_SUB_PERCENT" 997 | echo "RATE_UP: $RATE_UP ($RATE_USER_UP per user)" 998 | echo "CEIL_USER_UP: $CEIL_USER_UP" 999 | echo "RATE_DOWN: $RATE_DOWN ($RATE_USER_DOWN per user)" 1000 | echo "CEIL_USER_DOWN: $CEIL_USER_DOWN" 1001 | echo "RATE_LOCAL_UP: $RATE_LOCAL_UP ($RATE_LOCAL_PERCENT%)" 1002 | echo "--- IPP2P ---" 1003 | echo "IPP2P_ENABLE: $IPP2P_ENABLE" 1004 | echo "IPP2P_UDP: $IPP2P_UDP" 1005 | echo "IPP2P_DROP_ALL: $IPP2P_DROP_ALL" 1006 | echo "IPP2P_DROP_MARKED: $IPP2P_DROP_MARKED" 1007 | echo "--- HACKS ---" 1008 | echo "MSS_CLAMPING: $MSS_CLAMPING" 1009 | echo "HTB_MPU: $HTB_MPU" 1010 | echo "HTB_OVERHEAD: $HTB_OVERHEAD" 1011 | echo "FAIRNAT_PREFIX: $FAIRNAT_PREFIX" 1012 | echo "--- BINARIES ---" 1013 | echo "iptables: $BIN_IPT" 1014 | echo "tc: $BIN_TC" 1015 | echo "ifconfig: $BIN_IFC" 1016 | echo "grep: $BIN_GREP" 1017 | echo "sed: $BIN_SED" 1018 | echo "echo: $BIN_ECHO" 1019 | echo "modprobe: $BIN_MODPROBE" 1020 | exit 0 1021 | ;; 1022 | esac 1023 | done; 1024 | 1025 | # We are ready to start Fair NAT now. 1026 | start_fairnat 1027 | 1028 | # === End of file. === 1029 | --------------------------------------------------------------------------------