forked from KolibriOS/kolibrios
245 lines
8.0 KiB
PHP
245 lines
8.0 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 ;;
|
||
|
;; ;;
|
||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
|
||
|
$Revision$
|
||
|
|
||
|
|
||
|
; IP underlying protocols numbers
|
||
|
PROTOCOL_ICMP equ 1
|
||
|
PROTOCOL_TCP equ 6
|
||
|
PROTOCOL_UDP equ 17
|
||
|
|
||
|
struc IP_PACKET
|
||
|
{ .VersionAndIHL db ? ;+00 - Version[0-3 bits] and IHL(header length)[4-7 bits]
|
||
|
.TypeOfService db ? ;+01
|
||
|
.TotalLength dw ? ;+02
|
||
|
.Identification dw ? ;+04
|
||
|
.FlagsAndFragmentOffset dw ? ;+06 - Flags[0-2] and FragmentOffset[3-15]
|
||
|
.TimeToLive db ? ;+08
|
||
|
.Protocol db ? ;+09
|
||
|
.HeaderChecksum dw ? ;+10
|
||
|
.SourceAddress dd ? ;+12
|
||
|
.DestinationAddress dd ? ;+16
|
||
|
.DataOrOptional dd ? ;+20
|
||
|
}
|
||
|
|
||
|
virtual at 0
|
||
|
IP_PACKET IP_PACKET
|
||
|
end virtual
|
||
|
|
||
|
|
||
|
;*******************************************************************
|
||
|
; Interface
|
||
|
;
|
||
|
; ip_rx processes all packets received by the network layer
|
||
|
; It calls the appropriate protocol handler
|
||
|
;
|
||
|
;
|
||
|
;
|
||
|
;*******************************************************************
|
||
|
|
||
|
|
||
|
;
|
||
|
; IP Packet after reception - Normal IP packet format
|
||
|
;
|
||
|
; 0 1 2 3
|
||
|
; 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
|
||
|
;
|
||
|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
;0 |Version| IHL |Type of Service| Total Length |
|
||
|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
;4 | Identification |Flags| Fragment Offset |
|
||
|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
;8 | Time to Live | Protocol | Header Checksum |
|
||
|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
;12 | Source Address |
|
||
|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
;16 | Destination Address |
|
||
|
; +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||
|
;20 | Data |
|
||
|
; +-+-+-.......... -+
|
||
|
;
|
||
|
;
|
||
|
; [smb] attention! according to RFC 791 IP packet may have 'options' sections,
|
||
|
; so we can't simply think, that data have offset 20. We must calculate offset from
|
||
|
; IHL field
|
||
|
;
|
||
|
macro GET_IHL reg, header_addr
|
||
|
{
|
||
|
movzx reg, byte [header_addr]
|
||
|
|
||
|
; we need 4-7 bits, so....
|
||
|
and reg, 0x0000000F
|
||
|
|
||
|
; IHL keeps number of octets, so we need to << 2 'reg'
|
||
|
shl reg, 2
|
||
|
}
|
||
|
|
||
|
|
||
|
include "tcp.inc"
|
||
|
include "udp.inc"
|
||
|
include "icmp.inc"
|
||
|
|
||
|
;***************************************************************************
|
||
|
; Function
|
||
|
; ip_rx
|
||
|
;
|
||
|
; Description
|
||
|
; This is a kernel function, called by stack_handler
|
||
|
; Processes all IP-packets received by the network layer
|
||
|
; It calls the appropriate protocol handler
|
||
|
;
|
||
|
;***************************************************************************
|
||
|
proc ip_rx stdcall
|
||
|
local buffer_number dd ?
|
||
|
|
||
|
; Look for a buffer to tx
|
||
|
mov eax, IPIN_QUEUE
|
||
|
call dequeue
|
||
|
cmp ax, NO_BUFFER
|
||
|
je .exit ; Exit if no buffer available
|
||
|
|
||
|
mov [buffer_number], eax ;save buffer number
|
||
|
|
||
|
; convert buffer pointer eax to the absolute address
|
||
|
imul eax, IPBUFFSIZE
|
||
|
add eax, IPbuffs
|
||
|
|
||
|
mov ebx, eax ; ebx=pointer to IP_PACKET
|
||
|
|
||
|
; DEBUGF 1, "K : ip_rx - proto: %u\n", [ebx + IP_PACKET.Protocol]:1
|
||
|
|
||
|
; Validate the IP checksum
|
||
|
mov dx, word[ebx + IP_PACKET.HeaderChecksum]
|
||
|
xchg dh,dl ; Get the checksum in intel format
|
||
|
|
||
|
mov [ebx + IP_PACKET.HeaderChecksum], 0 ; clear checksum field - need to when
|
||
|
; recalculating checksum
|
||
|
; this needs two data pointers and two size #.
|
||
|
; 2nd pointer can be of length 0
|
||
|
|
||
|
GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx
|
||
|
stdcall checksum_jb, ebx, ecx ;buf_ptr, buf_size
|
||
|
cmp dx, ax
|
||
|
|
||
|
; DEBUGF 1, "K : ip_rx - checksums: %x - %x\n", dx, ax
|
||
|
|
||
|
jnz .dump.1 ;if CHECKSUM isn't valid then dump packet
|
||
|
mov edx, ebx ; EDX (IP-BUFFER POINTER) WILL BE USED FOR *_rx HANDLERS BELOW!!!
|
||
|
|
||
|
; DEBUGF 1, "K : ip_rx - dest: %x - %x\n", [ebx + IP_PACKET.DestinationAddress], [stack_ip]
|
||
|
|
||
|
; Validate the IP address, if it isn't broadcast
|
||
|
mov eax, [stack_ip]
|
||
|
cmp dword[ebx + IP_PACKET.DestinationAddress], eax
|
||
|
je @f
|
||
|
|
||
|
; If the IP address is 255.255.255.255, accept it
|
||
|
; - it is a broadcast packet, which we need for dhcp
|
||
|
|
||
|
mov eax, [ebx + IP_PACKET.DestinationAddress]
|
||
|
cmp eax, 0xffffffff
|
||
|
je @f
|
||
|
mov ecx, [stack_ip]
|
||
|
and eax, [subnet_mask]
|
||
|
and ecx, [subnet_mask]
|
||
|
cmp eax, ecx
|
||
|
jne .dump.2
|
||
|
mov eax, [ebx + IP_PACKET.DestinationAddress]
|
||
|
or eax, [subnet_mask]
|
||
|
cmp eax, 0xffffffff
|
||
|
jne .dump.2
|
||
|
|
||
|
@@:
|
||
|
mov al, [ebx + IP_PACKET.VersionAndIHL]
|
||
|
and al, 0x0f ;get IHL(header length)
|
||
|
cmp al, 0x05 ;if IHL!= 5*4(20 bytes)
|
||
|
; DEBUGF 1, "K : ip_rx - ihl: %x - 05\n", al
|
||
|
jnz .dump.3 ;then dump it
|
||
|
|
||
|
; DEBUGF 1, "K : ip_rx - ttl: %x - 00\n", [ebx + IP_PACKET.TimeToLive]:2
|
||
|
|
||
|
cmp [ebx + IP_PACKET.TimeToLive], 0
|
||
|
je .dump.4 ;if TTL==0 then dump it
|
||
|
|
||
|
mov ax, [ebx + IP_PACKET.FlagsAndFragmentOffset]
|
||
|
and ax, 0xFFBF ;get flags
|
||
|
; DEBUGF 1, "K : ip_rx - flags: %x - 0000\n", ax
|
||
|
cmp ax, 0 ;if some flags was set then we dump this packet
|
||
|
jnz .dump.5 ;the flags should be used for fragmented packets
|
||
|
|
||
|
; Check the protocol, and call the appropriate handler
|
||
|
; Each handler will re-use or free the queue buffer as appropriate
|
||
|
|
||
|
mov al, [ebx + IP_PACKET.Protocol]
|
||
|
|
||
|
cmp al , PROTOCOL_TCP
|
||
|
jne .not_tcp
|
||
|
; DEBUGF 1,"K : ip_rx - TCP packet\n"
|
||
|
mov eax, dword[buffer_number]
|
||
|
call tcp_rx
|
||
|
jmp .exit
|
||
|
|
||
|
.not_tcp:
|
||
|
cmp al, PROTOCOL_UDP
|
||
|
jne .not_udp
|
||
|
; DEBUGF 1,"K : ip_rx - UDP packet\n"
|
||
|
mov eax, dword[buffer_number]
|
||
|
call udp_rx
|
||
|
jmp .exit
|
||
|
|
||
|
.not_udp:
|
||
|
cmp al, PROTOCOL_ICMP
|
||
|
jne .dump.6 ;protocol ain't supported
|
||
|
|
||
|
; DEBUGF 1,"K : ip_rx - ICMP packet\n"
|
||
|
;GET_IHL ecx, ebx + IP_PACKET.VersionAndIHL ;get packet length in ecx
|
||
|
mov eax, dword[buffer_number]
|
||
|
stdcall icmp_rx,eax,ebx,ecx ;buffer_number,IPPacketBase,IPHeaderLength
|
||
|
jmp .exit
|
||
|
|
||
|
|
||
|
.dump.1:
|
||
|
DEBUGF 1, "K : ip_rx - dumped (checksum: 0x%x-0x%x)\n", dx, ax
|
||
|
jmp .dump.x
|
||
|
|
||
|
.dump.2:
|
||
|
DEBUGF 1, "K : ip_rx - dumped (ip: %u.%u.%u.%u)\n", [ebx + IP_PACKET.DestinationAddress + 0]:1, [ebx + IP_PACKET.DestinationAddress + 1]:1, [ebx + IP_PACKET.DestinationAddress + 2]:1, [ebx + IP_PACKET.DestinationAddress + 3]:1
|
||
|
jmp .dump.x
|
||
|
|
||
|
.dump.3:
|
||
|
DEBUGF 1, "K : ip_rx - dumped (ihl: %u)\n", al
|
||
|
jmp .dump.x
|
||
|
|
||
|
.dump.4:
|
||
|
DEBUGF 1, "K : ip_rx - dumped (ttl: %u)\n", [ebx + IP_PACKET.TimeToLive]
|
||
|
jmp .dump.x
|
||
|
|
||
|
.dump.5:
|
||
|
DEBUGF 1, "K : ip_rx - dumped (flags: 0x%x)\n", ax
|
||
|
jmp .dump.x
|
||
|
|
||
|
.dump.6:
|
||
|
DEBUGF 1, "K : ip_rx - dumped (proto: %u)\n", [ebx + IP_PACKET.Protocol]:1
|
||
|
|
||
|
.dump.x:
|
||
|
inc dword[dumped_rx_count]
|
||
|
mov eax, [buffer_number]
|
||
|
call freeBuff
|
||
|
|
||
|
.exit:
|
||
|
ret
|
||
|
endp
|
||
|
|