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 |