require("rsmdict")


--The Objects that is supported by the Script
local obj_ids = {
                   RSM.RSM_TagID.TAG_NET_PF_CFG                    
                }
                
local services = {}
local pf_file = ""
local pf_conf_file="/etc/blackwall/forward"
local pf_conf_file_test="/usr/share/lua/kses/test_pf"

local portforward_restart = "/etc/init.d/blackwall"

function print_table(t,p)

   for k,v in pairs(t) do
     print(p,k,v)
     if(type(v)=="table") then 
         print_table(v,p.."\t")
     end
  end
end


--Retuen the Object List
function getObjects()
 return obj_ids;
end

--Convert the config file into an object message nd return that.
--Actually supposed to check the request object to find the exact object if any to 
--return. We jippo that by always returning all of them
function getConfig(cfg)
  load_pf()
  msg = pf_to_msg()
  return msg
end


--Function to lookup and set a specific object(s)
--and then to update the cofig file with those values
function setConfig(cfg)
   --load_pf()   
   update_pf(cfg)
   store_pf()
end


function command_exec(cmd)
  local f = io.popen(cmd) 
  value = f:read("*a") or "none"
  f:close()
  return value
end

function writefile(fileaddres,value)
  local f = io.open(fileaddres,"w+")
  f:write(value)
  f:close()
  return true
end

function load_pf() 
  --print("Loading pf data...") 
  serviceCount = 0
  pff = command_exec("cat "..pf_conf_file)
  pf_file = pff  
  services = {}  
  
    
  --Add pf services Objects
  for name, pfConf in (pf_file:gmatch("#SERVNAME%s+([^\n]*)\n%s*([^\n]*)\n")) do
    serviceCount = serviceCount + 1
    
    if (pfConf:match("%s*(.-)%s+(%d+)%s+(.-)%s+(%d+)") ~= nil) then
       protocol, inPort, outIP, outPort = pfConf:match("%s*(.-)%s+(%d+)%s+(.-)%s+(%d+)")
       if (protocol ~= nil) and (inPort ~= nil) and (outIP ~= nil) and (outPort ~= nil) then
          services[name] = {}      
          services[name].name = name 
          services[name].protocol = protocol
          services[name].inPort = inPort   
          services[name].outIP = outIP
          services[name].outPort = outPort
          
          --[[print("Service name: "..services[name].name)
          print("Service protocol: "..services[name].protocol)
          print("Service inPort: "..services[name].inPort)
          print("Service outIP: "..services[name].outIP)
          print("Service outPort: "..services[name].outPort)]]--
       end
    end             
  end     
end

function pf_to_msg()
  local msg = {}
  pf_ctr = 0
  
  --print("Load Message: ")
  --Send Subnet info
  for idx,pff in pairs(services) do
     pf_cfg = {}
     pf_cfg.objid =  RSM.RSM_TagID.TAG_NET_PF_CFG
     pf_cfg[RSM.RSM_TagID.TAG_NET_LABEL] = pff.name
     
     if (pff.protocol == "") then
        pf_cfg[RSM.RSM_TagID.TAG_NET_PROTOCOL] = RSM.TAG_NET_PROTOCOL_Types.TAG_NET_PROTOCOL_NONE
     elseif (pff.protocol == "tcp") then
        pf_cfg[RSM.RSM_TagID.TAG_NET_PROTOCOL] = RSM.TAG_NET_PROTOCOL_Types.TAG_NET_PROTOCOL_TCP
     elseif   (pff.protocol == "udp") then
        pf_cfg[RSM.RSM_TagID.TAG_NET_PROTOCOL] = RSM.TAG_NET_PROTOCOL_Types.TAG_NET_PROTOCOL_UDP
     end         
    
     pf_cfg[RSM.RSM_TagID.TAG_NET_INPORT] = tonumber(pff.inPort)
     pf_cfg[RSM.RSM_TagID.TAG_NET_IP] = pff.outIP
     pf_cfg[RSM.RSM_TagID.TAG_NET_OUTPORT] = tonumber(pff.outPort)     
          
     msg[pf_ctr] = pf_cfg
     pf_ctr = pf_ctr+1
  end  
  
  return msg
end

function update_pf(cfg)
   for idx,obj in pairs(cfg) do
      if obj.objid and obj.objid == RSM.RSM_TagID.TAG_NET_PF_CFG then
          if obj[RSM.RSM_TagID.TAG_NET_LABEL] then         
              services[obj[RSM.RSM_TagID.TAG_NET_LABEL]]={}     
              pff = services[obj[RSM.RSM_TagID.TAG_NET_LABEL]]
              --print("Adding object: " .. obj[RSM.RSM_TagID.TAG_NET_LABEL]);
              if pff then
                setservices(pff,obj)
              end
          end 
      end      
   end 
end


function setservices(pff,obj)
    if obj[RSM.RSM_TagID.TAG_NET_LABEL] then
       pff.name = obj[RSM.RSM_TagID.TAG_NET_LABEL]
    end
    if obj[RSM.RSM_TagID.TAG_NET_PROTOCOL] then
    
       if obj[RSM.RSM_TagID.TAG_NET_PROTOCOL] == RSM.TAG_NET_PROTOCOL_Types.TAG_NET_PROTOCOL_NONE then  
          pff.protocol = "none"
       end 
       if obj[RSM.RSM_TagID.TAG_NET_PROTOCOL] == RSM.TAG_NET_PROTOCOL_Types.TAG_NET_PROTOCOL_TCP then  
          pff.protocol = "tcp"
       end    
       if obj[RSM.RSM_TagID.TAG_NET_PROTOCOL] == RSM.TAG_NET_PROTOCOL_Types.TAG_NET_PROTOCOL_UDP then  
          pff.protocol = "udp"
       end           
    end
    if obj[RSM.RSM_TagID.TAG_NET_INPORT] then
       pff.inPort = obj[RSM.RSM_TagID.TAG_NET_INPORT]
    end
    if obj[RSM.RSM_TagID.TAG_NET_IP] then
       pff.outIP = obj[RSM.RSM_TagID.TAG_NET_IP]
    end
    if obj[RSM.RSM_TagID.TAG_NET_OUTPORT] then
       pff.outPort = obj[RSM.RSM_TagID.TAG_NET_OUTPORT]
    end    
    pff.changed = 1
end

function store_pf()

local pf_config = ""

   pf_config = "### "..pf_conf_file.." generated by webconfig\n" 
   
   for idx,pff in pairs(services) do       
       pf_config = pf_config.."\n#SERVNAME " .. pff.name .. "\n"
       pf_config = pf_config..pff.protocol .. "\t" .. pff.inPort .. "\t" .. pff.outIP .. "\t" .. pff.outPort .. "\n" 
       
       --[[print("Storing the following: ");
       print(pff.name);  
       print(pff.protocol);  
       print(pff.inPort);  
       print(pff.outIP);  
       print(pff.outPort);]]--            
                   
   end
   
   pf_config = pf_config .. "\n### end of file\n"   
   
   writefile(pf_conf_file,pf_config)
   command_exec(portforward_restart)
end

--Testing....

--print("Testing...")
--print("Get Config: ")

--print_table(getConfig(),0)

--[[local testCfg = {}
local obj ={}
local obj1 ={}

obj.objid = RSM.RSM_TagID.TAG_NET_PF_CFG
obj[RSM.RSM_TagID.TAG_NET_LABEL] = "cam1"     
obj[RSM.RSM_TagID.TAG_NET_PROTOCOL] = 1
obj[RSM.RSM_TagID.TAG_NET_INPORT] = 8080
obj[RSM.RSM_TagID.TAG_NET_IP] = "192.168.2.30"
obj[RSM.RSM_TagID.TAG_NET_OUTPORT] = 80

obj1.objid = RSM.RSM_TagID.TAG_NET_PF_CFG
obj1[RSM.RSM_TagID.TAG_NET_LABEL] = "cam2"     
obj1[RSM.RSM_TagID.TAG_NET_PROTOCOL] = 1
obj1[RSM.RSM_TagID.TAG_NET_INPORT] = 8081
obj1[RSM.RSM_TagID.TAG_NET_IP] = "192.168.2.31"
obj1[RSM.RSM_TagID.TAG_NET_OUTPORT] = 80

testCfg[0] = obj
testCfg[1] = obj1

setConfig(testCfg)]]--





























