Subversion Repositories Kolibri OS

Rev

Rev 3687 | Rev 3704 | 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.     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.   .check_for_data:
  183.         mcall   recv, [socketnum], buffer_ptr, BUFFERSIZE, 0
  184.         cmp     eax, -1
  185.         jne     .parse_data
  186.         cmp     ebx, 6  ; EWOULDBLOCK
  187.         je      mainloop
  188.         jmp     closed
  189.  
  190.  
  191.   .parse_data:
  192.  
  193.     DEBUGF  1, 'TELNET: got %u bytes of data !\n', eax
  194.  
  195.         mov     esi, buffer_ptr
  196.         lea     edi, [esi + eax]
  197.         mov     byte [edi], 0
  198.  
  199.   .scan_cmd:
  200.         cmp     byte [esi], 0xff        ; Interpret As Command
  201.         jne     .no_cmd
  202.         ; TODO: parse options, for now, we will reply with 'WONT' to everything
  203.         mov     byte [esi + 1], 252     ; WONT
  204.         add     esi, 3                  ; a command is always 3 bytes
  205.         jmp     .scan_cmd
  206.   .no_cmd:
  207.  
  208.         cmp     esi, buffer_ptr
  209.         je      .print
  210.  
  211.     DEBUGF  1, 'TELNET: sending data\n'
  212.  
  213.         push    esi edi
  214.         sub     esi, buffer_ptr
  215.         mcall   send, [socketnum], buffer_ptr, , 0
  216.         pop     edi esi
  217.  
  218.   .print:
  219.         cmp     esi, edi
  220.         jae     .check_for_data
  221.  
  222.         push    esi
  223.         call    [con_write_asciiz]
  224.  
  225.   .loop:
  226.         lodsb
  227.         test    al, al
  228.         jz      .print
  229.         jmp     .loop
  230.  
  231.  
  232. socket_err:
  233.         DEBUGF  1, "TELNET: socket error %d", ebx
  234.         push    str6
  235.         call    [con_write_asciiz]
  236.  
  237.         jmp     prompt
  238.  
  239. dns_error:
  240.         DEBUGF  1, "TELNET: DNS error %d", eax
  241.         push    str5
  242.         call    [con_write_asciiz]
  243.  
  244.         jmp     prompt
  245.  
  246. hostname_error:
  247.         push    str11
  248.         call    [con_write_asciiz]
  249.         jmp     prompt
  250.  
  251. closed:
  252.         push    str12
  253.         call    [con_write_asciiz]
  254.         jmp     prompt
  255.  
  256. done:
  257.         push    1
  258.         call    [con_exit]
  259. exit:
  260.  
  261.         mcall   close, [socketnum]
  262.         mcall   -1
  263.  
  264.  
  265.  
  266. thread:
  267.         mcall   40, 0
  268.   .loop:
  269.         call    [con_getch2]
  270.         mov     byte [send_data], al
  271.         mcall   send, [socketnum], send_data, 1
  272.  
  273.         call    [con_get_flags]
  274.         test    eax, 0x200                      ; con window closed?
  275.         jz      .loop
  276.         mcall   -1
  277.  
  278. ; data
  279. title   db      'Telnet',0
  280. str1    db      'Telnet for KolibriOS',10,10,\
  281.                 'Please enter URL of telnet server (for example: towel.blinkenlights.nl:23)',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       rb 1
  330.  
  331. hostname        rb 1024
  332.  
  333. mem:
  334.