summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTed Trask <ttrask01@yahoo.com>2009-01-09 22:00:23 +0000
committerTed Trask <ttrask01@yahoo.com>2009-01-09 22:00:23 +0000
commitf524a6f6edf59eaf6e20043d4e54fe866f7f1357 (patch)
tree79bc7b7cffa77313526ae0d05026184b4e7bddbd
parentccdcb4b6983ee1f32842aebae229e4d8700d80e2 (diff)
downloadacf-opennhrp-f524a6f6edf59eaf6e20043d4e54fe866f7f1357.tar.bz2
acf-opennhrp-f524a6f6edf59eaf6e20043d4e54fe866f7f1357.tar.xz
Virtual rewrite of opennhrp to change config to listinterfaces and editinterface. Modified expert to allow writing of file with errors.
git-svn-id: svn://svn.alpinelinux.org/acf/opennhrp/trunk@1673 ab2d0c66-481e-0410-8bed-d214d4d58bed
-rw-r--r--opennhrp-config-html.lsp27
-rw-r--r--opennhrp-controller.lua8
-rw-r--r--opennhrp-editinterface-html.lsp10
-rw-r--r--opennhrp-listinterfaces-html.lsp25
-rw-r--r--opennhrp-model.lua341
-rw-r--r--opennhrp.menu2
-rw-r--r--opennhrp.roles4
7 files changed, 261 insertions, 156 deletions
diff --git a/opennhrp-config-html.lsp b/opennhrp-config-html.lsp
deleted file mode 100644
index 75c98ce..0000000
--- a/opennhrp-config-html.lsp
+++ /dev/null
@@ -1,27 +0,0 @@
-<% local form, viewlibrary, page_info, session = ...
-require("viewfunctions")
-%>
-<%
---[[ DEBUG INFORMATION
-io.write("<H1>DEBUGGING</H1><span style='color:red'><H2>DEBUG INFO: CFE</H2>")
-io.write(html.cfe_unpack(form))
-io.write("</span>")
---]]
-%>
-
-<% displaycommandresults({"startstop"}, session) %>
-
-<% if viewlibrary and viewlibrary.dispatch_component then
- viewlibrary.dispatch_component("status")
-end %>
-
-<H1>Config</H1>
-<%
- form.action = page_info.script .. page_info.prefix .. page_info.controller .. "/" .. page_info.action
- local order = {"outgoinginterface", "peers", "publishedinterfaces"}
- displayform(form, order)
-%>
-
-<% if viewlibrary and viewlibrary.dispatch_component then
- viewlibrary.dispatch_component("startstop")
-end %>
diff --git a/opennhrp-controller.lua b/opennhrp-controller.lua
index aab365d..94ea3eb 100644
--- a/opennhrp-controller.lua
+++ b/opennhrp-controller.lua
@@ -16,8 +16,12 @@ function startstop(self)
return controllerfunctions.handle_startstop(self, self.model.startstop_service, self.model.getstatus, self.clientdata)
end
-function config(self)
- return controllerfunctions.handle_form(self, function() return self.model:getconfig() end, function(value) return self.model:setconfig(value) end, self.clientdata, "Save", "Edit Config", "Configuration Set")
+function listinterfaces(self)
+ return self.model.listinterfaces(self)
+end
+
+function editinterface(self)
+ return controllerfunctions.handle_form(self, function() return self.model.getinterfacedetails(self.clientdata.interface) end, self.model.updateinterfacedetails, self.clientdata, "Save", "Edit Interface Config", "Interface Configuration Set")
end
function expert (self)
diff --git a/opennhrp-editinterface-html.lsp b/opennhrp-editinterface-html.lsp
new file mode 100644
index 0000000..73af9ab
--- /dev/null
+++ b/opennhrp-editinterface-html.lsp
@@ -0,0 +1,10 @@
+<% local form, viewlibrary, page_info = ...
+require("viewfunctions")
+%>
+
+<H1><%= form.label %></H1>
+<%
+ form.value.interface.contenteditable = false
+ local option = {"interface", "type", "map"}
+ displayform(form, option, nil, page_info)
+%>
diff --git a/opennhrp-listinterfaces-html.lsp b/opennhrp-listinterfaces-html.lsp
new file mode 100644
index 0000000..ca3fdb6
--- /dev/null
+++ b/opennhrp-listinterfaces-html.lsp
@@ -0,0 +1,25 @@
+<% local view, viewlibrary, page_info, session = ...
+require("viewfunctions")
+%>
+
+<% displaycommandresults({"editinterface"}, session) %>
+
+<h1><%= view.label %></h1>
+<TABLE>
+ <TR style="background:#eee;font-weight:bold;">
+ <TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">Action</TD>
+ <TD style="padding-right:20px;white-space:nowrap;text-align:right;" class="header">Interface</TD>
+ <TD style="padding-right:20px;white-space:nowrap;text-align:left;" class="header">Type</TD>
+ <TD style="white-space:nowrap;text-align:left;" class="header">Comment</TD>
+ </TR>
+<% for i,intf in ipairs(view.value) do %>
+ <TR>
+ <TD style="padding-right:20px;white-space:nowrap;">
+ <% io.write(html.link{value = "editinterface?interface="..intf.interface.."&redir="..page_info.orig_action, label="Edit " }) %>
+ </TD>
+ <TD style="padding-right:20px;white-space:nowrap;text-align:right;"><%= intf.interface %></TD>
+ <TD style="padding-right:20px;white-space:nowrap;"><%= intf.type %></TD>
+ <TD style="white-space:nowrap;" width="90%"><P class="error"><%= string.gsub(intf.errtxt or "", "\n", "<BR>") %></P></TD>
+ </TR>
+<% end %>
+</TABLE>
diff --git a/opennhrp-model.lua b/opennhrp-model.lua
index 2601655..ef9c69a 100644
--- a/opennhrp-model.lua
+++ b/opennhrp-model.lua
@@ -9,6 +9,9 @@ local configfile = "/etc/opennhrp/opennhrp.conf"
local processname = "opennhrp"
local packagename = "opennhrp"
+local interfaceslist, reverseinterfaceslist
+local config, configfilecontent
+
local descr = {
Type = {
['incomplete']="The protocol address is being resolved",
@@ -28,7 +31,130 @@ local descr = {
-- ################################################################################
-- LOCAL FUNCTIONS
-local function opennhrpctl_show()
+local function list_interfaces(self)
+ if not interfaceslist then
+ -- Get the list of available interfaces
+ local interfaces = self:new("alpine-baselayout/interfaces")
+ local availableinterfaces = interfaces:read()
+ interfaceslist = {}
+ reverseinterfaceslist = {}
+ for i,int in ipairs(availableinterfaces.value) do
+ interfaceslist[#interfaceslist + 1] = int.value.name.value
+ reverseinterfaceslist[int.value.name.value] = #interfaceslist
+ end
+ interfaces:destroy()
+ end
+ return interfaceslist, reverseinterfaceslist
+end
+
+local function parseconfigfile(configfilecontent)
+ local config = {}
+
+ local currentinterface
+ local words = {}
+ for word in configfilecontent:gmatch("%S+") do words[#words + 1] = word end
+ local i=1
+ while i <= table.maxn(words) do
+ local word = words[i]
+ if not currentinterface and word ~= "interface" then
+ currentinterface = ""
+ config[""].errtxt = "Syntax error - undefined interface"
+ end
+ if word == "interface" then
+ i = i+1
+ currentinterface = words[i]
+ if config[currentinterface] then
+ config[currentinterface].errtxt = "Syntax error - interface defined multiple times"
+ else
+ config[currentinterface] = {}
+ end
+ elseif word == "map" then
+ -- there may be more than one map statement
+ if not config[currentinterface].map then
+ config[currentinterface].map = {}
+ end
+ local temp = {words[i+1], words[i+2]}
+ i = i+2
+ if words[i+1] == "register" then
+ temp[3] = words[i+1]
+ i = i+1
+ end
+ table.insert(config[currentinterface].map, temp)
+ elseif word == "cisco-authentication" then
+ config[currentinterface]["cisco-authentication"] = {words[i+1]}
+ i = i+1
+ elseif word == "redirect" or word == "shortcut" or word == "non-caching" or word == "shortcut-destination" then
+ config[currentinterface][word] = {}
+ else
+ table.insert(config[currentinterface], word)
+ end
+ i = i+1
+ end
+
+ -- Check interfaces for errors
+ for interf,val in pairs(config) do
+ if val[1] then
+ local errtxt = "Syntax error - unrecognized keyword"
+ if val.errtxt then
+ val.errtxt = val.errtxt .. "\n" .. errtxt
+ else
+ val.errtxt = errtxt
+ end
+ end
+ end
+
+ return config
+end
+
+local function validateconfigfile(self, configfile)
+ local config = parseconfigfile(configfile.value.filecontent.value)
+ list_interfaces(self)
+ local errtxt = {}
+ for name,value in pairs(config) do
+ if name ~= "" and not reverseinterfaceslist[name] then
+ errtxt[#errtxt + 1] = name .. " - Nonexistant interface"
+ end
+ if value.errtxt then
+ errtxt[#errtxt + 1] = name .. " - " .. string.gsub(value.errtxt, "\n", "\n"..name.." - ")
+ end
+ end
+ if #errtxt then
+ configfile.value.filecontent.errtxt = table.concat(errtxt, "\n")
+ end
+ return configfile
+end
+
+local function validateinterfacedetails(interfacedetails)
+ local success = modelfunctions.validateselect(interfacedetails.value.type)
+ for i,map in ipairs(interfacedetails.value.map.value) do
+ local words = {}
+ for word in string.gmatch(map, "%S+") do words[#words+1] = word end
+ if not words[1] or not words[2] or (words[3] and words[3] ~= "register") or words[4] then
+ interfacedetails.value.map.errtxt = "Syntax error on line "..i
+ success = false
+ break
+ end
+ end
+ if not interfacedetails.value.interface.value or string.find(interfacedetails.value.interface.value, "%s") then
+ interfacedetails.value.interface.errtxt = "Invalid interface name"
+ success = false
+ end
+
+ return success, interfacedetails
+end
+
+-- ################################################################################
+-- PUBLIC FUNCTIONS
+
+function startstop_service(action)
+ return modelfunctions.startstop_service(processname, action)
+end
+
+function getstatus()
+ return modelfunctions.getstatus(processname, packagename, "OpenNHRP Status")
+end
+
+function getshowreport()
local peers_list = cfe({ type="structure", value={}, label="Peers" })
local opennhrpstatus = cfe({ value="Show report not available", label="Status" })
local cmd = "/usr/sbin/opennhrpctl show 2>/dev/null"
@@ -58,151 +184,118 @@ local function opennhrpctl_show()
return cfe({ type="group", value={peers_list=peers_list, status=opennhrpstatus}, label="OpenNHRP Show Report" })
end
-local function parseconfigfile(self, configfile)
- if fs.is_file(configfile) then
- configfile = fs.read_file(configfile)
+function getinterfacedetails(interface)
+ local details = {}
+ details.interface = cfe({ value=interface, label="Interface" })
+ details.type = cfe({ type="select", value="Unused", label="Interface type", option={"Unused", "NHRP Enabled", "Shortcut Destination"} })
+ details.map = cfe({ type="list", value={}, label="Static Peers", descr="List of static peer mappings of protocol-address to nbma-address. Optional 'register' parameter specifies Registration Request sent to this peer on startup. (protocol-address[/prefix] nbma-address [register])" })
+
+ configfilecontent = configfilecontent or fs.read_file(configfile)
+ config = config or parseconfigfile(configfilecontent)
+ if config and config[interface] then
+ if config[interface]["shortcut-destination"] then
+ details.type.value = "Shortcut Destination"
+ else
+ details.type.value = "NHRP Enabled"
+ end
+ for i,map in ipairs(config[interface].map or {}) do
+ table.insert(details.map.value, table.concat(map, " "))
+ end
+ details.interface.errtxt = config[interface].errtxt
end
- -- Get the list of available interfaces
- local interfaces = self:new("alpine-baselayout/interfaces")
- local availableinterfaces = interfaces:read()
- local listinterfaces = {}
- local reverseinterfaces = {}
- for i,int in ipairs(availableinterfaces.value) do
- listinterfaces[#listinterfaces + 1] = int.value.name.value
- reverseinterfaces[int.value.name.value] = #listinterfaces
- end
- interfaces:destroy()
+ return cfe({ type="group", value=details, label="OpenNHRP Interface Configuration" })
+end
- local outgoinginterface = cfe({ type="select", label="Outgoing Interface", option=listinterfaces })
- local publishedinterfaces = cfe({ type="multi", value={}, label="Published Interfaces", option=listinterfaces })
- local peers = cfe({ type="list", value={}, label="Registered Peers", descr="protocol-address[/prefix] nbma-address" })
- local currentinterface = ""
- local words = {}
- for word in configfile:gmatch("%S+") do words[#words + 1] = word end
- for i,word in ipairs(words) do
- if word == "interface" then
- currentinterface = words[i+1]
- elseif word == "map" then
- if outgoinginterface.value ~= "" and outgoinginterface.value ~= currentinterface then
- outgoinginterface.errtxt = "Multiple outgoing interfaces not supported"
- else
- outgoinginterface.value = currentinterface
- peers.value[#peers.value + 1] = words[i+1] .. " " .. words[i+2]
+function updateinterfacedetails(interfacedetails)
+ local success, interfacedetails = validateinterfacedetails(interfacedetails)
+
+ if success then
+ configfilecontent = configfilecontent or fs.read_file(configfile)
+ local startchar = string.find(configfilecontent or "", "interface%s+"..interfacedetails.value.interface.value)
+ local lines = {}
+ if startchar then
+ lines[1] = string.gsub(string.sub(configfilecontent, 1, startchar-1), "\n+$", "")
+ startchar = string.find(configfilecontent, "interface", startchar+1)
+ if startchar then
+ lines[2] = string.sub(configfilecontent, startchar, -1)
end
- elseif word == "shortcut-destination" then
- publishedinterfaces.value[#publishedinterfaces.value + 1] = currentinterface
+ else
+ lines[1] = string.gsub(configfilecontent or "", "\n+$", "")
end
- end
- return cfe({ type="group", value={outgoinginterface=outgoinginterface, peers=peers, publishedinterfaces=publishedinterfaces}, label="OpenNHRP Config" })
-end
+ if interfacedetails.value.type.value ~= "Unused" then
+ local intflines = {"interface "..interfacedetails.value.interface.value}
+ if interfacedetails.value.type.value == "Shortcut Destination" then
+ intflines[2] = "\tshortcut-destination"
+ else
+ for i,map in ipairs(interfacedetails.value.map.value) do
+ table.insert(intflines, "\tmap "..map)
+ end
-local function generateconfigfile(config)
- local filelines = {}
- filelines[#filelines + 1] = "interface " .. config.value.outgoinginterface.value
- for i,value in ipairs(config.value.peers.value) do
- filelines[#filelines + 1] = " map " .. value .. " register"
- end
- filelines[#filelines + 1] = " shortcut"
- filelines[#filelines + 1] = " redirect"
- filelines[#filelines + 1] = " non-caching"
- filelines[#filelines + 1] = ""
- for i,value in ipairs(config.value.publishedinterfaces.value) do
- filelines[#filelines + 1] = "interface " .. value
- filelines[#filelines + 1] = " shortcut-destination"
- filelines[#filelines + 1] = ""
+ config = config or parseconfigfile(configfilecontent)
+ local intfconfig = config[interfacedetails.value.interface.value] or {}
+ intfconfig.map = nil
+ intfconfig["shortcut-destination"] = nil
+ for name,arr in pairs(intfconfig) do
+APP.logevent(name)
+ if type(name) ~= "number" and name ~= "errtxt" then
+ table.insert(intflines, "\t"..name.." "..table.concat(arr, " "))
+ end
+ end
+ end
+ table.insert(lines, 2, table.concat(intflines, "\n"))
+ end
+
+ fs.write_file(configfile, table.concat(lines, "\n"))
+ configfilecontent = nil
+ config = nil
+ else
+ interfacedetails.errtxt = "Failed to save Interface Details"
end
- return table.concat(filelines, "\n")
+ return interfacedetails
end
-local function validateconfig(config)
- local success = true
- if not modelfunctions.validateselect(config.value.outgoinginterface) then
- success = false
- end
- if not modelfunctions.validatemulti(config.value.publishedinterfaces) then
- success = false
- end
- -- make sure don't try to publish the outgoing interface
- for i,value in ipairs(config.value.publishedinterfaces.value) do
- if value == config.value.outgoinginterface.value then
- success = false
- config.value.publishedinterfaces.errtxt = "Cannot publish outgoing interface"
- break
+function listinterfaces(self)
+ local interfaces = {}
+ list_interfaces(self)
+ configfilecontent = configfilecontent or fs.read_file(configfile)
+ config = config or parseconfigfile(configfilecontent)
+ for name,intf in pairs(config) do
+ temp = {interface=name, type="NHRP Enabled", errtxt=intf.errtxt}
+ if intf["shortcut-destination"] then
+ temp.type = "Shortcut Destination"
end
- end
- for i,value in ipairs(config.value.peers.value) do
- if not validator.is_ipv4(value:match("[^%s/]+")) then
- success = false
- config.value.peers.errtxt = "Syntax error - invalid ip address"
- break
- elseif value:match("/(%d*)") and not validator.is_integer_in_range(value:match("/(%d*)"), 1, 31) then
- success = false
- config.value.peers.errtxt = "Syntax error - invalid prefix"
- break
- elseif string.find(value:match("%s(%S+)"), "[^%w.-]") then
- success = false
- config.value.peers.errtxt = "Syntax error - invalid domain name"
- break
+ if not reverseinterfaceslist[name] then
+ local errtxt = "Nonexistant interface"
+ if temp.errtxt then
+ temp.errtxt = temp.errtxt .. "\n" .. errtxt
+ else
+ temp.errtxt = errtxt
+ end
end
+ table.insert(interfaces, temp)
end
- return success, config
-end
-local function validateconfigfile(self, configfile)
- local config = parseconfigfile(self, configfile.value.filecontent.value)
- local success, config = validateconfig(config)
- if not success then
- local errtxt = {}
- for name,value in pairs(config.value) do
- if value.errtxt then
- errtxt[#errtxt + 1] = name .. " - " .. value.errtxt
- end
- end
- if #errtxt then
- configfile.value.filecontent.errtxt = table.concat(errtxt, "\n")
+ for i,name in ipairs(interfaceslist) do
+ if not config[name] then
+ table.insert(interfaces, {interface=name, type="Unused"})
end
end
- return success, configfile
-end
-
--- ################################################################################
--- PUBLIC FUNCTIONS
-
-function startstop_service(action)
- return modelfunctions.startstop_service(processname, action)
-end
-function getstatus()
- return modelfunctions.getstatus(processname, packagename, "Opennhrp Status")
-end
-
-function getshowreport()
- return opennhrpctl_show()
-end
-
-function getconfig(self)
- local config = parseconfigfile(self, configfile)
- local result, config = validateconfig(config)
- return config
-end
-
-function setconfig(self, config)
- local success, config = validateconfig(config)
- if success then
- fs.write_file(configfile, generateconfigfile(config))
- else
- config.errtxt = "Failed to set configuration"
- end
- return config
+ return cfe({ type="structure", value=interfaces, label="OpenNHRP Interfaces" })
end
function getconfigfile(self)
- return modelfunctions.getfiledetails(configfile, nil, function(filedetails) return validateconfigfile(self, filedetails)end)
+ return validateconfigfile(self, modelfunctions.getfiledetails(configfile))
end
function setconfigfile(self, filedetails)
- return modelfunctions.setfiledetails(filedetails, {configfile}, function(filedetails) return validateconfigfile(self, filedetails)end)
+ filedetails = modelfunctions.setfiledetails(filedetails, {configfile})
+ if not filedetails.errtxt then
+ configfilecontent = nil
+ config = nil
+ end
+ return validateconfigfile(self, filedetails)
end
diff --git a/opennhrp.menu b/opennhrp.menu
index c8ce6cb..65dc1ee 100644
--- a/opennhrp.menu
+++ b/opennhrp.menu
@@ -1,4 +1,4 @@
#CAT GROUP/DESC TAB ACTION
Networking 45NHRP Status show
-Networking 45NHRP Config config
+Networking 45NHRP Config listinterfaces
Networking 45NHRP Expert expert
diff --git a/opennhrp.roles b/opennhrp.roles
index 2d16b10..b55dedf 100644
--- a/opennhrp.roles
+++ b/opennhrp.roles
@@ -1,4 +1,4 @@
USER=opennhrp:status,opennhrp:show,opennhrp:startstop
-EDITOR=opennhrp:config
+EDITOR=opennhrp:listinterfaces,opennhrp:editinterface
EXPERT=opennhrp:expert
-ADMIN=opennhrp:status,opennhrp:show,opennhrp:startstop,opennhrp:config,opennhrp:expert
+ADMIN=opennhrp:status,opennhrp:show,opennhrp:startstop,opennhrp:listinterfaces,opennhrp:editinterface,opennhrp:expert