Telnet chat server for Linux x86_64

Тема в разделе "WASM.BEGINNERS", создана пользователем Hacker, 16 июл 2023.

  1. Application

    Application Moderator Команда форума

    Публикаций:
    1
    Регистрация:
    8 дек 2007
    Сообщения:
    988
    Сервер.
     

    Вложения:

    • server.rar
      Размер файла:
      42,5 КБ
      Просмотров:
      59
  2. Orbit

    Orbit Member

    Публикаций:
    0
    Регистрация:
    13 дек 2016
    Сообщения:
    114
    Адрес:
    г. Москва
    Не запускается но компилируется
    Код (ASM):
    1.  
    2. ;;
    3. ;;
    4.  
    5. %include '/home/user/Desktop/nasmx/inc/nasmx.inc'
    6. %include '/home/user/Desktop/nasmx/inc/linux/libc.inc'
    7. %include '/home/user/Desktop/nasmx/inc/linux/syscall.inc'
    8.  
    9. FIONBIO equ 0x5421
    10.  
    11. entry begin
    12.  
    13. struc sockaddr_in
    14.     .sin_family resw 1
    15.     .sin_port resw 1
    16.     .sin_addr resd 1
    17.     .sin_zero resb 8
    18. endstruc
    19.  
    20. struc pollfd
    21.     .fd resq 1
    22.     .events resw 1
    23.     .revents resw 1
    24. endstruc
    25.  
    26. [SECTION .data]
    27.  
    28. tcs_so istruc sockaddr_in
    29.     at sockaddr_in.sin_family, dw 2
    30.     at sockaddr_in.sin_port, dw 0x1700
    31.     at sockaddr_in.sin_addr, dd 0
    32.     at sockaddr_in.sin_zero, dd 0, 0
    33. iend
    34.  
    35. sockaddr_in_size equ $ - tcs_so
    36.  
    37. fds istruc pollfd
    38.     at pollfd.fd, dq 0
    39.     at pollfd.events, dw 1
    40.     at pollfd.revents, dw 0
    41. iend
    42.  
    43. fds_size equ $ - fds
    44.  
    45. do_linemode db 255, 253, 34
    46. do_linemode_size equ $ - do_linemode
    47.  
    48. on_linemode db 255, 250, 34, 1, 1, 255, 240
    49. on_linemode_size equ $ - on_linemode
    50.  
    51. will_echo db 255, 253, 1
    52. will_echo_size equ $ - will_echo
    53.  
    54. wont_echo db 255, 252, 1
    55. wont_echo_size equ $ - wont_echo
    56.  
    57.  
    58.  
    59. [SECTION .bss]
    60.  
    61. client_fd resq 1
    62. buffer: resb 1728
    63. ioctlchar: resq 1
    64.  
    65. reply_buff db 512 dup(0)
    66. reply_buff_size equ  $ - reply_buff
    67.  
    68. [SECTION .text]
    69.  
    70. .begin:
    71.  
    72.     push rbp
    73.     mov rbp, rsp
    74.  
    75.     call main_proc
    76.  
    77. proc main_proc
    78. locals none
    79.  
    80.     syscall socket, 2, 1, 0
    81.     mov r13, rax
    82.  
    83.     syscall bind, r13, tcs_so, sockaddr_in_size
    84.     syscall listen, r13, 4096
    85.  
    86.     syscall ioctl, r13, FIONBIO, ioctlchar
    87.  
    88.     mov [pollfd.fd], r13
    89.  
    90. .loop:
    91.     syscall poll, fds, fds_size, 100
    92.  
    93.  
    94.     mov rax, fds
    95.     mov eax, [rax + 4]
    96.     test eax, 1
    97.     jz .loop
    98.  
    99.     syscall accept, r13, tcs_so, sockaddr_in_size
    100.  
    101.     mov [client_fd], rax
    102.  
    103.     syscall read, client_fd, reply_buff, reply_buff_size
    104.  
    105.     syscall write, pollfd.fd, do_linemode, do_linemode_size
    106.     syscall write, pollfd.fd, on_linemode, on_linemode_size
    107.     syscall write, pollfd.fd, will_echo, will_echo_size
    108.     syscall write, pollfd.fd, wont_echo, wont_echo_size
    109.  
    110.     jmp .loop
    111.  
    112.     ret
    113.  
    114. endproc
    115.  
    Код (Bash):
    1.  
    2. [user@Notebook nasmx]$ make
    3. nasm -f elf64 ttys.asm -o ttys.o
    4. ttys.asm:64: warning: attempt to initialize memory in BSS section `.bss': ignored [-w+other]
    5. ttys.asm:64: warning: attempt to initialize memory in BSS section `.bss': ignored [-w+other]
    6. ld  -o ttys ttys.o -lc
    7. ld: предупреждение: невозможно найти символ входа _start; используем значение по умолчанию 0000000000401000
    8. [user@Notebook nasmx]$ ./ttys
    9. bash: ./ttys: cannot execute: required file not found
    10.  
    --- Сообщение объединено, 10 авг 2026 в 05:53 ---
    Как правильно указать точку входа для BSD линкера?
    --- Сообщение объединено, 10 авг 2026 в 06:17 ---
    BSD ld линкер подключить не удалось, но очень бы хотелось, ошибки входа и нужно как-то указывать ему библиотеки?
    Сделал пока так

    Код (ASM):
    1.  
    2. ;;
    3. ;;
    4.  
    5. %include '/home/user/Desktop/nasmx/inc/nasmx.inc'
    6. %include '/home/user/Desktop/nasmx/inc/linux/libc.inc'
    7. %include '/home/user/Desktop/nasmx/inc/linux/syscall.inc'
    8.  
    9. FIONBIO equ 0x5421
    10.  
    11. entry begin
    12.  
    13. struc sockaddr_in
    14.     .sin_family resw 1
    15.     .sin_port resw 1
    16.     .sin_addr resd 1
    17.     .sin_zero resb 8
    18. endstruc
    19.  
    20. struc pollfd
    21.     .fd resq 1
    22.     .events resw 1
    23.     .revents resw 1
    24. endstruc
    25.  
    26. [SECTION .data]
    27.  
    28. tcs_so istruc sockaddr_in
    29.     at sockaddr_in.sin_family, dw 2
    30.     at sockaddr_in.sin_port, dw 0x1700
    31.     at sockaddr_in.sin_addr, dd 0
    32.     at sockaddr_in.sin_zero, dd 0, 0
    33. iend
    34.  
    35. sockaddr_in_size equ $ - tcs_so
    36.  
    37. fds istruc pollfd
    38.     at pollfd.fd, dq 0
    39.     at pollfd.events, dw 1
    40.     at pollfd.revents, dw 0
    41. iend
    42.  
    43. fds_size equ $ - fds
    44.  
    45. do_linemode db 255, 253, 34
    46. do_linemode_size equ $ - do_linemode
    47.  
    48. on_linemode db 255, 250, 34, 1, 1, 255, 240
    49. on_linemode_size equ $ - on_linemode
    50.  
    51. will_echo db 255, 253, 1
    52. will_echo_size equ $ - will_echo
    53.  
    54. wont_echo db 255, 252, 1
    55. wont_echo_size equ $ - wont_echo
    56.  
    57.  
    58.  
    59. [SECTION .bss]
    60.  
    61. buffer: resb 1728
    62. ioctlchar: resq 1
    63.  
    64. reply_buff db 512 dup(0)
    65. reply_buff_size equ  $ - reply_buff
    66.  
    67. [SECTION .text]
    68.  
    69. begin:
    70.  
    71.     push rbp
    72.     mov rbp, rsp
    73.  
    74.     call main_proc
    75.  
    76. proc main_proc
    77. locals none
    78.  
    79.     syscall socket, 2, 1, 0
    80.     mov r13, rax
    81.  
    82.     syscall bind, r13, tcs_so, sockaddr_in_size
    83.     syscall listen, r13, 4096
    84.  
    85.     syscall ioctl, r13, FIONBIO, ioctlchar
    86.  
    87.         mov [pollfd.fd], r13
    88.  
    89. .loop:
    90.     syscall poll, fds, fds_size, 100
    91.  
    92.  
    93.         mov rax, fds
    94.         mov eax, [rax + 4]
    95.         test eax, 1
    96.         jz .loop
    97.  
    98.     syscall accept, r13, tcs_so, sockaddr_in_size
    99.  
    100.     syscall read, rax, reply_buff, reply_buff_size
    101.  
    102.     syscall write, pollfd.fd, do_linemode, do_linemode_size
    103.     syscall write, pollfd.fd, on_linemode, on_linemode_size
    104.     syscall write, pollfd.fd, will_echo, will_echo_size
    105.     syscall write, pollfd.fd, wont_echo, wont_echo_size
    106.  
    107.     jmp .loop
    108.    
    109.     ret
    110.    
    111. endproc
    112.  
    113.  
    Код (Bash):
    1.  
    2. ##### Makefile #####
    3. NAME=ttys
    4. AS=nasm
    5. ASFLAGS=-f elf64
    6. LD=gcc
    7. LDFLAGS        =
    8. LIBS        =-lc
    9.  
    10. # [ Suffixes ]
    11. # Change the suffixes to match your system environment
    12. O           = .o
    13. ASM         = .asm
    14. INC         = .inc
    15. LST         = .lst
    16.  
    17. OBJS = $(NAME)$(O)
    18.  
    19. all: $(NAME)
    20.  
    21. $(NAME): $(OBJS)
    22.     $(LD) $(LDFLAGS) -o $(NAME) $(OBJS) $(LIBS)
    23.  
    24. $(NAME)$(O): $(NAME)$(ASM)
    25.     $(AS) $(ASFLAGS) $(NAME)$(ASM) -o $(NAME)$(O)
    26.  
    27. clean:
    28.     rm *$(O) ./$(NAME)
    29.  
    30. ##### End Makefile #####
    31.  
    32.  
    В итоге ошибка сегментирования :dntknw:
     
    Последнее редактирование: 10 авг 2026 в 05:53
  3. Application

    Application Moderator Команда форума

    Публикаций:
    1
    Регистрация:
    8 дек 2007
    Сообщения:
    988
    Код (ASM):
    1. ;;
    2. ;; Telnet server на NASM (попытка исправления)
    3. ;;
    4.  
    5. %include '/home/user/Desktop/nasmx/inc/nasmx.inc'
    6. %include '/home/user/Desktop/nasmx/inc/linux/libc.inc'
    7. %include '/home/user/Desktop/nasmx/inc/linux/syscall.inc'
    8.  
    9. ; Константы
    10. POLLIN      equ 1
    11. SOCK_STREAM equ 1
    12. AF_INET     equ 2
    13. SOL_SOCKET  equ 1
    14. SO_REUSEADDR equ 2
    15.  
    16. ; TELNET команды
    17. IAC         equ 255
    18. WILL        equ 251
    19. WONT        equ 252
    20. DO          equ 253
    21. DONT        equ 254
    22. SB          equ 250
    23. SE          equ 240
    24. LINEMODE    equ 34
    25. ECHO        equ 1
    26.  
    27. ; Структуры
    28. struc sockaddr_in
    29.     .sin_family resw 1
    30.     .sin_port   resw 1
    31.     .sin_addr   resd 1
    32.     .sin_zero   resb 8
    33. endstruc
    34.  
    35. struc pollfd
    36.     .fd      resd 1
    37.     .events  resw 1
    38.     .revents resw 1
    39. endstruc
    40.  
    41. entry begin
    42.  
    43. [SECTION .data]
    44.  
    45. ; Адрес для привязки (порт 2323)
    46. tcs_so istruc sockaddr_in
    47.     at sockaddr_in.sin_family, dw AF_INET
    48.     at sockaddr_in.sin_port,   dw 0x1309    ; 2323 в network byte order
    49.     at sockaddr_in.sin_addr,   dd 0         ; INADDR_ANY
    50.     at sockaddr_in.sin_zero,   dd 0, 0
    51. iend
    52.  
    53. sockaddr_in_size equ $ - tcs_so
    54.  
    55. ; Структура для poll
    56. fds istruc pollfd
    57.     at pollfd.fd,      dd 0
    58.     at pollfd.events,  dw POLLIN
    59.     at pollfd.revents, dw 0
    60. iend
    61.  
    62. ; TELNET negotiation
    63. telnet_negotiation db IAC, DO, LINEMODE
    64. telnet_negotiation_size equ $ - telnet_negotiation
    65.  
    66. telnet_subneg db IAC, SB, LINEMODE, 1, 1, IAC, SE
    67. telnet_subneg_size equ $ - telnet_subneg
    68.  
    69. telnet_will_echo db IAC, WILL, ECHO
    70. telnet_will_echo_size equ $ - telnet_will_echo
    71.  
    72. ; Сообщения для отладки
    73. msg_start db "Telnet server started on port 2323", 10, 0
    74. msg_start_len equ $ - msg_start
    75.  
    76. msg_connect db "Client connected!", 10, 0
    77. msg_connect_len equ $ - msg_connect
    78.  
    79. msg_data db "Received data: ", 0
    80. msg_data_len equ $ - msg_data
    81.  
    82. msg_goodbye db "Goodbye!", 10, 0
    83. msg_goodbye_len equ $ - msg_goodbye
    84.  
    85. msg_echo db "Echo: ", 0
    86. msg_echo_len equ $ - msg_echo
    87.  
    88. msg_error_bind db "Bind error!", 10, 0
    89. msg_error_bind_len equ $ - msg_error_bind
    90.  
    91. msg_error_listen db "Listen error!", 10, 0
    92. msg_error_listen_len equ $ - msg_error_listen
    93.  
    94. msg_error_setsockopt db "Setsockopt error!", 10, 0
    95. msg_error_setsockopt_len equ $ - msg_error_setsockopt
    96.  
    97. newline db 10, 0
    98.  
    99. [SECTION .bss]
    100.  
    101. client_fd  resd 1
    102. ioctl_val  resd 1
    103. addr_len   resd 1
    104. buffer     resb 4096
    105. bytes_read resq 1
    106.  
    107. [SECTION .text]
    108.  
    109. .begin:
    110.     push rbp
    111.     mov rbp, rsp
    112.     call main_proc
    113.     pop rbp
    114.     ret
    115.  
    116. proc main_proc
    117. locals none
    118.  
    119.     ; Вывод сообщения о запуске
    120.     syscall write, 1, msg_start, msg_start_len
    121.  
    122.     ; Создание сокета
    123.     syscall socket, AF_INET, SOCK_STREAM, 0
    124.     cmp rax, 0
    125.     jl .error_exit
    126.     mov r13, rax
    127.  
    128.     ; Устанавливаем SO_REUSEADDR
    129.     mov dword [ioctl_val], SO_REUSEADDR
    130.     syscall setsockopt, r13, SOL_SOCKET, SO_REUSEADDR, ioctl_val, 4
    131.     cmp rax, 0
    132.     jl .error_setsockopt
    133.  
    134.     ; Привязка
    135.     syscall bind, r13, tcs_so, sockaddr_in_size
    136.     cmp rax, 0
    137.     jl .error_bind
    138.  
    139.     ; Слушаем
    140.     syscall listen, r13, 4096
    141.     cmp rax, 0
    142.     jl .error_listen
    143.  
    144.     ; Устанавливаем неблокирующий режим для слушающего сокета
    145.     mov dword [ioctl_val], 1
    146.     syscall ioctl, r13, 0x5421, ioctl_val  ; FIONBIO
    147.  
    148.     ; Сохраняем fd в pollfd
    149.     mov dword [fds + pollfd.fd], r13d
    150.  
    151. .main_loop:
    152.  
    153.     ; Ожидание событий (таймаут 100 мс)
    154.     syscall poll, fds, 1, 100
    155.     cmp rax, 0
    156.     jle .main_loop
    157.  
    158.     ; Проверяем события на слушающем сокете
    159.     test word [fds + pollfd.revents], POLLIN
    160.     jz .main_loop
    161.  
    162.     ; Принимаем новое соединение
    163.     syscall accept, r13, 0, 0
    164.     cmp rax, 0
    165.     jl .main_loop
    166.  
    167.     mov [client_fd], eax
    168.  
    169.     ; Выводим сообщение о подключении
    170.     syscall write, 1, msg_connect, msg_connect_len
    171.  
    172.     ; ============================================
    173.     ; СНАЧАЛА Telnet negotiation
    174.     ; ============================================
    175.     syscall write, [client_fd], telnet_negotiation, telnet_negotiation_size
    176.     syscall write, [client_fd], telnet_subneg, telnet_subneg_size
    177.     syscall write, [client_fd], telnet_will_echo, telnet_will_echo_size
    178.  
    179.     ; Отправляем приветствие
    180.     syscall write, [client_fd], newline, 1
    181.     syscall write, [client_fd], msg_connect, msg_connect_len
    182.     syscall write, [client_fd], newline, 1
    183.  
    184.     ; ============================================
    185.     ; ТЕПЕРЬ читаем данные от клиента
    186.     ; ============================================
    187.     syscall read, [client_fd], buffer, 4096
    188.     cmp rax, 0
    189.     jle .close_client
    190.  
    191.     ; Сохраняем количество прочитанных байт
    192.     mov qword [bytes_read], rax
    193.  
    194.     ; ============================================
    195.     ; Отвечаем клиенту (echo с префиксом)
    196.     ; ============================================
    197.     syscall write, [client_fd], msg_echo, msg_echo_len
    198.  
    199.     ; Отправляем ТОЛЬКО реально полученные байты
    200.     mov rdx, qword [bytes_read]
    201.     syscall write, [client_fd], buffer, rdx
    202.  
    203.     syscall write, [client_fd], newline, 1
    204.  
    205.     ; Прощаемся
    206.     syscall write, [client_fd], msg_goodbye, msg_goodbye_len
    207.  
    208. .close_client:
    209.     ; Закрываем клиентский сокет
    210.     syscall close, [client_fd]
    211.     jmp .main_loop
    212.  
    213. .error_setsockopt:
    214.     syscall write, 1, msg_error_setsockopt, msg_error_setsockopt_len
    215.     jmp .error_exit
    216.  
    217. .error_bind:
    218.     syscall write, 1, msg_error_bind, msg_error_bind_len
    219.     jmp .error_exit
    220.  
    221. .error_listen:
    222.     syscall write, 1, msg_error_listen, msg_error_listen_len
    223.     jmp .error_exit
    224.  
    225. .error_exit:
    226.     syscall exit, 1
    227.  
    228.     ret
    229.  
    230. endproc
     
  4. Application

    Application Moderator Команда форума

    Публикаций:
    1
    Регистрация:
    8 дек 2007
    Сообщения:
    988
    С обработкой IAC и мультиплексированием.
    Код (ASM):
    1. ;;
    2. ;; Telnet server на NASM
    3. ;; Поддерживает:
    4. ;; - Множественные соединения через poll()
    5. ;; - Обработку Telnet IAC команд
    6. ;; - Неблокирующие сокеты
    7. ;; - Корректный echo
    8. ;;
    9.  
    10. %include '/home/user/Desktop/nasmx/inc/nasmx.inc'
    11. %include '/home/user/Desktop/nasmx/inc/linux/libc.inc'
    12. %include '/home/user/Desktop/nasmx/inc/linux/syscall.inc'
    13.  
    14. ; Константы
    15. POLLIN      equ 1
    16. POLLOUT     equ 4
    17. POLLERR     equ 8
    18. POLLHUP     equ 16
    19. POLLNVAL    equ 32
    20.  
    21. SOCK_STREAM equ 1
    22. AF_INET     equ 2
    23. SOL_SOCKET  equ 1
    24. SO_REUSEADDR equ 2
    25.  
    26. ; TELNET команды
    27. IAC         equ 255
    28. WILL        equ 251
    29. WONT        equ 252
    30. DO          equ 253
    31. DONT        equ 254
    32. SB          equ 250
    33. SE          equ 240
    34. LINEMODE    equ 34
    35. ECHO        equ 1
    36.  
    37. ; Максимальное количество клиентов
    38. MAX_CLIENTS equ 64
    39.  
    40. ; Структуры
    41. struc sockaddr_in
    42.     .sin_family resw 1
    43.     .sin_port   resw 1
    44.     .sin_addr   resd 1
    45.     .sin_zero   resb 8
    46. endstruc
    47.  
    48. struc pollfd
    49.     .fd      resd 1
    50.     .events  resw 1
    51.     .revents resw 1
    52. endstruc
    53.  
    54. struc client
    55.     .fd        resd 1
    56.     .state     resd 1     ; 0 = свободен, 1 = активен
    57.     .buffer    resb 4096
    58.     .buf_len   resq 1
    59.     .echo_on   resd 1
    60. endstruc
    61.  
    62. entry begin
    63.  
    64. [SECTION .data]
    65.  
    66. ; Адрес для привязки (порт 2323)
    67. tcs_so istruc sockaddr_in
    68.     at sockaddr_in.sin_family, dw AF_INET
    69.     at sockaddr_in.sin_port,   dw 0x1309    ; 2323 в network byte order
    70.     at sockaddr_in.sin_addr,   dd 0         ; INADDR_ANY
    71.     at sockaddr_in.sin_zero,   dd 0, 0
    72. iend
    73.  
    74. sockaddr_in_size equ $ - tcs_so
    75.  
    76. ; Структуры pollfd для всех сокетов
    77. ; Первая - слушающий сокет, остальные - клиенты
    78. fds:
    79.     istruc pollfd
    80.         at pollfd.fd,      dd 0
    81.         at pollfd.events,  dw POLLIN
    82.         at pollfd.revents, dw 0
    83.     iend
    84.     times MAX_CLIENTS istruc pollfd
    85.         at pollfd.fd,      dd 0
    86.         at pollfd.events,  dw POLLIN
    87.         at pollfd.revents, dw 0
    88.     iend
    89.  
    90. fds_size equ $ - fds
    91. fds_count equ (MAX_CLIENTS + 1)
    92.  
    93. ; TELNET negotiation
    94. telnet_negotiation db IAC, DO, LINEMODE
    95. telnet_negotiation_size equ $ - telnet_negotiation
    96.  
    97. telnet_subneg db IAC, SB, LINEMODE, 1, 1, IAC, SE
    98. telnet_subneg_size equ $ - telnet_subneg
    99.  
    100. telnet_will_echo db IAC, WILL, ECHO
    101. telnet_will_echo_size equ $ - telnet_will_echo
    102.  
    103. telnet_wont_echo db IAC, WONT, ECHO
    104. telnet_wont_echo_size equ $ - telnet_wont_echo
    105.  
    106. ; Сообщения
    107. msg_start db "Telnet server started on port 2323", 10, 0
    108. msg_start_len equ $ - msg_start
    109.  
    110. msg_connect db "Client connected! (", 0
    111. msg_connect_len equ $ - msg_connect
    112. msg_connect_end db ")", 10, 0
    113. msg_connect_end_len equ $ - msg_connect_end
    114.  
    115. msg_disconnect db "Client disconnected", 10, 0
    116. msg_disconnect_len equ $ - msg_disconnect
    117.  
    118. msg_prompt db "> ", 0
    119. msg_prompt_len equ $ - msg_prompt
    120.  
    121. msg_goodbye db "Goodbye!", 10, 0
    122. msg_goodbye_len equ $ - msg_goodbye
    123.  
    124. msg_error_bind db "Bind error!", 10, 0
    125. msg_error_bind_len equ $ - msg_error_bind
    126.  
    127. msg_error_listen db "Listen error!", 10, 0
    128. msg_error_listen_len equ $ - msg_error_listen
    129.  
    130. msg_error_setsockopt db "Setsockopt error!", 10, 0
    131. msg_error_setsockopt_len equ $ - msg_error_setsockopt
    132.  
    133. newline db 10, 0
    134.  
    135. [SECTION .bss]
    136.  
    137. reuseaddr_val resd 1
    138. nonblock_val  resd 1
    139. clients resb MAX_CLIENTS * client_size
    140. client_size equ $ - clients
    141.  
    142. [SECTION .text]
    143.  
    144. .begin:
    145.     push rbp
    146.     mov rbp, rsp
    147.     call main_proc
    148.     pop rbp
    149.     ret
    150.  
    151. proc main_proc
    152. locals none
    153.  
    154.     ; Вывод сообщения о запуске
    155.     syscall write, 1, msg_start, msg_start_len
    156.  
    157.     ; Создание сокета
    158.     syscall socket, AF_INET, SOCK_STREAM, 0
    159.     cmp rax, 0
    160.     jl .error_exit
    161.     mov r13, rax
    162.  
    163.     ; SO_REUSEADDR
    164.     mov dword [reuseaddr_val], SO_REUSEADDR
    165.     syscall setsockopt, r13, SOL_SOCKET, SO_REUSEADDR, reuseaddr_val, 4
    166.     cmp rax, 0
    167.     jl .error_setsockopt
    168.  
    169.     ; Привязка
    170.     syscall bind, r13, tcs_so, sockaddr_in_size
    171.     cmp rax, 0
    172.     jl .error_bind
    173.  
    174.     ; Слушаем
    175.     syscall listen, r13, 4096
    176.     cmp rax, 0
    177.     jl .error_listen
    178.  
    179.     ; Неблокирующий режим для слушающего сокета
    180.     mov dword [nonblock_val], 1
    181.     syscall ioctl, r13, 0x5421, nonblock_val
    182.     cmp rax, 0
    183.     jl .error_exit
    184.  
    185.     ; Сохраняем fd в pollfd
    186.     mov dword [fds + 0], r13d
    187.  
    188. .main_loop:
    189.  
    190.     ; Ожидание событий (таймаут 100 мс)
    191.     syscall poll, fds, fds_count, 100
    192.     cmp rax, 0
    193.     jle .main_loop
    194.  
    195.     ; Проверяем слушающий сокет
    196.     test word [fds + pollfd.revents], POLLIN
    197.     jz .check_clients
    198.  
    199.     ; Принимаем новое соединение
    200.     call accept_client
    201.     cmp rax, 0
    202.     jl .check_clients
    203.  
    204.     ; Добавляем клиента в pollfd
    205.     call add_client_to_poll
    206.     jmp .main_loop
    207.  
    208. .check_clients:
    209.     ; Проверяем всех клиентов
    210.     xor rbx, rbx
    211.     mov rcx, MAX_CLIENTS
    212.  
    213. .check_clients_loop:
    214.     cmp rcx, 0
    215.     je .main_loop
    216.  
    217.     ; Вычисляем смещение в массиве pollfd (первый клиент начинается с 1)
    218.     mov rax, rbx
    219.     inc rax
    220.     mov rdx, pollfd_size
    221.     mul rdx
    222.     add rax, fds
    223.  
    224.     mov r8, rax  ; Сохраняем указатель на pollfd
    225.  
    226.     ; Проверяем revents
    227.     test word [r8 + pollfd.revents], POLLIN
    228.     jz .next_client
    229.  
    230.     ; Проверяем на закрытие соединения
    231.     test word [r8 + pollfd.revents], POLLHUP
    232.     jnz .close_client
    233.  
    234.     ; Получаем fd клиента
    235.     mov eax, [r8 + pollfd.fd]
    236.     mov [client_fd], eax
    237.  
    238.     ; Читаем данные
    239.     call handle_client_data
    240.     cmp rax, 0
    241.     je .main_loop
    242.  
    243.     ; Если клиент закрыл соединение
    244.     call close_client
    245.  
    246. .next_client:
    247.     inc rbx
    248.     dec rcx
    249.     jmp .check_clients_loop
    250.  
    251. .close_client:
    252.     ; Закрываем клиента
    253.     call close_client
    254.     jmp .next_client
    255.  
    256.     ret
    257.  
    258. ; ============================================
    259. ; Принять новое соединение
    260. ; ============================================
    261. proc accept_client
    262. locals none
    263.  
    264.     syscall accept, r13, 0, 0
    265.     cmp rax, 0
    266.     jl .error
    267.  
    268.     ; Сохраняем fd клиента
    269.     mov [client_fd], eax
    270.  
    271.     ; Выводим сообщение
    272.     syscall write, 1, msg_connect, msg_connect_len
    273.  
    274.     ; Отправляем Telnet negotiation
    275.     syscall write, [client_fd], telnet_negotiation, telnet_negotiation_size
    276.     syscall write, [client_fd], telnet_subneg, telnet_subneg_size
    277.     syscall write, [client_fd], telnet_will_echo, telnet_will_echo_size
    278.  
    279.     ; Отправляем приветствие
    280.     syscall write, [client_fd], newline, 1
    281.     syscall write, [client_fd], msg_prompt, msg_prompt_len
    282.  
    283.     mov rax, 0
    284.     ret
    285.  
    286. .error:
    287.     mov rax, -1
    288.     ret
    289.  
    290. endproc
    291.  
    292. ; ============================================
    293. ; Добавить клиента в pollfd
    294. ; ============================================
    295. proc add_client_to_poll
    296. locals none
    297.  
    298.     ; Ищем свободный слот
    299.     xor rbx, rbx
    300.     mov rcx, MAX_CLIENTS
    301.  
    302. .find_free:
    303.     cmp rcx, 0
    304.     je .no_free
    305.  
    306.     ; Вычисляем смещение
    307.     mov rax, rbx
    308.     inc rax
    309.     mov rdx, pollfd_size
    310.     mul rdx
    311.     add rax, fds
    312.  
    313.     ; Проверяем, свободен ли слот
    314.     cmp dword [rax + pollfd.fd], 0
    315.     je .found_free
    316.  
    317.     inc rbx
    318.     dec rcx
    319.     jmp .find_free
    320.  
    321. .found_free:
    322.     ; Заполняем pollfd
    323.     mov eax, [client_fd]
    324.     mov [rax + pollfd.fd], eax
    325.     mov word [rax + pollfd.events], POLLIN
    326.     mov word [rax + pollfd.revents], 0
    327.  
    328.     ; Устанавливаем неблокирующий режим для клиента
    329.     mov dword [nonblock_val], 1
    330.     syscall ioctl, [client_fd], 0x5421, nonblock_val
    331.  
    332.     ; Инициализируем структуру клиента
    333.     mov rdx, client_size
    334.     mov rax, rbx
    335.     mul rdx
    336.     add rax, clients
    337.  
    338.     ; Сохраняем fd
    339.     mov edx, [client_fd]
    340.     mov [rax + client.fd], edx
    341.  
    342.     ; Сбрасываем состояние
    343.     mov dword [rax + client.state], 1
    344.     mov dword [rax + client.echo_on], 1
    345.     mov qword [rax + client.buf_len], 0
    346.  
    347.     mov rax, 0
    348.     ret
    349.  
    350. .no_free:
    351.     syscall write, 1, "No free slots!", 14
    352.     mov rax, -1
    353.     ret
    354.  
    355. endproc
    356.  
    357. ; ============================================
    358. ; Обработать данные от клиента
    359. ; ============================================
    360. proc handle_client_data
    361. locals none
    362.  
    363.     ; Сохраняем fd клиента
    364.     mov ebx, [client_fd]
    365.  
    366.     ; Читаем данные
    367.     syscall read, ebx, buffer, 4096
    368.     cmp rax, 0
    369.     jle .error
    370.  
    371.     ; Сохраняем количество байт
    372.     mov r12, rax
    373.  
    374.     ; Обрабатываем Telnet IAC команды
    375.     ; Упрощённо: пропускаем все IAC команды
    376.     xor r14, r14
    377.     xor r15, r15
    378.     mov rsi, buffer
    379.     mov rcx, r12
    380.  
    381. .parse_loop:
    382.     cmp rcx, 0
    383.     je .parse_done
    384.  
    385.     ; Читаем байт
    386.     mov al, [rsi]
    387.  
    388.     ; Проверяем IAC
    389.     cmp al, IAC
    390.     jne .not_iac
    391.  
    392.     ; Пропускаем IAC и следующий байт
    393.     inc rsi
    394.     dec rcx
    395.     cmp rcx, 0
    396.     je .parse_done
    397.  
    398.     ; Проверяем, не SB ли это
    399.     mov al, [rsi]
    400.     cmp al, SB
    401.     jne .skip_one
    402.  
    403.     ; Пропускаем SB до SE
    404.     inc rsi
    405.     dec rcx
    406.  
    407. .skip_subneg:
    408.     cmp rcx, 0
    409.     je .parse_done
    410.  
    411.     mov al, [rsi]
    412.     inc rsi
    413.     dec rcx
    414.  
    415.     cmp al, IAC
    416.     jne .skip_subneg
    417.  
    418.     ; Проверяем SE
    419.     cmp rcx, 0
    420.     je .parse_done
    421.  
    422.     mov al, [rsi]
    423.     cmp al, SE
    424.     jne .skip_subneg
    425.  
    426.     ; Пропускаем SE
    427.     inc rsi
    428.     dec rcx
    429.     jmp .parse_loop
    430.  
    431. .skip_one:
    432.     ; Пропускаем ещё один байт
    433.     inc rsi
    434.     dec rcx
    435.     jmp .parse_loop
    436.  
    437. .not_iac:
    438.     ; Сохраняем обычный байт
    439.     mov [reply_buff + r15], al
    440.     inc r15
    441.  
    442.     inc rsi
    443.     dec rcx
    444.     jmp .parse_loop
    445.  
    446. .parse_done:
    447.     ; Если есть обычные данные - отправляем echo
    448.     cmp r15, 0
    449.     je .no_data
    450.  
    451.     ; Отправляем echo
    452.     syscall write, ebx, reply_buff, r15
    453.     syscall write, ebx, newline, 1
    454.     syscall write, ebx, msg_prompt, msg_prompt_len
    455.  
    456. .no_data:
    457.     mov rax, 0
    458.     ret
    459.  
    460. .error:
    461.     mov rax, -1
    462.     ret
    463.  
    464. endproc
    465.  
    466. ; ============================================
    467. ; Закрыть клиента
    468. ; ============================================
    469. proc close_client
    470. locals none
    471.  
    472.     ; Отправляем прощание
    473.     syscall write, [client_fd], msg_goodbye, msg_goodbye_len
    474.  
    475.     ; Закрываем сокет
    476.     syscall close, [client_fd]
    477.  
    478.     ; Очищаем pollfd
    479.     mov edx, [client_fd]
    480.     mov dword [fds + pollfd.fd], 0
    481.  
    482.     ; Выводим сообщение
    483.     syscall write, 1, msg_disconnect, msg_disconnect_len
    484.  
    485.     mov rax, 0
    486.     ret
    487.  
    488. endproc
    489.  
    490. .error_setsockopt:
    491.     syscall write, 1, msg_error_setsockopt, msg_error_setsockopt_len
    492.     jmp .error_exit
    493.  
    494. .error_bind:
    495.     syscall write, 1, msg_error_bind, msg_error_bind_len
    496.     jmp .error_exit
    497.  
    498. .error_listen:
    499.     syscall write, 1, msg_error_listen, msg_error_listen_len
    500.     jmp .error_exit
    501.  
    502. .error_exit:
    503.     syscall exit, 1
    504.  
    505. endproc
     
  5. Application

    Application Moderator Команда форума

    Публикаций:
    1
    Регистрация:
    8 дек 2007
    Сообщения:
    988
    Упрощённая версия (без IAC парсера).
    Код (ASM):
    1. ; Минимальный echo-сервер с поддержкой нескольких клиентов
    2. ; (без обработки Telnet команд)
    3.  
    4. %include '/home/user/Desktop/nasmx/inc/nasmx.inc'
    5. %include '/home/user/Desktop/nasmx/inc/linux/libc.inc'
    6. %include '/home/user/Desktop/nasmx/inc/linux/syscall.inc'
    7.  
    8. POLLIN equ 1
    9. MAX_CLIENTS equ 64
    10.  
    11. struc sockaddr_in
    12.     .sin_family resw 1
    13.     .sin_port   resw 1
    14.     .sin_addr   resd 1
    15.     .sin_zero   resb 8
    16. endstruc
    17.  
    18. struc pollfd
    19.     .fd      resd 1
    20.     .events  resw 1
    21.     .revents resw 1
    22. endstruc
    23.  
    24. entry begin
    25.  
    26. [SECTION .data]
    27. tcs_so istruc sockaddr_in
    28.     at sockaddr_in.sin_family, dw 2
    29.     at sockaddr_in.sin_port,   dw 0x1309
    30.     at sockaddr_in.sin_addr,   dd 0
    31.     at sockaddr_in.sin_zero,   dd 0, 0
    32. iend
    33.  
    34. sockaddr_in_size equ $ - tcs_so
    35.  
    36. fds:
    37.     istruc pollfd
    38.         at pollfd.fd,      dd 0
    39.         at pollfd.events,  dw POLLIN
    40.         at pollfd.revents, dw 0
    41.     iend
    42.     times MAX_CLIENTS istruc pollfd
    43.         at pollfd.fd,      dd 0
    44.         at pollfd.events,  dw POLLIN
    45.         at pollfd.revents, dw 0
    46.     iend
    47.  
    48. fds_count equ MAX_CLIENTS + 1
    49.  
    50. msg_start db "Echo server on port 2323", 10, 0
    51. msg_start_len equ $ - msg_start
    52.  
    53. [SECTION .bss]
    54. client_fd resd 1
    55. buffer resb 4096
    56.  
    57. [SECTION .text]
    58. .begin:
    59.     push rbp
    60.     mov rbp, rsp
    61.     call main_proc
    62.     pop rbp
    63.     ret
    64.  
    65. proc main_proc
    66.     syscall write, 1, msg_start, msg_start_len
    67.  
    68.     syscall socket, 2, 1, 0
    69.     mov r13, rax
    70.  
    71.     syscall bind, r13, tcs_so, sockaddr_in_size
    72.     syscall listen, r13, 4096
    73.  
    74.     mov dword [fds + 0], r13d
    75.  
    76. .main_loop:
    77.     syscall poll, fds, fds_count, 100
    78.  
    79.     ; Проверяем слушающий сокет
    80.     test word [fds + pollfd.revents], POLLIN
    81.     jz .check_clients
    82.  
    83.     syscall accept, r13, 0, 0
    84.     cmp rax, 0
    85.     jl .check_clients
    86.     mov [client_fd], eax
    87.  
    88.     ; Добавляем в poll
    89.     call add_client
    90.  
    91. .check_clients:
    92.     ; Проверяем всех клиентов
    93.     xor rbx, rbx
    94.     mov rcx, MAX_CLIENTS
    95.  
    96. .check_loop:
    97.     cmp rcx, 0
    98.     je .main_loop
    99.  
    100.     mov rax, rbx
    101.     inc rax
    102.     mov rdx, pollfd_size
    103.     mul rdx
    104.     add rax, fds
    105.  
    106.     test word [rax + pollfd.revents], POLLIN
    107.     jz .next
    108.  
    109.     mov eax, [rax + pollfd.fd]
    110.     cmp eax, 0
    111.     je .next
    112.  
    113.     syscall read, eax, buffer, 4096
    114.     cmp rax, 0
    115.     jle .remove
    116.  
    117.     mov r12, rax
    118.     syscall write, eax, buffer, r12
    119.  
    120. .next:
    121.     inc rbx
    122.     dec rcx
    123.     jmp .check_loop
    124.  
    125. .remove:
    126.     syscall close, eax
    127.     ; Очищаем pollfd (упрощённо)
    128.  
    129.     jmp .next
    130. endproc
    131.  
    132. proc add_client
    133.     xor rbx, rbx
    134.     mov rcx, MAX_CLIENTS
    135.  
    136. .find_free:
    137.     cmp rcx, 0
    138.     je .done
    139.  
    140.     mov rax, rbx
    141.     inc rax
    142.     mov rdx, pollfd_size
    143.     mul rdx
    144.     add rax, fds
    145.  
    146.     cmp dword [rax + pollfd.fd], 0
    147.     je .found
    148.  
    149.     inc rbx
    150.     dec rcx
    151.     jmp .find_free
    152.  
    153. .found:
    154.     mov edx, [client_fd]
    155.     mov [rax + pollfd.fd], edx
    156.     mov word [rax + pollfd.events], POLLIN
    157.  
    158. .done:
    159.     ret
    160. endproc
     
  6. Orbit

    Orbit Member

    Публикаций:
    0
    Регистрация:
    13 дек 2016
    Сообщения:
    114
    Адрес:
    г. Москва
    Что там полноценного? Как вы его собирали если там одни ошибки? ИИ Вам это выдала? DO определяется как макрос как минимум и тд...
     
  7. Application

    Application Moderator Команда форума

    Публикаций:
    1
    Регистрация:
    8 дек 2007
    Сообщения:
    988
    Это примерная схема. Наивно ждать, что вам кто-то готовый код в прод бесплатно напишет.