Subversion Repositories Kolibri OS

Rev

Rev 4020 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2010-2013. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  telnet.asm - Telnet client for KolibriOS                       ;;
  7. ;;                                                                 ;;
  8. ;;  Written by hidnplayr@kolibrios.org                             ;;
  9. ;;                                                                 ;;
  10. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  11. ;;             Version 2, June 1991                                ;;
  12. ;;                                                                 ;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15. format binary as ""
  16.  
  17. __DEBUG__       = 0
  18. __DEBUG_LEVEL__ = 1
  19. BUFFERSIZE      = 4096
  20.  
  21. use32
  22. ; standard header
  23.         db      'MENUET01'      ; signature
  24.         dd      1               ; header version
  25.         dd      start           ; entry point
  26.         dd      i_end           ; initialized size
  27.         dd      mem+4096        ; required memory
  28.         dd      mem+4096        ; stack pointer
  29.         dd      hostname        ; parameters
  30.         dd      0               ; path
  31.  
  32. include '../../macros.inc'
  33. purge mov,add,sub
  34. include '../../proc32.inc'
  35. include '../../dll.inc'
  36. include '../../debug-fdo.inc'
  37. include '../../network.inc'
  38.  
  39. ; entry point
  40. start:
  41. ; load libraries
  42.         stdcall dll.Load, @IMPORT
  43.         test    eax, eax
  44.         jnz     exit
  45. ; initialize console
  46.         push    1
  47.         call    [con_start]
  48.         push    title
  49.         push    25
  50.         push    80
  51.         push    25
  52.         push    80
  53.         call    [con_init]
  54.  
  55. ; Check for parameters
  56.         cmp     byte [hostname], 0
  57.         jne     resolve
  58.  
  59. main:
  60.         call    [con_cls]
  61. ; Welcome user
  62.         push    str1
  63.         call    [con_write_asciiz]
  64.  
  65. prompt:
  66. ; write prompt
  67.         push    str2
  68.         call    [con_write_asciiz]
  69. ; read string
  70.         mov     esi, hostname
  71.         push    256
  72.         push    esi
  73.         call    [con_gets]
  74. ; check for exit
  75.         test    eax, eax
  76.         jz      done
  77.         cmp     byte [esi], 10
  78.         jz      done
  79.  
  80. resolve:
  81.  
  82.         mov     [sockaddr1.port], 23 shl 8
  83.  
  84. ; delete terminating '\n'
  85.         mov     esi, hostname
  86.   @@:
  87.         lodsb
  88.         cmp     al, ':'
  89.         je      .do_port
  90.         cmp     al, 0x20
  91.         ja      @r
  92.         mov     byte [esi-1], 0
  93.         jmp     .done
  94.  
  95.   .do_port:
  96.         xor     eax, eax
  97.         xor     ebx, ebx
  98.         mov     byte [esi-1], 0
  99.   .portloop:
  100.         lodsb
  101.         cmp     al, 0x20
  102.         jbe     .port_done
  103.         sub     al, '0'
  104.         jb      hostname_error
  105.         cmp     al, 9
  106.         ja      hostname_error
  107.         lea     ebx, [ebx*4 + ebx]
  108.         shl     ebx, 1
  109.         add     ebx, eax
  110.         jmp     .portloop
  111.  
  112.   .port_done:
  113.         xchg    bl, bh
  114.         mov     [sockaddr1.port], bx
  115.  
  116.   .done:
  117.  
  118. ; resolve name
  119.         push    esp     ; reserve stack place
  120.         push    esp     ; ptr to result
  121.         push    0       ; addrinfo hints
  122.         push    0       ; servname
  123.         push    hostname; hostname
  124.         call    [getaddrinfo]
  125.         pop     esi
  126. ; test for error
  127.         test    eax, eax
  128.         jnz     dns_error
  129.  
  130.         call    [con_cls]
  131.         push    str3
  132.         call    [con_write_asciiz]
  133.         push    hostname
  134.         call    [con_write_asciiz]
  135.  
  136. ; write results
  137.         push    str8
  138.         call    [con_write_asciiz]
  139. ;        mov     edi, esi
  140.  
  141. ; convert IP address to decimal notation
  142.         mov     eax, [esi+addrinfo.ai_addr]
  143.         mov     eax, [eax+sockaddr_in.sin_addr]
  144.         mov     [sockaddr1.ip], eax
  145.         push    eax
  146.         call    [inet_ntoa]
  147. ; write result
  148.         push    eax
  149.         call    [con_write_asciiz]
  150. ; free allocated memory
  151.         push    esi
  152.         call    [freeaddrinfo]
  153.  
  154.         push    str9
  155.         call    [con_write_asciiz]
  156.  
  157.         mcall   socket, AF_INET4, SOCK_STREAM, 0
  158.         cmp     eax, -1
  159.         jz      socket_err
  160.         mov     [socketnum], eax
  161.  
  162.         mcall   connect, [socketnum], sockaddr1, 18
  163.         test    eax, eax
  164.         jnz     socket_err
  165.  
  166.         mcall   40, 1 shl 7 ; + 7
  167.         call    [con_cls]
  168.  
  169.         mcall   18, 7
  170.         push    eax
  171.         mcall   51, 1, thread, mem - 2048
  172.         pop     ecx
  173.         mcall   18, 3
  174.  
  175. mainloop:
  176.         call    [con_get_flags]
  177.         test    eax, 0x200                      ; con window closed?
  178.         jnz     exit
  179.  
  180.         mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
  181.         cmp     eax, -1
  182.         je      closed
  183.  
  184.  
  185.     DEBUGF  1, 'TELNET: got %u bytes of data !\n', eax
  186.  
  187.         mov     esi, buffer_ptr
  188.         lea     edi, [esi + eax]
  189.         mov     byte [edi], 0
  190.  
  191.   .scan_cmd:
  192.         cmp     byte [esi], 0xff        ; Interpret As Command
  193.         jne     .no_cmd
  194.         ; TODO: parse options, for now, we will reply with 'WONT' to everything
  195.         mov     byte [esi + 1], 252     ; WONT
  196.         add     esi, 3                  ; a command is always 3 bytes
  197.         jmp     .scan_cmd
  198.   .no_cmd:
  199.  
  200.         cmp     esi, buffer_ptr
  201.         je      .print
  202.  
  203.     DEBUGF  1, 'TELNET: sending data\n'
  204.  
  205.         push    esi edi
  206.         sub     esi, buffer_ptr
  207.         mcall   send, [socketnum], buffer_ptr, , 0
  208.         pop     edi esi
  209.  
  210.   .print:
  211.         cmp     esi, edi
  212.         jae     mainloop
  213.  
  214.         push    esi
  215.         call    [con_write_asciiz]
  216.  
  217.   .loop:
  218.         lodsb
  219.         test    al, al
  220.         jz      .print
  221.         jmp     .loop
  222.  
  223.  
  224. socket_err:
  225.         DEBUGF  1, "TELNET: socket error %d", ebx
  226.         push    str6
  227.         call    [con_write_asciiz]
  228.  
  229.         jmp     prompt
  230.  
  231. dns_error:
  232.         DEBUGF  1, "TELNET: DNS error %d", eax
  233.         push    str5
  234.         call    [con_write_asciiz]
  235.  
  236.         jmp     prompt
  237.  
  238. hostname_error:
  239.         push    str11
  240.         call    [con_write_asciiz]
  241.         jmp     prompt
  242.  
  243. closed:
  244.         push    str12
  245.         call    [con_write_asciiz]
  246.         jmp     prompt
  247.  
  248. done:
  249.         push    1
  250.         call    [con_exit]
  251. exit:
  252.  
  253.         mcall   close, [socketnum]
  254.         mcall   -1
  255.  
  256.  
  257.  
  258. thread:
  259.         mcall   40, 0
  260.   .loop:
  261.         call    [con_getch2]
  262.         mov     [send_data], ax
  263.         xor     esi, esi
  264.         inc     esi
  265.         test    al, al
  266.         jnz     @f
  267.         inc     esi
  268.   @@:
  269.         mcall   send, [socketnum], send_data
  270.  
  271.         call    [con_get_flags]
  272.         test    eax, 0x200                      ; con window closed?
  273.         jz      .loop
  274.         mcall   -1
  275.  
  276. ; data
  277. title   db      'Telnet',0
  278. str1    db      'Telnet for KolibriOS',10,10,\
  279.                 'Please enter URL of telnet server (host:port)',10,10,\
  280.                 'fun stuff:',10,\
  281.                 'telehack.com            - arpanet simulator',10,\
  282.                 'towel.blinkenlights.nl  - ASCII Star Wars',10,\
  283.                 'nyancat.dakko.us        - Nyan cat',10,10,0
  284. str2    db      '> ',0
  285. str3    db      'Connecting to ',0
  286. str4    db      10,0
  287. str8    db      ' (',0
  288. str9    db      ')',10,0
  289.  
  290. str5    db      'Name resolution failed.',10,10,0
  291. str6    db      'Could not open socket.',10,10,0
  292. str11   db      'Invalid hostname.',10,10,0
  293. str12   db      10,'Remote host closed the connection.',10,10,0
  294.  
  295. sockaddr1:
  296.         dw AF_INET4
  297. .port   dw 0
  298. .ip     dd 0
  299.         rb 10
  300.  
  301. include_debug_strings    ; ALWAYS present in data section
  302.  
  303.  
  304.  
  305. ; import
  306. align 4
  307. @IMPORT:
  308.  
  309. library network, 'network.obj', console, 'console.obj'
  310. import  network,        \
  311.         getaddrinfo,    'getaddrinfo',  \
  312.         freeaddrinfo,   'freeaddrinfo', \
  313.         inet_ntoa,      'inet_ntoa'
  314. import  console,        \
  315.         con_start,      'START',        \
  316.         con_init,       'con_init',     \
  317.         con_write_asciiz,       'con_write_asciiz',     \
  318.         con_exit,       'con_exit',     \
  319.         con_gets,       'con_gets',\
  320.         con_cls,        'con_cls',\
  321.         con_getch2,     'con_getch2',\
  322.         con_set_cursor_pos, 'con_set_cursor_pos',\
  323.         con_write_string, 'con_write_string',\
  324.         con_get_flags,  'con_get_flags'
  325.  
  326.  
  327. i_end:
  328.  
  329. socketnum       dd ?
  330. buffer_ptr      rb BUFFERSIZE+1
  331. send_data       dw ?
  332.  
  333. hostname        rb 1024
  334.  
  335. mem:
  336.