applications/luci-splash: Add a filter for arguments, only allow valid mac and ip...
[project/luci.git] / applications / luci-splash / root / usr / sbin / luci-splash
index 2f4c1dd..a795421 100755 (executable)
@@ -44,6 +44,19 @@ function get_id(ip)
        end
 end
 
+function update_stats(leased, whitelisted, whitelisttotal, blacklisted, blacklisttotal) 
+       local leases = uci:get_all("luci_splash_leases", "stats")
+       uci:delete("luci_splash_leases", "stats")
+       uci:section("luci_splash_leases", "stats", "stats", {
+               leases    = leased or (leases and leases.leases) or 0,
+               whitelisttotal = whitelisttotal or (leased and leases.whitelisttotal) or 0,
+               whitelistonline = whitelisted or (leases and leases.whitelistonline) or 0,
+               blacklisttotal = blacklisttotal or (leases and leases.blacklisttotal) or 0,
+               blacklistonline = blacklisted or (leases and leases.blacklistonline) or 0,
+       })
+       uci:save("luci_splash_leases")
+end
+
 function get_device_for_ip(ipaddr)
        local dev
        uci:foreach("network", "interface", function(s)
@@ -93,6 +106,26 @@ function get_filter_handle(parent, direction, device, mac)
        return handle
 end
 
+function macvalid(mac)
+       if mac and mac:match(
+               "^[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]:" ..
+               "[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]:" ..
+               "[a-fA-F0-9][a-fA-F0-9]:[a-fA-F0-9][a-fA-F0-9]$"
+       ) then
+               return true
+       end
+
+       return false
+end
+
+function ipvalid(ipaddr)
+       if ipaddr then
+               return ip.IPv4(ipaddr) and true or false
+       end
+
+       return false
+end
+
 function main(argv)
        local cmd = table.remove(argv, 1)
        local arg = argv[1]
@@ -103,6 +136,12 @@ function main(argv)
        if ( cmd == "lease" or cmd == "add-rules" or cmd == "remove" or
             cmd == "whitelist" or cmd == "blacklist" or cmd == "status" ) and #argv > 0
        then
+               if not (macvalid(arg) or ipvalid(arg)) then
+                       print("Invalid argument. The second argument must " ..
+                               "be a valid IPv4 or Mac Address.")
+                       os.exit(1)
+               end
+
                lock()
 
                local arp_cache      = net.arptable()
@@ -299,6 +338,11 @@ function add_lease(mac, arp, no_uci)
        if ipaddr then
                local device = get_device_for_ip(ipaddr)
                if not no_uci then
+                       local leased = uci:get("luci_splash_leases", "stats", "leases")
+                       if type(tonumber(leased)) == "number" then
+                               update_stats(leased + 1, nil, nil, nil, nil)
+                       end
+
                        uci:section("luci_splash_leases", "lease", convert_mac_to_secname(mac), {
                                mac    = mac,
                                ipaddr = ipaddr,
@@ -324,6 +368,10 @@ function remove_lease(mac)
                function(s)
                        if s.mac:lower() == mac then
                                remove_lease_rule(mac, s.ipaddr, s.device, tonumber(s.limit_up), tonumber(s.limit_down))
+                               local leased = uci:get("luci_splash_leases", "stats", "leases")
+                               if type(tonumber(leased)) == "number" and tonumber(leased) > 0 then
+                                       update_stats(leased - 1, nil, nil, nil, nil)
+                               end
                                return true
                        end
                        return false
@@ -368,10 +416,12 @@ function remove_whitelist_tc(mac)
        end
         uci:foreach("luci_splash", "iface", function(s)
                local device = get_physdev(s['.name'])
-               local handle = get_filter_handle('ffff:', 'src', device, mac)
-               exec('tc filter del dev "%s" parent ffff: protocol ip prio 1 handle %s u32' % { device, handle })
-               local handle = get_filter_handle('1:', 'dest', device, mac)
-               exec('tc filter del dev "%s" parent 1:0 protocol ip prio 1 handle %s u32' % { device, handle })
+               if device and device ~= "" then
+                       local handle = get_filter_handle('ffff:', 'src', device, mac)
+                       exec('tc filter del dev "%s" parent ffff: protocol ip prio 1 handle %s u32' % { device, handle })
+                       local handle = get_filter_handle('1:', 'dest', device, mac)
+                       exec('tc filter del dev "%s" parent 1:0 protocol ip prio 1 handle %s u32' % { device, handle })
+               end
         end)
 end
 
@@ -464,8 +514,10 @@ function add_whitelist_rule(mac)
        end
         uci:foreach("luci_splash", "iface", function(s)
                local device = get_physdev(s['.name'])
-               exec('tc filter add dev "%s" parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { device, mac })
-               exec('tc filter add dev "%s" parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { device, mac })
+               if device and device ~= "" then
+                       exec('tc filter add dev "%s" parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { device, mac })
+                       exec('tc filter add dev "%s" parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { device, mac })
+               end
         end)
 end
 
@@ -503,7 +555,7 @@ function sync()
                                -- Remove expired
                                remove_lease_rule(v.mac, v.ipaddr, v.device, tonumber(v.limit_up), tonumber(v.limit_down))
                        else
-                               leasecount = count + 1
+                               leasecount = leasecount + 1
                                -- Rewrite state
                                uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), {             
                                        mac    = v.mac,
@@ -551,13 +603,7 @@ function sync()
                end
        end
 
-       uci:section("luci_splash_leases", "stats", "stats", {
-               leases    = leasecount,
-               whitelisttotal = whitelist_total,
-               whitelistonline = whitelist_online,
-               blacklisttotal = blacklist_total,
-               blacklistonline = blacklist_online,
-       })
+       update_stats(leasecount, whitelist_online, whitelist_total, blacklist_online, blacklist_total)
 
        uci:save("luci_splash_leases")