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

📄 stack.inc

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

    ; 204 - return MAC high dword
    mov     eax, [ARPTmp+4]
    ret
    
notsis204:
    cmp     ebx, 205
    jnz     notsis205

    ; 205 - return MAC ls word
    movzx   eax, word [ARPTmp+8]
    ret
    
notsis205:
    cmp     ebx, 206
    jnz     notsis206

    ; 206 - return status word
    movzx   eax, word [ARPTmp+10]
    ret
    
notsis206:
    cmp     ebx, 207
    jnz     notsis207

    ; 207 - return ttl word
    movzx   eax, word [ARPTmp+12]
    ret
    
notsis207:
    cmp     ebx, 2
    jnz     notsis2
   
    ;  2 : return number of IP packets received
    mov     eax, [ip_rx_count]
    ret
   
notsis2:
    cmp     ebx, 3
    jnz     notsis3
   
    ;  3 : return number of packets transmitted
    mov     eax, [ip_tx_count]
    ret
   
notsis3:
    cmp     ebx, 4
    jnz     notsis4
   
    ;  4 : return number of received packets dumped
    mov     eax, [dumped_rx_count]
    ret
   
notsis4:
    cmp     ebx, 5
    jnz     notsis5
   
    ;  5 : return number of arp packets received
    mov     eax, [arp_rx_count]
    ret
   
notsis5:
    cmp     ebx, 6
    jnz     notsis6
   
    ;  6 : return status of packet driver
    ;  ( 0 == not active, FFFFFFFF = successful )
    mov     eax, [eth_status]
    ret
   
notsis6:
    xor     eax, eax
    ret



;***************************************************************************
;   Function
;      stack_get_packet
;
;   Description
;       extracts an IP packet from the NET1 output queue
;       and sends the data to the calling process
;       pointer to data in edx
;       returns number of bytes read in eax
;
;***************************************************************************
stack_get_packet:
    ; Look for a buffer to tx
    mov     eax, NET1OUT_QUEUE
    call    dequeue
    cmp     ax, NO_BUFFER
    je      sgp_non_exit            ; Exit if no buffer available

    push    eax                     ; Save buffer number for freeing at end
    
    push    edx
    ; convert buffer pointer eax to the absolute address
    mov     ecx, IPBUFFSIZE
    mul     ecx
    add     eax, IPbuffs
    pop     edx
    
    push    eax                     ; save address of IP data
    
    ; Get the address of the callers data
    mov     edi,[0x3010]
    add     edi,0x10
    add     edx,[edi]
    mov     edi, edx
   
    pop     eax
    
    mov     ecx, 1500           ; should get the actual number of bytes to write
    mov     esi, eax
    cld
    rep     movsb               ; copy the data across

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

    mov     eax, 1500
    ret

sgp_non_exit:
    xor     eax, eax
    ret



;***************************************************************************
;   Function
;      stack_insert_packet
;
;   Description
;       writes an IP packet into the stacks receive queue
;       # of bytes to write in ecx
;       pointer to data in edx
;       returns 0 in eax ok, -1 == failed 
;
;***************************************************************************
stack_insert_packet:

    mov     eax, EMPTY_QUEUE
    call    dequeue
    cmp     ax, NO_BUFFER
    je      sip_err_exit
    
    push    eax
    
    ; save the pointers to the data buffer & size
    push    edx
    push    ecx

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

    mov     edx, eax
   
    ; So, edx holds the IPbuffer ptr

    pop     ecx                     ; count of bytes to send
    mov     ebx, ecx                ; need the length later
    pop     eax                     ; get callers ptr to data to send
   
    ; Get the address of the callers data
    mov     edi,[0x3010]
    add     edi,0x10
    add     eax,[edi]
    mov     esi, eax
   
    mov     edi, edx
    cld
    rep     movsb               ; copy the data across

    pop     ebx

    mov     eax, IPIN_QUEUE
    call    queue

    inc     dword [ip_rx_count]

    mov     eax, 0
    ret
    
sip_err_exit:
    mov     eax, 0xFFFFFFFF
    ret

   
   
;***************************************************************************
;   Function
;      socket_open
;
;   Description
;       find a free socket
;       local port in ebx
;       remote port in ecx
;       remote ip in edx
;       return socket # in eax, -1 if none available
;
;***************************************************************************
socket_open:
    call    get_free_socket
   
    cmp     eax, 0xFFFFFFFF
    jz      so_exit
   
    ; ax holds the socket number that is free. Get real address
    push    eax
    shl     eax, 12
    add     eax, sockets
   
    mov     [eax], dword SOCK_OPEN
   
    mov     [eax + 12], byte bh      ; Local port ( LS 16 bits )
    mov     [eax + 13], byte bl      ; Local port ( LS 16 bits )
    mov     ebx, [stack_ip]
    mov     [eax + 8], ebx         ; Local IP
    mov     [eax + 20], ch         ; Remote Port ( LS 16 bits )
    mov     [eax + 21], cl         ; Remote Port ( LS 16 bits )
    mov     [eax + 16], edx         ; Remote IP ( in Internet order )
    mov     [eax + 24], dword 0      ; recieved data count
   
    mov     esi, [0x3010]
    mov     ebx, [esi+0x4]
    mov     [eax + 4], ebx         ; save the process ID
    pop     eax      ; Get the socket number back, so we can return it
   
so_exit:
    ret
   


;***************************************************************************
;   Function
;      socket_open_tcp
;
;   Description
;       Opens a TCP socket in PASSIVE or ACTIVE mode
;       find a free socket
;       local port in ebx ( intel format )
;       remote port in ecx ( intel format )
;       remote ip in edx ( in Internet byte order )
;       Socket open mode in esi  ( SOCKET_PASSIVE or SOCKET_ACTIVE )
;       return socket # in eax, -1 if none available
;
;***************************************************************************
socket_open_tcp:
    call    get_free_socket
   
    cmp     eax, 0xFFFFFFFF
    jz      so_exit
   
    ; ax holds the socket number that is free. Get real address
    push    eax
    shl     eax, 12
    add     eax, sockets

    mov     [sktAddr], eax
    mov     [eax], dword SOCK_OPEN
    
    ; TODO - check this works!
    mov     [eax + 72], dword 0     ; Reset the window timer.
   
    mov     [eax + 12], byte bh      ; Local port ( LS 16 bits )
    mov     [eax + 13], byte bl      ; Local port ( LS 16 bits )
    mov     ebx, [stack_ip]
    mov     [eax + 8], ebx         ; Local IP
    mov     [eax + 20], ch         ; Remote Port ( LS 16 bits )
    mov     [eax + 21], cl         ; Remote Port ( LS 16 bits )
    mov     [eax + 16], edx         ; Remote IP ( in Internet order )
    mov     [eax + 24], dword 0      ; recieved data count
   
    ; Now fill in TCB state
    mov     ebx, TCB_LISTEN
    cmp     esi, SOCKET_PASSIVE
    jz      sot_001
    mov     ebx, TCB_SYN_SENT

sot_001:
    mov     [eax + 28], ebx            ; Indicate the state of the TCB

    mov     esi, [0x3010]
    mov     ecx, [esi+0x4]
    mov     [eax + 4], ecx         ; save the process ID
      
    cmp     ebx, TCB_LISTEN
    je      sot_done    
    
    ; Now, if we are in active mode, then we have to send a SYN to the specified remote port
   
  
    mov     eax, EMPTY_QUEUE
    call    dequeue
    cmp     ax, NO_BUFFER
    je      sot_done
   
    push    eax
    
    mov     bl, 0x02        ; SYN
    mov     ecx, 0
    
    call    buildTCPPacket    
    
    mov     eax, NET1OUT_QUEUE

    mov     edx, [stack_ip]
    mov     ecx, [ sktAddr ]
    mov     ecx, [ ecx + 16 ]
    cmp     edx, ecx
    jne     sot_notlocal
    mov     eax, IPIN_QUEUE

sot_notlocal:
       ; Send it.
    pop     ebx
    call    queue

    mov     esi, [sktAddr]
    
    ; increment SND.NXT in socket
    add     esi, 48
    call    inc_inet_esi
     
sot_done:
    pop     eax      ; Get the socket number back, so we can return it
   
sot_exit:
    ret

   
   
;***************************************************************************
;   Function
;      socket_close
;
;   Description
;       socket # in ebx
;       returns 0 for ok, -1 for socket not open (fail)
;
;***************************************************************************
socket_close:
    shl     ebx, 12
    add     ebx, sockets
    mov     eax, 0xFFFFFFFF         ; assume this operation will fail..
    cmp     [ebx], dword SOCK_EMPTY
    jz      sc_exit
   
    ; Clear the socket varaibles
    xor     eax, eax
    mov     edi,ebx
    mov     ecx,SOCKETHEADERSIZE
    cld
    rep     stosb
   
sc_exit:
    ret
    
   

;***************************************************************************
;   Function
;      socket_close_tcp
;
;   Description
;       socket # in ebx
;       returns 0 for ok, -1 for socket not open (fail)
;
;***************************************************************************
socket_close_tcp:
    ; first, remove any resend entries
    pusha

    mov     esi, resendQ
    mov     ecx, 0
    
sct001:
    cmp     ecx, NUMRESENDENTRIES
    je      sct003              ; None left
    cmp     [esi], bl
    je      sct002              ; found one
    inc     ecx
    add     esi, 4
    jmp     sct001
    
sct002:
    dec     dword [arp_rx_count] ; ************ TEST ONLY!
    
    mov     [esi], byte 0xFF
    jmp     sct001

sct003:
    popa
    
    shl     ebx, 12
    add     ebx, sockets
    mov     [sktAddr], ebx
    mov     eax, 0xFFFFFFFF         ; assume this operation will fail..
    cmp     [ebx], dword SOCK_EMPTY
    jz      sct_exit

    ; Now construct the response, and queue for sending by IP
    mov     eax, EMPTY_QUEUE
    call    dequeue
    cmp     ax, NO_BUFFER
    je      stl_exit

    push    eax
    
    mov     bl, 0x11        ; FIN + ACK
    mov     ecx, 0
    mov     esi, 0
    
    call    buildTCPPacket
    
    mov     ebx, [sktAddr]   

    ; increament SND.NXT in socket
    mov     esi, 48
    add     esi, ebx
    call    inc_inet_esi


    ; Get the socket state
    mov     eax, [ebx + 28]
    cmp     eax, TCB_LISTEN
    je      destroyTCB
    cmp     eax, TCB_SYN_SENT
    je      destroyTCB
    cmp     eax, TCB_SYN_RECEIVED
    je      sct_finwait1
    cmp     eax, TCB_ESTABLISHED
    je      sct_finwait1
    
    ; assume CLOSE WAIT
    ; Send a fin, then enter last-ack state
    mov     eax, TCB_LAST_ACK
    mov     [ebx + 28], eax
    xor     eax, eax
    jmp     sct_send
       
sct_finwait1:
    ; Send a fin, then enter finwait2 state

⌨️ 快捷键说明

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