2475
|
1 ********************************************************************
|
|
2 * telnet - telnet client
|
|
3 *
|
|
4 * $Id$
|
|
5 *
|
|
6 * Notes:
|
|
7 * This utility works in similar fashion to telnet commands on other systems.
|
|
8 * The user can telnet to a location, and once there, press the TELESCAPE key
|
|
9 * to invoke telnet command mode.
|
|
10 *
|
|
11 * Two sets of path options are kept for the standard input. The first is an
|
|
12 * unmodified copy and the second is a modifable copy. The second is set up
|
|
13 * for raw mode and is used when communicating with the host. The first will
|
|
14 * be used when going into telnet command mode or exiting the telnet program.
|
|
15 *
|
|
16 * The signal handler catches the S$HUP signal and shuts down gracefully. It
|
|
17 * also looks for the ABORT/QUIT characters and relays them to the session.
|
|
18 *
|
|
19 * Reference used: http://www.faqs.org/rfcs/rfc854.html
|
|
20 *
|
|
21 * Edt/Rev YYYY/MM/DD Modified by
|
|
22 * Comment
|
|
23 * ------------------------------------------------------------------
|
|
24 * 1 2010/01/02 Aaron Wolfe
|
|
25 * Most basic implementation using new DW utility API
|
|
26 *
|
|
27 * 2 2010/01/06 Boisy G. Pitre
|
|
28 * Reformatted and optimized source. Added SS.Opt support, added telnet
|
|
29 * command mode which can be entered by pressing the TELESCAPE key.
|
|
30 *
|
|
31 * 3 2010/01/07 Boisy G. Pitre
|
|
32 * Reworked buffer processing routine.
|
|
33 *
|
|
34 * 4 2010/01/12 Boisy G. Pitre
|
|
35 * We allow host to do echo if it wants, we also now advertise the
|
|
36 * escape character when a connection is successful.
|
|
37 *
|
|
38 * 5 2010/01/15 Boisy G. Pitre
|
|
39 * Modified to be an rma assembled module and use the netlib library.
|
|
40
|
|
41 * Set to 1 if you want to see telnet CTRL chars from host
|
|
42 DEBUG set 0
|
|
43
|
|
44 nam telnet
|
|
45 ttl program module
|
|
46
|
|
47 tylg set $01 Prgrm+Objct
|
|
48 atrv set $80+rev ReEnt+rev
|
|
49 rev set $00
|
|
50 edition set 5
|
|
51
|
|
52 psect telnet_a,tylg,atrv,edition,200,start
|
|
53
|
|
54 vsect
|
|
55 connected rmb 1
|
|
56 netdatardy rmb 1
|
|
57 keydatardy rmb 1
|
|
58 lastsig rmb 1
|
|
59 port rmb 2
|
|
60 hostname rmb 2
|
|
61 pbuffer rmb 256
|
|
62 pbufferl equ *
|
|
63 pbend rmb 2
|
|
64 cbuffer rmb 256
|
|
65 ccount rmb 1
|
|
66 opts rmb 32
|
|
67 orgopts rmb 32
|
|
68 tcmdbufl equ 32
|
|
69 tcmdbuf rmb tcmdbufl
|
|
70 portdev rmb 10
|
|
71 netpath rmb 1
|
|
72 outpath rmb 1
|
|
73 numbyt rmb 1
|
|
74 state rmb 1
|
|
75 telctrlbuf rmb 3
|
|
76 endsect
|
|
77
|
|
78 TELESCAPE equ 'Y-$40 * CTRL-Y
|
|
79
|
|
80 NetSig equ 32
|
|
81 KeySig equ 33
|
|
82
|
|
83 SE equ 240 * end of subnegotiation parameters
|
|
84 NOP equ 241 * no operation
|
|
85 DataMark equ 242 * the data stream portion of a Synch. This should always be accompanied by a TCP Urgent notification.
|
|
86 Break equ 243 * NVT character BRK.
|
|
87 IntProc equ 244 * the function IP
|
|
88 AbortOut equ 245 * the function AO.
|
|
89 AreUThere equ 246 * the function AYT
|
|
90 EraseChar equ 247 * the function EC.
|
|
91 EraseLine equ 248 * the function EL.
|
|
92 GoAhead equ 249 * the GA signal.
|
|
93 SB equ 250 * indicates that what follows is subnegotiation of the indicated option.
|
|
94 WILL equ 251 * indicates the desire to begin performing, or confirmation that you are now performing, the indicated option.
|
|
95 WONT equ 252 * indicates the refusal to perform, or continue performing, the indicated option.
|
|
96 DO equ 253 * indicates the request that the other party perform, or confirmation that you are expecting the other party to perform, the indicated option.
|
|
97 DONT equ 254 * indicates the demand that the other party stop performing, or confirmation that you are no longer expecting the other party to perform, the indicated option.
|
|
98 IAC equ 255 * data byte 255.
|
|
99
|
|
100 * Telnet Options
|
|
101 TO_ECHO equ $01
|
|
102
|
|
103 escprompt fcc /Escape character is '^/
|
|
104 fcb TELESCAPE+$40
|
|
105 fcc /'./
|
|
106 crlf fcb C$CR,C$LF
|
|
107 escpromptl equ *-escprompt
|
|
108 tprompt fcc /telnet> /
|
|
109 tpromptl equ *-tprompt
|
|
110
|
|
111 trying fcc /Trying.../
|
|
112 fcb C$CR
|
|
113 tryingl equ *-trying
|
|
114
|
|
115 peerclosm fcc /Connection closed by foreign host./
|
|
116 fcb C$CR
|
|
117 peerclosml equ *-peerclosm
|
|
118
|
|
119 using fcc 'Using port '
|
|
120 usingl equ *-using
|
|
121
|
|
122 defportstr fcc '23'
|
|
123 fcb 0
|
|
124
|
|
125 peerclosed
|
|
126 clr connected,u
|
|
127 leax peerclosm,pcr
|
|
128 ldy #peerclosml
|
|
129 os9 I$WritLn
|
|
130 lbra done
|
|
131
|
|
132 * signal intercept routine
|
|
133 sigint
|
|
134 stb lastsig,u * save our signal received
|
|
135 cmpb #KeySig
|
|
136 bne netchk
|
|
137 inc keydatardy,u
|
|
138 rti
|
|
139 netchk cmpb #NetSig
|
|
140 bne hupchk
|
|
141 inc netdatardy,u
|
|
142 rti
|
|
143 hupchk cmpb #S$HUP * disconnect from peer signal received?
|
|
144 beq peerclosed * yep, exit nicely
|
|
145 lda #$03 * usual interrupt character
|
|
146 cmpb #S$Intrpt
|
|
147 beq chksig
|
|
148 lda #$05 * usual quit character
|
|
149 cmpb #S$Abort
|
|
150 bne sigex
|
|
151 chksig tst connected,u
|
|
152 lbeq done
|
|
153 pshs a
|
|
154 leax ,s
|
|
155 ldy #$0001
|
|
156 lda netpath,u
|
|
157 os9 I$Write
|
|
158 puls a
|
|
159 sigex rti
|
|
160
|
|
161 * save initial parameters
|
|
162 start pshs x
|
|
163 clr connected,u
|
|
164 clr netdatardy,u
|
|
165 clr keydatardy,u
|
|
166
|
|
167 * setup signal intercept
|
|
168 leax sigint,pcr
|
|
169 os9 F$Icpt
|
|
170
|
|
171 * get path options (original and modifiable copy)
|
|
172 leax orgopts,u
|
|
173 ldd #SS.Opt
|
|
174 os9 I$GetStt
|
|
175 lbcs errex2
|
|
176
|
|
177 leax opts,u
|
|
178 ldd #SS.Opt
|
|
179 os9 I$GetStt
|
|
180 lbcs errex2
|
|
181
|
|
182 * set up our path to be raw (we will actually set it later)
|
|
183 leax PD.UPC-PD.OPT,x
|
|
184 ldb #PD.INT-PD.UPC
|
|
185 rawloop clr ,x+
|
|
186 decb
|
|
187 bne rawloop
|
|
188
|
|
189 * set address as nul terminated string
|
|
190 addrloop
|
|
191 ldx ,s
|
|
192 addrloop2
|
|
193 lda ,x+
|
|
194 cmpa #C$SPAC
|
|
195 beq nilit
|
|
196 cmpa #C$CR
|
|
197 beq nilit
|
|
198 bra addrloop2
|
|
199
|
|
200 nilit clr -1,x nil terminate previous param
|
|
201 cmpa #C$CR are we at end of command line?
|
|
202 beq defaultport yep, set default port
|
|
203
|
|
204 skipspc lda ,x+
|
|
205 cmpa #C$CR
|
|
206 beq defaultport
|
|
207 cmpa #C$SPAC
|
|
208 beq skipspc
|
|
209 * if here, we have a second parameter... probably port number
|
|
210 leay -1,x
|
|
211 bra parsedone
|
|
212 defaultport leay defportstr,pcr
|
|
213 parsedone puls x
|
|
214
|
|
215 * X holds pointer to nul terminated address
|
|
216 * Y holds port number string (nil terminated)
|
|
217 * do the open and connect
|
|
218 pshs y
|
|
219 std port,u
|
|
220 stx hostname,u
|
|
221
|
|
222 * announce our attempt to try to connect
|
|
223 lda #1
|
|
224 ldy #tryingl
|
|
225 leax trying,pcr
|
|
226 os9 I$WritLn
|
|
227
|
|
228 lbsr TCPOpen
|
|
229 puls y
|
|
230 lbcs errex1
|
|
231 sta netpath,u
|
|
232 ldx hostname,u
|
|
233 lbsr TCPConnectToHost
|
|
234 lbcs errex2
|
|
235 lbsr RawPath
|
|
236
|
|
237 * we're connected...
|
|
238 lda #1
|
|
239 sta connected,u
|
|
240 leax escprompt,pcr
|
|
241 ldy #escpromptl
|
|
242 os9 I$WritLn
|
|
243
|
|
244 * make our stdin opts raw
|
|
245 leax opts,u
|
|
246 ldd #SS.Opt
|
|
247 os9 I$SetStt
|
|
248 lbcs errex2
|
|
249
|
|
250 * setup data ready signal on stdin
|
|
251 clra
|
|
252 ldb #SS.SSig
|
|
253 ldx #KeySig
|
|
254 os9 I$SetStt
|
|
255 lbcs errex2
|
|
256
|
|
257 * setup data ready signal on netpath
|
|
258 lda netpath,u
|
|
259 ldb #SS.SSig
|
|
260 ldx #NetSig
|
|
261 os9 I$SetStt
|
|
262 lbcs errex2
|
|
263
|
|
264 * response loop
|
|
265 * check for typed characters
|
|
266 rloop
|
|
267 pshs cc save interrupt state
|
|
268 orcc #IntMasks mask interrupts
|
|
269 tst netdatardy,u
|
|
270 bne GetNetData
|
|
271 tst keydatardy,u
|
|
272 bne GetKeyData
|
|
273 * sleep until signal
|
|
274 ldx #$0000
|
|
275 os9 F$Sleep
|
|
276 puls cc
|
|
277 bra rloop
|
|
278
|
|
279 GetKeyData puls cc
|
|
280 dec keydatardy,u
|
|
281 bra stdinc
|
|
282
|
|
283 GetNetData puls cc
|
|
284 dec netdatardy,u
|
|
285 lda netpath,u
|
|
286 ldb #SS.Ready
|
|
287 os9 I$GetStt
|
|
288 lbcc serinc read and print the byte
|
|
289 bra rloop
|
|
290
|
|
291 * telnet command interface
|
|
292 cmdint
|
|
293 * restore original opts for now
|
|
294 leax orgopts,u
|
|
295 ldd #SS.Opt
|
|
296 os9 I$SetStt
|
|
297 bcs errex2
|
|
298
|
|
299 * write CR
|
|
300 lda #1
|
|
301 leax crlf,pcr
|
|
302 ldy #$02
|
|
303 os9 I$Write
|
|
304
|
|
305 * show prompt
|
|
306 cmdloop
|
|
307 lda #1
|
|
308 leax tprompt,pcr
|
|
309 ldy #tpromptl
|
|
310 os9 I$Write
|
|
311
|
|
312 * read command
|
|
313 leax tcmdbuf,u
|
|
314 ldy #tcmdbufl
|
|
315 clra
|
|
316 os9 I$ReadLn
|
|
317 bcs errex2
|
|
318
|
|
319 * process command
|
|
320 lda ,x
|
|
321 anda #$5F * make uppercase
|
|
322
|
|
323 cmpa #C$CR
|
|
324 beq ret2tel * just CR... return to telnet session
|
|
325 cmpa #'Q
|
|
326 beq okex
|
|
327 bra cmdloop
|
|
328
|
|
329 * return to telnet session
|
|
330 ret2tel
|
|
331 leax opts,u
|
|
332 ldd #SS.Opt
|
|
333 os9 I$SetStt
|
|
334 bcs errex2
|
|
335
|
|
336 * read one byte from stdin, send to server
|
|
337 stdinc ldy #$0001
|
|
338 clra
|
|
339 leax numbyt,u
|
|
340 os9 I$Read
|
|
341 bcs errex2
|
|
342
|
|
343 * check if it is an escape character
|
|
344 lda ,x
|
|
345 cmpa #TELESCAPE
|
|
346 beq cmdint
|
|
347
|
|
348 outc ldy #$0001
|
|
349 lda netpath,u
|
|
350 leax numbyt,u
|
|
351 os9 I$Write
|
|
352 bcs errex2
|
|
353
|
|
354 * setup data ready signal on stdin
|
|
355 clra
|
|
356 ldb #SS.SSig
|
|
357 ldx #KeySig
|
|
358 os9 I$SetStt
|
|
359 lbcs errex2
|
|
360
|
|
361 lbra rloop
|
|
362
|
|
363 done
|
|
364 okex clrb *no errors here
|
|
365 * close port
|
|
366 errex2
|
|
367 pshs b,cc
|
|
368 lda netpath,u
|
|
369 lbsr TCPDisconnect
|
|
370 clr connected,u
|
|
371
|
|
372 leax orgopts,u
|
|
373 ldd #SS.Opt
|
|
374 os9 I$SetStt *restore original path options
|
|
375 puls b,cc
|
|
376
|
|
377 errex1 os9 F$Exit *goodbye
|
|
378
|
|
379 * read B bytes from serial
|
|
380 serinc clra
|
|
381 tfr d,y
|
|
382 lda netpath,u
|
|
383 leax pbuffer,u
|
|
384 os9 I$Read
|
|
385 bcs errex2
|
|
386
|
|
387 * set buffer
|
|
388 tfr y,d
|
|
389 leax pbuffer,u
|
|
390 abx
|
|
391 stx pbend,u *set end addr
|
|
392 clrb
|
|
393 leax pbuffer,u
|
|
394 leay cbuffer,u
|
|
395 clr ccount,u
|
|
396
|
|
397 * call buffer processor
|
|
398 bsr procbuf
|
|
399
|
|
400 * print buffer
|
|
401 ldb ccount,u
|
|
402 beq serincex
|
|
403 clra
|
|
404 tfr d,y
|
|
405 lda #1
|
|
406 leax cbuffer,u
|
|
407 os9 I$Write
|
|
408 bcs errex2
|
|
409
|
|
410 * return to loop
|
|
411 serincex
|
|
412 * setup data ready signal on netpath
|
|
413 lda netpath,u
|
|
414 ldb #SS.SSig
|
|
415 ldx #NetSig
|
|
416 os9 I$SetStt
|
|
417 lbcs errex2
|
|
418
|
|
419 lbra rloop
|
|
420
|
|
421
|
|
422
|
|
423 * buffer processing routine
|
|
424 procbuf cmpx pbend,u
|
|
425 beq procbufex
|
|
426 * not at end of buffer, get next char
|
|
427 lda ,x+
|
|
428 * check state to see what we do with this byte
|
|
429 tst state,u
|
|
430 bne telctrl
|
|
431 cmpa #IAC
|
|
432 beq telstate
|
|
433 sta ,y+
|
|
434 inc ccount,u
|
|
435 bra procbuf
|
|
436 procbufex rts
|
|
437
|
|
438 conv anda #$0F
|
|
439 cmpa #$09
|
|
440 bgt alpha
|
|
441 adda #$30
|
|
442 fcb $8C
|
|
443 alpha adda #$41-$0A
|
|
444 rts
|
|
445
|
|
446 IFEQ DEBUG-1
|
|
447 printhex pshs d,x,y
|
|
448 bsr conv
|
|
449 pshs a
|
|
450 lda 1,s
|
|
451 lsra
|
|
452 lsra
|
|
453 lsra
|
|
454 lsra
|
|
455 bsr conv
|
|
456 pshs a
|
|
457 lda #'$
|
|
458 pshs a
|
|
459 leax ,s
|
|
460 ldy #$0003
|
|
461 lda #$01
|
|
462 os9 I$Write
|
|
463 leas 3,s
|
|
464 puls d,x,y,pc
|
|
465 ENDC
|
|
466
|
|
467 telstate sta telctrlbuf,u
|
|
468 IFEQ DEBUG-1
|
|
469 bsr printhex
|
|
470 ENDC
|
|
471 inc state,u
|
|
472 bra procbuf
|
|
473
|
|
474 clrngo clr state,u
|
|
475 bra procbuf
|
|
476
|
|
477 * handles telnet control sequence... A = byte
|
|
478 telctrl
|
|
479 IFEQ DEBUG-1
|
|
480 bsr printhex
|
|
481 ENDC
|
|
482 ldb state,u
|
|
483 cmpb #1
|
|
484 bne telctrl2
|
|
485 cmpa #SB
|
|
486 ble clrngo
|
|
487 sta telctrlbuf+1,u
|
|
488 inc state,u
|
|
489 bra procbuf
|
|
490 telctrl2 sta telctrlbuf+2,u
|
|
491 clr state,u
|
|
492 * here we have a complete telnet control sequence
|
|
493 ldd telctrlbuf+1,u
|
|
494 cmpa #DO
|
|
495 beq dowont
|
|
496 cmpa #WILL
|
|
497 lbne procbuf
|
|
498 cmpb #TO_ECHO
|
|
499 bne dodont
|
|
500 * allow host to echo
|
|
501 lda #DO
|
|
502 fcb $8C
|
|
503 dodont lda #DONT
|
|
504 fcb $8C
|
|
505 dowont lda #WONT
|
|
506 sta telctrlbuf+1,u
|
|
507 ldy #3
|
|
508 lda netpath,u
|
|
509 pshs x
|
|
510 leax telctrlbuf,u
|
|
511 os9 I$Write
|
|
512 puls x
|
|
513 lbra procbuf
|
|
514
|
|
515 endsect
|