From b2b43143486c92bf53bbd5d53385fca334e079eb Mon Sep 17 00:00:00 2001 From: CN_SZTL Date: Tue, 3 Nov 2020 13:40:58 +0800 Subject: [PATCH] qos-gargoyle: drop outdated packages --- include/netfilter.mk | 7 - .../ctcgfw/gargoyle-firewall-util/Makefile | 72 - .../files/gargoyle_additions.firewall | 2 - .../files/gargoyle_firewall.hotplug | 40 - .../files/gargoyle_firewall_util.sh | 639 ---- .../files/modemaccess.pppoe | 49 - .../files/set_kernel_timezone.init | 21 - .../gargoyle-firewall-util/src/Makefile | 19 - .../src/backup_quotas.c | 228 -- .../src/delete_chain_from_table.c | 79 - .../src/make_iptables_rules.c | 1040 ------ .../gargoyle-firewall-util/src/print_quotas.c | 429 --- .../src/restore_quotas.c | 1105 ------- package/ctcgfw/libericstools/Makefile | 59 - package/ctcgfw/libericstools/src/Makefile | 92 - .../ctcgfw/libericstools/src/erics_tools.h | 309 -- package/ctcgfw/libericstools/src/file_util.c | 195 -- package/ctcgfw/libericstools/src/list.c | 280 -- .../ctcgfw/libericstools/src/priority_queue.c | 360 --- .../ctcgfw/libericstools/src/safe_malloc.c | 80 - .../ctcgfw/libericstools/src/string_util.c | 683 ---- .../libericstools/src/test_list_and_queue.c | 91 - package/ctcgfw/libericstools/src/test_map.c | 350 -- .../ctcgfw/libericstools/src/test_string.c | 26 - package/ctcgfw/libericstools/src/tree_map.c | 911 ------ package/ctcgfw/libiptbwctl/Makefile | 83 - package/ctcgfw/libiptbwctl/src/Makefile | 70 - package/ctcgfw/libiptbwctl/src/ipt_bwctl.c | 1349 -------- package/ctcgfw/libiptbwctl/src/ipt_bwctl.h | 161 - .../libiptbwctl/src/ipt_bwctl_safe_malloc.c | 23 - package/ctcgfw/libiptbwctl/src/utils/Makefile | 12 - package/ctcgfw/libiptbwctl/src/utils/bw_get.c | 177 -- .../src/utils/bw_print_history_file.c | 39 - package/ctcgfw/libiptbwctl/src/utils/bw_set.c | 186 -- .../src/utils/set_kernel_timezone.c | 27 - package/ctcgfw/luci-app-qos-gargoyle/Makefile | 22 - .../luasrc/controller/qos_gargoyle.lua | 100 - .../model/cbi/qos_gargoyle/download.lua | 166 - .../model/cbi/qos_gargoyle/download_class.lua | 61 - .../model/cbi/qos_gargoyle/download_rule.lua | 87 - .../luasrc/model/cbi/qos_gargoyle/global.lua | 124 - .../luasrc/model/cbi/qos_gargoyle/upload.lua | 160 - .../model/cbi/qos_gargoyle/upload_class.lua | 52 - .../model/cbi/qos_gargoyle/upload_rule.lua | 87 - .../luasrc/model/qos_gargoyle.lua | 38 - .../luasrc/view/qos_gargoyle/list_view.htm | 97 - .../view/qos_gargoyle/troubleshooting.htm | 52 - .../po/zh_Hans/luci-app-qos-gargoyle.po | 514 --- .../etc/uci-defaults/40_luci-qos_gargoyle | 11 - .../rpcd/acl.d/luci-app-qos-gargoyle.json | 11 - package/network/utils/iptables/Makefile | 24 - ...add-gargoyle-netfilter-match-modules.patch | 2811 ----------------- 52 files changed, 13710 deletions(-) delete mode 100644 package/ctcgfw/gargoyle-firewall-util/Makefile delete mode 100755 package/ctcgfw/gargoyle-firewall-util/files/gargoyle_additions.firewall delete mode 100644 package/ctcgfw/gargoyle-firewall-util/files/gargoyle_firewall.hotplug delete mode 100644 package/ctcgfw/gargoyle-firewall-util/files/gargoyle_firewall_util.sh delete mode 100644 package/ctcgfw/gargoyle-firewall-util/files/modemaccess.pppoe delete mode 100755 package/ctcgfw/gargoyle-firewall-util/files/set_kernel_timezone.init delete mode 100644 package/ctcgfw/gargoyle-firewall-util/src/Makefile delete mode 100644 package/ctcgfw/gargoyle-firewall-util/src/backup_quotas.c delete mode 100644 package/ctcgfw/gargoyle-firewall-util/src/delete_chain_from_table.c delete mode 100644 package/ctcgfw/gargoyle-firewall-util/src/make_iptables_rules.c delete mode 100644 package/ctcgfw/gargoyle-firewall-util/src/print_quotas.c delete mode 100644 package/ctcgfw/gargoyle-firewall-util/src/restore_quotas.c delete mode 100644 package/ctcgfw/libericstools/Makefile delete mode 100644 package/ctcgfw/libericstools/src/Makefile delete mode 100644 package/ctcgfw/libericstools/src/erics_tools.h delete mode 100644 package/ctcgfw/libericstools/src/file_util.c delete mode 100644 package/ctcgfw/libericstools/src/list.c delete mode 100644 package/ctcgfw/libericstools/src/priority_queue.c delete mode 100644 package/ctcgfw/libericstools/src/safe_malloc.c delete mode 100644 package/ctcgfw/libericstools/src/string_util.c delete mode 100644 package/ctcgfw/libericstools/src/test_list_and_queue.c delete mode 100644 package/ctcgfw/libericstools/src/test_map.c delete mode 100644 package/ctcgfw/libericstools/src/test_string.c delete mode 100644 package/ctcgfw/libericstools/src/tree_map.c delete mode 100644 package/ctcgfw/libiptbwctl/Makefile delete mode 100644 package/ctcgfw/libiptbwctl/src/Makefile delete mode 100644 package/ctcgfw/libiptbwctl/src/ipt_bwctl.c delete mode 100644 package/ctcgfw/libiptbwctl/src/ipt_bwctl.h delete mode 100644 package/ctcgfw/libiptbwctl/src/ipt_bwctl_safe_malloc.c delete mode 100644 package/ctcgfw/libiptbwctl/src/utils/Makefile delete mode 100644 package/ctcgfw/libiptbwctl/src/utils/bw_get.c delete mode 100644 package/ctcgfw/libiptbwctl/src/utils/bw_print_history_file.c delete mode 100644 package/ctcgfw/libiptbwctl/src/utils/bw_set.c delete mode 100644 package/ctcgfw/libiptbwctl/src/utils/set_kernel_timezone.c delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/Makefile delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/controller/qos_gargoyle.lua delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download.lua delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_class.lua delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_rule.lua delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/global.lua delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload.lua delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_class.lua delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_rule.lua delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/qos_gargoyle.lua delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/list_view.htm delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/troubleshooting.htm delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/po/zh_Hans/luci-app-qos-gargoyle.po delete mode 100755 package/ctcgfw/luci-app-qos-gargoyle/root/etc/uci-defaults/40_luci-qos_gargoyle delete mode 100644 package/ctcgfw/luci-app-qos-gargoyle/root/usr/share/rpcd/acl.d/luci-app-qos-gargoyle.json delete mode 100644 package/network/utils/iptables/patches/608-add-gargoyle-netfilter-match-modules.patch diff --git a/include/netfilter.mk b/include/netfilter.mk index 0bb2896e81..c1c3b4a9fd 100644 --- a/include/netfilter.mk +++ b/include/netfilter.mk @@ -114,13 +114,6 @@ $(eval $(call nf_add,IPT_FILTER,CONFIG_NETFILTER_XT_MATCH_BPF, $(P_XT)xt_bpf)) $(eval $(call nf_add,IPT_IMQ,CONFIG_IP_NF_TARGET_IMQ, $(P_V4)ipt_IMQ)) $(eval $(call nf_add,IPT_IMQ,CONFIG_NETFILTER_XT_TARGET_IMQ, $(P_XT)xt_IMQ)) -# gargoyle-qos - -$(eval $(call nf_add,IPT_BANDWIDTH,CONFIG_IP_NF_MATCH_BANDWIDTH, $(P_V4)ipt_bandwidth)) -$(eval $(call nf_add,IPT_TIMERANGE,CONFIG_IP_NF_MATCH_TIMERANGE, $(P_V4)ipt_timerange)) -$(eval $(call nf_add,IPT_WEBMON,CONFIG_IP_NF_MATCH_WEBMON, $(P_V4)ipt_webmon)) -$(eval $(call nf_add,IPT_WEBURL,CONFIG_IP_NF_MATCH_WEBURL, $(P_V4)ipt_weburl)) - # ipopt $(eval $(call nf_add,IPT_IPOPT,CONFIG_NETFILTER_XT_MATCH_DSCP, $(P_XT)xt_dscp)) diff --git a/package/ctcgfw/gargoyle-firewall-util/Makefile b/package/ctcgfw/gargoyle-firewall-util/Makefile deleted file mode 100644 index f3071ebb48..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=gargoyle-firewall-util -PKG_VERSION:=$(GARGOYLE_VERSION) -ifeq ($(GARGOYLE_VERSION),) - PKG_VERSION:=1.0.0 -endif -PKG_RELEASE:=1 - -PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) - -include $(INCLUDE_DIR)/package.mk - -define Package/gargoyle-firewall-util - SECTION:=net - CATEGORY:=Network - TITLE:=A couple of shell script routines for firewall initialization - DEPENDS:=+ebtables +libericstools +uci +libiptbwctl +iptables-mod-filter +iptables-mod-ipopt +iptables-mod-conntrack-extra +iptables-mod-nat-extra +iptables-mod-extra +iptables-mod-iprange +iptables-mod-bandwidth +iptables-mod-timerange +iptables-mod-weburl +kmod-gre +kmod-pptp +kmod-tun +kmod-nf-nathelper +kmod-nf-nathelper-extra - MAINTAINER:=Eric Bishop -endef - -define Package/gargoyle-firewall-util/description - A couple of shell script routines for firewall initialization -endef - -define Build/Prepare - echo PACKAGE BUILD DIR = $(PACKAGE_BUILD_DIR) - mkdir -p $(PKG_BUILD_DIR) - $(CP) ./src/* $(PKG_BUILD_DIR)/ -endef - -define Build/Configure -endef - - -define Build/Compile - $(MAKE) -C $(PKG_BUILD_DIR) \ - $(TARGET_CONFIGURE_OPTS) \ - STAGING_DIR="$(STAGING_DIR)" \ - CFLAGS="$(TARGET_CFLAGS) -I $(STAGING_DIR)/usr/include" \ - LDFLAGS="$(TARGET_LDFLAGS) -L $(STAGING_DIR)/usr/lib" -endef - - - -define Package/gargoyle-firewall-util/postinst - included=$$(cat $${IPKG_INSTROOT}/etc/config/firewall | grep 'gargoyle_additions.firewall' ) - if [ -z "$$included" ] ; then printf "config include\n\toption type script\n\toption path /usr/lib/gargoyle_firewall_util/gargoyle_additions.firewall\n\toption family IPv4\n\toption reload 1\n\n" >> $${IPKG_INSTROOT}/etc/config/firewall ; fi -endef - -define Package/gargoyle-firewall-util/install - $(INSTALL_DIR) $(1)/usr/lib/gargoyle_firewall_util/ - $(INSTALL_DIR) $(1)/etc/hotplug.d/iface/ - $(INSTALL_DIR) $(1)/usr/bin/ - $(INSTALL_DIR) $(1)/etc/init.d/ - $(INSTALL_DIR) $(1)/etc/ppp/ip-up.d/ - - $(INSTALL_BIN) $(PKG_BUILD_DIR)/make_iptables_rules $(1)/usr/bin/make_iptables_rules - $(INSTALL_BIN) $(PKG_BUILD_DIR)/delete_chain_from_table $(1)/usr/bin/delete_chain_from_table - $(INSTALL_BIN) $(PKG_BUILD_DIR)/backup_quotas $(1)/usr/bin/backup_quotas - $(INSTALL_BIN) $(PKG_BUILD_DIR)/restore_quotas $(1)/usr/bin/restore_quotas - $(INSTALL_BIN) $(PKG_BUILD_DIR)/print_quotas $(1)/usr/bin/print_quotas - - $(INSTALL_BIN) ./files/gargoyle_firewall_util.sh $(1)/usr/lib/gargoyle_firewall_util/gargoyle_firewall_util.sh - $(INSTALL_BIN) ./files/gargoyle_additions.firewall $(1)/usr/lib/gargoyle_firewall_util/gargoyle_additions.firewall - $(INSTALL_BIN) ./files/gargoyle_firewall.hotplug $(1)/etc/hotplug.d/iface/21-gargoyle_firewall - $(INSTALL_BIN) ./files/set_kernel_timezone.init $(1)/etc/init.d/set_kernel_timezone - $(INSTALL_BIN) ./files/modemaccess.pppoe $(1)/etc/ppp/ip-up.d/modemaccess.sh -endef - - -$(eval $(call BuildPackage,gargoyle-firewall-util)) diff --git a/package/ctcgfw/gargoyle-firewall-util/files/gargoyle_additions.firewall b/package/ctcgfw/gargoyle-firewall-util/files/gargoyle_additions.firewall deleted file mode 100755 index 86df4d28cb..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/files/gargoyle_additions.firewall +++ /dev/null @@ -1,2 +0,0 @@ -. /usr/lib/gargoyle_firewall_util/gargoyle_firewall_util.sh -initialize_firewall diff --git a/package/ctcgfw/gargoyle-firewall-util/files/gargoyle_firewall.hotplug b/package/ctcgfw/gargoyle-firewall-util/files/gargoyle_firewall.hotplug deleted file mode 100644 index f6748fe5b8..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/files/gargoyle_firewall.hotplug +++ /dev/null @@ -1,40 +0,0 @@ -if [ "$INTERFACE" = "wan" ]; then - - . /usr/lib/gargoyle_firewall_util/gargoyle_firewall_util.sh - - if [ "$ACTION" = "ifup" ]; then - - # previously we waited until firewall was up here, testing firewall.core.loaded in /var/state - # unfortunately that was removed in barrier breaker, but new firewall (fw3) loads very FAST as it's a binary - # So... just wait 2 seconds - sleep 2 - - #Bring up the parts of the firewall that depend on device name and WAN IP address. - ifup_firewall - - #Start up the bandwidth monitor which depends on the device name - if [ -h /etc/rc.d/S55bwmon_gargoyle ] ; then - /etc/init.d/bwmon_gargoyle restart - fi - fi - - if [ "$ACTION" = "ifdown" ]; then - quota_chains_exist=$(iptables -t mangle -L combined_quotas 2>/dev/null) - if [ -n "$quota_chains_exist" ] ; then - backup_quotas - fi - fi - -fi - -if [ "$INTERFACE" = "lan" ]; then - wan_exists=$(uci get network.wan 2>/dev/null) - if [ -z "$wan_exists" ] ; then - if [ "$ACTION" = "ifup" ]; then - /etc/init.d/bwmon_gargoyle restart - fi - if [ "$ACTION" = "ifdown" ]; then - /etc/init.d/bwmon_gargoyle stop - fi - fi -fi diff --git a/package/ctcgfw/gargoyle-firewall-util/files/gargoyle_firewall_util.sh b/package/ctcgfw/gargoyle-firewall-util/files/gargoyle_firewall_util.sh deleted file mode 100644 index 7d704e115f..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/files/gargoyle_firewall_util.sh +++ /dev/null @@ -1,639 +0,0 @@ -# Copyright Eric Bishop, 2008-2010 -# This is free software licensed under the terms of the GNU GPL v2.0 -# -. /lib/functions.sh -include /lib/network - -ra_mask="0x0080" -ra_mark="$ra_mask/$ra_mask" - -death_mask=0x8000 -death_mark="$death_mask" - -wan_if="" - -mask_to_cidr() -{ - mask="$1" - bits=0; - mask_parts=$(echo $mask | sed 's/\./ /g') - for p in $mask_parts ; do - case $p in - 255) - bits=$(($bits + 8)) ;; - 254) - bits=$(($bits + 7)) ;; - 252) - bits=$(($bits + 6)) ;; - 248) - bits=$(($bits + 5)) ;; - 240) - bits=$(($bits + 4)) ;; - 224) - bits=$(($bits + 3)) ;; - 192) - bits=$(($bits + 2)) ;; - 128) - bits=$(($bits + 1)) ;; - esac - done - echo $bits -} - -define_wan_if() -{ - if [ -z "$wan_if" ] ; then - #Wait for up to 15 seconds for the wan interface to indicate it is up. - wait_sec=15 - while [ -z "$(uci -P /var/state get network.wan.up 2>/dev/null)" ] && [ "$wait_sec" -gt 0 ] ; do - sleep 1 - wait_sec=$(($wait_sec - 1)) - done - - #The interface name will depend on if pppoe is used or not. If pppoe is used then - #the name we are looking for is in network.wan.ifname. If there is nothing there - #use the device named by network.wan.device - - wan_if=$(uci -P /var/state get network.wan.ifname 2>/dev/null) - if [ -z "$wan_if" ] ; then - wan_if=$(uci -P /var/state get network.wan.device 2>/dev/null) - fi - fi -} - -# parse remote_accept sections in firewall config and add necessary rules -insert_remote_accept_rules() -{ - local config_name="firewall" - local section_type="remote_accept" - - ssh_max_attempts=$(uci get dropbear.@dropbear[0].max_remote_attempts 2>/dev/null) - ssh_port=$(uci get dropbear.@dropbear[0].Port) - if [ -z "$ssh_max_attempts" ] || [ "$ssh_max_attempts" = "unlimited" ] ; then - ssh_max_attempts="" - else - ssh_max_attempts=$(( $ssh_max_attempts + 1 )) - fi - - #add rules for remote_accepts - parse_remote_accept_config() - { - vars="local_port remote_port start_port end_port proto zone" - proto="tcp udp" - zone="wan" - for var in $vars ; do - config_get $var $1 $var - done - if [ "$proto" = "tcpudp" ] || [ -z "$proto" ] ; then - proto="tcp udp" - fi - - for prot in $proto ; do - if [ -n "$local_port" ] ; then - - if [ -z "$remote_port" ] ; then - remote_port="$local_port" - fi - - #Discourage brute force attacks on ssh from the WAN by limiting failed conneciton attempts. - #Each attempt gets a maximum of 10 password tries by dropbear. - if [ -n "$ssh_max_attempts" ] && [ "$local_port" = "$ssh_port" ] && [ "$prot" = "tcp" ] ; then - iptables -t filter -A "input_${zone}_rule" -p "$prot" --dport $ssh_port -m recent --set --name SSH_CHECK - iptables -t filter -A "input_${zone}_rule" -m recent --update --seconds 300 --hitcount $ssh_max_attempts --name SSH_CHECK -j DROP - fi - - if [ "$remote_port" != "$local_port" ] ; then - #since we're inserting with -I, insert redirect rule first which will then be hit second, after setting connmark - iptables -t nat -I "zone_"$zone"_prerouting" -p "$prot" --dport "$remote_port" -j REDIRECT --to-ports "$local_port" - iptables -t nat -I "zone_"$zone"_prerouting" -p "$prot" --dport "$remote_port" -j CONNMARK --set-mark "$ra_mark" - iptables -t filter -A "input_${zone}_rule" -p $prot --dport "$local_port" -m connmark --mark "$ra_mark" -j ACCEPT - else - iptables -t nat -I "zone_"$zone"_prerouting" -p "$prot" --dport "$remote_port" -j REDIRECT --to-ports "$local_port" - iptables -t filter -A "input_${zone}_rule" -p "$prot" --dport "$local_port" -j ACCEPT - fi - elif [ -n "$start_port" ] && [ -n "$end_port" ] ; then - iptables -t nat -I "zone_"$zone"_prerouting" -p "$prot" --dport "$start_port:$end_port" -j REDIRECT - iptables -t filter -A "input_${zone}_rule" -p "$prot" --dport "$start_port:$end_port" -j ACCEPT - fi - done - } - config_load "$config_name" - config_foreach parse_remote_accept_config "$section_type" -} - -# creates a chain that sets third byte of connmark to a value that denotes what l7 proto -# is associated with connection. This only sets the connmark, it does not save it to mark -create_l7marker_chain() -{ - # eliminate chain if it exists - delete_chain_from_table "mangle" "l7marker" - - app_proto_num=1 - app_proto_shift=16 - app_proto_mask="0xFF0000" - - all_prots=$(ls /etc/l7-protocols/* | sed 's/^.*\///' | sed 's/\.pat$//' ) - qos_active=$(ls /etc/rc.d/*qos_gargoyle* 2>/dev/null) - if [ -n "$qos_active" ] ; then - qos_l7=$(uci show qos_gargoyle | sed '/layer7=/!d; s/^.*=//g') - fi - fw_l7=$(uci show firewall | sed '/app_proto/!d; s/^.*=//g') - all_used="$fw_l7 $qos_l7" - - if [ "$all_used" != " " ] ; then - iptables -t mangle -N l7marker - iptables -t mangle -I PREROUTING -m connbytes --connbytes 0:20 --connbytes-dir both --connbytes-mode packets -m connmark --mark 0x0/$app_proto_mask -j l7marker - iptables -t mangle -I POSTROUTING -m connbytes --connbytes 0:20 --connbytes-dir both --connbytes-mode packets -m connmark --mark 0x0/$app_proto_mask -j l7marker - - for proto in $all_prots ; do - proto_is_used=$(echo "$all_used" | grep "$proto") - if [ -n "$proto_is_used" ] ; then - app_proto_mark=$(printf "0x%X" $(($app_proto_num << $app_proto_shift)) ) - iptables -t mangle -A l7marker -m connmark --mark 0x0/$app_proto_mask -m layer7 --l7proto $proto -j CONNMARK --set-mark $app_proto_mark/$app_proto_mask - echo "$proto $app_proto_mark $app_proto_mask" >> /tmp/l7marker.marks.tmp - app_proto_num=$((app_proto_num + 1)) - fi - done - - copy_file="y" - if [ -e /etc/md5/layer7.md5 ] ; then - old_md5=$(cat /etc/md5/layer7.md5) - current_md5=$(md5sum /tmp/l7marker.marks.tmp | awk ' { print $1 ; } ' ) - if [ "$current_md5" = "$old_md5" ] ; then - copy_file="n" - fi - fi - - if [ "$copy_file" = "y" ] ; then - mv /tmp/l7marker.marks.tmp /etc/l7marker.marks - mkdir -p /etc/md5 - md5sum /etc/l7marker.marks | awk ' { print $1 ; }' > /etc/md5/layer7.md5 - else - rm /tmp/l7marker.marks.tmp - fi - fi -} - -insert_pf_loopback_rules() -{ - config_name="firewall" - section_type="redirect" - - #Need to always delete the old chains first. - delete_chain_from_table "nat" "pf_loopback_A" - delete_chain_from_table "filter" "pf_loopback_B" - delete_chain_from_table "nat" "pf_loopback_C" - - define_wan_if - if [ -z "$wan_if" ] ; then return ; fi - wan_ip=$(uci -p /tmp/state get network.wan.ipaddr) - lan_mask=$(uci -p /tmp/state get network.lan.netmask) - - if [ -n "$wan_ip" ] && [ -n "$lan_mask" ] ; then - - iptables -t nat -N "pf_loopback_A" - iptables -t filter -N "pf_loopback_B" - iptables -t nat -N "pf_loopback_C" - - iptables -t nat -I zone_lan_prerouting -d $wan_ip -j pf_loopback_A - iptables -t filter -I zone_lan_forward -j pf_loopback_B - iptables -t nat -I postrouting_rule -o br-lan -j pf_loopback_C - - add_pf_loopback() - { - local vars="src dest proto src_dport dest_ip dest_port" - local all_defined="1" - for var in $vars ; do - config_get $var $1 $var - loaded=$(eval echo "\$$var") - #echo $var = $loaded - if [ -z "$loaded" ] && [ ! "$var" = "$src_dport" ] ; then - all_defined="0" - fi - done - - if [ -z "$src_dport" ] ; then - src_dport=$dest_port - fi - - sdp_dash=$src_dport - sdp_colon=$(echo $sdp_dash | sed 's/\-/:/g') - dp_dash=$dest_port - dp_colon=$(echo $dp_dash | sed 's/\-/:/g') - - if [ "$all_defined" = "1" ] && [ "$src" = "wan" ] && [ "$dest" = "lan" ] ; then - iptables -t nat -A pf_loopback_A -p $proto --dport $sdp_colon -j DNAT --to-destination $dest_ip:$dp_dash - iptables -t filter -A pf_loopback_B -p $proto --dport $dp_colon -d $dest_ip -j ACCEPT - iptables -t nat -A pf_loopback_C -p $proto --dport $dp_colon -d $dest_ip -s $dest_ip/$lan_mask -j MASQUERADE - fi - } - - config_load "$config_name" - config_foreach add_pf_loopback "$section_type" - fi -} - -insert_dmz_rule() -{ - local config_name="firewall" - local section_type="dmz" - - #add rules for remote_accepts - parse_dmz_config() - { - vars="to_ip from" - for var in $vars ; do - config_get $var $1 $var - done - if [ -n "$from" ] ; then - from_if=$(uci -q -p /tmp/state get network.$from.ifname) - fi - # echo "from_if = $from_if" - if [ -n "$to_ip" ] && [ -n "$from" ] && [ -n "$from_if" ] ; then - iptables -t nat -A "zone_"$from"_prerouting" -i $from_if -j DNAT --to-destination $to_ip - # echo "iptables -t nat -A "prerouting_"$from -i $from_if -j DNAT --to-destination $to_ip" - iptables -t filter -I "zone_"$from"_forward" -d $to_ip -j ACCEPT - fi - } - config_load "$config_name" - config_foreach parse_dmz_config "$section_type" -} - -insert_restriction_rules() -{ - define_wan_if - if [ -z "$wan_if" ] ; then return ; fi - - if [ -e /tmp/restriction_init.lock ] ; then return ; fi - touch /tmp/restriction_init.lock - - egress_exists=$(iptables -t filter -L egress_restrictions 2>/dev/null) - ingress_exists=$(iptables -t filter -L ingress_restrictions 2>/dev/null) - - if [ -n "$egress_exists" ] ; then - delete_chain_from_table filter egress_whitelist - delete_chain_from_table filter egress_restrictions - fi - if [ -n "$ingress_exists" ] ; then - delete_chain_from_table filter ingress_whitelist - delete_chain_from_table filter ingress_restrictions - fi - - iptables -t filter -N egress_restrictions - iptables -t filter -N ingress_restrictions - iptables -t filter -N egress_whitelist - iptables -t filter -N ingress_whitelist - - iptables -t filter -I FORWARD -o $wan_if -j egress_restrictions - iptables -t filter -I FORWARD -i $wan_if -j ingress_restrictions - - iptables -t filter -I egress_restrictions -j egress_whitelist - iptables -t filter -I ingress_restrictions -j ingress_whitelist - - package_name="firewall" - parse_rule_config() - { - section=$1 - section_type=$(uci get "$package_name"."$section") - - config_get "enabled" "$section" "enabled" - if [ -z "$enabled" ] ; then enabled="1" ; fi - if [ "$enabled" = "1" ] && ( [ "$section_type" = "restriction_rule" ] || [ "$section_type" = "whitelist_rule" ] ) ; then - #convert app_proto && not_app_proto to connmark here - config_get "app_proto" "$section" "app_proto" - config_get "not_app_proto" "$section" "not_app_proto" - - if [ -n "$app_proto" ] ; then - app_proto_connmark=$(cat /etc/l7marker.marks 2>/dev/null | grep $app_proto | awk '{ print $2 ; }' ) - app_proto_mask=$(cat /etc/l7marker.marks 2>/dev/null | grep $app_proto | awk '{ print $3 ; }' ) - uci set "$package_name"."$section".connmark="$app_proto_connmark/$app_proto_mask" - fi - if [ -n "$not_app_proto" ] ; then - not_app_proto_connmark=$(cat /etc/l7marker.marks 2>/dev/null | grep "$not_app_proto" | awk '{ print $2 }') - not_app_proto_mask=$(cat /etc/l7marker.marks 2>/dev/null | grep "$not_app_proto" | awk '{ print $3 }') - uci set "$package_name"."$section".not_connmark="$not_app_proto_connmark/$not_app_proto_mask" - fi - - table="filter" - chain="egress_restrictions" - ingress="" - target="REJECT" - - config_get "is_ingress" "$section" "is_ingress" - if [ "$is_ingress" = "1" ] ; then - ingress=" -i " - if [ "$section_type" = "restriction_rule" ] ; then - chain="ingress_restrictions" - else - chain="ingress_whitelist" - fi - else - if [ "$section_type" = "restriction_rule" ] ; then - chain="egress_restrictions" - else - chain="egress_whitelist" - fi - fi - - if [ "$section_type" = "whitelist_rule" ] ; then - target="ACCEPT" - fi - - make_iptables_rules -p "$package_name" -s "$section" -t "$table" -c "$chain" -g "$target" $ingress - make_iptables_rules -p "$package_name" -s "$section" -t "$table" -c "$chain" -g "$target" $ingress -r - - uci del "$package_name"."$section".connmark 2>/dev/null - uci del "$package_name"."$section".not_connmark 2>/dev/null - fi - } - - config_load "$package_name" - config_foreach parse_rule_config "whitelist_rule" - config_foreach parse_rule_config "restriction_rule" - - rm -rf /tmp/restriction_init.lock -} - -initialize_quotas() -{ - define_wan_if - if [ -z "$wan_if" ] ; then return ; fi - - if [ -e /tmp/quota_init.lock ] ; then return ; fi - touch /tmp/quota_init.lock - - lan_mask=$(uci -p /tmp/state get network.lan.netmask) - lan_ip=$(uci -p /tmp/state get network.lan.ipaddr) - full_qos_enabled=$(ls /etc/rc.d/*qos_gargoyle 2>/dev/null) - - if [ -n "$full_qos_enabled" ] ; then - full_up=$(uci get qos_gargoyle.upload.total_bandwidth 2>/dev/null) - full_down=$(uci get qos_gargoyle.download.total_bandwidth 2>/dev/null) - if [ -z "$full_up" ] && [ -z "$full_down" ] ; then - full_qos_enabled="" - fi - fi - - - # restore_quotas does the hard work of building quota chains & rebuilding crontab file to do backups - # - # this initializes qos functions ONLY if we have quotas that - # have up and down speeds defined for when quota is exceeded - # and full qos is not enabled - if [ -z "$full_qos_enabled" ] ; then - restore_quotas -w $wan_if -d $death_mark -m $death_mask -s "$lan_ip/$lan_mask" -c "0 0,4,8,12,16,20 * * * /usr/bin/backup_quotas >/dev/null 2>&1" - initialize_quota_qos - else - restore_quotas -q -w $wan_if -d $death_mark -m $death_mask -s "$lan_ip/$lan_mask" -c "0 0,4,8,12,16,20 * * * /usr/bin/backup_quotas >/dev/null 2>&1" - cleanup_old_quota_qos - fi - - #enable cron, but only restart cron if it is currently running - #since we initialize this before cron, this will - #make sure we don't start cron twice at boot - /etc/init.d/cron enable - cron_active=$(ps | grep "crond" | grep -v "grep" ) - if [ -n "$cron_active" ] ; then - /etc/init.d/cron restart - fi - - rm -rf /tmp/quota_init.lock -} - -load_all_config_sections() -{ - local config_name="$1" - local section_type="$2" - - all_config_sections="" - section_order="" - config_cb() - { - if [ -n "$2" ] || [ -n "$1" ] ; then - if [ -n "$section_type" ] ; then - if [ "$1" = "$section_type" ] ; then - all_config_sections="$all_config_sections $2" - fi - else - all_config_sections="$all_config_sections $2" - fi - fi - } - - config_load "$config_name" - echo "$all_config_sections" -} - -cleanup_old_quota_qos() -{ - for iface in $(tc qdisc show | awk '{print $5}' | sort -u ); do - tc qdisc del dev "$iface" root >/dev/null 2>&1 - done -} - -initialize_quota_qos() -{ - cleanup_old_quota_qos - - #speeds should be in kbyte/sec, units should NOT be present in config file (unit processing should be done by front-end) - quota_sections=$(load_all_config_sections "firewall" "quota") - upload_speeds="" - download_speeds="" - config_load "firewall" - for q in $quota_sections ; do - config_get "exceeded_up_speed" $q "exceeded_up_speed" - config_get "exceeded_down_speed" $q "exceeded_down_speed" - if [ -n "$exceeded_up_speed" ] && [ -n "$exceeded_down_speed" ] ; then - if [ $exceeded_up_speed -gt 0 ] && [ $exceeded_down_speed -gt 0 ] ; then - upload_speeds="$exceeded_up_speed $upload_speeds" - download_speeds="$exceeded_down_speed $download_speeds" - fi - fi - done - - #echo "upload_speeds = $upload_speeds" - - unique_up=$( printf "%d\n" $upload_speeds 2>/dev/null | sort -u -n) - unique_down=$( printf "%d\n" $download_speeds 2>/dev/null | sort -u -n) - - #echo "unique_up = $unique_up" - - num_up_bands=1 - num_down_bands=1 - if [ -n "$upload_speeds" ] ; then - num_up_bands=$((1 + $(printf "%d\n" $upload_speeds 2>/dev/null | sort -u -n | wc -l) )) - fi - if [ -n "$download_speeds" ] ; then - num_down_bands=$((1 + $(printf "%d\n" $download_speeds 2>/dev/null | sort -u -n | wc -l) )) - fi - - #echo "num_up_bands=$num_up_bands" - #echo "num_down_bands=$num_down_bands" - - if [ -n "$wan_if" ] && [ $num_up_bands -gt 1 ] && [ $num_down_bands -gt 1 ] ; then - insmod sch_prio >/dev/null 2>&1 - insmod sch_tbf >/dev/null 2>&1 - insmod cls_fw >/dev/null 2>&1 - - ifconfig imq0 down >/dev/null 2>&1 - ifconfig imq1 down >/dev/null 2>&1 - rmmod imq >/dev/null 2>&1 - insmod imq numdevs=1 hook_chains="INPUT,FORWARD" hook_tables="mangle,mangle" >/dev/null 2>&1 - ip link set imq0 up - - #egress/upload - tc qdisc del dev $wan_if root >/dev/null 2>&1 - tc qdisc add dev $wan_if handle 1:0 root prio bands $num_up_bands priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - cur_band=2 - upload_shift=0 - for rate_kb in $unique_up ; do - kbit=$(echo $((rate_kb*8))kbit) - mark=$(($cur_band << $upload_shift)) - tc filter add dev $wan_if parent 1:0 prio $cur_band protocol ip handle $mark fw flowid 1:$cur_band - tc qdisc add dev $wan_if parent 1:$cur_band handle $cur_band: tbf rate $kbit burst $kbit limit $kbit - cur_band=$(($cur_band+1)) - done - - #ingress/download - tc qdisc del dev imq0 root >/dev/null 2>&1 - tc qdisc add dev imq0 handle 1:0 root prio bands $num_down_bands priomap 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - cur_band=2 - download_shift=8 - for rate_kb in $unique_down ; do - kbit=$(echo $((rate_kb*8))kbit) - mark=$(($cur_band << $download_shift)) - tc filter add dev imq0 parent 1:0 prio $cur_band protocol ip handle $mark fw flowid 1:$cur_band - tc qdisc add dev imq0 parent 1:$cur_band handle $cur_band: tbf rate $kbit burst $kbit limit $kbit - cur_band=$(($cur_band+1)) - done - - iptables -t mangle -I ingress_quotas -i $wan_if -j IMQ --todev 0 - - #tc -s qdisc show dev $wan_if - #tc -s qdisc show dev imq0 - fi -} - -enforce_dhcp_assignments() -{ - enforce_assignments=$(uci get firewall.@defaults[0].enforce_dhcp_assignments 2> /dev/null) - delete_chain_from_table "filter" "lease_mismatch_check" - - local pairs1 - local pairs2 - local pairs - pairs1="" - pairs2="" - if [ -e /tmp/dhcp.leases ] ; then - pairs1=$(cat /tmp/dhcp.leases | sed '/^[ \t]*$/d' | awk ' { print $2"^"$3"\n" ; } ' ) - fi - if [ -e /etc/ethers ] ; then - pairs2=$(cat /etc/ethers | sed '/^[ \t]*$/d' | awk ' { print $1"^"$2"\n" ; } ' ) - fi - pairs=$( printf "$pairs1\n$pairs2\n" | sort | uniq ) - - - if [ "$enforce_assignments" = "1" ] && [ -n "$pairs" ] ; then - iptables -t filter -N lease_mismatch_check - local p - for p in $pairs ; do - local mac - local ip - mac=$(echo $p | sed 's/\^.*$//g') - ip=$(echo $p | sed 's/^.*\^//g') - if [ -n "$ip" ] && [ -n "$mac" ] ; then - iptables -t filter -A lease_mismatch_check ! -s "$ip" -m mac --mac-source "$mac" -j REJECT - iptables -t filter -A lease_mismatch_check -s "$ip" -m mac ! --mac-source "$mac" -j REJECT - fi - done - iptables -t filter -I delegate_forward -j lease_mismatch_check - fi -} - -force_router_dns() -{ - force_router_dns=$(uci get firewall.@defaults[0].force_router_dns 2> /dev/null) - if [ "$force_router_dns" = "1" ] ; then - iptables -t nat -I zone_lan_prerouting -p tcp --dport 53 -j REDIRECT - iptables -t nat -I zone_lan_prerouting -p udp --dport 53 -j REDIRECT - fi -} - -add_adsl_modem_routes() -{ - wan_proto=$(uci -q get network.wan.proto) - if [ "$wan_proto" = "pppoe" ] ; then - wan_dev=$(uci -q get network.wan.ifname) #not really the interface, but the device - iptables -A postrouting_rule -t nat -o $wan_dev -j MASQUERADE - iptables -A forwarding_rule -o $wan_dev -j ACCEPT - /etc/ppp/ip-up.d/modemaccess.sh firewall $wan_dev - fi -} - -initialize_firewall() -{ - iptables -I zone_lan_forward -i br-lan -o br-lan -j ACCEPT - insert_remote_accept_rules - insert_dmz_rule - create_l7marker_chain - enforce_dhcp_assignments - force_router_dns - add_adsl_modem_routes - isolate_guest_networks -} - - -guest_mac_from_uci() -{ - local is_guest_network - local macaddr - config_get is_guest_network "$1" is_guest_network - if [ "$is_guest_network" = "1" ] ; then - config_get macaddr "$1" macaddr - echo "$macaddr" - fi -} -get_guest_macs() -{ - config_load "wireless" - config_foreach guest_mac_from_uci "wifi-iface" -} -isolate_guest_networks() -{ - ebtables -t filter -F FORWARD - ebtables -t filter -F INPUT - local guest_macs=$( get_guest_macs ) - if [ -n "$guest_macs" ] ; then - local lanifs=`brctl show br-lan 2>/dev/null | awk ' $NF !~ /interfaces/ { print $NF } '` - local lif - - local lan_ip=$(uci -p /tmp/state get network.lan.ipaddr) - - for lif in $lanifs ; do - for gmac in $guest_macs ; do - local is_guest=$(ifconfig "$lif" 2>/dev/null | grep -i "$gmac") - if [ -n "$is_guest" ] ; then - echo "$lif with mac $gmac is wireless guest" - - #Allow access to WAN but not other LAN hosts for anyone on guest network - ebtables -t filter -A FORWARD -i "$lif" --logical-out br-lan -j DROP - - #Only allow DHCP/DNS access to router for anyone on guest network - ebtables -t filter -A INPUT -i "$lif" -p ARP -j ACCEPT - ebtables -t filter -A INPUT -i "$lif" -p IPV4 --ip-protocol udp --ip-destination-port 53 -j ACCEPT - ebtables -t filter -A INPUT -i "$lif" -p IPV4 --ip-protocol udp --ip-destination-port 67 -j ACCEPT - ebtables -t filter -A INPUT -i "$lif" -p IPV4 --ip-destination $lan_ip -j DROP - - fi - done - done - fi -} - - -ifup_firewall() -{ - insert_restriction_rules - initialize_quotas - insert_pf_loopback_rules -} diff --git a/package/ctcgfw/gargoyle-firewall-util/files/modemaccess.pppoe b/package/ctcgfw/gargoyle-firewall-util/files/modemaccess.pppoe deleted file mode 100644 index fce322bc8b..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/files/modemaccess.pppoe +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/sh - -#This script allows access to the ADSL modem web interface when pppoe is used. -#For this to work configure your modem in bridge mode with DHCP enabled on the modem. -#This will cause the modem to dish an address to the router interface when requested below. -# -#Alternatively you can manually set the below variable ROUTER_IP with the IP address -#you want to use. Make sure the IP address is on the same network as the modem. -#ROUTER_IP=10.0.0.2 - -#Main case statement used only by udhcp which only calls with one of the -#following four key words in parameter 1. -case "$1" in - deconfig) - ifconfig "$interface" 0.0.0.0 - exit 0 - ;; - renew) - ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+} - exit 0 - ;; - bound) - ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+} - exit 0 - ;; - nak) - exit 0 - ;; - leasefail) - exit 0 - ;; -esac - -#if we get here then udhcp did not call us. Must be from pppd or /usr/lib/gargoyle_firewall_util - -#configure the ethernet interface. -if [ -n "$ROUTER_IP" ] ; then - #In manual mode the user gave us an IP address for our interface - ifconfig $2 $ROUTER_IP netmask 255.255.255.0 -else - #In auto mode we first check if we have an ip address already. - ROUTER_IP=$(ifconfig $2 | grep "inet addr:") - if [ -z "$ROUTER_IP" ]; then - #Dont have one so try an get one. - udhcpc -f -i $2 -n -q -s /etc/ppp/ip-up.d/modemaccess.sh - fi -fi - -exit 0 diff --git a/package/ctcgfw/gargoyle-firewall-util/files/set_kernel_timezone.init b/package/ctcgfw/gargoyle-firewall-util/files/set_kernel_timezone.init deleted file mode 100755 index 3508f294d4..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/files/set_kernel_timezone.init +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh /etc/rc.common -START=30 - -start() -{ - /usr/bin/set_kernel_timezone - - touch /etc/crontabs/root - if ! grep -q "set_kernel_timezone" /etc/crontabs/root; then - echo '0,1,11,21,31,41,51 * * * * /usr/bin/set_kernel_timezone >/dev/null 2>&1' >> /etc/crontabs/root - /etc/init.d/cron enable - #only restart cron if it is currently running - #since we initialize this before cron, this will - #make sure we don't start cron twice at boot - cron_active=$(ps | grep "crond" | grep -v "grep" ) - if [ -n "$cron_active" ] ; then - /etc/init.d/cron restart - fi - fi -} - diff --git a/package/ctcgfw/gargoyle-firewall-util/src/Makefile b/package/ctcgfw/gargoyle-firewall-util/src/Makefile deleted file mode 100644 index 9c1f4417be..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/src/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -all: make_iptables_rules delete_chain_from_table backup_quotas restore_quotas print_quotas - -print_quotas: print_quotas.c - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lericstools -luci -liptbwctl - -restore_quotas: restore_quotas.c - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lericstools -luci -liptbwctl - -backup_quotas: backup_quotas.c - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lericstools -luci -liptbwctl - -delete_chain_from_table: delete_chain_from_table.c - $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lericstools - -make_iptables_rules: make_iptables_rules.c - $(CC) $(CFLAGS) $(LDFLAGS) make_iptables_rules.c -o make_iptables_rules -lericstools -luci -lm - -clean: - rm -rf make_iptables_rules delete_chain_from_table print_quotas backup_quotas restore_quotas *.o *~ .*sw* diff --git a/package/ctcgfw/gargoyle-firewall-util/src/backup_quotas.c b/package/ctcgfw/gargoyle-firewall-util/src/backup_quotas.c deleted file mode 100644 index 5d4e58aca8..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/src/backup_quotas.c +++ /dev/null @@ -1,228 +0,0 @@ -/* backup_quotas -- Used to backup quota data from iptables rules that use the "bandwidth" module - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#include -#include -#include - -#include -#include -#include -#define malloc safe_malloc -#define strdup safe_strdup - -list* get_all_sections_of_type(struct uci_context *ctx, char* package, char* section_type); -void backup_quota(char* quota_id, char* quota_backup_dir); -char* get_uci_option(struct uci_context* ctx,char* package_name, char* section_name, char* option_name); -char* get_option_value_string(struct uci_option* uopt); - - -int main(void) -{ - struct uci_context *ctx = uci_alloc_context(); - list* quota_sections = get_all_sections_of_type(ctx, "firewall", "quota"); - system("mkdir -p /usr/data/quotas"); - unlock_bandwidth_semaphore_on_exit(); - while(quota_sections->length > 0) - { - char* next_quota = shift_list(quota_sections); - char* ignore_backup = get_uci_option(ctx, "firewall", next_quota, "ignore_backup_at_next_restore"); - int do_backup = 1; - if(ignore_backup != NULL) - { - if(strcmp(ignore_backup, "1") == 0) - { - do_backup = 0; - } - free(ignore_backup); - } - - if(do_backup) - { - //do backup - - /* base id for quota is the ip associated with it*/ - char* backup_id = get_uci_option(ctx, "firewall", next_quota, "id"); - char* ip = get_uci_option(ctx, "firewall", next_quota, "ip"); - if(ip == NULL) - { - ip = strdup("ALL"); - } - else if(strcmp(ip, "") == 0) - { - free(ip); - ip = strdup("ALL"); - } - if(backup_id == NULL) - { - backup_id = strdup(ip); - } - else if(strcmp(backup_id, "") == 0) - { - free(backup_id); - backup_id = strdup(ip); - } - - - char* types[] = { "ingress_limit", "egress_limit", "combined_limit" }; - char* postfixes[] = { "_ingress", "_egress", "_combined" }; - int type_index; - for(type_index=0; type_index < 3; type_index++) - { - char* defined = get_uci_option(ctx, "firewall", next_quota, types[type_index]); - if(defined != NULL) - { - char* type_id = dynamic_strcat(2, backup_id, postfixes[type_index]); - - backup_quota(type_id, "/usr/data/quotas" ); - - free(type_id); - free(defined); - } - - } - free(backup_id); - free(ip); - } - free(next_quota); - } - - unsigned long num; - destroy_list(quota_sections, DESTROY_MODE_FREE_VALUES, &num); - uci_free_context(ctx); - - return 0; -} - -list* get_all_sections_of_type(struct uci_context *ctx, char* package, char* section_type) -{ - - struct uci_package *p = NULL; - struct uci_element *e = NULL; - - list* sections_of_type = initialize_list(); - if(uci_load(ctx, package, &p) == UCI_OK) - { - uci_foreach_element( &p->sections, e) - { - struct uci_section *section = uci_to_section(e); - if(safe_strcmp(section->type, section_type) == 0) - { - push_list(sections_of_type, strdup(section->e.name)); - } - } - } - return sections_of_type; -} - -void backup_quota(char* id, char* quota_backup_dir) -{ - /* if we ever bother to allow quotas to apply to subnets - * specified with '/', this may be necessary - */ - char* quota_file_name; - if(strstr(id, "/") != NULL) - { - char* quota_file_name = dynamic_replace(id, "/", "_"); - } - else - { - quota_file_name = strdup(id); - } - - char* quota_file_path = dynamic_strcat(3, quota_backup_dir, "/quota_", quota_file_name); - - unsigned long num_ips; - ip_bw *ip_buf = NULL; - int query_succeeded = get_all_bandwidth_usage_for_rule_id(id, &num_ips, &ip_buf, 5000); - if(query_succeeded) - { - save_usage_to_file(ip_buf, num_ips, quota_file_path); - free(ip_buf); - } - free(quota_file_path); - free(quota_file_name); -} - -char* get_uci_option(struct uci_context* ctx, char* package_name, char* section_name, char* option_name) -{ - char* option_value = NULL; - struct uci_ptr ptr; - char* lookup_str = dynamic_strcat(5, package_name, ".", section_name, ".", option_name); - int ret_value = uci_lookup_ptr(ctx, &ptr, lookup_str, 1); - if(ret_value == UCI_OK) - { - if( !(ptr.flags & UCI_LOOKUP_COMPLETE)) - { - ret_value = UCI_ERR_NOTFOUND; - } - else - { - struct uci_element *e = (struct uci_element*)ptr.o; - option_value = get_option_value_string(uci_to_option(e)); - } - } - free(lookup_str); - - return option_value; -} - - - - -// this function dynamically allocates memory for -// the option string, but since this program exits -// almost immediately (after printing variable info) -// the massive memory leak we're opening up shouldn't -// cause any problems. This is your reminder/warning -// that this might be an issue if you use this code to -// do anything fancy. -char* get_option_value_string(struct uci_option* uopt) -{ - char* opt_str = NULL; - if(uopt->type == UCI_TYPE_STRING) - { - opt_str = strdup(uopt->v.string); - } - if(uopt->type == UCI_TYPE_LIST) - { - struct uci_element* e; - uci_foreach_element(&uopt->v.list, e) - { - if(opt_str == NULL) - { - opt_str = strdup(e->name); - } - else - { - char* tmp; - tmp = dynamic_strcat(3, opt_str, " ", e->name); - free(opt_str); - opt_str = tmp; - } - } - } - - return opt_str; -} - - diff --git a/package/ctcgfw/gargoyle-firewall-util/src/delete_chain_from_table.c b/package/ctcgfw/gargoyle-firewall-util/src/delete_chain_from_table.c deleted file mode 100644 index b8f5548e19..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/src/delete_chain_from_table.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#define malloc safe_malloc -#define strdup safe_strdup - -void free_split_pieces(char** split_pieces); - -int main(int argc, char **argv) -{ - char *table = argv[1]; - char *delete_chain = argv[2]; - if(argc != 3) - { - printf("USAGE: %s [TABLE] [CHAIN TO DELETE]\n\n", argv[0]); - return 0; - } - - char *command = dynamic_strcat(3, "iptables -t ", table, " -L -n --line-numbers 2>/dev/null"); - unsigned long num_lines = 0; - char** table_dump = get_shell_command_output_lines(command, &num_lines); - free(command); - - - unsigned long line_index; - char* current_chain = NULL; - list* delete_commands = initialize_list(); - - - for(line_index=0; line_index < num_lines; line_index++) - { - char* line = table_dump[line_index]; - unsigned long num_pieces = 0; - char whitespace[] = { '\t', ' ', '\r', '\n' }; - char** line_pieces = split_on_separators(line, whitespace, 4, -1, 0, &num_pieces); - if(strcmp(line_pieces[0], "Chain") == 0) - { - if(current_chain != NULL) { free(current_chain); } - current_chain = strdup(line_pieces[1]); - } - else - { - unsigned long line_num; - int read = sscanf(line_pieces[0], "%ld", &line_num); - - if(read > 0 && current_chain != NULL && num_pieces >1) - { - if(strcmp(line_pieces[1], delete_chain) == 0) - { - char* delete_command = dynamic_strcat(7, "iptables -t ", table, " -D ", current_chain, " ", line_pieces[0], " 2>/dev/null"); - push_list(delete_commands, delete_command); - } - } - } - - //free line_pieces - free_null_terminated_string_array(line_pieces); - } - free_null_terminated_string_array(table_dump); - - /* final two commands to flush chain being deleted and whack it */ - unshift_list(delete_commands, dynamic_strcat(5, "iptables -t ", table, " -F ", delete_chain, " 2>/dev/null")); - unshift_list(delete_commands, dynamic_strcat(5, "iptables -t ", table, " -X ", delete_chain, " 2>/dev/null")); - - /* run delete commands */ - while(delete_commands->length > 0) - { - char *next_command = (char*)pop_list(delete_commands); - char **out = get_shell_command_output_lines(next_command, &num_lines); - free_null_terminated_string_array(out); - } - - return 0; -} - diff --git a/package/ctcgfw/gargoyle-firewall-util/src/make_iptables_rules.c b/package/ctcgfw/gargoyle-firewall-util/src/make_iptables_rules.c deleted file mode 100644 index e85f227886..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/src/make_iptables_rules.c +++ /dev/null @@ -1,1040 +0,0 @@ -/* make_iptables_rules -- A tool to generate firewall rules from options in UCI config files - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#include -#include -#include -#include - -#include - -#include -#include -#define malloc safe_malloc -#define strdup safe_strdup - -/* these are indices don't change! */ -#define MATCH_IP_INDEX 0 -#define MATCH_IP_RANGE_INDEX 1 -#define MATCH_MAC_INDEX 2 - -string_map* get_rule_definition(char* config, char* section); -char* get_option_value_string(struct uci_option* uopt); -int parse_option(char* option_name, char* option_value, string_map* definition); - -char*** parse_ips_and_macs(char* addr_str); -char** parse_ports(char* port_str); -char** parse_marks(char* list_str, unsigned long max_mask); -list* parse_quoted_list(char* list_str, char quote_char, char escape_char, char add_remainder_if_uneven_quotes); - -int truncate_if_starts_with(char* test_str, char* prefix); - -char** compute_rules(string_map *rule_def, char* table, char* chain, int is_ingress, char* target, char* target_options); -int compute_multi_rules(char** def, list* multi_rules, char** single_check, int never_single, char* rule_prefix, char* test_prefix1, char* test_prefix2, int is_negation1, int is_negation2, int mask_byte_index, char* proto, int requires_proto, int quoted_args); - -int main(int argc, char **argv) -{ - int c; - char* package = NULL; - char* section = NULL; - char* table = NULL; - char* chain = NULL; - char* target = NULL; - char* target_options = NULL; - int is_ingress = 0; - int run_commands = 0; - int usage_printed = 0; - while((c = getopt(argc, argv, "P:p:S:s:T:t:C:c:G:g:O:o:IiRrUu")) != -1) //section, page, css includes, javascript includes, title, output interface variables - { - switch(c) - { - case 'P': - case 'p': - package = strdup(optarg); - break; - case 'S': - case 's': - section = strdup(optarg); - break; - case 'T': - case 't': - table = strdup(optarg); - break; - case 'C': - case 'c': - chain = strdup(optarg); - break; - case 'G': - case 'g': - target = strdup(optarg); - break; - case 'O': - case 'o': - target_options = strdup(optarg); - break; - case 'I': - case 'i': - is_ingress = 1; - break; - case 'R': - case 'r': - run_commands = 1; - break; - case 'U': - case 'u': - default: - fprintf(stderr, "USAGE: %s -p [PACKAGE] -s [SECTION] -t [TABLE] -c [CHAIN] -g [TARGET] [OPTIONS]\n -o [TARGET_OPTIONS]\n -i indicates that this rule applies to ingress packets\n -r implies computed commands should be executed instead of just printed\n -u print usage and exit\n\n", argv[0]); - usage_printed = 1; - break; - - } - } - if(package != NULL && section != NULL && table != NULL && chain != NULL && target != NULL) - { - string_map* def = get_rule_definition(package, section); - if(def != NULL) - { - char** rules = compute_rules(def, table, chain, 0, target, target_options); - - int rindex = 0; - for(rindex=0; rules[rindex] != NULL; rindex++) - { - if(run_commands == 0) - { - printf("%s\n", rules[rindex]); - } - else - { - system(rules[rindex]); - } - } - } - else - { - fprintf(stderr, "ERROR: Invalid package / section\n"); - - } - } - else if(!usage_printed) - { - fprintf(stderr, "USAGE: %s -p [PACKAGE] -s [SECTION] -t [TABLE] -c [CHAIN] -g [TARGET] [OPTIONS]\n -o [TARGET_OPTIONS]\n -i indicates that this rule applies to ingress packets\n -r implies computed commands should be executed instead of just printed\n -u print usage and exit\n\n", argv[0]); - - } - - - - return 0; -} - - - - -/* - * Note we've currently maxed out out one whole byte of address space - * in the connmark at this point. If we want to match in - * further dimensions, we will have to be greedy and take - * even more address space - */ -char** compute_rules(string_map *rule_def, char* table, char* chain, int is_ingress, char* target, char* target_options) -{ - list* multi_rules = initialize_list(); - char* single_check = strdup(""); - char* rule_prefix = dynamic_strcat(5, "iptables -t ", table, " -A ", chain, " "); - - target = strdup(target); - to_uppercase(target); - - - /* get timerange vars first */ - char* active_hours = get_map_element(rule_def, "active_hours"); - char* active_weekdays = get_map_element(rule_def, "active_weekdays"); - char* active_weekly_ranges = get_map_element(rule_def, "active_weekly_ranges"); - if(active_weekly_ranges != NULL) - { - char* tmp = dynamic_strcat(3, " -m timerange --weekly_ranges \"", active_weekly_ranges, "\" " ); - dcat_and_free(&single_check, &tmp, 1, 1); - } - else if(active_hours != NULL && active_weekdays != NULL) - { - char* tmp = dynamic_strcat(5, " -m timerange --hours \"", active_hours, "\" --weekdays \"", active_weekdays, "\" " ); - dcat_and_free(&single_check, &tmp, 1, 1); - } - else if(active_hours != NULL) - { - char* tmp = dynamic_strcat(3, " -m timerange --hours \"", active_hours, "\" " ); - dcat_and_free(&single_check, &tmp, 1, 1); - } - else if(active_weekdays != NULL) - { - char* tmp = dynamic_strcat(3, " -m timerange --weekdays \"", active_weekdays, "\" " ); - dcat_and_free(&single_check, &tmp, 1, 1); - } - - - /* - * layer7 && ipp2p can not be negated. To negate them - * set a mark/connmark and negate that - */ - char* layer7_def = get_map_element(rule_def, "layer7"); - if(layer7_def != NULL) - { - char* tmp = dynamic_strcat(2, " -m layer7 --l7proto ", layer7_def ); - dcat_and_free(&single_check, &tmp, 1, 1); - } - char* ipp2p_def = get_map_element(rule_def, "ipp2p"); - if(ipp2p_def != NULL) - { - char* tmp = dynamic_strcat(2, " -m ipp2p --", ipp2p_def ); - dcat_and_free(&single_check, &tmp, 1, 1); - } - char* min_def = get_map_element(rule_def, "min_pkt_size"); - char* max_def = get_map_element(rule_def, "max_pkt_size"); - if(min_def != NULL && max_def != NULL) - { - min_def = min_def == NULL ? "0" : min_def; - max_def = max_def == NULL ? "3000" : max_def; //typical max transmission size is 1500, let's make default max 2x that - char* tmp = dynamic_strcat(5, " -m length --length ", min_def, ":", max_def, " " ); - dcat_and_free(&single_check, &tmp, 1, 1); - } - - - - /* make sure proto is lower case */ - char* proto = get_map_element(rule_def, "proto"); - if(proto == NULL) - { - proto = strdup("both"); - set_map_element(rule_def, "proto", proto); - - } - to_lowercase(proto); - if( safe_strcmp(proto, "udp") != 0 && safe_strcmp(proto, "tcp") != 0 && safe_strcmp(proto, "both") != 0 ) - { - char* tmp; - tmp = set_map_element(rule_def, "proto", strdup("both")); - free(tmp); - proto = (char*)get_map_element(rule_def, "proto"); - } - int include_proto = strcmp(proto, "both") == 0 ? 0 : 1; - - - /* parse multi rules */ - int mask_byte_index = 0; - list* initial_mask_list = initialize_list(); - list* final_mask_list = initialize_list(); - - - - - /* url matches are a bit of a special case, handle them first */ - /* we have to save this mask_byte_index specially, because it must be set separately, so it only gets set if packet is http request */ - int url_mask_byte_index = mask_byte_index; - - char* url_match_vars[] = { "url_contains", "url_regex", "url_exact", "url_domain_contains", "url_domain_regex", "url_domain_exact" }; - char* url_neg_match_vars[] = { "not_url_contains", "not_url_regex", "not_url_exact", "not_url_domain_contains", "not_url_domain_regex", "not_url_domain_exact" }; - char* url_prefixes1[] = { " -m weburl ", " -m weburl ", " -m weburl ", " -m weburl --domain_only ", " -m weburl --domain_only ", " -m weburl --domain_only " }; - char* url_prefixes2[] = { " --contains ", " --contains_regex ", " --matches_exactly ", " --contains ", " --contains_regex ", " --matches_exactly " }; - list* url_lists[6]; - int url_var_index=0; - int url_rule_count=0; - int url_is_negated=0; - - for(url_is_negated=0; url_is_negated < 2 && url_rule_count == 0; url_is_negated++) - { - char** url_vars = url_is_negated ? url_neg_match_vars : url_match_vars; - for(url_var_index=0; url_var_index < 6; url_var_index++) - { - list* url_list = get_map_element(rule_def, url_vars[url_var_index]); - if(url_list != NULL) - { - url_rule_count = url_rule_count + url_list->length; - } - url_lists[url_var_index] = url_list; - } - } - url_is_negated--; - - - proto = url_rule_count > 0 ? "tcp" : proto; - int url_is_multi = url_rule_count <= 1 ? 0 : 1; - for(url_var_index=0; url_var_index < 6; url_var_index++) - { - list* url_list = url_lists[url_var_index]; - if(url_list != NULL) - { - if(url_list->length > 0) - { - unsigned long num_vals; - char** url_def = (char**)get_list_values(url_list, &num_vals); - compute_multi_rules( url_def, multi_rules, &single_check, url_is_multi, rule_prefix, url_prefixes1[url_var_index], url_prefixes2[url_var_index], 0, url_is_negated, mask_byte_index, proto, include_proto, 1 ); - free(url_def); - } - } - } - push_list(initial_mask_list, (void*)&url_is_negated); - push_list(final_mask_list, (void*)&url_is_multi); - mask_byte_index++; - - - /* mark matches */ - char** mark_def = get_map_element(rule_def, "mark"); - int mark_is_negated = mark_def == NULL ? 1 : 0; - mark_def = mark_def == NULL ? get_map_element(rule_def, "not_mark") : mark_def; - mark_is_negated = mark_def == NULL ? 0 : mark_is_negated; - /* we can't do single negation with mark match, so always add seperate multi-match if mark is negated */ - int mark_is_multi = compute_multi_rules(mark_def, multi_rules, &single_check, mark_is_negated, rule_prefix, " -m mark ", " --mark ", mark_is_negated, 0, mask_byte_index, proto, include_proto, 0) == 2; - push_list(initial_mask_list, (void*)&mark_is_negated); - push_list(final_mask_list, (void*)&mark_is_multi); - mask_byte_index++; - - /* connmark matches */ - char** connmark_def = get_map_element(rule_def, "connmark"); - int connmark_is_negated = connmark_def == NULL ? 1 : 0; - connmark_def = connmark_def == NULL ? get_map_element(rule_def, "not_connmark") : connmark_def; - connmark_is_negated = connmark_def == NULL ? 0 : connmark_is_negated; - int connmark_is_multi = compute_multi_rules(connmark_def, multi_rules, &single_check, 0, rule_prefix, " -m connmark ", " --mark ", connmark_is_negated, 0, mask_byte_index, proto, include_proto, 0) == 2; - push_list(initial_mask_list, (void*)&connmark_is_negated); - push_list(final_mask_list, (void*)&connmark_is_multi); - mask_byte_index++; - - - /* - * for ingress source = remote, destination = local - * for egress source = local, destination = remote - * - * addresses are a bit tricky, since we need to handle 3 different kinds of matches: ips, ip ranges and macs - */ - char*** src_def = get_map_element(rule_def, (is_ingress ? "remote_addr" : "local_addr")); - char*** not_src_def = get_map_element(rule_def, (is_ingress ? "not_remote_addr" : "not_local_addr")); - int src_is_negated = src_def == NULL && not_src_def != NULL ? 1 : 0; - src_def = src_is_negated == 1 ? not_src_def : src_def; - - char*** dst_def = get_map_element(rule_def, (is_ingress ? "local_addr" : "remote_addr")); - char*** not_dst_def = get_map_element(rule_def, (is_ingress ? "not_local_addr" : "not_remote_addr")); - int dst_is_negated = dst_def == NULL && not_dst_def != NULL ? 1 : 0; - dst_def = dst_is_negated == 1 ? not_dst_def : dst_def; - - char*** addr_defs[2] = { src_def, dst_def }; - int addr_negated[2] = { src_is_negated, dst_is_negated }; - char* addr_prefix1[2][3] = { { " -s ", " -m iprange ", " -m mac --mac-source " }, { " -d", "-m iprange ", NULL } }; - char* addr_prefix2[2][3] = { {"", " --src-range ", "" }, { "", " --dst-range ", NULL } }; - - int addr_index = 0; - int is_true = 1; - int is_false = 0; - for(addr_index = 0; addr_index < 2; addr_index++) - { - char*** addrs = addr_defs[addr_index]; - if(addrs != NULL) - { - int total_rules = 0; - int test_list_index; - for(test_list_index=0; test_list_index < 3; test_list_index++) - { - char** test_list = addrs[test_list_index]; - if(test_list != NULL && addr_prefix1[addr_index][test_list_index] != NULL) - { - while(test_list[0] != NULL){ test_list++; total_rules++; } - } - } - int is_multi = total_rules > 1 ? 1 : 0; - int is_negated = addr_negated[addr_index]; - //printf("is negated = %d for addr_index = %d\n", is_negated, addr_index); - - for(test_list_index=0; test_list_index < 3; test_list_index++) - { - char** test_list = addrs[test_list_index]; - if(test_list != NULL && addr_prefix1[addr_index][test_list_index] != NULL) - { - if(test_list[0] != NULL) - { - compute_multi_rules(test_list, multi_rules, &single_check, is_multi, rule_prefix, addr_prefix1[addr_index][test_list_index], addr_prefix2[addr_index][test_list_index],(is_negated && (test_list_index != 1)), (is_negated && (test_list_index == 1)), mask_byte_index, proto, include_proto, 0); - } - } - } - - push_list(initial_mask_list, (void*)(addr_negated + addr_index)); - push_list(final_mask_list, (void*)(is_multi == 1 ? &is_true : &is_false) ); - mask_byte_index++; - } - } - - - - char** sport_def = get_map_element(rule_def, (is_ingress ? "remote_port" : "local_port")); - int sport_is_negated = sport_def == NULL ? 1 : 0; - sport_def = sport_def == NULL ? get_map_element(rule_def, (is_ingress ? "not_remote_port" : "not_local_port")) : sport_def; - sport_is_negated = sport_def == NULL ? 0 : sport_is_negated; - int sport_is_multi = compute_multi_rules(sport_def, multi_rules, &single_check, 0, rule_prefix, " --sport ", "", sport_is_negated, 0, mask_byte_index, proto, 1, 0) == 2; - push_list(initial_mask_list, (void*)&sport_is_negated); - push_list(final_mask_list, (void*)&sport_is_multi); - mask_byte_index++; - - - char** dport_def = get_map_element(rule_def, (is_ingress ? "local_port" : "remote_port")); - int dport_is_negated = dport_def == NULL ? 1 : 0; - dport_def = dport_def == NULL ? get_map_element(rule_def, (is_ingress ? "not_local_port" : "not_remote_port")) : dport_def; - dport_is_negated = dport_def == NULL ? 0 : dport_is_negated; - int dport_is_multi = compute_multi_rules(dport_def, multi_rules, &single_check, 0, rule_prefix, " --dport ", "", dport_is_negated, 0, mask_byte_index, proto, 1, 0) == 2; - push_list(initial_mask_list, (void*)&dport_is_negated); - push_list(final_mask_list, (void*)&dport_is_multi); - mask_byte_index++; - - list* all_rules = initialize_list(); - - - - //if no target_options specified, make sure it's an empty string, not null - target_options = (target_options == NULL) ? "" : target_options; - //if target_options is empty and we're rejecting and proto is tcp, set options to --reject-with tcp-reset instead of default - target_options = strlen(target_options) == 0 && (strcmp(proto, "tcp") == 0) && strcmp(target, "REJECT") == 0 ? " --reject-with tcp-reset " : target_options; - if(multi_rules->length > 0) - { - if(strlen(single_check) > 0) - { - char* dummy_multi[] = { single_check, NULL }; - int requires_proto = strcmp(proto, "both") == 0 && sport_def == NULL && dport_def == NULL ? 0 : 1; - compute_multi_rules(dummy_multi, multi_rules, &single_check, 1, rule_prefix, " ", "", 0, 0, mask_byte_index, proto, requires_proto, 0); - mask_byte_index++; - } - - - /* - printf("final mask length = %ld\n", final_mask_list->length); - printf("src is multi = %d\n", src_is_multi); - unsigned long mi; - int* one = shift_list(final_mask_list); - int* two = shift_list(final_mask_list); - printf("one = %d, two = %d\n", *one, *two); - unshift_list(final_mask_list, two); - unshift_list(final_mask_list, one); - */ - - unsigned long initial_url_mark = 0x01000000 * url_is_negated * url_is_multi; - unsigned long initial_main_mark = 0; - unsigned long final_match = 0; - int next_mask_index; - for(next_mask_index = 0; next_mask_index length > 0) - { - next_is_multi = shift_list(final_mask_list); - } - else - { - *next_is_multi = 1; - } - - - unsigned long next_mark_bit = 0x01000000 * (unsigned long)pow(2, next_mask_index) * (*next_is_multi); - final_match = final_match + next_mark_bit; - if(initial_mask_list->length > 0) - { - int* is_negation = (int*)shift_list(initial_mask_list); - if(*is_negation == 1 && next_mask_index != url_mask_byte_index ) - { - //printf("nonzero byte index for main mark = %d\n", next_mask_index); - initial_main_mark = initial_main_mark + next_mark_bit; - } - } - /* else it's last single_check mark which is never initialized to one */ - } - - - if(initial_main_mark > 0) - { - //set main_mark unconditionally - char mark[12]; - sprintf(mark, "0x%lX", initial_main_mark); - push_list(all_rules, dynamic_strcat(4, rule_prefix, " -j CONNMARK --set-mark ", mark, "/0xFF000000" )); - } - if(initial_url_mark > 0) //do url_mark second since because in order to set main mark we use full mask of 0xFF000000 - { - //set proper mark if this is an http request - char mark[12]; - sprintf(mark, "0x%lX", initial_url_mark); - push_list(all_rules, dynamic_strcat(5, rule_prefix, " -p tcp -m weburl --contains http -j CONNMARK --set-mark ", mark, "/", mark)); - } - - //put all rules in place from multi_rules list - while(multi_rules->length > 0) - { - push_list(all_rules, shift_list(multi_rules)); - } - unsigned long tmp_length; - destroy_list(multi_rules, DESTROY_MODE_IGNORE_VALUES, &tmp_length); - - //if final mark matches perfectly with mask of 0xFF000000, jump to (REJECT/ACCEPT) target - char final_match_str[12]; - sprintf(final_match_str, "0x%lX", final_match); - - //if we're rejecting, no target options are specified, and no proto is specified add two rules: one for tcp with tcp-reject, and one for everything else - if(safe_strcmp(target, "REJECT") == 0 && safe_strcmp(target_options, "") == 0 && safe_strcmp(proto, "both")) - { - push_list(all_rules, dynamic_strcat(4, rule_prefix, " -p tcp -m connmark --mark ", final_match_str, "/0xFF000000 -j REJECT --reject-with tcp-reset")); - push_list(all_rules, dynamic_strcat(4, rule_prefix, " -m connmark --mark ", final_match_str, "/0xFF000000 -j REJECT")); - - } - else - { - char* final_proto = strstr(target_options, "tcp-reset") == NULL ? "" : " -p tcp "; - push_list(all_rules, dynamic_strcat(7, rule_prefix, final_proto, " -m connmark --mark ", final_match_str, "/0xFF000000 -j ", target, target_options )); - } - //if final mark does not match (i.e. we didn't reject), unconditionally reset mark to 0x0 with mask of 0xFF000000 - push_list(all_rules, dynamic_strcat(2, rule_prefix, " -j CONNMARK --set-mark 0x0/0xFF000000" )); - } - else - { - if( strcmp(proto, "both") == 0 ) - { - if( dport_def == NULL && sport_def == NULL ) - { - if(safe_strcmp(target, "REJECT") == 0 && safe_strcmp(target_options, "") == 0 ) - { - push_list(all_rules, dynamic_strcat(4, rule_prefix, " -p tcp ", single_check, " -j REJECT --reject-with tcp-reset")); - } - push_list(all_rules, dynamic_strcat(5, rule_prefix, single_check, " -j ",target, target_options )); - } - else - { - if(safe_strcmp(target, "REJECT") == 0 && safe_strcmp(target_options, "") == 0 ) - { - push_list(all_rules, dynamic_strcat(4, rule_prefix, " -p tcp ", single_check, " -j REJECT --reject-with tcp-reset" )); - } - else - { - push_list(all_rules, dynamic_strcat(6, rule_prefix, " -p tcp ", single_check, " -j ", target, target_options )); - } - push_list(all_rules, dynamic_strcat(6, rule_prefix, " -p udp ", single_check, " -j ", target, target_options )); - } - } - else - { - push_list(all_rules, dynamic_strcat(8, rule_prefix, " -p ", proto, " ", single_check, " -j ", target, target_options )); - } - } - - /* handle very special case: if we're white-listing a URL we need to make - * sure other, non-request packets in connection get through too. So, we allow all traffic - * with a destination port of 80 that is NOT an HTTP request. This should allow - * HTTP connections to persist but prevent connections to any websites but those - * specified - */ - if(url_rule_count > 0 && safe_strcmp(target, "ACCEPT") == 0 && is_ingress == 0) - { - push_list(all_rules, dynamic_strcat(2, rule_prefix, " -p tcp -m weburl --contains http -j CONNMARK --set-mark 0xFF000000/0xFF000000" )); - push_list(all_rules, dynamic_strcat(2, rule_prefix, " -p tcp --dport 80 -m connmark ! --mark 0xFF000000/0xFF000000 -j ACCEPT " )); - push_list(all_rules, dynamic_strcat(2, rule_prefix, " -p tcp --dport 443 -m connmark ! --mark 0xFF000000/0xFF000000 -j ACCEPT " )); - push_list(all_rules, dynamic_strcat(2, rule_prefix, " -p tcp -m connmark --mark 0xFF000000/0xFF000000 -j REJECT --reject-with tcp-reset" )); - push_list(all_rules, dynamic_strcat(2, rule_prefix, " -j CONNMARK --set-mark 0x0/0xFF000000" )); - } - - unsigned long num_rules; - char** block_rule_list = (char**) destroy_list( all_rules, DESTROY_MODE_RETURN_VALUES, &num_rules); - - return block_rule_list; -} - - -/* returns 0 if no rules found, 1 if one rule found AND included in single_check, otherwise 2 */ -int compute_multi_rules(char** def, list* multi_rules, char** single_check, int never_single, char* rule_prefix, char* test_prefix1, char* test_prefix2, int is_negation1, int is_negation2, int mask_byte_index, char* proto, int requires_proto, int quoted_args) -{ - int parse_type = 0; - int is_negation = 0; - if(is_negation1 == 1 || is_negation2 == 1) - { - is_negation = 1; - } - if(def != NULL) - { - int num_rules; - for(num_rules=0; def[num_rules] != NULL; num_rules++){} - if(num_rules == 1 && !never_single) - { - parse_type = 1; - char* tmp = dynamic_strcat(7, (is_negation1 ? " ! " : " "), test_prefix1, (is_negation2 ? " ! " : " "), test_prefix2, (quoted_args ? " \"" : " "), def[0], (quoted_args ? "\" " : " ") ); - dcat_and_free(&tmp, single_check, 1, 1 ); - } - else - { - parse_type = 2; - unsigned long mask = 0x01000000 * (unsigned long)pow(2, mask_byte_index); - char mask_str[12]; - sprintf(mask_str, "0x%lX", mask); - char* connmark_part = dynamic_strcat(4, " -j CONNMARK --set-mark ", (is_negation ? "0x0" : mask_str), "/", mask_str); - - - int rule_index =0; - for(rule_index=0; def[rule_index] != NULL; rule_index++) - { - char* common_part = dynamic_strcat(7, test_prefix1, " ", test_prefix2, (quoted_args ? " \"" : " "), def[rule_index], (quoted_args ? "\" " : " "), connmark_part); - if(strcmp(proto, "both") == 0) - { - if(requires_proto) - { - push_list(multi_rules, dynamic_strcat(3, rule_prefix, " -p tcp ", common_part)); - push_list(multi_rules, dynamic_strcat(3, rule_prefix, " -p udp ", common_part)); - } - else - { - push_list(multi_rules, dynamic_strcat(3, rule_prefix, " ", common_part )); - } - } - else - { - push_list(multi_rules, dynamic_strcat(5, rule_prefix, " -p ", proto, " ", common_part)); - } - free(common_part); - } - free(connmark_part); - } - } - return parse_type; -} - - - - - - - -string_map* get_rule_definition(char* package, char* section) -{ - string_map* definition = NULL; - struct uci_context *ctx; - struct uci_package *p = NULL; - ctx = uci_alloc_context(); - if(uci_load(ctx, package, &p) == UCI_OK) - { - struct uci_ptr ptr; - char* lookup_str = dynamic_strcat(3, package, ".", section); - int ret_value = uci_lookup_ptr(ctx, &ptr, lookup_str, 1); - if(ret_value == UCI_OK) - { - struct uci_section *s = ptr.s; - if(s != NULL) - { - struct uci_element *e; - definition = initialize_string_map(1); - - uci_foreach_element(&s->options, e) - { - char* option_name = strdup(e->name); - to_lowercase(option_name); - char* option_value = get_option_value_string(uci_to_option(e)); - parse_option(option_name, option_value, definition); - free(option_name); - free(option_value); - } - } - } - } - uci_free_context(ctx); - - return definition; -} - -int parse_option(char* option_name, char* option_value, string_map* definition) -{ - int valid_option = 0; - if( safe_strcmp(option_name, "proto") == 0 || - safe_strcmp(option_name, "layer7") == 0 || - safe_strcmp(option_name, "ipp2p") == 0 || - safe_strcmp(option_name, "max_pkt_size") == 0 || - safe_strcmp(option_name, "min_pkt_size") ==0 - ) - { - valid_option = 1; - set_map_element(definition, option_name, strdup(option_value)); - } - else if( safe_strcmp(option_name, "active_hours") == 0 || - safe_strcmp(option_name, "active_weekly_ranges") == 0 || - safe_strcmp(option_name, "active_weekdays") == 0 - ) - { - to_lowercase(option_value); - if( safe_strcmp(option_value, "all") != 0 ) - { - valid_option = 1; - set_map_element(definition, option_name, strdup(option_value)); - } - } - else if( safe_strcmp(option_name, "mark") == 0 || - safe_strcmp(option_name, "connmark") == 0 || - safe_strcmp(option_name, "not_mark") == 0 || - safe_strcmp(option_name, "not_connmark") == 0 - ) - { - valid_option = 1; - set_map_element(definition, option_name, parse_marks(option_value, 0xFFFFFFFF)); - } - else if( safe_strcmp(option_name, "remote_addr") == 0 || - safe_strcmp(option_name, "local_addr") == 0 || - safe_strcmp(option_name, "not_remote_addr") == 0 || - safe_strcmp(option_name, "not_local_addr") == 0 - ) - { - char*** parsed_addr = parse_ips_and_macs(option_value); - if(parsed_addr != NULL) - { - valid_option = 1; - if( safe_strcmp(option_name, "not_remote_addr") == 0 || safe_strcmp(option_name, "remote_addr") == 0 ) - { - parsed_addr[MATCH_MAC_INDEX][0] = NULL; //doesn't make sense to match remote MAC address - } - set_map_element(definition, option_name, parsed_addr); - } - } - else if( safe_strcmp(option_name, "remote_port") == 0 || - safe_strcmp(option_name, "local_port") == 0 || - safe_strcmp(option_name, "not_remote_port") == 0 || - safe_strcmp(option_name, "not_local_port") == 0 - ) - { - char** parsed_ports = parse_ports(option_value); - if(parsed_ports != NULL) - { - valid_option = 1; - set_map_element(definition, option_name, parsed_ports); - } - } - else if( truncate_if_starts_with(option_name, "url_contains") || - truncate_if_starts_with(option_name, "url_regex") || - truncate_if_starts_with(option_name, "url_exact") || - truncate_if_starts_with(option_name, "url_domain_contains") || - truncate_if_starts_with(option_name, "url_domain_regex") || - truncate_if_starts_with(option_name, "url_domain_exact") || - truncate_if_starts_with(option_name, "not_url_contains") || - truncate_if_starts_with(option_name, "not_url_regex") || - truncate_if_starts_with(option_name, "not_url_exact") || - truncate_if_starts_with(option_name, "not_url_domain_contains") || - truncate_if_starts_with(option_name, "not_url_domain_regex") || - truncate_if_starts_with(option_name, "not_url_domain_exact") - ) - { - /* - * may be a quoted list of urls to block, so attempt to parse this - * if no quotes found, match on unquoted expresssion - * we don't need to de-escape quotes because when we define rule, - * we call iptables from system, and through the shell, which will de-escape quotes for us - */ - list* parsed_quoted = parse_quoted_list(option_value, '\"', '\\', 0); - list* old_parsed = get_map_element(definition, option_name); - if(old_parsed != NULL) - { - while(parsed_quoted->length > 0) - { - push_list(old_parsed, shift_list(parsed_quoted)); - } - free(parsed_quoted); - parsed_quoted = old_parsed; - } - if(parsed_quoted->length > 0) - { - valid_option = 1; - set_map_element(definition, option_name, parsed_quoted); - } - } - return valid_option; -} - - -// this function dynamically allocates memory for -// the option string, but since this program exits -// almost immediately (after printing variable info) -// the massive memory leak we're opening up shouldn't -// cause any problems. This is your reminder/warning -// that this might be an issue if you use this code to -// do anything fancy. -char* get_option_value_string(struct uci_option* uopt) -{ - char* opt_str = NULL; - if(uopt->type == UCI_TYPE_STRING) - { - opt_str = strdup(uopt->v.string); - } - if(uopt->type == UCI_TYPE_LIST) - { - struct uci_element* e; - uci_foreach_element(&uopt->v.list, e) - { - if(opt_str == NULL) - { - opt_str = strdup(e->name); - } - else - { - char* tmp; - tmp = dynamic_strcat(3, opt_str, " ", e->name); - free(opt_str); - opt_str = tmp; - } - } - } - - return opt_str; -} - - - - -char*** parse_ips_and_macs(char* addr_str) -{ - unsigned long num_pieces; - char** addr_parts = split_on_separators(addr_str, ",", 1, -1, 0, &num_pieces); - list* ip_list = initialize_list(); - list* ip_range_list = initialize_list(); - list* mac_list = initialize_list(); - - int ip_part_index; - for(ip_part_index=0; addr_parts[ip_part_index] != NULL; ip_part_index++) - { - char* next_str = addr_parts[ip_part_index]; - if(strchr(next_str, ':')) - { - trim_flanking_whitespace(next_str); - if(strlen(next_str) == 17) - { - push_list(mac_list, trim_flanking_whitespace(next_str)); - } - } - else if(strchr(next_str, '-') != NULL) - { - char** range_parts = split_on_separators(next_str, "-", 1, 2, 1, &num_pieces); - char* start = trim_flanking_whitespace(range_parts[0]); - char* end = trim_flanking_whitespace(range_parts[1]); - int start_ip[4]; - int end_ip[4]; - int start_valid = sscanf(start, "%d.%d.%d.%d", start_ip, start_ip+1, start_ip+2, start_ip+3); - int end_valid = sscanf(end, "%d.%d.%d.%d", end_ip, end_ip+1, end_ip+2, end_ip+3); - - if(start_valid == 4 && end_valid == 4) - { - //get_ip_range_strs(start_ip, end_ip, "", 4, ip_list); - push_list(ip_range_list, trim_flanking_whitespace(next_str)); - } - - free(start); - free(end); - free(range_parts); - //free(next_str); - } - else - { - int parsed_ip[4]; - int valid = sscanf(next_str, "%d.%d.%d.%d", parsed_ip, parsed_ip+1, parsed_ip+2, parsed_ip+3); - if(valid == 4) - { - push_list(ip_list, trim_flanking_whitespace(next_str)); - } - } - } - free(addr_parts); - - unsigned long num1, num2, num3; - char*** return_value = (char***)malloc(3*sizeof(char**)); - return_value[MATCH_IP_INDEX] = (char**)destroy_list(ip_list, DESTROY_MODE_RETURN_VALUES, &num1); - return_value[MATCH_IP_RANGE_INDEX] = (char**)destroy_list(ip_range_list, DESTROY_MODE_RETURN_VALUES, &num2); - return_value[MATCH_MAC_INDEX] = (char**)destroy_list(mac_list, DESTROY_MODE_RETURN_VALUES, &num3); - - if(num1 + num2 + num3 == 0) - { - free(return_value[0]); - free(return_value[1]); - free(return_value[2]); - free(return_value); - return_value = NULL; - } - return return_value; -} - - - -char** parse_ports(char* port_str) -{ - unsigned long num_pieces; - char** ports = split_on_separators(port_str, ",", 1, -1, 0, &num_pieces); - int port_index = 0; - for(port_index=0; ports[port_index] != NULL; port_index++) - { - char* dash_ptr; - while((dash_ptr=strchr(ports[port_index], '-')) != NULL) - { - dash_ptr[0] = ':'; - } - trim_flanking_whitespace( ports[port_index] ); - } - return ports; -} - - -/* - * parses a list of marks/connmarks - * the max_mask parameter specfies a maximal mask that will be used - * when matching marks/connmarks. If a user-defined mask is specified - * (by defining [mark]/[mask]) this is bitwise-anded with the maximum - * mask to get the final mask. This is especially necessary for - * connmarks, because the mechanism to handle negation when multiple - * test rules are needed uses the last (high) byte of the connmark - * address space, so this HAS to be masked out when matching - * connmarks, using max_mask=0x00FFFFFF - */ -char** parse_marks(char* list_str, unsigned long max_mask) -{ - char** marks = NULL; - if(list_str != NULL) - { - unsigned long num_pieces; - marks = split_on_separators(list_str, ",", 1, -1, 0, &num_pieces); - if(marks[0] == NULL) - { - free(marks); - marks = NULL; - } - else - { - int mark_index; - for(mark_index = 0; marks[mark_index] != NULL; mark_index++) - { - trim_flanking_whitespace(marks[mark_index]); - if(max_mask != 0xFFFFFFFF) - { - - char* m = marks[mark_index]; - char* mask_start; - if( (mask_start = strchr(m, '/')) != NULL ) - { - unsigned long mask = 0xFFFFFFFF; - mask_start++; - sscanf(mask_start, "%lX", &mask); - - mask = mask & max_mask; - - *(mask_start) = '\0'; - char new_mask_str[12]; - sprintf(new_mask_str, "0x%lX", mask); - marks[mark_index] = dynamic_strcat(2, m, new_mask_str); - } - else - { - char new_mask_str[12]; - sprintf(new_mask_str, "0x%lX", max_mask); - marks[mark_index] = dynamic_strcat(3, m, "/", new_mask_str); - } - free(m); - } - } - } - } - return marks; -} - - -/* - * parses list of quoted strings, ignoring escaped quote characters that are not themselves escaped - * Note that we don't de-escape anything here. If necessary that should be done elsewhere. - */ -list* parse_quoted_list(char* list_str, char quote_char, char escape_char, char add_remainder_if_uneven_quotes) -{ - - long num_quotes = 0; - long list_index = 0; - char previous_is_quoted = 0; - for(list_index=0; list_str[list_index] != '\0'; list_index++) - { - num_quotes = num_quotes + ( list_str[list_index] == quote_char && !previous_is_quoted ? 1 : 0); - previous_is_quoted = list_str[list_index] == escape_char && !previous_is_quoted ? 1 : 0; - } - - char** pieces = (char**)malloc( ((long)(num_quotes/2)+2) * sizeof(char*) ); - long piece_index = 0; - long next_start_index=-1; - previous_is_quoted = 0; - for(list_index=0; list_str[list_index] != '\0'; list_index++) - { - if( list_str[list_index] == quote_char && !previous_is_quoted ) - { - if(next_start_index < 0) - { - next_start_index = list_index+1; - } - else - { - long length = list_index-next_start_index; - char* next_piece = (char*)malloc( (1+length)*sizeof(char) ); - memcpy(next_piece, list_str+next_start_index, length); - next_piece[length] = '\0'; - pieces[piece_index] = next_piece; - piece_index++; - next_start_index = -1; - } - } - previous_is_quoted = list_str[list_index] == escape_char && !previous_is_quoted ? 1 : 0; - } - if(add_remainder_if_uneven_quotes && next_start_index >= 0) - { - long length = 1+list_index-next_start_index; - char* next_piece = (char*)malloc( (1+length)*sizeof(char) ); - memcpy(next_piece, list_str+next_start_index, length); - next_piece[length] = '\0'; - pieces[piece_index] = next_piece; - piece_index++; - } - pieces[piece_index] = NULL; - - list* quoted_list = initialize_list(); - if(pieces[0] != NULL) - { - for(piece_index=0; pieces[piece_index] != NULL; piece_index++) - { - push_list(quoted_list, pieces[piece_index]); - //don't free pieces[piece], we're just putting it in list - } - } - else - { - //if no quotes at all, just return list_str - push_list(quoted_list, strdup(list_str)); - } - free(pieces);//but do free array of char* pointers, we don't need it anymore - - return quoted_list; -} - - -int truncate_if_starts_with(char* test_str, char* prefix) -{ - int prefix_length = strlen(prefix); - int test_length = strlen(test_str); - int matches = 0; - if(prefix_length <= test_length) - { - matches = strncmp(test_str, prefix, prefix_length) == 0 ? 1 : 0; - if(matches) - { - test_str[prefix_length] = '\0'; - } - } - return matches; -} diff --git a/package/ctcgfw/gargoyle-firewall-util/src/print_quotas.c b/package/ctcgfw/gargoyle-firewall-util/src/print_quotas.c deleted file mode 100644 index 3aad95eed3..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/src/print_quotas.c +++ /dev/null @@ -1,429 +0,0 @@ -/* print_quotas -- Used to print quota data from iptables rules that use the "bandwidth" module - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009-2010 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#include -#include -#include - -#include -#include -#include -#define malloc safe_malloc -#define strdup safe_strdup - -list* get_all_sections_of_type(struct uci_context *ctx, char* package, char* section_type); -void backup_quota(char* quota_id, char* quota_backup_dir); -char* get_uci_option(struct uci_context* ctx,char* package_name, char* section_name, char* option_name); -char* get_option_value_string(struct uci_option* uopt); - - -int main(void) -{ - struct uci_context *ctx = uci_alloc_context(); - list* quota_sections = get_all_sections_of_type(ctx, "firewall", "quota"); - unlock_bandwidth_semaphore_on_exit(); - - /* for each ip have uint64_t[6], */ - string_map *id_ip_to_bandwidth = initialize_string_map(1); - string_map *id_ip_to_percents = initialize_string_map(1); - string_map *id_ip_to_limits = initialize_string_map(1); - list *id_to_time = initialize_list(); - - while(quota_sections->length > 0) - { - char* next_quota = shift_list(quota_sections); - - - /* base id for quota is the ip associated with it*/ - char *id = get_uci_option(ctx, "firewall", next_quota, "id"); - char* ip = get_uci_option(ctx, "firewall", next_quota, "ip"); - if(ip == NULL) - { - ip = strdup("ALL"); - } - else if(strcmp(ip, "") == 0) - { - free(ip); - ip = strdup("ALL"); - } - if(id == NULL) - { - id = strdup(ip); - } - else if(strcmp(id, "") == 0) - { - free(id); - id = strdup(ip); - } - - - - - - string_map* ip_to_bandwidth = get_string_map_element(id_ip_to_bandwidth, id); - ip_to_bandwidth = ip_to_bandwidth == NULL ? initialize_string_map(1) : ip_to_bandwidth; - set_string_map_element(id_ip_to_bandwidth, id, ip_to_bandwidth); - - string_map* ip_to_percents = get_string_map_element(id_ip_to_percents, id); - ip_to_percents = ip_to_percents == NULL ? initialize_string_map(1) : ip_to_percents; - set_string_map_element(id_ip_to_percents, id, ip_to_percents); - - string_map* ip_to_limits = get_string_map_element(id_ip_to_limits, id); - ip_to_limits = ip_to_limits == NULL ? initialize_string_map(1) : ip_to_limits; - set_string_map_element(id_ip_to_limits, id, ip_to_limits); - - char* offpeak_hours = get_uci_option(ctx, "firewall", next_quota, "offpeak_hours"); - char* offpeak_weekdays = get_uci_option(ctx, "firewall", next_quota, "offpeak_weekdays"); - char* offpeak_weekly_ranges = get_uci_option(ctx, "firewall", next_quota, "offpeak_weekly_ranges"); - char* onpeak_hours = get_uci_option(ctx, "firewall", next_quota, "onpeak_hours"); - char* onpeak_weekdays = get_uci_option(ctx, "firewall", next_quota, "onpeak_weekdays"); - char* onpeak_weekly_ranges = get_uci_option(ctx, "firewall", next_quota, "onpeak_weekly_ranges"); - if(offpeak_hours != NULL || offpeak_weekdays != NULL || offpeak_weekly_ranges != NULL || onpeak_hours != NULL || onpeak_weekdays != NULL || onpeak_weekly_ranges != NULL) - { - unsigned char is_off_peak = (offpeak_hours != NULL || offpeak_weekdays != NULL || offpeak_weekly_ranges != NULL) ? 1 : 0; - char* hours_var = is_off_peak ? offpeak_hours : onpeak_hours; - char* weekdays_var = is_off_peak ? offpeak_weekdays : onpeak_weekdays; - char* weekly_ranges_var = is_off_peak ? offpeak_weekly_ranges : onpeak_weekly_ranges; - char* active_var = is_off_peak ? strdup("except") : strdup("only"); - - if(weekly_ranges_var != NULL) - { - if(hours_var != NULL) { free(hours_var); hours_var=NULL; } - if(weekdays_var != NULL) { free(weekly_ranges_var); weekly_ranges_var=NULL; } - } - hours_var = hours_var == NULL ? strdup("") : hours_var; - weekdays_var = weekdays_var == NULL ? strdup("") : weekdays_var; - weekly_ranges_var = weekly_ranges_var == NULL ? strdup("") : weekly_ranges_var; - push_list(id_to_time, dynamic_strcat(11, "quotaTimes[\"", id, "\"] = [\"", hours_var, "\", \"", weekdays_var, "\", \"", weekly_ranges_var ,"\", \"", active_var, "\"];")); - - free(hours_var); - free(weekdays_var); - free(weekly_ranges_var); - free(active_var); - } - else - { - push_list(id_to_time, dynamic_strcat(3, "quotaTimes[\"", id, "\"] = [\"\", \"\", \"\", \"always\"];")); - } - - char* types[] = { "combined_limit", "ingress_limit", "egress_limit" }; - char* postfixes[] = { "_combined", "_ingress", "_egress" }; - - - int type_index; - for(type_index=0; type_index < 3; type_index++) - { - char* limit = get_uci_option(ctx, "firewall", next_quota, types[type_index]); - if(limit != NULL) - { - char* type_id = dynamic_strcat(2, id, postfixes[type_index]); - ip_bw* ip_buf; - unsigned long num_ips = 0; - int query_succeeded = get_all_bandwidth_usage_for_rule_id(type_id, &num_ips, &ip_buf, 5000); - if(query_succeeded && num_ips > 0) - { - unsigned long ip_index = 0; - for(ip_index = 0; ip_index < num_ips; ip_index++) - { - ip_bw next = ip_buf[ip_index]; - char* next_ip = NULL; - if(next.ip == 0) - { - next_ip = strdup(ip); - } - else - { - struct in_addr addr; - addr.s_addr = next.ip; - next_ip = strdup(inet_ntoa(addr)); - } - - - uint64_t *bw_list = get_string_map_element(ip_to_bandwidth,next_ip); - if(bw_list == NULL) - { - bw_list = (uint64_t*)malloc(sizeof(uint64_t)*6); - bw_list[0] = 0; - bw_list[1] = 0; - bw_list[2] = 0; - bw_list[3] = 0; - bw_list[4] = 0; - bw_list[5] = 0; - set_string_map_element(ip_to_bandwidth, next_ip, bw_list); - } - bw_list[type_index] = 1; - bw_list[type_index+3] = next.bw; - - char bw_str[50]; - sprintf(bw_str, "%lld", next.bw); - double bw_percent; - double bw_limit; - uint64_t bw_limit_64; - sscanf(bw_str, "%lf", &bw_percent); - sscanf(limit, "%lf", &bw_limit); - sscanf(limit, "%lld", &bw_limit_64); - if(bw_limit > 0) - { - bw_percent = (bw_percent*100.0)/bw_limit; - bw_percent = bw_percent > 100.0 ? 100.0 : bw_percent; - } - else - { - bw_percent = 100.0; - } - - double* percent_list = get_string_map_element(ip_to_percents, next_ip); - if(percent_list == NULL) - { - percent_list = (double*)malloc(sizeof(double)*3); - percent_list[0] = -1; - percent_list[1] = -1; - percent_list[2] = -1; - set_string_map_element(ip_to_percents, next_ip, percent_list); - } - percent_list[type_index] = bw_percent; - - uint64_t* limit_list = get_string_map_element(ip_to_limits, next_ip); - if(limit_list == NULL) - { - limit_list = (uint64_t*)malloc(sizeof(uint64_t)*3); - limit_list[0] = -1; - limit_list[1] = -1; - limit_list[2] = -1; - set_string_map_element(ip_to_limits, next_ip, limit_list); - } - limit_list[type_index] = bw_limit_64; - } - } - free(type_id); - free(limit); - - } - } - free(id); - free(ip); - free(next_quota); - } - - - unsigned long num_ids; - char** id_list = (char**)get_string_map_keys(id_ip_to_bandwidth, &num_ids); - printf("var quotaIdList = [ "); - char print_comma[10] = ""; - unsigned long id_index; - for(id_index=0; id_index < num_ids; id_index++) - { - printf("%s\"%s\"", print_comma, id_list[id_index]); - sprintf(print_comma, ", "); - } - printf(" ];\n"); - - printf("var quotaIpLists = [];\n"); - for(id_index=0; id_index < num_ids; id_index++) - { - string_map* ip_to_bandwidth = get_string_map_element(id_ip_to_bandwidth, id_list[id_index]); - if(ip_to_bandwidth != NULL) - { - unsigned long num_ips = 0; - unsigned long ip_index = 0; - char** ip_list = (char**)get_string_map_keys(ip_to_bandwidth, &num_ips); - printf("quotaIpLists[\"%s\"] = [ ", id_list[id_index]); - sprintf(print_comma, ""); - for(ip_index=0; ip_index < num_ips; ip_index++) - { - printf("%s\"%s\"", print_comma, ip_list[ip_index]); - sprintf(print_comma, ", "); - } - printf("];\n"); - } - } - - printf("var quotaTimes = new Array();\n"); - printf("var quotaUsed = new Array();\n"); - printf("var quotaLimits = new Array();\n"); - printf("var quotaPercents = new Array();\n"); - - char* next_time = shift_list(id_to_time); - while(next_time != NULL) - { - printf("%s\n", next_time); - next_time = shift_list(id_to_time); - } - - for(id_index=0; id_index < num_ids; id_index++) - { - char* next_id = id_list[id_index]; - string_map* ip_to_bandwidth = get_string_map_element(id_ip_to_bandwidth, next_id); - string_map* ip_to_percents = get_string_map_element(id_ip_to_percents, next_id); - string_map* ip_to_limits = get_string_map_element(id_ip_to_limits, next_id); - - printf("quotaUsed[ \"%s\" ] = [];\n", next_id); - printf("quotaPercents[ \"%s\" ] = [];\n", next_id); - printf("quotaLimits[ \"%s\" ] = [];\n", next_id); - - - if(ip_to_bandwidth != NULL) - { - unsigned long num_ips; - unsigned long ip_index = 0; - char** ip_list = (char**)get_string_map_keys(ip_to_bandwidth, &num_ips); - for(ip_index=0; ip_index < num_ips; ip_index++) - { - char* next_ip = ip_list[ip_index]; - uint64_t* used = (uint64_t*)get_string_map_element(ip_to_bandwidth, next_ip); - double* percents = (double*)get_string_map_element(ip_to_percents, next_ip); - uint64_t* limits = (uint64_t*)get_string_map_element(ip_to_limits, next_ip); - - if(used != NULL) - { - int type_index; - printf("quotaUsed[ \"%s\" ][ \"%s\" ] = [ ", next_id, next_ip); - sprintf(print_comma, ""); - for(type_index=0; type_index < 3; type_index++) - { - if(!used[type_index]) - { - printf("%s-1", print_comma); - } - else - { - printf("%s%lld", print_comma, (long long int)used[type_index+3]); - } - sprintf(print_comma, ", "); - } - printf(" ];\n"); - - printf("quotaPercents[ \"%s\" ][ \"%s\" ] = [ ", next_id, next_ip); - sprintf(print_comma, ""); - for(type_index=0; type_index < 3; type_index++) - { - printf("%s%6.3lf", print_comma, percents[type_index]); - sprintf(print_comma, ", "); - } - printf(" ];\n"); - - printf("quotaLimits[ \"%s\" ][ \"%s\" ] = [ ", next_id, next_ip); - sprintf(print_comma, ""); - for(type_index=0; type_index < 3; type_index++) - { - printf("%s%lld", print_comma,limits[type_index]); - sprintf(print_comma, ", "); - } - printf(" ];\n"); - } - } - } - } - - - unsigned long num; - destroy_list(quota_sections, DESTROY_MODE_FREE_VALUES, &num); - uci_free_context(ctx); - - return 0; -} - -list* get_all_sections_of_type(struct uci_context *ctx, char* package, char* section_type) -{ - - struct uci_package *p = NULL; - struct uci_element *e = NULL; - - list* sections_of_type = initialize_list(); - if(uci_load(ctx, package, &p) == UCI_OK) - { - uci_foreach_element( &p->sections, e) - { - struct uci_section *section = uci_to_section(e); - if(safe_strcmp(section->type, section_type) == 0) - { - push_list(sections_of_type, strdup(section->e.name)); - } - } - } - return sections_of_type; -} - - -char* get_uci_option(struct uci_context* ctx, char* package_name, char* section_name, char* option_name) -{ - char* option_value = NULL; - struct uci_ptr ptr; - char* lookup_str = dynamic_strcat(5, package_name, ".", section_name, ".", option_name); - int ret_value = uci_lookup_ptr(ctx, &ptr, lookup_str, 1); - if(ret_value == UCI_OK) - { - if( !(ptr.flags & UCI_LOOKUP_COMPLETE)) - { - ret_value = UCI_ERR_NOTFOUND; - } - else - { - struct uci_element *e = (struct uci_element*)ptr.o; - option_value = get_option_value_string(uci_to_option(e)); - } - } - free(lookup_str); - - return option_value; -} - - - - -// this function dynamically allocates memory for -// the option string, but since this program exits -// almost immediately (after printing variable info) -// the massive memory leak we're opening up shouldn't -// cause any problems. This is your reminder/warning -// that this might be an issue if you use this code to -// do anything fancy. -char* get_option_value_string(struct uci_option* uopt) -{ - char* opt_str = NULL; - if(uopt->type == UCI_TYPE_STRING) - { - opt_str = strdup(uopt->v.string); - } - if(uopt->type == UCI_TYPE_LIST) - { - struct uci_element* e; - uci_foreach_element(&uopt->v.list, e) - { - if(opt_str == NULL) - { - opt_str = strdup(e->name); - } - else - { - char* tmp; - tmp = dynamic_strcat(3, opt_str, " ", e->name); - free(opt_str); - opt_str = tmp; - } - } - } - - return opt_str; -} - - diff --git a/package/ctcgfw/gargoyle-firewall-util/src/restore_quotas.c b/package/ctcgfw/gargoyle-firewall-util/src/restore_quotas.c deleted file mode 100644 index 84a5c3a51f..0000000000 --- a/package/ctcgfw/gargoyle-firewall-util/src/restore_quotas.c +++ /dev/null @@ -1,1105 +0,0 @@ -/* restore_quotas -- Used to initialize and restore bandwidth quotas based on UCI config files - * and any previously saved quota data in /usr/data/quotas - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009-2010 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include - - -#include -#include -#include - -#include -#include -#include -#define malloc safe_malloc -#define strdup safe_strdup - -#define INGRESS_INDEX 0 -#define EGRESS_INDEX 1 -#define COMBINED_INDEX 2 - - - -void restore_backup_for_id(char* id, char* quota_backup_dir, unsigned char is_individual_other, list* defined_ip_groups); -uint32_t ip_to_host_int(char* ip_str); -uint32_t* ip_range_to_host_ints(char* ip_str); -list* filter_group_from_list(list** orig_ip_list, char* ip_group_str); - -void delete_chain_from_table(char* table, char* delete_chain); -void run_shell_command(char* command, int free_command_str); -void free_split_pieces(char** split_pieces); - -list* get_all_sections_of_type(struct uci_context *ctx, char* package, char* section_type); -char* get_uci_option(struct uci_context* ctx,char* package_name, char* section_name, char* option_name); -char* get_option_value_string(struct uci_option* uopt); - -int main(int argc, char** argv) -{ - - char* wan_if = NULL; - char* local_subnet = NULL; - char* death_mark = NULL; - char* death_mask = NULL; - char* crontab_line = NULL; - int ret; - - unsigned char full_qos_active = 0; - - char c; - while((ret = getopt(argc, argv, "W:w:s:S:d:D:m:M:c:C:qQ")) != -1) //section, page, css includes, javascript includes, title, output interface variables - { - c = ret; - switch(c) - { - case 'W': - case 'w': - wan_if = strdup(optarg); - break; - case 'S': - case 's': - local_subnet = strdup(optarg); - break; - case 'D': - case 'd': - death_mark = strdup(optarg); - break; - case 'M': - case 'm': - death_mask = strdup(optarg); - break; - case 'C': - case 'c': - crontab_line = strdup(optarg); - break; - case 'Q': - case 'q': - full_qos_active = 1; - break; - } - } - - /* even if parameters are wrong, whack old rules */ - char quota_table[] = "mangle"; - char crontab_dir[] = "/etc/crontabs/"; - char crontab_file_path[] = "/etc/crontabs/root"; - delete_chain_from_table(quota_table, "egress_quotas"); - delete_chain_from_table(quota_table, "ingress_quotas"); - delete_chain_from_table(quota_table, "combined_quotas"); - delete_chain_from_table(quota_table, "forward_quotas"); - delete_chain_from_table("nat", "quota_redirects"); - - if(wan_if == NULL) - { - fprintf(stderr, "ERRROR: No wan interface specified\n"); - return 0; - } - if(local_subnet == NULL) - { - fprintf(stderr, "ERRROR: No local subnet specified\n"); - return 0; - } - if(death_mark == NULL) - { - fprintf(stderr, "ERRROR: No death mark specified\n"); - return 0; - } - if(death_mask == NULL) - { - fprintf(stderr, "ERRROR: No death mask specified\n"); - return 0; - } - - - - struct uci_context *ctx = uci_alloc_context(); - struct uci_ptr ptr; - - list* quota_sections = get_all_sections_of_type(ctx, "firewall", "quota"); - if(quota_sections->length > 0) - { - /* load defined base ids */ - string_map* defined_base_ids = initialize_string_map(0); - string_map* upload_qos_marks = initialize_string_map(0); - string_map* download_qos_marks = initialize_string_map(0); - - long_map* up_speeds = initialize_long_map(); - long_map* down_speeds = initialize_long_map(); - list* quota_section_buf = initialize_list(); - while(quota_sections->length > 0) - { - char* next_quota = shift_list(quota_sections); - char* base_id = get_uci_option(ctx, "firewall", next_quota, "id"); - char* exceeded_up_speed_str = get_uci_option(ctx, "firewall", next_quota, "exceeded_up_speed"); - char* exceeded_down_speed_str = get_uci_option(ctx, "firewall", next_quota, "exceeded_down_speed"); - - - if(base_id != NULL) - { - //D, for dummy place holder - char* oldval = set_string_map_element(defined_base_ids, base_id, strdup("D") ); - if(oldval != NULL) { free(oldval); } - } - push_list(quota_section_buf, next_quota); - - if(exceeded_up_speed_str != NULL && exceeded_down_speed_str != NULL) - { - long up; - long down; - if(sscanf(exceeded_up_speed_str, "%ld", &up) > 0 && sscanf(exceeded_down_speed_str, "%ld", &down) > 0 ) - { - if(up > 0 && down > 0) - { - char* oldval = set_long_map_element(up_speeds, up, strdup(exceeded_up_speed_str) ); - if(oldval != NULL) { free(oldval); } - oldval = set_long_map_element(down_speeds, down, strdup(exceeded_down_speed_str) ); - if(oldval != NULL) { free(oldval); } - - } - } - } - free(base_id); - free(exceeded_up_speed_str); - free(exceeded_down_speed_str); - } - unsigned long num_destroyed; - destroy_list(quota_sections, DESTROY_MODE_FREE_VALUES, &num_destroyed); - quota_sections = quota_section_buf; - - - - /* initialize qos mark maps */ - unsigned long mark_band = 2; - int upload_shift = 0; - int download_shift = 8; - while(up_speeds->num_elements > 0) - { - unsigned long mark = mark_band << upload_shift; - char mark_str[10]; - unsigned long smallest_speed; - char* next_up_speed = remove_smallest_long_map_element(up_speeds, &smallest_speed); - sprintf(mark_str, "%ld", mark); - set_string_map_element(upload_qos_marks, next_up_speed, strdup(mark_str)); - free(next_up_speed); - mark_band++; - } - mark_band = 2; - while(down_speeds->num_elements > 0) - { - unsigned long mark = mark_band << download_shift; - char mark_str[10]; - unsigned long smallest_speed; - char* next_down_speed = remove_smallest_long_map_element(down_speeds, &smallest_speed); - sprintf(mark_str, "%ld", mark); - set_string_map_element(download_qos_marks, next_down_speed, strdup(mark_str)); - free(next_down_speed); - mark_band++; - } - - - - - /* initialize chains */ - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -N forward_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -N egress_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -N ingress_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -N combined_quotas 2>/dev/null"), 1); - - run_shell_command("iptables -t nat -N quota_redirects 2>/dev/null", 0); - run_shell_command("iptables -t nat -A quota_redirects -j CONNMARK --set-mark 0x0/0xFF000000 2>/dev/null", 0); - run_shell_command("iptables -t nat -I zone_lan_prerouting -j quota_redirects 2>/dev/null", 0); - - char* no_death_mark_test = dynamic_strcat(3, " -m connmark --mark 0x0/", death_mask, " "); - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -I INPUT 1 -i ", wan_if, no_death_mark_test, " -j ingress_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -I INPUT 2 -i ", wan_if, no_death_mark_test, " -j combined_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -I OUTPUT 1 -o ", wan_if, no_death_mark_test, " -j egress_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -I OUTPUT 2 -o ", wan_if, no_death_mark_test, " -j combined_quotas 2>/dev/null"), 1); - - - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -I FORWARD -j forward_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -A forward_quotas -o ", wan_if, no_death_mark_test, " -j egress_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -A forward_quotas -i ", wan_if, no_death_mark_test, " -j ingress_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -A forward_quotas -i ", wan_if, no_death_mark_test, " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -A forward_quotas -o ", wan_if, no_death_mark_test, " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -A forward_quotas -m connmark --mark 0x0F000000/0x0F000000 -j combined_quotas 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -A forward_quotas -j CONNMARK --set-mark 0x0/0x0F000000 2>/dev/null"), 1); - free(no_death_mark_test); - - run_shell_command(dynamic_strcat(5, "iptables -t ", quota_table, " -A egress_quotas -j CONNMARK --set-mark 0x0/", death_mask, " 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(5, "iptables -t ", quota_table, " -A ingress_quotas -j CONNMARK --set-mark 0x0/", death_mask, " 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(5, "iptables -t ", quota_table, " -A combined_quotas -j CONNMARK --set-mark 0x0/", death_mask, " 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -A egress_quotas -j CONNMARK --set-mark 0x0/0xFF000000 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -A ingress_quotas -j CONNMARK --set-mark 0x0/0xFF000000 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3, "iptables -t ", quota_table, " -A combined_quotas -j CONNMARK --set-mark 0x0/0xFF000000 2>/dev/null"), 1); - - /* add rules */ - char* set_death_mark = dynamic_strcat(5, " -j CONNMARK --set-mark ", death_mark, "/", death_mask, " "); - list* other_quota_section_names = initialize_list(); - list* defined_ip_groups = initialize_list(); - - unlock_bandwidth_semaphore_on_exit(); - while(quota_sections->length > 0 || other_quota_section_names->length > 0) - { - char* next_quota = NULL; - int process_other_quota = 0; - if(quota_sections->length > 0) - { - next_quota = shift_list(quota_sections); - } - else - { - process_other_quota = 1; - next_quota = shift_list(other_quota_section_names); - } - - char* quota_enabled_var = get_uci_option(ctx, "firewall", next_quota, "enabled"); - int enabled = 1; - if(quota_enabled_var != NULL) - { - if(strcmp(quota_enabled_var, "0") == 0) - { - enabled = 0; - } - } - free(quota_enabled_var); - - if(enabled) - { - char* ip = get_uci_option(ctx, "firewall", next_quota, "ip"); - char* exceeded_up_speed_str = NULL; - char* exceeded_down_speed_str = NULL; - if(!full_qos_active) /* without defined up/down speeds we always set hard cutoff, which is what we want when full qos is active */ - { - exceeded_up_speed_str = get_uci_option(ctx, "firewall", next_quota, "exceeded_up_speed"); - exceeded_down_speed_str = get_uci_option(ctx, "firewall", next_quota, "exceeded_down_speed"); - } - if(exceeded_up_speed_str == NULL) { exceeded_up_speed_str = strdup(" "); } - if(exceeded_down_speed_str == NULL) { exceeded_down_speed_str = strdup(" "); } - - - if(ip == NULL) { ip = strdup("ALL"); } - if(strlen(ip) == 0) { ip = strdup("ALL"); } - - /* remove spaces in ip range definitions */ - while(strstr(ip, " -") != NULL) - { - char* tmp_ip = ip; - ip = dynamic_replace(ip, " -", "-"); - free(tmp_ip); - } - while(strstr(ip, "- ") != NULL) - { - char* tmp_ip = ip; - ip = dynamic_replace(ip, "- ", "-"); - free(tmp_ip); - } - - - if( (strcmp(ip, "ALL_OTHERS_COMBINED") == 0 || strcmp(ip, "ALL_OTHERS_INDIVIDUAL") == 0) && (!process_other_quota) ) - { - push_list(other_quota_section_names, strdup(next_quota)); - } - else - { - unsigned char is_individual_other = strcmp(ip, "ALL_OTHERS_INDIVIDUAL") == 0 ? 1 : 0; - if( strcmp(ip, "ALL_OTHERS_COMBINED") != 0 && strcmp(ip, "ALL_OTHERS_INDIVIDUAL") != 0 && strcmp(ip, "ALL") != 0 ) - { - /* this is an explicitly defined ip or ip range, so save it for later, to deal with individual other overlap problem */ - push_list(defined_ip_groups, strdup(ip)); - } - - /* compute proper base id for rule, adding variable to uci if necessary */ - char* quota_base_id = get_uci_option(ctx, "firewall", next_quota, "id"); - if(quota_base_id == NULL) - { - char id_breaks[] = { ',', ' ', '\t'}; - unsigned long num_pieces; - char** split_ip = split_on_separators(ip, id_breaks, 3, -1, 0, &num_pieces); - char* first_ip = dynamic_replace(split_ip[0], "/", "_"); - free_null_terminated_string_array(split_ip); - - quota_base_id = strdup(first_ip); - unsigned long next_postfix_count = 0; - while( get_string_map_element(defined_base_ids, quota_base_id) != NULL) - { - char next_postfix[20]; - if(next_postfix_count > 25) - { - sprintf(next_postfix, "_%c", ('A' + next_postfix_count)); - } - else - { - sprintf(next_postfix, "_Z%ld", (next_postfix_count - 25)); - } - free(quota_base_id); - quota_base_id = dynamic_strcat(2, first_ip, next_postfix); - } - free(first_ip); - - /* D for dummy place holder */ - set_string_map_element(defined_base_ids, quota_base_id, strdup("D")); - - /* add id we've decided on to UCI */ - char* var_set = dynamic_strcat(4, "firewall.", next_quota, ".id=", quota_base_id); - if (uci_lookup_ptr(ctx, &ptr, var_set, true) == UCI_OK) - { - uci_set(ctx, &ptr); - } - } - - char* ignore_backup = get_uci_option(ctx, "firewall", next_quota, "ignore_backup_at_next_restore"); - int do_restore = 1; - if(ignore_backup != NULL) - { - do_restore = strcmp(ignore_backup, "1") == 0 ? 0 : 1; - if(!do_restore) - { - //remove variable from uci - char* var_name = dynamic_strcat(3, "firewall.", next_quota, ".ignore_backup_at_next_restore"); - if (uci_lookup_ptr(ctx, &ptr, var_name, true) == UCI_OK) - { - uci_delete(ctx, &ptr); - } - free(var_name); - } - } - free(ignore_backup); - - - - char* reset_interval = get_uci_option(ctx, "firewall", next_quota, "reset_interval"); - char* reset = strdup(""); - if(reset_interval != NULL) - { - char* reset_time = get_uci_option(ctx, "firewall", next_quota, "reset_time"); - - char* interval_option = strdup(" --reset_interval "); - reset = dcat_and_free(&reset, &interval_option, 1, 1); - reset = dcat_and_free(&reset, &reset_interval, 1, 1); - if(reset_time != NULL) - { - char* reset_option = strdup(" --reset_time "); - reset = dcat_and_free(&reset, &reset_option, 1, 1); - reset = dcat_and_free(&reset, &reset_time, 1, 1); - } - } - - char* time_match_str = strdup(""); - - char* offpeak_hours = get_uci_option(ctx, "firewall", next_quota, "offpeak_hours"); - char* offpeak_weekdays = get_uci_option(ctx, "firewall", next_quota, "offpeak_weekdays"); - char* offpeak_weekly_ranges = get_uci_option(ctx, "firewall", next_quota, "offpeak_weekly_ranges"); - - char* onpeak_hours = get_uci_option(ctx, "firewall", next_quota, "onpeak_hours"); - char* onpeak_weekdays = get_uci_option(ctx, "firewall", next_quota, "onpeak_weekdays"); - char* onpeak_weekly_ranges = get_uci_option(ctx, "firewall", next_quota, "onpeak_weekly_ranges"); - - - if(offpeak_hours != NULL || offpeak_weekdays != NULL || offpeak_weekly_ranges != NULL || onpeak_hours != NULL || onpeak_weekdays != NULL || onpeak_weekly_ranges != NULL) - { - unsigned char is_off_peak = (offpeak_hours != NULL || offpeak_weekdays != NULL || offpeak_weekly_ranges != NULL) ? 1 : 0; - char* hours_var = is_off_peak ? offpeak_hours : onpeak_hours; - char* weekdays_var = is_off_peak ? offpeak_weekdays : onpeak_weekdays; - char* weekly_ranges_var = is_off_peak ? offpeak_weekly_ranges : onpeak_weekly_ranges; - - char *timerange_match = is_off_peak ? strdup(" -m timerange ! ") : strdup(" -m timerange "); - char *hour_match = strdup(" --hours \""); - char *weekday_match = strdup(" --weekdays \""); - char *weekly_match = strdup(" --weekly_ranges \""); - char *quote_end = strdup("\" "); - - time_match_str = dcat_and_free(&time_match_str, &timerange_match, 1,1); - if(hours_var != NULL && weekly_ranges_var == NULL) - { - time_match_str = dcat_and_free(&time_match_str, &hour_match, 1, 1); - time_match_str = dcat_and_free(&time_match_str, &hours_var, 1, 1); - time_match_str = dcat_and_free(&time_match_str, "e_end, 1, 0); - } - if(weekdays_var != NULL && weekly_ranges_var == NULL) - { - time_match_str = dcat_and_free(&time_match_str, &weekday_match, 1, 1); - time_match_str = dcat_and_free(&time_match_str, &weekdays_var, 1, 1); - time_match_str = dcat_and_free(&time_match_str, "e_end, 1, 0); - } - if(weekly_ranges_var != NULL) - { - time_match_str = dcat_and_free(&time_match_str, &weekly_match, 1, 1); - time_match_str = dcat_and_free(&time_match_str, &weekly_ranges_var, 1, 1); - time_match_str = dcat_and_free(&time_match_str, "e_end, 1, 0); - } - free(quote_end); - } - - char* types[] = { "ingress_limit", "egress_limit", "combined_limit" }; - char* postfixes[] = { "_ingress", "_egress", "_combined" }; - char* chains[] = { "ingress_quotas", "egress_quotas", "combined_quotas" }; - - int type_index; - for(type_index=0; type_index < 3; type_index++) - { - char** ip_egress_tests = NULL; - char* applies_to = strdup("combined"); - char* subnet_definition = strdup(""); - - char* limit = get_uci_option(ctx, "firewall", next_quota, types[type_index]); - - char* type_id = dynamic_strcat(2, quota_base_id, postfixes[type_index] ); - - char* up_qos_mark = get_string_map_element(upload_qos_marks, exceeded_up_speed_str); - char* down_qos_mark = get_string_map_element(download_qos_marks, exceeded_down_speed_str); - if(full_qos_active) - { - up_qos_mark = get_uci_option(ctx, "firewall", next_quota, "exceeded_up_class_mark"); - down_qos_mark = get_uci_option(ctx, "firewall", next_quota, "exceeded_down_class_mark"); - } - - /* - * need to do ip test even if limit is null, because ALL_OTHERS quotas should not apply when any of the three types of explicit limit is defined - * and we therefore need to use this test to set mark indicating an explicit quota has been checked - */ - char* ip_test = strdup(""); - if( strcmp(ip, "ALL_OTHERS_COMBINED") != 0 && strcmp(ip, "ALL_OTHERS_INDIVIDUAL") != 0 && strcmp(ip, "ALL") != 0 ) - { - - char* src_test = strstr(ip, "-") == NULL ? dynamic_strcat(3, " --src ", ip, " ") : dynamic_strcat(3, " -m iprange --src-range ", ip, " "); - char* dst_test = strstr(ip, "-") == NULL ? dynamic_strcat(3, " --dst ", ip, " ") : dynamic_strcat(3, " -m iprange --dst-range ", ip, " "); - - if(strstr(ip, ",") != NULL || strstr(ip, " ") != NULL || strstr(ip, "\t") != NULL ) - { - char ip_breaks[] = { ',', ' ', '\t' }; - unsigned long num_ips = 0; - char** ip_list = split_on_separators(ip, ip_breaks, 3, -1, 0, &num_ips); - unsigned long ip_index; - for(ip_index=0; ip_index < num_ips; ip_index++) - { - char *next_ip = ip_list[ip_index]; - char* egress_test = strstr(next_ip, "-") == NULL ? dynamic_strcat(3, " --src ", next_ip, " ") : dynamic_strcat(3, " -m iprange --src-range ", next_ip, " "); - char* ingress_test = strstr(next_ip, "-") == NULL ? dynamic_strcat(3, " --dst ", next_ip, " ") : dynamic_strcat(3, " -m iprange --dst-range ", next_ip, " "); - - if(strcmp(types[type_index], "egress_limit") == 0) - { - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -A ", chains[type_index], egress_test, " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - } - else if(strcmp(types[type_index], "ingress_limit") == 0) - { - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -A ", chains[type_index], ingress_test, " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - } - else if(strcmp(types[type_index], "combined_limit") == 0) - { - run_shell_command(dynamic_strcat(8, "iptables -t ", quota_table, " -A ", chains[type_index], " -i ", wan_if, ingress_test, " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(8, "iptables -t ", quota_table, " -A ", chains[type_index], " -o ", wan_if, egress_test, " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - } - ip_list[ip_index] = egress_test; - free(next_ip); - free(ingress_test); - } - ip_egress_tests = ip_list; - char* rule_end = strdup(" -m connmark --mark 0x0F000000/0x0F000000 "); - ip_test = dcat_and_free(&ip_test, &rule_end, 1, 1); - } - else if(strcmp(types[type_index], "egress_limit") == 0) - { - ip_test=dcat_and_free(&ip_test, &src_test, 1, 0); - } - else if(strcmp(types[type_index], "ingress_limit") == 0) - { - ip_test=dcat_and_free(&ip_test, &dst_test, 1, 0); - } - else if(strcmp(types[type_index], "combined_limit") == 0) - { - run_shell_command(dynamic_strcat(8, "iptables -t ", quota_table, " -A ", chains[type_index], " -i ", wan_if, dst_test, " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(8, "iptables -t ", quota_table, " -A ", chains[type_index], " -o ", wan_if, src_test, " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - char* rule_end = strdup(" -m connmark --mark 0x0F000000/0x0F000000 "); - ip_test = dcat_and_free(&ip_test, &rule_end, 1, 1); - } - run_shell_command(dynamic_strcat(6, "iptables -t ", quota_table, " -A ", chains[type_index], ip_test, " -j CONNMARK --set-mark 0xF0000000/0xF0000000 2>/dev/null"), 1); - free(dst_test); - free(src_test); - } - else if( strcmp(ip, "ALL_OTHERS_COMBINED") == 0 || strcmp(ip, "ALL_OTHERS_INDIVIDUAL") == 0 ) - { - char* rule_end = strdup(" -m connmark --mark 0x0/0xF0000000 "); - ip_test=dcat_and_free(&ip_test, &rule_end, 1, 1); - if(strcmp(ip, "ALL_OTHERS_INDIVIDUAL") == 0) - { - free(applies_to); - if(strcmp(types[type_index], "egress_limit") == 0) - { - char* subnet_test = dynamic_strcat(3, " -s ", local_subnet, " "); - ip_test = dcat_and_free(&subnet_test, &ip_test, 1, 1); - applies_to = strdup("individual_src"); - } - else if(strcmp(types[type_index], "ingress_limit") == 0) - { - char* subnet_test = dynamic_strcat(3, " -d ", local_subnet, " "); - ip_test = dcat_and_free(&subnet_test, &ip_test, 1, 1); - applies_to = strdup("individual_dst"); - } - else if(strcmp(types[type_index], "combined_limit") == 0) - { - applies_to = strdup("individual_local"); - } - - char *subnet_option = strdup(" --subnet "); - subnet_definition = dcat_and_free(&subnet_definition, &subnet_option, 1, 1); - subnet_definition = dcat_and_free(&subnet_definition, &local_subnet, 1, 0); - } - } - - - - if(up_qos_mark != NULL && down_qos_mark != NULL) - { - char* set_egress_mark = dynamic_strcat(2, " -j MARK --set-mark ", up_qos_mark); - char* set_ingress_mark = dynamic_strcat(2, " -j MARK --set-mark ", down_qos_mark); - if(type_index == EGRESS_INDEX || type_index == INGRESS_INDEX) - { - int other_type_index= type_index == EGRESS_INDEX ? INGRESS_INDEX : EGRESS_INDEX; - char* other_limit = get_uci_option(ctx, "firewall", next_quota, types[other_type_index]); - if(other_limit != NULL) - { - char* other_type_id = dynamic_strcat(2, quota_base_id, postfixes[other_type_index] ); - if(type_index == EGRESS_INDEX) - { - run_shell_command(dynamic_strcat(10, "iptables -t ", quota_table, " -A ", chains[type_index], ip_test, time_match_str, " -m bandwidth --id \"", other_type_id, "\" --bcheck_with_src_dst_swap ", set_egress_mark), 1); - } - else - { - run_shell_command(dynamic_strcat(10, "iptables -t ", quota_table, " -A ", chains[type_index], ip_test, time_match_str, " -m bandwidth --id \"", other_type_id, "\" --bcheck_with_src_dst_swap ", set_ingress_mark), 1); - } - free(other_type_id); - } - free(other_limit); - } - free(set_egress_mark); - free(set_ingress_mark); - } - - if(limit != NULL) - { - if(up_qos_mark != NULL && down_qos_mark != NULL) - { - char* set_egress_mark = dynamic_strcat(2, " -j MARK --set-mark ", up_qos_mark); - char* set_ingress_mark = dynamic_strcat(2, " -j MARK --set-mark ", down_qos_mark); - if(strcmp(types[type_index], "egress_limit") == 0) - { - run_shell_command(dynamic_strcat(15, "iptables -t ", quota_table, " -A ", chains[type_index], ip_test, time_match_str, " -m bandwidth --id \"", type_id, "\" --type ", applies_to, subnet_definition, " --greater_than ", limit, reset, set_egress_mark), 1); - } - else if(strcmp(types[type_index], "ingress_limit") == 0) - { - run_shell_command(dynamic_strcat(15, "iptables -t ", quota_table, " -A ", chains[type_index], ip_test, time_match_str, " -m bandwidth --id \"", type_id, "\" --type ", applies_to, subnet_definition, " --greater_than ", limit, reset, set_ingress_mark), 1); - } - else //combined - { - run_shell_command(dynamic_strcat(14, "iptables -t ", quota_table, " -A ", chains[type_index], ip_test, time_match_str, " -m bandwidth --id \"", type_id, "\" --type ", applies_to, subnet_definition, " --greater_than ", limit, reset), 1); - run_shell_command(dynamic_strcat(13, "iptables -t ", quota_table, " -A ", chains[type_index], " -o ", wan_if, " ", ip_test, time_match_str, " -m bandwidth --id \"", type_id, "\" --bcheck ", set_egress_mark), 1); //egress - run_shell_command(dynamic_strcat(13, "iptables -t ", quota_table, " -A ", chains[type_index], " -i ", wan_if, " ", ip_test, time_match_str, " -m bandwidth --id \"", type_id, "\" --bcheck_with_src_dst_swap ", set_ingress_mark), 1); //ingress - } - free(set_egress_mark); - free(set_ingress_mark); - } - else - { - //insert quota block rule - run_shell_command(dynamic_strcat(15, "iptables -t ", quota_table, " -A ", chains[type_index], ip_test, time_match_str, " -m bandwidth --id \"", type_id, "\" --type ", applies_to, subnet_definition, " --greater_than ", limit, reset, set_death_mark), 1); - - - //insert redirect rule - if(strcmp(ip, "ALL") == 0 || strcmp(ip, "ALL_OTHERS_INDIVIDUAL") == 0) - { - char* check_str = (strcmp(types[type_index], "ingress_limit") == 0) ? strdup(" --bcheck_with_src_dst_swap ") : strdup(" --bcheck "); - run_shell_command(dynamic_strcat(7, "iptables -t nat -A quota_redirects -p tcp ", time_match_str, " -m multiport --destination-port 80,443 -m bandwidth ", check_str, " --id \"", type_id, "\" -j REDIRECT "), 1); - free(check_str); - } - else if(strcmp(ip, "ALL_OTHERS_COMBINED") == 0) - { - run_shell_command(dynamic_strcat(5, "iptables -t nat -A quota_redirects -p tcp ", time_match_str, " -m connmark --mark 0x0/0xF0000000 -m multiport --destination-port 80,443 -m bandwidth --bcheck --id \"", type_id, "\" -j REDIRECT "), 1); - } - else - { - if(ip_egress_tests != NULL) - { - unsigned long egress_test_index; - for(egress_test_index=0; ip_egress_tests[egress_test_index] != NULL; egress_test_index++ ) - { - run_shell_command(dynamic_strcat(3, "iptables -t nat -A quota_redirects ", ip_egress_tests[egress_test_index], " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - } - } - else - { - run_shell_command(dynamic_strcat(4, "iptables -t nat -A quota_redirects ", ( strstr(ip, "-") == NULL ? " --src " : " -m iprange --src-range "), ip, " -j CONNMARK --set-mark 0x0F000000/0x0F000000 2>/dev/null"), 1); - } - run_shell_command(dynamic_strcat(5, "iptables -t nat -A quota_redirects -p tcp ", time_match_str, " -m connmark --mark 0x0F000000/0x0F000000 -m multiport --destination-port 80,443 -m bandwidth --bcheck --id \"", type_id, "\" -j REDIRECT "), 1); - run_shell_command("iptables -t nat -A quota_redirects -m connmark --mark 0x0F000000/0x0F000000 -j CONNMARK --set-mark 0xF0000000/0xF0000000 2>/dev/null", 0); - run_shell_command("iptables -t nat -A quota_redirects -j CONNMARK --set-mark 0x0/0x0F000000 2>/dev/null", 0); - } - } - - - //restore from backup - if(do_restore) - { - restore_backup_for_id(type_id, "/usr/data/quotas", is_individual_other, defined_ip_groups); - } - free(limit); - - } - if(strstr(ip_test, "connmark") != NULL) - { - run_shell_command(dynamic_strcat(5, "iptables -t ", quota_table, " -A ", chains[type_index], " -j CONNMARK --set-mark 0x0/0x0F000000 2>/dev/null"), 1); - } - - - free(ip_test); - free(applies_to); - free(subnet_definition); - free(type_id); - if(full_qos_active) - { - free(up_qos_mark); - free(down_qos_mark); - } - if(ip_egress_tests != NULL) - { - free_null_terminated_string_array(ip_egress_tests); - } - } - free(time_match_str); - free(quota_base_id); - } - free(ip); - free(exceeded_up_speed_str); - free(exceeded_down_speed_str); - } - free(next_quota); - - } - - run_shell_command("iptables -t nat -A quota_redirects -j CONNMARK --set-mark 0x0/0xFF000000 2>/dev/null", 0); - run_shell_command(dynamic_strcat(3,"iptables -t ", quota_table, " -A egress_quotas -j CONNMARK --set-mark 0x0/0xFF000000 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3,"iptables -t ", quota_table, " -A ingress_quotas -j CONNMARK --set-mark 0x0/0xFF000000 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(3,"iptables -t ", quota_table, " -A combined_quotas -j CONNMARK --set-mark 0x0/0xFF000000 2>/dev/null"), 1); - run_shell_command(dynamic_strcat(5,"iptables -t filter -I FORWARD -m connmark --mark ", death_mark, "/", death_mask, " -j REJECT 2>/dev/null"), 1); - - //make sure crontab is up to date - if(crontab_line != NULL) - { - FILE* crontab_file = fopen(crontab_file_path,"r"); - int cron_line_found = 0; - if(crontab_file == NULL) - { - run_shell_command(dynamic_strcat(2, "mkdir -p ", crontab_dir), 1); - } - else - { - unsigned long read_length; - char* all_cron_data = (char*)read_entire_file(crontab_file, 2048, &read_length); - fclose(crontab_file); - - unsigned long num_lines; - char linebreaks[] = { '\n', '\r' }; - char** cron_lines = split_on_separators(all_cron_data, linebreaks, 2, -1, 0, &num_lines); - int line_index = 0; - for(line_index=0; line_index < num_lines && (!cron_line_found); line_index++) - { - if(strcmp(cron_lines[line_index], crontab_line) == 0) - { - cron_line_found = 1; - } - } - free_null_terminated_string_array(cron_lines); - } - if(!cron_line_found) - { - crontab_file = fopen(crontab_file_path, "a"); - fprintf(crontab_file, "%s\n", crontab_line); - fclose(crontab_file); - } - } - } - else - { - //remove crontab line if it exists - FILE* crontab_file = fopen(crontab_file_path,"r"); - if(crontab_file != NULL) - { - unsigned long cron_line_found = 0; - unsigned long read_length; - unsigned long num_lines; - char linebreaks[] = { '\n', '\r' }; - char* all_cron_data = (char*)read_entire_file(crontab_file, 2048, &read_length); - fclose(crontab_file); - char** cron_lines = split_on_separators(all_cron_data, linebreaks, 2, -1, 0, &num_lines); - int line_index = 0; - for(line_index=0; line_index < num_lines && (!cron_line_found); line_index++) - { - if(strcmp(cron_lines[line_index], crontab_line) == 0) - { - cron_line_found = 1; - } - } - if(cron_line_found) - { - crontab_file = fopen(crontab_file_path, "w"); - for(line_index=0; line_index < num_lines; line_index++) - { - if(strcmp(cron_lines[line_index], crontab_line) != 0) - { - fprintf(crontab_file, "%s\n", cron_lines[line_index]); - } - } - fclose(crontab_file); - } - free_null_terminated_string_array(cron_lines); - } - } - - /* commit changes to uci, to remove ignore_backup_at_next_restore variables permanently */ - if (uci_lookup_ptr(ctx, &ptr, "firewall", true) == UCI_OK) - { - uci_commit(ctx, &ptr.p, false); - } - uci_free_context(ctx); - - return 0; -} - -void restore_backup_for_id(char* id, char* quota_backup_dir, unsigned char is_individual_other, list* defined_ip_groups) -{ - char* quota_file_path = dynamic_strcat(3, quota_backup_dir, "/quota_", id); - unsigned long num_ips = 0; - time_t last_backup = 0; - ip_bw* loaded_backup_data = load_usage_from_file(quota_file_path, &num_ips, &last_backup); - if(loaded_backup_data != NULL) - { - //printf("restoring quota... id=%s, is_individual_other=%d, num_defined_ip_groups=%d\n", id, is_individual_other, defined_ip_groups->length); - if(is_individual_other) - { - //filter out any ips in the "other" data, that have now been assigned quotas of their own. - list* ip_bw_list = initialize_list(); - int ip_index; - for(ip_index=0; ip_index < num_ips; ip_index++) - { - ip_bw* ptr = loaded_backup_data + ip_index; - push_list(ip_bw_list, ptr); - } - - unsigned long num_groups = 0; - char** group_strs = (char**)get_list_values(defined_ip_groups, &num_groups); - unsigned long group_index; - - for(group_index = 0; group_index < num_groups; group_index++) - { - filter_group_from_list(&ip_bw_list, group_strs[group_index]); - } - - - //rebuild the backup data array from the filtered list - if(num_ips != ip_bw_list->length) - { - num_ips = ip_bw_list->length; - ip_bw* adj_backup = (ip_bw*)malloc( (1+ip_bw_list->length)*sizeof(ip_bw) ); - while(ip_bw_list->length > 0) - { - ip_bw* next = pop_list(ip_bw_list); - adj_backup[ ip_bw_list->length ] = *next; - } - free(loaded_backup_data); - loaded_backup_data = adj_backup; - } - - destroy_list(ip_bw_list, DESTROY_MODE_IGNORE_VALUES, &num_groups); - free(group_strs); //don't want to destroy values, they're still contained in list, so just destroy container array - } - set_bandwidth_usage_for_rule_id(id, 1, num_ips, last_backup, loaded_backup_data, 5000); - } - free(quota_file_path); -} - -list* filter_group_from_list(list** orig_ip_bw_list, char* ip_group_str) -{ - char* dyn_group_str = strdup(ip_group_str); - - /* remove spaces in ip range definitions */ - while(strstr(dyn_group_str, " -") != NULL) - { - char* tmp_group_str = dyn_group_str; - dyn_group_str = dynamic_replace(dyn_group_str, " -", "-"); - free(tmp_group_str); - } - while(strstr(dyn_group_str, "- ") != NULL) - { - char* tmp_group_str = dyn_group_str; - dyn_group_str = dynamic_replace(dyn_group_str, "- ", "-"); - free(tmp_group_str); - } - while(strstr(dyn_group_str, " -") != NULL) - { - char* tmp_group_str = dyn_group_str; - dyn_group_str = dynamic_replace(dyn_group_str, " /", "/"); - free(tmp_group_str); - } - while(strstr(dyn_group_str, "- ") != NULL) - { - char* tmp_group_str = dyn_group_str; - dyn_group_str = dynamic_replace(dyn_group_str, "/ ", "/"); - free(tmp_group_str); - } - - char group_breaks[]= ",\t "; - unsigned long num_groups = 0; - char** split_group = split_on_separators(dyn_group_str, group_breaks, 3, -1, 0, &num_groups); - unsigned long group_index; - - for(group_index = 0; group_index < num_groups; group_index++) - { - uint32_t* range = ip_range_to_host_ints( split_group[group_index] ); - list* new_ip_bw_list = initialize_list(); - while((*orig_ip_bw_list)->length > 0) - { - ip_bw* next_ip_bw = shift_list(*orig_ip_bw_list); - uint32_t test_ip = ntohl(next_ip_bw->ip); - if(test_ip >= range[0] && test_ip <= range[1]) - { - //overlap found! filter the ip by not adding it back! - } - else - { - push_list(new_ip_bw_list, next_ip_bw); - } - } - free(range); - unsigned long num_destroyed; - destroy_list(*orig_ip_bw_list, DESTROY_MODE_IGNORE_VALUES, &num_destroyed); - *orig_ip_bw_list = new_ip_bw_list; - } - free_null_terminated_string_array(split_group); - free(dyn_group_str); - - return *orig_ip_bw_list; - -} - -uint32_t* ip_range_to_host_ints(char* ip_str) -{ - uint32_t* ret_val = (uint32_t*)malloc(2*sizeof(uint32_t)); - uint32_t start = 0; - uint32_t end = 0; - - - unsigned long num_pieces = 0; - char ip_breaks[] = "/-"; - char** split_ip = split_on_separators(ip_str, ip_breaks, 2, -1, 0, &num_pieces); - start = ip_to_host_int(split_ip[0]); - if(strstr(ip_str, "/") != NULL) - { - uint32_t mask = -1; - if(strstr(split_ip[1], ".") != NULL) - { - mask = ip_to_host_int(split_ip[1]); - } - else - { - uint32_t mask_size; - sscanf(split_ip[1], "%d", &mask_size); - mask = mask << (32-mask_size); - } - start = start & mask; - end = start | ( ~mask ); - } - else if(strstr(ip_str, "-") != NULL) - { - end = ip_to_host_int(split_ip[1]); - } - else - { - end = start; - } - free_null_terminated_string_array(split_ip); - - ret_val[0] = start; - ret_val[1] = end; - return ret_val; -} - - -uint32_t ip_to_host_int(char* ip_str) -{ - struct in_addr inp; - inet_aton(ip_str, &inp); - return (uint32_t)ntohl(inp.s_addr); -} - - -void delete_chain_from_table(char* table, char* delete_chain) -{ - char *command = dynamic_strcat(3, "iptables -t ", table, " -L -n --line-numbers 2>/dev/null"); - unsigned long num_lines = 0; - char** table_dump = get_shell_command_output_lines(command, &num_lines ); - free(command); - - unsigned long line_index; - char* current_chain = NULL; - list* delete_commands = initialize_list(); - - - for(line_index=0; line_index < num_lines; line_index++) - { - char* line = table_dump[line_index]; - unsigned long num_pieces = 0; - char whitespace[] = { '\t', ' ', '\r', '\n' }; - char** line_pieces = split_on_separators(line, whitespace, 4, -1, 0, &num_pieces); - if(strcmp(line_pieces[0], "Chain") == 0) - { - if(current_chain != NULL) { free(current_chain); } - current_chain = strdup(line_pieces[1]); - } - else - { - unsigned long line_num; - int read = sscanf(line_pieces[0], "%ld", &line_num); - - if(read > 0 && current_chain != NULL && num_pieces >1) - { - if(strcmp(line_pieces[1], delete_chain) == 0) - { - char* delete_command = dynamic_strcat(7, "iptables -t ", table, " -D ", current_chain, " ", line_pieces[0], " 2>/dev/null"); - push_list(delete_commands, delete_command); - } - } - } - - //free line_pieces - free_null_terminated_string_array(line_pieces); - } - free_null_terminated_string_array(table_dump); - - /* final two commands to flush chain being deleted and whack it */ - unshift_list(delete_commands, dynamic_strcat(5, "iptables -t ", table, " -F ", delete_chain, " 2>/dev/null")); - unshift_list(delete_commands, dynamic_strcat(5, "iptables -t ", table, " -X ", delete_chain, " 2>/dev/null")); - - /* run delete commands */ - while(delete_commands->length > 0) - { - char *next_command = (char*)pop_list(delete_commands); - run_shell_command(next_command, 1); - } - -} - -void run_shell_command(char* command, int free_command_str) -{ - //printf("%s\n", command); - system(command); - if(free_command_str) - { - free(command); - } -} - -list* get_all_sections_of_type(struct uci_context *ctx, char* package, char* section_type) -{ - - struct uci_package *p = NULL; - struct uci_element *e = NULL; - - list* sections_of_type = initialize_list(); - if(uci_load(ctx, package, &p) == UCI_OK) - { - uci_foreach_element( &p->sections, e) - { - struct uci_section *section = uci_to_section(e); - if(safe_strcmp(section->type, section_type) == 0) - { - push_list(sections_of_type, strdup(section->e.name)); - } - } - } - return sections_of_type; -} - - -char* get_uci_option(struct uci_context* ctx, char* package_name, char* section_name, char* option_name) -{ - char* option_value = NULL; - struct uci_ptr ptr; - char* lookup_str = dynamic_strcat(5, package_name, ".", section_name, ".", option_name); - int ret_value = uci_lookup_ptr(ctx, &ptr, lookup_str, 1); - if(ret_value == UCI_OK) - { - if( !(ptr.flags & UCI_LOOKUP_COMPLETE)) - { - ret_value = UCI_ERR_NOTFOUND; - } - else - { - struct uci_element *e = (struct uci_element*)ptr.o; - option_value = get_option_value_string(uci_to_option(e)); - } - } - free(lookup_str); - - return option_value; -} - - - - -// this function dynamically allocates memory for -// the option string, but since this program exits -// almost immediately (after printing variable info) -// the massive memory leak we're opening up shouldn't -// cause any problems. This is your reminder/warning -// that this might be an issue if you use this code to -// do anything fancy. -char* get_option_value_string(struct uci_option* uopt) -{ - char* opt_str = NULL; - if(uopt->type == UCI_TYPE_STRING) - { - opt_str = strdup(uopt->v.string); - } - if(uopt->type == UCI_TYPE_LIST) - { - struct uci_element* e; - uci_foreach_element(&uopt->v.list, e) - { - if(opt_str == NULL) - { - opt_str = strdup(e->name); - } - else - { - char* tmp; - tmp = dynamic_strcat(3, opt_str, " ", e->name); - free(opt_str); - opt_str = tmp; - } - } - } - - return opt_str; -} - - diff --git a/package/ctcgfw/libericstools/Makefile b/package/ctcgfw/libericstools/Makefile deleted file mode 100644 index 191db48e62..0000000000 --- a/package/ctcgfw/libericstools/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# -# Copyright (C) 2006 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# -# $Id: Makefile 9907 2007-12-25 01:59:55Z nbd $ - -include $(TOPDIR)/rules.mk - -PKG_NAME:=libericstools -PKG_VERSION:=$(GARGOYLE_VERSION) -ifeq ($(GARGOYLE_VERSION),) - PKG_VERSION:=1.0.0 -endif -PKG_RELEASE:=1 - -PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) - -include $(INCLUDE_DIR)/package.mk - -define Package/libericstools - SECTION:=libs - CATEGORY:=Libraries - TITLE:=Erics Tools - URL:=http://www.gargoyle-router.com - MAINTAINER:=Eric Bishop -endef - - -define Package/libericstools/description - A bunch of routines/utilities written by Eric Bishop, - a library primarily used in Gargoyle Web Interface for OpenWrt -endef - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) - $(CP) ./src/* $(PKG_BUILD_DIR) -endef - - -define Build/Configure -endef - -define Build/InstallDev - mkdir -p $(STAGING_DIR)/usr/include/ - $(CP) $(PKG_BUILD_DIR)/*.h $(STAGING_DIR)/usr/include/ - - mkdir -p $(STAGING_DIR)/usr/lib - $(CP) $(PKG_BUILD_DIR)/*.so* $(STAGING_DIR)/usr/lib/ - -endef - -define Package/libericstools/install - $(INSTALL_DIR) $(1)/usr/lib - $(CP) $(PKG_BUILD_DIR)/*.so* $(1)/usr/lib/ -endef - -$(eval $(call BuildPackage,libericstools)) diff --git a/package/ctcgfw/libericstools/src/Makefile b/package/ctcgfw/libericstools/src/Makefile deleted file mode 100644 index 78d86662fc..0000000000 --- a/package/ctcgfw/libericstools/src/Makefile +++ /dev/null @@ -1,92 +0,0 @@ -all: erics_tools -VERSION=1 - - -ifeq ($(CC),) - CC=gcc -endif - -ifeq ($(LD),) - LD=ld -endif - -ifeq ($(AR),) - AR=ar -endif - -ifeq ($(RANLIB),) - RANLIB=ranlib -endif - - -CFLAGS:=$(CFLAGS) -Os -WARNING_FLAGS=-Wall -Wstrict-prototypes -pedantic -MINIMAL_WARNING_FLAGS=-Wall -Wstrict-prototypes - -OS=$(shell uname) -ifeq ($(OS),Darwin) - LINK=$(LD) - SHLIB_EXT=dylib - SHLIB_FLAGS=-dylib - SHLIB_FILE=libericstools.$(SHLIB_EXT).$(VERSION) - CFLAGS:=$(CFLAGS) -arch i386 -else - LINK=$(CC) - SHLIB_EXT=so - SHLIB_FILE=libericstools.$(SHLIB_EXT).$(VERSION) - SHLIB_FLAGS=-shared -Wl,-soname,$(SHLIB_FILE) -endif - - - - -test_list_and_queue: test_list_and_queue.c libericstools.a - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -test_list_and_queue.o: test_list_and_queue.c - $(CC) $(CFLAGS) $(MINIMAL_WARNING_FLAGS) -o $@ -c $^ - -test_string: test_string.o libericstools.a - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -test_string.o: test_string.c - $(CC) $(CFLAGS) $(MINIMAL_WARNING_FLAGS) -c $^ -o $@ - - -test_map: test_map.o libericstools.a - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -test_map.o: test_map.c - $(CC) $(CFLAGS) $(MINIMAL_WARNING_FLAGS) -c $^ -o $@ - - - - -all: erics_tools - -erics_tools: libericstools.$(SHLIB_EXT) libericstools.a - - -libericstools.a: list_static.o priority_queue_static.o tree_map_static.o string_util_static.o file_util_static.o safe_malloc_static.o - if [ -e $@ ] ; then rm $@ ; fi - $(AR) rc $@ $^ - $(RANLIB) $@ - - -libericstools.$(SHLIB_EXT) : list_dyn.o priority_queue_dyn.o tree_map_dyn.o string_util_dyn.o file_util_dyn.o safe_malloc_dyn.o - if [ -e libericstools.$(SHLIB_EXT) ] ; then rm libericstools.$(SHLIB_EXT)* ; fi - $(LINK) $(LDFLAGS) $(SHLIB_FLAGS) -o $(SHLIB_FILE) $^ -lc - ln -s $(SHLIB_FILE) libericstools.$(SHLIB_EXT) - - -%_dyn.o: %.c - $(CC) $(CFLAGS) -fPIC $(WARNING_FLAGS) -o $@ -c $^ - -%_static.o: %.c - $(CC) $(CFLAGS) $(WARNING_FLAGS) -o $@ -c $^ - - - -clean: - rm -rf *.a *.o .*sw* *~ test_map test_string test_list_and_queue - if [ "$(SHLIB_EXT)" != "" ] ; then rm -rf *.$(SHLIB_EXT)* ; fi -install: - cp *.h /usr/include - cp *.$(SHLIB_EXT)* /usr/lib diff --git a/package/ctcgfw/libericstools/src/erics_tools.h b/package/ctcgfw/libericstools/src/erics_tools.h deleted file mode 100644 index 2ca8c5e07b..0000000000 --- a/package/ctcgfw/libericstools/src/erics_tools.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright © 2008 by Eric Bishop - * - * This work 'as-is' we provide. - * No warranty, express or implied. - * We've done our best, - * to debug and test. - * Liability for damages denied. - * - * Permission is granted hereby, - * to copy, share, and modify. - * Use as is fit, - * free or for profit. - * On this notice these rights rely. - * - * - * - * Note that unlike other portions of Gargoyle this code - * does not fall under the GPL, but the rather whimsical - * 'Poetic License' above. - * - * Basically, this library contains a bunch of utilities - * that I find useful. I'm sure other libraries exist - * that are just as good or better, but I like these tools - * because I personally wrote them, so I know their quirks. - * (i.e. I know where the bodies are buried). I want to - * make sure that I can re-use these utilities for whatever - * code I may want to write in the future be it - * proprietary or open-source, so I've put them under - * a very, very permissive license. - * - * If you find this code useful, use it. If not, don't. - * I really don't care. - * - */ - -#ifndef ERICS_TOOLS_H -#define ERICS_TOOLS_H - - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifndef stricmp - #define stricmp strcasecmp -#endif - - - -/* tree_map structs / prototypes */ -typedef struct long_tree_map_node -{ - unsigned long key; - void* value; - - signed char balance; - struct long_tree_map_node* left; - struct long_tree_map_node* right; -} long_map_node; - -typedef struct -{ - long_map_node* root; - unsigned long num_elements; - -}long_map; - -typedef struct -{ - long_map lm; - unsigned char store_keys; - unsigned long num_elements; - -}string_map; - - - -/* long map functions */ -extern long_map* initialize_long_map(void); -extern void* get_long_map_element(long_map* map, unsigned long key); -void* get_smallest_long_map_element(long_map* map, unsigned long* smallest_key); -void* get_largest_long_map_element(long_map* map, unsigned long* largest_key); -void* remove_smallest_long_map_element(long_map* map, unsigned long* smallest_key); -void* remove_largest_long_map_element(long_map* map, unsigned long* largest_key); -extern void* set_long_map_element(long_map* map, unsigned long key, void* value); -extern void* remove_long_map_element(long_map* map, unsigned long key); -extern unsigned long* get_sorted_long_map_keys(long_map* map, unsigned long* num_keys_returned); -extern void** get_sorted_long_map_values(long_map* map, unsigned long* num_values_returned); -extern void** destroy_long_map(long_map* map, int destruction_type, unsigned long* num_destroyed); -extern void apply_to_every_long_map_value(long_map* map, void (*apply_func)(unsigned long key, void* value)); - - -/* string map functions */ -extern string_map* initialize_string_map(unsigned char store_keys); -extern void* get_string_map_element(string_map* map, const char* key); -extern void* set_string_map_element(string_map* map, const char* key, void* value); -extern void* remove_string_map_element(string_map* map, const char* key); -extern char** get_string_map_keys(string_map* map, unsigned long* num_keys_returned); -extern void** get_string_map_values(string_map* map, unsigned long* num_values_returned); -extern void** destroy_string_map(string_map* map, int destruction_type, unsigned long* num_destroyed); -extern void apply_to_every_string_map_value(string_map* map, void (*apply_func)(char* key, void* value)); -/* - * three different ways to deal with values when data structure is destroyed - */ -#define DESTROY_MODE_RETURN_VALUES 20 -#define DESTROY_MODE_FREE_VALUES 21 -#define DESTROY_MODE_IGNORE_VALUES 22 - - -/* - * for convenience & backwards compatibility alias _string_map_ functions to - * _map_ functions since string map is used more often than long map - */ -#define initialize_map initialize_string_map -#define set_map_element set_string_map_element -#define get_map_element get_string_map_element -#define remove_map_element remove_string_map_element -#define get_map_keys get_string_map_keys -#define get_map_values get_string_map_values -#define destroy_map destroy_string_map - - - -/* list structs / prototypes */ - -typedef struct list_node_struct -{ - struct list_node_struct* next; - struct list_node_struct* previous; - void* value; -} list_node; - -typedef struct list_struct -{ - long length; - list_node* head; - list_node* tail; - -}list; - -extern list* initialize_list(void); /* O(1) */ - - - -extern void* shift_list(list* l); /* O(1) */ -extern void unshift_list(list* l, void* value); /* O(1) */ -extern void* pop_list(list* l); /* O(1) */ -extern void push_list(list*l, void* value); /* O(1) */ - - -extern void** destroy_list(list* l, int destruction_type, unsigned long* num_destroyed); /* O(n) */ -extern void* list_element_at(list* l, unsigned long index); /* O(n) */ -extern void** get_list_values(list* l, unsigned long* num_values_returned); /* O(n) */ - -/* The idea behind the remove_internal_node function and - * the other functions below that perform list operations on - * list_node pointers instead of values is as follows: - * - * It is O(n) to remove arbitrary node from list. BUT, if - * we have a pointer to that node already it is O(1). So, - * provide functions to manipulate list with list_node pointers - * instead of values & a function to remove an internal node - * given a pointer to that node. This means we can have - * access to internal nodes & use another - * data structure to store internal nodes and delete in O(1) - */ -extern void remove_internal_list_node(list*l, list_node* internal); /* O(1) */ - -extern list_node* create_list_node(void* value); /* O(1) */ -extern void* free_list_node(list_node* delete_node); /* O(1) */ - -extern list_node* shift_list_node(list* l); /* O(1) */ -extern void unshift_list_node(list* l, list_node* new_node); /* O(1) */ -extern list_node* pop_list_node(list* l); /* O(1) */ -extern void push_list_node(list*l, list_node* new_node); /* O(1) */ - - - - - - -/* priority_queue structs / prototypes */ - -typedef struct priority_queue_node_struct -{ - unsigned long priority; - char* id; - void* value; -} priority_queue_node; - - -typedef struct priority_queue_struct -{ - long_map* priorities; - string_map* ids; - priority_queue_node* first; - long length; -} priority_queue; - -extern priority_queue* initialize_priority_queue(void); -extern priority_queue_node* create_priority_node(unsigned long priority, char* id, void* value); -extern void* free_priority_queue_node(priority_queue_node* pn); -extern void push_priority_queue(priority_queue* pq, unsigned long priority, char* id, void * value); -extern void* shift_priority_queue(priority_queue* pq, unsigned long* priority, char** id); -extern void* peek_priority_queue(priority_queue* pq, unsigned long* priority, char** id, int dynamic_alloc_id); -extern void* get_priority_queue_element_with_id(priority_queue* pq, char* id, long* priority); -extern void* remove_priority_queue_element_with_id(priority_queue* pq, char* id, long* priority); -extern void push_priority_queue_node(priority_queue* pq, priority_queue_node* pn); -extern priority_queue_node* shift_priority_queue_node(priority_queue* pq); -extern priority_queue_node* get_priority_queue_node_with_id(priority_queue* pq, char* id); -extern priority_queue_node* remove_priority_queue_node_with_id(priority_queue* pq, char* id); -extern void set_priority_for_id_in_priority_queue(priority_queue* pq, char* id, unsigned long priority); -extern priority_queue_node* peek_priority_queue_node(priority_queue* pq); -extern void** destroy_priority_queue(priority_queue* pq, int destroy_mode, unsigned long* num_destroyed); - - - -/* string_util structs / prototypes */ - -typedef struct -{ - char* str; - int terminator; -} dyn_read_t; - -/* non-dynamic functions */ -extern char* replace_prefix(char* original, char* old_prefix, char* new_prefix); -extern char* trim_flanking_whitespace(char* str); -extern int safe_strcmp(const char* str1, const char* str2); -extern void to_lowercase(char* str); -extern void to_uppercase(char* str); - -/* dynamic functions (e.g. new memory is allocated, return values must be freed) */ -int free_null_terminated_string_array(char** strs); -char** copy_null_terminated_string_array(char** original); -extern char* dynamic_strcat(int num_strs, ...); -extern char* dcat_and_free(char** one, char** two, int free1, int free2); -extern char** split_on_separators(char* line, char* separators, int num_separators, int max_pieces, int include_remainder_at_max, unsigned long* num_pieces); /*if max_pieces < 0, it is ignored */ -extern char* join_strs(char* separator, char** parts, int max_parts, int free_parts, int free_parts_array); /*if max_parts < 0, it is ignored*/ -extern char* dynamic_replace(char* template_str, char* old_str, char* new_str); -int convert_to_regex(char* str, regex_t* p); - - -/* functions to dynamically read files */ -extern dyn_read_t dynamic_read(FILE* open_file, char* terminators, int num_terminators, unsigned long* read_length); -extern int dyn_read_line(FILE* open_file, char** dest, unsigned long* read_len); -extern unsigned char* read_entire_file(FILE* in, unsigned long read_block_size, unsigned long* read_length); - -/* run a command and get (dynamically allocated) output lines */ -extern char** get_shell_command_output_lines(char* command, unsigned long* num_lines); - - -/* comparison functions for qsort */ -extern int sort_string_cmp(const void *a, const void *b); -extern int sort_string_icmp(const void *a, const void *b); - -/* wrappers for qsort calls */ -extern void do_str_sort(char** string_arr, unsigned long string_arr_len); -extern void do_istr_sort(char** string_arr, unsigned long string_arr_len); - - - - -/* safe malloc & strdup functions used by all others (actually aliased to malloc / strdup and used) */ -extern void* safe_malloc(size_t size); -extern char* safe_strdup(const char* str); - -/* utility functions to free memory */ -extern void free_if_not_null(void* p); -extern void free_and_set_null(void** p); - - -/* other file utils */ - -extern int mkdir_p(const char* path, mode_t mode); /* returns 0 on success, 1 on error */ -extern void rm_r(const char* path); -extern int create_tmp_dir(const char* tmp_root, char** tmp_dir); /* returns 0 on success, 1 on error */ - - - -#define PATH_DOES_NOT_EXIST 0 -#define PATH_IS_REGULAR_FILE 1 -#define PATH_IS_DIRECTORY 2 -#define PATH_IS_SYMLINK 3 -#define PATH_IS_OTHER 4 - -/* -returns: - PATH_DOES_NOT_EXIST (0) if path doesn't exist - PATH_IS_REGULAR_FILE (1) if path is regular file - PATH_IS_DIRECTORY (2) if path is directory - PATH_IS_SYMLINK (3) if path is symbolic link - PATH_IS_OTHER (4) if path exists and is something else - */ -extern int path_exists(const char* path); - -extern char** get_file_lines(char* file_path, unsigned long* lines_read); - - -#endif /* ERICS_TOOLS_H */ diff --git a/package/ctcgfw/libericstools/src/file_util.c b/package/ctcgfw/libericstools/src/file_util.c deleted file mode 100644 index 9bb713b72b..0000000000 --- a/package/ctcgfw/libericstools/src/file_util.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright © 2008 by Eric Bishop - * - * This work ‘as-is’ we provide. - * No warranty, express or implied. - * We’ve done our best, - * to debug and test. - * Liability for damages denied. - * - * Permission is granted hereby, - * to copy, share, and modify. - * Use as is fit, - * free or for profit. - * On this notice these rights rely. - * - * - * - * Note that unlike other portions of Gargoyle this code - * does not fall under the GPL, but the rather whimsical - * 'Poetic License' above. - * - * Basically, this library contains a bunch of utilities - * that I find useful. I'm sure other libraries exist - * that are just as good or better, but I like these tools - * because I personally wrote them, so I know their quirks. - * (i.e. I know where the bodies are buried). I want to - * make sure that I can re-use these utilities for whatever - * code I may want to write in the future be it - * proprietary or open-source, so I've put them under - * a very, very permissive license. - * - * If you find this code useful, use it. If not, don't. - * I really don't care. - * - */ - - - -#include "erics_tools.h" -#define malloc safe_malloc -#define strdup safe_strdup - - -static int __srand_called = 0; - -int create_tmp_dir(const char* tmp_root, char** tmp_dir) -{ - if(! __srand_called) - { - srand(time(NULL)); - __srand_called = 1; - } - sprintf((*tmp_dir), "%s/tmp_%d", tmp_root, rand()); - return (mkdir_p(*tmp_dir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH )); -} - -/* -returns: - PATH_DOES_NOT_EXIST (0) if path doesn't exist - PATH_IS_REGULAR_FILE (1) if path is regular file - PATH_IS_DIRECTORY (2) if path is directory - PATH_IS_SYMLINK (3) if path is symbolic link - PATH_IS_OTHER (4) if path exists and is something else - */ -int path_exists(const char* path) -{ - struct stat fs; - int exists = lstat(path,&fs) >= 0 ? PATH_IS_OTHER : PATH_DOES_NOT_EXIST; - if(exists > 0) - { - exists = S_ISREG(fs.st_mode) ? PATH_IS_REGULAR_FILE : exists; - exists = S_ISDIR(fs.st_mode) ? PATH_IS_DIRECTORY : exists; - exists = S_ISLNK(fs.st_mode) ? PATH_IS_SYMLINK : exists; - } - return exists; -} - -int mkdir_p(const char* path, mode_t mode) -{ - int err=0; - struct stat fs; - - char* dup_path = strdup(path); - char* sep = strchr(dup_path, '/'); - sep = (sep == dup_path) ? strchr(sep+1, '/') : sep; - while(sep != NULL && err == 0) - { - sep[0] = '\0'; - if(stat(dup_path,&fs) >= 0) - { - if(!S_ISDIR(fs.st_mode)) - { - err = 1; - } - } - else - { - mkdir(dup_path, mode); - } - err =1; - if(stat(dup_path,&fs) >= 0) - { - err = S_ISDIR(fs.st_mode) ? 0 : 1; - } - - sep[0] = '/'; - sep = strchr(sep+1, '/'); - } - if(err == 0) - { - if(stat(dup_path,&fs) >= 0) - { - if(!S_ISDIR(fs.st_mode)) - { - err = 1; - } - } - else - { - mkdir(dup_path, mode); - } - err =1; - if(stat(dup_path,&fs) >= 0) - { - err = S_ISDIR(fs.st_mode) ? 0 : 1; - } - - } - free(dup_path); - return err; -} - -void rm_r(const char* path) -{ - struct stat fs; - if(lstat(path,&fs) >= 0) - { - if(S_ISDIR (fs.st_mode)) - { - /* remove directory recursively */ - struct dirent **entries; - int num_entry_paths; - int entry_path_index; - num_entry_paths = scandir(path, &entries, 0, alphasort); - for(entry_path_index=0; entry_path_index < num_entry_paths; entry_path_index++) - { - struct dirent *dentry = entries[entry_path_index]; - if(strcmp(dentry->d_name, "..") != 0 && strcmp(dentry->d_name, ".") != 0) - { - char* entry_path = (char*)malloc(strlen(path) + strlen(dentry->d_name) + 2); - sprintf(entry_path,"%s/%s", path, dentry->d_name); - - /* recurse */ - rm_r(entry_path); - - free(entry_path); - } - } - remove(path); - } - else - { - /* remove regular file, no need to recurse */ - remove(path); - } - } -} - -char** get_file_lines(char* file_path, unsigned long* lines_read) -{ - char** result = NULL; - int path_type = path_exists(file_path); - *lines_read = 0; - if(path_type != PATH_DOES_NOT_EXIST && path_type != PATH_IS_DIRECTORY) /* exists and is not directory */ - { - FILE* read_file = fopen(file_path, "r"); - unsigned char* file_data = NULL; - if(read_file != NULL) - { - unsigned long file_length; - file_data = read_entire_file(read_file, 1024, &file_length); - fclose(read_file); - } - if(file_data != NULL) - { - char line_seps[] = {'\r', '\n'}; - result = split_on_separators((char*)file_data, line_seps , 2, -1, 0, lines_read); - free(file_data); - } - } - return result; -} - - - diff --git a/package/ctcgfw/libericstools/src/list.c b/package/ctcgfw/libericstools/src/list.c deleted file mode 100644 index f36f3cd598..0000000000 --- a/package/ctcgfw/libericstools/src/list.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright © 2008 by Eric Bishop - * - * This work ‘as-is’ we provide. - * No warranty, express or implied. - * We’ve done our best, - * to debug and test. - * Liability for damages denied. - * - * Permission is granted hereby, - * to copy, share, and modify. - * Use as is fit, - * free or for profit. - * On this notice these rights rely. - * - * - * - * Note that unlike other portions of Gargoyle this code - * does not fall under the GPL, but the rather whimsical - * 'Poetic License' above. - * - * Basically, this library contains a bunch of utilities - * that I find useful. I'm sure other libraries exist - * that are just as good or better, but I like these tools - * because I personally wrote them, so I know their quirks. - * (i.e. I know where the bodies are buried). I want to - * make sure that I can re-use these utilities for whatever - * code I may want to write in the future be it - * proprietary or open-source, so I've put them under - * a very, very permissive license. - * - * If you find this code useful, use it. If not, don't. - * I really don't care. - * - */ - - -#include "erics_tools.h" -#define malloc safe_malloc -#define strdup safe_strdup - - -list* initialize_list() -{ - list* l = (list*)malloc(sizeof(list)); - l->length = 0; - l->head = NULL; - l->tail = NULL; - return l; -} - -list_node* create_list_node(void* value) -{ - list_node* new_node = (list_node*)malloc(sizeof(list_node)); - new_node->value = value; - new_node->previous = NULL; - new_node->next = NULL; - return new_node; -} -void* free_list_node(list_node* delete_node) -{ - void* value = NULL; - if(delete_node != NULL) - { - value = delete_node->value; - free(delete_node); - } - return value; -} - - -list_node* shift_list_node(list* l) -{ - list_node* return_node = NULL; - if(l != NULL) - { - if(l->head != NULL) - { - return_node = l->head; - - l->head = l->head->next; - if(l->head != NULL) { l->head->previous = NULL; } - l->tail = l->tail == return_node ? NULL : l->tail; - l->length = l->length -1; - - return_node->previous = NULL; - return_node->next = NULL; - } - } - return return_node; -} -void unshift_list_node(list* l, list_node* new_node) -{ - if(l != NULL && new_node != NULL) - { - new_node->previous = NULL; - if(l->head == NULL) /* list is empty */ - { - new_node->next = NULL; - l->tail = new_node; - } - else - { - new_node->next = l->head; - l->head->previous = new_node; - - } - l->head = new_node; - l->length = l->length +1; - } -} -list_node* pop_list_node(list* l) -{ - list_node* return_node = NULL; - if(l != NULL) - { - if(l->tail != NULL) - { - return_node = l->tail; - l->tail = l->tail->previous; - if(l->tail != NULL) { l->tail->next = NULL; } - l->head = l->head == return_node ? NULL : l->head; - l->length = l->length -1; - - return_node->previous = NULL; - return_node->next = NULL; - } - } - return return_node; - -} -void push_list_node(list* l, list_node* new_node) -{ - if(l != NULL && new_node != NULL) - { - new_node->next = NULL; - if(l->tail == NULL) /* list is empty */ - { - new_node->previous = NULL; - l->head = new_node; - } - else - { - new_node->previous = l->tail; - l->tail->next = new_node; - } - l->tail = new_node; - l->length = l->length +1; - } -} - - -void* shift_list(list* l) -{ - return free_list_node ( shift_list_node(l) ); -} -void unshift_list(list* l, void* value) -{ - list_node* new_node = create_list_node(value); - unshift_list_node(l, new_node); -} -void* pop_list(list* l) -{ - return free_list_node ( pop_list_node(l) ); -} - -void push_list(list*l, void* value) -{ - list_node* new_node = create_list_node(value); - push_list_node(l, new_node); -} - - - -void remove_internal_list_node(list* l, list_node* internal) -{ - /* note we assume internal is in l, otherwise everything gets FUBAR! */ - if(l != NULL && internal != NULL) - { - list_node* next = internal->next; - list_node* previous = internal->previous; - if(previous == NULL) /* internal is head */ - { - l->head = next; - if(l->head != NULL) { l->head->previous = NULL; } - } - if(next == NULL) /* internal is tail */ - { - l->tail = previous; - if(l->tail != NULL) { l->tail->next = NULL; } - } - if(previous != NULL && next != NULL) - { - previous->next = next; - next->previous = previous; - } - internal->next = NULL; - internal->previous = NULL; - - l->length = l->length - 1; - } -} - - - -void** destroy_list(list* l, int destruction_type, unsigned long* num_values) -{ - void** values = NULL; - unsigned long value_index = 0; - if(l != NULL) - { - if(destruction_type == DESTROY_MODE_RETURN_VALUES) - { - values = (void**)malloc((1+l->length)*sizeof(void*)); - } - - - for(value_index=0; l->length > 0; value_index++) - { - void* value = shift_list(l); - if(destruction_type == DESTROY_MODE_RETURN_VALUES) - { - values[value_index] = value; - } - else if(destruction_type == DESTROY_MODE_FREE_VALUES) - { - free(value); - } - } - if(destruction_type == DESTROY_MODE_RETURN_VALUES) - { - values[value_index] = NULL; - } - free(l); - } - *num_values = value_index; - return values; -} - -void* list_element_at(list* l, unsigned long index) -{ - void* return_value = NULL; - if(l != NULL) - { - unsigned long current_index = index - (unsigned long)((l->length)/2) > 0 ? l->length -1 : 0; - list_node* current_node = current_index == 0 ? l->head : l->tail; - - while(current_index != index && current_node != NULL) - { - current_node = current_index > index ? current_node->previous : current_node->next; - current_index = current_index > index ? current_index -1 : current_index + 1; - } - if(current_node != NULL) - { - return_value = current_node->value; - } - } - return return_value; -} -void** get_list_values(list* l, unsigned long* num_values) /* returns null terminated array */ -{ - void** values = NULL; - unsigned long value_index = 0; - if(l != NULL) - { - - list_node* current_node = l->head; - values = (void**)malloc((1+l->length)*sizeof(void*)); - - for(value_index = 0; value_index < l->length; value_index++) - { - values[value_index] = current_node->value; - current_node = current_node->next; - } - values[value_index] = NULL; - } - *num_values = value_index; - return values; -} - diff --git a/package/ctcgfw/libericstools/src/priority_queue.c b/package/ctcgfw/libericstools/src/priority_queue.c deleted file mode 100644 index a5747af2eb..0000000000 --- a/package/ctcgfw/libericstools/src/priority_queue.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright © 2008 by Eric Bishop - * - * This work ‘as-is’ we provide. - * No warranty, express or implied. - * We’ve done our best, - * to debug and test. - * Liability for damages denied. - * - * Permission is granted hereby, - * to copy, share, and modify. - * Use as is fit, - * free or for profit. - * On this notice these rights rely. - * - * - * - * Note that unlike other portions of Gargoyle this code - * does not fall under the GPL, but the rather whimsical - * 'Poetic License' above. - * - * Basically, this library contains a bunch of utilities - * that I find useful. I'm sure other libraries exist - * that are just as good or better, but I like these tools - * because I personally wrote them, so I know their quirks. - * (i.e. I know where the bodies are buried). I want to - * make sure that I can re-use these utilities for whatever - * code I may want to write in the future be it - * proprietary or open-source, so I've put them under - * a very, very permissive license. - * - * If you find this code useful, use it. If not, don't. - * I really don't care. - * - */ - -#include "erics_tools.h" -#define malloc safe_malloc -#define strdup safe_strdup - -typedef struct id_map_node_struct -{ - list* id_list; - list_node* id_node; -} id_map_node; - - -priority_queue* initialize_priority_queue(void) -{ - priority_queue* pq = (priority_queue*)malloc(sizeof(priority_queue)); - pq->priorities = initialize_long_map(); - pq->ids = initialize_string_map(0); - pq->first = NULL; - pq->length = 0; - return pq; - -} - -priority_queue_node* create_priority_node(unsigned long priority, char* id, void* value) -{ - priority_queue_node* pn = (priority_queue_node*)malloc(sizeof(priority_queue_node)); - pn->priority = priority; - pn->id = strdup(id); - pn->value = value; - return pn; -} -void* free_priority_queue_node(priority_queue_node* pn) -{ - void *return_value = NULL; - if(pn != NULL) - { - return_value = pn->value; - free(pn->id); - free(pn); - } - return return_value; -} - -void push_priority_queue(priority_queue* pq, unsigned long priority, char* id, void * value) -{ - if(pq != NULL && id != NULL) - { - priority_queue_node* pn = create_priority_node(priority, id, value); - push_priority_queue_node(pq, pn); - } -} - -/* note id is ALWAYS dynamically allocated, need to free */ -void* shift_priority_queue(priority_queue* pq, unsigned long* priority, char** id) -{ - void* return_value = NULL; - priority_queue_node* pn = shift_priority_queue_node(pq); - if(pn != NULL) - { - *priority = pn->priority; - *id = strdup(pn->id); - return_value = free_priority_queue_node(pn); - } - return return_value; -} - -/* last param specified whether to dynamicall allocate id (otherwise pointer to id in priority_queue_node) */ -void* peek_priority_queue(priority_queue* pq, unsigned long* priority, char** id, int dynamic_alloc_id) -{ - void* return_value = NULL; - *priority = 0; - *id = NULL; - if(pq != NULL) - { - if(pq->first != NULL) - { - return_value = pq->first->value; - *priority = pq->first->priority; - if(dynamic_alloc_id) - { - *id = strdup(pq->first->id); - } - else - { - *id = pq->first->id; - } - } - } - return return_value; -} - - -void* get_priority_queue_element_with_id(priority_queue* pq, char* id, long* priority) -{ - void* return_value = NULL; - priority_queue_node* pn = get_priority_queue_node_with_id(pq, id); - if(pn != NULL) - { - *priority = pn->priority; - return_value = free_priority_queue_node(pn); - } - else - { - *priority = 0; - } - return return_value; -} - -void* remove_priority_queue_element_with_id(priority_queue* pq, char* id, long* priority) -{ - void* return_value = NULL; - priority_queue_node* pn = remove_priority_queue_node_with_id(pq, id); - if(pn != NULL) - { - *priority = pn->priority; - return_value = free_priority_queue_node(pn); - } - else - { - *priority = 0; - } - return return_value; -} - - -void push_priority_queue_node(priority_queue* pq, priority_queue_node* pn) -{ - if(pq != NULL && pn != NULL) - { - /* assume that most of the time we won't have collisions */ - list_node* lpn = create_list_node(pn); - list* new_list = initialize_list(); - list* old_list; - id_map_node* idn; - - push_list_node(new_list, lpn); - old_list = (list*)set_long_map_element(pq->priorities, pn->priority, new_list); - if(old_list != NULL) - { - push_list_node(old_list, lpn); - set_long_map_element(pq->priorities, pn->priority, old_list); - free(new_list); - new_list = old_list; - } - - /* update first */ - if(pq->first == NULL) - { - pq->first = pn; - } - else if(pn->priority < pq->first->priority) - { - pq->first = pn; - } - - - - - /* save id */ - idn = (id_map_node*)malloc(sizeof(id_map_node)); - idn->id_list = new_list; - idn->id_node = lpn; - set_string_map_element(pq->ids, pn->id, idn); - - pq->length = pq->length + 1;; - } -} - -priority_queue_node* shift_priority_queue_node(priority_queue* pq) -{ - priority_queue_node* return_node = NULL; - if(pq != NULL) - { - if(pq->first != NULL) - { - list* next_list = (list*)remove_long_map_element(pq->priorities, pq->first->priority); - list* next_first_list = NULL; - list_node* smallest_list_node = shift_list_node(next_list); - id_map_node* idn; - - if(next_list->length == 0) - { - unsigned long tmp; - destroy_list(next_list, DESTROY_MODE_IGNORE_VALUES, &tmp); - next_first_list = (list*)get_smallest_long_map_element(pq->priorities, &tmp); - } - else - { - set_long_map_element(pq->priorities, pq->first->priority, next_list); - next_first_list = next_list; - } - return_node = free_list_node(smallest_list_node); - idn = (id_map_node*)remove_string_map_element(pq->ids, return_node->id); - free(idn); - - if(next_first_list != NULL) - { - list_node* next_first_node = shift_list_node(next_first_list); - pq->first = (priority_queue_node*)next_first_node->value; - unshift_list_node(next_first_list, next_first_node); - } - else - { - pq->first = NULL; - } - - pq->length = pq->length -1; - } - } - - return return_node; -} - - -priority_queue_node* get_priority_queue_node_with_id(priority_queue* pq, char* id) -{ - priority_queue_node* return_node = NULL; - if(pq != NULL && id != NULL) - { - id_map_node* idn = (id_map_node*)get_string_map_element(pq->ids, id); - if(idn != NULL) - { - return_node = (priority_queue_node*)idn->id_node->value; - } - } - return return_node; -} - - -priority_queue_node* remove_priority_queue_node_with_id(priority_queue* pq, char* id) -{ - priority_queue_node* return_node = NULL; - if(pq != NULL && id != NULL) - { - id_map_node* idn = (id_map_node*)remove_string_map_element(pq->ids, id); - if(idn != NULL) - { - /* remove relevant node from list */ - remove_internal_list_node(idn->id_list, idn->id_node); - return_node = free_list_node(idn->id_node); - - /* if list is empty remove it from priority map */ - if(idn->id_list->length == 0) - { - unsigned long tmp; - remove_long_map_element(pq->priorities, return_node->priority); - destroy_list(idn->id_list, DESTROY_MODE_IGNORE_VALUES, &tmp); - } - free(idn); - - /* if we're removing first node, reset it */ - if(return_node == pq->first) - { - unsigned long tmp; - list* next_first_list = (list*)get_smallest_long_map_element(pq->priorities, &tmp); - if(next_first_list != NULL) - { - list_node* next_first_node = shift_list_node(next_first_list); - pq->first = (priority_queue_node*)next_first_node->value; - unshift_list_node(next_first_list, next_first_node); - } - else - { - pq->first = NULL; - } - } - pq->length = pq->length -1; - } - } - return return_node; -} - -void set_priority_for_id_in_priority_queue(priority_queue* pq, char* id, unsigned long priority) -{ - if(pq != NULL && id != NULL) - { - priority_queue_node* id_pq_node = remove_priority_queue_node_with_id(pq, id); - id_pq_node->priority = priority; - push_priority_queue_node(pq, id_pq_node); - } -} - -priority_queue_node* peek_priority_queue_node(priority_queue* pq) -{ - return pq->first; -} - -void** destroy_priority_queue(priority_queue* pq, int destroy_mode, unsigned long* num_elements_destroyed) -{ - void** values = NULL; - unsigned long tmp; - *num_elements_destroyed = 0; - if(pq != NULL) - { - if(destroy_mode == DESTROY_MODE_RETURN_VALUES) - { - values = (void**)malloc((pq->length+1)*sizeof(void*)); - } - while(pq->length > 0) - { - priority_queue_node* pqn = shift_priority_queue_node(pq); - void* next_value = free_priority_queue_node(pqn); - if(destroy_mode == DESTROY_MODE_RETURN_VALUES) - { - values[*num_elements_destroyed] = next_value; - } - else if(destroy_mode == DESTROY_MODE_FREE_VALUES) - { - free(next_value); - } - *num_elements_destroyed = *num_elements_destroyed + 1; - } - if(destroy_mode == DESTROY_MODE_RETURN_VALUES) - { - values[*num_elements_destroyed] = NULL; - } - - destroy_long_map(pq->priorities, DESTROY_MODE_FREE_VALUES, &tmp); - destroy_string_map(pq->ids, DESTROY_MODE_FREE_VALUES, &tmp); - free(pq); - } - return values; -} - - diff --git a/package/ctcgfw/libericstools/src/safe_malloc.c b/package/ctcgfw/libericstools/src/safe_malloc.c deleted file mode 100644 index 151b7e09ea..0000000000 --- a/package/ctcgfw/libericstools/src/safe_malloc.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright © 2008 by Eric Bishop - * - * This work ‘as-is’ we provide. - * No warranty, express or implied. - * We’ve done our best, - * to debug and test. - * Liability for damages denied. - * - * Permission is granted hereby, - * to copy, share, and modify. - * Use as is fit, - * free or for profit. - * On this notice these rights rely. - * - * - * - * Note that unlike other portions of Gargoyle this code - * does not fall under the GPL, but the rather whimsical - * 'Poetic License' above. - * - * Basically, this library contains a bunch of utilities - * that I find useful. I'm sure other libraries exist - * that are just as good or better, but I like these tools - * because I personally wrote them, so I know their quirks. - * (i.e. I know where the bodies are buried). I want to - * make sure that I can re-use these utilities for whatever - * code I may want to write in the future be it - * proprietary or open-source, so I've put them under - * a very, very permissive license. - * - * If you find this code useful, use it. If not, don't. - * I really don't care. - * - */ - -#include "erics_tools.h" - -void *safe_malloc(size_t size) -{ - void* val = malloc(size); - if(val == NULL) - { - fprintf(stderr, "ERROR: MALLOC FAILURE!\n"); - exit(1); - } - return val; -} - -char* safe_strdup(const char* str) -{ - char* new_str = NULL; - if(str != NULL) - { - new_str = strdup(str); - if(new_str == NULL) - { - fprintf(stderr, "ERROR: MALLOC FAILURE!\n"); - exit(1); - } - } - return new_str; -} - - -void free_if_not_null(void* p) -{ - if(p != NULL) - { - free(p); - } -} -void free_and_set_null(void** p) -{ - if(*p != NULL) - { - free(*p); - *p = NULL; - } -} diff --git a/package/ctcgfw/libericstools/src/string_util.c b/package/ctcgfw/libericstools/src/string_util.c deleted file mode 100644 index 499685a52d..0000000000 --- a/package/ctcgfw/libericstools/src/string_util.c +++ /dev/null @@ -1,683 +0,0 @@ -/* - * Copyright © 2008 by Eric Bishop - * - * This work ‘as-is’ we provide. - * No warranty, express or implied. - * We’ve done our best, - * to debug and test. - * Liability for damages denied. - * - * Permission is granted hereby, - * to copy, share, and modify. - * Use as is fit, - * free or for profit. - * On this notice these rights rely. - * - * - * - * Note that unlike other portions of Gargoyle this code - * does not fall under the GPL, but the rather whimsical - * 'Poetic License' above. - * - * Basically, this library contains a bunch of utilities - * that I find useful. I'm sure other libraries exist - * that are just as good or better, but I like these tools - * because I personally wrote them, so I know their quirks. - * (i.e. I know where the bodies are buried). I want to - * make sure that I can re-use these utilities for whatever - * code I may want to write in the future be it - * proprietary or open-source, so I've put them under - * a very, very permissive license. - * - * If you find this code useful, use it. If not, don't. - * I really don't care. - * - */ - -#include "erics_tools.h" -#define malloc safe_malloc -#define strdup safe_strdup - - - - -char* replace_prefix(char* original, char* old_prefix, char* new_prefix) -{ - char* replaced = NULL; - if(original != NULL && old_prefix != NULL && new_prefix != NULL && strstr(original, old_prefix) == original) - { - int old_prefix_length = strlen(old_prefix); - int new_prefix_length = strlen(new_prefix); - int remainder_length = strlen(original) - old_prefix_length; - int new_length = new_prefix_length + remainder_length; - /* printf("%d %d %d %d\n", old_prefix_length, new_prefix_length, remainder_length, new_length); */ - - replaced = malloc(new_length+1); - memcpy(replaced, new_prefix, new_prefix_length); - memcpy(replaced+new_prefix_length, original+old_prefix_length, remainder_length); - replaced[new_prefix_length+remainder_length] = '\0'; - } - return replaced; -} - -char* trim_flanking_whitespace(char* str) -{ - int new_start = 0; - int new_length = 0; - - char whitespace[5] = { ' ', '\t', '\n', '\r', '\0' }; - int num_whitespace_chars = 4; - - - int index = 0; - int is_whitespace = 1; - int test; - while( (test = str[index]) != '\0' && is_whitespace == 1) - { - int whitespace_index; - is_whitespace = 0; - for(whitespace_index = 0; whitespace_index < num_whitespace_chars && is_whitespace == 0; whitespace_index++) - { - is_whitespace = test == whitespace[whitespace_index] ? 1 : 0; - } - index = is_whitespace == 1 ? index+1 : index; - } - new_start = index; - - - index = strlen(str) - 1; - is_whitespace = 1; - while( index >= new_start && is_whitespace == 1) - { - int whitespace_index; - is_whitespace = 0; - for(whitespace_index = 0; whitespace_index < num_whitespace_chars && is_whitespace == 0; whitespace_index++) - { - is_whitespace = str[index] == whitespace[whitespace_index] ? 1 : 0; - } - index = is_whitespace == 1 ? index-1 : index; - } - new_length = str[new_start] == '\0' ? 0 : index + 1 - new_start; - - - if(new_start > 0) - { - for(index = 0; index < new_length; index++) - { - str[index] = str[index+new_start]; - } - } - str[new_length] = 0; - return str; -} - -int safe_strcmp(const char* str1, const char* str2) -{ - if(str1 == NULL && str2 == NULL) - { - return 0; - } - else if(str1 == NULL && str2 != NULL) - { - return 1; - } - else if(str1 != NULL && str2 == NULL) - { - return -1; - } - return strcmp(str1, str2); -} - - -void to_lowercase(char* str) -{ - int i; - for(i = 0; str[i] != '\0'; i++) - { - str[i] = tolower(str[i]); - } -} -void to_uppercase(char* str) -{ - int i; - for(i = 0; str[i] != '\0'; i++) - { - str[i] = toupper(str[i]); - } -} - -/* returns number freed */ -int free_null_terminated_string_array(char** strs) -{ - unsigned long str_index = 0; - if(strs != NULL) - { - for(str_index=0; strs[str_index] != NULL; str_index++) - { - free(strs[str_index]); - } - free(strs); - } - return str_index; -} - -char** copy_null_terminated_string_array(char** original) -{ - unsigned long size; - char** new; - for(size=0; original[size] != NULL ; size++) ; - new = (char**)malloc( (size+1)*sizeof(char*)); - for(size=0; original[size] != NULL; size++) - { - new[size] = strdup(original[size]); - } - new[size] = NULL; - return new; -} - - - -char* dynamic_strcat(int num_strs, ...) -{ - - va_list strs; - int new_length = 0; - int i; - int next_start; - char* new_str; - - va_start(strs, num_strs); - for(i=0; i < num_strs; i++) - { - char* next_arg = va_arg(strs, char*); - if(next_arg != NULL) - { - new_length = new_length + strlen(next_arg); - } - } - va_end(strs); - - new_str = malloc((1+new_length)*sizeof(char)); - va_start(strs, num_strs); - next_start = 0; - for(i=0; i < num_strs; i++) - { - char* next_arg = va_arg(strs, char*); - if(next_arg != NULL) - { - int next_length = strlen(next_arg); - memcpy(new_str+next_start,next_arg, next_length); - next_start = next_start+next_length; - } - } - new_str[next_start] = '\0'; - - return new_str; -} - -char* dcat_and_free(char** one, char** two, int free1, int free2) -{ - char* s = NULL; - - if(one != NULL && two != NULL) { s = dynamic_strcat(2, *one, *two); } - else if(one != NULL) { s = strdup(*one); } - else if(two != NULL) { s = strdup(*two); } - else { s= strdup(""); } - - if(free1){ free(*one); *one=s; } - if(free2){ free(*two); *two=s; } - - return s; -} - - -/* - * line is the line to be parsed -- it is not modified in any way - * max_pieces indicates number of pieces to return, if negative this is determined dynamically - * include_remainder_at_max indicates whether the last piece, when max pieces are reached, - * should be what it would normally be (0) or the entire remainder of the line (1) - * if max_pieces < 0 this parameter is ignored - * - * - * returns all non-separator pieces in a line - * result is dynamically allocated, MUST be freed after call-- even if - * line is empty (you still get a valid char** pointer to to a NULL char*) - */ -char** split_on_separators(char* line, char* separators, int num_separators, int max_pieces, int include_remainder_at_max, unsigned long *num_pieces) -{ - char** split; - - *num_pieces = 0; - if(line != NULL) - { - int split_index; - int non_separator_found; - char* dup_line; - char* start; - - if(max_pieces < 0) - { - /* count number of separator characters in line -- this count + 1 is an upperbound on number of pieces */ - int separator_count = 0; - int line_index; - for(line_index = 0; line[line_index] != '\0'; line_index++) - { - int sep_index; - int found = 0; - for(sep_index =0; found == 0 && sep_index < num_separators; sep_index++) - { - found = separators[sep_index] == line[line_index] ? 1 : 0; - } - separator_count = separator_count+ found; - } - max_pieces = separator_count + 1; - } - split = (char**)malloc((1+max_pieces)*sizeof(char*)); - split_index = 0; - split[split_index] = NULL; - - - dup_line = strdup(line); - start = dup_line; - non_separator_found = 0; - while(non_separator_found == 0) - { - int matches = 0; - int sep_index; - for(sep_index =0; sep_index < num_separators; sep_index++) - { - matches = matches == 1 || separators[sep_index] == start[0] ? 1 : 0; - } - non_separator_found = matches==0 || start[0] == '\0' ? 1 : 0; - if(non_separator_found == 0) - { - start++; - } - } - - while(start[0] != '\0' && split_index < max_pieces) - { - /* find first separator index */ - int first_separator_index = 0; - int separator_found = 0; - while( separator_found == 0 ) - { - int sep_index; - for(sep_index =0; separator_found == 0 && sep_index < num_separators; sep_index++) - { - separator_found = separators[sep_index] == start[first_separator_index] || start[first_separator_index] == '\0' ? 1 : 0; - } - if(separator_found == 0) - { - first_separator_index++; - } - } - - /* copy next piece to split array */ - if(first_separator_index > 0) - { - char* next_piece = NULL; - if(split_index +1 < max_pieces || include_remainder_at_max <= 0) - { - next_piece = (char*)malloc((first_separator_index+1)*sizeof(char)); - memcpy(next_piece, start, first_separator_index); - next_piece[first_separator_index] = '\0'; - } - else - { - next_piece = strdup(start); - } - split[split_index] = next_piece; - split[split_index+1] = NULL; - split_index++; - } - - - /* find next non-separator index, indicating start of next piece */ - start = start+ first_separator_index; - non_separator_found = 0; - while(non_separator_found == 0) - { - int matches = 0; - int sep_index; - for(sep_index =0; sep_index < num_separators; sep_index++) - { - matches = matches == 1 || separators[sep_index] == start[0] ? 1 : 0; - } - non_separator_found = matches==0 || start[0] == '\0' ? 1 : 0; - if(non_separator_found == 0) - { - start++; - } - } - } - free(dup_line); - *num_pieces = split_index; - } - else - { - split = (char**)malloc((1)*sizeof(char*)); - split[0] = NULL; - } - return split; -} - -char* join_strs(char* separator, char** parts, int max_parts, int free_parts, int free_parts_array) -{ - char* joined = NULL; - int num_parts = 0; - for(num_parts=0; parts[num_parts] != NULL && (max_parts < 0 || num_parts < max_parts); num_parts++){} - if(num_parts > 0) - { - num_parts--; - joined = strdup(parts[num_parts]); - if(free_parts){ free(parts[num_parts]); } - num_parts--; - - while(num_parts >= 0) - { - char* tmp = joined; - joined = dynamic_strcat(3, parts[num_parts], separator, joined); - free(tmp); - if(free_parts){ free(parts[num_parts]); } - num_parts--; - } - } - if(free_parts_array) - { - free(parts); - } - return joined; -} - - -char* dynamic_replace(char* template_str, char* old, char* new) -{ - char *ret; - int i, count = 0; - int newlen = strlen(new); - int oldlen = strlen(old); - - char* dyn_template = strdup(template_str); - char* s = dyn_template; - for (i = 0; s[i] != '\0'; i++) - { - if (strstr(&s[i], old) == &s[i]) - { - count++; - i += oldlen - 1; - } - } - ret = malloc(i + 1 + count * (newlen - oldlen)); - - i = 0; - while (*s) - { - if (strstr(s, old) == s) - { - strcpy(&ret[i], new); - i += newlen; - s += oldlen; - } - else - { - ret[i++] = *s++; - } - } - ret[i] = '\0'; - free(dyn_template); - - return ret; -} - - -/* - requires expression to be surrounded by '/' characters, and deals with escape - characters '\/', '\r', '\n', and '\t' when escapes haven't been interpreted - (e.g. after recieving regex string from user) - - returns 1 on good regex, 0 on bad regex -*/ -int convert_to_regex(char* str, regex_t* p) -{ - char* trimmed = trim_flanking_whitespace(strdup(str)); - int trimmed_length = strlen(trimmed); - char* new = NULL; - - int valid = 1; - /* regex must be defined by surrounding '/' characters */ - if(trimmed[0] != '/' || trimmed[trimmed_length-1] != '/') - { - valid = 0; - free(trimmed); - } - - if(valid == 1) - { - char* internal = (char*)malloc(trimmed_length*sizeof(char)); - int internal_length = trimmed_length-2; - - int new_index = 0; - int internal_index = 0; - char previous = '\0'; - - - memcpy(internal, trimmed+1, internal_length); - internal[internal_length] = '\0'; - free(trimmed); - - new = (char*)malloc(trimmed_length*sizeof(char)); - while(internal[internal_index] != '\0' && valid == 1) - { - char next = internal[internal_index]; - if(next == '/' && previous != '\\') - { - valid = 0; - } - else if((next == 'n' || next == 'r' || next == 't' || next == '/') && previous == '\\') - { - char previous2 = '\0'; - if(internal_index >= 2) - { - previous2 = internal[internal_index-2]; - } - - new_index = previous2 == '\\' ? new_index : new_index-1; - switch(next) - { - case 'n': - new[new_index] = previous2 == '\\' ? next : '\n'; - break; - case 'r': - new[new_index] = previous2 == '\\' ? next : '\r'; - break; - case 't': - new[new_index] = previous2 == '\\' ? next : '\t'; - break; - case '/': - new[new_index] = previous2 == '\\' ? next : '/'; - break; - } - previous = '\0'; - internal_index++; - new_index++; - - } - else - { - new[new_index] = next; - previous = next; - internal_index++; - new_index++; - } - } - if(valid == 0 || previous == '\\') - { - valid = 0; - free(new); - new = NULL; - } - else - { - new[new_index] = '\0'; - } - free(internal); - } - if(valid == 1) - { - valid = regcomp(p,new,REG_EXTENDED) == 0 ? 1 : 0; - if(valid == 0) - { - regfree(p); - } - free(new); - } - - return valid; -} - - - - -/* note: str element in return value is dynamically allocated, need to free */ -dyn_read_t dynamic_read(FILE* open_file, char* terminators, int num_terminators, unsigned long* read_length) -{ - fpos_t start_pos; - unsigned long size_to_read = 0; - int terminator_found = 0; - int terminator; - char* str; - dyn_read_t ret_value; - - fgetpos(open_file, &start_pos); - - while(terminator_found == 0) - { - int nextch = fgetc(open_file); - int terminator_index = 0; - for(terminator_index = 0; terminator_index < num_terminators && terminator_found == 0; terminator_index++) - { - terminator_found = nextch == terminators[terminator_index] ? 1 : 0; - terminator = nextch; - } - terminator_found = nextch == EOF ? 1 : terminator_found; - terminator = nextch == EOF ? EOF : nextch; - if(terminator_found == 0) - { - size_to_read++; - } - } - - str = (char*)malloc((size_to_read+1)*sizeof(char)); - if(size_to_read > 0) - { - int i; - fsetpos(open_file, &start_pos); - for(i=0; ilength > 0) - { - printf("%s\n", (char*)pop_list(l)); - } - - - unsigned long dl; - destroy_list(l, DESTROY_MODE_IGNORE_VALUES, &dl); - - - printf("-------queue test-------------\n"); - unsigned long priority; - char* id; - - - priority_queue* pq = initialize_priority_queue(); - push_priority_queue(pq, 30, "id_1", "value_1"); - push_priority_queue(pq, 10, "id_2", "value_2"); - push_priority_queue(pq, 10, "id_3", "value_3"); - push_priority_queue(pq, 40, "id_4", "value_4"); - push_priority_queue(pq, 5, "id_5", "value_5"); - push_priority_queue(pq, 30, "id_6", "value_6"); - push_priority_queue(pq, 30, "id_7", "value_7"); - - - printf("queue length = %ld\n", pq->length); - unsigned long num_destroyed; - - char* tmp = peek_priority_queue(pq, &priority, &id, 0); - printf("first is \"%s\"\n", tmp); - - - set_priority_for_id_in_priority_queue(pq, "id_5", 35); - - tmp = peek_priority_queue(pq, &priority, &id, 0); - printf("first is \"%s\"\n", tmp); - - set_priority_for_id_in_priority_queue(pq, "id_2", 36); - - tmp = peek_priority_queue(pq, &priority, &id, 0); - printf("first is \"%s\"\n", tmp); - - /* - char** values = (char**)destroy_priority_queue(pq, DESTROY_MODE_RETURN_VALUES, &num_destroyed); - int index = 0; - for(index = 0; values[index] != NULL; index++) - { - printf("%s\n", values[index]); - } - */ - - - while(pq->length > 0) - { - char* value = (char*)shift_priority_queue(pq, &priority, &id); - printf("%s\n", value); - free(id); - } - destroy_priority_queue(pq, DESTROY_MODE_FREE_VALUES, &dl); - - return 0; -} diff --git a/package/ctcgfw/libericstools/src/test_map.c b/package/ctcgfw/libericstools/src/test_map.c deleted file mode 100644 index dfad823007..0000000000 --- a/package/ctcgfw/libericstools/src/test_map.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright © 2008 by Eric Bishop - * - * This work 'as-is' we provide. - * No warranty, express or implied. - * We've done our best, - * to debug and test. - * Liability for damages denied. - * - * Permission is granted hereby, - * to copy, share, and modify. - * Use as is fit, - * free or for profit. - * On this notice these rights rely. - * - * - * - * Note that unlike other portions of Gargoyle this code - * does not fall under the GPL, but the rather whimsical - * 'Poetic License' above. - * - * Basically, this library contains a bunch of utilities - * that I find useful. I'm sure other libraries exist - * that are just as good or better, but I like these tools - * because I personally wrote them, so I know their quirks. - * (i.e. I know where the bodies are buried). I want to - * make sure that I can re-use these utilities for whatever - * code I may want to write in the future be it - * proprietary or open-source, so I've put them under - * a very, very permissive license. - * - * If you find this code useful, use it. If not, don't. - * I really don't care. - * - */ - - - - -#include "erics_tools.h" -#include - - -void get_max_depth(long_map_node* n, unsigned long* max_depth, unsigned long current_depth); -void get_min_depth(long_map_node* n, unsigned long* min_depth, unsigned long current_depth); -void print_map(long_map_node* n, int depth); - -int main (void) -{ - unsigned long num_insertions = 2500; - unsigned long max_insertion = 5000; - int num_repeats = 3; - - unsigned int seed = (unsigned int)time(NULL); - srand (seed); - - printf("TESTING LONG MAP....\n\n"); - - - printf("initializing map....\n"); - long_map* lm = initialize_long_map(); - printf("initialized!\n\n"); - - - - - - int repeat = 0; - for(repeat =0; repeat < num_repeats; repeat++) - { - - printf("randomly inserting %ld integers randomly selected (not in order) between 0 and %ld\n", num_insertions, max_insertion); - - - unsigned long i; - unsigned long dupes = 0; - for(i=0; iroot->left, &left_depth, 0); - get_max_depth(lm->root->right, &right_depth, 0); - - unsigned long original_size = lm->num_elements; - printf("insertion complete\n"); - printf("after insertion, tree size = %ld \n", original_size); - printf("(note this may be less than %ld because the same numbers can be selected for insertion more than once, replacing the original node)\n", num_insertions); - printf("dupes = %ld\n", dupes); - printf("depth of left branch = %ld, depth of right branch = %ld\n\n", left_depth, right_depth); - - - if(repeat+1 < num_repeats) - { - - printf("randomly selecting %ld numbers between 0 and %ld to remove from tree.\n", num_insertions, max_insertion); - printf("note that these keys will not necessarily be present in tree -- the selection process is entirely random.\n"); - - int j; - int found = 0; - for(j=0; j < num_insertions; j++) - { - - unsigned long r = (unsigned long)(max_insertion*((double)rand()/(double)RAND_MAX)); - if( remove_long_map_element(lm, r) != NULL) - { - found++; - } - } - right_depth = 0; - left_depth = 0; - get_max_depth(lm->root->left, &left_depth, 0); - get_max_depth(lm->root->right, &right_depth, 0); - - printf("removal complete\n"); - printf("after removal, tree size = %ld \n", lm->num_elements); - printf("depth of left branch = %ld, depth of right branch = %ld\n", left_depth, right_depth); - if(original_size - found == lm->num_elements) - { - printf("size consistent with number of nodes successfully removed\n\n"); - } - else - { - printf("SIZE IS BAD -- IS NOT CONSISTENT WITH NUMBER OF NODES REMOVED !!!!\n\n"); - } - - printf("removing remaining nodes in tree in random order\n"); - unsigned long length; - unsigned long *keys = get_sorted_long_map_keys(lm, &length); - while(lm->root != NULL && lm->num_elements > 0) - { - unsigned long r = (unsigned long)(length*((double)rand()/(double)RAND_MAX)); - if( remove_long_map_element(lm, keys[r]) != NULL) - { - found++; - if(original_size - found != lm->num_elements) - { - printf("SIZE IS BAD!!!!\n"); - } - } - } - printf("done removing remaining nodes\n"); - printf("tree size is now %ld, and root is %s\n\n", lm->num_elements, lm->root == NULL ? "null" : "not null"); - - free(keys); - - printf("repeating insertion/deletion\n\n"); - } - else - { - unsigned long num_destroyed; - printf("destroying map...\n"); - void** values = destroy_long_map(lm, DESTROY_MODE_RETURN_VALUES, &num_destroyed); - printf("map destroyed.\n"); - int v=0; - for(v=0; values[v] != NULL; v++){} - free(values); - printf("number of values returned after map destruction = %d\n", v); - - } - } - - - printf("LONG MAP TESTING COMPLETE. TESTING STRING MAP (WITH KEY STORAGE) \n\n"); - - - - printf("initializing map....\n"); - string_map* sm = initialize_string_map(1); - printf("initialized!\n\n"); - - - repeat = 0; - for(repeat =0; repeat < num_repeats; repeat++) - { - - printf("randomly inserting %ld integer strings randomly selected (not in order) between 0 and %ld\n", num_insertions, max_insertion); - - - unsigned long i; - unsigned long dupes = 0; - for(i=0; ilm.root->left, &left_depth, 0); - get_max_depth(sm->lm.root->right, &right_depth, 0); - - - unsigned long original_size = sm->num_elements; - printf("insertion complete\n"); - printf("after insertion, tree size = %ld \n", original_size); - printf("(note this may be less than %ld because the same numbers can be selected for insertion more than once, replacing the original node)\n", num_insertions); - printf("dupes = %ld\n", dupes); - printf("depth of left branch = %ld, depth of right branch = %ld\n\n", left_depth, right_depth); - - - if(repeat+1 < num_repeats) - { - printf("randomly selecting %ld numbers between 0 and %ld to remove from tree.\n", num_insertions, max_insertion); - printf("note that these keys will not necessarily be present in tree -- the selection process is entirely random.\n"); - - int j; - int found = 0; - for(j=0; j < num_insertions; j++) - { - unsigned long r = (unsigned long)(max_insertion*((double)rand()/(double)RAND_MAX)); - char* new_str = (char*)malloc(40*sizeof(char)); - sprintf(new_str, "%ld", r); - void* old; - if( (old = remove_string_map_element(sm, new_str)) != NULL) - { - found++; - } - free(new_str); - } - right_depth = 0; - left_depth = 0; - get_max_depth(sm->lm.root->left, &left_depth, 0); - get_max_depth(sm->lm.root->right, &right_depth, 0); - - printf("removal complete\n"); - printf("after removal, tree size = %ld \n", sm->num_elements); - printf("depth of left branch = %ld, depth of right branch = %ld\n", left_depth, right_depth); - if(original_size - found == sm->num_elements) - { - printf("size consistent with number of nodes successfully removed\n\n"); - } - else - { - printf("SIZE IS BAD -- IS NOT CONSISTENT WITH NUMBER OF NODES REMOVED !!!!\n\n"); - } - - printf("removing remaining nodes in tree in random order\n"); - unsigned long length = sm->num_elements; - char** keys = get_string_map_keys(sm, &length); - while(sm->lm.root != NULL && sm->num_elements > 0) - { - unsigned long r = (unsigned long)(length*((double)rand()/(double)RAND_MAX)); - if( remove_string_map_element(sm, keys[r]) != NULL) - { - found++; - if(original_size - found != sm->num_elements) - { - printf("SIZE IS BAD!!!!\n"); - } - } - } - - int k; - for(k=0; knum_elements, sm->lm.root == NULL ? "null" : "not null"); - - printf("repeating insertion/deletion\n\n"); - } - else - { - unsigned long num_destroyed; - printf("destroying map...\n"); - void** values = destroy_string_map(sm, DESTROY_MODE_RETURN_VALUES, &num_destroyed); - printf("map destroyed.\n"); - int v=0; - for(v=0; values[v] != NULL; v++){ } - free(values); - printf("number of values returned after map destruction = %d\n", v); - - - - } - } - - - - - return(0); -} -void get_max_depth(long_map_node* n, unsigned long* max_depth, unsigned long current_depth) -{ - if(n == NULL) - { - *max_depth = current_depth > *max_depth ? current_depth : *max_depth; - return; - } - else - { - *max_depth = current_depth+1 > *max_depth ? current_depth+1 : *max_depth; - get_max_depth(n->left, max_depth, current_depth+1); - get_max_depth(n->right, max_depth, current_depth+1); - } -} -void get_min_depth(long_map_node* n, unsigned long* min_depth, unsigned long current_depth) -{ - if(n == NULL) - { - return; - } - else if(n->left == NULL && n->right == NULL) - { - *min_depth = current_depth < *min_depth ? current_depth : *min_depth; - } - else - { - - get_min_depth(n->left, min_depth, current_depth+1); - get_min_depth(n->right, min_depth, current_depth+1); - } -} - - -void print_map(long_map_node* n, int depth) -{ - if(n == NULL) - { - return; - } - int i; - for(i=0; i < depth; i++){ printf("\t");} - printf("%ld (%d)\n", n->key, n->balance); - for(i=0; i < depth; i++){ printf("\t");} - printf("left:\n"); - print_map(n->left, depth+1); - for(i=0; i < depth; i++){ printf("\t");} - printf("right:\n"); - print_map(n->right, depth+1); -} - diff --git a/package/ctcgfw/libericstools/src/test_string.c b/package/ctcgfw/libericstools/src/test_string.c deleted file mode 100644 index 69cdd201e9..0000000000 --- a/package/ctcgfw/libericstools/src/test_string.c +++ /dev/null @@ -1,26 +0,0 @@ -#include "erics_tools.h" - -int main(void) -{ - FILE* f = fopen("tmp", "r"); - char terminators[] = "\n\r"; - - - unsigned long length; - char* file_data = (char*)read_entire_file(f, 100, &length); - printf("%s\n", file_data); - fclose(f); - - f = fopen("tmp", "r"); - dyn_read_t next; - next.terminator = '\n'; - while(next.terminator != EOF) - { - next = dynamic_read(f, terminators, 2, &length); - printf("read \"%s\"\n", next.str); - free(next.str); - } - fclose(f); - - return 0; -} diff --git a/package/ctcgfw/libericstools/src/tree_map.c b/package/ctcgfw/libericstools/src/tree_map.c deleted file mode 100644 index 24760c63e8..0000000000 --- a/package/ctcgfw/libericstools/src/tree_map.c +++ /dev/null @@ -1,911 +0,0 @@ -/* - * Copyright © 2008 by Eric Bishop - * - * This work 'as-is' we provide. - * No warranty, express or implied. - * We've done our best, - * to debug and test. - * Liability for damages denied. - * - * Permission is granted hereby, - * to copy, share, and modify. - * Use as is fit, - * free or for profit. - * On this notice these rights rely. - * - * - * - * Note that unlike other portions of Gargoyle this code - * does not fall under the GPL, but the rather whimsical - * 'Poetic License' above. - * - * Basically, this library contains a bunch of utilities - * that I find useful. I'm sure other libraries exist - * that are just as good or better, but I like these tools - * because I personally wrote them, so I know their quirks. - * (i.e. I know where the bodies are buried). I want to - * make sure that I can re-use these utilities for whatever - * code I may want to write in the future be it - * proprietary or open-source, so I've put them under - * a very, very permissive license. - * - * If you find this code useful, use it. If not, don't. - * I really don't care. - * - */ - -#include "erics_tools.h" -#define malloc safe_malloc -#define strdup safe_strdup - -/* internal utility structures/ functions */ -typedef struct stack_node_struct -{ - long_map_node** node_ptr; - signed char direction; - struct stack_node_struct* previous; -} stack_node; - -static void** destroy_long_map_values(long_map* map, int destruction_type, unsigned long* num_destroyed); -static void apply_to_every_long_map_node(long_map_node* node, void (*apply_func)(unsigned long key, void* value)); -static void apply_to_every_string_map_node(long_map_node* node, unsigned char has_key, void (*apply_func)(char* key, void* value)); -static void get_sorted_node_keys(long_map_node* node, unsigned long* key_list, unsigned long* next_key_index, int depth); -static void get_sorted_node_values(long_map_node* node, void** value_list, unsigned long* next_value_index, int depth); -static signed char rebalance (long_map_node** n, signed char direction, signed char update_op); -static void rotate_right (long_map_node** parent); -static void rotate_left (long_map_node** parent); - -/* internal for string map */ -typedef struct -{ - char* key; - void* value; -} string_map_key_value; - - -static unsigned long sdbm_string_hash(const char *key); - - -/*************************************************** - * For testing only - ***************************************************/ -/* -void print_list(stack_node *l); - -void print_list(stack_node *l) -{ - if(l != NULL) - { - printf(" list key = %ld, dir=%d, \n", (*(l->node_ptr))->key, l->direction); - print_list(l->previous); - } -} -*/ -/****************************************************** - * End testing Code - *******************************************************/ - - - - -/*************************************************** - * string_map function definitions - ***************************************************/ - -string_map* initialize_string_map(unsigned char store_keys) -{ - string_map* map = (string_map*)malloc(sizeof(string_map)); - map->store_keys = store_keys; - map->lm.root = NULL; - map->lm.num_elements = 0; - map->num_elements = map->lm.num_elements; - - return map; -} - -void* get_string_map_element(string_map* map, const char* key) -{ - unsigned long hashed_key = sdbm_string_hash(key); - void* return_value = get_long_map_element( &(map->lm), hashed_key); - if(return_value != NULL && map->store_keys) - { - string_map_key_value* r = (string_map_key_value*)return_value; - return_value = r->value; - } - map->num_elements = map->lm.num_elements; - return return_value; -} - -void* set_string_map_element(string_map* map, const char* key, void* value) -{ - unsigned long hashed_key = sdbm_string_hash(key); - void* return_value = NULL; - if(map->store_keys) - { - string_map_key_value* kv = (string_map_key_value*)malloc(sizeof(string_map_key_value)); - kv->key = strdup(key); - kv->value = value; - return_value = set_long_map_element( &(map->lm), hashed_key, kv); - if(return_value != NULL) - { - string_map_key_value* r = (string_map_key_value*)return_value; - return_value = r->value; - free(r->key); - free(r); - } - } - else - { - return_value = set_long_map_element( &(map->lm), hashed_key, value); - } - map->num_elements = map->lm.num_elements; - return return_value; -} - -void* remove_string_map_element(string_map* map, const char* key) -{ - unsigned long hashed_key = sdbm_string_hash(key); - void* return_value = remove_long_map_element( &(map->lm), hashed_key); - - if(return_value != NULL && map->store_keys) - { - string_map_key_value* r = (string_map_key_value*)return_value; - return_value = r->value; - free(r->key); - free(r); - } - map->num_elements = map->lm.num_elements; - return return_value; -} - -char** get_string_map_keys(string_map* map, unsigned long* num_keys_returned) -{ - char** str_keys; - str_keys = (char**)malloc((map->num_elements+1)*sizeof(char*)); - str_keys[0] = NULL; - *num_keys_returned = 0; - if(map->store_keys && map->num_elements > 0) - { - unsigned long list_length; - void** long_values = get_sorted_long_map_values( &(map->lm), &list_length); - unsigned long key_index; - for(key_index = 0; key_index < list_length; key_index++) - { - str_keys[key_index] = strdup( ((string_map_key_value*)(long_values[key_index]))->key); - *num_keys_returned = *num_keys_returned + 1; - } - str_keys[list_length] = NULL; - free(long_values); - } - return str_keys; -} - -void** get_string_map_values(string_map* map, unsigned long* num_values_returned) -{ - void** values = NULL; - if(map != NULL) - { - values = get_sorted_long_map_values ( &(map->lm), num_values_returned ); - } - return values; -} - - - -void** destroy_string_map(string_map* map, int destruction_type, unsigned long* num_destroyed) -{ - void** return_values = NULL; - if(map != NULL) - { - if(map->store_keys) - { - void** kvs = destroy_long_map_values( &(map->lm), DESTROY_MODE_RETURN_VALUES, num_destroyed ); - unsigned long kv_index = 0; - for(kv_index=0; kv_index < *num_destroyed; kv_index++) - { - string_map_key_value* kv = (string_map_key_value*)kvs[kv_index]; - void* value = kv->value; - - free(kv->key); - free(kv); - if(destruction_type == DESTROY_MODE_FREE_VALUES) - { - free(value); - } - if(destruction_type == DESTROY_MODE_RETURN_VALUES) - { - kvs[kv_index] = value; - } - } - if(destruction_type == DESTROY_MODE_RETURN_VALUES) - { - return_values = kvs; - } - else - { - free(kvs); - } - } - else - { - return_values = destroy_long_map_values( &(map->lm), destruction_type, num_destroyed ); - } - free(map); - } - return return_values; -} - - - -/*************************************************** - * long_map function definitions - ***************************************************/ - -long_map* initialize_long_map(void) -{ - long_map* map = (long_map*)malloc(sizeof(long_map)); - map->root = NULL; - map->num_elements = 0; - - return map; -} - -void* get_long_map_element(long_map* map, unsigned long key) -{ - void* value = NULL; - - if(map->root != NULL) - { - long_map_node* parent_node = map->root; - long_map_node* next_node; - while( key != parent_node->key && (next_node = (long_map_node *)(key < parent_node->key ? parent_node->left : parent_node->right)) != NULL) - { - parent_node = next_node; - } - if(parent_node->key == key) - { - value = parent_node->value; - } - } - return value; -} - -void* get_smallest_long_map_element(long_map* map, unsigned long* smallest_key) -{ - void* value = NULL; - if(map->root != NULL) - { - long_map_node* next_node = map->root; - while( next_node->left != NULL) - { - next_node = next_node->left; - } - value = next_node->value; - *smallest_key = next_node->key; - } - return value; -} - -void* get_largest_long_map_element(long_map* map, unsigned long* largest_key) -{ - void* value = NULL; - if(map->root != NULL) - { - long_map_node* next_node = map->root; - while( next_node->right != NULL) - { - next_node = next_node->right; - } - value = next_node->value; - *largest_key = next_node->key; - } - return value; -} - -void* remove_smallest_long_map_element(long_map* map, unsigned long* smallest_key) -{ - get_smallest_long_map_element(map, smallest_key); - return remove_long_map_element(map, *smallest_key); -} - -void* remove_largest_long_map_element(long_map* map, unsigned long* largest_key) -{ - get_largest_long_map_element(map, largest_key); - return remove_long_map_element(map, *largest_key); -} - - -/* if replacement performed, returns replaced value, otherwise null */ -void* set_long_map_element(long_map* map, unsigned long key, void* value) -{ - stack_node* parent_list = NULL; - void* old_value = NULL; - int old_value_found = 0; - - long_map_node* parent_node; - long_map_node* next_node; - stack_node* next_parent; - stack_node* previous_parent; - signed char new_balance; - - - long_map_node* new_node = (long_map_node*)malloc(sizeof(long_map_node)); - new_node->value = value; - new_node->key = key; - new_node->left = NULL; - new_node->right = NULL; - new_node->balance = 0; - - - - if(map->root == NULL) - { - map->root = new_node; - } - else - { - parent_node = map->root; - - next_parent = (stack_node*)malloc(sizeof(stack_node)); - next_parent->node_ptr = &(map->root); - next_parent->previous = parent_list; - parent_list = next_parent; - - while( key != parent_node->key && (next_node = (key < parent_node->key ? parent_node->left : parent_node->right) ) != NULL) - { - next_parent = (stack_node*)malloc(sizeof(stack_node)); - next_parent->node_ptr = key < parent_node->key ? &(parent_node->left) : &(parent_node->right); - next_parent->previous = parent_list; - next_parent->previous->direction = key < parent_node->key ? -1 : 1; - parent_list = next_parent; - - parent_node = next_node; - } - - - if(key == parent_node->key) - { - old_value = parent_node->value; - old_value_found = 1; - parent_node->value = value; - free(new_node); - /* we merely replaced a node, no need to rebalance */ - } - else - { - if(key < parent_node->key) - { - parent_node->left = (void*)new_node; - parent_list->direction = -1; - } - else - { - parent_node->right = (void*)new_node; - parent_list->direction = 1; - } - - - /* we inserted a node, rebalance */ - previous_parent = parent_list; - new_balance = 1; /* initial value is not used, but must not be 0 for initial loop condition */ - - - while(previous_parent != NULL && new_balance != 0) - { - new_balance = rebalance(previous_parent->node_ptr, previous_parent->direction, 1); - previous_parent = previous_parent->previous; - } - } - } - - while(parent_list != NULL) - { - previous_parent = parent_list; - parent_list = previous_parent->previous; - free(previous_parent); - } - - if(old_value_found == 0) - { - map->num_elements = map->num_elements + 1; - } - - return old_value; -} - - -void* remove_long_map_element(long_map* map, unsigned long key) -{ - - void* value = NULL; - - long_map_node* root_node = map->root; - stack_node* parent_list = NULL; - - - long_map_node* remove_parent; - long_map_node* remove_node; - long_map_node* next_node; - - long_map_node* replacement; - long_map_node* replacement_parent; - long_map_node* replacement_next; - - stack_node* next_parent; - stack_node* previous_parent; - stack_node* replacement_stack_node; - - - signed char new_balance; - - - - if(root_node != NULL) - { - remove_parent = root_node; - remove_node = key < remove_parent->key ? remove_parent->left : remove_parent->right; - - if(remove_node != NULL && key != remove_parent->key) - { - next_parent = (stack_node*)malloc(sizeof(stack_node)); - next_parent->node_ptr = &(map->root); - next_parent->previous = parent_list; - parent_list = next_parent; - while( key != remove_node->key && (next_node = (key < remove_node->key ? remove_node->left : remove_node->right)) != NULL) - { - next_parent = (stack_node*)malloc(sizeof(stack_node)); - next_parent->node_ptr = key < remove_parent->key ? &(remove_parent->left) : &(remove_parent->right); - next_parent->previous = parent_list; - next_parent->previous->direction = key < remove_parent->key ? -1 : 1; - parent_list = next_parent; - - - remove_parent = remove_node; - remove_node = next_node; - } - parent_list->direction = key < remove_parent-> key ? -1 : 1; - } - else - { - remove_node = remove_parent; - } - - - if(key == remove_node->key) - { - - /* find replacement for node we are deleting */ - if( remove_node->right == NULL ) - { - replacement = remove_node->left; - } - else if( remove_node->right->left == NULL) - { - - replacement = remove_node->right; - replacement->left = remove_node->left; - replacement->balance = remove_node->balance; - - /* put pointer to replacement node into list for balance update */ - replacement_stack_node = (stack_node*)malloc(sizeof(stack_node));; - replacement_stack_node->previous = parent_list; - replacement_stack_node->direction = 1; /* replacement is from right */ - if(remove_node == remove_parent) /* special case for root node */ - { - replacement_stack_node->node_ptr = &(map->root); - } - else - { - replacement_stack_node->node_ptr = key < remove_parent-> key ? &(remove_parent->left) : &(remove_parent->right); - } - parent_list = replacement_stack_node; - - } - else - { - /* put pointer to replacement node into list for balance update */ - replacement_stack_node = (stack_node*)malloc(sizeof(stack_node)); - replacement_stack_node->previous = parent_list; - replacement_stack_node->direction = 1; /* we always look for replacement on right */ - if(remove_node == remove_parent) /* special case for root node */ - { - replacement_stack_node->node_ptr = &(map->root); - } - else - { - replacement_stack_node->node_ptr = key < remove_parent-> key ? &(remove_parent->left) : &(remove_parent->right); - } - - parent_list = replacement_stack_node; - - - /* - * put pointer to replacement node->right into list for balance update - * this node will have to be updated with the proper pointer - * after we have identified the replacement - */ - replacement_stack_node = (stack_node*)malloc(sizeof(stack_node)); - replacement_stack_node->previous = parent_list; - replacement_stack_node->direction = -1; /* we always look for replacement to left of this node */ - parent_list = replacement_stack_node; - - /* find smallest node on right (large) side of tree */ - replacement_parent = remove_node->right; - replacement = replacement_parent->left; - - while((replacement_next = replacement->left) != NULL) - { - next_parent = (stack_node*)malloc(sizeof(stack_node)); - next_parent->node_ptr = &(replacement_parent->left); - next_parent->previous = parent_list; - next_parent->direction = -1; /* we always go left */ - parent_list = next_parent; - - replacement_parent = replacement; - replacement = replacement_next; - - } - - replacement_parent->left = replacement->right; - - replacement->left = remove_node->left; - replacement->right = remove_node->right; - replacement->balance = remove_node->balance; - replacement_stack_node->node_ptr = &(replacement->right); - } - - /* insert replacement at proper location in tree */ - if(remove_node == remove_parent) - { - map->root = replacement; - } - else - { - remove_parent->left = remove_node == remove_parent->left ? replacement : remove_parent->left; - remove_parent->right = remove_node == remove_parent->right ? replacement : remove_parent->right; - } - - - /* rebalance tree */ - previous_parent = parent_list; - new_balance = 0; - while(previous_parent != NULL && new_balance == 0) - { - new_balance = rebalance(previous_parent->node_ptr, previous_parent->direction, -1); - previous_parent = previous_parent->previous; - } - - - - - /* - * since we found a value to remove, decrease number of elements in map - * set return value to the deleted node's value and free the node - */ - map->num_elements = map->num_elements - 1; - value = remove_node->value; - free(remove_node); - } - } - - - while(parent_list != NULL) - { - previous_parent = parent_list; - parent_list = previous_parent->previous; - free(previous_parent); - } - - return value; -} - - -/* note: returned keys are dynamically allocated, you need to free them! */ -unsigned long* get_sorted_long_map_keys(long_map* map, unsigned long* num_keys_returned) -{ - unsigned long* key_list = (unsigned long*)malloc((map->num_elements)*sizeof(unsigned long)); - - unsigned long next_key_index = 0; - get_sorted_node_keys(map->root, key_list, &next_key_index, 0); - - *num_keys_returned = map->num_elements; - - return key_list; -} - - -void** get_sorted_long_map_values(long_map* map, unsigned long* num_values_returned) -{ - void** value_list = (void**)malloc((map->num_elements+1)*sizeof(void*)); - - unsigned long next_value_index = 0; - get_sorted_node_values(map->root, value_list, &next_value_index, 0); - value_list[map->num_elements] = NULL; /* since we're dealing with pointers make list null terminated */ - - *num_values_returned = map->num_elements; - return value_list; - -} - - -void** destroy_long_map(long_map* map, int destruction_type, unsigned long* num_destroyed) -{ - void** return_values = NULL; - unsigned long return_index = 0; - - *num_destroyed = 0; - - if(destruction_type == DESTROY_MODE_RETURN_VALUES) - { - return_values = (void**)malloc((map->num_elements+1)*sizeof(void*)); - return_values[map->num_elements] = NULL; - } - while(map->num_elements > 0) - { - unsigned long smallest_key = 0; - void* removed_value = remove_smallest_long_map_element(map, &smallest_key); - if(destruction_type == DESTROY_MODE_RETURN_VALUES) - { - return_values[return_index] = removed_value; - } - if(destruction_type == DESTROY_MODE_FREE_VALUES) - { - free(removed_value); - } - return_index++; - *num_destroyed = *num_destroyed + 1; - } - free(map); - - return return_values; -} - -void apply_to_every_long_map_value(long_map* map, void (*apply_func)(unsigned long key, void* value)) -{ - apply_to_every_long_map_node(map->root, apply_func); -} -void apply_to_every_string_map_value(string_map* map, void (*apply_func)(char* key, void* value)) -{ - apply_to_every_string_map_node( (map->lm).root, map->store_keys, apply_func); -} - - -/*************************************************** - * internal utility function definitions - ***************************************************/ -static void** destroy_long_map_values(long_map* map, int destruction_type, unsigned long* num_destroyed) -{ - void** return_values = NULL; - unsigned long return_index = 0; - - *num_destroyed = 0; - - if(destruction_type == DESTROY_MODE_RETURN_VALUES) - { - return_values = (void**)malloc((map->num_elements+1)*sizeof(void*)); - return_values[map->num_elements] = NULL; - } - while(map->num_elements > 0) - { - unsigned long smallest_key = 0; - void* removed_value = remove_smallest_long_map_element(map, &smallest_key); - if(destruction_type == DESTROY_MODE_RETURN_VALUES) - { - return_values[return_index] = removed_value; - } - if(destruction_type == DESTROY_MODE_FREE_VALUES) - { - free(removed_value); - } - return_index++; - *num_destroyed = *num_destroyed + 1; - } - return return_values; -} - -static void apply_to_every_long_map_node(long_map_node* node, void (*apply_func)(unsigned long key, void* value)) -{ - if(node != NULL) - { - apply_to_every_long_map_node(node->left, apply_func); - - apply_func(node->key, node->value); - - apply_to_every_long_map_node(node->right, apply_func); - } -} -static void apply_to_every_string_map_node(long_map_node* node, unsigned char has_key, void (*apply_func)(char* key, void* value)) -{ - if(node != NULL) - { - apply_to_every_string_map_node(node->left, has_key, apply_func); - - if(has_key) - { - string_map_key_value* kv = (string_map_key_value*)(node->value); - apply_func(kv->key, kv->value); - } - else - { - apply_func(NULL, node->value); - } - apply_to_every_string_map_node(node->right, has_key, apply_func); - } -} - - -static void get_sorted_node_keys(long_map_node* node, unsigned long* key_list, unsigned long* next_key_index, int depth) -{ - if(node != NULL) - { - get_sorted_node_keys(node->left, key_list, next_key_index, depth+1); - - key_list[ *next_key_index ] = node->key; - (*next_key_index)++; - - get_sorted_node_keys(node->right, key_list, next_key_index, depth+1); - } -} - -static void get_sorted_node_values(long_map_node* node, void** value_list, unsigned long* next_value_index, int depth) -{ - if(node != NULL) - { - get_sorted_node_values(node->left, value_list, next_value_index, depth+1); - - value_list[ *next_value_index ] = node->value; - (*next_value_index)++; - - get_sorted_node_values(node->right, value_list, next_value_index, depth+1); - } -} - - - -/* - * direction = -1 indicates left subtree updated, direction = 1 for right subtree - * update_op = -1 indicates delete node, update_op = 1 for insert node - */ -static signed char rebalance (long_map_node** n, signed char direction, signed char update_op) -{ - /* - printf( "original: key = %ld, balance = %d, update_op=%d, direction=%d\n", (*n)->key, (*n)->balance, update_op, direction); - */ - - (*n)->balance = (*n)->balance + (update_op*direction); - - if( (*n)->balance < -1) - { - if((*n)->left->balance < 0) - { - rotate_right(n); - (*n)->right->balance = 0; - (*n)->balance = 0; - } - else if((*n)->left->balance == 0) - { - rotate_right(n); - (*n)->right->balance = -1; - (*n)->balance = 1; - } - else if((*n)->left->balance > 0) - { - rotate_left( &((*n)->left) ); - rotate_right(n); - /* - if( (*n)->balance < 0 ) - { - (*n)->left->balance = 0; - (*n)->right->balance = 1; - } - else if( (*n)->balance == 0 ) - { - (*n)->left->balance = 0; - (*n)->right->balance = 0; - } - else if( (*n)->balance > 0 ) - { - (*n)->left->balance = -1; - (*n)->right->balance = 0; - } - */ - (*n)->left->balance = (*n)->balance > 0 ? -1 : 0; - (*n)->right->balance = (*n)->balance < 0 ? 1 : 0; - (*n)->balance = 0; - } - } - if( (*n)->balance > 1) - { - if((*n)->right->balance > 0) - { - rotate_left(n); - (*n)->left->balance = 0; - (*n)->balance = 0; - } - else if ((*n)->right->balance == 0) - { - rotate_left(n); - (*n)->left->balance = 1; - (*n)->balance = -1; - } - else if((*n)->right->balance < 0) - { - rotate_right( &((*n)->right) ); - rotate_left(n); - /* - if( (*n)->balance < 0 ) - { - (*n)->left->balance = 0; - (*n)->right->balance = 1; - } - else if( (*n)->balance == 0 ) - { - (*n)->left->balance = 0; - (*n)->right->balance = 0; - } - else if( (*n)->balance > 0 ) - { - (*n)->left->balance = -1; - (*n)->right->balance = 0; - } - */ - (*n)->left->balance = (*n)->balance > 0 ? -1 : 0; - (*n)->right->balance = (*n)->balance < 0 ? 1 : 0; - (*n)->balance = 0; - } - } - - /* - printf( "key = %ld, balance = %d\n", (*n)->key, (*n)->balance); - */ - - return (*n)->balance; -} - - -static void rotate_right (long_map_node** parent) -{ - long_map_node* old_parent = *parent; - long_map_node* pivot = old_parent->left; - old_parent->left = pivot->right; - pivot->right = old_parent; - - *parent = pivot; -} - -static void rotate_left (long_map_node** parent) -{ - long_map_node* old_parent = *parent; - long_map_node* pivot = old_parent->right; - old_parent->right = pivot->left; - pivot->left = old_parent; - - *parent = pivot; -} - - - -/*************************************************************************** - * This algorithm was created for the sdbm database library (a public-domain - * reimplementation of ndbm) and seems to work relatively well in - * scrambling bits - * - * - * This code was derived from code found at: - * http://www.cse.yorku.ca/~oz/hash.html - ***************************************************************************/ -static unsigned long sdbm_string_hash(const char *key) -{ - unsigned long hashed_key = 0; - - int index = 0; - unsigned int nextch; - while(key[index] != '\0') - { - nextch = key[index]; - hashed_key = nextch + (hashed_key << 6) + (hashed_key << 16) - hashed_key; - index++; - } - return hashed_key; -} - diff --git a/package/ctcgfw/libiptbwctl/Makefile b/package/ctcgfw/libiptbwctl/Makefile deleted file mode 100644 index 681e55d750..0000000000 --- a/package/ctcgfw/libiptbwctl/Makefile +++ /dev/null @@ -1,83 +0,0 @@ -# -# Copyright (C) 2006 OpenWrt.org -# Copyright (C) 2009 Eric Bishop -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=libiptbwctl -PKG_VERSION:=$(GARGOYLE_VERSION) -ifeq ($(GARGOYLE_VERSION),) - PKG_VERSION:=1.0.0 -endif -PKG_RELEASE:=1 - -PKG_BUILD_DIR:=$(BUILD_DIR)/libiptbwctl - -include $(INCLUDE_DIR)/package.mk - -define Package/libiptbwctl - SECTION:=net - CATEGORY:=Network - DEPENDS:=+iptables-mod-bandwidth - TITLE:=IPT bandwidth control library - URL:=http://www.gargoyle-router.com - MAINTAINER:=Eric Bishop -endef - - -define Package/libiptbwctl/description - IPT bandwidth control library -endef - - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) - $(CP) ./src/* $(PKG_BUILD_DIR)/ -endef - - -define Build/Configure -endef - -define Build/Compile - -$(MAKE) -C $(PKG_BUILD_DIR) clean - $(MAKE) -C $(PKG_BUILD_DIR) \ - $(TARGET_CONFIGURE_OPTS) \ - STAGING_DIR="$(STAGING_DIR)" \ - CFLAGS="$(TARGET_CFLAGS) -I $(STAGING_DIR)/usr/include" \ - LDFLAGS="$(TARGET_LDFLAGS) -L $(STAGING_DIR)/usr/lib" \ - all - - mkdir -p $(STAGING_DIR)/usr/include/ - $(CP) $(PKG_BUILD_DIR)/*.h $(STAGING_DIR)/usr/include/ - - mkdir -p $(STAGING_DIR)/usr/lib - $(CP) $(PKG_BUILD_DIR)/*.so* $(STAGING_DIR)/usr/lib/ - - $(MAKE) -C $(PKG_BUILD_DIR)/utils \ - $(TARGET_CONFIGURE_OPTS) \ - STAGING_DIR="$(STAGING_DIR)" \ - CFLAGS="$(TARGET_CFLAGS) -I $(STAGING_DIR)/usr/include" \ - LDFLAGS="$(TARGET_LDFLAGS) -L $(STAGING_DIR)/usr/lib" \ - all -endef - - - -define Package/libiptbwctl/install - $(INSTALL_DIR) $(1)/usr/lib - $(INSTALL_DIR) $(1)/usr/bin - $(CP) $(PKG_BUILD_DIR)/*.so* $(1)/usr/lib/ - $(INSTALL_BIN) $(PKG_BUILD_DIR)/utils/bw_get $(1)/usr/bin/bw_get - $(INSTALL_BIN) $(PKG_BUILD_DIR)/utils/bw_set $(1)/usr/bin/bw_set - $(INSTALL_BIN) $(PKG_BUILD_DIR)/utils/bw_print_history_file $(1)/usr/bin/bw_print_history_file - $(INSTALL_BIN) $(PKG_BUILD_DIR)/utils/set_kernel_timezone $(1)/usr/bin/set_kernel_timezone -endef - - -$(eval $(call BuildPackage,libiptbwctl)) - diff --git a/package/ctcgfw/libiptbwctl/src/Makefile b/package/ctcgfw/libiptbwctl/src/Makefile deleted file mode 100644 index 5306846620..0000000000 --- a/package/ctcgfw/libiptbwctl/src/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -VERSION=1 - - -ifeq ($(CC),) - CC=gcc -endif - -ifeq ($(LD),) - LD=ld -endif - -ifeq ($(AR),) - AR=ar -endif - -ifeq ($(RANLIB),) - RANLIB=ranlib -endif - - - -OS=$(shell uname) -ifeq ($(OS),Darwin) - LINK=$(LD) - SHLIB_EXT=dylib - SHLIB_FLAGS=-dylib - SHLIB_FILE=libiptbwctl.$(SHLIB_EXT).$(VERSION) -else - LINK=$(CC) - SHLIB_EXT=so - SHLIB_FILE=libiptbwctl.$(SHLIB_EXT).$(VERSION) - SHLIB_FLAGS=-shared -Wl,-soname,$(SHLIB_FILE) -endif - -CFLAGS:=$(CFLAGS) -Os -WARNING_FLAGS=-Wall -Wstrict-prototypes - - - -all: libiptbwctl - -libiptbwctl: libiptbwctl.$(SHLIB_EXT) libiptbwctl.a - - -libiptbwctl.a: ipt_bwctl_static.o ipt_bwctl_safe_malloc_static.o - if [ -e $@ ] ; then rm $@ ; fi - $(AR) rc $@ $^ - $(RANLIB) $@ - - -libiptbwctl.$(SHLIB_EXT) : ipt_bwctl_dyn.o ipt_bwctl_safe_malloc_dyn.o - if [ -e libiptbwctl.$(SHLIB_EXT) ] ; then rm libiptbwctl.$(SHLIB_EXT)* ; fi - $(LINK) $(LDFLAGS) $(SHLIB_FLAGS) -o $(SHLIB_FILE) $^ -lc - ln -s $(SHLIB_FILE) libiptbwctl.$(SHLIB_EXT) - -%_dyn.o: %.c - $(CC) $(CFLAGS) -fPIC $(WARNING_FLAGS) -o $@ -c $^ - -%_static.o: %.c - $(CC) $(CFLAGS) $(WARNING_FLAGS) -o $@ -c $^ - - - - -clean: - cd utils - rm -rf bw_get bw_set *.a *.o *~ .*sw* - cd .. - if [ -n "$(SHLIB_EXT)" ] ; then rm -rf *.$(SHLIB_EXT)* ; fi - rm -rf *.a *.o *~ .*sw* diff --git a/package/ctcgfw/libiptbwctl/src/ipt_bwctl.c b/package/ctcgfw/libiptbwctl/src/ipt_bwctl.c deleted file mode 100644 index 27f33a2ab5..0000000000 --- a/package/ctcgfw/libiptbwctl/src/ipt_bwctl.c +++ /dev/null @@ -1,1349 +0,0 @@ -/* libiptbwctl -- A userspace library for querying the bandwidth iptables module - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include "ipt_bwctl.h" -#define malloc ipt_bwctl_safe_malloc -#define strdup ipt_bwctl_safe_strdup - - -static int bandwidth_semaphore = -1; - -union semun -{ - int val; // Value for SETVAL - struct semid_ds *buf; // Buffer for IPC_STAT, IPC_SET - unsigned short *array; // Array for GETALL, SETALL - struct seminfo *__buf; // Buffer for IPC_INFO (Linux specific) -}; - - - - -/* semaphore functions */ -static int get_sem_val(int sid, int member); -static int get_sem(int *sid, key_t key); -static int lock_sem(int sid); -static int unlock_sem(int sid); -static int lock(unsigned long max_wait_milliseconds); -static int unlock(void); - - -/* needed to calculate history time intervals */ -static time_t get_next_node_start_time( time_t current_start_time, - time_t reset_interval, - time_t reset_time, - unsigned char is_constant_interval - ); - -/* functions used to get data from kernel module */ -static void parse_returned_ip_data( void *out_data, - uint32_t* out_index, - unsigned char* in_buffer, - uint32_t* in_index, - unsigned char get_history, - time_t reset_interval, - time_t reset_time, - unsigned char is_constant_interval - ); - -static int get_bandwidth_data( char* id, - unsigned char get_history, - char* ip, - unsigned long* num_ips, - void** data, - unsigned long max_wait_milliseconds - ); - - -/* functions used to send/restore data to kernel module */ -static int set_ip_block( void* ip_block_data, - unsigned char is_history, - unsigned char* output_buffer, - uint32_t* current_output_index, - uint32_t output_buffer_length - ); - -static int set_bandwidth_data( char* id, - unsigned char zero_unset, - unsigned char set_history, - unsigned long num_ips, - time_t last_backup, - void* data, - unsigned long max_wait_milliseconds - ); - -/* utility i/o functions when saving/restoring data to/from file */ -static unsigned char* read_entire_file( FILE* in, - unsigned long read_block_size, - unsigned long *length - ); - -static char** split_on_separators( char* line, - char* separators, - int num_separators, - int max_pieces, - int include_remainder_at_max, - unsigned long *pieces_read - ); - - - -static int get_sem_val(int sid, int member) -{ - int semval; - semval = semctl(sid, member, GETVAL, 0); - return(semval); -} - -static int get_sem(int *sid, key_t key) -{ - int cntr; - union semun semopts; - int members = 1; - - - int success = ((*sid = semget(key, members, IPC_CREAT|IPC_EXCL|0777))== -1) ? 0 : 1; - if(success) - { - semopts.val = 1; - /* Initialize all members (could be done with SETALL) */ - for(cntr=0; cntr 0) - { - sem_lock.sem_num = member; - if((semop(sid, &sem_lock, 1)) != -1) - { - success = 1; - } - } - - return success; -} - -static int unlock_sem(int sid) -{ - int member = 0; - struct sembuf sem_unlock={ member, 1, IPC_NOWAIT}; - - /* will fail if we can't can't unlock semaphore for some reason, - * will NOT fail if semaphore is already unlocked - */ - int success = 1; - - - /* Is the semaphore set locked? */ - int semval = get_sem_val(sid, member); - if(semval == 0) - { - /* it's locked, unlock it */ - sem_unlock.sem_num = member; - success = ((semop(sid, &sem_unlock, 1)) == -1) ? 0 : 1; - } - return success; -} - - - -static int lock(unsigned long max_wait_milliseconds) -{ - int locked = 0; - if(bandwidth_semaphore == -1) - { - get_sem(&bandwidth_semaphore, (key_t)(BANDWIDTH_SEMAPHORE_KEY) ); - } - if(bandwidth_semaphore != -1) - { - do - { - locked = lock_sem(bandwidth_semaphore); - if(locked == 0 && max_wait_milliseconds > 25) - { - usleep(1000*25); - } - max_wait_milliseconds = max_wait_milliseconds > 25 ? max_wait_milliseconds - 25 : 0; - } while(locked == 0 && max_wait_milliseconds > 0); - } - return locked; -} - -static int unlock(void) -{ - int unlocked = 0; - if(bandwidth_semaphore == -1) - { - get_sem(&bandwidth_semaphore, (key_t)(BANDWIDTH_SEMAPHORE_KEY) ); - } - if(bandwidth_semaphore != -1) - { - unlocked = unlock_sem(bandwidth_semaphore); - } - return unlocked; - -} - - -static time_t get_next_node_start_time( time_t current_start_time, - time_t reset_interval, - time_t reset_time, - unsigned char is_constant_interval - ) -{ - time_t next = current_start_time; - if(is_constant_interval) - { - next = current_start_time + reset_interval; - } - else - { - while(next + reset_time <= current_start_time) - { - struct tm* curr = localtime(¤t_start_time); - curr->tm_isdst = -1; - if(reset_interval == BANDWIDTH_MINUTE) - { - curr->tm_sec = 0; - curr->tm_min = curr->tm_min+1; - next = mktime(curr); - } - else if(reset_interval == BANDWIDTH_HOUR) - { - curr->tm_sec = 0; - curr->tm_min = 0; - curr->tm_hour = curr->tm_hour+1; - next = mktime(curr); - } - else if(reset_interval == BANDWIDTH_DAY) - { - curr->tm_sec = 0; - curr->tm_min = 0; - curr->tm_hour = 0; - curr->tm_mday = curr->tm_mday+1; - next = mktime(curr); - } - else if(reset_interval == BANDWIDTH_WEEK) - { - curr->tm_sec = 0; - curr->tm_min = 0; - curr->tm_hour = 0; - curr->tm_mday = curr->tm_mday+1; - time_t tmp = mktime(curr); - curr = localtime(&tmp); - while(curr->tm_wday != 0) - { - curr->tm_mday=curr->tm_mday+1; - tmp = mktime(curr); - curr = localtime(&tmp); - } - next = mktime(curr); - } - else if(reset_interval == BANDWIDTH_MONTH) - { - curr->tm_sec = 0; - curr->tm_min = 0; - curr->tm_hour = 0; - curr->tm_mday = 1; - curr->tm_mon = curr->tm_mon+1; - next = mktime(curr); - } - } - next = next + reset_time; - } - return next; -} - -static void parse_returned_ip_data( void *out_data, - uint32_t* out_index, - unsigned char* in_buffer, - uint32_t* in_index, - unsigned char get_history, - time_t reset_interval, - time_t reset_time, - unsigned char is_constant_interval - ) -{ - uint32_t ip = *( (uint32_t*)(in_buffer + *in_index) ); - ip_bw_kernel_data_item* ip_bw_data = (ip_bw_kernel_data*)(in_buffer + *in_index); - if(get_history == 0) - { - (((ip_bw*)out_data)[*out_index]).ip = ip; - *in_index = *in_index + 4; - (((ip_bw*)out_data)[*out_index]).bw = *( (uint64_t*)(in_buffer + *in_index) ); - *in_index = *in_index + 8; - } - else - { - ip_bw_history *history = ((ip_bw_history*)out_data) + *out_index; - history->reset_interval = reset_interval; - history->reset_time = reset_time; - history->is_constant_interval = is_constant_interval; - - history->ip = ip_bw_data->ip; - history->num_nodes = ip_bw_data->num_nodes; - history->first_start = ip_bw_data->first_start; - history->first_end = ip_bw_data->first_end; - history->last_end = ip_bw_data->last_end; - - history->history_bws = (uint64_t*)malloc( (history->num_nodes+1)*sizeof(uint64_t) ); - - /* read bws */ - int node_index = 0; - *in_index += 32; - for (node_index = 0; node_index < history->num_nodes; node_index++) - { - *in_index += 8; - (history->history_bws)[node_index] = ip_bw_data->ipbw_data[node_index]; - } - - - /* - * We now need to deal with DST - * - * The problem is that the kernel can't tell the difference - * between timezones being switched and entering daylight savings - * time. Whenever the time offset from UTC shifts, the kernel module - * shifts values in the bandwidth history to reflect the time - * as it would be if the current offset from UTC had always been - * in effect. So, we need to go backwards through the history and - * anytime we go from DST to non-DST (or visa-versa) implement a - * shift so that returned times reflect reality. - */ - time_t now; - time(&now); - int current_minutes_west = get_minutes_west(now); - history->first_start = history->first_start + (60*(get_minutes_west(history->first_start)-current_minutes_west)); - history->first_end = history->first_end + (60*(get_minutes_west(history->first_end)-current_minutes_west)); - history->last_end = history->last_end + (60*(get_minutes_west(history->last_end)-current_minutes_west)); - } - *out_index = *out_index + 1; -} - - -static int get_bandwidth_data(char* id, unsigned char get_history, char* ip, unsigned long* num_ips, void** data, unsigned long max_wait_milliseconds) -{ - - unsigned char buf[BANDWIDTH_QUERY_LENGTH]; - memset(buf, '\0', BANDWIDTH_QUERY_LENGTH); - int done = 0; - ip_bw_kernel_data* ip_bw_data = (ip_bw_kernel_data*)(buf); - - *data = NULL; - *num_ips = 0; - - - int got_lock = lock(max_wait_milliseconds); - int sockfd = -1; - if(got_lock) - { - sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); - } - - - uint32_t* request_ip = (uint32_t*)buf; - uint32_t* request_index = (uint32_t*)(buf + 4); - unsigned char* request_history =(unsigned char*)(buf + 8); - char* request_id = (char*)(buf+9); - - if(strcmp(ip, "ALL") == 0) - { - *request_ip = 0; - } - else - { - struct in_addr addr; - inet_aton(ip, &addr); - *request_ip = (uint32_t)addr.s_addr; - } - *request_index = 0; - *request_history = get_history; - sprintf(request_id, "%s", id); - - unsigned char error = 0; - unsigned char data_initialized = 0; - uint32_t data_index = 0; - uint32_t next_request_index = 0; - - while(!done && sockfd >= 0 && got_lock) - { - uint32_t size = BANDWIDTH_QUERY_LENGTH; - getsockopt(sockfd, IPPROTO_IP, BANDWIDTH_GET, buf, &size); - error = (unsigned char)buf[0]; - if(error != 0) - { - done = 1; - } - else - { - uint32_t total_ips = ip_bw_data->ip_total; - /*uint32_t next_ip_index = *( (uint32_t*)(buf+5) ); //unused */ - uint32_t response_ips = ip_bw_data->ip_num; - time_t reset_interval = ip_bw_data->reset_interval; - time_t reset_time = ip_bw_data->reset_time; - unsigned char is_constant_interval = ip_bw_data->reset_is_constant_interval; - - if(!data_initialized) - { - *num_ips = total_ips; - if(get_history) - { - *data = (void*)malloc(sizeof(ip_bw_history)*(total_ips+1)); - memset(*data, 0, sizeof(ip_bw_history)*(total_ips+1)); - } - else - { - *data = (void*)malloc(sizeof(ip_bw)*(total_ips+1)); - memset(*data, 0, sizeof(ip_bw)*(total_ips+1)); - } - data_initialized = 1; - } - - int response_index=0; - uint32_t buffer_index = 30; - for(response_index=0; response_index < response_ips; response_index++) - { - parse_returned_ip_data(*data, &data_index, buf, &buffer_index, get_history, reset_interval, reset_time, is_constant_interval); - } - next_request_index = next_request_index + response_ips; - done = next_request_index < total_ips ? 0 : 1; - if(!done) - { - memset(buf, '\0', BANDWIDTH_QUERY_LENGTH); - - if(strcmp(ip, "ALL") == 0) - { - *request_ip = 0; - } - else - { - struct in_addr addr; - inet_aton(ip, &addr); - *request_ip = (uint32_t)addr.s_addr; - } - *request_index = next_request_index; - *request_history = get_history; - sprintf(request_id, "%s", id); - } - } - } - if( (error != 0) && data_initialized) - { - if(get_history) - { - free_ip_bw_histories( (ip_bw_history*)(*data), *num_ips ); - } - else - { - free(*data); - } - *data = NULL; - *num_ips = 0; - } - - if(sockfd >= 0) - { - close(sockfd); - } - if(got_lock) - { - unlock(); - } - - return got_lock && (error == 0); -} - - -static int set_ip_block(void* ip_block_data, unsigned char is_history, unsigned char* output_buffer, uint32_t* current_output_index, uint32_t output_buffer_length) -{ - if(is_history) - { - ip_bw_history* history = (ip_bw_history*)ip_block_data; - uint32_t block_length = (2*4) + (3*8) + (8*history->num_nodes); - if(*current_output_index + block_length > output_buffer_length) - { - return 1; - } - - *( (uint32_t*)(output_buffer + *current_output_index) ) = history->ip; - *current_output_index = *current_output_index + 4; - - *( (uint32_t*)(output_buffer + *current_output_index) ) = history->num_nodes; - *current_output_index = *current_output_index + 4; - - - /* - * We now need to deal with DST - * - * The problem is that the kernel module can't tell the difference - * between timezones being switched and entering daylight savings - * time. Whenever the time offset from UTC shifts, the kernel module - * shifts values in the bandwidth history to reflect the time - * as it would be if the current offset from UTC had always been - * in effect. In order to keep all data in the kernel module - * consistent we need to make sure values we send kernel module - * are adjusted for current offset from UTC, not the real one, - * where the offset may be inconsistent because of DST. - * - * Also note we ignore all but the first, second and last values in the - * history time list. These are the only values the kernel needs/uses. - * We have the whole list in the structure so that we don't have to make - * programs that deal with the library worry about the conversion when - * values are returned. However, when setting data, it's perfectly ok - * to just have the three necessary values and set everything else to zero - */ - time_t first_start = history->first_start; - time_t first_end = history->first_end; - time_t last_end = history->last_end; - - time_t now; - time(&now); - int current_minutes_west = get_minutes_west(now); - first_start = first_start + (get_minutes_west(first_start)-current_minutes_west); - first_end = first_end + (get_minutes_west(first_end)-current_minutes_west); - last_end = last_end + (get_minutes_west(last_end)-current_minutes_west); - - - *( (uint64_t*)(output_buffer + *current_output_index) ) = (uint64_t)first_start; - *current_output_index = *current_output_index + 8; - - *( (uint64_t*)(output_buffer + *current_output_index) ) = (uint64_t)first_end; - *current_output_index = *current_output_index + 8; - - *( (uint64_t*)(output_buffer + *current_output_index) ) = (uint64_t)last_end; - *current_output_index = *current_output_index + 8; - - uint32_t node_num = 0; - for(node_num=0; node_num < history->num_nodes; node_num++) - { - *( (uint64_t*)(output_buffer + *current_output_index) ) = (history->history_bws)[ node_num ]; - *current_output_index = *current_output_index + 8; - } - } - else - { - if(*current_output_index + 12 > output_buffer_length) - { - return 1; - } - - - ip_bw* ib = (ip_bw*)ip_block_data; - *( (uint32_t*)(output_buffer + *current_output_index) ) = ib->ip; - *current_output_index = *current_output_index + 4; - *( (uint64_t*)(output_buffer + *current_output_index) ) = ib->bw; - - /* - struct in_addr addr; - addr.s_addr = ib->ip; - printf("setting ip = %s, ip index = %ld\n", inet_ntoa(addr), (*current_output_index)-4); - printf("setting bw = %lld, bw_index = %ld\n", ib->bw, *current_output_index); - */ - - *current_output_index = *current_output_index + 8; - } - return 0; -} - -static int set_bandwidth_data(char* id, unsigned char zero_unset, unsigned char set_history, unsigned long num_ips, time_t last_backup, void* data, unsigned long max_wait_milliseconds) -{ - unsigned char buf[BANDWIDTH_QUERY_LENGTH]; - memset(buf, 0, BANDWIDTH_QUERY_LENGTH); - int done = 0; - - - int got_lock = lock(max_wait_milliseconds); - int sockfd = -1; - if(got_lock) - { - sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); - } - - uint32_t* total_ips = (uint32_t*)(buf+0); - uint32_t* next_ip_index = (uint32_t*)(buf+4); - uint32_t* num_ips_in_buffer = (uint32_t*)(buf+8); - unsigned char* history_included = (unsigned char*)(buf+12); - unsigned char* zero_unset_ips = (unsigned char*)(buf+13); - uint64_t* last_backup_time = (uint64_t*)(buf+14); - unsigned char* set_id = (unsigned char*)(buf+22); - - - *total_ips = num_ips; - *next_ip_index = 0; - *num_ips_in_buffer = 0; - *history_included = set_history; - *zero_unset_ips = zero_unset; - *last_backup_time = (uint64_t)last_backup; - strncpy(set_id, id, BANDWIDTH_MAX_ID_LENGTH); - set_id[BANDWIDTH_MAX_ID_LENGTH-1] = '\0'; - - while(!done && sockfd >= 0 && got_lock) - { - uint32_t buf_index = (3*4) + (2*1) + 8 + BANDWIDTH_MAX_ID_LENGTH; - uint32_t ip_index = *next_ip_index; - unsigned char buffer_full = 0; - memset( (buf + buf_index), 0, (BANDWIDTH_QUERY_LENGTH-buf_index) ); - *num_ips_in_buffer = 0; - done = (ip_index >= *total_ips); - - - while( (!buffer_full) && (!done) ) - { - void *next_data = set_history ? (void*)(((ip_bw_history*)data) + ip_index) : (void*)(((ip_bw*)data) + ip_index); - buffer_full = set_ip_block(next_data , set_history, buf, &buf_index, BANDWIDTH_QUERY_LENGTH); - ip_index = buffer_full ? ip_index : ip_index+1; - *num_ips_in_buffer = buffer_full ? *num_ips_in_buffer : *num_ips_in_buffer + 1; - done = (ip_index >= *total_ips); - - } - setsockopt(sockfd, IPPROTO_IP, BANDWIDTH_SET, buf, BANDWIDTH_QUERY_LENGTH); - - *next_ip_index = ip_index; - } - if(sockfd >= 0) - { - close(sockfd); - } - if(got_lock) - { - unlock(); - } - return got_lock; -} - -static unsigned char* read_entire_file(FILE* in, unsigned long read_block_size, unsigned long *length) -{ - int max_read_size = read_block_size; - unsigned char* read_string = (unsigned char*)malloc(max_read_size+1); - unsigned long bytes_read = 0; - int end_found = 0; - while(end_found == 0) - { - int nextch = '?'; - while(nextch != EOF && bytes_read < max_read_size) - { - nextch = fgetc(in); - if(nextch != EOF) - { - read_string[bytes_read] = (unsigned char)nextch; - bytes_read++; - } - } - read_string[bytes_read] = '\0'; - end_found = (nextch == EOF) ? 1 : 0; - if(end_found == 0) - { - unsigned char *new_str; - max_read_size = max_read_size + read_block_size; - new_str = (unsigned char*)malloc(max_read_size+1); - memcpy(new_str, read_string, bytes_read); - free(read_string); - read_string = new_str; - } - } - *length = bytes_read; - return read_string; -} - -/* - * line is the line to be parsed -- it is not modified in any way - * max_pieces indicates number of pieces to return, if negative this is determined dynamically - * include_remainder_at_max indicates whether the last piece, when max pieces are reached, - * should be what it would normally be (0) or the entire remainder of the line (1) - * if max_pieces < 0 this parameter is ignored - * - * - * returns all non-separator pieces in a line - * result is dynamically allocated, MUST be freed after call-- even if - * line is empty (you still get a valid char** pointer to to a NULL char*) - */ -static char** split_on_separators(char* line, char* separators, int num_separators, int max_pieces, int include_remainder_at_max, unsigned long *pieces_read) -{ - char** split; - *pieces_read = 0; - - if(line != NULL) - { - int split_index; - int non_separator_found; - char* dup_line; - char* start; - - if(max_pieces < 0) - { - /* count number of separator characters in line -- this count + 1 is an upperbound on number of pieces */ - int separator_count = 0; - int line_index; - for(line_index = 0; line[line_index] != '\0'; line_index++) - { - int sep_index; - int found = 0; - for(sep_index =0; found == 0 && sep_index < num_separators; sep_index++) - { - found = separators[sep_index] == line[line_index] ? 1 : 0; - } - separator_count = separator_count+ found; - } - max_pieces = separator_count + 1; - } - split = (char**)malloc((1+max_pieces)*sizeof(char*)); - split_index = 0; - split[split_index] = NULL; - - - dup_line = strdup(line); - start = dup_line; - non_separator_found = 0; - while(non_separator_found == 0) - { - int matches = 0; - int sep_index; - for(sep_index =0; sep_index < num_separators; sep_index++) - { - matches = matches == 1 || separators[sep_index] == start[0] ? 1 : 0; - } - non_separator_found = matches==0 || start[0] == '\0' ? 1 : 0; - if(non_separator_found == 0) - { - start++; - } - } - - while(start[0] != '\0' && split_index < max_pieces) - { - /* find first separator index */ - int first_separator_index = 0; - int separator_found = 0; - while( separator_found == 0 ) - { - int sep_index; - for(sep_index =0; separator_found == 0 && sep_index < num_separators; sep_index++) - { - separator_found = separators[sep_index] == start[first_separator_index] || start[first_separator_index] == '\0' ? 1 : 0; - } - if(separator_found == 0) - { - first_separator_index++; - } - } - - /* copy next piece to split array */ - if(first_separator_index > 0) - { - char* next_piece = NULL; - if(split_index +1 < max_pieces || include_remainder_at_max <= 0) - { - next_piece = (char*)malloc((first_separator_index+1)*sizeof(char)); - memcpy(next_piece, start, first_separator_index); - next_piece[first_separator_index] = '\0'; - } - else - { - next_piece = strdup(start); - } - split[split_index] = next_piece; - split[split_index+1] = NULL; - split_index++; - *pieces_read = split_index; - } - - - /* find next non-separator index, indicating start of next piece */ - start = start+ first_separator_index; - non_separator_found = 0; - while(non_separator_found == 0) - { - int matches = 0; - int sep_index; - for(sep_index =0; sep_index < num_separators; sep_index++) - { - matches = matches == 1 || separators[sep_index] == start[0] ? 1 : 0; - } - non_separator_found = matches==0 || start[0] == '\0' ? 1 : 0; - if(non_separator_found == 0) - { - start++; - } - } - } - free(dup_line); - - } - else - { - split = (char**)malloc((1)*sizeof(char*)); - split[0] = NULL; - } - return split; -} - - -time_t* get_interval_starts_for_history(ip_bw_history history) -{ - time_t *start_times = NULL; - if(history.num_nodes > 0) - { - start_times = (time_t*)malloc(history.num_nodes*sizeof(time_t)); - int node_index =0; - time_t next_start = history.first_start; - time_t next_end = get_next_node_start_time(next_start, history.reset_interval, history.reset_time, history.is_constant_interval); - for(node_index=0; node_index < history.num_nodes; node_index++) - { - start_times[node_index] = next_start; - next_start = next_end; - next_end = get_next_node_start_time(next_start, history.reset_interval, history.reset_time, history.is_constant_interval); - } - } - return start_times; -} - - - -void free_ip_bw_histories(ip_bw_history* histories, int num_histories) -{ - if(histories == NULL) - { - return; - } - int history_index = 0; - for(history_index=0; history_index < num_histories; history_index++) - { - if((histories[history_index]).history_bws != NULL) - { - free( (histories[history_index]).history_bws ); - } - } - free(histories); -} - - - - - - -int get_all_bandwidth_history_for_rule_id(char* id, unsigned long* num_ips, ip_bw_history** data, unsigned long max_wait_milliseconds) -{ - return get_bandwidth_data(id, 1, "ALL", num_ips, (void*)data, max_wait_milliseconds); -} -int get_ip_bandwidth_history_for_rule_id(char* id, char* ip, ip_bw_history** data, unsigned long max_wait_milliseconds) -{ - unsigned long num_ips; - return get_bandwidth_data(id, 1, ip, &num_ips, (void*)data, max_wait_milliseconds); -} -int get_all_bandwidth_usage_for_rule_id(char* id, unsigned long* num_ips, ip_bw** data, unsigned long max_wait_milliseconds) -{ - return get_bandwidth_data(id, 0, "ALL", num_ips, (void*)data, max_wait_milliseconds); -} -int get_ip_bandwidth_usage_for_rule_id(char* id, char* ip, ip_bw** data, unsigned long max_wait_milliseconds) -{ - unsigned long num_ips; - return get_bandwidth_data(id, 0, ip, &num_ips, (void*)data, max_wait_milliseconds); -} - - -int set_bandwidth_history_for_rule_id(char* id, unsigned char zero_unset, unsigned long num_ips, ip_bw_history* data, unsigned long max_wait_milliseconds) -{ - return set_bandwidth_data(id, zero_unset, 1, num_ips, 0, data, max_wait_milliseconds); -} - -int set_bandwidth_usage_for_rule_id(char* id, unsigned char zero_unset, unsigned long num_ips, time_t last_backup, ip_bw* data, unsigned long max_wait_milliseconds) -{ - return set_bandwidth_data(id, zero_unset, 0, num_ips, last_backup, data, max_wait_milliseconds); -} - - - - - - -/* save single id in ascii */ -int save_usage_to_file(ip_bw* data, unsigned long num_ips, char* out_file_path) -{ - - int success = 0; - FILE* out_file = fopen(out_file_path, "w"); - if(out_file != NULL) - { - //dump backup time - time_t now; - time(&now); - fprintf(out_file, "%-15ld\n", now); - - //dump ips - int out_index=0; - for(out_index=0; out_index < num_ips; out_index++) - { - struct in_addr ipaddr; - ip_bw next = data[out_index]; - ipaddr.s_addr = next.ip; - fprintf(out_file, "%-15s\t%lld\n", inet_ntoa(ipaddr), (long long int)next.bw); - } - fclose(out_file); - success = 1; - } - return success; -} - -/* save history (must be for one id only) in binary so it takes up less space */ -int save_history_to_file(ip_bw_history* data, unsigned long num_ips, char* out_file_path) -{ - int success = 0; - FILE* out_file = fopen(out_file_path, "wb"); - if(out_file != NULL) - { - //dump number of ips & history interval parameter - //note that we assume interval is same for all histories - //(which will be the case if they all come from the same rule id) - fwrite((uint32_t*)(&num_ips), 4, 1, out_file); - if(num_ips > 0) - { - ip_bw_history first = data[0]; - uint64_t interval = (uint64_t)(first.reset_interval); - uint64_t time = (uint64_t)(first.reset_time); - unsigned char is_constant = first.is_constant_interval; - - fwrite( &interval, 8, 1, out_file); - fwrite( &time, 8, 1, out_file); - fwrite( &is_constant, 1, 1, out_file); - } - - unsigned char bw_fits_in_32bits = 1; - uint32_t out_index=0; - for(out_index=0; out_index < num_ips && bw_fits_in_32bits; out_index++) - { - uint32_t node_index = 0; - ip_bw_history next = data[out_index]; - for(node_index=0; node_index < next.num_nodes && bw_fits_in_32bits; node_index++) - { - uint64_t bw = (next.history_bws)[node_index]; - bw_fits_in_32bits = bw_fits_in_32bits && (bw < INT32_MAX); - } - } - - //dump data for each ip - for(out_index=0; out_index < num_ips; out_index++) - { - ip_bw_history next = data[out_index]; - - fwrite( &(next.ip), 4, 1, out_file); - fwrite( &(next.num_nodes), 4, 1, out_file); - if(next.num_nodes == 0) - { - uint64_t dummy = 0; - unsigned char bw_bits = 32; - fwrite( &dummy, 8, 1, out_file); - fwrite( &dummy, 8, 1, out_file); - fwrite( &dummy, 8, 1, out_file); - fwrite( &bw_bits, 1, 1, out_file); - } - else - { - uint32_t node_index = 0; - uint64_t first_start = (uint64_t)next.first_start; - uint64_t first_end = (uint64_t)next.first_end; - uint64_t last_end = (uint64_t)next.last_end; - unsigned char bw_bits = 32; - for(node_index=0; node_index < next.num_nodes && bw_bits == 32; node_index++) - { - uint64_t bw = (next.history_bws)[node_index]; - bw_bits = bw_bits == 32 && (bw < INT32_MAX) ? 32 : 64; - } - - - fwrite( &first_start, 8, 1, out_file); - fwrite( &first_end, 8, 1, out_file); - fwrite( &last_end, 8, 1, out_file); - fwrite( &bw_bits, 1, 1, out_file); - for(node_index=0; node_index < next.num_nodes; node_index++) - { - if(bw_bits == 32) - { - uint32_t bw = (uint32_t)(next.history_bws)[node_index]; - fwrite( &bw, 4, 1, out_file); - - } - else - { - uint64_t bw = (next.history_bws)[node_index]; - fwrite( &bw, 8, 1, out_file); - } - } - } - } - fclose(out_file); - success = 1; - } - return success; -} - - -ip_bw* load_usage_from_file(char* in_file_path, unsigned long* num_ips, time_t* last_backup) -{ - ip_bw* data = NULL; - *num_ips = 0; - *last_backup = 0; - FILE* in_file = fopen(in_file_path, "r"); - if(in_file != NULL) - { - unsigned long num_data_parts = 0; - char* file_data = read_entire_file(in_file, 4086, &num_data_parts); - fclose(in_file); - char whitespace[] = {'\n', '\r', '\t', ' '}; - char** data_parts = split_on_separators(file_data, whitespace, 4, -1, 0, &num_data_parts); - free(file_data); - - *num_ips = (num_data_parts/2) + 1; - data = (ip_bw*)malloc( (*num_ips) * sizeof(ip_bw) ); - *num_ips = 0; - unsigned long data_index = 0; - unsigned long data_part_index = 0; - while(data_part_index < num_data_parts) - { - ip_bw next; - struct in_addr ipaddr; - if(data_part_index == 0) - { - sscanf(data_parts[data_part_index], "%ld", last_backup); - //printf("last_backup = %ld\n", *last_backup); - data_part_index++; - } - int valid = inet_aton(data_parts[data_part_index], &ipaddr); - data_part_index++; - - if(valid && data_index < num_data_parts) - { - next.ip = ipaddr.s_addr; - valid = sscanf(data_parts[data_part_index], "%lld", (long long int*)&(next.bw) ); - data_part_index++; - } - else - { - valid = 0; - } - - if(valid) - { - //printf("next.bw = %lld\n", next.bw); - //printf("next.ip = %d\n", next.ip); - data[data_index] = next; - data_index++; - *num_ips = *num_ips + 1; - } - } - - /* cleanup by freeing data_parts */ - for(data_part_index = 0; data_part_index < num_data_parts; data_part_index++) - { - free(data_parts[data_part_index]); - } - - free(data_parts); - } - return data; -} - - -ip_bw_history* load_history_from_file(char* in_file_path, unsigned long* num_ips) -{ - ip_bw_history* data = NULL; - *num_ips = 0; - FILE* in_file = fopen(in_file_path, "rb"); - if(in_file != NULL) - { - uint64_t reset_interval; - uint64_t reset_time; - unsigned char is_constant_interval; - - uint32_t nips = 0; - fread(&nips, 4, 1, in_file); - *num_ips = (unsigned long)nips; - - if(*num_ips > 0) - { - fread(&reset_interval, 8, 1, in_file); - fread(&reset_time, 8, 1, in_file); - fread(&is_constant_interval, 1, 1, in_file); - data = (ip_bw_history*)malloc( (*num_ips) * sizeof(ip_bw_history)); - } - - uint32_t ip_index; - for(ip_index=0; ip_index < *num_ips; ip_index++) - { - - uint32_t ip; - uint32_t num_nodes; - uint64_t first_start; - uint64_t first_end; - uint64_t last_end; - unsigned char bw_bits; - - fread(&ip, 4, 1, in_file); - fread(&num_nodes, 4, 1, in_file); - fread(&first_start, 8, 1, in_file); - fread(&first_end, 8, 1, in_file); - fread(&last_end, 8, 1, in_file); - fread(&bw_bits, 1, 1, in_file); - - ip_bw_history next; - next.reset_interval = (time_t)reset_interval; - next.reset_time = (time_t)reset_time; - next.is_constant_interval = is_constant_interval; - next.ip = ip; - next.num_nodes = num_nodes; - next.first_start = (time_t)first_start; - next.first_end = (time_t)first_end; - next.last_end = (time_t)last_end; - next.history_bws = NULL; - if(next.num_nodes > 0) - { - next.history_bws = malloc( next.num_nodes * sizeof(uint64_t) ); - uint32_t node_index = 0; - for(node_index=0; node_index < next.num_nodes; node_index++) - { - if(bw_bits == 32) - { - uint32_t nextbw = 0; - fread(&nextbw, 4, 1, in_file); - (next.history_bws)[node_index] = (uint64_t)nextbw; - - } - else - { - uint64_t nextbw = 0; - fread(&nextbw, 8, 1, in_file); - (next.history_bws)[node_index] = nextbw; - } - } - } - data[ip_index] = next; - } - fclose(in_file); - } - return data; -} - - -void print_usage(FILE* out, ip_bw* usage, unsigned long num_ips) -{ - unsigned long usage_index; - for(usage_index =0; usage_index < num_ips; usage_index++) - { - ip_bw next = usage[usage_index]; - if(next.ip != 0) - { - struct in_addr ipaddr; - ipaddr.s_addr = next.ip; - fprintf(out, "%-15s\t%lld\n", inet_ntoa(ipaddr), (long long int)next.bw); - } - else - { - fprintf(out, "%-15s\t%lld\n", "COMBINED", (long long int)next.bw); - } - } - fprintf(out, "\n"); -} - -void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned long num_histories, char output_type) -{ - unsigned long history_index = 0; - for(history_index=0; history_index < num_histories; history_index++) - { - ip_bw_history history = histories[history_index]; - - int history_initialized = 1; - if( history.first_start == 0 && history.first_end == 0 && history.last_end == 0) - { - history_initialized = 0; - } - - if(history_initialized) - { - char *ip_str = NULL; - time_t *times = NULL; - - - if(history.ip != 0) - { - struct in_addr ipaddr; - ipaddr.s_addr = history.ip; - ip_str = strdup(inet_ntoa(ipaddr)); - } - else - { - ip_str = strdup("COMBINED"); - } - - - if(output_type == 'm' || output_type == 'h') - { - fprintf(out, "%s %-15s\n", id, ip_str); - } - - if(output_type == 'm') - { - printf("%ld\n", history.first_start); - printf("%ld\n", history.first_end); - printf("%ld\n", history.last_end); - } - else - { - times = get_interval_starts_for_history(history); - } - - int hindex = 0; - for(hindex=0; hindex < history.num_nodes; hindex++) - { - uint64_t bw = (history.history_bws)[hindex]; - if(output_type == 'm') - { - if(hindex != 0) { printf(","); }; - printf("%lld", (unsigned long long int)bw); - } - else if(times != NULL) - { - time_t start = times[hindex]; - time_t end = hindex+1 < history.num_nodes ? times[hindex+1] : 0 ; - - char* start_str = strdup(asctime(localtime(&start))); - char* end_str = end == 0 ? strdup("(Now)") : strdup(asctime(localtime(&end))); - char* nl = strchr(start_str, '\n'); - if(nl != NULL) - { - *nl = '\0'; - } - nl = strchr(end_str, '\n'); - if(nl != NULL) - { - *nl = '\0'; - } - - if(output_type == 'h') - { - fprintf(out, "%lld\t%s\t%s\n", (unsigned long long int)bw, start_str, end_str); - } - else - { - fprintf(out, "%s,%s,%ld,%ld,%lld\n", id, ip_str, start, end, (unsigned long long int)bw ); - } - - - free(start_str); - free(end_str); - } - } - fprintf(out, "\n"); - if(times != NULL) { free(times); }; - if(ip_str != NULL) { free(ip_str); }; - } - } -} - - - - -void unlock_bandwidth_semaphore(void) -{ - unlock(); -} - -void signal_handler(int sig) -{ - if(sig == SIGTERM || sig == SIGINT ) - { - unlock_bandwidth_semaphore(); - exit(0); - } -} - -void unlock_bandwidth_semaphore_on_exit(void) -{ - signal(SIGTERM,signal_handler); - signal(SIGINT, signal_handler); -} - - -int get_minutes_west(time_t now) -{ - struct tm* utc_info; - struct tm* tz_info; - int utc_day; - int utc_hour; - int utc_minute; - int tz_day; - int tz_hour; - int tz_minute; - int minuteswest; - - utc_info = gmtime(&now); - utc_day = utc_info->tm_mday; - utc_hour = utc_info->tm_hour; - utc_minute = utc_info->tm_min; - tz_info = localtime(&now); - tz_day = tz_info->tm_mday; - tz_hour = tz_info->tm_hour; - tz_minute = tz_info->tm_min; - - utc_day = utc_day < tz_day - 1 ? tz_day + 1 : utc_day; - tz_day = tz_day < utc_day - 1 ? utc_day + 1 : tz_day; - - minuteswest = (24*60*utc_day + 60*utc_hour + utc_minute) - (24*60*tz_day + 60*tz_hour + tz_minute) ; - - return minuteswest; -} - - -void set_kernel_timezone(void) -{ - time_t now; - struct timeval tv; - struct timezone old_tz; - struct timezone new_tz; - - time(&now); - new_tz.tz_minuteswest = get_minutes_west(now); - new_tz.tz_dsttime = 0; - - /* Get tv to pass to settimeofday(2) to be sure we avoid hour-sized warp */ - /* (see gettimeofday(2) man page, or /usr/src/linux/kernel/time.c) */ - syscall(SYS_gettimeofday, &tv, &old_tz); - - /* set timezone */ - syscall(SYS_settimeofday, &tv, &new_tz); -} diff --git a/package/ctcgfw/libiptbwctl/src/ipt_bwctl.h b/package/ctcgfw/libiptbwctl/src/ipt_bwctl.h deleted file mode 100644 index 5f70d9f8a2..0000000000 --- a/package/ctcgfw/libiptbwctl/src/ipt_bwctl.h +++ /dev/null @@ -1,161 +0,0 @@ -/* libiptbwctl -- A userspace library for querying the bandwidth iptables module - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define BANDWIDTH_QUERY_LENGTH 16384 - -/* socket id parameters (for userspace i/o) */ -#define BANDWIDTH_SET 2048 -#define BANDWIDTH_GET 2049 - - -/* max id length */ -#define BANDWIDTH_MAX_ID_LENGTH 50 - -/* pick something rather random... let's make it end in 666 to - * freak out the crazy fundies out there ;-) */ -#define BANDWIDTH_SEMAPHORE_KEY 12699666 - -/* possible reset intervals */ -#define BANDWIDTH_MINUTE 80 -#define BANDWIDTH_HOUR 81 -#define BANDWIDTH_DAY 82 -#define BANDWIDTH_WEEK 83 -#define BANDWIDTH_MONTH 84 -#define BANDWIDTH_NEVER 85 - - -#pragma pack(push, 1) -typedef struct ip_bw_struct -{ - uint32_t ip; - uint64_t bw; -}ip_bw; - -/* -* format of response: -* byte 1 : error code (0 for ok) -* bytes 2-5 : total_num_ips found in query (further gets may be necessary to retrieve them) -* bytes 6-9 : start_index, index (in a list of total_num_ips) of first ip in response -* bytes 10-13 : num_ips_in_response, number of ips in this response -* bytes 14-21 : reset_interval (helps deal with DST shifts in userspace) -* bytes 22-29 : reset_time (helps deal with DST shifts in userspace) -* byte 30 : reset_is_constant_interval (helps deal with DST shifts in userspace) -* remaining bytes contain blocks of ip data -* format is dependent on whether history was queried -*/ -typedef struct ip_bw_kernel_data_item_struct -{ - uint32_t ip; - uint32_t num_nodes; - uint64_t first_start; - uint64_t first_end; - uint64_t last_end; - uint64_t ipbw_data[0]; -}ip_bw_kernel_data_item; - -typedef struct -{ - uint8_t error; - uint32_t ip_total; - uint32_t index_start; - uint32_t ip_num; - uint64_t reset_interval; - uint64_t reset_time; - uint8_t reset_is_constant_interval; - /*payload for history ip bw data*/ - ip_bw_kernel_data_item data_item[0]; -}ip_bw_kernel_data; - -typedef struct history_struct -{ - uint32_t ip; - uint32_t num_nodes; - - time_t reset_interval; - time_t reset_time; - unsigned char is_constant_interval; - - time_t first_start; - time_t first_end; - time_t last_end; - - uint64_t* history_bws; -} ip_bw_history; -#pragma pack(pop) - -time_t* get_interval_starts_for_history(ip_bw_history history); - -extern void free_ip_bw_histories(ip_bw_history* histories, int num_histories); - -extern int get_all_bandwidth_history_for_rule_id(char* id, unsigned long* num_ips, ip_bw_history** data, unsigned long max_wait_milliseconds); -extern int get_ip_bandwidth_history_for_rule_id(char* id, char* ip, ip_bw_history** data, unsigned long max_wait_milliseconds); -extern int get_all_bandwidth_usage_for_rule_id(char* id, unsigned long* num_ips, ip_bw** data, unsigned long max_wait_milliseconds); -extern int get_ip_bandwidth_usage_for_rule_id(char* id, char* ip, ip_bw** data, unsigned long max_wait_milliseconds); - - - -extern int set_bandwidth_history_for_rule_id(char* id, unsigned char zero_unset, unsigned long num_ips, ip_bw_history* data, unsigned long max_wait_milliseconds); -extern int set_bandwidth_usage_for_rule_id(char* id, unsigned char zero_unset, unsigned long num_ips, time_t last_backup, ip_bw* data, unsigned long max_wait_milliseconds); - - - -extern int save_usage_to_file(ip_bw* data, unsigned long num_ips, char* out_file_path); -extern int save_history_to_file(ip_bw_history* data, unsigned long num_ips, char* out_file_path); - - - -extern ip_bw* load_usage_from_file(char* in_file_path, unsigned long* num_ips, time_t* last_backup); -extern ip_bw_history* load_history_from_file(char* in_file_path, unsigned long* num_ips); - -extern void print_usage(FILE* out, ip_bw* usage, unsigned long num_ips); -extern void print_histories(FILE* out, char* id, ip_bw_history* histories, unsigned long num_histories, char output_type); - - - - -extern void unlock_bandwidth_semaphore(void); -extern void unlock_bandwidth_semaphore_on_exit(void); - - -/* sets kernel timezone minuteswest to match user timezone */ -extern int get_minutes_west(time_t now); -extern void set_kernel_timezone(void); - - -/* safe malloc & strdup functions used to handle malloc errors cleanly */ -extern void* ipt_bwctl_safe_malloc(size_t size); -extern char* ipt_bwctl_safe_strdup(const char* str); diff --git a/package/ctcgfw/libiptbwctl/src/ipt_bwctl_safe_malloc.c b/package/ctcgfw/libiptbwctl/src/ipt_bwctl_safe_malloc.c deleted file mode 100644 index 463379acfd..0000000000 --- a/package/ctcgfw/libiptbwctl/src/ipt_bwctl_safe_malloc.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "ipt_bwctl.h" - -void *ipt_bwctl_safe_malloc(size_t size) -{ - void* val = malloc(size); - if(val == NULL) - { - fprintf(stderr, "ERROR: MALLOC FAILURE!\n"); - exit(1); - } - return val; -} - -char* ipt_bwctl_safe_strdup(const char* str) -{ - char* new_str = strdup(str); - if(new_str == NULL) - { - fprintf(stderr, "ERROR: MALLOC FAILURE!\n"); - exit(1); - } - return new_str; -} diff --git a/package/ctcgfw/libiptbwctl/src/utils/Makefile b/package/ctcgfw/libiptbwctl/src/utils/Makefile deleted file mode 100644 index c2bc9f3d2d..0000000000 --- a/package/ctcgfw/libiptbwctl/src/utils/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -all: bw_set bw_get bw_print_history_file set_kernel_timezone -bw_set: bw_set.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -liptbwctl -bw_get: bw_get.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -liptbwctl -bw_print_history_file: bw_print_history_file.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -liptbwctl -set_kernel_timezone: set_kernel_timezone.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ -liptbwctl - -clean: - rm -rf bw_set bw_get print_history_file set_kernel_timezone *.o *~ .*sw* diff --git a/package/ctcgfw/libiptbwctl/src/utils/bw_get.c b/package/ctcgfw/libiptbwctl/src/utils/bw_get.c deleted file mode 100644 index b4df411fcf..0000000000 --- a/package/ctcgfw/libiptbwctl/src/utils/bw_get.c +++ /dev/null @@ -1,177 +0,0 @@ -/* libiptbwctl -- A userspace library for querying the bandwidth iptables module - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#define malloc ipt_bwctl_safe_malloc -#define strdup ipt_bwctl_safe_strdup - - -int main(int argc, char **argv) -{ - char *id = NULL; - char* out_file_path = NULL;; - char *address = NULL; - - unsigned long num_ips; - void *ip_buf; - unsigned long out_index; - int query_succeeded; - int get_history = 0; - char output_type = 'h'; - - int c; - struct in_addr read_addr; - while((c = getopt(argc, argv, "i:I:a:A:f:F:tThHmMuU")) != -1) - { - switch(c) - { - case 'i': - case 'I': - if(strlen(optarg) < BANDWIDTH_MAX_ID_LENGTH && strlen(optarg) > 0) - { - id = strdup(optarg); - } - else - { - fprintf(stderr, "ERROR: ID length is improper length.\n"); - exit(0); - } - break; - case 'a': - case 'A': - if(strcmp(optarg, "combined") == 0 || strcmp(optarg, "COMBINED") == 0) - { - address = strdup("0.0.0.0"); - } - else if( inet_aton(optarg, &read_addr) ) - { - address = strdup(optarg); - } - else - { - fprintf(stderr, "ERROR: invalid IP address specified\n"); - exit(0); - } - - break; - case 'f': - case 'F': - out_file_path = strdup(optarg); - break; - case 'h': - case 'H': - get_history = 1; - break; - case 'm': - case 'M': - output_type = 'm'; - break; - case 't': - case 'T': - output_type = 't'; - break; - case 'u': - case 'U': - default: - fprintf(stderr, "USAGE:\n\t%s -i [ID] -a [IP ADDRESS] -f [OUT_FILE_NAME]\n", argv[0]); - exit(0); - } - } - - - if(id == NULL) - { - fprintf(stderr, "ERROR: you must specify an id to query\n\n"); - exit(0); - } - - set_kernel_timezone(); - unlock_bandwidth_semaphore_on_exit(); - - if(get_history == 0) - { - if(address == NULL) - { - query_succeeded = get_all_bandwidth_usage_for_rule_id(id, &num_ips, (ip_bw**)&ip_buf, 1000); - } - else - { - num_ips = 1; - query_succeeded = get_ip_bandwidth_usage_for_rule_id(id, address, (ip_bw**)&ip_buf, 1000); - } - } - else - { - if(address == NULL) - { - query_succeeded = get_all_bandwidth_history_for_rule_id(id, &num_ips, (ip_bw_history**)&ip_buf, 1000); - } - else - { - num_ips = 1; - query_succeeded = get_ip_bandwidth_history_for_rule_id(id, address, (ip_bw_history**)&ip_buf, 1000); - } - } - if(!query_succeeded) - { - fprintf(stderr, "ERROR: Bandwidth query failed, make sure rule with specified id exists, and that you are performing only one query at a time.\n\n"); - exit(0); - } - - - if(out_file_path != NULL) - { - if(get_history == 0) - { - save_usage_to_file( (ip_bw*)ip_buf, num_ips, out_file_path); - } - else - { - save_history_to_file( (ip_bw_history*)ip_buf, num_ips, out_file_path); - } - } - else - { - if(get_history == 0) - { - print_usage(stdout, (ip_bw*)ip_buf, num_ips); - } - else - { - print_histories(stdout, id, (ip_bw_history*)ip_buf, num_ips, output_type ); - } - } - if(num_ips == 0) - { - if(output_type != 't' && output_type != 'm') - { - fprintf(stderr, "No data available for id \"%s\"\n", id); - } - } - printf("\n"); - - if(out_file_path != NULL) - { - free(out_file_path); - } - - return 0; -} diff --git a/package/ctcgfw/libiptbwctl/src/utils/bw_print_history_file.c b/package/ctcgfw/libiptbwctl/src/utils/bw_print_history_file.c deleted file mode 100644 index b13aa7c156..0000000000 --- a/package/ctcgfw/libiptbwctl/src/utils/bw_print_history_file.c +++ /dev/null @@ -1,39 +0,0 @@ -/* libiptbwctl -- A userspace library for querying the bandwidth iptables module - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include -#define malloc ipt_bwctl_safe_malloc -#define strdup ipt_bwctl_safe_strdup - - -int main(int argc, char **argv) -{ - if(argc > 1) - { - unsigned long num_ips; - ip_bw_history* histories = load_history_from_file(argv[1], &num_ips); - if(histories != NULL) - { - print_histories(stdout, argv[1], histories, num_ips, 'h'); - } - } - return 0; -} diff --git a/package/ctcgfw/libiptbwctl/src/utils/bw_set.c b/package/ctcgfw/libiptbwctl/src/utils/bw_set.c deleted file mode 100644 index 8d5f34876f..0000000000 --- a/package/ctcgfw/libiptbwctl/src/utils/bw_set.c +++ /dev/null @@ -1,186 +0,0 @@ -/* libiptbwctl -- A userspace library for querying the bandwidth iptables module - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#define malloc ipt_bwctl_safe_malloc -#define strdup ipt_bwctl_safe_strdup - -static char* read_entire_file(FILE* in, int read_block_size); -static char** split_on_separators(char* line, char* separators, int num_separators, int max_pieces, int include_remainder_at_max, unsigned long *pieces_read); - -int main(int argc, char **argv) -{ - char *id = NULL; - char* in_file_path = NULL; - FILE* in_file = NULL; - time_t last_backup = 0; - int last_backup_from_cl = 0; - int is_history_file = 0; - - - int c; - while((c = getopt(argc, argv, "i:I:b:B:f:F:UuHh")) != -1) - { - switch(c) - { - case 'i': - case 'I': - if(strlen(optarg) < BANDWIDTH_MAX_ID_LENGTH) - { - id = strdup(optarg); - } - else - { - fprintf(stderr, "ERROR: ID length is improper length.\n"); - exit(0); - } - - break; - case 'b': - case 'B': - if(sscanf(optarg, "%ld", &last_backup) == 0) - { - fprintf(stderr, "ERROR: invalid backup time specified. Should be unix epoch seconds -- number of seconds since 1970 (UTC)\n"); - exit(0); - } - last_backup_from_cl = 1; - break; - case 'f': - case 'F': - in_file_path = strdup(optarg); - in_file = fopen(optarg, "rb"); - if(in_file == NULL) - { - fprintf(stderr, "ERROR: cannot open specified file for reading\n"); - exit(0); - } - fclose(in_file); - break; - case 'h': - case 'H': - is_history_file = 1; - break; - case 'u': - case 'U': - default: - fprintf(stderr, "USAGE:\n\t%s -i [ID] -b [LAST_BACKUP_TIME] -f [IN_FILE_NAME] [ IP BANDWIDTH PAIRS, IF -f NOT SPECIFIED ]\n", argv[0]); - exit(0); - - } - } - - if(id == NULL) - { - fprintf(stderr, "ERROR: you must specify an id for which to set data\n\n"); - exit(0); - } - if(in_file_path == NULL && is_history_file) - { - fprintf(stderr, "ERROR: you need to specify file to load history from\n\t\t(history format is too complex to load from command line)\n"); - } - - - set_kernel_timezone(); - unlock_bandwidth_semaphore_on_exit(); - int query_succeeded = 0; - if(in_file_path != NULL) - { - if(is_history_file) - { - unsigned long num_ips; - ip_bw_history* history_data = load_history_from_file(in_file_path, &num_ips); - if(history_data != NULL) - { - query_succeeded = set_bandwidth_history_for_rule_id(id, 1, num_ips, history_data, 1000); - } - } - else - { - unsigned long num_ips; - time_t last_backup; - ip_bw* usage_data = load_usage_from_file(in_file_path, &num_ips, &last_backup); - if(usage_data != NULL) - { - query_succeeded = set_bandwidth_usage_for_rule_id(id, 1, num_ips, last_backup, usage_data, 1000); - } - } - } - else - { - char** data_parts; - unsigned long num_data_parts; - data_parts = argv+optind; - num_data_parts = argc - optind; - - - unsigned long num_ips = num_data_parts/2; - ip_bw* buffer = (ip_bw*)malloc(num_ips*sizeof(ip_bw)); - unsigned long data_index = 0; - unsigned long buffer_index = 0; - while(data_index < num_data_parts) - { - ip_bw next; - struct in_addr ipaddr; - int valid = inet_aton(data_parts[data_index], &ipaddr); - if((!valid) && (!last_backup_from_cl)) - { - sscanf(data_parts[data_index], "%ld", &last_backup); - } - data_index++; - - if(valid && data_index < num_data_parts) - { - next.ip = ipaddr.s_addr; - valid = sscanf(data_parts[data_index], "%lld", (long long int*)&(next.bw) ); - data_index++; - } - else - { - valid = 0; - } - - if(valid) - { - /* printf("ip=%d, bw=%lld\n", next.ip, (long long int)next.bw); */ - buffer[buffer_index] = next; - buffer_index++; - } - } - num_ips = buffer_index; /* number that were successfully read */ - query_succeeded = set_bandwidth_usage_for_rule_id(id, 1, num_ips, last_backup, buffer, 1000); - } - - if(!query_succeeded) - { - fprintf(stderr, "ERROR: Could not set data. Please try again.\n\n"); - } - else - { - fprintf(stderr, "Data set successfully\n\n"); - } - - if(in_file_path != NULL) - { - free(in_file_path); - } - - return 0; -} - diff --git a/package/ctcgfw/libiptbwctl/src/utils/set_kernel_timezone.c b/package/ctcgfw/libiptbwctl/src/utils/set_kernel_timezone.c deleted file mode 100644 index 5fd958b3df..0000000000 --- a/package/ctcgfw/libiptbwctl/src/utils/set_kernel_timezone.c +++ /dev/null @@ -1,27 +0,0 @@ -/* libiptbwctl -- A userspace library for querying the bandwidth iptables module - * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) - * - * - * Copyright © 2009 by Eric Bishop - * - * This file is free software: you may copy, redistribute and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 2 of the License, or (at your - * option) any later version. - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -int main(void) -{ - set_kernel_timezone(); - return 0; -} diff --git a/package/ctcgfw/luci-app-qos-gargoyle/Makefile b/package/ctcgfw/luci-app-qos-gargoyle/Makefile deleted file mode 100644 index f0187a81a6..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# -# Copyright (C) 2017 Xingwang Liao -# -# This is free software, licensed under the Apache License, Version 2.0 . -# - -include $(TOPDIR)/rules.mk - -PKG_NAME:=luci-app-qos-gargoyle -PKG_VERSION:=1.3.6 -PKG_RELEASE:=1 - -PKG_LICENSE:=Apache-2.0 -PKG_MAINTAINER:=Xingwang Liao - -LUCI_TITLE:=LuCI Support for Gargoyle QoS -LUCI_DEPENDS:=+qos-gargoyle -LUCI_PKGARCH:=all - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/controller/qos_gargoyle.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/controller/qos_gargoyle.lua deleted file mode 100644 index 5b9ca56c5f..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/controller/qos_gargoyle.lua +++ /dev/null @@ -1,100 +0,0 @@ --- Copyright 2017 Xingwang Liao --- Licensed to the public under the Apache License 2.0. - -module("luci.controller.qos_gargoyle", package.seeall) - -local util = require "luci.util" -local http = require "luci.http" - -function index() - if not nixio.fs.access("/etc/config/qos_gargoyle") then - return - end - - entry({"admin", "network", "qos_gargoyle"}, - firstchild(), _("Gargoyle QoS"), 60) - - entry({"admin", "network", "qos_gargoyle", "global"}, - cbi("qos_gargoyle/global"), _("Global Settings"), 10) - - entry({"admin", "network", "qos_gargoyle", "upload"}, - cbi("qos_gargoyle/upload"), _("Upload Settings"), 20) - - entry({"admin", "network", "qos_gargoyle", "upload", "class"}, - cbi("qos_gargoyle/upload_class")).leaf = true - - entry({"admin", "network", "qos_gargoyle", "upload", "rule"}, - cbi("qos_gargoyle/upload_rule")).leaf = true - - entry({"admin", "network", "qos_gargoyle", "download"}, - cbi("qos_gargoyle/download"), _("Download Settings"), 30) - - entry({"admin", "network", "qos_gargoyle", "download", "class"}, - cbi("qos_gargoyle/download_class")).leaf = true - - entry({"admin", "network", "qos_gargoyle", "download", "rule"}, - cbi("qos_gargoyle/download_rule")).leaf = true - - entry({"admin", "network", "qos_gargoyle", "troubleshooting"}, - template("qos_gargoyle/troubleshooting"), _("Troubleshooting"), 40) - - entry({"admin", "network", "qos_gargoyle", "troubleshooting", "data"}, - call("action_troubleshooting_data")) - - entry({"admin", "network", "qos_gargoyle", "load_data"}, - call("action_load_data")).leaf = true -end - -function action_troubleshooting_data() - local uci = require "luci.model.uci".cursor() - local i18n = require "luci.i18n" - - local data = {} - - local monenabled = uci:get("qos_gargoyle", "download", "qos_monenabled") or "false" - - local show_data = util.trim(util.exec("/etc/init.d/qos_gargoyle show 2>/dev/null")) - if show_data == "" then - show_data = i18n.translate("No data found") - end - - data.show = show_data - - local mon_data - if monenabled == "true" then - mon_data = util.trim(util.exec("cat /tmp/qosmon.status 2>/dev/null")) - - if mon_data == "" then - mon_data = i18n.translate("No data found") - end - else - mon_data = i18n.translate("\"Active Congestion Control\" not enabled") - end - - data.mon = mon_data - - http.prepare_content("application/json") - http.write_json(data) -end - -function action_load_data(type) - local device - if type == "download" then - device = "imq0" - elseif type == "upload" then - local qos = require "luci.model.qos_gargoyle" - local wan = qos.get_wan() - device = wan and wan:ifname() or "" - end - - if device then - local data - if device ~= "" then - data = util.exec("tc -s class show dev %s 2>/dev/null" % device) - end - http.prepare_content("text/plain") - http.write(data or "") - else - http.status(500, "Bad address") - end -end diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download.lua deleted file mode 100644 index a165178874..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download.lua +++ /dev/null @@ -1,166 +0,0 @@ --- Copyright 2017 Xingwang Liao --- Licensed to the public under the Apache License 2.0. - -local wa = require "luci.tools.webadmin" -local uci = require "luci.model.uci".cursor() -local dsp = require "luci.dispatcher" -local http = require "luci.http" -local qos = require "luci.model.qos_gargoyle" - -local m, class_s, rule_s, o -local download_classes = {} -local qos_gargoyle = "qos_gargoyle" - -uci:foreach(qos_gargoyle, "download_class", function(s) - local class_alias = s.name - if class_alias then - download_classes[#download_classes + 1] = {name = s[".name"], alias = class_alias} - end -end) - -m = Map(qos_gargoyle, translate("Download Settings")) -m.template = "qos_gargoyle/list_view" - -class_s = m:section(TypedSection, "download_class", translate("Service Classes"), - translate("Each service class is specified by four parameters: percent bandwidth at capacity, " - .. "realtime bandwidth and maximum bandwidth and the minimimze round trip time flag.")) -class_s.anonymous = true -class_s.addremove = true -class_s.template = "cbi/tblsection" -class_s.extedit = dsp.build_url("admin/network/qos_gargoyle/download/class/%s") -class_s.create = function(...) - local sid = TypedSection.create(...) - if sid then - m.uci:save(qos_gargoyle) - http.redirect(class_s.extedit % sid) - return - end -end - -o = class_s:option(DummyValue, "name", translate("Class Name")) -o.cfgvalue = function(...) - return Value.cfgvalue(...) or translate("None") -end - -o = class_s:option(DummyValue, "percent_bandwidth", translate("Percent Bandwidth At Capacity")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - if v and v > 0 then - return "%d %%" % v - end - return translate("Not set") -end - -o = class_s:option(DummyValue, "min_bandwidth", "%s (kbps)" % translate("Minimum Bandwidth")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - return v or translate("Zero") -end - -o = class_s:option(DummyValue, "max_bandwidth", "%s (kbps)" % translate("Maximum Bandwidth")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - return v or translate("Unlimited") -end - -o = class_s:option(DummyValue, "minRTT", translate("Minimize RTT")) -o.cfgvalue = function(...) - local v = Value.cfgvalue(...) - return v and translate(v) or translate("No") -end - -o = class_s:option(DummyValue, "_ld", "%s (kbps)" % translate("Load")) -o.rawhtml = true -o.value = "*" - -rule_s = m:section(TypedSection, "download_rule", translate("Classification Rules"), - translate("Packets are tested against the rules in the order specified -- rules toward the top " - .. "have priority. As soon as a packet matches a rule it is classified, and the rest of the rules " - .. "are ignored. The order of the rules can be altered using the arrow controls.") - ) -rule_s.addremove = true -rule_s.sortable = true -rule_s.anonymous = true -rule_s.template = "cbi/tblsection" -rule_s.extedit = dsp.build_url("admin/network/qos_gargoyle/download/rule/%s") -rule_s.create = function(...) - local sid = TypedSection.create(...) - if sid then - m.uci:save(qos_gargoyle) - http.redirect(rule_s.extedit % sid) - return - end -end - -o = rule_s:option(ListValue, "class", translate("Service Class")) -for _, s in ipairs(download_classes) do o:value(s.name, s.alias) end - -o = rule_s:option(Value, "proto", translate("Transport Protocol")) -o:value("", translate("All")) -o:value("tcp", "TCP") -o:value("udp", "UDP") -o:value("icmp", "ICMP") -o:value("gre", "GRE") -o.size = "10" -o.cfgvalue = function(...) - local v = Value.cfgvalue(...) - return v and v:upper() or "" -end -o.write = function(self, section, value) - Value.write(self, section, value:lower()) -end - -o = rule_s:option(Value, "source", translate("Source IP(s)")) -o:value("", translate("All")) -wa.cbi_add_knownips(o) -o.datatype = "ipmask4" - -o = rule_s:option(Value, "srcport", translate("Source Port(s)")) -o:value("", translate("All")) -o.datatype = "or(port, portrange)" - -o = rule_s:option(Value, "destination", translate("Destination IP(s)")) -o:value("", translate("All")) -wa.cbi_add_knownips(o) -o.datatype = "ipmask4" - -o = rule_s:option(Value, "dstport", translate("Destination Port(s)")) -o:value("", translate("All")) -o.datatype = "or(port, portrange)" - -o = rule_s:option(DummyValue, "min_pkt_size", translate("Minimum Packet Length")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - if v and v > 0 then - return wa.byte_format(v) - end - return translate("Not set") -end - -o = rule_s:option(DummyValue, "max_pkt_size", translate("Maximum Packet Length")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - if v and v > 0 then - return wa.byte_format(v) - end - return translate("Not set") -end - -o = rule_s:option(DummyValue, "connbytes_kb", translate("Connection Bytes Reach")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - if v and v > 0 then - return wa.byte_format(v * 1024) - end - return translate("Not set") -end - -if qos.has_ndpi() then - o = rule_s:option(DummyValue, "ndpi", translate("DPI Protocol")) - o.cfgvalue = function(...) - local v = Value.cfgvalue(...) - return v and v:upper() or translate("All") - end -end - -return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_class.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_class.lua deleted file mode 100644 index c26cb78301..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_class.lua +++ /dev/null @@ -1,61 +0,0 @@ --- Copyright 2017 Xingwang Liao --- Licensed to the public under the Apache License 2.0. - -local m, s, o -local sid = arg[1] -local qos_gargoyle = "qos_gargoyle" - -m = Map(qos_gargoyle, translate("Edit Download Service Class")) -m.redirect = luci.dispatcher.build_url("admin/network/qos_gargoyle/download") - -if m.uci:get(qos_gargoyle, sid) ~= "download_class" then - luci.http.redirect(m.redirect) - return -end - -s = m:section(NamedSection, sid, "download_class") -s.anonymous = true -s.addremove = false - -o = s:option(Value, "name", translate("Service Class Name")) -o.rmempty = false - -o = s:option(Value, "percent_bandwidth", translate("Percent Bandwidth At Capacity"), - translate("The percentage of the total available bandwidth that should be allocated to this class " - .. "when all available bandwidth is being used. If unused bandwidth is available, more can (and " - .. "will) be allocated. The percentages can be configured to equal more (or less) than 100, but " - .. "when the settings are applied the percentages will be adjusted proportionally so that they " - .. "add to 100. This setting only comes into effect when the WAN link is saturated.")) -o.datatype = "range(1, 100)" -o.rmempty = false - -o = s:option(Value, "min_bandwidth", translate("Minimum Bandwidth"), - translate("The minimum service this class will be allocated when the link is at capacity. Classes " - .. "which specify minimum service are known as realtime classes by the active congestion " - .. "controller. Streaming video, VoIP and interactive online gaming are all examples of " - .. "applications that must have a minimum bandwith to function. To determine what to enter use " - .. "the application on an unloaded LAN and observe how much bandwidth it uses. Then enter a " - .. "number only slightly higher than this into this field. QoS will satisfiy the minimum service " - .. "of all classes first before allocating to other waiting classes so be careful to use minimum " - .. "bandwidths sparingly.")) -o:value("0", translate("Zero")) -o.datatype = "uinteger" -o.default = "0" - -o = s:option(Value, "max_bandwidth", translate("Maximum Bandwidth"), - translate("The maximum amount of bandwidth this class will be allocated in kbit/s. Even if unused " - .. "bandwidth is available, this service class will never be permitted to use more than this " - .. "amount of bandwidth.")) -o:value("", translate("Unlimited")) -o.datatype = "uinteger" - -o = s:option(Flag, "minRTT", translate("Minimize RTT"), - translate("Indicates to the active congestion controller that you wish to minimize round trip " - .. "times (RTT) when this class is active. Use this setting for online gaming or VoIP " - .. "applications that need low round trip times (ping times). Minimizing RTT comes at the expense " - .. "of efficient WAN throughput so while these class are active your WAN throughput will decline " - .. "(usually around 20%).")) -o.enabled = "Yes" -o.disabled = "No" - -return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_rule.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_rule.lua deleted file mode 100644 index cbc970e2f0..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/download_rule.lua +++ /dev/null @@ -1,87 +0,0 @@ --- Copyright 2017 Xingwang Liao --- Licensed to the public under the Apache License 2.0. - -local wa = require "luci.tools.webadmin" -local uci = require "luci.model.uci".cursor() -local qos = require "luci.model.qos_gargoyle" - -local m, s, o -local sid = arg[1] -local download_classes = {} -local qos_gargoyle = "qos_gargoyle" - -uci:foreach(qos_gargoyle, "download_class", function(s) - local class_alias = s.name - if class_alias then - download_classes[#download_classes + 1] = {name = s[".name"], alias = class_alias} - end -end) - -m = Map(qos_gargoyle, translate("Edit Download Classification Rule")) -m.redirect = luci.dispatcher.build_url("admin/network/qos_gargoyle/download") - -if m.uci:get(qos_gargoyle, sid) ~= "download_rule" then - luci.http.redirect(m.redirect) - return -end - -s = m:section(NamedSection, sid, "download_rule") -s.anonymous = true -s.addremove = false - -o = s:option(ListValue, "class", translate("Service Class")) -for _, s in ipairs(download_classes) do o:value(s.name, s.alias) end - -o = s:option(Value, "proto", translate("Transport Protocol")) -o:value("", translate("All")) -o:value("tcp", "TCP") -o:value("udp", "UDP") -o:value("icmp", "ICMP") -o:value("gre", "GRE") -o.write = function(self, section, value) - Value.write(self, section, value:lower()) -end - -o = s:option(Value, "source", translate("Source IP(s)"), - translate("Packet's source ip, can optionally have /[mask] after it (see -s option in iptables " - .. "man page).")) -o:value("", translate("All")) -wa.cbi_add_knownips(o) -o.datatype = "ipmask4" - -o = s:option(Value, "srcport", translate("Source Port(s)"), - translate("Packet's source port, can be a range (eg. 80-90).")) -o:value("", translate("All")) -o.datatype = "or(port, portrange)" - -o = s:option(Value, "destination", translate("Destination IP(s)"), - translate("Packet's destination ip, can optionally have /[mask] after it (see -d option in " - .. "iptables man page).")) -o:value("", translate("All")) -wa.cbi_add_knownips(o) -o.datatype = "ipmask4" - -o = s:option(Value, "dstport", translate("Destination Port(s)"), - translate("Packet's destination port, can be a range (eg. 80-90).")) -o:value("", translate("All")) -o.datatype = "or(port, portrange)" - -o = s:option(Value, "min_pkt_size", translate("Minimum Packet Length"), - translate("Packet's minimum size (in bytes).")) -o.datatype = "range(1, 1500)" - -o = s:option(Value, "max_pkt_size", translate("Maximum Packet Length"), - translate("Packet's maximum size (in bytes).")) -o.datatype = "range(1, 1500)" - -o = s:option(Value, "connbytes_kb", translate("Connection Bytes Reach"), - translate("The total size of data transmitted since the establishment of the link (in kBytes).")) -o.datatype = "range(0, 4194303)" - -if qos.has_ndpi() then - o = s:option(ListValue, "ndpi", translate("DPI Protocol")) - o:value("", translate("All")) - qos.cbi_add_dpi_protocols(o) -end - -return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/global.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/global.lua deleted file mode 100644 index b698590be9..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/global.lua +++ /dev/null @@ -1,124 +0,0 @@ --- Copyright 2017 Xingwang Liao --- Licensed to the public under the Apache License 2.0. - -local sys = require "luci.sys" -local uci = require "luci.model.uci".cursor() -local net = require "luci.model.network".init() -local qos = require "luci.model.qos_gargoyle" - -local m, s, o -local upload_classes = {} -local download_classes = {} -local qos_gargoyle = "qos_gargoyle" - -local function qos_enabled() - return sys.init.enabled(qos_gargoyle) -end - -uci:foreach(qos_gargoyle, "upload_class", function(s) - local class_alias = s.name - if class_alias then - upload_classes[#upload_classes + 1] = {name = s[".name"], alias = class_alias} - end -end) - -uci:foreach(qos_gargoyle, "download_class", function(s) - local class_alias = s.name - if class_alias then - download_classes[#download_classes + 1] = {name = s[".name"], alias = class_alias} - end -end) - -m = Map(qos_gargoyle, translate("Gargoyle QoS"), - translate("Quality of Service (QoS) provides a way to control how available bandwidth is " - .. "allocated.")) - -s = m:section(TypedSection, 'global', translate("Global Settings")) -s.anonymous = true - -o = s:option(Button, "", translate("QoS Switch")) -o.render = function(self, section, scope) - if qos_enabled() then - self.title = translate("Disable QoS") - self.inputstyle = "reset" - else - self.title = translate("Enable QoS") - self.inputstyle = "apply" - end - Button.render(self, section, scope) -end -o.write = function(...) - if qos_enabled() then - sys.init.stop(qos_gargoyle) - sys.init.disable(qos_gargoyle) - else - sys.init.enable(qos_gargoyle) - sys.init.start(qos_gargoyle) - end -end - -s = m:section(NamedSection, "upload", "upload", translate("Upload Settings")) -s.anonymous = true - -o = s:option(ListValue, "default_class", translate("Default Service Class"), - translate("Specifie how packets that do not match any rule should be classified.")) -for _, s in ipairs(upload_classes) do o:value(s.name, s.alias) end - -o = s:option(Value, "total_bandwidth", translate("Total Upload Bandwidth"), - translate("Should be set to around 98% of your available upload bandwidth. Entering a number " - .. "which is too high will result in QoS not meeting its class requirements. Entering a number " - .. "which is too low will needlessly penalize your upload speed. You should use a speed test " - .. "program (with QoS off) to determine available upload bandwidth. Note that bandwidth is " - .. "specified in kbps, leave blank to disable update QoS. There are 8 kilobits per kilobyte.")) -o.datatype = "uinteger" - -s = m:section(NamedSection, "download", "download", translate("Download Settings")) -s.anonymous = true - -o = s:option(ListValue, "default_class", translate("Default Service Class"), - translate("Specifie how packets that do not match any rule should be classified.")) -for _, s in ipairs(download_classes) do o:value(s.name, s.alias) end - -o = s:option(Value, "total_bandwidth", translate("Total Download Bandwidth"), - translate("Specifying correctly is crucial to making QoS work. Note that bandwidth is specified " - .. "in kbps, leave blank to disable download QoS. There are 8 kilobits per kilobyte.")) -o.datatype = "uinteger" - -o = s:option(Flag, "qos_monenabled", translate("Enable Active Congestion Control"), - translate("

The active congestion control (ACC) observes your download activity and " - .. "automatically adjusts your download link limit to maintain proper QoS performance. ACC " - .. "automatically compensates for changes in your ISP's download speed and the demand from your " - .. "network adjusting the link speed to the highest speed possible which will maintain proper QoS " - .. "function. The effective range of this control is between 15% and 100% of the total download " - .. "bandwidth you entered above.

") .. - translate("

While ACC does not adjust your upload link speed you must enable and properly " - .. "configure your upload QoS for it to function properly.

") - ) -o.enabled = "true" -o.disabled = "false" - -o = s:option(Value, "ptarget_ip", translate("Use Non-standard Ping Target"), - translate("The segment of network between your router and the ping target is where congestion is " - .. "controlled. By monitoring the round trip ping times to the target congestion is detected. By " - .. "default ACC uses your WAN gateway as the ping target. If you know that congestion on your " - .. "link will occur in a different segment then you can enter an alternate ping target. Leave " - .. "empty to use the default settings.")) -o:depends("qos_monenabled", "true") --- local wan = qos.get_wan() --- if wan then o:value(wan:gwaddr()) end --- TODO: get wan address -o.datatype = "ipaddr" - -o = s:option(Value, "pinglimit", translate("Manual Ping Limit"), - translate("Round trip ping times are compared against the ping limits. ACC controls the link " - .. "limit to maintain ping times under the appropriate limit. By default ACC attempts to " - .. "automatically select appropriate target ping limits for you based on the link speeds you " - .. "entered and the performance of your link it measures during initialization. You cannot change " - .. "the target ping time for the minRTT mode but by entering a manual time you can control the " - .. "target ping time of the active mode. The time you enter becomes the increase in the target " - .. "ping time between minRTT and active mode. Leave empty to use the default settings.")) -o:depends("qos_monenabled", "true") -o:value("Auto", translate("Auto")) -o.datatype = "or('Auto', range(10, 250))" - -return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload.lua deleted file mode 100644 index a5f86927ef..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload.lua +++ /dev/null @@ -1,160 +0,0 @@ --- Copyright 2017 Xingwang Liao --- Licensed to the public under the Apache License 2.0. - -local wa = require "luci.tools.webadmin" -local uci = require "luci.model.uci".cursor() -local dsp = require "luci.dispatcher" -local http = require "luci.http" -local qos = require "luci.model.qos_gargoyle" - -local m, class_s, rule_s, o -local upload_classes = {} -local qos_gargoyle = "qos_gargoyle" - -uci:foreach(qos_gargoyle, "upload_class", function(s) - local class_alias = s.name - if class_alias then - upload_classes[#upload_classes + 1] = {name = s[".name"], alias = class_alias} - end -end) - -m = Map(qos_gargoyle, translate("Upload Settings")) -m.template = "qos_gargoyle/list_view" - -class_s = m:section(TypedSection, "upload_class", translate("Service Classes"), - translate("Each upload service class is specified by three parameters: percent bandwidth at " - .. "capacity, minimum bandwidth and maximum bandwidth.")) -class_s.anonymous = true -class_s.addremove = true -class_s.template = "cbi/tblsection" -class_s.extedit = dsp.build_url("admin/network/qos_gargoyle/upload/class/%s") -class_s.create = function(...) - local sid = TypedSection.create(...) - if sid then - m.uci:save(qos_gargoyle) - http.redirect(class_s.extedit % sid) - return - end -end - -o = class_s:option(DummyValue, "name", translate("Class Name")) -o.cfgvalue = function(...) - return Value.cfgvalue(...) or translate("None") -end - -o = class_s:option(DummyValue, "percent_bandwidth", translate("Percent Bandwidth At Capacity")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - if v and v > 0 then - return "%d %%" % v - end - return translate("Not set") -end - -o = class_s:option(DummyValue, "min_bandwidth", "%s (kbps)" % translate("Minimum Bandwidth")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - return v or translate("Zero") -end - -o = class_s:option(DummyValue, "max_bandwidth", "%s (kbps)" % translate("Maximum Bandwidth")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - return v or translate("Unlimited") -end - -o = class_s:option(DummyValue, "_ld", "%s (kbps)" % translate("Load")) -o.rawhtml = true -o.value = "*" - -rule_s = m:section(TypedSection, "upload_rule",translate("Classification Rules"), - translate("Packets are tested against the rules in the order specified -- rules toward the top " - .. "have priority. As soon as a packet matches a rule it is classified, and the rest of the rules " - .. "are ignored. The order of the rules can be altered using the arrow controls.") -) -rule_s.addremove = true -rule_s.sortable = true -rule_s.anonymous = true -rule_s.template = "cbi/tblsection" -rule_s.extedit = dsp.build_url("admin/network/qos_gargoyle/upload/rule/%s") -rule_s.create = function(...) - local sid = TypedSection.create(...) - if sid then - m.uci:save(qos_gargoyle) - http.redirect(rule_s.extedit % sid) - return - end -end - -o = rule_s:option(ListValue, "class", translate("Service Class")) -for _, s in ipairs(upload_classes) do o:value(s.name, s.alias) end - -o = rule_s:option(Value, "proto", translate("Transport Protocol")) -o:value("", translate("All")) -o:value("tcp", "TCP") -o:value("udp", "UDP") -o:value("icmp", "ICMP") -o:value("gre", "GRE") -o.size = "10" -o.cfgvalue = function(...) - local v = Value.cfgvalue(...) - return v and v:upper() or "" -end -o.write = function(self, section, value) - Value.write(self, section, value:lower()) -end - -o = rule_s:option(Value, "source", translate("Source IP(s)")) -o:value("", translate("All")) -wa.cbi_add_knownips(o) -o.datatype = "ipmask4" - -o = rule_s:option(Value, "srcport", translate("Source Port(s)")) -o:value("", translate("All")) -o.datatype = "or(port, portrange)" - -o = rule_s:option(Value, "destination", translate("Destination IP(s)")) -o:value("", translate("All")) -wa.cbi_add_knownips(o) -o.datatype = "ipmask4" - -o = rule_s:option(Value, "dstport", translate("Destination Port(s)")) -o:value("", translate("All")) -o.datatype = "or(port, portrange)" - -o = rule_s:option(DummyValue, "min_pkt_size", translate("Minimum Packet Length")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - if v and v > 0 then - return wa.byte_format(v) - end - return translate("Not set") -end - -o = rule_s:option(DummyValue, "max_pkt_size", translate("Maximum Packet Length")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - if v and v > 0 then - return wa.byte_format(v) - end - return translate("Not set") -end - -o = rule_s:option(DummyValue, "connbytes_kb", translate("Connection Bytes Reach")) -o.cfgvalue = function(...) - local v = tonumber(Value.cfgvalue(...)) - if v and v > 0 then - return wa.byte_format(v * 1024) - end - return translate("Not set") -end - -if qos.has_ndpi() then - o = rule_s:option(DummyValue, "ndpi", translate("DPI Protocol")) - o.cfgvalue = function(...) - local v = Value.cfgvalue(...) - return v and v:upper() or translate("All") - end -end - -return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_class.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_class.lua deleted file mode 100644 index 9739b9794b..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_class.lua +++ /dev/null @@ -1,52 +0,0 @@ --- Copyright 2017 Xingwang Liao --- Licensed to the public under the Apache License 2.0. - -local m, s, o -local sid = arg[1] -local qos_gargoyle = "qos_gargoyle" - -m = Map(qos_gargoyle, translate("Edit Upload Service Class")) -m.redirect = luci.dispatcher.build_url("admin/network/qos_gargoyle/upload") - -if m.uci:get(qos_gargoyle, sid) ~= "upload_class" then - luci.http.redirect(m.redirect) - return -end - -s = m:section(NamedSection, sid, "upload_class") -s.anonymous = true -s.addremove = false - -o = s:option(Value, "name", translate("Service Class Name")) -o.rmempty = false - -o = s:option(Value, "percent_bandwidth", translate("Percent Bandwidth At Capacity"), - translate("The percentage of the total available bandwidth that should be allocated to this class " - .. "when all available bandwidth is being used. If unused bandwidth is available, more can (and " - .. "will) be allocated. The percentages can be configured to equal more (or less) than 100, but " - .. "when the settings are applied the percentages will be adjusted proportionally so that they " - .. "add to 100. This setting only comes into effect when the WAN link is saturated.")) -o.datatype = "range(1, 100)" -o.rmempty = false - -o = s:option(Value, "min_bandwidth", translate("Minimum Bandwidth"), - translate("The minimum service this class will be allocated when the link is at capacity. Classes " - .. "which specify minimum service are known as realtime classes by the active congestion " - .. "controller. Streaming video, VoIP and interactive online gaming are all examples of " - .. "applications that must have a minimum bandwith to function. To determine what to enter use " - .. "the application on an unloaded LAN and observe how much bandwidth it uses. Then enter a " - .. "number only slightly higher than this into this field. QoS will satisfiy the minimum service " - .. "of all classes first before allocating to other waiting classes so be careful to use minimum " - .. "bandwidths sparingly.")) -o:value("0", translate("Zero")) -o.datatype = "uinteger" -o.default = "0" - -o = s:option(Value, "max_bandwidth", translate("Maximum Bandwidth"), - translate("The maximum amount of bandwidth this class will be allocated in kbit/s. Even if unused " - .. "bandwidth is available, this service class will never be permitted to use more than this " - .. "amount of bandwidth.")) -o:value("", translate("Unlimited")) -o.datatype = "uinteger" - -return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_rule.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_rule.lua deleted file mode 100644 index 8abcac35d9..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/cbi/qos_gargoyle/upload_rule.lua +++ /dev/null @@ -1,87 +0,0 @@ --- Copyright 2017 Xingwang Liao --- Licensed to the public under the Apache License 2.0. - -local wa = require "luci.tools.webadmin" -local uci = require "luci.model.uci".cursor() -local qos = require "luci.model.qos_gargoyle" - -local m, s, o -local sid = arg[1] -local upload_classes = {} -local qos_gargoyle = "qos_gargoyle" - -uci:foreach(qos_gargoyle, "upload_class", function(s) - local class_alias = s.name - if class_alias then - upload_classes[#upload_classes + 1] = {name = s[".name"], alias = class_alias} - end -end) - -m = Map(qos_gargoyle, translate("Edit Upload Classification Rule")) -m.redirect = luci.dispatcher.build_url("admin/network/qos_gargoyle/upload") - -if m.uci:get(qos_gargoyle, sid) ~= "upload_rule" then - luci.http.redirect(m.redirect) - return -end - -s = m:section(NamedSection, sid, "upload_rule") -s.anonymous = true -s.addremove = false - -o = s:option(ListValue, "class", translate("Service Class")) -for _, s in ipairs(upload_classes) do o:value(s.name, s.alias) end - -o = s:option(Value, "proto", translate("Transport Protocol")) -o:value("", translate("All")) -o:value("tcp", "TCP") -o:value("udp", "UDP") -o:value("icmp", "ICMP") -o:value("gre", "GRE") -o.write = function(self, section, value) - Value.write(self, section, value:lower()) -end - -o = s:option(Value, "source", translate("Source IP(s)"), - translate("Packet's source ip, can optionally have /[mask] after it (see -s option in iptables " - .. "man page).")) -o:value("", translate("All")) -wa.cbi_add_knownips(o) -o.datatype = "ipmask4" - -o = s:option(Value, "srcport", translate("Source Port(s)"), - translate("Packet's source port, can be a range (eg. 80-90).")) -o:value("", translate("All")) -o.datatype = "or(port, portrange)" - -o = s:option(Value, "destination", translate("Destination IP(s)"), - translate("Packet's destination ip, can optionally have /[mask] after it (see -d option in " - .. "iptables man page).")) -o:value("", translate("All")) -wa.cbi_add_knownips(o) -o.datatype = "ipmask4" - -o = s:option(Value, "dstport", translate("Destination Port(s)"), - translate("Packet's destination port, can be a range (eg. 80-90).")) -o:value("", translate("All")) -o.datatype = "or(port, portrange)" - -o = s:option(Value, "min_pkt_size", translate("Minimum Packet Length"), - translate("Packet's minimum size (in bytes).")) -o.datatype = "range(1, 1500)" - -o = s:option(Value, "max_pkt_size", translate("Maximum Packet Length"), - translate("Packet's maximum size (in bytes).")) -o.datatype = "range(1, 1500)" - -o = s:option(Value, "connbytes_kb", translate("Connection Bytes Reach"), - translate("The total size of data transmitted since the establishment of the link (in kBytes).")) -o.datatype = "range(0, 4194303)" - -if qos.has_ndpi() then - o = s:option(ListValue, "ndpi", translate("DPI Protocol")) - o:value("", translate("All")) - qos.cbi_add_dpi_protocols(o) -end - -return m diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/qos_gargoyle.lua b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/qos_gargoyle.lua deleted file mode 100644 index d12af8b1c3..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/model/qos_gargoyle.lua +++ /dev/null @@ -1,38 +0,0 @@ --- Copyright 2017 Xingwang Liao --- Licensed to the public under the Apache License 2.0. - -module("luci.model.qos_gargoyle", package.seeall) - -function has_ndpi() - return luci.sys.call("lsmod | cut -d ' ' -f1 | grep -q 'xt_ndpi'") == 0 -end - -function cbi_add_dpi_protocols(field) - local util = require "luci.util" - - local dpi_protocols = {} - - for line in util.execi("iptables -m ndpi --help 2>/dev/null | grep '^--'") do - local _, _, protocol, name = line:find("%-%-([^%s]+) Match for ([^%s]+)") - - if protocol and name then - dpi_protocols[protocol] = name - end - end - - for p, n in util.kspairs(dpi_protocols) do - field:value(p, n) - end -end - -function get_wan() - local network = require "luci.model.network".init() - local bundle = network:get_status_by_route("0.0.0.0", 0) - local net, stat - for k, v in pairs(bundle) do - net = k - stat = v - break - end - return net and network:network(net, stat.proto) -end diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/list_view.htm b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/list_view.htm deleted file mode 100644 index 87d3994de2..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/list_view.htm +++ /dev/null @@ -1,97 +0,0 @@ -<%# - Copyright 2017 Xingwang Liao - Licensed to the public under the Apache License 2.0. --%> - -<% - local dsp = require "luci.dispatcher" - local request = dsp.context.path - local leaf = request[#request] --%> - - - -<%+cbi/map%> - - diff --git a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/troubleshooting.htm b/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/troubleshooting.htm deleted file mode 100644 index 17197850e8..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/luasrc/view/qos_gargoyle/troubleshooting.htm +++ /dev/null @@ -1,52 +0,0 @@ -<%# - Copyright 2017 Xingwang Liao - Licensed to the public under the Apache License 2.0. --%> - -<% css = [[ - - #troubleshoot_text { - padding: 20px; - text-align: left; - } - #troubleshoot_text pre { - word-break: break-all; - margin: 0; - } - .description { - background-color: #33CCFF; - } - -]] --%> - -<%+header%> - - - - -
-
- <%:Troubleshooting Data%> -
<%:Loading%><%:Collecting data...%>
-
-
- -<%+footer%> diff --git a/package/ctcgfw/luci-app-qos-gargoyle/po/zh_Hans/luci-app-qos-gargoyle.po b/package/ctcgfw/luci-app-qos-gargoyle/po/zh_Hans/luci-app-qos-gargoyle.po deleted file mode 100644 index fc2782492f..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/po/zh_Hans/luci-app-qos-gargoyle.po +++ /dev/null @@ -1,514 +0,0 @@ -msgid "" -msgstr "" -"Content-Type: text/plain; charset=UTF-8\n" -"Project-Id-Version: PACKAGE VERSION\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" -"Language: zh-Hans\n" -"MIME-Version: 1.0\n" -"Content-Transfer-Encoding: 8bit\n" - -#: luasrc/controller/qos_gargoyle.lua:71 -msgid "\"Active Congestion Control\" not enabled" -msgstr "“主动拥塞控制”未启用" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:88 -msgid "" -"

The active congestion control (ACC) observes your download activity and " -"automatically adjusts your download link limit to maintain proper QoS " -"performance. ACC automatically compensates for changes in your ISP's " -"download speed and the demand from your network adjusting the link speed to " -"the highest speed possible which will maintain proper QoS function. The " -"effective range of this control is between 15% and 100% of the total " -"download bandwidth you entered above.

" -msgstr "" -"

主动拥塞控制系统(ACC)观察你的下载活动并自动调整你的下载链接限制以保持适" -"当的 QoS 性能。ACC 自动调整 QoS 功能以补偿来自你 ISP 的下载速度变化及来自你网" -"络链接速度的调整需求,使速度最大化。这个控制的有效范围在你上面输入的下载总带" -"宽的 15% 至 100% 之间。

" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:94 -msgid "" -"

While ACC does not adjust your upload link speed you must enable and " -"properly configure your upload QoS for it to function properly.

" -msgstr "" -"

虽然 ACC 不调整你的上传链路速度,但你必须启用并正确配置你的上传 QoS 带宽以" -"使该功能正常工作。

" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:99 -#: luasrc/model/cbi/qos_gargoyle/download.lua:114 -#: luasrc/model/cbi/qos_gargoyle/download.lua:119 -#: luasrc/model/cbi/qos_gargoyle/download.lua:123 -#: luasrc/model/cbi/qos_gargoyle/download.lua:128 -#: luasrc/model/cbi/qos_gargoyle/download.lua:162 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:36 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:48 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:54 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:60 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:66 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:83 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:93 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:108 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:113 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:117 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:122 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:156 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:36 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:48 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:54 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:60 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:66 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:83 -msgid "All" -msgstr "全部" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:121 -msgid "Auto" -msgstr "自动" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:40 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:40 -msgid "Class Name" -msgstr "类型名称" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:76 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:70 -msgid "Classification Rules" -msgstr "分类规则" - -#: luasrc/view/qos_gargoyle/troubleshooting.htm:48 -msgid "Collecting data..." -msgstr "正在收集数据..." - -#: luasrc/model/cbi/qos_gargoyle/download.lua:149 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:77 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:143 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:77 -msgid "Connection Bytes Reach" -msgstr "连接流量达到" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:159 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:82 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:153 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:82 -msgid "DPI Protocol" -msgstr "DPI 协议" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:63 -#: luasrc/model/cbi/qos_gargoyle/global.lua:78 -msgid "Default Service Class" -msgstr "默认服务类型" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:122 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:57 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:116 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:57 -msgid "Destination IP(s)" -msgstr "目标 IP" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:127 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:64 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:121 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:64 -msgid "Destination Port(s)" -msgstr "目标端口" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:42 -msgid "Disable QoS" -msgstr "禁用 QoS" - -#: luasrc/controller/qos_gargoyle.lua:30 -#: luasrc/model/cbi/qos_gargoyle/download.lua:21 -#: luasrc/model/cbi/qos_gargoyle/global.lua:75 -msgid "Download Settings" -msgstr "下载设置" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:25 -msgid "" -"Each service class is specified by four parameters: percent bandwidth at " -"capacity, realtime bandwidth and maximum bandwidth and the minimimze round " -"trip time flag." -msgstr "" -"每个下载服务类型由四个参数指定:带宽占用百分比、最小保证带宽、最大带宽和最小" -"往返延时标志。" - -#: luasrc/model/cbi/qos_gargoyle/upload.lua:25 -msgid "" -"Each upload service class is specified by three parameters: percent " -"bandwidth at capacity, minimum bandwidth and maximum bandwidth." -msgstr "每个上传服务类型由三个参数指定:带宽占用百分比、最小带宽和最大带宽。" - -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:20 -msgid "Edit Download Classification Rule" -msgstr "编辑下载分类规则" - -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:8 -msgid "Edit Download Service Class" -msgstr "编辑下载服务类型" - -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:20 -msgid "Edit Upload Classification Rule" -msgstr "编辑上传分类规则" - -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:8 -msgid "Edit Upload Service Class" -msgstr "编辑上传服务类型" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:87 -msgid "Enable Active Congestion Control" -msgstr "启用主动拥塞控制" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:45 -msgid "Enable QoS" -msgstr "启用 QoS" - -#: luasrc/view/qos_gargoyle/troubleshooting.htm:39 -msgid "Error collecting troubleshooting information" -msgstr "收集故障排查信息失败" - -#: luasrc/controller/qos_gargoyle.lua:15 -#: luasrc/model/cbi/qos_gargoyle/global.lua:32 -msgid "Gargoyle QoS" -msgstr "石像鬼 QoS" - -#: luasrc/controller/qos_gargoyle.lua:18 -#: luasrc/model/cbi/qos_gargoyle/global.lua:36 -msgid "Global Settings" -msgstr "全局设置" - -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:53 -msgid "" -"Indicates to the active congestion controller that you wish to minimize " -"round trip times (RTT) when this class is active. Use this setting for " -"online gaming or VoIP applications that need low round trip times (ping " -"times). Minimizing RTT comes at the expense of efficient WAN throughput so " -"while these class are active your WAN throughput will decline (usually " -"around 20%)." -msgstr "" -"告诉主动拥塞控制器你希望该服务类型启用时尽量减少往返延时(RTT)。该设置一般用" -"在 VoIP 或在线游戏这类需要低延时(Ping 值)的应用上。减小往返延时(RTT)会带" -"来WAN有效吞吐量的额外花销,所以当这些服务类型启用时你的 WAN 吞吐量将下降(通" -"常在20%左右)" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:72 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:66 -msgid "Load" -msgstr "负载" - -#: luasrc/view/qos_gargoyle/troubleshooting.htm:48 -msgid "Loading" -msgstr "正在加载" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:112 -msgid "Manual Ping Limit" -msgstr "手动 Ping 限制" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:60 -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:45 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:60 -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:45 -msgid "Maximum Bandwidth" -msgstr "最大带宽" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:140 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:73 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:134 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:73 -msgid "Maximum Packet Length" -msgstr "最大数据包长度" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:66 -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:52 -msgid "Minimize RTT" -msgstr "最小往返延时" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:54 -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:32 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:54 -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:32 -msgid "Minimum Bandwidth" -msgstr "最小带宽" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:131 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:69 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:125 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:69 -msgid "Minimum Packet Length" -msgstr "最小数据包长度" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:69 -msgid "No" -msgstr "否" - -#: luasrc/controller/qos_gargoyle.lua:58 luasrc/controller/qos_gargoyle.lua:68 -msgid "No data found" -msgstr "无数据" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:42 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:42 -msgid "None" -msgstr "无" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:51 -#: luasrc/model/cbi/qos_gargoyle/download.lua:137 -#: luasrc/model/cbi/qos_gargoyle/download.lua:146 -#: luasrc/model/cbi/qos_gargoyle/download.lua:155 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:51 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:131 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:140 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:149 -msgid "Not set" -msgstr "未设置" - -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:58 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:58 -msgid "" -"Packet's destination ip, can optionally have /[mask] after it (see -d option " -"in iptables man page)." -msgstr "" -"数据包的目标 IP,可以在后面加子网掩码(/[mask],请看 iptables 的 -d 参数说" -"明)" - -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:65 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:65 -msgid "Packet's destination port, can be a range (eg. 80-90)." -msgstr "数据包的目标端口,可以是一个范围(例如:80-90)" - -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:74 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:74 -msgid "Packet's maximum size (in bytes)." -msgstr "数据包的最大大小(单位:bytes)" - -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:70 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:70 -msgid "Packet's minimum size (in bytes)." -msgstr "数据包的最小大小(单位:bytes)" - -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:46 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:46 -msgid "" -"Packet's source ip, can optionally have /[mask] after it (see -s option in " -"iptables man page)." -msgstr "" -"数据包的源 IP,可以在后面加子网掩码(/[mask],请看 iptables 的 -s 参数说明)" - -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:53 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:53 -msgid "Packet's source port, can be a range (eg. 80-90)." -msgstr "数据包的源端口,可以是一个范围(例如:80-90)" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:77 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:71 -msgid "" -"Packets are tested against the rules in the order specified -- rules toward " -"the top have priority. As soon as a packet matches a rule it is classified, " -"and the rest of the rules are ignored. The order of the rules can be altered " -"using the arrow controls." -msgstr "" -"数据包将按规则中指定的顺序进行匹配 —— 靠上的规则优先进行匹配。一旦数据包匹配" -"一条规则那它将被归类,并且其余的规则将被忽略。使用上下箭头可调整规则的顺序。" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:45 -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:23 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:45 -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:23 -msgid "Percent Bandwidth At Capacity" -msgstr "带宽占用百分比" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:39 -msgid "QoS Switch" -msgstr "QoS 开关" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:33 -msgid "" -"Quality of Service (QoS) provides a way to control how available bandwidth " -"is allocated." -msgstr "QoS 可以用来分配和控制可用带宽。" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:113 -msgid "" -"Round trip ping times are compared against the ping limits. ACC controls the " -"link limit to maintain ping times under the appropriate limit. By default " -"ACC attempts to automatically select appropriate target ping limits for you " -"based on the link speeds you entered and the performance of your link it " -"measures during initialization. You cannot change the target ping time for " -"the minRTT mode but by entering a manual time you can control the target " -"ping time of the active mode. The time you enter becomes the increase in the " -"target ping time between minRTT and active mode. Leave empty to use the " -"default settings." -msgstr "" -"Ping 延时会与 Ping 限制进行比较。ACC 控制链路限制以保持 Ping 延时在适当范围。" -"默认情况下,ACC 会自动根据你输入的链接适当为你选择适当的 Ping 限制。如果你想" -"尝试不同的 Ping 限制,你可以在这里输入一个时间值。输入高的时间值将导致更高的 " -"Ping 限制,低的时间值会有更低的限制。留空则将由 ACC 自动控制。" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:95 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:32 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:89 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:32 -msgid "Service Class" -msgstr "服务类型" - -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:20 -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:20 -msgid "Service Class Name" -msgstr "服务类型名称" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:24 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:24 -msgid "Service Classes" -msgstr "服务类型" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:68 -msgid "" -"Should be set to around 98% of your available upload bandwidth. Entering a " -"number which is too high will result in QoS not meeting its class " -"requirements. Entering a number which is too low will needlessly penalize " -"your upload speed. You should use a speed test program (with QoS off) to " -"determine available upload bandwidth. Note that bandwidth is specified in " -"kbps, leave blank to disable update QoS. There are 8 kilobits per kilobyte." -msgstr "" -"应被设置为你可用上传带宽的 98% 左右。输入数值太高将导致 QoS 不能匹配服务类型" -"的要求。输入数值太低将造成不必要的上传速度限制。你应当在 QoS 关闭的情况下使用" -"测速程序以确定可用的上传带宽。带宽以 kbps 为单位,留空以禁用上传 QoS。" -"(1KByte/s=8Kbps)" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:113 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:45 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:107 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:45 -msgid "Source IP(s)" -msgstr "源 IP" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:118 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:52 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:112 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:52 -msgid "Source Port(s)" -msgstr "源端口" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:64 -#: luasrc/model/cbi/qos_gargoyle/global.lua:79 -msgid "Specifie how packets that do not match any rule should be classified." -msgstr "指定当数据包不匹配任何规则时将被如何归类。" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:83 -msgid "" -"Specifying correctly is crucial to making QoS work. Note that bandwidth is " -"specified in kbps, leave blank to disable download QoS. There are 8 kilobits " -"per kilobyte." -msgstr "" -"正确设置对于 QoS 的工作至关重要。带宽以 kbps 为单位,留空以禁用下载 QoS。" -"(1KByte/s=8Kbps)" - -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:46 -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:46 -msgid "" -"The maximum amount of bandwidth this class will be allocated in kbit/s. Even " -"if unused bandwidth is available, this service class will never be permitted " -"to use more than this amount of bandwidth." -msgstr "" -"该服务类型可被分配的带宽最大值(以 kbit/s 为单位)。即使存在未使用带宽,该服" -"务类型也将永远不被允许使用超过此量的带宽。" - -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:33 -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:33 -msgid "" -"The minimum service this class will be allocated when the link is at " -"capacity. Classes which specify minimum service are known as realtime " -"classes by the active congestion controller. Streaming video, VoIP and " -"interactive online gaming are all examples of applications that must have a " -"minimum bandwith to function. To determine what to enter use the application " -"on an unloaded LAN and observe how much bandwidth it uses. Then enter a " -"number only slightly higher than this into this field. QoS will satisfiy the " -"minimum service of all classes first before allocating to other waiting " -"classes so be careful to use minimum bandwidths sparingly." -msgstr "" -"将被分配用于该服务类型的最低链路带宽容量。指定了最小带宽的服务类型会被主动拥" -"塞控制器看作实时类应用。例如视频流、VoIP 和在线互动游戏都应该设置最小带宽。要" -"确定需要多少最小带宽,可以在一个没有负载的局域网中使用应用程序并观察它使用了" -"多少带宽。然后输入一个略高于这个值的数字到字段中。在分配剩余带宽到其它服务类" -"型前,QoS 将优先满足所有服务类型的最小带宽要求,所以要谨慎地使用最小带宽。" - -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:24 -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:24 -msgid "" -"The percentage of the total available bandwidth that should be allocated to " -"this class when all available bandwidth is being used. If unused bandwidth " -"is available, more can (and will) be allocated. The percentages can be " -"configured to equal more (or less) than 100, but when the settings are " -"applied the percentages will be adjusted proportionally so that they add to " -"100. This setting only comes into effect when the WAN link is saturated." -msgstr "" -"当所有可用带宽被占满后该服务类型占据总带宽的百分比。如果带宽未用完,该服务类" -"型会被分配更多带宽。该百分比值可被设置为等于、大于或小于 100,但当设置被应用" -"时,百分比值将会被按比例调整以便使它们加起来等于 100。该设置只在 WAN 端链路饱" -"和时才生效。(PS:WAN 端链路饱和即带宽被占用完)" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:101 -msgid "" -"The segment of network between your router and the ping target is where " -"congestion is controlled. By monitoring the round trip ping times to the " -"target congestion is detected. By default ACC uses your WAN gateway as the " -"ping target. If you know that congestion on your link will occur in a " -"different segment then you can enter an alternate ping target. Leave empty " -"to use the default settings." -msgstr "" -"在路由器和 Ping 目标之间的网络部分是拥塞控制的地方。拥塞通过监视和目标间的 " -"Ping 延时来检测。默认情况下 ACC 使用你的 WAN 网关作为 Ping 的目标。假如你知道" -"拥塞会在你链路的不同段发生,你可用输入一个备用的 Ping 目标。留空则将由ACC 自" -"动控制。" - -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:78 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:78 -msgid "" -"The total size of data transmitted since the establishment of the link (in " -"kBytes)." -msgstr "自连接建立以来,传输的数据总量(单位:kBytes)" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:82 -msgid "Total Download Bandwidth" -msgstr "下载总带宽" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:67 -msgid "Total Upload Bandwidth" -msgstr "上传总带宽" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:98 -#: luasrc/model/cbi/qos_gargoyle/download_rule.lua:35 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:92 -#: luasrc/model/cbi/qos_gargoyle/upload_rule.lua:35 -msgid "Transport Protocol" -msgstr "协议" - -#: luasrc/controller/qos_gargoyle.lua:39 -msgid "Troubleshooting" -msgstr "故障排除" - -#: luasrc/view/qos_gargoyle/troubleshooting.htm:47 -msgid "Troubleshooting Data" -msgstr "故障排除数据" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:63 -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:49 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:63 -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:49 -msgid "Unlimited" -msgstr "不限制" - -#: luasrc/controller/qos_gargoyle.lua:21 -#: luasrc/model/cbi/qos_gargoyle/global.lua:60 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:21 -msgid "Upload Settings" -msgstr "上传设置" - -#: luasrc/model/cbi/qos_gargoyle/global.lua:100 -msgid "Use Non-standard Ping Target" -msgstr "使用自定义 Ping 目标" - -#: luasrc/model/cbi/qos_gargoyle/download.lua:57 -#: luasrc/model/cbi/qos_gargoyle/download_class.lua:41 -#: luasrc/model/cbi/qos_gargoyle/upload.lua:57 -#: luasrc/model/cbi/qos_gargoyle/upload_class.lua:41 -msgid "Zero" -msgstr "零" diff --git a/package/ctcgfw/luci-app-qos-gargoyle/root/etc/uci-defaults/40_luci-qos_gargoyle b/package/ctcgfw/luci-app-qos-gargoyle/root/etc/uci-defaults/40_luci-qos_gargoyle deleted file mode 100755 index 675fd39fc3..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/root/etc/uci-defaults/40_luci-qos_gargoyle +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@qos_gargoyle[-1] - add ucitrack qos_gargoyle - set ucitrack.@qos_gargoyle[-1].init=qos_gargoyle - commit ucitrack -EOF - -rm -rf /tmp/luci-modulecache /tmp/luci-indexcache -exit 0 diff --git a/package/ctcgfw/luci-app-qos-gargoyle/root/usr/share/rpcd/acl.d/luci-app-qos-gargoyle.json b/package/ctcgfw/luci-app-qos-gargoyle/root/usr/share/rpcd/acl.d/luci-app-qos-gargoyle.json deleted file mode 100644 index f6621d5d8b..0000000000 --- a/package/ctcgfw/luci-app-qos-gargoyle/root/usr/share/rpcd/acl.d/luci-app-qos-gargoyle.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "luci-app-qos-gargoyle": { - "description": "Grant UCI access for luci-app-qos-gargoyle", - "read": { - "uci": [ "qos_gargoyle" ] - }, - "write": { - "uci": [ "qos_gargoyle" ] - } - } -} diff --git a/package/network/utils/iptables/Makefile b/package/network/utils/iptables/Makefile index 37972c82f6..8a037a141e 100644 --- a/package/network/utils/iptables/Makefile +++ b/package/network/utils/iptables/Makefile @@ -195,26 +195,6 @@ iptables extension for IMQ support. endef -define Package/iptables-mod-bandwidth -$(call Package/iptables/Module, +kmod-ipt-bandwidth) - TITLE:=bandwidth option extensions -endef - -define Package/iptables-mod-timerange -$(call Package/iptables/Module, +kmod-ipt-timerange) - TITLE:=timerange option extensions -endef - -define Package/iptables-mod-webmon -$(call Package/iptables/Module, +kmod-ipt-webmon) - TITLE:=webmon option extensions -endef - -define Package/iptables-mod-weburl -$(call Package/iptables/Module, +kmod-ipt-weburl) - TITLE:=weburl option extensions -endef - define Package/iptables-mod-ipopt $(call Package/iptables/Module, +kmod-ipt-ipopt) TITLE:=IP/Packet option extensions @@ -712,10 +692,6 @@ $(eval $(call BuildPlugin,iptables-mod-physdev,$(IPT_PHYSDEV-m))) $(eval $(call BuildPlugin,iptables-mod-filter,$(IPT_FILTER-m))) $(eval $(call BuildPlugin,iptables-mod-cgroup,$(IPT_CGROUP-m))) $(eval $(call BuildPlugin,iptables-mod-imq,$(IPT_IMQ-m))) -$(eval $(call BuildPlugin,iptables-mod-bandwidth,$(IPT_BANDWIDTH-m))) -$(eval $(call BuildPlugin,iptables-mod-timerange,$(IPT_TIMERANGE-m))) -$(eval $(call BuildPlugin,iptables-mod-webmon,$(IPT_WEBMON-m))) -$(eval $(call BuildPlugin,iptables-mod-weburl,$(IPT_WEBURL-m))) $(eval $(call BuildPlugin,iptables-mod-ipopt,$(IPT_IPOPT-m))) $(eval $(call BuildPlugin,iptables-mod-ipsec,$(IPT_IPSEC-m))) $(eval $(call BuildPlugin,iptables-mod-nat-extra,$(IPT_NAT_EXTRA-m))) diff --git a/package/network/utils/iptables/patches/608-add-gargoyle-netfilter-match-modules.patch b/package/network/utils/iptables/patches/608-add-gargoyle-netfilter-match-modules.patch deleted file mode 100644 index 17ad17f7e4..0000000000 --- a/package/network/utils/iptables/patches/608-add-gargoyle-netfilter-match-modules.patch +++ /dev/null @@ -1,2811 +0,0 @@ ---- /dev/null -+++ b/extensions/libipt_bandwidth.c -@@ -0,0 +1,657 @@ -+/* bandwidth -- An iptables extension for bandwidth monitoring/control -+ * Can be used to efficiently monitor bandwidth and/or implement bandwidth quotas -+ * Can be queried using the iptbwctl userspace library -+ * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) -+ * -+ * -+ * Copyright © 2009 by Eric Bishop -+ * -+ * This file is free software: you may copy, redistribute and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * in iptables 1.4.0 and higher, iptables.h includes xtables.h, which -+ * we can use to check whether we need to deal with the new requirements -+ * in pre-processor directives below -+ */ -+#include -+#include -+ -+#ifdef _XTABLES_H -+ #define iptables_rule_match xtables_rule_match -+ #define iptables_match xtables_match -+ #define iptables_target xtables_target -+ #define ipt_tryload xt_tryload -+#endif -+ -+/* -+ * XTABLES_VERSION_CODE is only defined in versions 1.4.1 and later, which -+ * also require the use of xtables_register_match -+ * -+ * Version 1.4.0 uses register_match like previous versions -+ */ -+#ifdef XTABLES_VERSION_CODE -+ #define register_match xtables_register_match -+#endif -+ -+ -+ -+int get_minutes_west(void); -+void set_kernel_timezone(void); -+int parse_sub(char* subnet_string, uint32_t* subnet, uint32_t* subnet_mask); -+static unsigned long get_pow(unsigned long base, unsigned long pow); -+static void param_problem_exit_error(char* msg); -+ -+ -+/* Function which prints out usage message. */ -+static void help(void) -+{ -+ printf("bandwidth options:\n"); -+ printf(" --id [unique identifier for querying bandwidth]\n"); -+ printf(" --type [combined|individual_src|individual_dst|individual_local|individual_remote]\n"); -+ printf(" --subnet [a.b.c.d/mask] (0 < mask < 32)\n"); -+ printf(" --greater_than [BYTES]\n"); -+ printf(" --less_than [BYTES]\n"); -+ printf(" --current_bandwidth [BYTES]\n"); -+ printf(" --reset_interval [minute|hour|day|week|month]\n"); -+ printf(" --reset_time [OFFSET IN SECONDS]\n"); -+ printf(" --intervals_to_save [NUMBER OF PREVIOS INTERVALS TO STORE IN MEMORY]\n"); -+ printf(" --last_backup_time [UTC SECONDS SINCE 1970]\n"); -+ printf(" --bcheck Check another bandwidth rule without incrementing it\n"); -+ printf(" --bcheck_with_src_dst_swap Check another bandwidth rule without incrementing it, swapping src & dst ips for check\n"); -+} -+ -+static struct option opts[] = -+{ -+ { .name = "id", .has_arg = 1, .flag = 0, .val = BANDWIDTH_ID }, -+ { .name = "type", .has_arg = 1, .flag = 0, .val = BANDWIDTH_TYPE }, -+ { .name = "subnet", .has_arg = 1, .flag = 0, .val = BANDWIDTH_SUBNET }, -+ { .name = "greater_than", .has_arg = 1, .flag = 0, .val = BANDWIDTH_GT }, -+ { .name = "less_than", .has_arg = 1, .flag = 0, .val = BANDWIDTH_LT }, -+ { .name = "current_bandwidth", .has_arg = 1, .flag = 0, .val = BANDWIDTH_CURRENT }, -+ { .name = "reset_interval", .has_arg = 1, .flag = 0, .val = BANDWIDTH_RESET_INTERVAL }, -+ { .name = "reset_time", .has_arg = 1, .flag = 0, .val = BANDWIDTH_RESET_TIME }, -+ { .name = "intervals_to_save", .has_arg = 1, .flag = 0, .val = BANDWIDTH_NUM_INTERVALS }, -+ { .name = "last_backup_time", .has_arg = 1, .flag = 0, .val = BANDWIDTH_LAST_BACKUP}, -+ { .name = "bcheck", .has_arg = 0, .flag = 0, .val = BANDWIDTH_CHECK_NOSWAP }, -+ { .name = "bcheck_with_src_dst_swap", .has_arg = 0, .flag = 0, .val = BANDWIDTH_CHECK_SWAP }, -+ { .name = 0 } -+}; -+ -+ -+/* Function which parses command options; returns true if it -+ ate an option */ -+static int parse( int c, -+ char **argv, -+ int invert, -+ unsigned int *flags, -+#ifdef _XTABLES_H -+ const void *entry, -+#else -+ const struct ipt_entry *entry, -+ unsigned int *nfcache, -+#endif -+ struct ipt_entry_match **match -+ ) -+{ -+ struct ipt_bandwidth_info *info = (struct ipt_bandwidth_info *)(*match)->data; -+ int valid_arg = 0; -+ long int num_read; -+ uint64_t read_64; -+ time_t read_time; -+ -+ /* set defaults first time we get here */ -+ if(*flags == 0) -+ { -+ /* generate random id */ -+ srand ( time(NULL) ); -+ unsigned long id_num = rand(); -+ sprintf(info->id, "%lu", id_num); -+ -+ info->type = BANDWIDTH_COMBINED; -+ info->check_type = BANDWIDTH_CHECK_NOSWAP; -+ info->local_subnet = 0; -+ info->local_subnet_mask = 0; -+ info->cmp = BANDWIDTH_MONITOR; /* don't test greater/less than, just monitor bandwidth */ -+ info->current_bandwidth = 0; -+ info->reset_is_constant_interval = 0; -+ info->reset_interval = BANDWIDTH_NEVER; -+ info->reset_time=0; -+ info->last_backup_time = 0; -+ info->next_reset = 0; -+ -+ info->num_intervals_to_save=0; -+ -+ info->non_const_self = NULL; -+ info->ref_count = NULL; -+ -+ *flags = *flags + BANDWIDTH_INITIALIZED; -+ } -+ -+ switch (c) -+ { -+ case BANDWIDTH_ID: -+ if(strlen(optarg) < BANDWIDTH_MAX_ID_LENGTH) -+ { -+ sprintf(info->id, "%s", optarg); -+ valid_arg = 1; -+ } -+ c=0; -+ break; -+ case BANDWIDTH_TYPE: -+ valid_arg = 1; -+ if(strcmp(optarg, "combined") == 0) -+ { -+ info->type = BANDWIDTH_COMBINED; -+ } -+ else if(strcmp(optarg, "individual_src") == 0) -+ { -+ info->type = BANDWIDTH_INDIVIDUAL_SRC; -+ } -+ else if(strcmp(optarg, "individual_dst") == 0) -+ { -+ info->type = BANDWIDTH_INDIVIDUAL_DST; -+ } -+ else if(strcmp(optarg, "individual_local") == 0) -+ { -+ info->type = BANDWIDTH_INDIVIDUAL_LOCAL; -+ *flags = *flags + BANDWIDTH_REQUIRES_SUBNET; -+ } -+ else if(strcmp(optarg, "individual_remote") == 0) -+ { -+ info->type = BANDWIDTH_INDIVIDUAL_REMOTE; -+ *flags = *flags + BANDWIDTH_REQUIRES_SUBNET; -+ } -+ else -+ { -+ valid_arg = 0; -+ } -+ -+ c=0; -+ break; -+ -+ case BANDWIDTH_SUBNET: -+ valid_arg = parse_sub(optarg, &(info->local_subnet), &(info->local_subnet_mask)); -+ break; -+ case BANDWIDTH_LT: -+ num_read = sscanf(argv[optind-1], "%lld", &read_64); -+ if(num_read > 0 && (*flags & BANDWIDTH_CMP) == 0) -+ { -+ info->cmp = BANDWIDTH_LT; -+ info->bandwidth_cutoff = read_64; -+ valid_arg = 1; -+ } -+ c = BANDWIDTH_CMP; //only need one flag for less_than/greater_than -+ break; -+ case BANDWIDTH_GT: -+ num_read = sscanf(argv[optind-1], "%lld", &read_64); -+ if(num_read > 0 && (*flags & BANDWIDTH_CMP) == 0) -+ { -+ info->cmp = BANDWIDTH_GT; -+ info->bandwidth_cutoff = read_64; -+ valid_arg = 1; -+ } -+ c = BANDWIDTH_CMP; //only need one flag for less_than/greater_than -+ break; -+ case BANDWIDTH_CHECK_NOSWAP: -+ if( (*flags & BANDWIDTH_CMP) == 0 ) -+ { -+ info->cmp = BANDWIDTH_CHECK; -+ info->check_type = BANDWIDTH_CHECK_NOSWAP; -+ valid_arg = 1; -+ } -+ c = BANDWIDTH_CMP; -+ break; -+ case BANDWIDTH_CHECK_SWAP: -+ if( (*flags & BANDWIDTH_CMP) == 0 ) -+ { -+ info->cmp = BANDWIDTH_CHECK; -+ info->check_type = BANDWIDTH_CHECK_SWAP; -+ valid_arg = 1; -+ } -+ c = BANDWIDTH_CMP; -+ break; -+ case BANDWIDTH_CURRENT: -+ num_read = sscanf(argv[optind-1], "%lld", &read_64); -+ if(num_read > 0 ) -+ { -+ info->current_bandwidth = read_64; -+ valid_arg = 1; -+ } -+ break; -+ case BANDWIDTH_RESET_INTERVAL: -+ valid_arg = 1; -+ if(strcmp(argv[optind-1],"minute") ==0) -+ { -+ info->reset_interval = BANDWIDTH_MINUTE; -+ info->reset_is_constant_interval = 0; -+ } -+ else if(strcmp(argv[optind-1],"hour") ==0) -+ { -+ info->reset_interval = BANDWIDTH_HOUR; -+ info->reset_is_constant_interval = 0; -+ } -+ else if(strcmp(argv[optind-1],"day") ==0) -+ { -+ info->reset_interval = BANDWIDTH_DAY; -+ info->reset_is_constant_interval = 0; -+ } -+ else if(strcmp(argv[optind-1],"week") ==0) -+ { -+ info->reset_interval = BANDWIDTH_WEEK; -+ info->reset_is_constant_interval = 0; -+ } -+ else if(strcmp(argv[optind-1],"month") ==0) -+ { -+ info->reset_interval = BANDWIDTH_MONTH; -+ info->reset_is_constant_interval = 0; -+ } -+ else if(strcmp(argv[optind-1],"never") ==0) -+ { -+ info->reset_interval = BANDWIDTH_NEVER; -+ } -+ else if(sscanf(argv[optind-1], "%ld", &read_time) > 0) -+ { -+ info->reset_interval = read_time; -+ info->reset_is_constant_interval = 1; -+ } -+ else -+ { -+ valid_arg = 0; -+ } -+ break; -+ case BANDWIDTH_NUM_INTERVALS: -+ if( sscanf(argv[optind-1], "%ld", &num_read) > 0) -+ { -+ info->num_intervals_to_save = num_read; -+ valid_arg=1; -+ } -+ c=0; -+ break; -+ case BANDWIDTH_RESET_TIME: -+ num_read = sscanf(argv[optind-1], "%ld", &read_time); -+ if(num_read > 0 ) -+ { -+ info->reset_time = read_time; -+ valid_arg = 1; -+ } -+ break; -+ case BANDWIDTH_LAST_BACKUP: -+ num_read = sscanf(argv[optind-1], "%ld", &read_time); -+ if(num_read > 0 ) -+ { -+ info->last_backup_time = read_time; -+ valid_arg = 1; -+ } -+ break; -+ } -+ *flags = *flags + (unsigned int)c; -+ -+ -+ //if we have both reset_interval & reset_time, check reset_time is in valid range -+ if((*flags & BANDWIDTH_RESET_TIME) == BANDWIDTH_RESET_TIME && (*flags & BANDWIDTH_RESET_INTERVAL) == BANDWIDTH_RESET_INTERVAL) -+ { -+ if( (info->reset_interval == BANDWIDTH_NEVER) || -+ (info->reset_interval == BANDWIDTH_MONTH && info->reset_time >= 60*60*24*28) || -+ (info->reset_interval == BANDWIDTH_WEEK && info->reset_time >= 60*60*24*7) || -+ (info->reset_interval == BANDWIDTH_DAY && info->reset_time >= 60*60*24) || -+ (info->reset_interval == BANDWIDTH_HOUR && info->reset_time >= 60*60) || -+ (info->reset_interval == BANDWIDTH_MINUTE && info->reset_time >= 60) -+ ) -+ { -+ valid_arg = 0; -+ param_problem_exit_error("Parameter for '--reset_time' is not in valid range"); -+ } -+ } -+ if(info->type != BANDWIDTH_COMBINED && (*flags & BANDWIDTH_CURRENT) == BANDWIDTH_CURRENT) -+ { -+ valid_arg = 0; -+ param_problem_exit_error("You may only specify current bandwidth for combined type\n Use user-space library for setting bandwidth for individual types"); -+ } -+ -+ return valid_arg; -+} -+ -+ -+ -+static void print_bandwidth_args( struct ipt_bandwidth_info* info ) -+{ -+ if(info->cmp == BANDWIDTH_CHECK) -+ { -+ if(info->check_type == BANDWIDTH_CHECK_NOSWAP) -+ { -+ printf("--bcheck "); -+ } -+ else -+ { -+ printf("--bcheck_with_src_dst_swap "); -+ } -+ } -+ printf("--id %s ", info->id); -+ -+ -+ -+ if(info->cmp != BANDWIDTH_CHECK) -+ { -+ /* determine current time in seconds since epoch, with offset for current timezone */ -+ int minuteswest = get_minutes_west(); -+ time_t now; -+ time(&now); -+ now = now - (minuteswest*60); -+ -+ if(info->type == BANDWIDTH_COMBINED) -+ { -+ printf("--type combined "); -+ } -+ if(info->type == BANDWIDTH_INDIVIDUAL_SRC) -+ { -+ printf("--type individual_src "); -+ } -+ if(info->type == BANDWIDTH_INDIVIDUAL_DST) -+ { -+ printf("--type individual_dst "); -+ } -+ if(info->type == BANDWIDTH_INDIVIDUAL_LOCAL) -+ { -+ printf("--type individual_local "); -+ } -+ if(info->type == BANDWIDTH_INDIVIDUAL_REMOTE) -+ { -+ printf("--type individual_remote "); -+ } -+ -+ -+ if(info->local_subnet != 0) -+ { -+ unsigned char* sub = (unsigned char*)(&(info->local_subnet)); -+ int msk_bits=0; -+ int pow=0; -+ for(pow=0; pow<32; pow++) -+ { -+ uint32_t test = get_pow(2, pow); -+ msk_bits = ( (info->local_subnet_mask & test) == test) ? msk_bits+1 : msk_bits; -+ } -+ printf("--subnet %u.%u.%u.%u/%u ", (unsigned char)sub[0], (unsigned char)sub[1], (unsigned char)sub[2], (unsigned char)sub[3], msk_bits); -+ } -+ if(info->cmp == BANDWIDTH_GT) -+ { -+ printf("--greater_than %lld ", info->bandwidth_cutoff); -+ } -+ if(info->cmp == BANDWIDTH_LT) -+ { -+ printf("--less_than %lld ", info->bandwidth_cutoff); -+ } -+ if (info->type == BANDWIDTH_COMBINED) /* too much data to print for multi types, have to use socket to get/set data */ -+ { -+ if( info->reset_interval != BANDWIDTH_NEVER && info->next_reset != 0 && info->next_reset < now) -+ { -+ /* -+ * current bandwidth only gets reset when first packet after reset interval arrives, so output -+ * zero if we're already past interval, but no packets have arrived -+ */ -+ printf("--current_bandwidth 0 "); -+ } -+ else -+ { -+ printf("--current_bandwidth %lld ", info->current_bandwidth); -+ } -+ } -+ if(info->reset_is_constant_interval) -+ { -+ printf("--reset_interval %ld ", info->reset_interval); -+ } -+ else -+ { -+ if(info->reset_interval == BANDWIDTH_MINUTE) -+ { -+ printf("--reset_interval minute "); -+ } -+ else if(info->reset_interval == BANDWIDTH_HOUR) -+ { -+ printf("--reset_interval hour "); -+ } -+ else if(info->reset_interval == BANDWIDTH_DAY) -+ { -+ printf("--reset_interval day "); -+ } -+ else if(info->reset_interval == BANDWIDTH_WEEK) -+ { -+ printf("--reset_interval week "); -+ } -+ else if(info->reset_interval == BANDWIDTH_MONTH) -+ { -+ printf("--reset_interval month "); -+ } -+ } -+ if(info->reset_time > 0) -+ { -+ printf("--reset_time %ld ", info->reset_time); -+ } -+ if(info->num_intervals_to_save > 0) -+ { -+ printf("--intervals_to_save %d ", info->num_intervals_to_save); -+ } -+ } -+} -+ -+/* -+ * Final check, we can't have reset_time without reset_interval -+ */ -+static void final_check(unsigned int flags) -+{ -+ if (flags == 0) -+ { -+ param_problem_exit_error("You must specify at least one argument. "); -+ } -+ if( (flags & BANDWIDTH_RESET_INTERVAL) == 0 && (flags & BANDWIDTH_RESET_TIME) != 0) -+ { -+ param_problem_exit_error("You may not specify '--reset_time' without '--reset_interval' "); -+ } -+ if( (flags & BANDWIDTH_REQUIRES_SUBNET) == BANDWIDTH_REQUIRES_SUBNET && (flags & BANDWIDTH_SUBNET) == 0 ) -+ { -+ param_problem_exit_error("You must specify a local subnet (--subnet a.b.c.d/mask) to match individual local/remote IPs "); -+ } -+ -+ /* update timezone minutes_west in kernel to match userspace*/ -+ set_kernel_timezone(); -+} -+ -+/* Prints out the matchinfo. */ -+#ifdef _XTABLES_H -+static void print(const void *ip, const struct xt_entry_match *match, int numeric) -+#else -+static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric) -+#endif -+{ -+ printf("bandwidth "); -+ struct ipt_bandwidth_info *info = (struct ipt_bandwidth_info *)match->data; -+ -+ print_bandwidth_args(info); -+} -+ -+/* Saves the union ipt_matchinfo in parsable form to stdout. */ -+#ifdef _XTABLES_H -+static void save(const void *ip, const struct xt_entry_match *match) -+#else -+static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) -+#endif -+{ -+ struct ipt_bandwidth_info *info = (struct ipt_bandwidth_info *)match->data; -+ time_t now; -+ -+ print_bandwidth_args(info); -+ -+ time(&now); -+ printf("--last_backup-time %ld ", now); -+} -+ -+static struct iptables_match bandwidth = -+{ -+ .next = NULL, -+ .name = "bandwidth", -+ #ifdef XTABLES_VERSION_CODE -+ .version = XTABLES_VERSION, -+ #else -+ .version = IPTABLES_VERSION, -+ #endif -+ .size = XT_ALIGN(sizeof(struct ipt_bandwidth_info)), -+ .userspacesize = XT_ALIGN(sizeof(struct ipt_bandwidth_info)), -+ .help = &help, -+ .parse = &parse, -+ .final_check = &final_check, -+ .print = &print, -+ .save = &save, -+ .extra_opts = opts -+}; -+ -+void _init(void) -+{ -+ register_match(&bandwidth); -+} -+ -+static void param_problem_exit_error(char* msg) -+{ -+ #ifdef xtables_error -+ xtables_error(PARAMETER_PROBLEM, "%s", msg); -+ #else -+ exit_error(PARAMETER_PROBLEM, msg); -+ #endif -+} -+ -+/* -+ * implement a simple function to get positive powers of positive integers so we don't have to mess with math.h -+ * all we really need are powers of 2 for calculating netmask -+ * This is only called a couple of times, so speed isn't an issue either -+ */ -+static unsigned long get_pow(unsigned long base, unsigned long pow) -+{ -+ unsigned long ret = pow == 0 ? 1 : base*get_pow(base, pow-1); -+ return ret; -+} -+ -+ -+int parse_sub(char* subnet_string, uint32_t* subnet, uint32_t* subnet_mask) -+{ -+ -+ int valid = 0; -+ unsigned int A,B,C,D,E,F,G,H; -+ int read_int = sscanf(subnet_string, "%u.%u.%u.%u/%u.%u.%u.%u", &A, &B, &C, &D, &E, &F, &G, &H); -+ if(read_int >= 5) -+ { -+ if( A <= 255 && B <= 255 && C <= 255 && D <= 255) -+ { -+ unsigned char* sub = (unsigned char*)(subnet); -+ unsigned char* msk = (unsigned char*)(subnet_mask); -+ -+ *( sub ) = (unsigned char)A; -+ *( sub + 1 ) = (unsigned char)B; -+ *( sub + 2 ) = (unsigned char)C; -+ *( sub + 3 ) = (unsigned char)D; -+ -+ if(read_int == 5) -+ { -+ unsigned int mask = E; -+ if(mask <= 32) -+ { -+ int msk_index; -+ for(msk_index=0; msk_index*8 < mask; msk_index++) -+ { -+ int bit_index; -+ msk[msk_index] = 0; -+ for(bit_index=0; msk_index*8 + bit_index < mask && bit_index < 8; bit_index++) -+ { -+ msk[msk_index] = msk[msk_index] + get_pow(2, 7-bit_index); -+ } -+ } -+ } -+ valid = 1; -+ } -+ if(read_int == 8) -+ { -+ if( E <= 255 && F <= 255 && G <= 255 && H <= 255) -+ *( msk ) = (unsigned char)E; -+ *( msk + 1 ) = (unsigned char)F; -+ *( msk + 2 ) = (unsigned char)G; -+ *( msk + 3 ) = (unsigned char)H; -+ valid = 1; -+ } -+ } -+ } -+ if(valid) -+ { -+ *subnet = (*subnet & *subnet_mask ); -+ } -+ return valid; -+} -+ -+ -+ -+int get_minutes_west(void) -+{ -+ time_t now; -+ struct tm* utc_info; -+ struct tm* tz_info; -+ int utc_day; -+ int utc_hour; -+ int utc_minute; -+ int tz_day; -+ int tz_hour; -+ int tz_minute; -+ int minuteswest; -+ -+ time(&now); -+ utc_info = gmtime(&now); -+ utc_day = utc_info->tm_mday; -+ utc_hour = utc_info->tm_hour; -+ utc_minute = utc_info->tm_min; -+ tz_info = localtime(&now); -+ tz_day = tz_info->tm_mday; -+ tz_hour = tz_info->tm_hour; -+ tz_minute = tz_info->tm_min; -+ -+ utc_day = utc_day < tz_day - 1 ? tz_day + 1 : utc_day; -+ tz_day = tz_day < utc_day - 1 ? utc_day + 1 : tz_day; -+ -+ minuteswest = (24*60*utc_day + 60*utc_hour + utc_minute) - (24*60*tz_day + 60*tz_hour + tz_minute) ; -+ -+ return minuteswest; -+} -+ -+void set_kernel_timezone(void) -+{ -+ struct timeval tv; -+ struct timezone old_tz; -+ struct timezone new_tz; -+ -+ new_tz.tz_minuteswest = get_minutes_west();; -+ new_tz.tz_dsttime = 0; -+ -+ /* Get tv to pass to settimeofday(2) to be sure we avoid hour-sized warp */ -+ /* (see gettimeofday(2) man page, or /usr/src/linux/kernel/time.c) */ -+ gettimeofday(&tv, &old_tz); -+ -+ /* set timezone */ -+ settimeofday(&tv, &new_tz); -+} - ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ipt_bandwidth.h -@@ -0,0 +1,106 @@ -+/* bandwidth -- An iptables extension for bandwidth monitoring/control -+ * Can be used to efficiently monitor bandwidth and/or implement bandwidth quotas -+ * Can be queried using the iptbwctl userspace library -+ * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) -+ * -+ * -+ * Copyright © 2009 by Eric Bishop -+ * -+ * This file is free software: you may copy, redistribute and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+#ifndef _IPT_BANDWIDTH_H -+#define _IPT_BANDWIDTH_H -+ -+/*flags -- first three don't map to parameters the rest do */ -+#define BANDWIDTH_INITIALIZED 1 -+#define BANDWIDTH_REQUIRES_SUBNET 2 -+#define BANDWIDTH_SUBNET 4 -+#define BANDWIDTH_CMP 8 -+#define BANDWIDTH_CURRENT 16 -+#define BANDWIDTH_RESET_INTERVAL 32 -+#define BANDWIDTH_RESET_TIME 64 -+#define BANDWIDTH_LAST_BACKUP 128 -+ -+ -+/* parameter defs that don't map to flag bits */ -+#define BANDWIDTH_TYPE 70 -+#define BANDWIDTH_ID 71 -+#define BANDWIDTH_GT 72 -+#define BANDWIDTH_LT 73 -+#define BANDWIDTH_MONITOR 74 -+#define BANDWIDTH_CHECK 75 -+#define BANDWIDTH_CHECK_NOSWAP 76 -+#define BANDWIDTH_CHECK_SWAP 77 -+#define BANDWIDTH_NUM_INTERVALS 78 -+ -+/* possible reset intervals */ -+#define BANDWIDTH_MINUTE 80 -+#define BANDWIDTH_HOUR 81 -+#define BANDWIDTH_DAY 82 -+#define BANDWIDTH_WEEK 83 -+#define BANDWIDTH_MONTH 84 -+#define BANDWIDTH_NEVER 85 -+ -+/* possible monitoring types */ -+#define BANDWIDTH_COMBINED 90 -+#define BANDWIDTH_INDIVIDUAL_SRC 91 -+#define BANDWIDTH_INDIVIDUAL_DST 92 -+#define BANDWIDTH_INDIVIDUAL_LOCAL 93 -+#define BANDWIDTH_INDIVIDUAL_REMOTE 94 -+ -+ -+ -+/* socket id parameters (for userspace i/o) */ -+#define BANDWIDTH_SET 2048 -+#define BANDWIDTH_GET 2049 -+ -+/* max id length */ -+#define BANDWIDTH_MAX_ID_LENGTH 50 -+ -+/* 4 bytes for total number of entries, 100 entries of 12 bytes each, + 1 byte indicating whether all have been dumped */ -+#define BANDWIDTH_QUERY_LENGTH 1205 -+#define BANDWIDTH_ENTRY_LENGTH 12 -+ -+ -+struct ipt_bandwidth_info -+{ -+ char id[BANDWIDTH_MAX_ID_LENGTH]; -+ unsigned char type; -+ unsigned char check_type; -+ uint32_t local_subnet; -+ uint32_t local_subnet_mask; -+ -+ unsigned char cmp; -+ unsigned char reset_is_constant_interval; -+ time_t reset_interval; //specific fixed type (see above) or interval length in seconds -+ time_t reset_time; //seconds from start of month/week/day/hour/minute to do reset, or start point of interval if it is a constant interval -+ uint64_t bandwidth_cutoff; -+ uint64_t current_bandwidth; -+ time_t next_reset; -+ time_t previous_reset; -+ time_t last_backup_time; -+ -+ uint32_t num_intervals_to_save; -+ -+ -+ unsigned long hashed_id; -+ void* iam; -+ uint64_t* combined_bw; -+ struct ipt_bandwidth_info* non_const_self; -+ unsigned long* ref_count; -+ -+ -+}; -+#endif /*_IPT_BANDWIDTH_H*/ - ---- /dev/null -+++ b/extensions/libipt_timerange.c -@@ -0,0 +1,876 @@ -+/* timerange -- An iptables extension to match multiple timeranges within a week -+ * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) -+ * -+ * -+ * Copyright © 2009-2010 by Eric Bishop -+ * -+ * This file is free software: you may copy, redistribute and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+/* -+ * in iptables 1.4.0 and higher, iptables.h includes xtables.h, which -+ * we can use to check whether we need to deal with the new requirements -+ * in pre-processor directives below -+ */ -+#include -+#include -+ -+#ifdef _XTABLES_H -+ #define iptables_rule_match xtables_rule_match -+ #define iptables_match xtables_match -+ #define iptables_target xtables_target -+ #define ipt_tryload xt_tryload -+#endif -+ -+/* -+ * XTABLES_VERSION_CODE is only defined in versions 1.4.1 and later, which -+ * also require the use of xtables_register_match -+ * -+ * Version 1.4.0 uses register_match like previous versions -+ */ -+#ifdef XTABLES_VERSION_CODE -+ #define register_match xtables_register_match -+#endif -+ -+/* utility functions necessary for module to work across multiple iptables versions */ -+static int my_check_inverse(const char option[], int* invert, int *my_optind, int argc); -+static void param_problem_exit_error(char* msg); -+ -+ -+long* parse_time_ranges(char* time_ranges, unsigned char is_weekly_range); -+void merge_adjacent_time_ranges(long* time_ranges, unsigned char is_weekly_range); -+unsigned long parse_time(char* time_str); -+long* parse_weekdays(char* wd_str); -+ -+char** split_on_separators(char* line, char* separators, int num_separators, int max_pieces, int include_remainder_at_max); -+void to_lowercase(char* str); -+char* trim_flanking_whitespace(char* str); -+ -+void set_kernel_timezone(void); -+ -+/* Function which prints out usage message. */ -+static void help(void) -+{ -+ printf( "timerange options:\n --hours [HOURLY RANGES] --weekdays [WEEKDAYS ACTIVE] --weekly_ranges [WEEKLY RANGES]\n"); -+} -+ -+static struct option opts[] = -+{ -+ { .name = "hours", .has_arg = 1, .flag = 0, .val = HOURS }, -+ { .name = "weekdays", .has_arg = 1, .flag = 0, .val = WEEKDAYS }, -+ { .name = "weekly_ranges", .has_arg = 1, .flag = 0, .val = WEEKLY_RANGE }, -+ { .name = 0 } -+}; -+ -+ -+/* Function which parses command options; returns true if it -+ ate an option */ -+static int parse( int c, -+ char **argv, -+ int invert, -+ unsigned int *flags, -+#ifdef _XTABLES_H -+ const void *entry, -+#else -+ const struct ipt_entry *entry, -+ unsigned int *nfcache, -+#endif -+ struct ipt_entry_match **match -+ ) -+{ -+ struct ipt_timerange_info *info = (struct ipt_timerange_info *)(*match)->data; -+ int valid_arg = 0; -+ if(*flags == 0) -+ { -+ my_check_inverse(optarg, &invert, &optind, 0); -+ info->invert = invert ? 1 : 0; -+ } -+ -+ long* parsed = NULL; -+ switch (c) -+ { -+ case HOURS: -+ parsed = parse_time_ranges(argv[optind-1], 0); -+ if(parsed != NULL && (*flags & HOURS) == 0 && (*flags & WEEKLY_RANGE) == 0) -+ { -+ int range_index = 0; -+ for(range_index = 0; parsed[range_index] != -1; range_index++) -+ { -+ if(range_index > 100) -+ { -+ return 0; -+ } -+ info->ranges[range_index] = parsed[range_index]; -+ } -+ info->ranges[range_index] = -1; -+ free(parsed); -+ -+ -+ valid_arg = 1; -+ *flags = *flags+ c; -+ info->type = *flags; -+ } -+ break; -+ -+ -+ case WEEKDAYS: -+ parsed = parse_weekdays(argv[optind-1]); -+ if(parsed != NULL && (*flags & WEEKDAYS) == 0 && (*flags & WEEKLY_RANGE) == 0) -+ { -+ int day_index; -+ for(day_index=0; day_index < 7; day_index++) -+ { -+ info->days[day_index] = parsed[day_index]; -+ } -+ free(parsed); -+ -+ valid_arg = 1 ; -+ *flags = *flags + c; -+ info->type = *flags; -+ } -+ break; -+ case WEEKLY_RANGE: -+ parsed = parse_time_ranges(argv[optind-1], 1); -+ if(parsed != NULL && (*flags & HOURS) == 0 && (*flags & WEEKDAYS) == 0 && (*flags & WEEKLY_RANGE) == 0 ) -+ { -+ int range_index = 0; -+ for(range_index = 0; parsed[range_index] != -1; range_index++) -+ { -+ if(range_index > 100) -+ { -+ return 0; -+ } -+ info->ranges[range_index] = parsed[range_index]; -+ -+ } -+ info->ranges[range_index] = -1; -+ free(parsed); -+ -+ valid_arg = 1; -+ *flags = *flags+c; -+ info->type = *flags; -+ } -+ break; -+ } -+ -+ return valid_arg; -+} -+ -+ -+ -+static void print_timerange_args( struct ipt_timerange_info* info ) -+{ -+ int i; -+ -+ if(info->invert == 1) -+ { -+ printf(" ! "); -+ } -+ -+ switch(info->type) -+ { -+ case DAYS_HOURS: -+ case HOURS: -+ printf(" --hours "); -+ for(i=0; info->ranges[i] != -1; i++) -+ { -+ printf("%ld", info->ranges[i]); -+ if(info->ranges[i+1] != -1) -+ { -+ if(i % 2 == 0){ printf("-"); } -+ else { printf(","); } -+ } -+ } -+ if(info->type == HOURS) { break; } -+ case WEEKDAYS: -+ printf(" --weekdays "); -+ for(i=0; i<7; i++) -+ { -+ printf("%d", info->days[i]); -+ if(i != 6){ printf(","); } -+ } -+ break; -+ case WEEKLY_RANGE: -+ printf(" --weekly_ranges "); -+ for(i=0; info->ranges[i] != -1; i++) -+ { -+ printf("%ld", info->ranges[i]); -+ if(info->ranges[i+1] != -1) -+ { -+ if(i % 2 == 0){ printf("-"); } -+ else { printf(","); } -+ } -+ } -+ break; -+ } -+ printf(" "); -+ -+} -+ -+/* Final check; must have specified a test string with either --contains or --contains_regex. */ -+static void final_check(unsigned int flags) -+{ -+ if(flags ==0) -+ { -+ param_problem_exit_error("Invalid arguments to time_range"); -+ } -+ -+ /* update timezone minutes_west in kernel to match userspace*/ -+ set_kernel_timezone(); -+} -+ -+/* Prints out the matchinfo. */ -+#ifdef _XTABLES_H -+static void print(const void *ip, const struct xt_entry_match *match, int numeric) -+#else -+static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric) -+#endif -+{ -+ printf("timerange "); -+ struct ipt_timerange_info *info = (struct ipt_timerange_info *)match->data; -+ -+ print_timerange_args(info); -+} -+ -+/* Saves the union ipt_matchinfo in parsable form to stdout. */ -+#ifdef _XTABLES_H -+static void save(const void *ip, const struct xt_entry_match *match) -+#else -+static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) -+#endif -+{ -+ struct ipt_timerange_info *info = (struct ipt_timerange_info *)match->data; -+ print_timerange_args(info); -+} -+ -+static struct iptables_match timerange = -+{ -+ .next = NULL, -+ .name = "timerange", -+ #ifdef XTABLES_VERSION_CODE -+ .version = XTABLES_VERSION, -+ #else -+ .version = IPTABLES_VERSION, -+ #endif -+ .size = XT_ALIGN(sizeof(struct ipt_timerange_info)), -+ .userspacesize = XT_ALIGN(sizeof(struct ipt_timerange_info)), -+ .help = &help, -+ .parse = &parse, -+ .final_check = &final_check, -+ .print = &print, -+ .save = &save, -+ .extra_opts = opts -+}; -+ -+void _init(void) -+{ -+ register_match(&timerange); -+} -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+#ifndef FALSE -+#define FALSE 0 -+#endif -+static int my_check_inverse(const char option[], int* invert, int *my_optind, int argc) -+{ -+ if (option && strcmp(option, "!") == 0) -+ { -+ if (*invert) -+ { -+ param_problem_exit_error("Multiple `!' flags not allowed"); -+ } -+ *invert = TRUE; -+ if (my_optind != NULL) -+ { -+ ++*my_optind; -+ if (argc && *my_optind > argc) -+ { -+ param_problem_exit_error("no argument following `!'"); -+ } -+ } -+ return TRUE; -+ } -+ return FALSE; -+} -+static void param_problem_exit_error(char* msg) -+{ -+ #ifdef xtables_error -+ xtables_error(PARAMETER_PROBLEM, "%s", msg); -+ #else -+ exit_error(PARAMETER_PROBLEM, msg); -+ #endif -+} -+ -+/* takes a string of days e.g. "Monday, Tuesday, Friday", and turns into an array of 7 longs -+ * each 0 or 1, one for each weekday starting with sunday, e.g. [0,1,1,0,0,1,0] for our example -+ */ -+long* parse_weekdays(char* wd_str) -+{ -+ long* weekdays = (long*)malloc(7*sizeof(long)); -+ weekdays[0] = weekdays[1] = weekdays[2] = weekdays[3] = weekdays[4] = weekdays[5] = weekdays[6] = 0; -+ -+ char** days = split_on_separators(wd_str, ",", 1, -1, 0); -+ int day_index; -+ int found = 0; -+ for(day_index=0; days[day_index] != NULL; day_index++) -+ { -+ char day[4]; -+ trim_flanking_whitespace(days[day_index]); -+ memcpy(day, days[day_index], 3); -+ free(days[day_index]); -+ day[3] = '\0'; -+ to_lowercase(day); -+ if(strcmp(day, "sun") == 0) -+ { -+ weekdays[0] = 1; -+ found = 1; -+ } -+ else if(strcmp(day, "mon") ==0) -+ { -+ weekdays[1] = 1; -+ found = 1; -+ } -+ else if(strcmp(day, "tue") ==0) -+ { -+ weekdays[2] = 1; -+ found = 1; -+ } -+ else if(strcmp(day, "wed") ==0) -+ { -+ weekdays[3] = 1; -+ found = 1; -+ } -+ else if(strcmp(day, "thu") ==0) -+ { -+ weekdays[4] = 1; -+ found = 1; -+ } -+ else if(strcmp(day, "fri") ==0) -+ { -+ weekdays[5] = 1; -+ found = 1; -+ } -+ else if(strcmp(day, "sat") ==0) -+ { -+ weekdays[6] = 1; -+ found = 1; -+ } -+ else if(strcmp(day, "all") ==0) -+ { -+ weekdays[0] = weekdays[1] = weekdays[2] = weekdays[3] = weekdays[4] = weekdays[5] = weekdays[6] = 1; -+ found = 1; -+ } -+ } -+ free(days); -+ if(found == 0) -+ { -+ free(weekdays); -+ weekdays = NULL; -+ } -+ return weekdays; -+} -+ -+ -+/* is_weekly_range indicates whether we're parsing hours within a single day or a range over a whole week */ -+long* parse_time_ranges(char* time_ranges, unsigned char is_weekly_range) -+{ -+ char** pieces = split_on_separators(time_ranges, ",", 1, -1, 0); -+ int num_pieces = 0; -+ for(num_pieces = 0; pieces[num_pieces] != NULL; num_pieces++) {}; -+ long *parsed = (long*)malloc( (1+(num_pieces*2)) * sizeof(long)); -+ -+ -+ -+ int piece_index = 0; -+ for(piece_index = 0; pieces[piece_index] != NULL; piece_index++) -+ { -+ trim_flanking_whitespace(pieces[piece_index]); -+ char** times=split_on_separators(pieces[piece_index], "-", 1, 2, 0); -+ int time_count = 0; -+ for(time_count = 0; times[time_count] != 0 ; time_count++){} -+ if( time_count == 2 ) -+ { -+ unsigned long start = parse_time(trim_flanking_whitespace(times[0])); -+ unsigned long end = parse_time(trim_flanking_whitespace(times[1])); -+ parsed[ piece_index*2 ] = (long)start; -+ parsed[ (piece_index*2)+1 ] = (long)end; -+ -+ free( times[1] ); -+ } -+ if( time_count > 0) { free(times[0]); } -+ -+ free(times); -+ free(pieces[piece_index]); -+ } -+ free(pieces); -+ parsed[ (num_pieces*2) ] = -1; // terminated with -1 -+ -+ -+ // make sure there is no overlap -- this will invalidate ranges -+ int range_index = 0; -+ char overlap_found = 0; -+ for(range_index = 0; range_index < num_pieces; range_index++) -+ { -+ // now test for overlap -+ long start1 = parsed[ (range_index*2) ]; -+ long end1 = parsed[ (range_index*2)+1 ]; -+ end1= end1 < start1 ? end1 + (is_weekly_range ? 7*24*60*60 : 24*60*60) : end1; -+ -+ int range_index2 = 0; -+ for(range_index2 = 0; range_index2 < num_pieces; range_index2++) -+ { -+ if(range_index2 != range_index) -+ { -+ long start2 = parsed[ (range_index2*2) ]; -+ long end2 = parsed[ (range_index2*2)+1 ]; -+ end2= end2 < start2 ? end2 + (is_weekly_range ? 7*24*60*60 : 24*60*60) : end2; -+ overlap_found = overlap_found || (start1 < end2 && end1 > start2 ); -+ } -+ } -+ } -+ -+ if(!overlap_found) -+ { -+ // sort ranges -+ int sorted_index = 0; -+ while(parsed[sorted_index] != -1) -+ { -+ int next_start=-1; -+ int next_start_index=-1; -+ int test_index; -+ long tmp1; -+ long tmp2; -+ for(test_index=sorted_index; parsed[test_index] != -1; test_index=test_index+2) -+ { -+ next_start_index = next_start < 0 || next_start > parsed[test_index] ? test_index : next_start_index; -+ next_start = next_start < 0 || next_start > parsed[test_index] ? parsed[test_index] : next_start; -+ } -+ tmp1 = parsed[next_start_index]; -+ tmp2 = parsed[next_start_index+1]; -+ parsed[next_start_index] = parsed[sorted_index]; -+ parsed[next_start_index+1] = parsed[sorted_index+1]; -+ parsed[sorted_index] = tmp1; -+ parsed[sorted_index+1] = tmp2; -+ sorted_index = sorted_index + 2; -+ } -+ } -+ else -+ { -+ // de-allocate parsed, set to NULL -+ free(parsed); -+ parsed = NULL; -+ } -+ -+ // merge time ranges where end of first = start of second -+ merge_adjacent_time_ranges(parsed, is_weekly_range); -+ -+ -+ // if always active, free & return NULL -+ int max_multiple = is_weekly_range ? 7 : 1; -+ if(parsed[0] == 0 && parsed[1] == max_multiple*24*60*60) -+ { -+ free(parsed); -+ parsed = NULL; -+ } -+ -+ -+ //adjust so any range that crosses end of range is split in two -+ int num_range_indices=0; -+ for(num_range_indices=0; parsed[num_range_indices] != -1; num_range_indices++){} -+ -+ long* adjusted_range = (long*)malloc((3+num_range_indices)*sizeof(long)); -+ int ar_index = 0; -+ int old_index = 0; -+ if(parsed[num_range_indices-1] < parsed[0]) -+ { -+ adjusted_range[0] = 0; -+ adjusted_range[1] = parsed[num_range_indices-1]; -+ ar_index = ar_index + 2; -+ parsed[num_range_indices-1] = -1; -+ } -+ for(old_index=0; parsed[old_index] != -1; old_index++) -+ { -+ adjusted_range[ar_index] = parsed[old_index]; -+ ar_index++; -+ } -+ -+ if(ar_index % 2 == 1 ) -+ { -+ adjusted_range[ar_index] = is_weekly_range ? 7*24*60*60 : 24*60*60; -+ ar_index++; -+ } -+ adjusted_range[ar_index] = -1; -+ free(parsed); -+ -+ return adjusted_range; -+} -+ -+ -+ -+void merge_adjacent_time_ranges(long* time_ranges, unsigned char is_weekly_range) -+{ -+ int range_length = 0; -+ while(time_ranges[range_length] != -1){ range_length++; } -+ int* merged_indices = (int*)malloc((range_length+1)*sizeof(int)); -+ -+ int merged_index=0; -+ int next_index; -+ for(next_index=0; time_ranges[next_index] != -1; next_index++) -+ { -+ if(next_index == 0) -+ { -+ merged_indices[merged_index] = next_index; -+ merged_index++; -+ } -+ else if( time_ranges[next_index+1] == -1 ) -+ { -+ merged_indices[merged_index] = next_index; -+ merged_index++; -+ } -+ else if( time_ranges[next_index] != time_ranges[next_index-1] && time_ranges[next_index] != time_ranges[next_index+1] ) -+ { -+ merged_indices[merged_index] = next_index; -+ merged_index++; -+ } -+ } -+ merged_indices[merged_index] = -1; -+ -+ for(next_index=0; merged_indices[next_index] != -1; next_index++) -+ { -+ time_ranges[next_index] = time_ranges[ merged_indices[next_index] ]; -+ } -+ time_ranges[next_index] = -1; -+ free(merged_indices); -+ -+} -+ -+ -+ -+ -+/* -+ * assumes 24hr time, not am/pm, in format: -+ * (Day of week) hours:minutes:seconds -+ * if day of week is present, returns seconds since midnight on Sunday -+ * otherwise, seconds since midnight -+ */ -+unsigned long parse_time(char* time_str) -+{ -+ while((*time_str == ' ' || *time_str == '\t') && *time_str != '\0') { time_str++; } -+ -+ int weekday = -1; -+ if(strlen(time_str) > 3) -+ { -+ char wday_test[4]; -+ memcpy(wday_test, time_str, 3); -+ wday_test[3] = '\0'; -+ to_lowercase(wday_test); -+ if(strcmp(wday_test, "sun") == 0) -+ { -+ weekday = 0; -+ } -+ else if(strcmp(wday_test, "mon") == 0) -+ { -+ weekday = 1; -+ } -+ else if(strcmp(wday_test, "tue") == 0) -+ { -+ weekday = 2; -+ } -+ else if(strcmp(wday_test, "wed") == 0) -+ { -+ weekday = 3; -+ } -+ else if(strcmp(wday_test, "thu") == 0) -+ { -+ weekday = 4; -+ } -+ else if(strcmp(wday_test, "fri") == 0) -+ { -+ weekday = 5; -+ } -+ else if(strcmp(wday_test, "sat") == 0) -+ { -+ weekday = 6; -+ } -+ } -+ -+ if(weekday >= 0) -+ { -+ time_str = time_str + 3; -+ while( (*time_str < 48 || *time_str > 57) && *time_str != '\0') { time_str++; } -+ } -+ -+ char** time_parts=split_on_separators(time_str, ":", 1, -1, 0); -+ unsigned long seconds = weekday < 0 ? 0 : ( ((unsigned long)(weekday))*60*60*24 ); -+ unsigned long tmp; -+ unsigned long multiple = 60*60; -+ -+ int tp_index = 0; -+ for(tp_index=0; time_parts[tp_index] != NULL; tp_index++) -+ { -+ sscanf(time_parts[tp_index], "%ld", &tmp); -+ seconds = seconds + (tmp*multiple); -+ multiple = (unsigned long)(multiple/60); -+ free(time_parts[tp_index]); -+ } -+ free(time_parts); -+ -+ return seconds; -+} -+ -+void to_lowercase(char* str) -+{ -+ int i; -+ for(i = 0; str[i] != '\0'; i++) -+ { -+ str[i] = tolower(str[i]); -+ } -+} -+ -+/* -+ * line_str is the line to be parsed -- it is not modified in any way -+ * max_pieces indicates number of pieces to return, if negative this is determined dynamically -+ * include_remainder_at_max indicates whether the last piece, when max pieces are reached, -+ * should be what it would normally be (0) or the entire remainder of the line (1) -+ * if max_pieces < 0 this parameter is ignored -+ * -+ * -+ * returns all non-separator pieces in a line -+ * result is dynamically allocated, MUST be freed after call-- even if -+ * line is empty (you still get a valid char** pointer to to a NULL char*) -+ */ -+char** split_on_separators(char* line_str, char* separators, int num_separators, int max_pieces, int include_remainder_at_max) -+{ -+ char** split; -+ -+ if(line_str != NULL) -+ { -+ int split_index; -+ int non_separator_found; -+ char* dup_line; -+ char* start; -+ -+ if(max_pieces < 0) -+ { -+ /* count number of separator characters in line -- this count + 1 is an upperbound on number of pieces */ -+ int separator_count = 0; -+ int line_index; -+ for(line_index = 0; line_str[line_index] != '\0'; line_index++) -+ { -+ int sep_index; -+ int found = 0; -+ for(sep_index =0; found == 0 && sep_index < num_separators; sep_index++) -+ { -+ found = separators[sep_index] == line_str[line_index] ? 1 : 0; -+ } -+ separator_count = separator_count+ found; -+ } -+ max_pieces = separator_count + 1; -+ } -+ split = (char**)malloc((1+max_pieces)*sizeof(char*)); -+ split_index = 0; -+ split[split_index] = NULL; -+ -+ -+ dup_line = strdup(line_str); -+ start = dup_line; -+ non_separator_found = 0; -+ while(non_separator_found == 0) -+ { -+ int matches = 0; -+ int sep_index; -+ for(sep_index =0; sep_index < num_separators; sep_index++) -+ { -+ matches = matches == 1 || separators[sep_index] == start[0] ? 1 : 0; -+ } -+ non_separator_found = matches==0 || start[0] == '\0' ? 1 : 0; -+ if(non_separator_found == 0) -+ { -+ start++; -+ } -+ } -+ -+ while(start[0] != '\0' && split_index < max_pieces) -+ { -+ /* find first separator index */ -+ int first_separator_index = 0; -+ int separator_found = 0; -+ while( separator_found == 0 ) -+ { -+ int sep_index; -+ for(sep_index =0; separator_found == 0 && sep_index < num_separators; sep_index++) -+ { -+ separator_found = separators[sep_index] == start[first_separator_index] || start[first_separator_index] == '\0' ? 1 : 0; -+ } -+ if(separator_found == 0) -+ { -+ first_separator_index++; -+ } -+ } -+ -+ /* copy next piece to split array */ -+ if(first_separator_index > 0) -+ { -+ char* next_piece = NULL; -+ if(split_index +1 < max_pieces || include_remainder_at_max <= 0) -+ { -+ next_piece = (char*)malloc((first_separator_index+1)*sizeof(char)); -+ memcpy(next_piece, start, first_separator_index); -+ next_piece[first_separator_index] = '\0'; -+ } -+ else -+ { -+ next_piece = strdup(start); -+ } -+ split[split_index] = next_piece; -+ split[split_index+1] = NULL; -+ split_index++; -+ } -+ -+ -+ /* find next non-separator index, indicating start of next piece */ -+ start = start+ first_separator_index; -+ non_separator_found = 0; -+ while(non_separator_found == 0) -+ { -+ int matches = 0; -+ int sep_index; -+ for(sep_index =0; sep_index < num_separators; sep_index++) -+ { -+ matches = matches == 1 || separators[sep_index] == start[0] ? 1 : 0; -+ } -+ non_separator_found = matches==0 || start[0] == '\0' ? 1 : 0; -+ if(non_separator_found == 0) -+ { -+ start++; -+ } -+ } -+ } -+ free(dup_line); -+ } -+ else -+ { -+ split = (char**)malloc((1)*sizeof(char*)); -+ split[0] = NULL; -+ } -+ return split; -+} -+ -+ -+char* trim_flanking_whitespace(char* str) -+{ -+ int new_start = 0; -+ int new_length = 0; -+ -+ char whitespace[5] = { ' ', '\t', '\n', '\r', '\0' }; -+ int num_whitespace_chars = 4; -+ -+ -+ int str_index = 0; -+ int is_whitespace = 1; -+ int test; -+ while( (test = str[str_index]) != '\0' && is_whitespace == 1) -+ { -+ int whitespace_index; -+ is_whitespace = 0; -+ for(whitespace_index = 0; whitespace_index < num_whitespace_chars && is_whitespace == 0; whitespace_index++) -+ { -+ is_whitespace = test == whitespace[whitespace_index] ? 1 : 0; -+ } -+ str_index = is_whitespace == 1 ? str_index+1 : str_index; -+ } -+ new_start = str_index; -+ -+ -+ str_index = strlen(str) - 1; -+ is_whitespace = 1; -+ while( str_index >= new_start && is_whitespace == 1) -+ { -+ int whitespace_index; -+ is_whitespace = 0; -+ for(whitespace_index = 0; whitespace_index < num_whitespace_chars && is_whitespace == 0; whitespace_index++) -+ { -+ is_whitespace = str[str_index] == whitespace[whitespace_index] ? 1 : 0; -+ } -+ str_index = is_whitespace == 1 ? str_index-1 : str_index; -+ } -+ new_length = str[new_start] == '\0' ? 0 : str_index + 1 - new_start; -+ -+ -+ if(new_start > 0) -+ { -+ for(str_index = 0; str_index < new_length; str_index++) -+ { -+ str[str_index] = str[str_index+new_start]; -+ } -+ } -+ str[new_length] = 0; -+ return str; -+} -+ -+void set_kernel_timezone(void) -+{ -+ time_t now; -+ struct tm* utc_info; -+ struct tm* tz_info; -+ int utc_day; -+ int utc_hour; -+ int utc_minute; -+ int tz_day; -+ int tz_hour; -+ int tz_minute; -+ int minuteswest; -+ -+ struct timeval tv; -+ struct timezone old_tz; -+ struct timezone new_tz; -+ -+ time(&now); -+ utc_info = gmtime(&now); -+ utc_day = utc_info->tm_mday; -+ utc_hour = utc_info->tm_hour; -+ utc_minute = utc_info->tm_min; -+ tz_info = localtime(&now); -+ tz_day = tz_info->tm_mday; -+ tz_hour = tz_info->tm_hour; -+ tz_minute = tz_info->tm_min; -+ -+ utc_day = utc_day < tz_day - 1 ? tz_day + 1 : utc_day; -+ tz_day = tz_day < utc_day - 1 ? utc_day + 1 : tz_day; -+ -+ minuteswest = (24*60*utc_day + 60*utc_hour + utc_minute) - (24*60*tz_day + 60*tz_hour + tz_minute) ; -+ new_tz.tz_minuteswest = minuteswest; -+ new_tz.tz_dsttime = 0; -+ -+ /* Get tv to pass to settimeofday(2) to be sure we avoid hour-sized warp */ -+ /* (see gettimeofday(2) man page, or /usr/src/linux/kernel/time.c) */ -+ gettimeofday(&tv, &old_tz); -+ -+ /* set timezone */ -+ settimeofday(&tv, &new_tz); -+ -+} - ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ipt_timerange.h -@@ -0,0 +1,43 @@ -+/* timerange -- An iptables extension to match multiple timeranges within a week -+ * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) -+ * -+ * -+ * Copyright © 2009 by Eric Bishop -+ * -+ * This file is free software: you may copy, redistribute and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+ -+ -+ -+#ifndef _IPT_TIMERANGE_H -+#define _IPT_TIMERANGE_H -+ -+ -+#define RANGE_LENGTH 51 -+ -+#define HOURS 1 -+#define WEEKDAYS 2 -+#define DAYS_HOURS (HOURS+WEEKDAYS) -+#define WEEKLY_RANGE 4 -+ -+ -+struct ipt_timerange_info -+{ -+ long ranges[RANGE_LENGTH]; -+ char days[7]; -+ char type; -+ unsigned char invert; -+}; -+#endif /*_IPT_TIMERANGE_H*/ - ---- /dev/null -+++ b/extensions/libipt_webmon.c -@@ -0,0 +1,700 @@ -+/* webmon -- An iptables extension to match URLs in HTTP(S) requests -+ * This module can match using string match or regular expressions -+ * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) -+ * -+ * -+ * Copyright © 2008-2011 by Eric Bishop -+ * -+ * This file is free software: you may copy, redistribute and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+/* -+ * in iptables 1.4.0 and higher, iptables.h includes xtables.h, which -+ * we can use to check whether we need to deal with the new requirements -+ * in pre-processor directives below -+ */ -+#include -+#include -+ -+#ifdef _XTABLES_H -+ #define iptables_rule_match xtables_rule_match -+ #define iptables_match xtables_match -+ #define iptables_target xtables_target -+ #define ipt_tryload xt_tryload -+#endif -+ -+/* -+ * XTABLES_VERSION_CODE is only defined in versions 1.4.1 and later, which -+ * also require the use of xtables_register_match -+ * -+ * Version 1.4.0 uses register_match like previous versions -+ */ -+#ifdef XTABLES_VERSION_CODE -+ #define register_match xtables_register_match -+#endif -+ -+ -+#define STRIP "%d.%d.%d.%d" -+#define NIPQUAD(addr) \ -+ ((unsigned char *)&addr)[0], \ -+ ((unsigned char *)&addr)[1], \ -+ ((unsigned char *)&addr)[2], \ -+ ((unsigned char *)&addr)[3] -+ -+ -+ -+/* utility functions necessary for module to work across multiple iptables versions */ -+static void param_problem_exit_error(char* msg); -+ -+ -+void parse_ips_and_ranges(char* addr_str, struct ipt_webmon_info *info); -+ -+char** split_on_separators(char* line, char* separators, int num_separators, int max_pieces, int include_remainder_at_max); -+char* trim_flanking_whitespace(char* str); -+unsigned char* read_entire_file(FILE* in, unsigned long read_block_size, unsigned long *length); -+ -+#define DEFAULT_MAX 300 -+ -+#define SEARCH_LOAD_FILE 100 -+#define DOMAIN_LOAD_FILE 101 -+#define CLEAR_SEARCH 102 -+#define CLEAR_DOMAIN 103 -+ -+static char* domain_load_file = NULL; -+static char* search_load_file = NULL; -+static uint32_t global_max_domains = DEFAULT_MAX; -+static uint32_t global_max_searches = DEFAULT_MAX; -+ -+/* Function which prints out usage message. */ -+static void help(void) -+{ -+ printf( "webmon options:\n"); -+} -+ -+static struct option opts[] = -+{ -+ { .name = "exclude_ips", .has_arg = 1, .flag = 0, .val = WEBMON_EXCLUDE }, -+ { .name = "include_ips", .has_arg = 1, .flag = 0, .val = WEBMON_INCLUDE }, -+ { .name = "max_domains", .has_arg = 1, .flag = 0, .val = WEBMON_MAXDOMAIN }, -+ { .name = "max_searches", .has_arg = 1, .flag = 0, .val = WEBMON_MAXSEARCH }, -+ { .name = "search_load_file", .has_arg = 1, .flag = 0, .val = SEARCH_LOAD_FILE }, -+ { .name = "domain_load_file", .has_arg = 1, .flag = 0, .val = DOMAIN_LOAD_FILE }, -+ { .name = "clear_search", .has_arg = 0, .flag = 0, .val = CLEAR_SEARCH }, -+ { .name = "clear_domain", .has_arg = 0, .flag = 0, .val = CLEAR_DOMAIN }, -+ -+ { .name = 0 } -+}; -+ -+static void webmon_init( -+#ifdef _XTABLES_H -+ struct xt_entry_match *match -+#else -+ struct ipt_entry_match *match, unsigned int *nfcache -+#endif -+ ) -+{ -+ struct ipt_webmon_info *info = (struct ipt_webmon_info *)match->data; -+ info->max_domains=DEFAULT_MAX; -+ info->max_searches=DEFAULT_MAX; -+ info->num_exclude_ips=0; -+ info->num_exclude_ranges=0; -+ info->exclude_type = WEBMON_EXCLUDE; -+ info->ref_count = NULL; -+} -+ -+ -+/* Function which parses command options; returns true if it ate an option */ -+static int parse( int c, -+ char **argv, -+ int invert, -+ unsigned int *flags, -+#ifdef _XTABLES_H -+ const void *entry, -+#else -+ const struct ipt_entry *entry, -+ unsigned int *nfcache, -+#endif -+ struct ipt_entry_match **match -+ ) -+{ -+ struct ipt_webmon_info *info = (struct ipt_webmon_info *)(*match)->data; -+ int valid_arg = 1; -+ long max; -+ switch (c) -+ { -+ case WEBMON_EXCLUDE: -+ parse_ips_and_ranges(optarg, info); -+ info->exclude_type = WEBMON_EXCLUDE; -+ break; -+ case WEBMON_INCLUDE: -+ parse_ips_and_ranges(optarg, info); -+ info->exclude_type = WEBMON_INCLUDE; -+ break; -+ case WEBMON_MAXSEARCH: -+ if( sscanf(argv[optind-1], "%ld", &max) == 0) -+ { -+ info->max_searches = DEFAULT_MAX ; -+ valid_arg = 0; -+ } -+ else -+ { -+ info->max_searches = (uint32_t)max; -+ global_max_searches = info->max_searches; -+ } -+ break; -+ case WEBMON_MAXDOMAIN: -+ if( sscanf(argv[optind-1], "%ld", &max) == 0) -+ { -+ info->max_domains = DEFAULT_MAX ; -+ valid_arg = 0; -+ } -+ else -+ { -+ info->max_domains = (uint32_t)max; -+ global_max_domains = info->max_domains; -+ } -+ break; -+ case SEARCH_LOAD_FILE: -+ search_load_file = strdup(optarg); -+ break; -+ case DOMAIN_LOAD_FILE: -+ domain_load_file = strdup(optarg); -+ break; -+ case CLEAR_SEARCH: -+ search_load_file = strdup("/dev/null"); -+ break; -+ case CLEAR_DOMAIN: -+ domain_load_file = strdup("/dev/null"); -+ break; -+ default: -+ valid_arg = 0; -+ } -+ return valid_arg; -+ -+} -+ -+ -+ -+static void print_webmon_args( struct ipt_webmon_info* info ) -+{ -+ printf("--max_domains %ld ", (unsigned long int)info->max_domains); -+ printf("--max_searches %ld ", (unsigned long int)info->max_searches); -+ if(info->num_exclude_ips > 0 || info->num_exclude_ranges > 0) -+ { -+ int ip_index = 0; -+ char comma[3] = ""; -+ printf("--%s ", (info->exclude_type == WEBMON_EXCLUDE ? "exclude_ips" : "include_ips")); -+ for(ip_index=0; ip_index < info->num_exclude_ips; ip_index++) -+ { -+ printf("%s"STRIP, comma, NIPQUAD((info->exclude_ips)[ip_index]) ); -+ sprintf(comma, ","); -+ } -+ for(ip_index=0; ip_index < info->num_exclude_ranges; ip_index++) -+ { -+ struct ipt_webmon_ip_range r = (info->exclude_ranges)[ip_index]; -+ printf("%s"STRIP"-"STRIP, comma, NIPQUAD(r.start), NIPQUAD(r.end) ); -+ sprintf(comma, ","); -+ } -+ printf(" "); -+ } -+} -+ -+ -+static void do_load(char* file, uint32_t max, unsigned char type) -+{ -+ if(file != NULL) -+ { -+ unsigned char* data = NULL; -+ unsigned long data_length = 0; -+ char* file_data = NULL; -+ if(strcmp(file, "/dev/null") != 0) -+ { -+ FILE* in = fopen(file, "r"); -+ if(in != NULL) -+ { -+ file_data = (char*)read_entire_file(in, 4096, &data_length); -+ fclose(in); -+ } -+ } -+ if(file_data == NULL) -+ { -+ file_data=strdup(""); -+ } -+ -+ if(file_data != NULL) -+ { -+ data_length = strlen(file_data) + sizeof(uint32_t)+2; -+ data = (unsigned char*)malloc(data_length); -+ if(data != NULL) -+ { -+ int sockfd = -1; -+ uint32_t* maxp = (uint32_t*)(data+1); -+ data[0] = type; -+ *maxp = max; -+ sprintf( (data+1+sizeof(uint32_t)), "%s", file_data); -+ -+ sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); -+ if(sockfd >= 0) -+ { -+ setsockopt(sockfd, IPPROTO_IP, WEBMON_SET, data, data_length); -+ close(sockfd); -+ } -+ free(data); -+ } -+ free(file_data); -+ } -+ } -+ -+} -+ -+ -+static void final_check(unsigned int flags) -+{ -+ do_load(domain_load_file, global_max_domains, WEBMON_DOMAIN); -+ do_load(search_load_file, global_max_searches, WEBMON_SEARCH); -+} -+ -+/* Prints out the matchinfo. */ -+#ifdef _XTABLES_H -+static void print(const void *ip, const struct xt_entry_match *match, int numeric) -+#else -+static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric) -+#endif -+{ -+ printf("WEBMON "); -+ struct ipt_webmon_info *info = (struct ipt_webmon_info *)match->data; -+ -+ print_webmon_args(info); -+} -+ -+/* Saves the union ipt_matchinfo in parsable form to stdout. */ -+#ifdef _XTABLES_H -+static void save(const void *ip, const struct xt_entry_match *match) -+#else -+static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) -+#endif -+{ -+ struct ipt_webmon_info *info = (struct ipt_webmon_info *)match->data; -+ print_webmon_args(info); -+} -+ -+static struct iptables_match webmon = -+{ -+ .next = NULL, -+ .name = "webmon", -+ #ifdef XTABLES_VERSION_CODE -+ .version = XTABLES_VERSION, -+ #else -+ .version = IPTABLES_VERSION, -+ #endif -+ .size = XT_ALIGN(sizeof(struct ipt_webmon_info)), -+ .userspacesize = XT_ALIGN(sizeof(struct ipt_webmon_info)), -+ .help = &help, -+ .init = &webmon_init, -+ .parse = &parse, -+ .final_check = &final_check, -+ .print = &print, -+ .save = &save, -+ .extra_opts = opts -+}; -+ -+void _init(void) -+{ -+ register_match(&webmon); -+} -+ -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+ -+ -+ -+ -+ -+ -+static void param_problem_exit_error(char* msg) -+{ -+ #ifdef xtables_error -+ xtables_error(PARAMETER_PROBLEM, "%s", msg); -+ #else -+ exit_error(PARAMETER_PROBLEM, msg); -+ #endif -+} -+ -+ -+void parse_ips_and_ranges(char* addr_str, struct ipt_webmon_info *info) -+{ -+ char** addr_parts = split_on_separators(addr_str, ",", 1, -1, 0); -+ -+ info->num_exclude_ips=0; -+ info->num_exclude_ranges = 0; -+ -+ int ip_part_index; -+ for(ip_part_index=0; addr_parts[ip_part_index] != NULL; ip_part_index++) -+ { -+ char* next_str = addr_parts[ip_part_index]; -+ if(strchr(next_str, '-') != NULL) -+ { -+ char** range_parts = split_on_separators(next_str, "-", 1, 2, 1); -+ char* start = trim_flanking_whitespace(range_parts[0]); -+ char* end = trim_flanking_whitespace(range_parts[1]); -+ int start_ip[4]; -+ int end_ip[4]; -+ int start_valid = sscanf(start, "%d.%d.%d.%d", start_ip, start_ip+1, start_ip+2, start_ip+3); -+ int end_valid = sscanf(end, "%d.%d.%d.%d", end_ip, end_ip+1, end_ip+2, end_ip+3); -+ -+ if(start_valid == 4 && end_valid == 4) -+ { -+ struct ipt_webmon_ip_range r; -+ struct in_addr sip, eip; -+ inet_pton(AF_INET, start, &sip); -+ inet_pton(AF_INET, end, &eip); -+ r.start = (uint32_t)sip.s_addr; -+ r.end = (uint32_t)eip.s_addr; -+ -+ if(info->num_exclude_ranges < WEBMON_MAX_IP_RANGES && (unsigned long)ntohl(r.start) < (unsigned long)ntohl(r.end) ) -+ { -+ (info->exclude_ranges)[ info->num_exclude_ranges ] = r; -+ info->num_exclude_ranges = info->num_exclude_ranges + 1; -+ } -+ } -+ -+ free(start); -+ free(end); -+ free(range_parts); -+ } -+ else if(strchr(next_str, '/') != NULL) -+ { -+ char** range_parts = split_on_separators(next_str, "/", 1, 2, 1); -+ char* start = trim_flanking_whitespace(range_parts[0]); -+ char* end = trim_flanking_whitespace(range_parts[1]); -+ int base_ip[4]; -+ int base_valid = sscanf(start, "%d.%d.%d.%d", base_ip, base_ip+1, base_ip+2, base_ip+3); -+ if(base_valid == 4) -+ { -+ int mask_valid = 0; -+ uint32_t mask; -+ if(strchr(end, '.') != NULL) -+ { -+ uint32_t mask_ip[4]; -+ int mask_test = sscanf(end, "%d.%d.%d.%d", mask_ip, mask_ip+1, mask_ip+2, mask_ip+3); -+ if(mask_test == 4) -+ { -+ struct in_addr mask_add; -+ inet_pton(AF_INET, end, &mask_add); -+ mask = (uint32_t)mask_add.s_addr; -+ mask_valid = 1; -+ } -+ } -+ else -+ { -+ int mask_bits; -+ if( sscanf(end, "%d", &mask_bits) > 0) -+ { -+ if(mask_bits >=0 && mask_bits <= 32) -+ { -+ uint32_t byte = 0; -+ mask = 0; -+ for(byte=0; byte < 4; byte++) -+ { -+ unsigned char byte_bits = mask_bits > 8 ? 8 : mask_bits; -+ uint32_t byte_mask = 0; -+ mask_bits = mask_bits - byte_bits; -+ -+ while(byte_bits > 0) -+ { -+ byte_mask = byte_mask | (256 >> byte_bits); -+ byte_bits--; -+ } -+ mask = mask | ((uint32_t)byte_mask << (byte*8)); -+ printf("mask = "STRIP"\n", NIPQUAD(mask)); -+ } -+ mask_valid = 1; -+ } -+ } -+ } -+ if(mask_valid) -+ { -+ struct ipt_webmon_ip_range r; -+ struct in_addr bip; -+ inet_pton(AF_INET, start, &bip); -+ r.start = ( ((uint32_t)bip.s_addr) & mask ); -+ r.end = ( ((uint32_t)bip.s_addr) | (~mask) ); -+ if(info->num_exclude_ranges < WEBMON_MAX_IP_RANGES && ntohl(r.start) <= ntohl(r.end) ) -+ { -+ (info->exclude_ranges)[ info->num_exclude_ranges ] = r; -+ info->num_exclude_ranges = info->num_exclude_ranges + 1; -+ } -+ } -+ } -+ free(start); -+ free(end); -+ free(range_parts); -+ } -+ else -+ { -+ int parsed_ip[4]; -+ int valid = sscanf(next_str, "%d.%d.%d.%d", parsed_ip, parsed_ip+1, parsed_ip+2, parsed_ip+3); -+ if(valid == 4) -+ { -+ struct in_addr ip; -+ trim_flanking_whitespace(next_str); -+ inet_pton(AF_INET, next_str, &ip); -+ -+ if(info->num_exclude_ranges < WEBMON_MAX_IPS) -+ { -+ (info->exclude_ips)[ info->num_exclude_ips ] = (uint32_t)ip.s_addr; -+ info->num_exclude_ips = info->num_exclude_ips + 1; -+ } -+ } -+ } -+ free(next_str); -+ } -+ free(addr_parts); -+ -+} -+ -+ -+ -+/* -+ * line_str is the line to be parsed -- it is not modified in any way -+ * max_pieces indicates number of pieces to return, if negative this is determined dynamically -+ * include_remainder_at_max indicates whether the last piece, when max pieces are reached, -+ * should be what it would normally be (0) or the entire remainder of the line (1) -+ * if max_pieces < 0 this parameter is ignored -+ * -+ * -+ * returns all non-separator pieces in a line -+ * result is dynamically allocated, MUST be freed after call-- even if -+ * line is empty (you still get a valid char** pointer to to a NULL char*) -+ */ -+char** split_on_separators(char* line_str, char* separators, int num_separators, int max_pieces, int include_remainder_at_max) -+{ -+ char** split; -+ -+ if(line_str != NULL) -+ { -+ int split_index; -+ int non_separator_found; -+ char* dup_line; -+ char* start; -+ -+ if(max_pieces < 0) -+ { -+ /* count number of separator characters in line -- this count + 1 is an upperbound on number of pieces */ -+ int separator_count = 0; -+ int line_index; -+ for(line_index = 0; line_str[line_index] != '\0'; line_index++) -+ { -+ int sep_index; -+ int found = 0; -+ for(sep_index =0; found == 0 && sep_index < num_separators; sep_index++) -+ { -+ found = separators[sep_index] == line_str[line_index] ? 1 : 0; -+ } -+ separator_count = separator_count+ found; -+ } -+ max_pieces = separator_count + 1; -+ } -+ split = (char**)malloc((1+max_pieces)*sizeof(char*)); -+ split_index = 0; -+ split[split_index] = NULL; -+ -+ -+ dup_line = strdup(line_str); -+ start = dup_line; -+ non_separator_found = 0; -+ while(non_separator_found == 0) -+ { -+ int matches = 0; -+ int sep_index; -+ for(sep_index =0; sep_index < num_separators; sep_index++) -+ { -+ matches = matches == 1 || separators[sep_index] == start[0] ? 1 : 0; -+ } -+ non_separator_found = matches==0 || start[0] == '\0' ? 1 : 0; -+ if(non_separator_found == 0) -+ { -+ start++; -+ } -+ } -+ -+ while(start[0] != '\0' && split_index < max_pieces) -+ { -+ /* find first separator index */ -+ int first_separator_index = 0; -+ int separator_found = 0; -+ while( separator_found == 0 ) -+ { -+ int sep_index; -+ for(sep_index =0; separator_found == 0 && sep_index < num_separators; sep_index++) -+ { -+ separator_found = separators[sep_index] == start[first_separator_index] || start[first_separator_index] == '\0' ? 1 : 0; -+ } -+ if(separator_found == 0) -+ { -+ first_separator_index++; -+ } -+ } -+ -+ /* copy next piece to split array */ -+ if(first_separator_index > 0) -+ { -+ char* next_piece = NULL; -+ if(split_index +1 < max_pieces || include_remainder_at_max <= 0) -+ { -+ next_piece = (char*)malloc((first_separator_index+1)*sizeof(char)); -+ memcpy(next_piece, start, first_separator_index); -+ next_piece[first_separator_index] = '\0'; -+ } -+ else -+ { -+ next_piece = strdup(start); -+ } -+ split[split_index] = next_piece; -+ split[split_index+1] = NULL; -+ split_index++; -+ } -+ -+ -+ /* find next non-separator index, indicating start of next piece */ -+ start = start+ first_separator_index; -+ non_separator_found = 0; -+ while(non_separator_found == 0) -+ { -+ int matches = 0; -+ int sep_index; -+ for(sep_index =0; sep_index < num_separators; sep_index++) -+ { -+ matches = matches == 1 || separators[sep_index] == start[0] ? 1 : 0; -+ } -+ non_separator_found = matches==0 || start[0] == '\0' ? 1 : 0; -+ if(non_separator_found == 0) -+ { -+ start++; -+ } -+ } -+ } -+ free(dup_line); -+ } -+ else -+ { -+ split = (char**)malloc((1)*sizeof(char*)); -+ split[0] = NULL; -+ } -+ return split; -+} -+ -+ -+ -+char* trim_flanking_whitespace(char* str) -+{ -+ int new_start = 0; -+ int new_length = 0; -+ -+ char whitespace[5] = { ' ', '\t', '\n', '\r', '\0' }; -+ int num_whitespace_chars = 4; -+ -+ -+ int str_index = 0; -+ int is_whitespace = 1; -+ int test; -+ while( (test = str[str_index]) != '\0' && is_whitespace == 1) -+ { -+ int whitespace_index; -+ is_whitespace = 0; -+ for(whitespace_index = 0; whitespace_index < num_whitespace_chars && is_whitespace == 0; whitespace_index++) -+ { -+ is_whitespace = test == whitespace[whitespace_index] ? 1 : 0; -+ } -+ str_index = is_whitespace == 1 ? str_index+1 : str_index; -+ } -+ new_start = str_index; -+ -+ -+ str_index = strlen(str) - 1; -+ is_whitespace = 1; -+ while( str_index >= new_start && is_whitespace == 1) -+ { -+ int whitespace_index; -+ is_whitespace = 0; -+ for(whitespace_index = 0; whitespace_index < num_whitespace_chars && is_whitespace == 0; whitespace_index++) -+ { -+ is_whitespace = str[str_index] == whitespace[whitespace_index] ? 1 : 0; -+ } -+ str_index = is_whitespace == 1 ? str_index-1 : str_index; -+ } -+ new_length = str[new_start] == '\0' ? 0 : str_index + 1 - new_start; -+ -+ -+ if(new_start > 0) -+ { -+ for(str_index = 0; str_index < new_length; str_index++) -+ { -+ str[str_index] = str[str_index+new_start]; -+ } -+ } -+ str[new_length] = 0; -+ return str; -+} -+ -+ -+unsigned char* read_entire_file(FILE* in, unsigned long read_block_size, unsigned long *length) -+{ -+ int max_read_size = read_block_size; -+ unsigned char* read_string = (unsigned char*)malloc(max_read_size+1); -+ unsigned long bytes_read = 0; -+ int end_found = 0; -+ while(end_found == 0) -+ { -+ int nextch = '?'; -+ while(nextch != EOF && bytes_read < max_read_size) -+ { -+ nextch = fgetc(in); -+ if(nextch != EOF) -+ { -+ read_string[bytes_read] = (unsigned char)nextch; -+ bytes_read++; -+ } -+ } -+ read_string[bytes_read] = '\0'; -+ end_found = (nextch == EOF) ? 1 : 0; -+ if(end_found == 0) -+ { -+ unsigned char *new_str; -+ max_read_size = max_read_size + read_block_size; -+ new_str = (unsigned char*)malloc(max_read_size+1); -+ memcpy(new_str, read_string, bytes_read); -+ free(read_string); -+ read_string = new_str; -+ } -+ } -+ *length = bytes_read; -+ return read_string; -+} -+ - ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ipt_webmon.h -@@ -0,0 +1,63 @@ -+/* webmon -- A netfilter module to match URLs in HTTP(S) requests -+ * This module can match using string match or regular expressions -+ * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) -+ * -+ * -+ * Copyright © 2008-2010 by Eric Bishop -+ * -+ * This file is free software: you may copy, redistribute and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+ -+ -+ -+#ifndef _IPT_WEBMON_H -+#define _IPT_WEBMON_H -+ -+ -+#define WEBMON_MAX_IPS 256 -+#define WEBMON_MAX_IP_RANGES 16 -+ -+#define WEBMON_EXCLUDE 1 -+#define WEBMON_INCLUDE 2 -+ -+#define WEBMON_MAXDOMAIN 4 -+#define WEBMON_MAXSEARCH 8 -+ -+#define WEBMON_DOMAIN 16 -+#define WEBMON_SEARCH 32 -+ -+ -+#define WEBMON_SET 3064 -+ -+struct ipt_webmon_ip_range -+{ -+ uint32_t start; -+ uint32_t end; -+}; -+ -+struct ipt_webmon_info -+{ -+ uint32_t max_domains; -+ uint32_t max_searches; -+ uint32_t exclude_ips[WEBMON_MAX_IPS]; -+ struct ipt_webmon_ip_range exclude_ranges[WEBMON_MAX_IP_RANGES]; -+ uint32_t num_exclude_ips; -+ uint32_t num_exclude_ranges; -+ unsigned char exclude_type; -+ uint32_t* ref_count; -+ -+}; -+ -+#endif /*_IPT_WEBMON_H*/ - ---- /dev/null -+++ b/extensions/libipt_weburl.c -@@ -0,0 +1,290 @@ -+/* weburl -- An iptables extension to match URLs in HTTP(S) requests -+ * This module can match using string match or regular expressions -+ * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) -+ * -+ * -+ * Copyright © 2008-2010 by Eric Bishop -+ * -+ * This file is free software: you may copy, redistribute and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+ -+ -+/* -+ * in iptables 1.4.0 and higher, iptables.h includes xtables.h, which -+ * we can use to check whether we need to deal with the new requirements -+ * in pre-processor directives below -+ */ -+#include -+#include -+ -+#ifdef _XTABLES_H -+ #define iptables_rule_match xtables_rule_match -+ #define iptables_match xtables_match -+ #define iptables_target xtables_target -+ #define ipt_tryload xt_tryload -+#endif -+ -+/* -+ * XTABLES_VERSION_CODE is only defined in versions 1.4.1 and later, which -+ * also require the use of xtables_register_match -+ * -+ * Version 1.4.0 uses register_match like previous versions -+ */ -+#ifdef XTABLES_VERSION_CODE -+ #define register_match xtables_register_match -+#endif -+ -+ -+/* utility functions necessary for module to work across multiple iptables versions */ -+static int my_check_inverse(const char option[], int* invert, int *my_optind, int argc); -+static void param_problem_exit_error(char* msg); -+ -+ -+ -+/* Function which prints out usage message. */ -+static void help(void) -+{ -+ printf( "weburl options:\n --contains [!] [STRING]\n --contains_regex [!] [REGEX]\n --matches_exactly [!] [STRING]\n --domain_only\n --path_only\n"); -+} -+ -+static struct option opts[] = -+{ -+ { .name = "contains", .has_arg = 1, .flag = 0, .val = WEBURL_CONTAINS_TYPE }, //string -+ { .name = "contains_regex", .has_arg = 1, .flag = 0, .val = WEBURL_REGEX_TYPE }, //regex -+ { .name = "matches_exactly", .has_arg = 1, .flag = 0, .val = WEBURL_EXACT_TYPE }, //exact string match -+ { .name = "domain_only", .has_arg = 0, .flag = 0, .val = WEBURL_DOMAIN_PART }, //only match domain portion of url -+ { .name = "path_only", .has_arg = 0, .flag = 0, .val = WEBURL_PATH_PART }, //only match path portion of url -+ { .name = 0 } -+}; -+ -+ -+/* Function which parses command options; returns true if it -+ ate an option */ -+static int parse( int c, -+ char **argv, -+ int invert, -+ unsigned int *flags, -+#ifdef _XTABLES_H -+ const void *entry, -+#else -+ const struct ipt_entry *entry, -+ unsigned int *nfcache, -+#endif -+ struct ipt_entry_match **match -+ ) -+{ -+ struct ipt_weburl_info *info = (struct ipt_weburl_info *)(*match)->data; -+ int valid_arg = 0; -+ -+ if(*flags < 10) -+ { -+ info->match_part = WEBURL_ALL_PART; -+ } -+ -+ switch (c) -+ { -+ case WEBURL_CONTAINS_TYPE: -+ case WEBURL_REGEX_TYPE: -+ case WEBURL_EXACT_TYPE: -+ info->match_type = c; -+ -+ //test whether to invert rule -+ my_check_inverse(optarg, &invert, &optind, 0); -+ info->invert = invert ? 1 : 0; -+ -+ //test that test string is reasonable length, then to info -+ int testlen = strlen(argv[optind-1]); -+ if(testlen > 0 && testlen < MAX_TEST_STR) -+ { -+ strcpy(info->test_str, argv[optind-1]); -+ } -+ else if(testlen >= MAX_TEST_STR) -+ { -+ char err[100]; -+ sprintf(err, "Parameter definition is too long, must be less than %d characters", MAX_TEST_STR); -+ param_problem_exit_error(err); -+ } -+ else -+ { -+ param_problem_exit_error("Parameter definition is incomplete"); -+ } -+ -+ if(*flags % 10 == 1) -+ { -+ param_problem_exit_error("You may only specify one string/pattern to match"); -+ } -+ *flags = *flags + 1; -+ -+ valid_arg = 1; -+ break; -+ -+ case WEBURL_DOMAIN_PART: -+ case WEBURL_PATH_PART: -+ info->match_part = c; -+ if(*flags >= 10) -+ { -+ param_problem_exit_error("You may specify at most one part of the url to match:\n\t--domain_only, --path_only or neither (to match full url)\n"); -+ } -+ *flags = *flags+10; -+ -+ valid_arg = 1; -+ break; -+ } -+ -+ return valid_arg; -+} -+ -+ -+ -+static void print_weburl_args( struct ipt_weburl_info* info ) -+{ -+ //invert -+ if(info->invert > 0) -+ { -+ printf("! "); -+ } -+ //match type -+ switch (info->match_type) -+ { -+ case WEBURL_CONTAINS_TYPE: -+ printf("--contains "); -+ break; -+ case WEBURL_REGEX_TYPE: -+ printf("--contains_regex "); -+ break; -+ case WEBURL_EXACT_TYPE: -+ printf("--matches_exactly "); -+ break; -+ } -+ //test string -+ printf("%s ", info->test_str); -+ -+ //match part -+ switch(info->match_part) -+ { -+ case WEBURL_DOMAIN_PART: -+ printf("--domain_only "); -+ break; -+ case WEBURL_PATH_PART: -+ printf("--path_only "); -+ break; -+ case WEBURL_ALL_PART: -+ //print nothing -+ break; -+ } -+ -+} -+ -+/* Final check; must have specified a test string with either --contains or --contains_regex. */ -+static void final_check(unsigned int flags) -+{ -+ if (flags %10 == 0) -+ { -+ param_problem_exit_error("You must specify '--contains' or '--contains_regex' or '--matches_exactly'"); -+ } -+} -+ -+/* Prints out the matchinfo. */ -+#ifdef _XTABLES_H -+static void print(const void *ip, const struct xt_entry_match *match, int numeric) -+#else -+static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric) -+#endif -+{ -+ printf("WEBURL "); -+ struct ipt_weburl_info *info = (struct ipt_weburl_info *)match->data; -+ -+ print_weburl_args(info); -+} -+ -+/* Saves the union ipt_matchinfo in parsable form to stdout. */ -+#ifdef _XTABLES_H -+static void save(const void *ip, const struct xt_entry_match *match) -+#else -+static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) -+#endif -+{ -+ struct ipt_weburl_info *info = (struct ipt_weburl_info *)match->data; -+ print_weburl_args(info); -+} -+ -+static struct iptables_match weburl = -+{ -+ .next = NULL, -+ .name = "weburl", -+ #ifdef XTABLES_VERSION_CODE -+ .version = XTABLES_VERSION, -+ #else -+ .version = IPTABLES_VERSION, -+ #endif -+ .size = XT_ALIGN(sizeof(struct ipt_weburl_info)), -+ .userspacesize = XT_ALIGN(sizeof(struct ipt_weburl_info)), -+ .help = &help, -+ .parse = &parse, -+ .final_check = &final_check, -+ .print = &print, -+ .save = &save, -+ .extra_opts = opts -+}; -+ -+void _init(void) -+{ -+ register_match(&weburl); -+} -+ -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+#ifndef FALSE -+#define FALSE 0 -+#endif -+static int my_check_inverse(const char option[], int* invert, int *my_optind, int argc) -+{ -+ if (option && strcmp(option, "!") == 0) -+ { -+ if (*invert) -+ { -+ param_problem_exit_error("Multiple `!' flags not allowed"); -+ } -+ *invert = TRUE; -+ if (my_optind != NULL) -+ { -+ ++*my_optind; -+ if (argc && *my_optind > argc) -+ { -+ param_problem_exit_error("no argument following `!'"); -+ } -+ } -+ return TRUE; -+ } -+ return FALSE; -+} -+static void param_problem_exit_error(char* msg) -+{ -+ #ifdef xtables_error -+ xtables_error(PARAMETER_PROBLEM, "%s", msg); -+ #else -+ exit_error(PARAMETER_PROBLEM, msg); -+ #endif -+} -+ -+ - ---- /dev/null -+++ b/include/linux/netfilter_ipv4/ipt_weburl.h -@@ -0,0 +1,45 @@ -+/* weburl -- A netfilter module to match URLs in HTTP(S) requests -+ * This module can match using string match or regular expressions -+ * Originally designed for use with Gargoyle router firmware (gargoyle-router.com) -+ * -+ * -+ * Copyright © 2008 by Eric Bishop -+ * -+ * This file is free software: you may copy, redistribute and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation, either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * This file is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program. If not, see . -+ */ -+ -+ -+ -+ -+#ifndef _IPT_WEBURL_H -+#define _IPT_WEBURL_H -+ -+ -+#define MAX_TEST_STR 1024 -+ -+#define WEBURL_CONTAINS_TYPE 1 -+#define WEBURL_REGEX_TYPE 2 -+#define WEBURL_EXACT_TYPE 3 -+#define WEBURL_ALL_PART 4 -+#define WEBURL_DOMAIN_PART 5 -+#define WEBURL_PATH_PART 6 -+ -+struct ipt_weburl_info -+{ -+ char test_str[MAX_TEST_STR]; -+ unsigned char match_type; -+ unsigned char match_part; -+ unsigned char invert; -+}; -+#endif /*_IPT_WEBURL_H*/