Skip to content

Commit

Permalink
web-sniffer
Browse files Browse the repository at this point in the history
  • Loading branch information
hannesm committed Jan 21, 2014
1 parent d546b28 commit b552995
Show file tree
Hide file tree
Showing 8 changed files with 390 additions and 0 deletions.
1 change: 1 addition & 0 deletions registry/generic/web-sniffer
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
abstract://dylan/web-sniffer/web-sniffer.lid
44 changes: 44 additions & 0 deletions web-sniffer/library.dylan
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module: dylan-user
define library web-sniffer
use common-dylan;
use io;
use system;

//web stuff
use http-common;
use http-server;
use json;

//nnv stuff
use binary-data;
use network-interfaces;
use protocols;
use layer;
use flow;
use network-flow;
end;

define module web-sniffer
use common-dylan, exclude: { format-to-string };
use date;
use format;
use format-out;
use standard-io;
use streams;
use threads;

//web stuff
use http-common;
use http-server;
use json;

//nnv stuff
use binary-data;
use network-interfaces;
use ethernet;
use layer;
use flow;
use network-flow;
end module;

1 change: 1 addition & 0 deletions web-sniffer/registry/generic/web-sniffer
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
abstract://dylan/web-sniffer.lid
131 changes: 131 additions & 0 deletions web-sniffer/static/gui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
Function.prototype.curry = function () {
// wir merken uns f
var f = this
if (arguments.length < 1) {
return f //nothing to curry with - return function
}
var a = toArray(arguments)
return function () {
var b = toArray(arguments)
return f.apply(this, a.concat(b))
}
}

function toArray (xs) {
return Array.prototype.slice.call(xs)
}

function initialize () {
var evtSource = new EventSource("events")

evtSource.onmessage = function (e) {
var newElement = document.createElement("li")
newElement.innerHTML = "message: " + e.data
document.getElementById("list").appendChild(newElement)
}

var shell = document.getElementById("shell")
var output = document.getElementById("output")
var debug = document.getElementById("debug")
shell.onkeyup = handle_keypress.curry(debug, output, shell)
}


function mouseX (evt) {
if (evt.pageX) return evt.pageX;
else if (evt.clientX)
return evt.clientX + (document.documentElement.scrollLeft ?
document.documentElement.scrollLeft :
document.body.scrollLeft);
else return null;
}

function mouseY (evt) {
if (evt.pageY) return evt.pageY;
else if (evt.clientY)
return evt.clientY + (document.documentElement.scrollTop ?
document.documentElement.scrollTop :
document.body.scrollTop);
else return null;
}

function handle_keypress (debug, output, inputfield, event) {
var keyCode = ('which' in event) ? event.which : event.keyCode
var val = inputfield.value
switch (keyCode) {
case 32: //space
debug.innerHTML = "space: " + val; break
case 13: //return
executeCommand(val, output); break
case 191: //?
getHelp(val, output); break
default:
debug.innerHTML = "unknown key " + keyCode
}
}

function executeCommand (command, output) {
function reqListener () {
var value = this.responseText
if (! value)
output.innerHTML = "RECEIVED error"
var res = eval(value)
var list = document.createElement("ul")
for (var i = 0; i < res.length; i++) {
var x = res[i]
var ele = document.createElement("li")
ele.innerHTML = x
list.appendChild(ele)
}
var old = output.firstChild
if (old)
output.replaceChild(list, old)
else
output.appendChild(list)
}

var eles = command.split(" ")
var req = eles.join("/")

var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.open("get", ("/execute/" + req), true);
oReq.send();
}

function getHelp (partialinput, output) {
function reqListener () {
var value = this.responseText
if (! value)
output.innerHTML = "RECEIVED error"
var res = eval(value)
var list = document.createElement("ul")
for (var i = 0; i < res.length; i++) {
var x = res[i]
var ele = document.createElement("li")
ele.innerHTML = x["name"] + ": " + x["description"]
list.appendChild(ele)
}
var old = output.firstChild
if (old)
output.replaceChild(list, old)
else
output.appendChild(list)
}

var oReq = new XMLHttpRequest()
oReq.onload = reqListener
oReq.open("get", ("/help/" + partialinput), true)
oReq.send()
}

function create_context_menu (ele) {
ele.onmouseover = function (event) {
document.getElementById("contextmenu").className = "show"
document.getElementById("contextmenu").style.top = mouseY(event)
document.getElementById("contextmenu").style.left = mouseX(event)
}
ele.onmouseout = function (event) {
document.getElementById("contextmenu").className = "hide"
}
}
26 changes: 26 additions & 0 deletions web-sniffer/static/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<html>
<link rel="stylesheet" href="my.css" />
<script src="gui.js"></script>
<script>window.onload = initialize</script>
<body>
<div>
input&gt; <input type="text" id="shell" autofocus="true"></input><br/>

output: <div id="output"></div></br>

debug: <div id="debug"></div>

</div>


<ul id="list"></ul>

<div class="hide" id="contextmenu">
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
</div>
</body>
</html>
23 changes: 23 additions & 0 deletions web-sniffer/static/my.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.show {
z-index:1000;
position: absolute;
background-color:#C0C0C0;
border: 1px solid blue;
padding: 2px;
display: block;
margin: 0;
list-style-type: none;
list-style: none;


}

.hide {
display: none;

}

.show li{list-style: none; }
.show a {border: 0 !important; text-decoration: none;}
.show a:hover {text-decoration: underline !important;}

161 changes: 161 additions & 0 deletions web-sniffer/web-sniffer.dylan
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
module: web-sniffer
define function dbg (#rest args)
apply(format-out, args);
force-output(*standard-output*);
end;


let server = make(<http-server>,
listeners: list("127.0.0.1:8888"));

let static-resource = make(<directory-resource>,
directory: "/home/hannes/dylan/network-night-vision/web-sniffer/static",
allow-directory-listing?: #t);
add-resource(server, "/", static-resource);


define variable *events-socket* :: false-or(<stream>) = #f;

define function stream-function (#rest args)
let req = current-request();
let stream :: <stream> = req.request-socket;
let response-line = format-to-string("%s %d %s",
"HTTP/1.1",
200,
"OK");
format(stream, "%s\r\n", response-line);
format(stream, "Content-Type: text/event-stream\r\n\r\n");
format(stream, "Cache-Control: no-cache\r\n\r\n");
format(stream, "\r\n\r\n");

dbg("events socket set to %=\n", stream);
*events-socket* := stream;
while (#t)
//different event types in JS!
//source.addEventListener('add', addHandler, false);
//source.addEventListener('remove', removeHandler, false);
// format(stream, "data: %s\r\n\r\n", as-iso8601-string(current-date()));
// force-output(stream);
sleep(50);
end;
end;

let stream-resource = make(<function-resource>,
function: stream-function);
add-resource(server, "/events", stream-resource);


define class <struct> (<object>)
constant slot value :: <collection>, required-init-keyword: value:;
end;

define function struct (#rest args) => (struct :: <struct>)
make(<struct>, value: args)
end;

define method encode-json (stream :: <stream>, object :: <struct>)
write(stream, "{");
for (key from 0 below object.value.size by 2,
val from 1 by 2)
if (key > 0)
write(stream, ", ");
end if;
encode-json(stream, as(<string>, object.value[key]));
write(stream, ":");
encode-json(stream, object.value[val]);
end for;
write(stream, "}");
end;

define function help (#key partial)
let response = current-response();
set-header(response, "Content-type", "application/json");
let res = make(<stretchy-vector>);
for (x in $command-table)
add!(res, struct(#"name", x.command-name,
#"description", x.command-description,
#"signature", x.command-signature));
end;
encode-json(response,res);
end;

let help-resource = make(<function-resource>, function: help);
add-resource(server, "/help/{partial}", help-resource);


define constant $command-table = make(<table>);

define constant $object-table = make(<table>);

define abstract class <command> (<object>)
constant slot command-name :: <symbol>, required-init-keyword: name:;
constant slot command-description :: <string>, required-init-keyword: description:;
constant slot command-signature :: <string> = "", init-keyword: signature:;
end;

define generic execute (c :: <command>, #rest args, #key, #all-keys);

define method make (class :: subclass(<command>), #rest rest, #key, #all-keys) =>
(res :: <command>)
let res = next-method();
$command-table[res.command-name] := res
end;

define class <list-command> (<command>)
end;
make(<list-command>, name: #"list", description: "Lists all available interfaces");

define method execute (c :: <list-command>, #key)
let devices = find-all-devices();
do(method (x)
$object-table[as(<symbol>, x.device-name)] := x
end, devices);
map(device-name, devices)
end;

define class <open-command> (<command>)
end;
make(<open-command>, name: #"open", description: "Opens a network interface", signature: "<interface>");


define method recursive-summary (frame :: <header-frame>) => (res :: <string>)
concatenate(summary(frame), "/", recursive-summary(frame.payload));
end;

define method recursive-summary (frame :: <frame>) => (res :: <string>)
summary(frame);
end;

define function print-summary (stream :: <stream>, frame :: <object>)
write(stream, "data: ");
quote-html(recursive-summary(frame), stream: stream);
write(stream, "\r\n\r\n");
force-output(stream);
end;

define method execute (c :: <open-command>, #rest args, #key)
let interface = args[0];
block ()
let mac = mac-address("00:de:ad:be:ef:00");
let ethernet-layer = build-ethernet-layer(interface, default-mac-address: mac);
let ethernet-socket = create-raw-socket(ethernet-layer);
let sum = make(<closure-node>, closure: curry(print-summary, *events-socket*));
connect(ethernet-socket, sum);
#("connected!")
exception (c :: <condition>)
struct(error: format-to-string("Cannot open interface %=: %=", interface, c));
end
end;

define function execute-handler (#key command, arguments)
let response = current-response();
set-header(response, "Content-type", "application/json");
let result = apply(execute, $command-table[as(<symbol>, command)], arguments);
encode-json(response, result)
end;

let execute-resource = make(<function-resource>, function: execute-handler);
add-resource(server, "/execute/{command}/{arguments*}", execute-resource);

start-server(server);
3 changes: 3 additions & 0 deletions web-sniffer/web-sniffer.lid
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Library: web-sniffer
Files: library
web-sniffer

0 comments on commit b552995

Please sign in to comment.