⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ethernet.inc

📁 MenuetOS是一个用汇编开发的32/64位PC操作系统
💻 INC
📖 第 1 页 / 共 4 页
字号:
    jne     etx_002

    pop     eax
    call    freeBuff
    jmp     etx_exit

etx_002:
    ; There is no entry. Re queue the request, and ask ARP to send a request

    ; IP address is in edx
    push    edx
    call    arp_request
    pop     ebx

    ; Add an entry in the ARP table, awaiting response

    cmp     byte [NumARP], ARP_TABLE_SIZE
    je      etx_003            ; We cannot add a new entry in the table

    inc     byte [NumARP]

    movzx   eax, byte [NumARP]
    mov     ecx, ARP_ENTRY_SIZE
    mul     ecx
    sub     eax, ARP_ENTRY_SIZE

    mov     [eax + ARPTable], ebx
    xor     ebx, ebx
    mov     [eax + ARPTable + 4], ebx
    mov     [eax + ARPTable + 8], bx

    ; set the status field up - awaiting response
    mov     cl, 0x00
    mov     [eax + ARPTable + 10], cl
    mov     cl, 0x02
    mov     [eax + ARPTable + 11], cl

    ; Initialise the time to live field - 10s
    mov     cx, 0x000A
    mov     [eax + ARPTable + 12], cx

etx_003:
    pop     ebx                        ; Get the buffer back
    mov     eax, NET1OUT_QUEUE
    call    queue
    jmp     etx_exit

etx_send:
    xor     ecx, ecx
    mov     ch, [ebx+2]
    mov     cl, [ebx+3]          ; ; Size of IP packet to send

    mov     esi, ebx

    mov     edi, MACAddress

if DEBUGGING_STATE = DEBUGGING_ENABLED
    pusha
    mov     cx, 42
    mov     eax, 1                    ; Indicate that this is a tx packet
    call    eth_dump
    popa
end if

    mov     bx, ETHER_IP
    call    dword [drvr_transmit]       ; Call the drivers transmit function

    ; OK, we have sent a packet, so increment the count
    inc     dword [ip_tx_count]

    ; And finally, return the buffer to the free queue
    pop     eax
    call    freeBuff

etx_exit:
    ret

;***************************************************************************
;   Function
;      ether_IP_handler
;
;   Description
;      Called when an IP ethernet packet is received on the ethernet
;      Header + Data is in Ether_buffer[]
;      We just need to get a buffer from the 'free' queue, and
;      store the packet in it, then insert the packet number into the
;      IPRX queue.
;      If no queue entry is available, the packet is silently discarded
;      All registers may be destroyed
;
;***************************************************************************
ether_IP_handler:
    mov     eax, EMPTY_QUEUE
    call    dequeue
    cmp     ax, NO_BUFFER
    je      eiph00x

    ; convert buffer pointer eax to the absolute address
    push    eax
    mov     ecx, IPBUFFSIZE
    mul     ecx
    add     eax, IPbuffs

    mov     edi, eax

    ; get a pointer to the start of the DATA
    mov     esi, Ether_buffer + 14

    ; Now store it all away
    mov     ecx, IPBUFFSIZE / 4     ; Copy all of the available
                              ; data across - worse case
    cld
    rep     movsd

    ; And finally, place the buffer in the IPRX queue
    pop     ebx
    mov     eax, IPIN_QUEUE
    call    queue

eiph00x:
    ret

;***************************************************************************
;
;  ARP CODE FOLLOWS
;
;  The ARP code is used by ethernet drivers to translate an destination
;  IP address into an ethernet hardware address. Functions to broadcast
;  requests and handle response are (or will be) here.
;  The IP layer has no knowledge of ARP, as this is a network interface
;  issue
;
;***************************************************************************

;***************************************************************************
;   Function
;      arp_timer
;
;   Description
;      Called every 1s
;      It is responsible for removing expired routes
;      All registers may be destroyed
;
;***************************************************************************
arp_timer:
    ; loop through all the ARP entries, decrementing each one
    ; that doesn't have a TTL of 0xFFFF
    movzx   eax, byte [NumARP]

arp_001:
    cmp     eax, 0
    je      arp_003

    push    eax
    dec     eax
    mov     ecx, ARP_ENTRY_SIZE
    mul     ecx
    cmp     word [ eax + ARPTable + 12], 0xFFFF
    je      arp_002

    cmp     word [ eax + ARPTable + 12], 0
    je      arp_002

    dec     word [eax + ARPTable + 12]

arp_002:
    pop     eax
    dec     eax
    jmp     arp_001

    ; Now, look for entries with a TTL of 0
    ; Valid entries and response timeout entries get removed
    ; awaiting response gets converted into a response timeout, with a
    ; short life time - this allows queued packets to be flushed
arp_003:
    movzx   edx, byte [NumARP]
    cmp     edx, 0
    je      arp_exit

    ; EDX holds the # of entries to search through
    mov     eax, 0

arp_005:
    cmp     word [ eax + ARPTable + 12], 0
    jne     arp_004

    ; If it's status code is 0001 or 0003, delete the entry
    cmp     word [eax + ARPTable + 10], 0x0100
    je      arp_007
    cmp     word [eax + ARPTable + 10], 0x0300
    je      arp_007

    ; The only other valid code is 0002 - indicating a
    ; timeout while waiting for a response. Change the
    ; entry to response timed out

    mov     [eax + ARPTable + 10], word 0x0300
    mov     [eax + ARPTable + 12], word 0x000A
    jmp     arp_004

arp_007:
    ; Delete this entry
    mov     edi, ARPTable
    add     edi, eax
    mov     esi, edi
    add     esi, ARP_ENTRY_SIZE

    mov     ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
    sub     ecx, eax

    rep     movsb

    dec     byte [NumARP]
    jmp     arp_006

arp_004:
    add     eax, ARP_ENTRY_SIZE
arp_006:
    dec     edx
    cmp     edx, 0
    jne     arp_005

arp_exit:
    ret

;***************************************************************************
;   Function
;      arp_request
;
;   Description
;      Sends an ARP request on the ethernet
;        The requested IP address is in edx
;      All registers may be destroyed
;
;***************************************************************************
arp_request:
    mov     ebx, Ether_buffer
    mov     ax, 0x0100
    mov     [ebx], ax
    add     ebx, 2

    mov     ax, 0x0008
    mov     [ebx], ax
    add     ebx, 2

    mov     ax, 0x0406
    mov     [ebx], ax
    add     ebx, 2

    mov     ax, 0x0100
    mov     [ebx], ax
    add     ebx, 2

    mov     ecx, node_addr
    mov     eax, [ecx]
    mov     [ebx], eax
    add     ecx, 4
    add     ebx, 4
    mov     ax, [ecx]
    mov     [ebx], ax
    add     ebx, 2
    mov     eax, [stack_ip]
    mov     [ebx], eax
    add     ebx, 4

    xor     eax, eax
    mov     [ebx], eax
    add     ebx, 4
    mov     [ebx], ax

    add     ebx, 2
    mov     [ebx], edx

    ; Now, send it!

    ; Pointer to 48 bit destination address in edi
    ; Type of packet in bx
    ; size of packet in ecx
    ; pointer to packet data in esi
    mov      edi, broadcast_add

;if DEBUGGING_STATE = DEBUGGING_ENABLED
;    pusha
;    mov     eax, 1                    ; Indicate that this is a tx packet
;    mov     ecx, 28
;   mov      esi, Ether_buffer
;    call    eth_dump
;    popa
;end if

    mov     bx, ETHER_ARP
    mov     ecx, 28
    mov     esi, Ether_buffer
    call    dword [drvr_transmit]       ; Call the drivers transmit function
    ret

;***************************************************************************
;   Function
;      arp_handler
;
;   Description
;      Called when an ARP packet is received on the ethernet
;      Header + Data is in Ether_buffer[]
;       It looks to see if the packet is a request to resolve this Hosts
;       IP address. If it is, send the ARP reply packet.
;      This Hosts IP address is in dword [stack_ip]  ( in network format )
;       This Hosts MAC address is in node_addr[6]
;      All registers may be destroyed
;
;***************************************************************************
arp_handler:
    ; Is this a REQUEST?
    ; Is this a request for My Host IP
    ; Yes - So construct a response message.
    ; Send this message to the ethernet card for transmission

    mov     ebx, Ether_buffer

    mov     edx, ebx
    add     edx, 20
    mov     ax, [edx]
    cmp     ax, ARP_REQ_OPCODE      ; Is this a request packet?
    jne     arph_resp            ; No - so test for response

    mov     edx, ebx
    add     edx, 38
    mov     eax, [edx]

    cmp     eax, [stack_ip]         ; Is it looking for my IP address?
    jne     arph_exit            ; No - so quit now

    ; OK, it is a request for my MAC address. Build the frame and send it

    ; Save the important data from the original packet
    ; remote MAC address first
    mov     ecx, remote_hw_add
    mov     edx, ebx
    add     edx, 22               ; edx points to Source h/w address
    mov     eax, [edx]
    mov     [ecx], eax
    add     edx, 4
    add     ecx, 4
    mov     ax, [edx]
    mov     [ecx],ax

    ; and also the remote IP address
    add     edx, 2
    mov     eax,[edx]
    mov     [remote_ip_add], eax

    ; So now we can reuse the packet. ebx still holds the address of
    ; the header + packet
    ; We dont need the header ( first 14 bytes )

    mov     edx, ebx
    add     edx, 20
    mov     ax, ARP_REP_OPCODE
    mov     [edx], ax
    add     edx, 2

    mov     ecx, node_addr
    mov     eax, [ecx]
    mov     [edx], eax
    add     ecx, 4
    add     edx, 4
    mov     ax, [ecx]
    mov     [edx], ax
    add     edx, 2
    mov     eax, [stack_ip]
    mov     [edx], eax
    add     edx, 4
    mov     ecx, remote_hw_add
    mov     eax, [ecx]
    mov     [edx], eax
    add     ecx, 4
    add     edx, 4
    mov     ax, [ecx]
    mov     [edx], ax

    add     edx, 2
    mov     eax, [remote_ip_add]
    mov     [edx], eax

    ; Now, send it!

    ; Pointer to 48 bit destination address in edi
    ; Type of packet in bx
    ; size of packet in ecx
    ; pointer to packet data in esi
    mov     edi, remote_hw_add

;if DEBUGGING_STATE = DEBUGGING_ENABLED
;    pusha
;    mov     eax, 1                    ; Indicate that this is a tx packet
;    mov     ecx, 28
;   mov      esi, Ether_buffer + 14
 ;   call    eth_dump
;    popa
;end if

    mov     bx, ETHER_ARP
    mov     ecx, 28
    mov     esi, Ether_buffer + 14
    call    dword [drvr_transmit]       ; Call the drivers transmit function
    jmp     arph_exit

arph_resp:
    cmp     ax, ARP_REP_OPCODE      ; Is this a replypacket?
    jne     arph_resp            ; No - so quit

    ; This was a reply, probably directed at me.
    ; save the remotes MAC & IP
    mov     ecx, remote_hw_add
    mov     edx, ebx
    add     edx, 22               ; edx points to Source h/w address
    mov     eax, [edx]
    mov     [ecx], eax

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -