#!/bin/sh /etc/rc.common START=95 STOP=01 EXTRA_COMMANDS="save reset show json" EXTRA_HELP=</dev/null) else used_bytes=0 fi echo -n $used_bytes } get_iptables_quota_rule_num(){ if [ -n "$EXCLUDE_NETWORK" ];then echo -n 3 else echo -n 1 fi } get_current_used_bytes(){ local used_bytes=$(iptables -vnxL $IPTABLES_CHAIN $(get_iptables_quota_rule_num) | awk '{print $2}') if [ -n "$used_bytes" ];then echo -n $used_bytes else get_saved_used_bytes fi } set_saved_used_bytes(){ local used_bytes=$(get_current_used_bytes) if [ $used_bytes -gt 0 ];then echo -n $used_bytes > $USED_BYTES_FILE fi } get_total_quota_until_today(){ local current_time=$(date +'%s') local first_day=$(date -d $(date +"%Y-%m-$FIRST_DAY") +'%s') local next_first_day if [ $current_time -ge $first_day ]; then next_first_day=$(date -d $(date -d "1 month" +"%Y-%m-$FIRST_DAY") +'%s') else next_first_day=$first_day first_day=$(date -d $(date -d "1 month ago" +"%Y-%m-$FIRST_DAY") +'%s') fi local seconds_in_month=$(($next_first_day - $first_day)) local montly_quota_bytes=$(($MONTHLY_QUOTA * 1024 * 1024 * 1024)) local elapsed_seconds_tomorrow=$(($(date -d $(date -d "1 day" +'%Y-%m-%d') +'%s') - $first_day)) echo -n $(($montly_quota_bytes * $elapsed_seconds_tomorrow / $seconds_in_month)) } get_remaining_quota(){ echo -n $(($(get_total_quota_until_today) - $(get_current_used_bytes))) } show_remaining_quota(){ echo Remaining: $(($(get_remaining_quota) / 1024 / 1024)) MB echo Total quota until today: $(($(get_total_quota_until_today) / 1024 / 1024)) MB } get_json(){ echo -n "{ \"remaining\": $(get_remaining_quota), \"used_bytes\": $(get_current_used_bytes), \"current_quota\": $(get_total_quota_until_today), \"total_quota\": $(($MONTHLY_QUOTA * 1024 * 1024 * 1024)) }" } reset_quota(){ iptables -Z $IPTABLES_CHAIN $(get_iptables_quota_rule_num) echo -n 0 > ${USED_BYTES_FILE} } del_iptables_rule(){ iptables -F $IPTABLES_CHAIN for chain_name in $IPTABLES_FORWARD $IPTABLES_INPUT $IPTABLES_OUTPUT do while true do line=$(iptables -L $chain_name|sed -e '1,2d'|grep -n $IPTABLES_CHAIN|head -1|cut -d : -f 1 2>/dev/null) [ -n "$(echo $line|grep -E ^[[:digit:]]+$)" ] && iptables -D $chain_name $line || break done done iptables -X $IPTABLES_CHAIN } set_iptables_rule(){ iptables -N $IPTABLES_CHAIN if [ -n "$EXCLUDE_NETWORK" ];then iptables -I $IPTABLES_CHAIN 1 -s $EXCLUDE_NETWORK -j ACCEPT iptables -I $IPTABLES_CHAIN 2 -d $EXCLUDE_NETWORK -j ACCEPT fi iptables -I $IPTABLES_CHAIN $(get_iptables_quota_rule_num) -c 0 $(get_saved_used_bytes) -m quota --quota $(get_remaining_quota) -j ACCEPT iptables -I $IPTABLES_CHAIN $(($(get_iptables_quota_rule_num) + 1)) -j REJECT # Iptables requires UTC time local start_time_utc=$(date -u +%H:%M --date=@$(date -d "today $START_TIME" +%s)) local end_time_utc=$(date -u +%H:%M --date=@$(date -d "today $END_TIME" +%s)) iptables -I $IPTABLES_FORWARD -i $WAN_DEV ! -s $INTRANET -m time --timestart $start_time_utc --timestop $end_time_utc -j $IPTABLES_CHAIN iptables -I $IPTABLES_FORWARD -o $WAN_DEV ! -d $INTRANET -m time --timestart $start_time_utc --timestop $end_time_utc -j $IPTABLES_CHAIN iptables -I $IPTABLES_INPUT -i $WAN_DEV ! -s $INTRANET -m time --timestart $start_time_utc --timestop $end_time_utc -j $IPTABLES_CHAIN iptables -I $IPTABLES_OUTPUT -o $WAN_DEV ! -d $INTRANET -m time --timestart $start_time_utc --timestop $end_time_utc -j $IPTABLES_CHAIN } start() { set_iptables_rule } stop() { set_saved_used_bytes echo $(date +'%F %H:%M') used_bytes=$(get_current_used_bytes) >> $LOG_FILE del_iptables_rule } restart() { stop start } save() { set_saved_used_bytes } reset() { reset_quota restart } show() { show_remaining_quota } json() { get_json }