home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / msk316src.zip / MSNTNI.ASM < prev    next >
Assembly Source File  |  1999-04-24  |  26KB  |  942 lines

  1.     NAME    msntni
  2. ; File MSNTNI.ASM
  3. ; Telnet interface to MS-DOS Kermit
  4. ;
  5. ;    Copyright (C) 1982, 1999, 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.     jnc    ourser4            ; nc = gave data, 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.     cmp    _msgcnt,0
  409.     jne    oursmsg1        ; ne = have msg
  410.     stc                ; say nothing done here
  411.     ret
  412. oursmsg1:
  413.     push    es            ; debug to log file
  414.     mov    bx,seg tloghnd        ; transaction log handle segment
  415.     mov    es,bx
  416.     mov    bx,es:tloghnd        ; transaction log handle
  417.     pop    es
  418.     cmp    bx,-1            ; transaction log open?
  419.     je    oursmsg2        ; e = no, no file writing
  420.     push    ax
  421.     push    cx
  422.     mov    cx,_msgcnt
  423.     mov    dx,offset DGROUP:_msgbuf ; ds:dx is source buffer
  424.     mov    ah,write2        ; write cx bytes with handle in bx
  425.     int    dos
  426.     sub    _msgcnt,ax        ; deduct quantity written
  427.     pop    cx            ; preserve original cx
  428.     pop    ax            ; preserve original request in ax
  429.     stc                ; say no data to be read from here
  430.     ret
  431. oursmsg2:                ; debug to main body
  432.     push    ax
  433.     push    cx
  434.     mov    cx,_msgcnt
  435.     cmp    cx,_bapireq        ; longer than request?
  436.     jbe    oursmsg3        ; be = no
  437.     mov    cx,_bapireq        ; do this much now
  438. oursmsg3:
  439.     push    cx
  440.     push    es
  441.     mov    si,DGROUP
  442.     mov    ds,si
  443.     mov    si,offset DGROUP:_msgbuf ; whence it comes
  444.     les    di,_bapiadr        ; where it goes
  445.     cld
  446.     rep    movsb            ; copy Telnet buffer to main body
  447.     pop    es
  448.     pop    cx            ; return count in cx
  449.     mov    _bapiret,cx        ; return count to user
  450.     sub    _msgcnt,cx        ; deduct chars relayed
  451.     cmp    _msgcnt,0        ; examine remainder
  452.     je    oursmsg4        ; le = none
  453.     push    es
  454.     mov    si,DGROUP
  455.     mov    es,si
  456.     mov    si,offset DGROUP:_msgbuf ; whence it comes
  457.     mov    di,si
  458.     add    si,cx            ; number bytes read
  459.     mov    cx,_msgcnt        ; number of bytes remaining
  460.     cld
  461.     rep    movsb
  462.     pop    es
  463. oursmsg4:pop    cx            ; caller's request count
  464.     pop    ax            ; and function code
  465.     mov    cx,_bapiret        ; original count minus filled here
  466.     xor    ax,ax            ; return status of success
  467.     clc                ; filled caller's buffer
  468.     ret                ; cx has delivered byte count
  469. oursmsg    endp
  470.  
  471.  
  472. ; tcpaddress db    'unknown',(32-($-tcpaddress)) dup (0),0
  473. ; tcpsubnet  db    '255.255.255.0',(32-($-tcpsubnet)) dup (0),0
  474. ; tcpdomain  db    'unknown',(32-($-tcpdomain)) dup (0),0
  475. ; tcpgateway db    'unknown',(32-($-tcpgateway)) dup (0),0
  476. ; tcpprimens db    'unknown',(32-($-tcpprimens)) dup (0),0
  477. ; tcpsecondns db 'unknown',(32-($-tcpsecondns)) dup (0),0
  478. ; tcphost db    (60 -($-tcphost)) dup (0),0
  479. ; tcpbcast db    '255.255.255.255',(32-($-tcpbcast)) dup (0),0
  480. ; tcpport dw    23
  481. ; tcppdint dw    0
  482. ; tcpttbuf db    32 dup (0),0        ; term-type-override buffer
  483. ; tcpmss   dw    1500
  484. ; tcpdata dw    offset tcpaddress ; externally visible far pointers
  485. ;     dw    offset tcpsubnet    + 2
  486. ;     dw    offset tcpdomain    + 4
  487. ;     dw    offset tcpgateway    + 6
  488. ;     dw    offset tcpprimens    + 8
  489. ;     dw    offset tcpsecondns    + 10
  490. ;    dw    offset tcphost        + 12
  491. ;    dw    offset tcpbcast        + 14
  492. ;    dw    offset tcpport        + 16
  493. ;    dw    offset tcppdint        + 18
  494. ;    dw    offset tcpttbuf        + 20
  495. ;    dw    offset tcpbtpserver    + 22
  496. ;    dw    offset tcpnewline    + 24
  497. ;    dw    offset tcpdebug        + 26
  498. ;    dw    offset tcpmode        + 28
  499. ;    dw    offset tcpmss        + 30
  500. ;
  501. ; Open a TCP/IP Telnet connection. Returns -1 if failure or if success it
  502. ; returns the small int session ident code. Creates a new session; use
  503. ; ktcpswap to reactivate existing sessions.
  504.     public    ktcpopen
  505. ktcpopen proc    far
  506.     ASSUME    DS:DATA, ES:DGROUP
  507.     push    es            ; save regs on main Kermit stack
  508.     push    ds
  509.     push    di
  510.     push    si
  511.     push    dx
  512.     push    cx
  513.     push    bx
  514.     push    bp
  515.     mov    ax,DGROUP
  516.     mov    es,ax            ; destination is the TCP module
  517.     cld
  518.     mov    si,offset tcpaddress    ; get offset of our IP address
  519.     mov    di,offset DGROUP:_kmyip    ; our storage slot
  520.     mov    cx,16            ; max bytes
  521. start5:    lodsb
  522.     stosb
  523.     or    al,al
  524.     loopne    start5            ; copy IP address string, asciiz
  525.     xor    al,al            ; extra terminator
  526.     stosb
  527.     mov    si,offset tcpsubnet    ; subnet mask
  528.     mov    di,offset DGROUP:_knetmask
  529.     mov    cx,16
  530. start6:    lodsb
  531.     stosb
  532.     or    al,al
  533.     loopne    start6
  534.     xor    al,al
  535.     stosb
  536.     mov    si,offset tcpdomain    ; domain
  537.     mov    di,offset DGROUP:_kdomain
  538.     mov    cx,32
  539. start7:    lodsb
  540.     stosb
  541.     or    al,al
  542.     loopne    start7
  543.     xor    al,al
  544.     stosb
  545.     mov    si,offset tcpgateway        ; gateway
  546.     mov    di,offset DGROUP:_kgateway
  547.     mov    cx,16
  548. start8:    lodsb
  549.     stosb
  550.     or    al,al
  551.     loopne    start8
  552.     xor    al,al
  553.     stosb
  554.     mov    si,offset tcpprimens        ; primary nameserver
  555.     mov    di,offset DGROUP:_kns1
  556.     mov    cx,16
  557. start9:    lodsb
  558.     stosb
  559.     or    al,al
  560.     loopne    start9
  561.     xor    al,al
  562.     stosb
  563.     mov    si,offset tcpsecondns        ; secondary nameserver
  564.     mov    di,offset DGROUP:_kns2
  565.     mov    cx,16
  566. start10:lodsb
  567.     stosb
  568.     or    al,al
  569.     loopne    start10
  570.     xor    al,al
  571.     stosb
  572.     mov    si,offset tcphost        ; remote host IP
  573.     mov    di,offset DGROUP:_khost
  574.     mov    cx,60
  575. start11:lodsb
  576.     stosb
  577.     or    al,al
  578.     loopne    start11
  579.     xor    al,al
  580.     stosb
  581.     mov    si,offset tcpbcast        ; IP broadcast
  582.     mov    di,offset DGROUP:_kbcast
  583.     mov    cx,16
  584. start12:lodsb
  585.     stosb
  586.     or    al,al
  587.     loopne    start12
  588.     xor    al,al
  589.     stosb
  590.     mov    ax,tcpport        ; port
  591.     mov    es:_kport,ax
  592.     mov    ax,tcppdint        ; Packet Driver Interrupt
  593.     mov    es:_kpdint,ax        ; 0 means scan
  594.     mov    si,offset tcpttbuf    ; offset of term-type string
  595.     mov    di,offset DGROUP:_ktttype ; local storage of the string
  596.     mov    cx,32
  597. start13:lodsb
  598.     stosb
  599.     or    al,al
  600.     loopne    start13
  601.     xor    al,al
  602.     stosb
  603.     mov    al,tcpdebug        ; debug-Options
  604.     mov    es:_kdebug,al
  605.     mov    al,tcpmode        ; mode
  606.     mov    es:_ktnmode,al
  607.     mov    ax,tcpmss        ; MSS override
  608.     mov    es:_ktcpmss,ax
  609.  
  610.     mov    si,portval
  611.     mov    al,[si].ecoflg        ; mainline SET echo flag
  612.     mov    es:_echo,al        ; init Options to this value
  613.  
  614.     mov    es:_display_mode,0    ; presume quiet screen
  615.     test    flags.remflg,dquiet    ; quiet display mode?
  616.     jnz    start14            ; nz = yes. Don't write to screen
  617.     inc    es:_display_mode    ; say can write to screen
  618. start14:mov    es:_kserver,0        ; assume not a server
  619.     test    flags.remflg,dserver    ; Server mode?
  620.     jz    start16            ; z = no
  621.     mov    es:_kserver,1        ; say being a server (do Listen)
  622. start16:mov    ax,flags.vtflg        ; get terminal type index
  623.     mov    es:_kterm,ax
  624.  
  625. start20:mov    bx,portval
  626.     mov    al,[bx].ecoflg        ; get mainline SET echo flag
  627.     mov    es:_echo,al        ; init Telnet echo status
  628.     mov    bx,tcptos        ; top of stack for tcp code
  629.  
  630.     assume    ds:DGROUP, ES:NOTHING
  631.     
  632.     mov    ax,dgroup        ; set addressibility to our dgroup
  633.     mov    ds,ax
  634.     mov    es,ax
  635.                     ; cold vs warm start
  636.     mov    word ptr kstack,sp    ; store Kermit's stack ptr
  637.     cmp    word ptr tcpstack+2,0    ; defined setup yet?
  638.     je    start1            ; e = no, get stack segment
  639.     mov    ax,word ptr tcpstack    ; set sp to existing TCP sp
  640.     mov    sp,ax            ; warm restart
  641.     jmp    short start2
  642.  
  643. start1:    mov    word ptr tcpstack+2,ax    ; set TCP stack seg to DGROUP
  644.     mov    word ptr tcpstack,bx    ; cold start
  645.     mov    sp,bx            ; new TCP stack pointer, DGROUP based
  646.  
  647. start2:    mov    bp,sp            ; preset this as insurance
  648.     or    _tcpflag,1        ; say this is running TCP code
  649.  
  650.     call    _tnmain            ; call the C code
  651.     mov    sp,word ptr kstack    ; restore for Kermit's main stack
  652.  
  653.     ASSUME    ES:DATA
  654.     mov    bx,data            ; main Kermit data segment
  655.     mov    es,bx
  656.     mov    bx,_tcp_status        ; status from msntnd.c
  657.     mov    es:tcp_status,bx    ; return tcp_status to main body
  658.     mov    bx,_kpdint        ; report back Packet Driver Int
  659.     mov    es:tcppdint,bx        ; store value in main data seg
  660.     ASSUME    ES:NOTHING
  661.     and    _tcpflag,not 1        ; finished running tcp code
  662.     pop    bp            ; restore regs, Kermit's main stack
  663.     pop    bx
  664.     pop    cx
  665.     pop    dx
  666.     pop    si
  667.     pop    di
  668.     pop    ds
  669.     pop    es
  670.     ret                ; return to caller, status in AX
  671. ktcpopen endp
  672.  
  673. ; Close session whose session ident is in register AL. If AL holds -1
  674. ; then shut down all sessions and shutdown Telnet. Returns ident of next
  675. ; active session (cyclic from the current session ident) or -1 if none
  676. ; remains active.
  677.     public    ktcpclose
  678. ktcpclose proc    far
  679.     assume    ds:dgroup, es:nothing
  680.     push    es            ; save regs on the user's stack
  681.     push    ds
  682.     push    di
  683.     push    si
  684.     push    dx
  685.     push    cx
  686.     push    bx
  687.     push    bp
  688.     mov    cx,dgroup        ; set addressibility to dgroup
  689.     mov    ds,cx
  690.     mov    es,cx
  691.     mov    kstack,sp        ; remember Kermit's main sp
  692.     cmp    word ptr tcpstack+2,0    ; have setup stack?
  693.     jne    ktcpclo4        ; ne = yes
  694.     mov    ax,-1            ; set failure status
  695.     jmp    short ktcpclo6        ; e = no, skip this routine
  696.  
  697. ktcpclo4:or    _tcpflag,1        ; say we are running TCP code
  698.     mov    cx,word ptr tcpstack    ; set sp to TCP sp
  699.     mov    sp,cx
  700.     mov    bp,sp            ; preset this as insurance
  701.     cbw                ; sign extend
  702.     cmp    al,-1            ; close all sessions and TCP/IP?
  703.     je    ktcpclo5        ; e = yes
  704.     push    ax            ; AL = session number
  705.     call    _session_close        ; close this session
  706.     add    sp,2            ; returns status in AL
  707.     jmp    short ktcpclo6        ; common completion code
  708.  
  709. ktcpclo5:                ; forceful shutdown of TCP/IP Telnet
  710.     xor    ax,ax
  711.     push    ax            ; tnexit(0) setup
  712.     call    _tnexit
  713.     add    sp,2            ; returns status in AX
  714. ktcpclo6:cbw                ; sign extend
  715.     mov    sp,kstack
  716.     mov    _tcpflag,0        ; no one is running the TCP code
  717.     pop    bp            ; restore regs, Kermit's main stack
  718.     pop    bx
  719.     pop    cx
  720.     pop    dx
  721.     pop    si
  722.     pop    di
  723.     pop    ds
  724.     pop    es
  725.     ret                ; return to caller
  726. ktcpclose endp
  727.  
  728. ; Change active sessions. Enter with AL holding desired session ident.
  729. ; Returns -1 if failure, else returns active session ident.
  730.     public    ktcpswap
  731. ktcpswap proc    far
  732.     assume    ds:dgroup, es:nothing
  733.     push    es            ; save regs on the user's stack
  734.     push    ds
  735.     push    di
  736.     push    si
  737.     push    dx
  738.     push    cx
  739.     push    bx
  740.     push    bp
  741.     mov    cx,dgroup        ; set addressibility to our dgroup
  742.     mov    ds,cx
  743.     mov    es,cx
  744.     cmp    word ptr tcpstack+2,0    ; have setup stack?
  745.     jne    ktcpswap1        ; ne = yes
  746.     mov    ax,-1            ; set failure status
  747.     jmp    short ktcpswap2        ; fail
  748. ktcpswap1:or    _tcpflag,1        ; say we are running TCP code
  749.     mov    kstack,sp        ; remember Kermit's main sp
  750.     mov    sp,word ptr tcpstack    ; move to our TCP stack
  751.     mov    bp,sp            ; preset this as insurance
  752.  
  753.     cbw                ; sign extend now
  754.     push    AX            ; new session number
  755.     call    _session_change
  756.     add    sp,2            ; pop argument, status is in AX
  757.     mov    _tcpflag,0        ; no one is running the TCP code
  758.     mov    sp,kstack
  759. ktcpswap2:pop    bp            ; restore regs, Kermit's main stack
  760.     pop    bx
  761.     pop    cx
  762.     pop    dx
  763.     pop    si
  764.     pop    di
  765.     pop    ds
  766.     pop    es
  767.     ret                ; return to caller
  768. ktcpswap endp
  769.  
  770. ; Copies TCP/IP info from Telnet space to main Kermit space via table of
  771. ; pointers tcpdata (in segment data, file mssset.asm).
  772. ; For use only by Telnet code as an internal procedure.
  773.     public    _readback
  774. _readback proc    near
  775.     assume    ds:dgroup, es:nothing
  776.     push    bp
  777.     mov    bp,sp
  778.     push    si
  779.     push    di
  780.     push    es
  781.     mov    si,offset dgroup:_kmyip
  782.     push    si
  783.     push    si                ; argument
  784.     call    _strlen                ; get length of string
  785.     add    sp,2                ; ax has string length
  786.     pop    si
  787.  
  788.     ASSUME    ES:DATA
  789.  
  790.     mov    di,DATA
  791.     mov    es,di
  792.     mov    di,offset tcpaddress        ; offset of the string
  793.     mov    cx,ax                ; length
  794.     cld
  795.     rep    movsb
  796.     xor    al,al
  797.     stosb                    ; terminator
  798.     mov    si,offset dgroup:_knetmask
  799.     mov    di,offset tcpsubnet
  800.     mov    cx,17
  801.     rep    movsb
  802.     stosb                    ; terminator
  803.     mov    si,offset dgroup:_kdomain
  804.     mov    di,offset tcpdomain
  805.     mov    cx,32
  806.     rep    movsb
  807.     stosb                    ; terminator
  808.     mov    si,offset dgroup:_kgateway
  809.     mov    di,offset tcpgateway
  810.     mov    cx,17
  811.     rep    movsb
  812.     stosb                    ; terminator
  813.     mov    si,offset dgroup:_kns1
  814.     mov    di,offset tcpprimens
  815.     mov    cx,17
  816.     rep    movsb
  817.     stosb                    ; terminator
  818.     mov    si,offset dgroup:_kns2
  819.     mov    di,offset tcpsecondns
  820.     mov    cx,17
  821.     rep    movsb
  822.     stosb                    ; terminator
  823.     mov    si,offset dgroup:_khost
  824.     mov    di,offset tcphost
  825.     mov    cx,60
  826.     rep    movsb
  827.     stosb                    ; terminator
  828.     mov    di,offset tcpbtpserver
  829.     mov    cx,16
  830.     mov    si,offset dgroup:_kbtpserver
  831.     rep    movsb
  832.     stosb                    ; terminator
  833.     mov    di,offset tcpbtpkind
  834.     mov    al,_bootmethod
  835.     stosb
  836.     pop    es
  837.     pop    di
  838.     pop    si
  839.     pop    bp
  840.     ret
  841. _readback endp
  842.  
  843. ; Track Telnet echo variable (0 do not do local echo) into terminal emulator
  844. ; and Kermit main body. Call this each time Telnet options change echo.
  845. ; For use only by Telnet code as an internal procedure.
  846.     public    _kecho
  847. _kecho    proc    near
  848.     assume    ds:data, es:dgroup
  849.     push    bp
  850.     mov    bp,sp
  851.     push    ds
  852.     push    es
  853.     push    si
  854.     push    ax
  855.     mov    ax,data            ; Kermit main data segment
  856.     mov    ds,ax
  857.     mov    ax,DGROUP
  858.     mov    es,ax
  859.     mov    ax,[bp+4+0]        ; get Telnet _echo variable
  860.     and    yflags,not lclecho    ; assume no local echo in emulator
  861.     or    al,al            ; Telnet local echo is off?
  862.     jz    kecho1            ; z = yes
  863.     mov    al,lclecho        ; lclecho flag for emulator
  864. kecho1:    or    yflags,al        ; set terminal emulator
  865.     mov    si,portval
  866.     mov    [si].ecoflg,al        ; set mainline SET echo flag
  867. ifndef    no_terminal
  868.     cmp    ttyact,0        ; acting as a Terminal?
  869.     je    kecho2            ; e = no
  870.     call    dword ptr ftogmod    ; toggle mode line
  871.     call    dword ptr ftogmod    ; and again
  872. endif    ; no_terminal
  873. kecho2:    pop    ax
  874.     pop    si
  875.     pop    es
  876.     pop    ds
  877.     pop    bp
  878.     ret
  879. _kecho    endp
  880.  
  881. ; Track Telnet dobinary variable into Kermit main body. 
  882. ; Call this each time Telnet options change dobinary.
  883. ; For use only by Telnet code as an internal procedure.
  884.     public    _kmode
  885. _kmode    proc    near
  886.     assume    ds:data, es:nothing
  887.     push    bp
  888.     mov    bp,sp
  889.     push    ds
  890.     push    ax
  891.     push    bx
  892.     mov    ax,data            ; Kermit main data segment
  893.     mov    ds,ax
  894.     mov    al,[bp+4+0]        ; get Telnet _dobinary variable
  895.     mov    tcpmode,al        ; update main body
  896.     pop    bx
  897.     pop    ax
  898.     pop    ds
  899.     pop    bp
  900.     ret
  901. _kmode    endp
  902.  
  903. ; Get current terminal emulation screen lines and columns
  904.     public    _get_kscreen
  905. _get_kscreen    proc    near
  906.     assume    ds:data, es:DGROUP
  907.     push    ds
  908.     push    es
  909.     mov    ax,seg data        ; address main body
  910.     mov    ds,ax
  911.     mov    ax,DGROUP
  912.     mov    es,ax
  913.     mov    al,ds:crt_lins        ; get display height
  914.     mov    es:_kterm_lines,al
  915.     mov    al,ds:crt_cols        ; get display width
  916.     mov    es:_kterm_cols,al
  917.     pop    es
  918.     pop    ds
  919.     ret
  920. _get_kscreen    endp
  921.  
  922. ; Report s->rto to tcp_rto variable for mainline Kermit
  923.     public    _krto
  924. _krto    proc    near
  925.     ASSUME    ES:DATA
  926.     push    bp
  927.     mov    bp,sp
  928.     push    es
  929.     mov    ax,seg DATA
  930.     mov    es,ax
  931.     mov    ax,[bp+4]        ; get s->rto
  932.     mov    es:tcp_rto,ax        ; report to mainline code
  933.     pop    es
  934.     pop    bp
  935.     ret
  936.     ASSUME    ES:NOTHING
  937. _krto    endp
  938. _TEXT    ends
  939.         end
  940.  
  941.