forked from KolibriOS/kolibrios
202 lines
5.6 KiB
PHP
202 lines
5.6 KiB
PHP
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
;; ;;
|
||
|
;; IP.INC ;;
|
||
|
;; ;;
|
||
|
;; IP Processes for Menuet OS TCP/IP stack ;;
|
||
|
;; ;;
|
||
|
;; Version 0.3 29 August 2002 ;;
|
||
|
;; ;;
|
||
|
;; Copyright 2002 Mike Hibbett, mikeh@oceanfree.net ;;
|
||
|
;; ;;
|
||
|
;; See file COPYING for details ;;
|
||
|
;; ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
|
||
|
|
||
|
;*******************************************************************
|
||
|
; Interface
|
||
|
;
|
||
|
; ip_rx processes all packets received by the network layer
|
||
|
; It calls the appropriate protocol handler
|
||
|
;
|
||
|
;
|
||
|
;
|
||
|
;*******************************************************************
|
||
|
|
||
|
|
||
|
;***************************************************************************
|
||
|
; Function
|
||
|
; ip_rx
|
||
|
;
|
||
|
; Description
|
||
|
; Handles received IP packets
|
||
|
; This is a kernel function, called by stack_handler
|
||
|
;
|
||
|
;***************************************************************************
|
||
|
ip_rx:
|
||
|
; Look for a buffer to tx
|
||
|
mov eax, IPIN_QUEUE
|
||
|
call dequeue
|
||
|
cmp ax, NO_BUFFER
|
||
|
je ipr_exit ; Exit if no buffer available
|
||
|
|
||
|
push eax
|
||
|
|
||
|
; convert buffer pointer eax to the absolute address
|
||
|
mov ecx, IPBUFFSIZE
|
||
|
mul ecx
|
||
|
add eax, IPbuffs
|
||
|
|
||
|
mov edx, eax ; Save the address in edx for use by future processes
|
||
|
|
||
|
; Validate the IP checksum
|
||
|
mov ebx, edx
|
||
|
mov ah, [ebx + 10]
|
||
|
mov al, [ebx + 11] ; Get the checksum in intel format
|
||
|
mov [ebx + 10], word 0 ; clear checksum field - need to when
|
||
|
; recalculating checksum
|
||
|
|
||
|
; this needs two data pointers and two size #.
|
||
|
; 2nd pointer can be of length 0
|
||
|
mov ebx, edx
|
||
|
mov [checkAdd1], ebx
|
||
|
mov [checkSize1], word 20
|
||
|
mov [checkAdd2], dword 0
|
||
|
mov [checkSize2], word 0
|
||
|
|
||
|
call checksum ; Recalculate IP checksum
|
||
|
cmp ax, [checkResult]
|
||
|
jnz ipr_dump
|
||
|
|
||
|
; If the IP address is 255.255.255.255, accept it
|
||
|
; - it is a broadcast packet, which we need for dhcp
|
||
|
mov eax, [edx + 16]
|
||
|
cmp eax, 0xffffffff
|
||
|
je ipr_p0
|
||
|
|
||
|
; Validate the IP address, if it isn't broadcast
|
||
|
cmp eax, [stack_ip]
|
||
|
jnz ipr_dump
|
||
|
|
||
|
ipr_p0:
|
||
|
mov al, [edx]
|
||
|
and al, 0x0f
|
||
|
cmp al, 0x05
|
||
|
jnz ipr_dump
|
||
|
|
||
|
cmp [edx+8], byte 0
|
||
|
jz ipr_dump
|
||
|
|
||
|
mov ax, [edx + 6]
|
||
|
and ax, 0xFFBF
|
||
|
cmp ax, 0
|
||
|
jnz ipr_dump
|
||
|
|
||
|
; Check the protocol, and call the appropriate handler
|
||
|
; Each handler will re-use or free the queue buffer as appropriate
|
||
|
mov al, [edx + 9]
|
||
|
cmp al , PROTOCOL_ICMP
|
||
|
jnz ipr_p1
|
||
|
pop eax
|
||
|
call icmp_rx
|
||
|
jmp ipr_exit
|
||
|
|
||
|
ipr_p1:
|
||
|
cmp al , PROTOCOL_TCP
|
||
|
jnz ipr_p2
|
||
|
pop eax
|
||
|
call tcp_rx
|
||
|
jmp ipr_exit
|
||
|
|
||
|
ipr_p2:
|
||
|
cmp al , PROTOCOL_UDP
|
||
|
jnz ipr_dump
|
||
|
pop eax
|
||
|
call udp_rx
|
||
|
jmp ipr_exit
|
||
|
|
||
|
ipr_dump:
|
||
|
; No protocol handler available, so
|
||
|
; silently dump the packet, freeing up the queue buffer
|
||
|
|
||
|
; inc dword [dumped_rx_count]
|
||
|
|
||
|
pop eax
|
||
|
call freeBuff
|
||
|
|
||
|
ipr_exit:
|
||
|
ret
|
||
|
|
||
|
|
||
|
|
||
|
;***************************************************************************
|
||
|
; Function
|
||
|
; icmp_rx
|
||
|
;
|
||
|
; Description
|
||
|
; ICMP protocol handler
|
||
|
; This is a kernel function, called by ip_rx
|
||
|
; edx contains the address of the buffer in use.
|
||
|
; This buffer must be reused or marked as empty afterwards
|
||
|
;
|
||
|
;***************************************************************************
|
||
|
icmp_rx:
|
||
|
cmp [edx + 20], byte 8 ; Is this an echo request? discard if not
|
||
|
jz icmp_echo
|
||
|
|
||
|
call freeBuff
|
||
|
jmp icmp_exit
|
||
|
|
||
|
icmp_echo:
|
||
|
push eax
|
||
|
mov [edx + 10], word 0 ; I think this was already done by IP rx
|
||
|
|
||
|
; swap the source and destination addresses
|
||
|
mov ecx, [edx + 16]
|
||
|
mov eax, [edx + 12]
|
||
|
mov [edx + 16], eax
|
||
|
mov [edx + 12], ecx
|
||
|
|
||
|
; recaluculate the IP header checksum
|
||
|
|
||
|
mov ebx, edx
|
||
|
mov [checkAdd1], ebx
|
||
|
mov [checkSize1], word 20
|
||
|
mov [checkAdd2], dword 0
|
||
|
mov [checkSize2], word 0
|
||
|
|
||
|
call checksum
|
||
|
mov ax, [checkResult]
|
||
|
mov [edx + 10], ah
|
||
|
mov [edx + 11], al ; ?? correct byte order?
|
||
|
|
||
|
mov [edx + 20], byte 0 ; change the request to a response
|
||
|
mov [edx + 22], word 0 ; clear ICMP checksum prior to re-calc
|
||
|
|
||
|
; Calculate the length of the ICMP data ( IP payload)
|
||
|
mov ah, [edx + 2]
|
||
|
mov al, [edx + 3]
|
||
|
sub ax, 20
|
||
|
|
||
|
mov [checkSize1], ax
|
||
|
mov ebx, edx
|
||
|
add ebx, 20
|
||
|
|
||
|
mov [checkAdd1], ebx
|
||
|
mov [checkAdd2], dword 0
|
||
|
mov [checkSize2], word 0
|
||
|
|
||
|
call checksum
|
||
|
|
||
|
mov ax, [checkResult]
|
||
|
mov [edx + 22], ah
|
||
|
mov [edx + 23], al
|
||
|
|
||
|
; Queue packet for transmission
|
||
|
|
||
|
pop ebx
|
||
|
mov eax, NET1OUT_QUEUE
|
||
|
call queue
|
||
|
|
||
|
icmp_exit:
|
||
|
ret
|