mirror of
https://github.com/ShadowKatStudios/OC-Minitel.git
synced 2024-11-26 03:48:06 +11:00
Compare commits
5 Commits
52ae542344
...
36d5df5fcc
Author | SHA1 | Date | |
---|---|---|---|
36d5df5fcc | |||
3496f70d6d | |||
5c1730d9d3 | |||
11ec131ab8 | |||
970926efb6 |
@ -85,6 +85,7 @@
|
|||||||
["vtunnel"] = {
|
["vtunnel"] = {
|
||||||
files = {
|
files = {
|
||||||
["master/vTunnel/interminitel.lua"] = "/lib",
|
["master/vTunnel/interminitel.lua"] = "/lib",
|
||||||
|
["master/vTunnel/OpenOS/usr/man/vtunnel"] = "/man",
|
||||||
["master/vTunnel/OpenOS/etc/rc.d/vtunnel.lua"] = "//etc/rc.d",
|
["master/vTunnel/OpenOS/etc/rc.d/vtunnel.lua"] = "//etc/rc.d",
|
||||||
},
|
},
|
||||||
dependencies = {
|
dependencies = {
|
||||||
|
@ -1,88 +1,142 @@
|
|||||||
local vcomp = require "vcomponent"
|
local vcomponent = require "vcomponent"
|
||||||
|
local serial = require "serialization"
|
||||||
local component = require "component"
|
local component = require "component"
|
||||||
local computer = require "computer"
|
local computer = require "computer"
|
||||||
local imt = require "interminitel"
|
|
||||||
local event = require "event"
|
local event = require "event"
|
||||||
local internet = component.internet
|
local imt = require "interminitel"
|
||||||
|
|
||||||
local addr, raddr = vcomp.uuid(),vcomp.uuid()
|
local cfg = {}
|
||||||
local poll = 0.5
|
cfg.peers = {}
|
||||||
local listener, timer
|
cfg.rtimer = 5
|
||||||
local socket
|
cfg.katimer = 30
|
||||||
|
local listeners = {}
|
||||||
|
local timers = {}
|
||||||
|
local proxies = {}
|
||||||
|
|
||||||
-- dumb keepalive stuff
|
local function loadcfg()
|
||||||
local keepalive = 30
|
local f = io.open("/etc/vtunnel.cfg","rb")
|
||||||
local katimer
|
if not f then return false end
|
||||||
|
for k,v in pairs(serial.unserialize(f:read("*a")) or {}) do
|
||||||
function start(faddr)
|
cfg[k] = v
|
||||||
if listener then return end
|
|
||||||
if faddr then
|
|
||||||
local host,nport = faddr:match("(.+):(%d+)")
|
|
||||||
end
|
end
|
||||||
local iaddr,port = host or faddr or "shadowkat.net", tonumber(nport) or 4096
|
f:close()
|
||||||
socket = internet.connect(iaddr,port)
|
end
|
||||||
print("Connecting to "..iaddr..":"..tostring(port).."...")
|
local function savecfg()
|
||||||
|
local f = io.open("/etc/vtunnel.cfg","wb")
|
||||||
|
if not f then
|
||||||
|
print("Warning: unable to save configuration.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
f:write(serial.serialize(cfg))
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function createTunnel(host,port,addr,raddr)
|
||||||
|
local proxy = {address=addr,buffer=""}
|
||||||
|
function proxy.connect()
|
||||||
|
if proxy.socket then
|
||||||
|
proxy.socket.close()
|
||||||
|
end
|
||||||
|
proxy.socket = component.internet.connect(host,port)
|
||||||
|
local st = computer.uptime()
|
||||||
repeat
|
repeat
|
||||||
os.sleep(0.5)
|
coroutine.yield()
|
||||||
until socket.finishConnect()
|
until proxy.socket.finishConnect() or computer.uptime() > st+5
|
||||||
print("Connected!")
|
|
||||||
|
|
||||||
local proxy = {}
|
|
||||||
local rbuffer = ""
|
|
||||||
local timer = nil
|
|
||||||
|
|
||||||
function listener(t)
|
|
||||||
rbuffer=rbuffer..(socket.read(4096) or "")
|
|
||||||
if imt.decodePacket(rbuffer) then
|
|
||||||
computer.pushSignal("modem_message",addr,raddr,0,0,imt.decodePacket(rbuffer))
|
|
||||||
rbuffer = imt.getRemainder(rbuffer) or ""
|
|
||||||
end
|
end
|
||||||
if t == "internet_ready" and timer then
|
|
||||||
event.cancel(timer)
|
|
||||||
timer = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
timer = event.timer(poll,listener,math.huge) -- this is only here because OCEmu doesn't do internet_ready
|
|
||||||
event.listen("internet_ready",listener)
|
|
||||||
|
|
||||||
-- also dumb keepalive stuff, fix this later
|
|
||||||
katimer = event.timer(keepalive,function()
|
|
||||||
socket.write("\0\1\0")
|
|
||||||
end,math.huge)
|
|
||||||
|
|
||||||
function proxy.send(...)
|
function proxy.send(...)
|
||||||
socket.write(imt.encodePacket(...))
|
rt = 0
|
||||||
|
while not proxy.socket.write(imt.encodePacket(...)) and rt < 10 do
|
||||||
|
proxy.connect()
|
||||||
|
rt = rt + 1
|
||||||
|
end
|
||||||
|
proxy.last = computer.uptime()
|
||||||
|
end
|
||||||
|
function proxy.read()
|
||||||
|
local rb, r
|
||||||
|
local rt = 0
|
||||||
|
while true do
|
||||||
|
rb,r = proxy.socket.read(4096)
|
||||||
|
if rb or rt > 10 then break end
|
||||||
|
if type(rb) == "nil" then
|
||||||
|
proxy.connect()
|
||||||
|
end
|
||||||
|
rt = rt + 1
|
||||||
|
end
|
||||||
|
proxy.buffer = proxy.buffer .. rb
|
||||||
|
while imt.decodePacket(proxy.buffer) do
|
||||||
|
computer.pushSignal("modem_message",addr,raddr,0,0,imt.decodePacket(proxy.buffer))
|
||||||
|
proxy.buffer = imt.getRemainder(proxy.buffer) or ""
|
||||||
|
end
|
||||||
|
if computer.uptime() > proxy.last + cfg.katimer then
|
||||||
|
proxy.socket.write("\0\1\0")
|
||||||
|
proxy.last = computer.uptime()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
event.listen("internet_ready",proxy.read)
|
||||||
|
listeners[addr] = {"internet_ready",proxy.read}
|
||||||
|
timers[addr] = event.timer(cfg.rtimer, proxy.read, math.huge)
|
||||||
|
proxy.connect()
|
||||||
|
proxy.last = computer.uptime()
|
||||||
|
return proxy
|
||||||
end
|
end
|
||||||
|
|
||||||
function proxy.maxPacketSize()
|
function start()
|
||||||
return 12288
|
loadcfg()
|
||||||
|
for k,v in pairs(cfg.peers) do
|
||||||
|
print(string.format("Connecting to %s:%d",v.host,v.port))
|
||||||
|
v.addr = v.addr or vcomponent.uuid()
|
||||||
|
v.raddr = v.raddr or vcomponent.uuid()
|
||||||
|
local px = createTunnel(v.host, v.port, v.addr, v.raddr)
|
||||||
|
vcomponent.register(v.addr, "tunnel", px)
|
||||||
|
proxies[v.addr] = px
|
||||||
end
|
end
|
||||||
|
|
||||||
proxy.type = "tunnel"
|
|
||||||
proxy.slot = 4096
|
|
||||||
|
|
||||||
local docs = {
|
|
||||||
send = "function(data...) -- Sends the specified data to the card this one is linked to.",
|
|
||||||
maxPacketSize = "function():number -- Gets the maximum packet size (config setting)."
|
|
||||||
}
|
|
||||||
vcomp.register(addr,"tunnel",proxy,docs)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function stop()
|
function stop()
|
||||||
if listener then
|
for k,v in pairs(listeners) do
|
||||||
event.ignore("internet_ready",listener)
|
event.ignore(v[1],v[2])
|
||||||
listener = nil
|
|
||||||
end
|
end
|
||||||
if timer then
|
for k,v in pairs(timers) do
|
||||||
event.cancel(timer)
|
event.cancel(v)
|
||||||
timer = nil
|
|
||||||
end
|
end
|
||||||
if katimer then
|
for k,v in pairs(proxies) do
|
||||||
event.cancel(katimer)
|
vcomponent.unregister(k)
|
||||||
katimer = nil
|
|
||||||
end
|
end
|
||||||
if component.type(addr) then
|
|
||||||
vcomp.unregister(addr)
|
|
||||||
end
|
end
|
||||||
socket.close()
|
|
||||||
|
function settimer(time)
|
||||||
|
time = tonumber(time)
|
||||||
|
if not time then
|
||||||
|
print("Timer must be a number.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
cfg.rtime = time
|
||||||
|
savecfg()
|
||||||
|
end
|
||||||
|
|
||||||
|
function addpeer(host,port)
|
||||||
|
port = tonumber(port) or 4096
|
||||||
|
local t = {}
|
||||||
|
t.host = host
|
||||||
|
t.port = port
|
||||||
|
t.addr = vcomponent.uuid()
|
||||||
|
t.raddr = vcomponent.uuid()
|
||||||
|
cfg.peers[#cfg.peers+1] = t
|
||||||
|
print(string.format("Added peer #%d (%s:%d) to the configuration.\nRestart to apply changes.",#cfg.peers,host,port))
|
||||||
|
savecfg()
|
||||||
|
end
|
||||||
|
|
||||||
|
function listpeers()
|
||||||
|
for k,v in pairs(cfg.peers) do
|
||||||
|
print(string.format("#%d (%s:%d)\n Local address: %s\n Remote address: %s",k,v.host,v.port,v.addr,v.raddr))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
function delpeer(n)
|
||||||
|
n=tonumber(n)
|
||||||
|
if not n then
|
||||||
|
print("delpeer requires a number, representing the peer number, as an argument.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local dp = table.remove(cfg.peers, n)
|
||||||
|
savecfg()
|
||||||
|
print(string.format("Removed peer %s:%d",dp.host, dp.port))
|
||||||
end
|
end
|
||||||
|
75
vTunnel/OpenOS/usr/man/vtunnel
Normal file
75
vTunnel/OpenOS/usr/man/vtunnel
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# vTunnel - TCP-based Linked Card Emulator
|
||||||
|
|
||||||
|
vTunnel can be used to add bridging over the internet to any existing OpenOS software that uses linked cards.
|
||||||
|
|
||||||
|
Despite originally being written for Minitel, vTunnel implements a fully-functional linked card emulator and a server that will run under most unix-likes (OpenBSD is currently somewhat flaky, Linux is recommended).
|
||||||
|
|
||||||
|
The protocol is documented [here](vtunnel-protocol.md)
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
### Server Requirements
|
||||||
|
|
||||||
|
- Some form of unix-like
|
||||||
|
- Lua 5.2 or 5.3
|
||||||
|
- Luasocket
|
||||||
|
|
||||||
|
### Client Installation
|
||||||
|
|
||||||
|
#### OPPM
|
||||||
|
|
||||||
|
```
|
||||||
|
oppm install vtunnel
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Manual
|
||||||
|
|
||||||
|
1. Install vtunnel.lua to /etc/rc.d
|
||||||
|
2. Install interminitel.lua to /usr/lib
|
||||||
|
|
||||||
|
### Client setup
|
||||||
|
|
||||||
|
#### Creating a connection
|
||||||
|
Many connections can be configured. To add one:
|
||||||
|
|
||||||
|
```
|
||||||
|
rc vtunnel addpeer <server address> <server port>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Running the server
|
||||||
|
|
||||||
|
At present, all you need to do is run bridge.lua, for example:
|
||||||
|
|
||||||
|
```
|
||||||
|
lua53 bridge.lua [port] [timeout]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Client
|
||||||
|
|
||||||
|
vTunnel is invoked as follows:
|
||||||
|
|
||||||
|
```
|
||||||
|
rc vtunnel start
|
||||||
|
```
|
||||||
|
|
||||||
|
vTunnel can also be configured to start automatically:
|
||||||
|
|
||||||
|
```
|
||||||
|
rc vtunnel enable
|
||||||
|
```
|
||||||
|
|
||||||
|
There are several other commands available under `rc vtunnel`:
|
||||||
|
|
||||||
|
- settimer - allows you to configure how often vTunnel polls the TCP socket
|
||||||
|
- listpeers - shows which peers are configured, and the associated tunnel card addresses
|
||||||
|
- delpeer - deletes a peer from the configuration, as shown in listpeers
|
||||||
|
|
||||||
|
### Minitel configuration
|
||||||
|
|
||||||
|
1. Disable minitel with rc - `rc minitel disable`
|
||||||
|
2. Enable vtunnel with rc - `rc vtunnel enable`
|
||||||
|
3. Enable minitel with rc - `rc minitel enable`
|
||||||
|
|
||||||
|
This will ensure that Minitel starts later than vTunnel, allowing it to see the virtual tunnel component.
|
@ -1,72 +0,0 @@
|
|||||||
# vTunnel - TCP-based Linked Card Emulator
|
|
||||||
|
|
||||||
vTunnel can be used to add bridging over the internet to any existing OpenOS software that uses linked cards.
|
|
||||||
|
|
||||||
Despite originally being written for Minitel, vTunnel implements a fully-functional linked card emulator and a server that will run under most unix-likes (OpenBSD is currently somewhat flaky, Linux is recommended).
|
|
||||||
|
|
||||||
The protocol is documented [here](vtunnel-protocol.md)
|
|
||||||
|
|
||||||
## Setup
|
|
||||||
|
|
||||||
### Server
|
|
||||||
|
|
||||||
#### Requirements
|
|
||||||
|
|
||||||
- Some form of unix-like
|
|
||||||
- Lua 5.2 or 5.3
|
|
||||||
- Luasocket
|
|
||||||
|
|
||||||
#### Running the server
|
|
||||||
|
|
||||||
At present, all you need to do is run bridge.lua, for example:
|
|
||||||
|
|
||||||
```
|
|
||||||
lua53 bridge.lua [port] [timeout]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Client
|
|
||||||
|
|
||||||
#### OPPM
|
|
||||||
|
|
||||||
```
|
|
||||||
oppm install vtunnel
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Manual
|
|
||||||
|
|
||||||
1. Install vtunnel.lua to /etc/rc.d
|
|
||||||
2. Install interminitel.lua to /usr/lib
|
|
||||||
|
|
||||||
#### Running
|
|
||||||
|
|
||||||
vTunnel is invoked as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
rc vtunnel start <server address>:<server port>
|
|
||||||
```
|
|
||||||
|
|
||||||
This will create a virtual linked card component connected to server\_address:server\_port.
|
|
||||||
|
|
||||||
#### Configuration
|
|
||||||
|
|
||||||
vTunnel can also be configured to start automatically. First, one would enable the rc service:
|
|
||||||
|
|
||||||
```
|
|
||||||
rc vtunnel enable
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, edit /etc/rc.cfg and add a line as follows:
|
|
||||||
|
|
||||||
```
|
|
||||||
vtunnel = "server.address:port"
|
|
||||||
```
|
|
||||||
|
|
||||||
Leaving it as default will result in vTunnel connecting to the public SKS bridge.
|
|
||||||
|
|
||||||
#### Minitel configuration
|
|
||||||
|
|
||||||
1. Disable minitel with rc - `rc minitel disable`
|
|
||||||
2. Enable vtunnel with rc - `rc vtunnel enable`
|
|
||||||
3. Enable minitel with rc - `rc minitel enable`
|
|
||||||
|
|
||||||
This will ensure that Minitel starts later than vTunnel, allowing it to see the virtual tunnel component.
|
|
1
vTunnel/README.md
Symbolic link
1
vTunnel/README.md
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
OpenOS/usr/man/vtunnel
|
70
vTunnel/Wireshark/imtdissector.lua
Normal file
70
vTunnel/Wireshark/imtdissector.lua
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
local imtp = Proto("imt","InterMinitel")
|
||||||
|
local imt = require "interminitel"
|
||||||
|
|
||||||
|
local pid = ProtoField.string("imt.packet_id","Packet ID")
|
||||||
|
local ptype = ProtoField.int32("imt.packet_type","Packet type")
|
||||||
|
local dest = ProtoField.string("imt.destination","Destination address")
|
||||||
|
local src = ProtoField.string("imt.source","Source address")
|
||||||
|
local port = ProtoField.int32("imt.port","Port")
|
||||||
|
local data = ProtoField.string("imt.data","Data")
|
||||||
|
local conv = ProtoField.int32("imt.conversation","Conversation")
|
||||||
|
local cport = ProtoField.int32("imt.conversation_port","Conversation Port")
|
||||||
|
|
||||||
|
local seg = ProtoField.string("imt.segment","Segment")
|
||||||
|
|
||||||
|
imtp.fields = {pid, ptype, dest, src, port, data, conv, cport}
|
||||||
|
|
||||||
|
local conversations = {}
|
||||||
|
local function checkConversation(p,c)
|
||||||
|
if p[5] == c.port and c.addresses[p[4]] and c.addresses[p[3]] then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local conversationPackets = {}
|
||||||
|
|
||||||
|
function imtp.dissector(buffer,pinfo,tree)
|
||||||
|
pinfo.cols.protocol=imtp.name
|
||||||
|
local d = buffer():string()
|
||||||
|
local dp, sp = imt.decodePacket(d)
|
||||||
|
local subtree = tree:add(imtp,"InterMinitel Data")
|
||||||
|
for k,v in pairs(dp) do
|
||||||
|
subtree:add(imtp.fields[k], buffer(sp[k], tostring(v):len()), v)
|
||||||
|
end
|
||||||
|
pinfo.cols.src = dp[4]
|
||||||
|
pinfo.cols.dst = dp[3]
|
||||||
|
pinfo.cols.src_port = dp[5]
|
||||||
|
pinfo.cols.dst_port = dp[5]
|
||||||
|
if dp[2] == "0" then
|
||||||
|
pinfo.cols.info = "Unreliable packet."
|
||||||
|
elseif dp[2] == "1" then
|
||||||
|
pinfo.cols.info = "Reliable packet."
|
||||||
|
elseif dp[2] == "2" then
|
||||||
|
pinfo.cols.info = "Acknowledgement packet for '"..dp[6].."'"
|
||||||
|
end
|
||||||
|
if dp[6] == "openstream" then
|
||||||
|
local t = {addresses = {}, iport = dp[5]}
|
||||||
|
t.addresses[dp[3]] = true
|
||||||
|
t.addresses[dp[4]] = true
|
||||||
|
t.id = conversationPackets[dp[1]] or #conversations+1
|
||||||
|
print("Conversation started by "..dp[4].." talking to "..dp[3].." on port "..tostring(dp[5]))
|
||||||
|
conversations[t.id] = t
|
||||||
|
subtree:add(conv, t.id):set_generated()
|
||||||
|
subtree:add(cport, t.iport):set_generated()
|
||||||
|
conversationPackets[dp[1]] = t.id
|
||||||
|
end
|
||||||
|
for k,v in pairs(conversations) do
|
||||||
|
if not v.port and v.iport == dp[5] and tonumber(dp[6]) and v.addresses[dp[3]] and v.addresses[dp[4]] then
|
||||||
|
v.port = tostring(tonumber(dp[6]))
|
||||||
|
print(string.format("Conversation %d port set to %d",k,v.port))
|
||||||
|
subtree:add(conv, v.id):set_generated()
|
||||||
|
subtree:add(cport, v.iport):set_generated()
|
||||||
|
conversationPackets[dp[1]] = v.id
|
||||||
|
elseif checkConversation(dp,v) then
|
||||||
|
print(dp[1].." is part of "..tostring(k))
|
||||||
|
subtree:add(conv, v.id):set_generated()
|
||||||
|
subtree:add(cport, v.iport):set_generated()
|
||||||
|
conversationPackets[dp[1]] = v.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
66
vTunnel/Wireshark/interminitel.lua
Normal file
66
vTunnel/Wireshark/interminitel.lua
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
local imt = {}
|
||||||
|
|
||||||
|
imt.ttypes = {}
|
||||||
|
imt.ttypes.string=1
|
||||||
|
imt.ttypes.number=2
|
||||||
|
|
||||||
|
imt.ftypes = {tostring,tonumber}
|
||||||
|
|
||||||
|
function imt.to16bn(n)
|
||||||
|
return string.char(math.floor(n/256))..string.char(math.floor(n%256))
|
||||||
|
end
|
||||||
|
function imt.from16bn(s)
|
||||||
|
return (string.byte(s,1,1)*256)+string.byte(s,2,2)
|
||||||
|
end
|
||||||
|
|
||||||
|
function imt.encodePacket(...)
|
||||||
|
local tArgs = {...}
|
||||||
|
local packet = string.char(#tArgs%256)
|
||||||
|
for _,segment in ipairs(tArgs) do
|
||||||
|
local segtype = type(segment)
|
||||||
|
segment = tostring(segment)
|
||||||
|
packet = packet .. imt.to16bn(segment:len()) .. string.char(imt.ttypes[segtype]) .. tostring(segment)
|
||||||
|
end
|
||||||
|
packet = imt.to16bn(packet:len()) .. packet
|
||||||
|
return packet
|
||||||
|
end
|
||||||
|
|
||||||
|
function imt.decodePacket(s)
|
||||||
|
local count=0
|
||||||
|
local function getfirst(n)
|
||||||
|
local ns = s:sub(1,n)
|
||||||
|
s=s:sub(n+1)
|
||||||
|
count=count+n
|
||||||
|
return ns
|
||||||
|
end
|
||||||
|
if s:len() < 2 then return false end
|
||||||
|
local plen = imt.from16bn(getfirst(2))
|
||||||
|
local segments, starts = {}, {}
|
||||||
|
if s:len() < plen then return false end
|
||||||
|
local nsegments = string.byte(getfirst(1))
|
||||||
|
-- print(tostring(plen).." bytes, "..tostring(nsegments).." segments")
|
||||||
|
for i = 1, nsegments do
|
||||||
|
starts[#starts+1] = count+3
|
||||||
|
local seglen = imt.from16bn(getfirst(2))
|
||||||
|
local segtype = imt.ftypes[string.byte(getfirst(1))]
|
||||||
|
local segment = getfirst(seglen)
|
||||||
|
-- print(seglen,segtype,segment,type(segment))
|
||||||
|
segments[#segments+1] = segment
|
||||||
|
end
|
||||||
|
return segments, starts
|
||||||
|
end
|
||||||
|
function imt.getRemainder(s)
|
||||||
|
local function getfirst(n)
|
||||||
|
local ns = s:sub(1,n)
|
||||||
|
s=s:sub(n+1)
|
||||||
|
return ns
|
||||||
|
end
|
||||||
|
local plen = imt.from16bn(getfirst(2))
|
||||||
|
if s:len() > plen then
|
||||||
|
getfirst(plen)
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return imt
|
@ -1,9 +1,10 @@
|
|||||||
local socket = require "socket"
|
local socket = require "socket"
|
||||||
local imt = require "interminitel"
|
local imt = require "interminitel"
|
||||||
|
local pcap = require "pcap"
|
||||||
|
|
||||||
local tArgs = {...}
|
local tArgs = {...}
|
||||||
|
|
||||||
local port, timeout = tonumber(tArgs[1]) or 4096, tonumber(tArgs[2]) or 60
|
local port, timeout, pf = tonumber(tArgs[1]) or 4096, tonumber(tArgs[2]) or 60, tArgs[3]
|
||||||
|
|
||||||
local clients, coroutines, messages = {}, {}, {}
|
local clients, coroutines, messages = {}, {}, {}
|
||||||
|
|
||||||
@ -96,8 +97,18 @@ function pushLoop()
|
|||||||
for id,msg in pairs(messages) do
|
for id,msg in pairs(messages) do
|
||||||
if msg[1]:len() > 3 then
|
if msg[1]:len() > 3 then
|
||||||
for k,client in pairs(clients) do
|
for k,client in pairs(clients) do
|
||||||
|
if k ~= msg[2] then
|
||||||
client.conn:send(msg[1])
|
client.conn:send(msg[1])
|
||||||
reprint("Message #"..tostring(id).." (Client #"..tostring(msg[2]).." -> Client #"..tostring(k).." - "..msg[1])
|
reprint("Message #"..tostring(id).." (Client #"..tostring(msg[2]).." -> Client #"..tostring(k)..") - "..msg[1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if pf then
|
||||||
|
local f=io.open(pf,"ab")
|
||||||
|
if f then
|
||||||
|
f:write(pcap.packet(msg[1]))
|
||||||
|
print(pcap.packet(msg[1]))
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
messages[id] = nil
|
messages[id] = nil
|
||||||
@ -124,6 +135,16 @@ end
|
|||||||
|
|
||||||
spawn(bufferLoop)
|
spawn(bufferLoop)
|
||||||
|
|
||||||
|
if pf then
|
||||||
|
local f=io.open(pf,"wb")
|
||||||
|
if f then
|
||||||
|
f:write(pcap.header())
|
||||||
|
f:close()
|
||||||
|
else
|
||||||
|
pf=nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
while #coroutines > 0 do
|
while #coroutines > 0 do
|
||||||
for k,v in pairs(coroutines) do
|
for k,v in pairs(coroutines) do
|
||||||
coroutine.resume(v)
|
coroutine.resume(v)
|
||||||
|
35
vTunnel/pcap.lua
Normal file
35
vTunnel/pcap.lua
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
local pcap = {}
|
||||||
|
local function uint32(n)
|
||||||
|
s = ""
|
||||||
|
for i = 3, 0, -1 do
|
||||||
|
s=s..string.char((n>>(8*i))%256)
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
local function uint16(n)
|
||||||
|
s = ""
|
||||||
|
for i = 1, 0, -1 do
|
||||||
|
s=s..string.char((n>>(8*i))%256)
|
||||||
|
end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
function pcap.header(type)
|
||||||
|
local s=uint32(0xa1b2c3d4) -- magic number
|
||||||
|
s=s..uint16(2) -- major version
|
||||||
|
s=s..uint16(4) -- minor version
|
||||||
|
s=s..uint32(0) -- timezone
|
||||||
|
s=s..uint32(0) -- accuracy
|
||||||
|
s=s..uint32(2^16) -- snaplen
|
||||||
|
s=s..uint32(type or 147)
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
function pcap.packet(d)
|
||||||
|
local s = uint32(os.time()) -- timestamp
|
||||||
|
s=s..uint32(0) -- usec
|
||||||
|
s=s..uint32(d:len()) -- included length
|
||||||
|
s=s..uint32(d:len()) -- actual length
|
||||||
|
return s..d
|
||||||
|
end
|
||||||
|
|
||||||
|
return pcap
|
Loading…
Reference in New Issue
Block a user