home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / mskermit / msntni.asm < prev    next >
Assembly Source File  |  2020-01-01  |  26KB  |  931 lines

  1.     NAME    msntni
  2. ; File MSNTNI.ASM
  3. ; Telnet interface to MS-DOS Kermit
  4. ;
  5. ;    Copyright (C) 1982, 1997, Trustees of Columbia University in the 
  6. ;    City of New York.  The MS-DOS Kermit software may not be, in whole 
  7. ;    or in part, licensed or sold for profit as a software product itself,
  8. ;    nor may it be included in or distributed with commercial products
  9. ;    or otherwise distributed by commercial concerns to their clients 
  10. ;    or customers without written permission of the Office of Kermit 
  11. ;    Development and Distribution, Columbia University.  This copyright 
  12. ;    notice must not be removed, altered, or obscured.
  13. ;
  14. ; Written by Joe R. Doupnik, Utah State University, 
  15. ;  jrd@cc.usu.edu, jrd@usu.Bitnet.
  16. ;
  17. ; Edit history
  18. ; 12 Jan 1995 version 3.14
  19. ; Last edit
  20. ; 12 Jan 1995
  21. ;
  22. ; Some rules of the road.
  23. ; Starting a session: call ktpcopen. This will ensure the interrupts are
  24. ; hooked and will start a new session. Ktcpopen will return the ident of
  25. ; the new session, or -1 upon failure.
  26. ; Stopping a session: this must be done from outside Telnet. Call ktcpclose
  27. ; with a particular session ident (0.. MAXSESSIONS-1) to close that session
  28. ; or call it with an ident of -1 to close all and shutdown TCP. Ktcpclose
  29. ; will return with the ident of the next (cyclic) active session, or -1 if
  30. ; none remain active. Register AX holds incoming indent, outgoing status.
  31. ; When TCP/IP shuts down it releases all interrupts and disengages from the
  32. ; Packet Driver. This will occur upon closing the last active connection.
  33. ;
  34. ; Swapping active sessions: call ktcpswap with a new session ident to change
  35. ; to that new one. This will return with the new ident if successful, or -1.
  36. ; We have to guess session idents so an outside manager can pick and choose.
  37. ; Use ktcpswap to resume a session because ktcpstart always tries to start a
  38. ; new one.
  39.  
  40.     include    mssdef.h
  41.  
  42. bapicon    equ    0a0h        ; 3Com BAPI, connect to port
  43. bapidisc equ    0a1h        ; 3Com BAPI, disconnect
  44. bapiwrit equ    0a4h        ; 3Com BAPI, write block
  45. bapiread equ    0a5h        ; 3Com BAPI, read block
  46. bapibrk    equ    0a6h        ; 3Com BAPI, send short break
  47. bapistat equ    0a7h        ; 3Com BAPI, read status (# chars to be read)
  48. bapihere equ    0afh        ; 3Com BAPI, presence check
  49. bapieecm equ    0b0h        ; 3Com BAPI, enable/disable ECM char
  50. bapiecm    equ    0b1h        ; 3Com BAPI, trap Enter Command Mode char
  51.  
  52. data    segment public 'kdata'
  53.     extrn    tcptos:word        ; top of stack for TCP code
  54.     extrn    flags:byte, yflags:byte, portval:word, ttyact:byte
  55.     extrn    crt_lins:byte, crt_cols:byte
  56.     extrn    tcp_status:word
  57.     extrn    tcpaddress:byte, tcpsubnet:byte, tcpdomain:byte
  58.     extrn    tcpgateway:byte, tcpprimens:byte, tcpsecondns:byte
  59.     extrn    tcphost:byte, tcpbcast:byte, tcpbtpserver:byte
  60.     extrn    tcpport:word, tcppdint:word, tcpttbuf:byte, tcpnewline:byte
  61.     extrn    tcpdebug:byte, tcpmode:byte, tcpmss:word, tcpbtpkind:byte
  62.     extrn    tloghnd:word, tcp_rto:word
  63. ifndef    no_terminal
  64.     extrn    ftogmod:dword
  65. endif    ; no_terminal
  66. data    ends
  67.  
  68. _TEXT    SEGMENT  WORD PUBLIC 'CODE'
  69. _TEXT    ENDS
  70. _DATA    SEGMENT  WORD PUBLIC 'DATA'
  71. _DATA    ENDS
  72. CONST    SEGMENT  WORD PUBLIC 'CONST'
  73. CONST    ENDS
  74. _BSS    SEGMENT  WORD PUBLIC 'BSS'
  75. _BSS    ENDS
  76. DGROUP    GROUP    CONST, _BSS, _DATA
  77.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP
  78.  
  79. _DATA      SEGMENT
  80.     public    _kmyip, _knetmask, _kdomain, _kgateway, _kns1, _kns2, _khost
  81.     public    _kbcast, _bapiadr, _bapireq, _bapiret
  82.     public    _display_mode, _kport, _kpdint, _kserver, _kdebug, _kterm
  83.     public    _ktttype, _kterm_lines, _kterm_cols, _kbtpserver, _tcp_status
  84.     public    _tcpflag, _ktnmode, _ktcpmss, int8cnt
  85.     extrn    _msgcnt:word, _msgbuf:byte, _echo:byte, _bootmethod:byte
  86.  
  87.         db 10 dup (0)        ; guard
  88.         db 'DUMMY',0           ; null pointer guard
  89. _kmyip        db 17 dup (0)        ; our IP number
  90. _knetmask    db 17 dup (0)        ; our netmask
  91. _kdomain    db 33 dup (0)        ; our domain
  92. _kgateway     db 33 dup (0)        ; our gateway
  93. _kns1        db 17 dup (0)        ; our nameserver #1
  94. _kns2        db 17 dup (0)        ; our nameserver #2
  95. _khost        db 61 dup (0)        ; remote host name/IP #
  96. _kbcast        db 17 dup (0)        ; broadcast IP
  97. _ktttype    db 33 dup (0)        ; terminal-type override string
  98. _kbtpserver    db 17 dup (0)        ; Bootp server which responded
  99. _kserver    dw    0        ; non-zero for Kermit server
  100. _kport        dw    23        ; TCP port (Telnet = 23)
  101. _kpdint        dw    0        ; Packet Driver Int, 0 = search
  102. _kdebug        db    0        ; if SET DEBUG ON is effective
  103. _ktnmode    db    0        ; Telnet mode (0=NVT-ASCII,1=BINARY)
  104. _kterm        dw    0        ; terminal type index, see mssdef.h
  105. _kterm_lines    db    0        ; terminal screen height (24)
  106. _kterm_cols    db    0        ; terminal screen width (80)
  107. _ktcpmss    dw    0        ; MSS override
  108. oldint8    dd    0            ; original Int 8 owner
  109. tcpstack dd    0            ; TCP code stack
  110. stack8    dd    0            ; stack at Int 8 invokation
  111. kstack    dw    0            ; Kermit mainline stack pointer
  112. tempax    dw    0            ; a temp
  113. _tcpflag db    0        ; who is running TCP code: 1=Kermit, 2=Int 8
  114. int8cnt    db    0            ; Int 8 times called counter
  115. hooked    db    0            ; Int 8 hooked status (0 = unhooked)
  116. _display_mode db 0            ; msg, none if == 0
  117. _bapireq dw    0            ; BAPI count of chars requested
  118. _bapiret dw    0            ; BAPI count of chars processed
  119. _bapiadr dd    0
  120. _tcp_status dw    0            ; tcp/ip status from msntnd.c
  121. _DATA      ENDS
  122.  
  123. _TEXT    segment
  124.     ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, es:nothing
  125.     extrn    _serial_handler:near, _tnmain:near, _tnexit:near 
  126.     extrn    _pkt_release:near, _tcp_tick:near
  127.     extrn    _strlen:near, _strcpy:near, _session_close:near
  128.     extrn    _session_change:near
  129.  
  130.     public    cpatch
  131. cpatch    equ    this byte
  132.     db    (100-($-cpatch)) dup (0)    ; _TEXT segment patch buffer
  133.  
  134. public    _enable
  135. enable    proc    near
  136. _enable    equ    this byte
  137.     sti
  138.     ret
  139. enable    endp
  140.  
  141. public    _disable
  142. disable    proc    near
  143. _disable equ    this byte
  144.     cli
  145.     ret
  146. disable    endp
  147.  
  148. ; Hook Interrupt 8h. Return AX = 1 if successful else 0.
  149. ; For use only by Telnet code as an internal procedure.
  150.     public    _hookvect
  151. hookvect proc    near
  152. _hookvect equ    this byte
  153.     cmp    hooked,0        ; hooked already?
  154.     je    hook0            ; e = no
  155.     mov    ax,1            ; say success
  156.     ret
  157. hook0:    push    bp
  158.     mov    bp,sp
  159.     mov    ax,bp
  160.     add    ax,2+2            ; C sp just before this call
  161.     cmp    word ptr tcpstack+2,0    ; have setup stack?
  162.     jne    hook1            ; ne = yes
  163.     mov    word ptr tcpstack,ax    ; save as main prog stack level
  164. hook1:    push    es
  165.     mov    ah,getintv        ; get interrupt vector
  166.     mov    al,8            ; vector number
  167.     int    dos
  168.     mov    ax,es
  169.     mov    cx,cs
  170.     cmp    ax,cx            ; points to us now?
  171.     je    hook2            ; e = yes, do not touch
  172.     mov    word ptr DGROUP:oldint8+2,ax    ; save segment
  173.     mov    word ptr DGROUP:oldint8,bx    ; save offset
  174.     mov    dx,offset ourtimer     ; new handler
  175.     push    ds
  176.     mov    ax,cs            ; segment
  177.     mov    ds,ax
  178.     mov    al,8            ; for Int 8
  179.     mov    ah,setintv        ; set interrupt address from ds:dx
  180.     int    dos
  181.     pop    ds
  182.     mov    hooked,1        ; say have hooked vector
  183. hook2:    mov    _tcpflag,1     ; say Kermit but not Int 8 is running TCP
  184.     mov    ax,1            ; return 1 for success
  185.     pop    es
  186.     pop    bp
  187.     ret
  188. hook3:    call    unhookvect        ; put any back
  189.     xor    ax,ax            ; return 0 for failure
  190.     pop    es
  191.     pop    bp
  192.     ret
  193. hookvect endp
  194.  
  195. ; For use only by Telnet code as an internal procedure.
  196.     public    _unhookvect
  197. unhookvect proc    near
  198. _unhookvect equ    this byte
  199.     cmp    hooked,0        ; hooked the vector?
  200.     jne    unhook1            ; ne = yes
  201.     mov    ax,1            ; say success
  202.     ret
  203. unhook1:push    bp
  204.     mov    bp,sp
  205.     push    es
  206.     push    bx
  207.     push    cx
  208.     clc
  209.     mov    tempax,0        ; assume failure status
  210.     mov    ah,getintv        ; get interrupt vector
  211.     mov    al,8            ; vector number
  212.     int    dos
  213.     jc    unhook2            ; c = failed
  214.     mov    ax,es            ; es:bx is current owner, us?
  215.     mov    cx,cs
  216.     cmp    ax,cx            ; seg should be right here
  217.     jne    unhook2            ; ne = is not
  218.     cmp    bx,offset ourtimer    ; should be the same too
  219.     jne    unhook2            ; ne = is not, let them have the int
  220.     mov    ax,word ptr DGROUP:oldint8+2    ; segment
  221.     mov    dx,word ptr DGROUP:oldint8    ; offset
  222.     mov    cx,dx
  223.     or    cx,ax            ; was it used by us?
  224.     jz    unhook2            ; z = no, leave alone
  225.     push    ds
  226.     mov    ds,ax
  227.     mov    al,8            ; for Int 8
  228.     mov    ah,setintv        ; set interrupt address from ds:dx
  229.     int    dos
  230.     pop    ds
  231.     and    _tcpflag,not 2        ; Int 8 no longer touches TCP
  232.     mov    word ptr DGROUP:oldint8,0
  233.     mov    word ptr DGROUP:oldint8+2,0
  234.     mov    hooked,0        ; say not hooked
  235.     mov    tempax,1        ; success status
  236.     jmp    short unhook3
  237. unhook2:mov    tempax,0        ; failure
  238. unhook3:mov    ax,tempax        ; return status (1=success, 0=fail)
  239.     pop    cx
  240.     pop    bx
  241.     pop    es
  242.     pop    bp
  243.     ret
  244. unhookvect endp
  245.  
  246. ; Int 8 routine to call the TCP code if Kermit main body does not.
  247. ; For use only by Telnet code as an internal procedure.
  248. ourtimer proc near
  249.     assume    ds:DGROUP, es:nothing
  250.     push    ds
  251.     push    ax
  252.     mov    ax,dgroup        ; set addressibility to our dgroup
  253.     mov    ds,ax
  254.     pushf                ; simulate interrupt invokation
  255.     call    dword ptr DGROUP:oldint8 ; call previous owner of Int 8
  256.     mov    ax,DGROUP        ; set addressibility to our dgroup
  257.     mov    ds,ax
  258.     test    _tcpflag,1+2        ; is TCP code running now?
  259.     jnz    ourtim2            ; nz = yes, so we don't run now
  260.     mov    al,int8cnt        ; get our times-called counter
  261.     inc    al            ; up once again
  262.     and    al,3            ; keep 2 bits, about .25 sec @18.2t/s
  263.     mov    int8cnt,al        ; store
  264.     or    al,al            ; is it zero?
  265.     jnz    ourtim2            ; nz = no, go away for awhile
  266.     or    _tcpflag,2        ; say we are running the TCP code
  267.     push    bp
  268.     push    bx
  269.     push    cx
  270.     push    dx
  271.     push    si
  272.     push    di
  273.     push    es
  274.     mov    ax,DGROUP
  275.     mov    es,ax
  276.     cli
  277.     mov    ax,ss
  278.     mov    word ptr stack8+2,ax    ; save current stack
  279.     mov    word ptr stack8,sp
  280.     mov    ax,word ptr tcpstack+2    ; get TCP stack seg
  281.     mov    ss,ax            ; set to TCP stack
  282.     mov    sp,word ptr tcpstack
  283.     sti                ; restart interrupts
  284.     xor    ax,ax            ; socket pointer, null
  285.     push    ax            ; set call frame for tcp_tick(NULL)
  286.  
  287.     call    _tcp_tick        ; process some incoming packets
  288.     pop    ax            ; clean call frame
  289.     mov    ax,DGROUP
  290.     mov    ds,ax
  291.     mov    ax,word ptr stack8+2    ; get original stack seg
  292.     cli
  293.     mov    ss,ax
  294.     mov    sp,word ptr stack8
  295.     sti
  296.     pop    es
  297.     pop    di
  298.     pop    si
  299.     pop    dx
  300.     pop    cx
  301.     pop    bx
  302.     pop    bp
  303.     and    _tcpflag,not 2        ; finished our running of TCP code
  304. ourtim2:pop    ax
  305.     pop    ds
  306.     iret
  307. ourtimer endp
  308.  
  309. ; This routine is invoked from outside by a Far call. Enter with the caller's
  310. ; registers but our CS. Switch stacks and data segments.
  311. ; This version supports 3Com BAPI calls and does the near/far stuff via
  312. ; a local buffer.
  313. ; AH holds BAPI request code
  314. ; ES:BX is pointer to user's buffer, CX holds request count.
  315.     public    ktcpcom
  316. ktcpcom     proc    FAR            ; i/o service routine
  317.     assume    ds:DGROUP, es:nothing
  318.     push    ds
  319.     push    ax
  320.     mov    ax,DGROUP        ; set addressibility to our dgroup
  321.     mov    ds,ax
  322.     pop    ax
  323.     cmp    hooked,0        ; have we inited (hooked vectors)?
  324.     je    ourser7            ; e = no, report nothing
  325.     test    _tcpflag,2        ; is Int 8 running TCP?
  326.     jz    ourser8            ; z = no, opposite should never happen
  327. ourser7:mov    ah,1            ; say no char written
  328.     xor    cx,cx            ; chars written
  329.     pop    ds
  330.     ret
  331.  
  332. ourser8:or    _tcpflag,1        ; say we are running TCP
  333.     push    es            ; save regs on the user's stack
  334.     push    di
  335.     push    si
  336.     push    dx
  337.     push    bx
  338.     push    bp
  339.     mov    kstack,sp        ; remember caller's stack now
  340.     mov    sp,word ptr tcpstack    ; move to our TCP stack
  341.     mov    word ptr _bapiadr,bx    ; remember caller's es:bx
  342.     mov    word ptr _bapiadr+2,es    ;  (i/o buffer address)
  343.     mov    _bapireq,cx        ; requested char count to TCP code
  344.     mov    _bapiret,0        ; init returned CX char count
  345.     cmp    ah,bapihere        ; presence check?
  346.     jne    ourser2            ; ne = no
  347.     mov    ax,0af01h        ; return this value
  348.     jmp    ourser4            ; done
  349.  
  350. ourser2:cmp    ah,bapiread        ; read?
  351.     jne    ourser3            ; ne = no
  352.     cmp    _msgcnt,0        ; any outstanding msgs from TCP?
  353.     je    ourser3            ; e = no msgs
  354.     call    oursmsg            ; send back the msgs instead
  355.     jmp    short ourser4        ; ax has status of ok
  356. ourser3:
  357.     mov    bx,DGROUP        ; set up es to dgroup too
  358.     mov    es,bx            ; bx is not needed at this time
  359.     ASSUME    DS:DATA
  360.     push    ds
  361.     mov    bx,seg data        ; address main body
  362.     mov    ds,bx
  363.     mov    es:_kserver,0        ; assume not a server
  364.     test    flags.remflg,dserver    ; Server mode?
  365.     jz    ourser3a        ; z = no
  366.     mov    es:_kserver,1        ; say being a server
  367. ourser3a:
  368.     push    ax
  369.     mov    al,tcpdebug        ; debug option
  370.     mov    es:_kdebug,al
  371.     pop    ax
  372.     pop    ds            ; return ds to dgroup
  373.  
  374.     ASSUME    DS:DGROUP, ES:DGROUP
  375.     xchg    ah,al            ; put BAPI function code in al
  376.     xor    ah,ah
  377.     push    ax            ; setup call frame
  378.  
  379.     call    _serial_handler        ; a near call, _serial_handler(ax)
  380.                     ; reg ax has return status
  381.     add    sp,2            ; clean stack
  382.     mov    cx,DGROUP        ; local addressing again
  383.     mov    ds,cx
  384.     mov    cx,_bapiret        ; CX has count of chars returned
  385. ourser4:clc                ; assume success
  386.     xchg    ah,al            ; put return status in ah
  387.     xor    al,al
  388.     cmp    ah,3            ; serious error status?
  389.     jb    ourserx            ; b = no, zero is success
  390.     stc                ; set carry too
  391. ourserx:mov    sp,kstack         ; move to caller's stack
  392.     and    _tcpflag,not 1        ; say we are not running TCP
  393.     pop    bp
  394.     pop    bx
  395.     pop    dx
  396.     pop    si
  397.     pop    di
  398.     pop    es
  399.     pop    ds
  400.     ret                ; AX and CX are changed as returns
  401. ktcpcom endp
  402.  
  403. ; Copy contents of msgbuf (local Telnet msg collector buffer) to main body.
  404. ; For use only by Telnet code as an internal procedure.
  405. ; Return CX as number of bytes delivered to Kermit main body.
  406. oursmsg    proc    near
  407.     assume    ds:DGROUP, es:nothing
  408.     mov    cx,_msgcnt
  409.     jcxz    ourser3            ; z = no msgs
  410.     push    es            ; debug to log file
  411.     mov    bx,seg tloghnd        ; transaction log handle segment
  412.     mov    es,bx
  413.     mov    bx,es:tloghnd        ; transaction log handle
  414.     pop    es
  415.     cmp    bx,-1            ; transaction log open?
  416.     je    oursmsg4        ; e = no, no file writing
  417.     mov    dx,offset DGROUP:_msgbuf ; ds:dx is source buffer
  418.     mov    ah,write2        ; write cx bytes with handle in bx
  419.     int    dos
  420.     sub    _msgcnt,ax        ; deduct quantity written
  421.     xor    cx,cx            ; count of bytes returned to caller
  422.     jmp    short oursmsg3        ; all done
  423. oursmsg4:                ; debug to transaction log file
  424.     cmp    cx,_bapireq        ; longer than request?
  425.     jbe    oursmsg1        ; be = no
  426.     mov    cx,_bapireq        ; do this much now
  427. oursmsg1:
  428.     push    cx
  429.     push    es
  430.     mov    si,DGROUP
  431.     mov    ds,si
  432.     mov    si,offset DGROUP:_msgbuf ; whence it comes
  433.     les    di,_bapiadr        ; where it goes
  434.     cld
  435.     rep    movsb            ; copy Telnet buffer to main body
  436.     pop    es
  437.     pop    cx            ; return count in cx
  438.     mov    _bapiret,cx        ; return count to user
  439.     sub    _msgcnt,cx        ; deduct chars relayed
  440.     cmp    _msgcnt,0        ; examine remainder
  441.     je    oursmsg3        ; le = none
  442.     push    cx
  443.     push    es
  444.     mov    si,DGROUP
  445.     mov    es,si
  446.     mov    si,offset DGROUP:_msgbuf ; whence it comes
  447.     mov    di,si
  448.     add    si,cx            ; number bytes read
  449.     mov    cx,_msgcnt        ; number of bytes remaining
  450.     cld
  451.     rep    movsb
  452.     pop    es
  453.     pop    cx
  454.  
  455. oursmsg3:xor    ax,ax            ; return status of success
  456.     ret                ; cx has delivered byte count
  457. oursmsg    endp
  458.  
  459.  
  460. ; tcpaddress db    'unknown',(32-($-tcpaddress)) dup (0),0
  461. ; tcpsubnet  db    '255.255.255.0',(32-($-tcpsubnet)) dup (0),0
  462. ; tcpdomain  db    'unknown',(32-($-tcpdomain)) dup (0),0
  463. ; tcpgateway db    'unknown',(32-($-tcpgateway)) dup (0),0
  464. ; tcpprimens db    'unknown',(32-($-tcpprimens)) dup (0),0
  465. ; tcpsecondns db 'unknown',(32-($-tcpsecondns)) dup (0),0
  466. ; tcphost db    (60 -($-tcphost)) dup (0),0
  467. ; tcpbcast db    '255.255.255.255',(32-($-tcpbcast)) dup (0),0
  468. ; tcpport dw    23
  469. ; tcppdint dw    0
  470. ; tcpttbuf db    32 dup (0),0        ; term-type-override buffer
  471. ; tcpmss   dw    1500
  472. ; tcpdata dw    offset tcpaddress ; externally visible far pointers
  473. ;     dw    offset tcpsubnet    + 2
  474. ;     dw    offset tcpdomain    + 4
  475. ;     dw    offset tcpgateway    + 6
  476. ;     dw    offset tcpprimens    + 8
  477. ;     dw    offset tcpsecondns    + 10
  478. ;    dw    offset tcphost        + 12
  479. ;    dw    offset tcpbcast        + 14
  480. ;    dw    offset tcpport        + 16
  481. ;    dw    offset tcppdint        + 18
  482. ;    dw    offset tcpttbuf        + 20
  483. ;    dw    offset tcpbtpserver    + 22
  484. ;    dw    offset tcpnewline    + 24
  485. ;    dw    offset tcpdebug        + 26
  486. ;    dw    offset tcpmode        + 28
  487. ;    dw    offset tcpmss        + 30
  488. ;
  489. ; Open a TCP/IP Telnet connection. Returns -1 if failure or if success it
  490. ; returns the small int session ident code. Creates a new session; use
  491. ; ktcpswap to reactivate existing sessions.
  492.     public    ktcpopen
  493. ktcpopen proc    far
  494.     ASSUME    DS:DATA, ES:DGROUP
  495.     push    es            ; save regs on main Kermit stack
  496.     push    ds
  497.     push    di
  498.     push    si
  499.     push    dx
  500.     push    cx
  501.     push    bx
  502.     push    bp
  503.     mov    ax,DGROUP
  504.     mov    es,ax            ; destination is the TCP module
  505.     cld
  506.     mov    si,offset tcpaddress    ; get offset of our IP address
  507.     mov    di,offset DGROUP:_kmyip    ; our storage slot
  508.     mov    cx,16            ; max bytes
  509. start5:    lodsb
  510.     stosb
  511.     or    al,al
  512.     loopne    start5            ; copy IP address string, asciiz
  513.     xor    al,al            ; extra terminator
  514.     stosb
  515.     mov    si,offset tcpsubnet    ; subnet mask
  516.     mov    di,offset DGROUP:_knetmask
  517.     mov    cx,16
  518. start6:    lodsb
  519.     stosb
  520.     or    al,al
  521.     loopne    start6
  522.     xor    al,al
  523.     stosb
  524.     mov    si,offset tcpdomain    ; domain
  525.     mov    di,offset DGROUP:_kdomain
  526.     mov    cx,32
  527. start7:    lodsb
  528.     stosb
  529.     or    al,al
  530.     loopne    start7
  531.     xor    al,al
  532.     stosb
  533.     mov    si,offset tcpgateway        ; gateway
  534.     mov    di,offset DGROUP:_kgateway
  535.     mov    cx,16
  536. start8:    lodsb
  537.     stosb
  538.     or    al,al
  539.     loopne    start8
  540.     xor    al,al
  541.     stosb
  542.     mov    si,offset tcpprimens        ; primary nameserver
  543.     mov    di,offset DGROUP:_kns1
  544.     mov    cx,16
  545. start9:    lodsb
  546.     stosb
  547.     or    al,al
  548.     loopne    start9
  549.     xor    al,al
  550.     stosb
  551.     mov    si,offset tcpsecondns        ; secondary nameserver
  552.     mov    di,offset DGROUP:_kns2
  553.     mov    cx,16
  554. start10:lodsb
  555.     stosb
  556.     or    al,al
  557.     loopne    start10
  558.     xor    al,al
  559.     stosb
  560.     mov    si,offset tcphost        ; remote host IP
  561.     mov    di,offset DGROUP:_khost
  562.     mov    cx,60
  563. start11:lodsb
  564.     stosb
  565.     or    al,al
  566.     loopne    start11
  567.     xor    al,al
  568.     stosb
  569.     mov    si,offset tcpbcast        ; IP broadcast
  570.     mov    di,offset DGROUP:_kbcast
  571.     mov    cx,16
  572. start12:lodsb
  573.     stosb
  574.     or    al,al
  575.     loopne    start12
  576.     xor    al,al
  577.     stosb
  578.     mov    ax,tcpport        ; port
  579.     mov    es:_kport,ax
  580.     mov    ax,tcppdint        ; Packet Driver Interrupt
  581.     mov    es:_kpdint,ax        ; 0 means scan
  582.     mov    si,offset tcpttbuf    ; offset of term-type string
  583.     mov    di,offset DGROUP:_ktttype ; local storage of the string
  584.     mov    cx,32
  585. start13:lodsb
  586.     stosb
  587.     or    al,al
  588.     loopne    start13
  589.     xor    al,al
  590.     stosb
  591.     mov    al,tcpdebug        ; debug-Options
  592.     mov    es:_kdebug,al
  593.     mov    al,tcpmode        ; mode
  594.     mov    es:_ktnmode,al
  595.     mov    ax,tcpmss        ; MSS override
  596.     mov    es:_ktcpmss,ax
  597.  
  598.     mov    si,portval
  599.     mov    al,[si].ecoflg        ; mainline SET echo flag
  600.     mov    es:_echo,al        ; init Options to this value
  601.  
  602.     mov    es:_display_mode,0    ; presume quiet screen
  603.     test    flags.remflg,dquiet    ; quiet display mode?
  604.     jnz    start14            ; nz = yes. Don't write to screen
  605.     inc    es:_display_mode    ; say can write to screen
  606. start14:mov    es:_kserver,0        ; assume not a server
  607.     test    flags.remflg,dserver    ; Server mode?
  608.     jz    start16            ; z = no
  609.     mov    es:_kserver,1        ; say being a server (do Listen)
  610. start16:mov    ax,flags.vtflg        ; get terminal type index
  611.     mov    es:_kterm,ax
  612.  
  613. start20:mov    bx,portval
  614.     mov    al,[bx].ecoflg        ; get mainline SET echo flag
  615.     mov    es:_echo,al        ; init Telnet echo status
  616.     mov    bx,tcptos        ; top of stack for tcp code
  617.  
  618.     assume    ds:DGROUP, ES:NOTHING
  619.     
  620.     mov    ax,dgroup        ; set addressibility to our dgroup
  621.     mov    ds,ax
  622.     mov    es,ax
  623.                     ; cold vs warm start
  624.     mov    word ptr kstack,sp    ; store Kermit's stack ptr
  625.     cmp    word ptr tcpstack+2,0    ; defined setup yet?
  626.     je    start1            ; e = no, get stack segment
  627.     mov    ax,word ptr tcpstack    ; set sp to existing TCP sp
  628.     mov    sp,ax            ; warm restart
  629.     jmp    short start2
  630.  
  631. start1:    mov    word ptr tcpstack+2,ax    ; set TCP stack seg to DGROUP
  632.     mov    word ptr tcpstack,bx    ; cold start
  633.     mov    sp,bx            ; new TCP stack pointer, DGROUP based
  634.  
  635. start2:    mov    bp,sp            ; preset this as insurance
  636.     or    _tcpflag,1        ; say this is running TCP code
  637.  
  638.     call    _tnmain            ; call the C code
  639.     mov    sp,word ptr kstack    ; restore for Kermit's main stack
  640.  
  641.     ASSUME    ES:DATA
  642.     mov    bx,data            ; main Kermit data segment
  643.     mov    es,bx
  644.     mov    bx,_tcp_status        ; status from msntnd.c
  645.     mov    es:tcp_status,bx    ; return tcp_status to main body
  646.     mov    bx,_kpdint        ; report back Packet Driver Int
  647.     mov    es:tcppdint,bx        ; store value in main data seg
  648.     ASSUME    ES:NOTHING
  649.     and    _tcpflag,not 1        ; finished running tcp code
  650.     pop    bp            ; restore regs, Kermit's main stack
  651.     pop    bx
  652.     pop    cx
  653.     pop    dx
  654.     pop    si
  655.     pop    di
  656.     pop    ds
  657.     pop    es
  658.     ret                ; return to caller, status in AX
  659. ktcpopen endp
  660.  
  661. ; Close session whose session ident is in register AL. If AL holds -1
  662. ; then shut down all sessions and shutdown Telnet. Returns ident of next
  663. ; active session (cyclic from the current session ident) or -1 if none
  664. ; remains active.
  665.     public    ktcpclose
  666. ktcpclose proc    far
  667.     assume    ds:dgroup, es:nothing
  668.     push    es            ; save regs on the user's stack
  669.     push    ds
  670.     push    di
  671.     push    si
  672.     push    dx
  673.     push    cx
  674.     push    bx
  675.     push    bp
  676.     mov    cx,dgroup        ; set addressibility to dgroup
  677.     mov    ds,cx
  678.     mov    es,cx
  679.     mov    kstack,sp        ; remember Kermit's main sp
  680.     cmp    word ptr tcpstack+2,0    ; have setup stack?
  681.     jne    ktcpclo4        ; ne = yes
  682.     mov    ax,-1            ; set failure status
  683.     jmp    short ktcpclo6        ; e = no, skip this routine
  684.  
  685. ktcpclo4:or    _tcpflag,1        ; say we are running TCP code
  686.     mov    cx,word ptr tcpstack    ; set sp to TCP sp
  687.     mov    sp,cx
  688.     mov    bp,sp            ; preset this as insurance
  689.     cbw                ; sign extend
  690.     cmp    al,-1            ; close all sessions and TCP/IP?
  691.     je    ktcpclo5        ; e = yes
  692.     push    ax            ; AL = session number
  693.     call    _session_close        ; close this session
  694.     add    sp,2            ; returns status in AL
  695.     jmp    short ktcpclo6        ; common completion code
  696.  
  697. ktcpclo5:                ; forceful shutdown of TCP/IP Telnet
  698.     xor    ax,ax
  699.     push    ax            ; tnexit(0) setup
  700.     call    _tnexit
  701.     add    sp,2            ; returns status in AX
  702. ktcpclo6:cbw                ; sign extend
  703.     mov    sp,kstack
  704.     mov    _tcpflag,0        ; no one is running the TCP code
  705.     pop    bp            ; restore regs, Kermit's main stack
  706.     pop    bx
  707.     pop    cx
  708.     pop    dx
  709.     pop    si
  710.     pop    di
  711.     pop    ds
  712.     pop    es
  713.     ret                ; return to caller
  714. ktcpclose endp
  715.  
  716. ; Change active sessions. Enter with AL holding desired session ident.
  717. ; Returns -1 if failure, else returns active session ident.
  718.     public    ktcpswap
  719. ktcpswap proc    far
  720.     assume    ds:dgroup, es:nothing
  721.     push    es            ; save regs on the user's stack
  722.     push    ds
  723.     push    di
  724.     push    si
  725.     push    dx
  726.     push    cx
  727.     push    bx
  728.     push    bp
  729.     mov    cx,dgroup        ; set addressibility to our dgroup
  730.     mov    ds,cx
  731.     mov    es,cx
  732.     cmp    word ptr tcpstack+2,0    ; have setup stack?
  733.     jne    ktcpswap1        ; ne = yes
  734.     mov    ax,-1            ; set failure status
  735.     jmp    short ktcpswap2        ; fail
  736. ktcpswap1:or    _tcpflag,1        ; say we are running TCP code
  737.     mov    kstack,sp        ; remember Kermit's main sp
  738.     mov    sp,word ptr tcpstack    ; move to our TCP stack
  739.     mov    bp,sp            ; preset this as insurance
  740.  
  741.     cbw                ; sign extend now
  742.     push    AX            ; new session number
  743.     call    _session_change
  744.     add    sp,2            ; pop argument, status is in AX
  745.     mov    _tcpflag,0        ; no one is running the TCP code
  746.     mov    sp,kstack
  747. ktcpswap2:pop    bp            ; restore regs, Kermit's main stack
  748.     pop    bx
  749.     pop    cx
  750.     pop    dx
  751.     pop    si
  752.     pop    di
  753.     pop    ds
  754.     pop    es
  755.     ret                ; return to caller
  756. ktcpswap endp
  757.  
  758. ; Copies TCP/IP info from Telnet space to main Kermit space via table of
  759. ; pointers tcpdata (in segment data, file mssset.asm).
  760. ; For use only by Telnet code as an internal procedure.
  761.     public    _readback
  762. _readback proc    near
  763.     assume    ds:dgroup, es:nothing
  764.     push    bp
  765.     mov    bp,sp
  766.     push    si
  767.     push    di
  768.     push    es
  769.     mov    si,offset dgroup:_kmyip
  770.     push    si
  771.     push    si                ; argument
  772.     call    _strlen                ; get length of string
  773.     add    sp,2                ; ax has string length
  774.     pop    si
  775.  
  776.     ASSUME    ES:DATA
  777.  
  778.     mov    di,DATA
  779.     mov    es,di
  780.     mov    di,offset tcpaddress        ; offset of the string
  781.     mov    cx,ax                ; length
  782.     cld
  783.     rep    movsb
  784.     xor    al,al
  785.     stosb                    ; terminator
  786.     mov    si,offset dgroup:_knetmask
  787.     mov    di,offset tcpsubnet
  788.     mov    cx,17
  789.     rep    movsb
  790.     stosb                    ; terminator
  791.     mov    si,offset dgroup:_kdomain
  792.     mov    di,offset tcpdomain
  793.     mov    cx,32
  794.     rep    movsb
  795.     stosb                    ; terminator
  796.     mov    si,offset dgroup:_kgateway
  797.     mov    di,offset tcpgateway
  798.     mov    cx,17
  799.     rep    movsb
  800.     stosb                    ; terminator
  801.     mov    si,offset dgroup:_kns1
  802.     mov    di,offset tcpprimens
  803.     mov    cx,17
  804.     rep    movsb
  805.     stosb                    ; terminator
  806.     mov    si,offset dgroup:_kns2
  807.     mov    di,offset tcpsecondns
  808.     mov    cx,17
  809.     rep    movsb
  810.     stosb                    ; terminator
  811.     mov    si,offset dgroup:_khost
  812.     mov    di,offset tcphost
  813.     mov    cx,60
  814.     rep    movsb
  815.     stosb                    ; terminator
  816.     mov    di,offset tcpbtpserver
  817.     mov    cx,16
  818.     mov    si,offset dgroup:_kbtpserver
  819.     rep    movsb
  820.     stosb                    ; terminator
  821.     mov    di,offset tcpbtpkind
  822.     mov    al,_bootmethod
  823.     stosb
  824.     pop    es
  825.     pop    di
  826.     pop    si
  827.     pop    bp
  828.     ret
  829. _readback endp
  830.  
  831. ; Track Telnet echo variable (0 do not do local echo) into terminal emulator
  832. ; and Kermit main body. Call this each time Telnet options change echo.
  833. ; For use only by Telnet code as an internal procedure.
  834.     public    _kecho
  835. _kecho    proc    near
  836.     assume    ds:data, es:dgroup
  837.     push    bp
  838.     mov    bp,sp
  839.     push    ds
  840.     push    es
  841.     push    si
  842.     push    ax
  843.     mov    ax,data            ; Kermit main data segment
  844.     mov    ds,ax
  845.     mov    ax,DGROUP
  846.     mov    es,ax
  847.     mov    ax,[bp+4+0]        ; get Telnet _echo variable
  848.     and    yflags,not lclecho    ; assume no local echo in emulator
  849.     or    al,al            ; Telnet local echo is off?
  850.     jz    kecho1            ; z = yes
  851.     mov    al,lclecho        ; lclecho flag for emulator
  852. kecho1:    or    yflags,al        ; set terminal emulator
  853.     mov    si,portval
  854.     mov    [si].ecoflg,al        ; set mainline SET echo flag
  855. ifndef    no_terminal
  856.     cmp    ttyact,0        ; acting as a Terminal?
  857.     je    kecho2            ; e = no
  858.     call    dword ptr ftogmod    ; toggle mode line
  859.     call    dword ptr ftogmod    ; and again
  860. endif    ; no_terminal
  861. kecho2:    pop    ax
  862.     pop    si
  863.     pop    es
  864.     pop    ds
  865.     pop    bp
  866.     ret
  867. _kecho    endp
  868.  
  869. ; Track Telnet dobinary variable into Kermit main body. 
  870. ; Call this each time Telnet options change dobinary.
  871. ; For use only by Telnet code as an internal procedure.
  872.     public    _kmode
  873. _kmode    proc    near
  874.     assume    ds:data, es:nothing
  875.     push    bp
  876.     mov    bp,sp
  877.     push    ds
  878.     push    ax
  879.     push    bx
  880.     mov    ax,data            ; Kermit main data segment
  881.     mov    ds,ax
  882.     mov    al,[bp+4+0]        ; get Telnet _dobinary variable
  883.     mov    tcpmode,al        ; update main body
  884.     pop    bx
  885.     pop    ax
  886.     pop    ds
  887.     pop    bp
  888.     ret
  889. _kmode    endp
  890.  
  891. ; Get current terminal emulation screen lines and columns
  892.     public    _get_kscreen
  893. _get_kscreen    proc    near
  894.     assume    ds:data, es:DGROUP
  895.     push    ds
  896.     push    es
  897.     mov    ax,seg data        ; address main body
  898.     mov    ds,ax
  899.     mov    ax,DGROUP
  900.     mov    es,ax
  901.     mov    al,ds:crt_lins        ; get display height
  902.     mov    es:_kterm_lines,al
  903.     mov    al,ds:crt_cols        ; get display width
  904.     mov    es:_kterm_cols,al
  905.     pop    es
  906.     pop    ds
  907.     ret
  908. _get_kscreen    endp
  909.  
  910. ; Report s->rto to tcp_rto variable for mainline Kermit
  911.     public    _krto
  912. _krto    proc    near
  913.     ASSUME    ES:DATA
  914.     push    bp
  915.     mov    bp,sp
  916.     push    es
  917.     mov    ax,seg DATA
  918.     mov    es,ax
  919.     mov    ax,[bp+4]        ; get s->rto
  920.     mov    es:tcp_rto,ax        ; report to mainline code
  921.     pop    es
  922.     pop    bp
  923.     ret
  924.     ASSUME    ES:NOTHING
  925. _krto    endp
  926.  
  927. _TEXT    ends
  928.         end
  929.  
  930.