#!/bin/bash

tc=/sbin/tc
iptables=/sbin/iptables
mode=htb
check=-1

function askBW() {
	leftBW=$bw
	echo -n "bandwidth to reserve for VoIP: "
	read bwVOIP; let leftBW=$bw-$bwVOIP; echo "left bandwidth: ${leftBW}kbit"
	echo -n "bandwidth to reserve for HTTP: "
	read bwHTTP; let leftBW=$leftBW-$bwHTTP; echo "left bandwidth: ${leftBW}kbit"
	echo -n "bandwidth to reserve for SSH: "
	read bwSSH; let leftBW=$leftBW-$bwSSH; echo "left bandwidth: ${leftBW}kbit"
	echo -n "bandwidth to reserve for IMAP: "
	read bwIMAP; let leftBW=$leftBW-$bwIMAP; 
	echo "bandwidth reserved for others: ${leftBW}kbit"
	bwOTHER=$leftBW

	let check=$bw-$bwVOIP-$bwHTTP-$bwSSH-$bwIMAP
	return $check
}

echo -n "Which device to setup for QoS <eth0|eth1>: "
read dev

echo -n "What is your max bandwidth (in kbit/s): "
read bw

while [ $check -le 0 ]; do
	askBW
done


# create root queueing discipline
$tc qdisc add dev $dev root handle 1:0 $mode
# create class and setup bandwidth
$tc class add dev $dev parent 1:0 classid 1:1 $mode rate ${bw}kbit

# setup bandwidth for services
echo "setup classes...."
$tc class add dev $dev parent 1:0 classid 1:21 $mode rate ${bwVOIP}kbit prio 0 # rtp
$tc class add dev $dev parent 1:0 classid 1:22 $mode rate ${bwHTTP}kbit prio 1 # http
$tc class add dev $dev parent 1:0 classid 1:23 $mode rate ${bwSSH}kbit prio 1  # ssh
$tc class add dev $dev parent 1:0 classid 1:24 $mode rate ${bwIMAP}kbit prio 2  # imap
$tc class add dev $dev parent 1:0 classid 1:25 $mode rate ${bwOTHER}kbit prio 3  # other

# setup stochastic fairness queueing, optimize every 10 seconds
echo "setup queueing method...."
$tc qdisc add dev $dev parent 1:21 handle 210:0 sfq perturb 10 
$tc qdisc add dev $dev parent 1:22 handle 220:0 sfq perturb 10 
$tc qdisc add dev $dev parent 1:23 handle 230:0 sfq perturb 10 
$tc qdisc add dev $dev parent 1:24 handle 240:0 sfq perturb 10 
$tc qdisc add dev $dev parent 1:25 handle 250:0 sfq perturb 10 

echo "mark packets via iptables...."
# RTP Stream class 1:21
$iptables -A POSTROUTING -t mangle -p udp -m udp --dport 10000:20000 -j MARK --set-mark 21 
# HTTP/HTTPs  class 1:22
$iptables -A POSTROUTING -t mangle -p tcp --dport 80 -j MARK --set-mark 22 
$iptables -A POSTROUTING -t mangle -p tcp --dport 443 -j MARK --set-mark 22 
# SSH class 1:23
$iptables -A POSTROUTING -t mangle -p tcp --dport 22 -j MARK --set-mark 23 
# IMAP class 1:24
$iptables -A POSTROUTING -t mangle -p tcp --dport 143 -j MARK --set-mark 24
$iptables -A POSTROUTING -t mangle -p tcp --dport 993 -j MARK --set-mark 24
# other class 1:25
$iptables -A POSTROUTING -t mangle -j MARK --set-mark 25

# send the packets to the right queue
echo "send packets to right queue...."
$tc filter add dev $dev parent 1:0 protocol ip handle 21 fw flowid 1:21 
$tc filter add dev $dev parent 1:0 protocol ip handle 22 fw flowid 1:22 
$tc filter add dev $dev parent 1:0 protocol ip handle 23 fw flowid 1:23 
$tc filter add dev $dev parent 1:0 protocol ip handle 24 fw flowid 1:24 
$tc filter add dev $dev parent 1:0 protocol ip handle 25 fw flowid 1:25 

