Subversion Repositories Kolibri OS

Rev

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

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2010-2012. 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__       equ 0
  18. __DEBUG_LEVEL__ equ 1
  19. BUFFERSIZE      equ 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     fail
  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      fail2
  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.     DEBUGF  1, 'TELNET: Waiting for events\n'
  175.         mcall   10
  176.     DEBUGF  1, 'TELNET: EVENT %x !\n', eax
  177.  
  178.         call    [con_get_flags]
  179.         test    eax, 0x200                      ; con window closed?
  180.         jnz     exit
  181.  
  182.         mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
  183.         cmp     eax, -1
  184.         je      mainloop
  185.  
  186.     DEBUGF  1, 'TELNET: got %u bytes of data !\n', eax
  187.  
  188.         mov     esi, buffer_ptr
  189.         lea     edi, [esi + eax]
  190.         mov     byte [edi], 0
  191.  
  192.   .scan_cmd:
  193.         cmp     byte [esi], 0xff        ; Interpret As Command
  194.         jne     .no_cmd
  195.         ; TODO: parse options, for now, we will reply with 'WONT' to everything
  196.         mov     byte [esi + 1], 252     ; WONT
  197.         add     esi, 3                  ; a command is always 3 bytes
  198.         jmp     .scan_cmd
  199.   .no_cmd:
  200.  
  201.         cmp     esi, buffer_ptr
  202.         je      .print_loop
  203.  
  204.     DEBUGF  1, 'TELNET: sending data\n'
  205.  
  206.         push    esi edi
  207.         sub     esi, buffer_ptr
  208.         mcall   send, [socketnum], buffer_ptr, , 0
  209.         pop     edi esi
  210.  
  211.   .print_loop:
  212.     DEBUGF  1, 'TELNET: printloop\n'
  213.         cmp     esi, edi
  214.         jae     mainloop
  215.  
  216.         cmp     byte [esi], 0x1b        ; escape character
  217.         jne     .print_byte
  218.         inc     esi
  219.  
  220.         cmp     word [esi], 0x485b      ; move cursor to beginning
  221.         jne     @f
  222.         inc     esi
  223.         inc     esi
  224.  
  225.     DEBUGF  1, 'TELNET: resetting cursor \n'
  226.  
  227.         push    0
  228.         push    0
  229.         call    [con_set_cursor_pos]
  230.         jmp     .print_loop
  231.  
  232.   @@:
  233.         inc     esi
  234.         inc     esi
  235.         jmp     .print_loop
  236.  
  237.   .print_byte:
  238.         push    dword 1
  239.         push    esi                     ; next string to print
  240.         inc     esi
  241.         call    [con_write_string]
  242.         jmp     .print_loop
  243.  
  244.  
  245. fail2:
  246.         push    str6
  247.         call    [con_write_asciiz]
  248.  
  249.         jmp     prompt
  250.  
  251. fail:
  252.         push    str5
  253.         call    [con_write_asciiz]
  254.  
  255.         jmp     prompt
  256.  
  257. hostname_error:
  258.         push    str11
  259.         call    [con_write_asciiz]
  260.         jmp     prompt
  261.  
  262. done:
  263.         push    1
  264.         call    [con_exit]
  265. exit:
  266.  
  267.         mcall   close, [socketnum]
  268.         mcall   -1
  269.  
  270.  
  271.  
  272. thread:
  273.         mcall   40, 0
  274.   .loop:
  275.         call    [con_getch2]
  276.         mov     byte [send_data], al
  277.         mcall   send, [socketnum], send_data, 1
  278.  
  279.         call    [con_get_flags]
  280.         test    eax, 0x200                      ; con window closed?
  281.         jz      .loop
  282.         mcall   -1
  283.  
  284. ; data
  285. title   db      'Telnet',0
  286. str1    db      'Telnet for KolibriOS',10,10,\
  287.                 'Please enter URL of telnet server (for example: towel.blinkenlights.nl:23)',10,10,0
  288. str2    db      '> ',0
  289. str3    db      'Connecting to ',0
  290. str4    db      10,0
  291. str8    db      ' (',0
  292. str9    db      ')',10,0
  293.  
  294. str5    db      'Name resolution failed.',10,10,0
  295. str6    db      'Could not open socket.',10,10,0
  296. str11   db      'Invalid hostname.',10,10,0
  297.  
  298. sockaddr1:
  299.         dw AF_INET4
  300. .port   dw 0
  301. .ip     dd 0
  302.         rb 10
  303.  
  304. include_debug_strings    ; ALWAYS present in data section
  305.  
  306.  
  307.  
  308. ; import
  309. align 4
  310. @IMPORT:
  311.  
  312. library network, 'network.obj', console, 'console.obj'
  313. import  network,        \
  314.         getaddrinfo,    'getaddrinfo',  \
  315.         freeaddrinfo,   'freeaddrinfo', \
  316.         inet_ntoa,      'inet_ntoa'
  317. import  console,        \
  318.         con_start,      'START',        \
  319.         con_init,       'con_init',     \
  320.         con_write_asciiz,       'con_write_asciiz',     \
  321.         con_exit,       'con_exit',     \
  322.         con_gets,       'con_gets',\
  323.         con_cls,        'con_cls',\
  324.         con_getch2,     'con_getch2',\
  325.         con_set_cursor_pos, 'con_set_cursor_pos',\
  326.         con_write_string, 'con_write_string',\
  327.         con_get_flags,  'con_get_flags'
  328.  
  329.  
  330. i_end:
  331.  
  332. socketnum       dd ?
  333. buffer_ptr      rb BUFFERSIZE+1
  334. send_data       rb 1
  335.  
  336. hostname        rb 1024
  337.  
  338. mem:
  339.