A lot of bugfixes in ARP, IPv4, UDP and sockets code.

git-svn-id: svn://kolibrios.org@1206 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr
2009-10-12 14:39:59 +00:00
parent 78ba1dbcaa
commit e39d270463
96 changed files with 1400 additions and 1264 deletions

View File

@@ -14,7 +14,7 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision: 1019 $
$Revision$
align 4
struct SOCKET
@@ -27,8 +27,8 @@ struct SOCKET
.Protocol dd ? ; ICMP/IPv4/ARP/
.LocalIP dd ? ; local IP address
.RemoteIP dd ? ; remote IP address
.LocalPort dw ? ; local port
.RemotePort dw ? ; remote port
.LocalPort dw ? ; local port (In INET byte order)
.RemotePort dw ? ; remote port (IN INET byte order
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
.rxDataCount dd ? ; rx data count
@@ -130,6 +130,7 @@ s_error:
; OUT: eax is socket num, -1 on error
;
;-----------------------------------------------
align 4
socket_open:
DEBUGF 1,"socket_open: domain: %u, type: %u",ecx, edx
@@ -162,7 +163,7 @@ socket_open:
; OUT: 0 on success
;
;-----------------------------------------------
align 4
socket_bind:
DEBUGF 1,"Socket_bind: socknum: %u sockaddr: %x, length: %u, ",ecx,edx,esi
@@ -175,51 +176,32 @@ socket_bind:
jl s_error
cmp word [edx], AF_INET4
je .af_inet4
jmp s_error
jne s_error
.af_inet4:
cmp esi, 6
jl s_error
mov ecx, [eax + SOCKET.Type]
mov bx, word [edx + 2]
rol bx,8 ;;;
DEBUGF 1,"local port: %u ",bx
DEBUGF 1,"local port: %x ",bx
test bx, bx
jnz .check_only
jz .find_free
mov bx , [last_UDP_port]
call socket_check_port
test bx, bx
je s_error
jmp .got_port
.find_port_loop:
inc bx
inc [last_UDP_port]
.find_free:
.check_only:
mov esi, net_sockets
call socket_find_port
test bx, bx
je s_error
.next_udp_socket:
mov esi, [esi + SOCKET.NextPtr]
or esi, esi
jz .udp_port_ok
cmp [esi + SOCKET.Type], IP_PROTO_UDP
jne .next_udp_socket
cmp [esi + SOCKET.LocalPort], bx
jne .next_udp_socket
cmp word [edx + 2], 0
jne s_error
cmp bx, MAX_EPHEMERAL_PORT
jle .find_port_loop
mov [last_UDP_port], MIN_EPHEMERAL_PORT
jmp s_error
.udp_port_ok:
.got_port:
DEBUGF 1,"using port: %x ",bx
mov word [eax + SOCKET.LocalPort], bx
mov ebx, dword [edx + 4]
@@ -246,7 +228,6 @@ socket_bind:
;
;-----------------------------------------------
align 4
socket_connect:
DEBUGF 1,"Socket_connect: socknum: %u sockaddr: %x, length: %u,",ecx,edx,esi
@@ -274,22 +255,19 @@ socket_connect:
cmp [eax + SOCKET.Type], IP_PROTO_ICMP
je .icmp
; cmp [eax + SOCKET.Type], IP_PROTO_TCP
; je .tcp
cmp [eax + SOCKET.Type], IP_PROTO_TCP
je .tcp
jmp s_error
.udp:
mov bx , word [edx + 2]
rol bx, 8
mov word [eax + SOCKET.RemotePort], bx
DEBUGF 1,"remote port: %u ",bx
DEBUGF 1,"remote port: %x ",bx
mov ebx, dword [edx + 4]
mov dword [eax + SOCKET.RemoteIP], ebx
DEBUGF 1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1
mov dword [esp+32],0
@@ -395,7 +373,7 @@ socket_connect:
; OUT: eax is socket num, -1 on error
;
;-----------------------------------------------
align 4
socket_listen:
DEBUGF 1,"Socket_listen: socknum: %u backlog: %u\n",ecx,edx
@@ -432,8 +410,7 @@ socket_listen:
; OUT: eax is socket num, -1 on error
;
;-----------------------------------------------
align 4
socket_accept:
DEBUGF 1,"Socket_accept: socknum: %u sockaddr: %x, length: %u\n",ecx,edx,esi
@@ -479,7 +456,7 @@ socket_accept:
; OUT: eax is socket num, -1 on error
;
;-----------------------------------------------
align 4
socket_close:
DEBUGF 1,"Socket_close: socknum: %u\n",ecx
@@ -495,8 +472,8 @@ socket_close:
cmp [eax + SOCKET.Type], IP_PROTO_ICMP
je .icmp
; cmp [eax + SOCKET.Type], IP_PROTO_TCP
; je .tcp
cmp [eax + SOCKET.Type], IP_PROTO_TCP
je .tcp
jmp s_error
@@ -629,7 +606,7 @@ end if
; OUT: eax is number of bytes copied, -1 on error
;
;-----------------------------------------------
align 4
socket_recv:
DEBUGF 1,"Socket_receive: socknum: %u sockaddr: %x, length: %u, flags: %x\n",ecx,edx,esi,edi
@@ -703,13 +680,13 @@ socket_recv:
;
;
; IN: socket number in ecx
; addr in edx
; addrlen in esi
; pointer to data in edx
; datalength in esi
; flags in edi
; OUT: -1 on error
;
;-----------------------------------------------
align 4
socket_send:
DEBUGF 1,"Socket_send: socknum: %u sockaddr: %x, length: %u, flags: %x, ",ecx,edx,esi,edi
@@ -718,6 +695,13 @@ socket_send:
or eax, eax
jz s_error
cmp word [eax + SOCKET.Domain], AF_INET4
je .af_inet4
jmp s_error
.af_inet4:
DEBUGF 1,"Socket type:%u\n", [eax + SOCKET.Type]:4
cmp [eax + SOCKET.Type], IP_PROTO_UDP
@@ -726,21 +710,30 @@ socket_send:
cmp [eax + SOCKET.Type], IP_PROTO_ICMP
je .icmp
; cmp [eax + SOCKET.Type], IP_PROTO_TCP
; je .tcp
cmp [eax + SOCKET.Type], IP_PROTO_TCP
je .tcp
jmp s_error
.udp:
DEBUGF 1,"type: UDP\n"
DEBUGF 1,"type: UDP, "
cmp [eax + SOCKET.LocalPort],0
jne .port_ok
mov ecx, [eax + SOCKET.Type]
call socket_find_port
test bx, bx
je s_error
mov [eax + SOCKET.LocalPort], bx
.port_ok:
mov ecx, esi
mov esi, edx
mov edx, dword [eax + SOCKET.LocalPort] ; load local port and remote port at once
DEBUGF 1,"local port: %u, remote port:%u\n",[eax + SOCKET.LocalPort]:2, [eax + SOCKET.RemotePort]:2
bswap edx ;;;
rol edx, 16 ;;;
DEBUGF 1,"local port: %x, remote port: %x\n",[eax + SOCKET.LocalPort]:2, [eax + SOCKET.RemotePort]:2
mov ebx, [eax + SOCKET.LocalIP]
mov eax, [eax + SOCKET.RemoteIP]
@@ -781,6 +774,173 @@ socket_send:
;-----------------------------------------------
;
; SOCKET_find_free_port (local port)
;
; works with INET byte order
;
; IN: type in ecx (TCP/UDP)
; OUT: bx = 0 on error, portnumber otherwise
;
;-----------------------------------------------
align 4
socket_find_port:
DEBUGF 1,"Socket_find_free_port, type: %u ",eax
cmp ecx, IP_PROTO_UDP
je .udp
cmp ecx, IP_PROTO_TCP
je .tcp
.udp:
mov bx, [last_UDP_port]
je .continue
.tcp:
mov bx, [last_TCP_port]
.continue:
inc bx
.check_only:
mov esi, net_sockets
.next_socket:
mov esi, [esi + SOCKET.NextPtr]
or esi, esi
jz .port_ok
cmp [esi + SOCKET.Type], ecx
jne .next_socket
rol bx, 8
cmp [esi + SOCKET.LocalPort], bx
rol bx, 8 ; this doesnt change the zero flag, does it ?
jne .next_socket
cmp bx, MAX_EPHEMERAL_PORT
jle .continue
; todo: WRAP!
; mov [last_UDP_port], MIN_EPHEMERAL_PORT
.exit:
xor ebx, ebx
.port_ok:
rol bx, 8
ret
;-----------------------------------------------
;
; SOCKET_check_port (local port)
;
; works with INET byte order
;
; IN: type in ecx (TCP/UDP)
; port to check in bx
; OUT: bx = 0 on error, unchanged otherwise
;
;-----------------------------------------------
align 4
socket_check_port:
mov esi, net_sockets
.next_socket:
mov esi, [esi + SOCKET.NextPtr]
or esi, esi
jz .port_ok
cmp [esi + SOCKET.Type], ecx
jne .next_socket
cmp [esi + SOCKET.LocalPort], bx
jne .next_socket
xor ebx, ebx
.port_ok:
ret
;-----------------------------------------------
;
; SOCKET_internal_receiver
;
; Checks if any socket wants the received data
; If so, update the socket
;
; IN: eax = socket number
; ecx = number of bytes
; esi = pointer to beginning of data
; dx = Remote port (in INET byte order)
; edi = IP address of sender
;
; OUT: xxx
;
;-----------------------------------------------
align 4
socket_internal_receiver:
DEBUGF 1,"internal socket receiver\n"
lea ebx, [eax + SOCKET.lock]
call wait_mutex
mov [eax + SOCKET.RemotePort], dx ; update remote port number
mov [eax + SOCKET.RemoteIP], edi
mov edx, [eax + SOCKET.rxDataCount] ; get # of bytes already in buffer
DEBUGF 1,"bytes already in socket: %u ", edx
lea edi, [ecx + edx] ; check for buffer overflow
cmp edi, SOCKETBUFFSIZE - SOCKETHEADERSIZE ;
jg .dump ;
lea edi, [eax + SOCKET.rxData + edx]
add [eax + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer
DEBUGF 1,"adding %u bytes\n", ecx
; copy the data across
push cx
shr ecx, 2
rep movsd
pop cx
and cx, 3
rep movsb
DEBUGF 1,"socket updated\n"
mov [eax + SOCKET.lock], 0
; flag an event to the application
mov edx, [eax + SOCKET.PID] ; get socket owner PID
mov ecx, 1
mov esi, TASK_DATA + TASKDATA.pid
.next_pid:
cmp [esi], edx
je .found_pid
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next_pid
ret
.found_pid:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
mov [check_idle_semaphore], 200
ret
.dump:
mov [eax + SOCKET.lock], 0
ret