The man page for the sever does say
"Because of bugs in the original 4.2 BSD telnet(1), telnetd performs some dubious protocol exchanges"
So, wading thru RFCs and wireshark captures to fake up the telnet options results in this :
-- tn.lua =====================================
-- TELNET OPTIONS
NUL = string.char(0)
ECHO = string.char(1)
SGA = string.char(3)
ESC = string.char(27)
FLOWCONTROL = string.char(33)
SUB = string.char(250)
WILL = string.char(251) --fb
WONT = string.char(252) --fc
DO = string.char(253) --fd
DONT = string.char(254) --fe
IAC = string.char(255) --ff
AYT = string.char(246) -- ARE YOU THERE
SE = string.char(240) -- End of subnegotiation
GA = string.char(249) -- GO AHEAD
BRK = string.char(243) -- BRK
IP = string.char(244) -- INTERUPT PROCESS
DM = string.char(244) -- DATA MARK
optionsSent = nil
buffer = ""
hexprint = function(s)
for z=1,#s do
uart.write(0, string.format("/x%x - %d ",string.byte(s,z),string.byte(s,z)))
end
end
function conff = function(s,...) return s:format(...) end
telnetOptions = IAC .. DO .. SGA ..
IAC .. WILL .. string.char(24)..
IAC .. WILL .. string.char(31) ..
IAC .. WILL .. string.char(32) ..
IAC .. WONT .. FLOWCONTROL ..
IAC .. WILL .. string.char(34) ..
IAC .. WILL .. string.char(39) ..
IAC .. DO .. string.char(05) ..
IAC .. WILL .. string.char(35)
--subptions
telnetSubOptions = IAC .. SUB .. string.char(31) .. NUL .. string.char(80) .. NUL .. string.char(24) .. IAC .. SE ..
IAC .. SUB .. string.char(32) .. NUL .. "115200,115200" .. IAC .. SE ..
IAC .. SUB .. string.char(35) .. NUL .. "ESP8266" .. IAC .. SE ..
IAC .. SUB .. string.char(39) .. NUL .. "ESP8266" .. IAC .. SE ..
IAC .. SUB .. string.char(24) .. NUL .. "ansi" .. IAC .. SE
if IP and LOGIN and PASSWORD then
conn=net.createConnection(net.TCP, false)
conn:on("connection", function(sck, c)
if DEBUG then print ("*** Connection ***") end
optionsSent = 1
conn:send(telnetOptions)
if DEBUG then print "** Telnet options SENT ***" end
end )
conn:on("sent",function(sck,c)
-- print "**** SENT ***"
if optionsSent == 1 then
if DEBUG then print "** Telnet sub options SENT ***" end
conn:send(telnetSubOptions)
optionsSent = optionsSent + 1
end
end )
conn:on("receive", function(sck, c)
if DEBUG then print ("*** Receiving ***") end
if string.find(c, IAC .. DO .. string.char(24)) then
print("DO TERMINAL")
-- conn:send(conff("%c%c%c",IAC,DO,24))
end
if string.find(c, IAC .. DO .. string.char(32)) then
print("DO TSPEED")
-- conn:send(conff("%c%c%c",IAC,DO,32))
end
if string.find(c, IAC .. DO .. string.char(35)) then
print("DO XDISPLOC")
-- conn:send(conff("%c%c%c",IAC,DO,32))
end
if string.find(c, IAC .. DO .. string.char(39)) then
print("DO ENVIRON")
-- conn:send(conff("%c%c%c",IAC,DO,39))
-- conn:send(conff("%c%c%c",IAC,DO,03))
end
if string.find(c, IAC .. DO .. ECHO ) then
conn:send(IAC .. WONT .. ECHO) -- WONT DO ECHO
print "rec do echo, send wont"
end
if string.find(c, IAC .. WILL .. ECHO ) then
conn:send(IAC .. DO .. ECHO) -- WONT DO ECHO
print "rec will echo, sending do"
end
if string.find(c, IAC .. SUB .. FLOWCONTROL .. NUL ) then
print ("REMOTE FLOW CONTROL OFF")
end
if string.find(c, IAC .. SUB .. FLOWCONTROL .. string.char(01) ) then
print ("REMOTE FLOW CONTROL ON")
tmr.delay(100)
end
if string.find(c, "gin:") then conn:send(LOGIN .. "\n") end
if string.find(c, "word:") then conn:send(PASSWORD .. "\n") end
uart.write(0,c)
end )
uart.on("data", 0 ,
function(data)
if buffer == "" then
buffer = data
else
buffer = buffer .. data
end
if string.find(buffer,"+++q") then
uart.on("data") -- unregister callback function
conn:close()
end
if string.find(buffer,"+++c") then
buffer = ""
conn:connect(23,HOSTIP)
end
if #buffer > 20 then buffer = "" end
if string.find(buffer,"\r") then buffer = "" end
if string.find(buffer,ESC ) then
if DEBUG then hexprint ( buffer ) end
if string.find(buffer,ESC .. ESC ) then
conn:send( ESC )
buffer = ""
end
-- CURSOR KEYS
CURSORKEY = ESC .. "%[%u"
if string.find(buffer,CURSORKEY ) then
if DEBUG then hexprint ( buffer ) end
conn:send( string.match(buffer,CURSORKEY ))
buffer = ""
end
else
conn:send( data )
end
end, 0)
print "+++c to connect , +++q to disconnect"
else
print ("define HOSTIP, LOGIN and PASSWORD and try again")
end
--=======================================================
this works for the old server, but doesn't work on a busybox telnetd or a newer telnetd (GNU inetutils) 1.9.2. it needs a proper state machine to do negotiation.And you need to push escape twice to send escape, it is a work in progress.
No comments:
Post a Comment