Сеть низкого уровня в ассемблере (совместимая с x86)

Я хочу написать загрузочную программу на ассемблере, которая была бы способна отправлять и получать сетевые пакеты. Я не хочу использовать какие-либо библиотеки, я хотел бы создать все это сам (и учиться при этом). К сожалению, мне не удалось найти какую-либо информацию относительно связи с сетевой картой на самом низком уровне (отправка необработанных сокетов). Я считаю, что необходимо использовать OUT а также IN инструкции, хотя я не смог найти никакой информации о порте, который назначен сетевой карте (или как найти его, если он не всегда одинаков). Кто-нибудь может указать мне правильное направление?;-)

3 ответа

Это довольно большая проблема для решения. Даже получение "сырых сокетов" будет довольно трудоемким.

Во-первых, в современном BIOS ваша сетевая карта обычно не конфигурируется по умолчанию, поэтому вам нужно иметь дело с конфигурацией PCI, чтобы настроить ее на наличие портов, видимых для процессора. Это даст вам базовую возможность заставить процессор фактически общаться с сетевой картой.

Во-вторых, вам нужно будет найти некоторую документацию по конкретному чипсету, который он использует, чтобы вы знали, как читать и записывать сетевые данные. С некоторыми старыми картами это было довольно легко, но большинство новых карт действуют как мастера шины с аппаратным обеспечением разброса / сбора. Программирование их для выполнения даже простой передачи может быть нетривиальным. Это полностью зависит от оборудования, хотя.

В-третьих, вам потребуется разработать значительную часть стека IP, чтобы можно было использовать даже необработанные сокеты. На аппаратном уровне у вас в основном есть две возможности: принимать любые пакеты, которые поступают, и отправлять пакеты на указанные MAC-адреса - или другие аппаратные адреса, если ваша карта не (и не выглядит / не действует) как Ethernet.

Следующими двумя уровнями будут ARP-преобразователь (чтобы вы могли использовать IP-адреса вместо MAC-адресов) и DNS-клиент (так что вы можете использовать обычные имена адресов вместо чего-то вроде пунктирных квадратов). Возможно, вы захотите создать программное обеспечение, которое знает, как создавать / понимать дейтаграммы IP.

Разные сетевые карты имеют разные аппаратные интерфейсы (поэтому у них разные драйверы устройств).

Вы можете получить информацию об оборудовании от производителя устройства (или нет: они могут расценить это как конфиденциальную информацию и написать свои собственные драйверы устройств).

Вы также можете получить эту информацию, посмотрев исходный код сетевых карт с открытым исходным кодом: например, я думаю, для Linux; или, возможно, пакетные драйверы Crynwr.

В x86-64 Linux вы можете выполнять системные вызовы для использования необработанных сокетов.

      global _start

section .text:
_start:
    ;sys_socket: rax, 41
    mov rax,41 

    ;sys_socket inputs:
    ;%rdi    %rsi  %rdx
    ;family  type  protocol

    mov rdi,2  ;AF_INET 
    mov rsi,2  ;DGRAM Socket
    mov rdx,0  ;protocol
    syscall

    ;sys_sendto: rax, 44
    ; I will do this later because rax holds the file desc 

    ;sys_sendto inputs:
    ;%rdi       %rsi  %rdx    %r10   %r8   %r9
    ;file desc  buff  lenght  flags  addr  addr-lenght
    mov rdi,rax  ;file desc
    mov rax,44   ;sys_sendto
    mov rsi,msg  ;buff
    mov rdx,msgl ;length
    mov r8,addr  ;addr
    mov r9,16    ;remember htons()??? that's why 16
    syscall


section .data:
    msg: db "hello"
    msgl: equ $-msg
    ;addr
    addr: dw 2
      db 10h,00h  ;htons()
      db 7fh,0h,0h,01h
      db 0,0,0,0,0,0,0,0

Из обучающего видео:https://youtu.be/vOJoisKtR-A

Другие вопросы по тегам