diff --git a/kernel/branches/net/applications/telnet/dll.inc b/kernel/branches/net/applications/telnet/dll.inc new file mode 100644 index 0000000000..6ceb2d514d --- /dev/null +++ b/kernel/branches/net/applications/telnet/dll.inc @@ -0,0 +1,157 @@ +;----------------------------------------------------------------------------- +proc mem.Alloc size ;///////////////////////////////////////////////////////// +;----------------------------------------------------------------------------- + push ebx ecx + mov eax,[size] + lea ecx,[eax+4+4095] + and ecx,not 4095 + mcall 68,12 + add ecx,-4 + mov [eax],ecx + add eax,4 + pop ecx ebx + ret +endp + +;----------------------------------------------------------------------------- +proc mem.ReAlloc mptr,size;/////////////////////////////////////////////////// +;----------------------------------------------------------------------------- + push ebx ecx esi edi eax + mov eax,[mptr] + mov ebx,[size] + or eax,eax + jz @f + lea ecx,[ebx+4+4095] + and ecx,not 4095 + add ecx,-4 + cmp ecx,[eax-4] + je .exit + @@: mov eax,ebx + call mem.Alloc + xchg eax,[esp] + or eax,eax + jz .exit + mov esi,eax + xchg eax,[esp] + mov edi,eax + mov ecx,[esi-4] + cmp ecx,[edi-4] + jbe @f + mov ecx,[edi-4] + @@: add ecx,3 + shr ecx,2 + cld + rep movsd + xchg eax,[esp] + call mem.Free + .exit: + pop eax edi esi ecx ebx + ret +endp + +;----------------------------------------------------------------------------- +proc mem.Free mptr ;////////////////////////////////////////////////////////// +;----------------------------------------------------------------------------- + mov eax,[mptr] + or eax,eax + jz @f + push ebx ecx + lea ecx,[eax-4] + mcall 68,13 + pop ecx ebx + @@: ret +endp + + +proc dll.Load, import_table:dword + mov esi,[import_table] + .next_lib: mov edx,[esi] + or edx,edx + jz .exit + push esi + mov esi,[esi+4] + mov edi,s_libdir.fname + @@: lodsb + stosb + or al,al + jnz @b + mcall 68,19,s_libdir + or eax,eax + jz .fail + stdcall dll.Link,eax,edx + stdcall dll.Init,[eax+4] + pop esi + add esi,8 + jmp .next_lib + .exit: xor eax,eax + ret + .fail: add esp,4 + xor eax,eax + inc eax + ret +endp + +proc dll.Link, exp:dword,imp:dword + push eax + mov esi,[imp] + test esi,esi + jz .done + .next: lodsd + test eax,eax + jz .done + stdcall dll.GetProcAddress,[exp],eax + or eax,eax + jz @f + mov [esi-4],eax + jmp .next + @@: mov dword[esp],0 + .done: pop eax + ret +endp + +proc dll.Init, dllentry:dword + pushad + mov eax,mem.Alloc + mov ebx,mem.Free + mov ecx,mem.ReAlloc + mov edx,dll.Load + stdcall [dllentry] + popad + ret +endp + +proc dll.GetProcAddress, exp:dword,sz_name:dword + mov edx,[exp] + xor eax,eax + .next: or edx,edx + jz .end + cmp dword[edx],0 + jz .end + stdcall strcmp,[edx],[sz_name] + test eax,eax + jz .ok + add edx,8 + jmp .next + .ok: mov eax,[edx+4] + .end: ret +endp + +proc strcmp, str1:dword,str2:dword + push esi edi + mov esi,[str1] + mov edi,[str2] + xor eax,eax + @@: lodsb + scasb + jne .fail + or al,al + jnz @b + jmp .ok + .fail: or eax,-1 + .ok: pop edi esi + ret +endp + +s_libdir: + db '/sys/lib/' + .fname rb 32 diff --git a/kernel/branches/net/applications/telnet/telnet.asm b/kernel/branches/net/applications/telnet/telnet.asm new file mode 100644 index 0000000000..0c644bf0f3 --- /dev/null +++ b/kernel/branches/net/applications/telnet/telnet.asm @@ -0,0 +1,212 @@ +use32 +; standard header + db 'MENUET01' ; signature + dd 1 ; header version + dd start ; entry point + dd i_end ; initialized size + dd mem ; required memory + dd mem ; stack pointer + dd 0 ; parameters + dd 0 ; path + + +BUFFERSIZE equ 1500 +; useful includes +include '../macros.inc' +purge mov,add,sub +include '../proc32.inc' +include 'dll.inc' + +include '../network.inc' + +; entry point +start: +; load libraries + stdcall dll.Load, @IMPORT + test eax, eax + jnz exit +; initialize console + push 1 + call [con_start] + push title + push -1 + push -1 + push -1 + push -1 + call [con_init] +; main loop + push str1 + call [con_write_asciiz] +main: +; write prompt + push str2 + call [con_write_asciiz] +; read string + mov esi, s + push 256 + push esi + call [con_gets] +; check for exit + test eax, eax + jz done + cmp byte [esi], 10 + jz done +; delete terminating '\n' + push esi +@@: + lodsb + test al, al + jnz @b + mov byte [esi-2], al + pop esi +; resolve name + push esp ; reserve stack place + push esp ; fourth parameter + push 0 ; third parameter + push 0 ; second parameter + push esi ; first parameter + call [getaddrinfo] + pop esi +; test for error + test eax, eax + jnz fail + +; write results + push str3 + call [con_write_asciiz] +; mov edi, esi + +; convert IP address to decimal notation + mov eax, [esi+addrinfo.ai_addr] + mov eax, [eax+sockaddr_in.sin_addr] + mov [sockaddr1.ip], eax + push eax + call [inet_ntoa] +; write result + push eax + call [con_write_asciiz] +; free allocated memory + push esi + call [freeaddrinfo] + + push str4 + call [con_write_asciiz] + + mcall socket, AF_INET4, IPPROTO_TCP, 0 + cmp eax, -1 + jz fail2 + mov [socketnum], eax + + mcall connect, [socketnum], sockaddr1, 18 + + mcall 40, 1 shl 7 ; + 7 + call [con_cls] + + mcall 51, 1, thread, mem - 2048 + +mainloop: + mcall 10 + + mcall recv, [socketnum], buffer_ptr, BUFFERSIZE, 0 + cmp eax, -1 + je mainloop + + mov esi, buffer_ptr + mov byte [esi + eax], 0 + + @@: + cmp byte [esi], 0xff ; 'IAC' = Interpret As Command + jne @f + ; TODO: parse options, for now, we will reply with 'WONT' to everything + mov byte [esi + 1], 252 ; WONT + add esi, 3 ; a command is always 3 bytes + jmp @r + + @@: + push esi + + cmp esi, buffer_ptr + je .nocommands + + mov edx, buffer_ptr + sub esi, buffer_ptr + xor edi, edi + mcall send, [socketnum] + + .nocommands: + call [con_write_asciiz] + jmp mainloop + + +; write newline and continue main loop + push str4 +@@: + call [con_write_asciiz] + jmp main +fail: + push str5 + jmp @b +fail2: + push str6 + jmp @b + +done: + push 1 + call [con_exit] +exit: + mcall -1 + + + +thread: + mcall 40, 0 + call [con_getch2] + mov byte [send_data], al + mcall send, [socketnum], send_data, 1 + jmp thread + +; data +title db 'Telnet',0 +str1 db 'Telnet v0.1',10,' for KolibriOS # 1250 or later. ',10,10,0 +str2 db '> ',0 +str3 db 'Connecting to: ',0 +str4 db 10,0 +str5 db 'Name resolution failed.',10,10,0 +str6 db 'Could not open socket',10,10,0 +str7 db 'Got data!',10,10,0 + +sockaddr1: + dw AF_INET4 +.port dw 23 shl 8 +.ip dd 0 + rb 10 + + + +; import +align 4 +@IMPORT: + +library network, 'network.obj', console, 'console.obj' +import network, \ + getaddrinfo, 'getaddrinfo', \ + freeaddrinfo, 'freeaddrinfo', \ + inet_ntoa, 'inet_ntoa' +import console, \ + con_start, 'START', \ + con_init, 'con_init', \ + con_write_asciiz, 'con_write_asciiz', \ + con_exit, 'con_exit', \ + con_gets, 'con_gets',\ + con_cls, 'con_cls',\ + con_getch2, 'con_getch2' +i_end: + +socketnum dd ? +buffer_ptr rb BUFFERSIZE +send_data rb 100 + +s rb 256 +align 4 +rb 4096 ; stack +mem: