require("rsmdict")


--The Objects that is supported by the Script
local obj_ids = {
                   RSM.RSM_TagID.TAG_NET_DHCP_CFG,
                   RSM.RSM_TagID.TAG_NET_DHCP_DOMAIN 
                }
                
local subnets = {}
local domain = {}
local dhcp_file = ""
local dhcp_conf_file="/etc/dhcpd.conf"
local dhcp_conf_file_test="/usr/share/lua/kses/test_dhcp"

local dhcpd_stop = "sv stop dhcpd"
local dhcpd_start = "sv start dhcpd"

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_dhcp()
  msg = dhcp_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_dhcp()   
   update_dhcp(cfg)
   store_dhcp()
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_dhcp()   
  subnetCount = 0
  dhcpf = command_exec("cat "..dhcp_conf_file)
  dhcp_file = dhcpf  
  domain = {}  
  subnets = {}  
  
    
  --Add Global Domain Object
  --[[for dom in (dhcp_file:gmatch('option%s+domain%-name%s+%"?(.-)%"?;')) do  
     
    domain[dom] = {}        
    domain[dom].name = dom 
    domain[dom].server = dhcp_file:match('option%s+domain%-name%-servers%s+%"?(.-)%"?;')    
    
  end]]--
  
  for dom in (dhcp_file:gmatch('option%s+domain%-name%s+%"?(.-)%"?;')) do  
     
    domain[0] = {}        
    domain[0].name = dom 
    domain[0].server = dhcp_file:match('option%s+domain%-name%-servers%s+%"?(.-)%"?;')    
    
  end
  
  --Add Subnet Objects
  for subnet, subnetConf in (dhcp_file:gmatch("%s-subnet%s(.-)%s(.-})%s-")) do
    subnetCount = subnetCount + 1    
    subnets[subnet] = {}      
    subnets[subnet].subnet = subnet 
    subnets[subnet].netmask = subnetConf:match('netmask%s-(%d+%.%d+%.%d+%.%d+)')  
    subnets[subnet].router = subnetConf:match("option%s+routers%s+(%d+%.%d+%.%d+%.%d+);")     
    subnets[subnet].addrStart = subnetConf:match("range%s+(%d+%.%d+%.%d+%.%d+)%s+%d+%.%d+%.%d+%.%d+;")
    subnets[subnet].addrEnd = subnetConf:match("range%s+%d+%.%d+%.%d+%.%d+%s+(%d+%.%d+%.%d+%.%d+);")   
             
  end     
end

function dhcp_to_msg()
  local msg = {}
  dhcp_ctr = 0  
  
  --Send Subnet info
  for idx,dhcpf in pairs(subnets) do
     sub_cfg = {}
     sub_cfg.objid =  RSM.RSM_TagID.TAG_NET_DHCP_CFG
     sub_cfg[RSM.RSM_TagID.TAG_NET_SUBNET] = dhcpf.subnet     
     sub_cfg[RSM.RSM_TagID.TAG_NET_NETMASK] = dhcpf.netmask
     sub_cfg[RSM.RSM_TagID.TAG_NET_ROUTER] = dhcpf.router
     sub_cfg[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_START] = dhcpf.addrStart
     sub_cfg[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_END] = dhcpf.addrEnd         
          
     msg[dhcp_ctr] = sub_cfg
     dhcp_ctr = dhcp_ctr+1
  end
  
  --Send domain info
  for idx,dhcpf in pairs(domain) do    
     dom_cfg = {} 
     dom_cfg.objid = RSM.RSM_TagID.TAG_NET_DHCP_DOMAIN
     dom_cfg[RSM.RSM_TagID.TAG_NET_DOMAINNAME] = dhcpf.name
     dom_cfg[RSM.RSM_TagID.TAG_NET_SERVERNAME] = dhcpf.server     
     
     msg[dhcp_ctr] = dom_cfg
     dhcp_ctr = dhcp_ctr+1
  end 
    
  return msg
end

function update_dhcp(cfg)
subnets = {}
domain[0] = {}
   for idx,obj in pairs(cfg) do
      if obj.objid and obj.objid == RSM.RSM_TagID.TAG_NET_DHCP_CFG then
          if obj[RSM.RSM_TagID.TAG_NET_SUBNET] then              
              subnets[obj[RSM.RSM_TagID.TAG_NET_SUBNET]]={}              
              subf = subnets[obj[RSM.RSM_TagID.TAG_NET_SUBNET]]
              if subf then
                setsubnets(subf,obj)
              end
          end 
      end
      --[[if obj.objid and obj.objid == RSM.RSM_TagID.TAG_NET_DHCP_DOMAIN then
          if obj[RSM.RSM_TagID.TAG_NET_DOMAINNAME] then
              domf = domain[obj[RSM.RSM_TagID.TAG_NET_DOMAINNAME]]
              --[[if domf then
                setdomain(domf,obj)
              end
          end 
      end]]--
      if obj.objid and obj.objid == RSM.RSM_TagID.TAG_NET_DHCP_DOMAIN then
          if obj[RSM.RSM_TagID.TAG_NET_DOMAINNAME] then
              domf = domain[0]
              if domf then
                setdomain(domf,obj)
              end
          end 
      end
   end 
end

function setsubnets(subf,obj)
    if obj[RSM.RSM_TagID.TAG_NET_SUBNET] then
       subf.subnet = obj[RSM.RSM_TagID.TAG_NET_SUBNET]
    end
    if obj[RSM.RSM_TagID.TAG_NET_NETMASK] then
       subf.netmask = obj[RSM.RSM_TagID.TAG_NET_NETMASK]
    end
    if obj[RSM.RSM_TagID.TAG_NET_ROUTER] then
       subf.router = obj[RSM.RSM_TagID.TAG_NET_ROUTER]
    end
    if obj[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_START] then
       subf.addrStart = obj[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_START]
    end
    if obj[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_END] then
       subf.addrEnd = obj[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_END]
    end    
    subf.changed = 1
end
function setdomain(domf,obj)
    if obj[RSM.RSM_TagID.TAG_NET_DOMAINNAME] then    
       domf.name = obj[RSM.RSM_TagID.TAG_NET_DOMAINNAME]
       print("Storing domain name: "..domf.name)
    end 
    if obj[RSM.RSM_TagID.TAG_NET_SERVERNAME] then
       domf.server = obj[RSM.RSM_TagID.TAG_NET_SERVERNAME]
       print("Storing server name: "..domf.server)
    end       
    domf.changed = 1
end

function store_dhcp()

local dhcp_config = ""

   for idx,domf in pairs(domain) do       
       dhcp_config =  'option domain-name "'..domf.name..'";\n'
       dhcp_config = dhcp_config.."option domain-name-servers "..domf.server..";\n"
       dhcp_config = dhcp_config.."\n"         
   end
   
   dhcp_config = dhcp_config.."default-lease-time 14440;\n"
   dhcp_config = dhcp_config.."ddns-update-style none;\n"
   dhcp_config = dhcp_config.."deny bootp;\n"
   dhcp_config = dhcp_config.."\n" 
   
   for idx,subf in pairs(subnets) do       
       dhcp_config = dhcp_config.."subnet "..subf.subnet.." "
       dhcp_config = dhcp_config.."netmask "..subf.netmask.." {\n\t"
       dhcp_config = dhcp_config.."option routers "..subf.router..";\n\t"
       dhcp_config = dhcp_config.."range "..subf.addrStart.." "..subf.addrEnd..";\n}\n\n"           
   end
   
   --dhcp_file = dhcp_config        
   
   writefile(dhcp_conf_file,dhcp_config)
   command_exec(dhcpd_stop)
   command_exec(dhcpd_start)
end

--Testing....

--[[print("Testing...")

print("Get Config: ")

print_table(getConfig(),0)

local testCfg = {}
local obj ={}
local obj1 ={}
local obj2 ={}
local obj3 ={}

obj.objid = RSM.RSM_TagID.TAG_NET_DHCP_CFG
obj[RSM.RSM_TagID.TAG_NET_DHCP_SUBNET] = "192.168.5.0"     
obj[RSM.RSM_TagID.TAG_NET_DHCP_NETMASK] = "255.255.255.0"
obj[RSM.RSM_TagID.TAG_NET_DHCP_ROUTER] = "192.168.5.1"
obj[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_START] = "192.168.5.50"
obj[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_END] = "192.168.5.200" 

obj1.objid = RSM.RSM_TagID.TAG_NET_DHCP_CFG
obj1[RSM.RSM_TagID.TAG_NET_DHCP_SUBNET] = "192.168.2.0"     
obj1[RSM.RSM_TagID.TAG_NET_DHCP_NETMASK] = "255.255.255.0"
obj1[RSM.RSM_TagID.TAG_NET_DHCP_ROUTER] = "192.168.2.1"
obj1[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_START] = "192.168.2.50"
obj1[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_END] = "192.168.2.200"

obj3.objid = RSM.RSM_TagID.TAG_NET_DHCP_CFG
obj3[RSM.RSM_TagID.TAG_NET_DHCP_SUBNET] = "999.999.2.0"     
obj3[RSM.RSM_TagID.TAG_NET_DHCP_NETMASK] = "255.255.255.0"
obj3[RSM.RSM_TagID.TAG_NET_DHCP_ROUTER] = "999.999.2.1"
obj3[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_START] = "999.999.2.50"
obj3[RSM.RSM_TagID.TAG_NET_DHCP_ADDR_END] = "999.999.2.200"

obj2.objid = RSM.RSM_TagID.TAG_NET_DHCP_DOMAIN
obj2[RSM.RSM_TagID.TAG_NET_DOMAINNAME] = "guinnux.local"
obj2[RSM.RSM_TagID.TAG_NET_SERVERNAME] = "8.8.8.8"

testCfg[3] = obj
testCfg[2] = obj1
testCfg[1] = obj3
testCfg[4] = obj2

setConfig(testCfg)]]--





























