/usr/share/wireshark/dtd_gen.lua is in libwireshark-data 2.0.2+ga16e22e-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | -- dtd_gen.lua
--
-- a DTD generator for wireshark
--
-- (c) 2006 Luis E. Garcia Ontanon <luis@ontanon.org>
--
-- Wireshark - Network traffic analyzer
-- By Gerald Combs <gerald@wireshark.org>
-- Copyright 1998 Gerald Combs
--
-- This program is free software; you can redistribute it 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 program 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, write to the Free Software
-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
if gui_enabled() then
local xml_fld = Field.new("xml")
local function dtd_generator()
local displayed = {} -- whether or not a dtd is already displayed
local dtds = {} -- the dtds
local changed = {} -- whether or not a dtd has been modified
local dtd -- the dtd being dealt with
local dtd_name -- its name
-- we'll tap onto every frame that has xml
local ws = {} -- the windows for each dtd
local w = TextWindow.new("DTD Generator")
local function help()
local wh = TextWindow.new("DTD Generator Help")
-- XXX write help
wh:set('DTD Generator Help\n')
end
local function get_dtd_from_xml(text,d,parent)
-- obtains dtd information from xml
-- text: xml to be parsed
-- d: the current dtd (if any)
-- parent: parent entity (if any)
-- cleanup the text from useless chars
text = string.gsub(text ,"%s*<%s*","<");
text = string.gsub(text ,"%s*>%s*",">");
text = string.gsub(text ,"<%-%-(.-)%-%->"," ");
text = string.gsub(text ,"%s+"," ");
while true do
-- find the first tag
local open_tag = string.match(text,"%b<>")
if open_tag == nil then
-- no more tags, we're done
return true
end
local name = string.match(open_tag,"[%w%d_-]+")
local this_ent = nil
if d == nil then
-- there's no current dtd, this is entity is it
d = dtds[name]
if d == nil then
d = {ents = {}, attrs = {}}
dtds[name] = d
end
dtd = d
dtd_name = name
end
this_ent = d[name]
if this_ent == nil then
-- no entity by this name in this dtd, create it
this_ent = {ents = {}, attrs = {}}
d.ents[name] = this_ent
changed[dtd_name] = true
end
if parent ~= nil then
-- add this entity to its parent
parent.ents[name] = 1
changed[dtd_name] = true
end
-- add the attrs to the entity
for att in string.gmatch(open_tag, "([%w%d_-]+)%s*=") do
if not this_ent.attrs[att] then
changed[dtd_name] = true
this_ent.attrs[att] = true
end
end
if string.match(open_tag,"/>") then
-- this tag is "self closed" just remove it and continue
text = string.gsub(text,"%b<>","",1)
else
local close_tag_pat = "</%s*" .. name .. "%s*>"
if not string.match(text,close_tag_pat) then return false end
local span,left = string.match(text,"%b<>(.-)" .. close_tag_pat .. "(.*)")
if span ~= nil then
-- recurse to find child entities
if not get_dtd_from_xml(span,d,this_ent) then
return false
end
end
-- continue with what's left
text = left
end
end
return true
end
local function entity_tostring(name,entity_data)
-- name: the name of the entity
-- entity_data: a table containg the entity data
-- returns the dtd text for that entity
local text = ''
text = text .. '\t<!ELEMENT ' .. name .. ' (' --)
for e,j in pairs(entity_data.ents) do
text = text .. " " .. e .. ' |'
end
text = text .. " #PCDATA ) >\n"
text = text .. "\t<!ATTLIST " .. name
for a,j in pairs(entity_data.attrs) do
text = text .. "\n\t\t" .. a .. ' CDTATA #IMPLIED'
end
text = text .. " >\n\n"
text = string.gsub(text,"<!ATTLIST " .. name .. " >\n","")
return text
end
local function dtd_tostring(name,doctype)
local text = '<? wireshark:protocol proto_name="' .. name ..'" hierarchy="yes" ?>\n\n'
local root = doctype.ents[name]
doctype.ents[name] = nil
text = text .. entity_tostring(name,root)
for n,es in pairs(doctype.ents) do
text = text .. entity_tostring(n,es)
end
doctype.ents[name] = root
return text
end
local function element_body(name,text)
-- get the entity's children from dtd text
-- name: the name of the element
-- text: the list of children
text = string.gsub(text,"[%s%?%*%#%+%(%)]","")
text = string.gsub(text,"$","|")
text = string.gsub(text,
"^(.-)|",
function(s)
if dtd.ents[name] == nil then
dtd.ents[name] = {ents={},attrs={}}
end
dtd.ents[name].ents[s] = true
return ""
end
)
return ''
end
local function attlist_body(name,text)
-- get the entity's attributes from dtd text
-- name: the name of the element
-- text: the list of attributes
text = string.gsub(text,"([%w%d_-]+) [A-Z]+ #[A-Z]+",
function(s)
dtd.atts[s] = true
return ""
end
)
return ''
end
local function dtd_body(buff)
-- get the dtd's entities from dtd text
-- buff: the dtd text
local old_buff = buff
buff = string.gsub(buff,"<!ELEMENT ([%w%d_-]+) (%b())>%s*",element_body)
buff = string.gsub(buff,"<!ATTLIST ([%w%d_-]+) (.-)>%s*",attlist_body)
end
local function load_dtd(filename)
local dtd_filename = USER_DIR .. "/dtds/" .. filename
local buff = ''
local wireshark_info
dtd_name = nil
dtd = nil
for line in io.lines(dtd_filename) do
buff = buff .. line
end
buff = string.gsub(buff ,"%s*<%!%s*","<!");
buff = string.gsub(buff ,"%s*>%s*",">");
buff = string.gsub(buff ,"<!%-%-(.-)%-%->"," ");
buff = string.gsub(buff ,"%s+"," ");
buff = string.gsub(buff ,"^%s+","");
buff = string.gsub(buff,'(<%?%s*wireshark:protocol%s+.-%s*%?>)',
function(s)
wireshark_info = s
end
)
buff = string.gsub(buff,"^<!DOCTYPE ([%w%d_-]+) (%b[])%s*>",
function(name,body)
dtd = { ents = {}, attrs = {}}
dtd_name = name
dtds[name] = dtd
dtd_body(body)
return ""
end
)
if not dtd then
dtd_body(buff)
end
if wireshark_info then
dtd.wstag = wireshark_info
end
end
local function load_dtds()
-- loads all existing dtds in the user directory
local dirname = persconffile_path("dtds")
local status, dir = pcall(Dir.open,dirname,".dtd")
w:set('Loading DTDs from ' .. dirname .. ' \n')
if not status then
w:append("Error: could not open the directory" .. dirname .. " , make sure it exists.\n")
return
end
for dtd_filename in dir do
w:append("File:" .. dtd_filename .. "\n")
load_dtd(dtd_filename)
end
end
local function dtd_window(name)
return function()
local wd = TextWindow.new(name .. '.dtd')
wd:set(dtd_tostring(name,dtds[name]))
wd:set_editable()
local function save()
local file = io.open(persconffile_path("dtds/") .. name .. ".dtd" ,"w")
file:write(wd:get_text())
file:close()
end
wd:add_button("Save",save)
end
end
local function close()
if li ~= nil then
li:remove()
li = nil
end
end
w:set_atclose(close)
-- w:add_button("Help",help)
load_dtds()
local li = Listener.new("frame","xml")
w:append('Running')
function li.packet()
w:append('.')
local txt = xml_fld().range:string();
get_dtd_from_xml(txt)
end
function li.draw()
for name,j in pairs(changed) do
w:append("\n" .. name .. " has changed\n")
if not displayed[name] then
w:add_button(name,dtd_window(name))
displayed[name] = true
end
end
end
retap_packets()
w:append(t2s(dtds))
w:append('\n')
end
register_menu("DTD Generator",dtd_generator,MENU_TOOLS_UNSORTED)
end
|