Subversion Repositories Kolibri OS

Compare Revisions

No changes between revisions

Regard whitespace Rev 1205 → Rev 1206

/kernel/branches/net/network/udp.inc
14,7 → 14,7
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
$Revision: 983 $
$Revision$
 
 
struct UDP_Packet
44,7 → 44,6
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
UDP_init:
 
72,117 → 71,67
; OUT: /
;
;-----------------------------------------------------------------
 
align 4
UDP_handler:
 
DEBUGF 1,"UDP_Handler\n"
; TODO: First validate the header & checksum. Discard buffer if error
; TODO: First validate the header & checksum!
 
; Look for a socket where
; IP Packet UDP Destination Port = local Port
; IP Packet SA = Remote IP
 
mov esi, net_sockets
mov eax, net_sockets
.try_more:
mov ax , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
rol ax , 8
mov bx , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
.next_socket:
mov esi, [esi + SOCKET.NextPtr]
or esi, esi
mov eax, [eax + SOCKET.NextPtr]
or eax, eax
jz .dump
cmp [esi + SOCKET.Type], IP_PROTO_UDP
cmp [eax + SOCKET.Domain], AF_INET4
jne .next_socket
cmp [esi + SOCKET.LocalPort], ax
cmp [eax + SOCKET.Type], IP_PROTO_UDP
jne .next_socket
cmp [eax + SOCKET.LocalPort], bx
jne .next_socket
 
; For dhcp, we must allow any remote server to respond.
; I will accept the first incoming response to be the one
; I bind to, if the socket is opened with a destination IP address of
; 255.255.255.255
cmp [esi + SOCKET.RemoteIP], 0xffffffff
je @f
cmp [eax + SOCKET.RemoteIP], 0xffffffff
je .ok1
 
mov eax, [esp]
mov eax, [eax + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet
cmp [esi + SOCKET.RemoteIP], eax
mov ebx, [esp]
mov ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet
cmp [eax + SOCKET.RemoteIP], eax
jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
 
@@:
DEBUGF 1,"Found valid UDP packet for socket %x\n", esi
.ok1:
 
; sub ecx, UDP_Packet.Data ; get # of bytes in ecx
; mov eax, ecx
mov bx, [edx + UDP_Packet.SourcePort] ; Remote port must be 0, or equal to sourceport of packet
 
movzx ecx, [edx + UDP_Packet.Length]
xchg cl , ch
cmp [eax + SOCKET.RemotePort],0
je .ok2
 
; cmp ecx, eax ; If UDP packet size is bigger then IP packet told us,
; jg .error ; Something must went wrong!
cmp [eax + SOCKET.RemotePort], bx
jne .dump
 
lea ebx, [esi + SOCKET.lock]
call wait_mutex
.ok2:
 
; OK - we have a valid UDP Packet for this socket.
; First, update the sockets remote port number with the incoming msg
; - it will have changed
; from the original ( 69 normally ) to allow further connects
mov ax, [edx + UDP_Packet.SourcePort] ; get the UDP source port
xchg al, ah
mov [esi + SOCKET.RemotePort], ax
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
lea esi, [edx + UDP_Packet.Data]
movzx ecx, [edx + UDP_Packet.Length]
rol cx , 8
sub cx , UDP_Packet.Data
mov dx , bx
 
; Now, copy data to socket. We have socket address as [eax + sockets].
; We have IP Packet in edx
call socket_internal_receiver
 
add edx, UDP_Packet.Data
mov eax, [esi + SOCKET.rxDataCount] ; get # of bytes already in buffer
DEBUGF 1,"bytes in socket: %u ", eax
lea edi, [ecx + eax] ; check for buffer overflow
cmp edi, SOCKETBUFFSIZE - SOCKETHEADERSIZE ;
jg .dump ;
add [esi + SOCKET.rxDataCount], ecx ; increment the count of bytes in buffer
DEBUGF 1,"adding %u bytes\n", ecx
inc [UDP_PACKETS_RX]
 
; ecx has count, edx points to data
 
lea edi, [esi + eax + SOCKETHEADERSIZE]
push esi
push ecx
mov esi, edx
shr ecx, 2
rep movsd ; copy the data across
pop ecx
and ecx, 3
rep movsb
pop esi
 
DEBUGF 1,"UDP socket updated\n"
 
mov [esi + SOCKET.lock], 0
 
; flag an event to the application
mov eax, [esi + SOCKET.PID] ; get socket owner PID
mov ecx, 1
mov esi, TASK_DATA + TASKDATA.pid
 
.next_pid:
cmp [esi], eax
je .found_pid
inc ecx
add esi, 0x20
cmp ecx, [TASK_COUNT]
jbe .next_pid
 
jmp .dump
 
.found_pid:
shl ecx, 8
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
 
mov [check_idle_semaphore], 200
 
.dump:
DEBUGF 1,"UDP_handler - dumping\n"
 
DEBUGF 1,"Dumping UDP packet\n"
call kernel_free
add esp, 4 ; pop (balance stack)
 
205,7 → 154,7
 
UDP_create_packet:
 
DEBUGF 1,"Create UDP Packet\n"
DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
 
push edx esi
 
216,7 → 165,7
 
call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6
cmp edi, -1
je .exit
je .fail
 
mov byte[edi + UDP_Packet.Length], ch
mov byte[edi + UDP_Packet.Length+1], cl
234,17 → 183,15
pop edi
 
pop ecx
; bswap ecx ; convert little endian - big endian
; rol ecx, 16 ;
mov dword [edi + UDP_Packet.SourcePort], ecx ; notice: we write both port's at once
 
 
mov [edi + UDP_Packet.Checksum], 0
 
; TODO: calculate checksum using Pseudo-header (However, using a 0 as checksum shouldnt generate any errors :)
 
push ebx eax ; TODO: make this work on other protocols besides ethernet
mov ebx,edx ;
inc [UDP_PACKETS_TX]
 
push edx eax ; TODO: make this work on other protocols besides ethernet
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx ;
jmp ETH_Sender ;
 
251,8 → 198,13
.exit:
ret
 
.fail:
; todo: queue the packet
add esp, 8
ret
 
 
 
;---------------------------------------------------------------------------
;
; UDP_API
Property changes:
Added: svn:keywords
+Revision
\ No newline at end of property