Subversion Repositories Kolibri OS

Rev

Rev 3704 | 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.  
  164.         mcall   40, 1 shl 7 ; + 7
  165.         call    [con_cls]
  166.  
  167.         mcall   18, 7
  168.         push    eax
  169.         mcall   51, 1, thread, mem - 2048
  170.         pop     ecx
  171.         mcall   18, 3
  172.  
  173. mainloop:
  174.         call    [con_get_flags]
  175.         test    eax, 0x200                      ; con window closed?
  176.         jnz     exit
  177.  
  178.         mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
  179.         cmp     eax, -1
  180.         je      closed
  181.  
  182.  
  183.     DEBUGF  1, 'TELNET: got %u bytes of data !\n', eax
  184.  
  185.         mov     esi, buffer_ptr
  186.         lea     edi, [esi + eax]
  187.         mov     byte [edi], 0
  188.  
  189.   .scan_cmd:
  190.         cmp     byte [esi], 0xff        ; Interpret As Command
  191.         jne     .no_cmd
  192.         ; TODO: parse options, for now, we will reply with 'WONT' to everything
  193.         mov     byte [esi + 1], 252     ; WONT
  194.         add     esi, 3                  ; a command is always 3 bytes
  195.         jmp     .scan_cmd
  196.   .no_cmd:
  197.  
  198.         cmp     esi, buffer_ptr
  199.         je      .print
  200.  
  201.     DEBUGF  1, 'TELNET: sending data\n'
  202.  
  203.         push    esi edi
  204.         sub     esi, buffer_ptr
  205.         mcall   send, [socketnum], buffer_ptr, , 0
  206.         pop     edi esi
  207.  
  208.   .print:
  209.         cmp     esi, edi
  210.         jae     mainloop
  211.  
  212.         push    esi
  213.         call    [con_write_asciiz]
  214.  
  215.   .loop:
  216.         lodsb
  217.         test    al, al
  218.         jz      .print
  219.         jmp     .loop
  220.  
  221.  
  222. socket_err:
  223.         DEBUGF  1, "TELNET: socket error %d", ebx
  224.         push    str6
  225.         call    [con_write_asciiz]
  226.  
  227.         jmp     prompt
  228.  
  229. dns_error:
  230.         DEBUGF  1, "TELNET: DNS error %d", eax
  231.         push    str5
  232.         call    [con_write_asciiz]
  233.  
  234.         jmp     prompt
  235.  
  236. hostname_error:
  237.         push    str11
  238.         call    [con_write_asciiz]
  239.         jmp     prompt
  240.  
  241. closed:
  242.         push    str12
  243.         call    [con_write_asciiz]
  244.         jmp     prompt
  245.  
  246. done:
  247.         push    1
  248.         call    [con_exit]
  249. exit:
  250.  
  251.         mcall   close, [socketnum]
  252.         mcall   -1
  253.  
  254.  
  255.  
  256. thread:
  257.         mcall   40, 0
  258.   .loop:
  259.         call    [con_getch2]
  260.         mov     [send_data], ax
  261.         xor     esi, esi
  262.         inc     esi
  263.         test    al, al
  264.         jnz     @f
  265.         inc     esi
  266.   @@:
  267.         mcall   send, [socketnum], send_data
  268.  
  269.         call    [con_get_flags]
  270.         test    eax, 0x200                      ; con window closed?
  271.         jz      .loop
  272.         mcall   -1
  273.  
  274. ; data
  275. title   db      'Telnet',0
  276. str1    db      'Telnet for KolibriOS',10,10,\
  277.                 'Please enter URL of telnet server (host:port)',10,10,\
  278.                 'fun stuff:',10,\
  279.                 'telehack.com            - arpanet simulator',10,\
  280.                 'towel.blinkenlights.nl  - ASCII Star Wars',10,\
  281.                 'miku.acm.uiuc.edu       - Nyan cat',10,10,0
  282. str2    db      '> ',0
  283. str3    db      'Connecting to ',0
  284. str4    db      10,0
  285. str8    db      ' (',0
  286. str9    db      ')',10,0
  287.  
  288. str5    db      'Name resolution failed.',10,10,0
  289. str6    db      'Could not open socket.',10,10,0
  290. str11   db      'Invalid hostname.',10,10,0
  291. str12   db      10,'Remote host closed the connection.',10,10,0
  292.  
  293. sockaddr1:
  294.         dw AF_INET4
  295. .port   dw 0
  296. .ip     dd 0
  297.         rb 10
  298.  
  299. include_debug_strings    ; ALWAYS present in data section
  300.  
  301.  
  302.  
  303. ; import
  304. align 4
  305. @IMPORT:
  306.  
  307. library network, 'network.obj', console, 'console.obj'
  308. import  network,        \
  309.         getaddrinfo,    'getaddrinfo',  \
  310.         freeaddrinfo,   'freeaddrinfo', \
  311.         inet_ntoa,      'inet_ntoa'
  312. import  console,        \
  313.         con_start,      'START',        \
  314.         con_init,       'con_init',     \
  315.         con_write_asciiz,       'con_write_asciiz',     \
  316.         con_exit,       'con_exit',     \
  317.         con_gets,       'con_gets',\
  318.         con_cls,        'con_cls',\
  319.         con_getch2,     'con_getch2',\
  320.         con_set_cursor_pos, 'con_set_cursor_pos',\
  321.         con_write_string, 'con_write_string',\
  322.         con_get_flags,  'con_get_flags'
  323.  
  324.  
  325. i_end:
  326.  
  327. socketnum       dd ?
  328. buffer_ptr      rb BUFFERSIZE+1
  329. send_data       dw ?
  330.  
  331. hostname        rb 1024
  332.  
  333. mem:
  334.