forked from KolibriOS/kolibrios
Changes in net branch:
Things changed: sockets data organisation, queue macro's are more universal, new checksum routines, changed socket structures, ... What's new: UDP checksum generation & validation Rough TCP code has been written, but not debugged yet. git-svn-id: svn://kolibrios.org@1249 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
725fe0911e
commit
7f9d0c6697
File diff suppressed because it is too large
Load Diff
@ -221,7 +221,7 @@ ARP_create_request:
|
|||||||
mov ecx, 60 ; minimum packet size
|
mov ecx, 60 ; minimum packet size
|
||||||
mov edx, edi ;;;
|
mov edx, edi ;;;
|
||||||
mov di , ETHER_ARP
|
mov di , ETHER_ARP
|
||||||
call ETH_create_Packet
|
call ETH_create_packet
|
||||||
cmp edi, -1
|
cmp edi, -1
|
||||||
je .exit
|
je .exit
|
||||||
|
|
||||||
@ -248,7 +248,7 @@ ARP_create_request:
|
|||||||
DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx
|
DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx
|
||||||
|
|
||||||
push edx ecx
|
push edx ecx
|
||||||
jmp ETH_Sender
|
jmp ETH_sender
|
||||||
|
|
||||||
.exit:
|
.exit:
|
||||||
add esp, 8
|
add esp, 8
|
||||||
@ -555,7 +555,7 @@ ARP_handler:
|
|||||||
|
|
||||||
DEBUGF 1,"ARP_Handler - Sending reply \n"
|
DEBUGF 1,"ARP_Handler - Sending reply \n"
|
||||||
|
|
||||||
jmp ETH_Sender ; And send it!
|
jmp ETH_sender ; And send it!
|
||||||
|
|
||||||
.exit:
|
.exit:
|
||||||
call kernel_free
|
call kernel_free
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
;; Copyright (C) KolibriOS team 2004-2009. All rights reserved. ;;
|
||||||
;; Distributed under terms of the GNU General Public License ;;
|
;; Distributed under terms of the GNU General Public License ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; IP.INC ;;
|
;; IPv4.INC ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; Part of the tcp/ip network stack for KolibriOS ;;
|
;; Part of the tcp/ip network stack for KolibriOS ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
@ -52,7 +52,7 @@ struct FRAGMENT_entry ; This structure will replace the ethernet header
|
|||||||
.PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet)
|
.PrevPtr dd ? ; Pointer to previous fragment entry (-1 for first packet)
|
||||||
.NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet)
|
.NextPtr dd ? ; Pointer to next fragment entry (-1 for last packet)
|
||||||
.Owner dd ? ; Pointer to structure of driver
|
.Owner dd ? ; Pointer to structure of driver
|
||||||
rb 2 ; to match ethernet header size
|
rb 2 ; to match ethernet header size ; TODO: fix this hack
|
||||||
.Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet)
|
.Data: ; Ip header begins here (we will need the IP header to re-construct the complete packet)
|
||||||
ends
|
ends
|
||||||
|
|
||||||
@ -99,10 +99,9 @@ IPv4_init:
|
|||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; IP_Handler:
|
; IPv4_Handler:
|
||||||
;
|
;
|
||||||
; Called by eth_handler,
|
; Will check if IP Packet isnt damaged
|
||||||
; will check if IP Packet isnt damaged
|
|
||||||
; and call appropriate handler. (TCP/UDP/ICMP/..)
|
; and call appropriate handler. (TCP/UDP/ICMP/..)
|
||||||
;
|
;
|
||||||
; It will also re-construct fragmented packets
|
; It will also re-construct fragmented packets
|
||||||
@ -119,20 +118,27 @@ align 4
|
|||||||
IPv4_handler:
|
IPv4_handler:
|
||||||
|
|
||||||
DEBUGF 1,"IP_Handler - start\n"
|
DEBUGF 1,"IP_Handler - start\n"
|
||||||
mov cx , [edx + IPv4_Packet.HeaderChecksum]
|
|
||||||
xchg ch , cl ; Get the checksum in intel format
|
|
||||||
|
|
||||||
mov word [edx + IPv4_Packet.HeaderChecksum], 0 ; Clear checksum field to recalculating checksum
|
|
||||||
|
|
||||||
movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
|
push edx ebx
|
||||||
and eax, 0x0000000F ;
|
|
||||||
shl eax, 2 ;
|
|
||||||
|
|
||||||
push edx
|
; save checksum, and clear it in original packet
|
||||||
stdcall checksum_jb, edx, eax ; buf_ptr, buf_size
|
mov di , [edx + IPv4_Packet.HeaderChecksum]
|
||||||
pop edx
|
DEBUGF 1,"checksum: %x\n",di
|
||||||
cmp cx , ax
|
mov word [edx + IPv4_Packet.HeaderChecksum], 0
|
||||||
jnz .dump ; if CHECKSUM isn't valid then dump Packet
|
|
||||||
|
; Re-calculate checksum
|
||||||
|
movzx ecx, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
|
||||||
|
and ecx, 0x0000000F ;
|
||||||
|
shl cx , 2 ;
|
||||||
|
mov esi, edx
|
||||||
|
xor edx, edx
|
||||||
|
call checksum_1
|
||||||
|
call checksum_2
|
||||||
|
|
||||||
|
; now compare the two..
|
||||||
|
cmp dx, di
|
||||||
|
pop ebx edx
|
||||||
|
jne .dump ; if checksum isn't valid then dump packet
|
||||||
|
|
||||||
mov eax, [edx + IPv4_Packet.DestinationAddress]
|
mov eax, [edx + IPv4_Packet.DestinationAddress]
|
||||||
mov edi, BROADCAST
|
mov edi, BROADCAST
|
||||||
@ -183,10 +189,14 @@ IPv4_handler:
|
|||||||
add eax, edx
|
add eax, edx
|
||||||
push eax
|
push eax
|
||||||
mov al , [edx + IPv4_Packet.Protocol]
|
mov al , [edx + IPv4_Packet.Protocol]
|
||||||
|
;----------------------- experimental
|
||||||
|
mov esi, [edx + IPv4_Packet.SourceAddress]
|
||||||
|
mov edi, [edx + IPv4_Packet.DestinationAddress]
|
||||||
|
;-----------------------
|
||||||
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
|
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
|
||||||
|
|
||||||
cmp al , IP_PROTO_TCP
|
cmp al , IP_PROTO_TCP
|
||||||
; je TCP_handler
|
je TCP_handler
|
||||||
|
|
||||||
cmp al , IP_PROTO_UDP
|
cmp al , IP_PROTO_UDP
|
||||||
je UDP_handler
|
je UDP_handler
|
||||||
@ -385,14 +395,21 @@ IPv4_handler:
|
|||||||
movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
|
movzx eax, byte [edx + IPv4_Packet.VersionAndIHL] ; Calculate Header length by using IHL field
|
||||||
and ax, 0x000F ;
|
and ax, 0x000F ;
|
||||||
shl ax, 2 ;
|
shl ax, 2 ;
|
||||||
sub ecx, eax ;
|
|
||||||
|
sub ecx, eax
|
||||||
|
|
||||||
|
|
||||||
add eax, edx
|
add eax, edx
|
||||||
push eax
|
push eax
|
||||||
mov al , [edx + IPv4_Packet.Protocol]
|
mov al , [edx + IPv4_Packet.Protocol]
|
||||||
|
;----------------------- experimental
|
||||||
|
mov esi, [edx + IPv4_Packet.SourceAddress]
|
||||||
|
mov edi, [edx + IPv4_Packet.DestinationAddress]
|
||||||
|
;-----------------------
|
||||||
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
|
pop edx ; Offset to data (tcp/udp/icmp/.. Packet)
|
||||||
|
|
||||||
cmp al , IP_PROTO_TCP
|
cmp al , IP_PROTO_TCP
|
||||||
; je TCP_handler
|
je TCP_handler
|
||||||
|
|
||||||
cmp al , IP_PROTO_UDP
|
cmp al , IP_PROTO_UDP
|
||||||
je UDP_handler
|
je UDP_handler
|
||||||
@ -493,12 +510,12 @@ IPv4_decrease_fragment_ttls:
|
|||||||
; dx = fragment id
|
; dx = fragment id
|
||||||
; di = protocol
|
; di = protocol
|
||||||
;
|
;
|
||||||
; OUT: eax points to buffer start
|
; OUT: eax = pointer to buffer start
|
||||||
; ebx is size of complete buffer
|
; ebx = pointer to device struct (needed for sending procedure)
|
||||||
; edi = pointer to start of data (-1 on error)
|
|
||||||
; ecx = unchanged (packet size of embedded data)
|
; ecx = unchanged (packet size of embedded data)
|
||||||
; edx = pointer to device struct (needed for sending procedure)
|
; edx = size of complete buffer
|
||||||
; esi = pointer to sending procedure
|
; esi = pointer to sending procedure
|
||||||
|
; edi = pointer to start of data (-1 on error)
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
|
|
||||||
@ -550,7 +567,7 @@ IPv4_create_packet:
|
|||||||
mov ecx, [esp+18] ;; 18 or 22 ??
|
mov ecx, [esp+18] ;; 18 or 22 ??
|
||||||
add ecx, IPv4_Packet.DataOrOptional
|
add ecx, IPv4_Packet.DataOrOptional
|
||||||
mov di , ETHER_IPv4
|
mov di , ETHER_IPv4
|
||||||
call ETH_create_Packet ; TODO: figure out a way to make this work with other protocols too
|
call ETH_create_packet ; TODO: figure out a way to make this work with other protocols too
|
||||||
add esp, 6
|
add esp, 6
|
||||||
cmp edi, -1
|
cmp edi, -1
|
||||||
je .exit
|
je .exit
|
||||||
@ -571,21 +588,25 @@ IPv4_create_packet:
|
|||||||
pop ecx
|
pop ecx
|
||||||
mov [edi + IPv4_Packet.DestinationAddress], ecx
|
mov [edi + IPv4_Packet.DestinationAddress], ecx
|
||||||
|
|
||||||
push eax
|
push eax ebx edx
|
||||||
stdcall checksum_jb, edi, IPv4_Packet.DataOrOptional ; buf_ptr, buf_size
|
; calculate checksum
|
||||||
xchg al, ah
|
xor edx, edx
|
||||||
mov [edi + IPv4_Packet.HeaderChecksum], ax
|
mov esi, edi
|
||||||
pop eax ecx
|
mov ecx, IPv4_Packet.DataOrOptional
|
||||||
|
call checksum_1
|
||||||
|
call checksum_2
|
||||||
|
mov [edi + IPv4_Packet.HeaderChecksum], dx
|
||||||
|
pop edx ebx eax ecx
|
||||||
add edi, IPv4_Packet.DataOrOptional
|
add edi, IPv4_Packet.DataOrOptional
|
||||||
|
|
||||||
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", edx
|
DEBUGF 1,"IPv4 Packet for device %x created successfully\n", ebx
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
.not_found:
|
.not_found:
|
||||||
DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n"
|
DEBUGF 1,"Create IPv4 Packet - ARP entry not found!\n"
|
||||||
; TODO: QUEUE!
|
; TODO: QUEUE the packet to resend later!
|
||||||
.exit:
|
.exit:
|
||||||
add esp, 16
|
add esp, 16
|
||||||
.exit_:
|
.exit_:
|
||||||
|
@ -80,13 +80,8 @@ ETH_init:
|
|||||||
mov ecx, (1+MAX_ETH_DEVICES)
|
mov ecx, (1+MAX_ETH_DEVICES)
|
||||||
rep stosd
|
rep stosd
|
||||||
|
|
||||||
mov dword [ETH_IN_QUEUE], ETH_QUEUE_SIZE
|
init_queue ETH_IN_QUEUE
|
||||||
mov dword [ETH_IN_QUEUE+4], ETH_IN_QUEUE + queue.data
|
init_queue ETH_OUT_QUEUE
|
||||||
mov dword [ETH_IN_QUEUE+8], ETH_IN_QUEUE + queue.data
|
|
||||||
|
|
||||||
mov dword [ETH_OUT_QUEUE], ETH_QUEUE_SIZE
|
|
||||||
mov dword [ETH_OUT_QUEUE+4], ETH_OUT_QUEUE + queue.data
|
|
||||||
mov dword [ETH_OUT_QUEUE+8], ETH_OUT_QUEUE + queue.data
|
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -104,7 +99,7 @@ ETH_init:
|
|||||||
;---------------------------------------------------------
|
;---------------------------------------------------------
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
ETH_Add_Device:
|
ETH_add_device:
|
||||||
|
|
||||||
DEBUGF 1,"ETH_Add_Device: %x ", ebx
|
DEBUGF 1,"ETH_Add_Device: %x ", ebx
|
||||||
|
|
||||||
@ -122,7 +117,6 @@ ETH_Add_Device:
|
|||||||
mov ecx, MAX_ETH_DEVICES ; We need to check whole list because a device may be removed without re-organizing list
|
mov ecx, MAX_ETH_DEVICES ; We need to check whole list because a device may be removed without re-organizing list
|
||||||
mov edi, ETH_DRV_LIST
|
mov edi, ETH_DRV_LIST
|
||||||
|
|
||||||
cld
|
|
||||||
repne scasd ; See if device is already in the list
|
repne scasd ; See if device is already in the list
|
||||||
jz .error
|
jz .error
|
||||||
|
|
||||||
@ -167,7 +161,7 @@ ETH_Add_Device:
|
|||||||
;--------------------------------
|
;--------------------------------
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
ETH_Remove_Device:
|
ETH_remove_device:
|
||||||
|
|
||||||
cmp [ETH_RUNNING], 0
|
cmp [ETH_RUNNING], 0
|
||||||
je .error
|
je .error
|
||||||
@ -212,12 +206,21 @@ ETH_Remove_Device:
|
|||||||
;-------------------------------------------------------------
|
;-------------------------------------------------------------
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
ETH_Receiver:
|
ETH_receiver:
|
||||||
DEBUGF 1,"ETH_Receiver \n"
|
DEBUGF 1,"ETH_Receiver: "
|
||||||
|
|
||||||
add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, .gohome
|
push ebx
|
||||||
|
mov esi, esp
|
||||||
|
add_to_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail
|
||||||
|
DEBUGF 1,"Queued packet successfully\n"
|
||||||
|
add esp, 4*3
|
||||||
|
ret
|
||||||
|
|
||||||
.gohome:
|
.fail:
|
||||||
|
DEBUGF 1,"ETH_IN_QUEUE is full!\n"
|
||||||
|
add esp, 4
|
||||||
|
call kernel_free
|
||||||
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
@ -238,7 +241,18 @@ ETH_Receiver:
|
|||||||
align 4
|
align 4
|
||||||
ETH_handler:
|
ETH_handler:
|
||||||
|
|
||||||
get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, .gohome
|
get_from_queue ETH_IN_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome
|
||||||
|
|
||||||
|
push ETH_handler
|
||||||
|
|
||||||
|
lodsd
|
||||||
|
mov ebx, eax
|
||||||
|
lodsd
|
||||||
|
mov ecx, eax
|
||||||
|
lodsd
|
||||||
|
xchg eax, ecx
|
||||||
|
push ecx
|
||||||
|
push eax
|
||||||
|
|
||||||
DEBUGF 1,"ETH_Handler - size: %u\n", ecx
|
DEBUGF 1,"ETH_Handler - size: %u\n", ecx
|
||||||
cmp ecx, 60 ; check packet length
|
cmp ecx, 60 ; check packet length
|
||||||
@ -262,13 +276,13 @@ ETH_handler:
|
|||||||
add esp, 4
|
add esp, 4
|
||||||
|
|
||||||
.gohome:
|
.gohome:
|
||||||
ret ; return 1. to get more from queue / 2. to caller
|
ret ; return to get more from queue / to caller
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; ETH_Sender:
|
; ETH_sender:
|
||||||
;
|
;
|
||||||
; This function sends an ethernet packet to the correct driver.
|
; This function sends an ethernet packet to the correct driver.
|
||||||
;
|
;
|
||||||
@ -280,35 +294,66 @@ ETH_handler:
|
|||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
ETH_Sender:
|
ETH_sender:
|
||||||
DEBUGF 1,"ETH_Sender \n"
|
DEBUGF 1,"ETH_Sender: queuing for device: %x, %u bytes\n", [esp], [esp + 4]
|
||||||
|
|
||||||
add_to_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, .gohome
|
push ebx
|
||||||
|
mov esi, esp
|
||||||
.gohome:
|
add_to_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .fail
|
||||||
|
DEBUGF 1,"Queued packet successfully\n"
|
||||||
|
add esp, 3*4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
.fail:
|
||||||
|
DEBUGF 1,"ETH_OUT_QUEUE is full!\n"
|
||||||
|
add esp, 4
|
||||||
|
call kernel_free
|
||||||
|
add esp, 4
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; ETH_send_queued:
|
||||||
|
;
|
||||||
|
; IN: /
|
||||||
|
; OUT: /
|
||||||
|
;
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
ETH_send_queued:
|
ETH_send_queued:
|
||||||
|
|
||||||
get_from_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, .gohome
|
get_from_queue ETH_OUT_QUEUE, ETH_QUEUE_SIZE, eth_queue_entry.size, .gohome
|
||||||
|
|
||||||
call ETH_struc2dev ; convert struct ptr to device num (this way we know if driver is still mounted)
|
push ETH_send_queued
|
||||||
|
|
||||||
|
lodsd
|
||||||
|
mov ebx, eax
|
||||||
|
|
||||||
|
sub esp, 8
|
||||||
|
mov edi, esp
|
||||||
|
movsd
|
||||||
|
movsd
|
||||||
|
|
||||||
|
DEBUGF 1,"dequeued packet for device %x\n", ebx
|
||||||
|
|
||||||
|
call ETH_struc2dev ; convert struct ptr to device num (this way we know if driver is still mounted)
|
||||||
cmp edi, -1
|
cmp edi, -1
|
||||||
je .fail
|
je .fail
|
||||||
|
|
||||||
DEBUGF 1,"ETH_Sender - device: %u\n", edi
|
jmp [ebx+ETH_DEVICE.transmit] ; we will return to get_from_queue macro after transmitting packet
|
||||||
|
|
||||||
jmp [ebx+ETH_DEVICE.transmit]
|
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4 ; pop (balance stack)
|
add esp, 4 ; pop (balance stack)
|
||||||
DEBUGF 1,"ETH_Sender - fail\n"
|
DEBUGF 1,"ETH_Sender - fail\n"
|
||||||
|
|
||||||
.gohome:
|
.gohome:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
;---------------------------------------------------------------------------
|
;---------------------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; ETH_struc2dev
|
; ETH_struc2dev
|
||||||
@ -362,7 +407,7 @@ ETH_struc2dev:
|
|||||||
;---------------------------------------------------------------------------
|
;---------------------------------------------------------------------------
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
ETH_create_Packet:
|
ETH_create_packet:
|
||||||
|
|
||||||
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
|
DEBUGF 1,"Creating Ethernet Packet (size=%u): \n", ecx
|
||||||
|
|
||||||
@ -394,7 +439,7 @@ ETH_create_Packet:
|
|||||||
lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start
|
lea eax, [edi - ETH_FRAME.Data] ; Set eax to buffer start
|
||||||
mov edx, ecx ; Set ebx to complete buffer size
|
mov edx, ecx ; Set ebx to complete buffer size
|
||||||
pop ecx
|
pop ecx
|
||||||
mov esi, ETH_Sender
|
mov esi, ETH_sender
|
||||||
|
|
||||||
xor ebx, ebx ;;;; TODO: Fixme
|
xor ebx, ebx ;;;; TODO: Fixme
|
||||||
mov ebx, [ETH_DRV_LIST + ebx]
|
mov ebx, [ETH_DRV_LIST + ebx]
|
||||||
|
@ -133,8 +133,8 @@ ICMP_init:
|
|||||||
;
|
;
|
||||||
; ICMP_Handler:
|
; ICMP_Handler:
|
||||||
;
|
;
|
||||||
; Called by IP_handler,
|
; this procedure will send reply's to ICMP echo's
|
||||||
; this procedure will send reply's to ICMP echo's etc ;;; TODO: update this to work with fragmented packets too!
|
; and insert packets into sockets when needed ;;; TODO: update this to work with fragmented packets too!
|
||||||
;
|
;
|
||||||
; IN: Pointer to buffer in [esp]
|
; IN: Pointer to buffer in [esp]
|
||||||
; size of buffer in [esp+4]
|
; size of buffer in [esp+4]
|
||||||
@ -181,33 +181,31 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
|
|||||||
mov dword [esi + ETH_FRAME.Data + IPv4_Packet.SourceAddress], ecx
|
mov dword [esi + ETH_FRAME.Data + IPv4_Packet.SourceAddress], ecx
|
||||||
|
|
||||||
; Recalculate ip header checksum
|
; Recalculate ip header checksum
|
||||||
; mov esi, [esp]
|
|
||||||
add esi, ETH_FRAME.Data ; Point esi to start of IP Packet
|
add esi, ETH_FRAME.Data ; Point esi to start of IP Packet
|
||||||
movzx eax, byte [esi + IPv4_Packet.VersionAndIHL] ; Calculate IP Header length by using IHL field
|
movzx ecx, byte [esi + IPv4_Packet.VersionAndIHL] ; Calculate IP Header length by using IHL field
|
||||||
and eax, 0x0000000F ;
|
and ecx, 0x0000000F ;
|
||||||
shl eax, 2 ;
|
shl cx , 2
|
||||||
push ebx edx esi
|
push ebx edx ecx esi
|
||||||
stdcall checksum_jb, esi, eax ; calculate the checksum
|
xor edx, edx
|
||||||
pop esi edx ebx
|
call checksum_1
|
||||||
xchg al, ah ; convert to intel byte order
|
call checksum_2
|
||||||
; mov esi, [esp]
|
pop esi
|
||||||
mov word [esi + IPv4_Packet.HeaderChecksum], ax ; Store it in the IP Packet header
|
mov word [esi + IPv4_Packet.HeaderChecksum], dx ; Store it in the IP Packet header
|
||||||
|
|
||||||
; Recalculate ICMP CheckSum
|
; Recalculate ICMP CheckSum
|
||||||
; mov esi, [esp] ; Find length of IP Packet
|
movzx eax, word[esi + IPv4_Packet.TotalLength] ; Find length of IP Packet
|
||||||
movzx eax, word[esi + IPv4_Packet.TotalLength] ;
|
|
||||||
xchg ah , al ;
|
xchg ah , al ;
|
||||||
movzx edi, byte [esi + IPv4_Packet.VersionAndIHL] ; Calculate IP Header length by using IHL field
|
sub eax, [esp] ; Now we know the length of ICMP data in eax
|
||||||
and edi, 0x0000000F ;
|
mov ecx, eax
|
||||||
shl edi, 2 ;
|
mov esi, [esp + 4]
|
||||||
sub ax , di ; Now we know the length of ICMP data in eax
|
xor edx, edx
|
||||||
push ebx edx
|
call checksum_1
|
||||||
stdcall checksum_jb,edx,eax ; Calculate the checksum of icmp data
|
call checksum_2
|
||||||
pop edx ebx
|
mov ax , dx
|
||||||
xchg al, ah ; Convert to intel byte order
|
pop ecx edx ebx
|
||||||
mov word [edx + ICMP_Packet.Checksum], ax
|
mov word [edx + ICMP_Packet.Checksum], ax
|
||||||
|
|
||||||
jmp ETH_Sender ; Send the reply
|
jmp ETH_sender ; Send the reply
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -222,20 +220,14 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
|
|||||||
.try_more:
|
.try_more:
|
||||||
mov ax , [edx + ICMP_Packet.Identifier]
|
mov ax , [edx + ICMP_Packet.Identifier]
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov esi, [esi + SOCKET.NextPtr]
|
mov esi, [esi + SOCKET_head.NextPtr]
|
||||||
or esi, esi
|
or esi, esi
|
||||||
jz .dump
|
jz .dump
|
||||||
cmp [esi + SOCKET.Type], IP_PROTO_ICMP
|
cmp [esi + SOCKET_head.Type], IP_PROTO_ICMP
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
cmp [esi + SOCKET.LocalPort], ax
|
cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + ICMP_SOCKET.Identifier], ax
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
cmp [esi + SOCKET.rxDataCount],0 ; get # of bytes already in buffer
|
|
||||||
jnz .dump ; only one packet at a time may be in the buffer!
|
|
||||||
|
|
||||||
cmp ecx, SOCKETBUFFSIZE - SOCKETHEADERSIZE; TODO: fix this problem !
|
|
||||||
jg .dump
|
|
||||||
|
|
||||||
call IPv4_dest_to_dev
|
call IPv4_dest_to_dev
|
||||||
cmp edi,-1
|
cmp edi,-1
|
||||||
je .dump
|
je .dump
|
||||||
@ -243,60 +235,25 @@ ICMP_handler: ;TODO: works only on pure ethernet right now !
|
|||||||
|
|
||||||
DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi
|
DEBUGF 1,"Found valid ICMP packet for socket %x\n", esi
|
||||||
|
|
||||||
lea ebx, [esi + SOCKET.lock]
|
lea ebx, [esi + SOCKET_head.lock]
|
||||||
call wait_mutex
|
call wait_mutex
|
||||||
|
|
||||||
; Now, copy data to socket. We have socket address in esi.
|
; Now, assign data to socket. We have socket address in esi.
|
||||||
; We have ICMP Packet in edx
|
; We have ICMP Packet in edx
|
||||||
; number of bytes in ecx
|
; number of bytes in ecx
|
||||||
|
|
||||||
; note: we do not strip the header!
|
mov eax, esi
|
||||||
|
|
||||||
DEBUGF 1,"bytes: %u\n", ecx
|
|
||||||
|
|
||||||
mov [esi + SOCKET.rxDataCount], ecx
|
|
||||||
|
|
||||||
lea edi, [esi + 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
|
pop esi
|
||||||
|
add esp, 4
|
||||||
DEBUGF 1,"ICMP socket updated\n"
|
sub edx, esi
|
||||||
|
mov edi, edx
|
||||||
mov [esi + SOCKET.lock], 0
|
jmp socket_internal_receiver
|
||||||
|
|
||||||
; 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:
|
.dump:
|
||||||
DEBUGF 1,"ICMP_Handler - dumping\n"
|
DEBUGF 1,"ICMP_Handler - dumping\n"
|
||||||
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 8 ; pop (balance stack)
|
add esp, 4 ; pop (balance stack)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -351,7 +308,7 @@ ICMP_handler_fragments: ; works only on pure ethernet right now !
|
|||||||
DEBUGF 1,"ICMP_Handler_fragments - end\n"
|
DEBUGF 1,"ICMP_Handler_fragments - end\n"
|
||||||
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 8 ; pop (balance stack)
|
add esp, 4 ; pop (balance stack)
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
@ -397,11 +354,14 @@ ICMP_create_packet:
|
|||||||
mov [edi + ICMP_Packet.Identifier], ax
|
mov [edi + ICMP_Packet.Identifier], ax
|
||||||
mov [edi + ICMP_Packet.Checksum], 0
|
mov [edi + ICMP_Packet.Checksum], 0
|
||||||
|
|
||||||
stdcall checksum_jb, edi , ecx
|
push eax ebx ecx edx
|
||||||
xchg al, ah
|
mov esi, edi
|
||||||
mov [edi + ICMP_Packet.Checksum], ax
|
xor edx, edx
|
||||||
|
call checksum_1
|
||||||
|
call checksum_2
|
||||||
|
mov [edi + ICMP_Packet.Checksum], dx
|
||||||
|
pop edx ecx ebx eax esi
|
||||||
|
|
||||||
pop esi
|
|
||||||
sub ecx, ICMP_Packet.Data
|
sub ecx, ICMP_Packet.Data
|
||||||
add edi, ICMP_Packet.Data
|
add edi, ICMP_Packet.Data
|
||||||
push cx
|
push cx
|
||||||
|
@ -15,88 +15,97 @@
|
|||||||
$Revision$
|
$Revision$
|
||||||
|
|
||||||
struct queue
|
struct queue
|
||||||
.size dd ?
|
.size dd ? ; number of queued packets in thsi queue
|
||||||
.w_ptr dd ?
|
.w_ptr dd ? ; current writing pointer in queue
|
||||||
.r_ptr dd ?
|
.r_ptr dd ? ; current reading pointer
|
||||||
.data:
|
.data:
|
||||||
ends
|
ends
|
||||||
|
|
||||||
struct queue_entry
|
struct eth_queue_entry
|
||||||
.owner dd ?
|
.owner dd ?
|
||||||
.data_ptr dd ?
|
.data_ptr dd ?
|
||||||
.data_size dd ?
|
.data_size dd ?
|
||||||
.size:
|
.size:
|
||||||
ends
|
ends
|
||||||
|
|
||||||
|
struct tcp_in_queue_entry
|
||||||
|
.data_ptr dd ?
|
||||||
|
.data_size dd ?
|
||||||
|
.offset dd ?
|
||||||
|
.size:
|
||||||
|
ends
|
||||||
|
|
||||||
macro add_to_queue ptr, size, returnaddr {
|
struct tcp_out_queue_entry
|
||||||
|
.data_ptr dd ?
|
||||||
|
.data_size dd ?
|
||||||
|
.ttl dd ?
|
||||||
|
.retries dd ?
|
||||||
|
.owner dd ?
|
||||||
|
.sendproc dd ?
|
||||||
|
.ack_num dd ?
|
||||||
|
.size:
|
||||||
|
ends
|
||||||
|
|
||||||
cmp dword [ptr + queue.size], size ; Check if queue isnt full
|
struct socket_queue_entry
|
||||||
jge .fail
|
.data_ptr dd ?
|
||||||
|
.data_size dd ?
|
||||||
|
.offset dd ?
|
||||||
|
.size:
|
||||||
|
ends
|
||||||
|
|
||||||
DEBUGF 1,"Queuing packet for device %x\n",ebx
|
macro add_to_queue ptr, size, entry_size, failaddr {
|
||||||
|
|
||||||
inc dword [ptr + queue.size]
|
cmp [ptr + queue.size], size ; Check if queue isnt full
|
||||||
|
jge failaddr
|
||||||
|
|
||||||
mov edi, dword [ptr + queue.w_ptr] ; Current write pointer (FIFO!)
|
inc [ptr + queue.size]
|
||||||
|
|
||||||
mov eax, ebx
|
mov edi, [ptr + queue.w_ptr] ; Current write pointer (FIFO!)
|
||||||
stosd
|
mov ecx, entry_size/4 ; Write the queue entry
|
||||||
pop eax
|
rep movsd ;
|
||||||
stosd
|
|
||||||
pop eax
|
|
||||||
stosd
|
|
||||||
|
|
||||||
cmp edi, size*queue_entry.size+ptr+queue.data ; entry size
|
lea ecx, [size*entry_size+ptr+queue.data]
|
||||||
|
cmp edi, ecx ; entry size
|
||||||
jl .no_wrap
|
jl .no_wrap
|
||||||
|
|
||||||
sub edi, size*queue_entry.size
|
sub edi, size*entry_size
|
||||||
|
|
||||||
.no_wrap:
|
.no_wrap:
|
||||||
mov dword [ptr + queue.w_ptr], edi
|
mov [ptr + queue.w_ptr], edi
|
||||||
jmp returnaddr
|
|
||||||
|
|
||||||
.fail:
|
|
||||||
DEBUGF 1,"queuing failed\n"
|
|
||||||
|
|
||||||
call kernel_free
|
|
||||||
add esp, 4
|
|
||||||
ret
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
macro get_from_queue ptr, size, returnaddr {
|
|
||||||
|
|
||||||
.start_of_code:
|
macro get_from_queue ptr, size, entry_size, failaddr {
|
||||||
cmp dword [ptr + queue.size], 0 ; any packets queued?
|
|
||||||
je returnaddr
|
|
||||||
|
|
||||||
DEBUGF 1,"Dequeuing packet"
|
cmp [ptr + queue.size], 0 ; any packets queued?
|
||||||
|
je failaddr
|
||||||
|
|
||||||
dec dword [ptr + queue.size]
|
dec [ptr + queue.size]
|
||||||
|
|
||||||
push dword .start_of_code ; return address for call's
|
|
||||||
|
|
||||||
mov esi, [ptr + queue.r_ptr]
|
mov esi, [ptr + queue.r_ptr]
|
||||||
lodsd
|
push esi
|
||||||
mov ebx, eax
|
|
||||||
lodsd
|
|
||||||
mov ecx, eax
|
|
||||||
lodsd
|
|
||||||
push eax
|
|
||||||
push ecx
|
|
||||||
xchg eax, ecx
|
|
||||||
|
|
||||||
DEBUGF 1," for device %x\n", ebx
|
add esi, entry_size
|
||||||
|
|
||||||
cmp esi, size*queue_entry.size+ptr+queue.data ; entry size
|
lea ecx, [size*entry_size+ptr+queue.data]
|
||||||
|
cmp esi, ecx ; entry size
|
||||||
jl .no_wrap
|
jl .no_wrap
|
||||||
|
|
||||||
sub esi, size*queue_entry.size
|
sub esi, size*entry_size
|
||||||
|
|
||||||
.no_wrap:
|
.no_wrap:
|
||||||
mov dword [ptr + queue.r_ptr], esi
|
mov dword [ptr + queue.r_ptr], esi
|
||||||
|
|
||||||
|
pop esi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro init_queue queue_ptr {
|
||||||
|
|
||||||
|
mov [queue_ptr + queue.size] , 0
|
||||||
|
lea esi, [queue_ptr + queue.data]
|
||||||
|
mov [queue_ptr + queue.w_ptr], esi
|
||||||
|
mov [queue_ptr + queue.r_ptr], esi
|
||||||
|
}
|
@ -5,7 +5,6 @@
|
|||||||
;; ;;
|
;; ;;
|
||||||
;; SOCKET.INC ;;
|
;; SOCKET.INC ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
;; ;;
|
|
||||||
;; Written by hidnplayr@kolibrios.org ;;
|
;; Written by hidnplayr@kolibrios.org ;;
|
||||||
;; based on code by mike.dld ;;
|
;; based on code by mike.dld ;;
|
||||||
;; ;;
|
;; ;;
|
||||||
@ -16,8 +15,7 @@
|
|||||||
|
|
||||||
$Revision$
|
$Revision$
|
||||||
|
|
||||||
align 4
|
struct SOCKET_head
|
||||||
struct SOCKET
|
|
||||||
.PrevPtr dd ? ; pointer to previous socket in list
|
.PrevPtr dd ? ; pointer to previous socket in list
|
||||||
.NextPtr dd ? ; pointer to next socket in list
|
.NextPtr dd ? ; pointer to next socket in list
|
||||||
.Number dd ? ; socket number (unique within single process)
|
.Number dd ? ; socket number (unique within single process)
|
||||||
@ -25,35 +23,73 @@ struct SOCKET
|
|||||||
.Domain dd ? ; INET/UNIX/..
|
.Domain dd ? ; INET/UNIX/..
|
||||||
.Type dd ? ; RAW/UDP/TCP/...
|
.Type dd ? ; RAW/UDP/TCP/...
|
||||||
.Protocol dd ? ; ICMP/IPv4/ARP/
|
.Protocol dd ? ; ICMP/IPv4/ARP/
|
||||||
.LocalIP dd ? ; local IP address
|
.lock dd ? ; lock mutex
|
||||||
.RemoteIP dd ? ; remote IP address
|
.end:
|
||||||
.LocalPort dw ? ; local port (In INET byte order)
|
ends
|
||||||
.RemotePort dw ? ; remote port (IN INET byte order
|
|
||||||
|
struct IPv4_SOCKET
|
||||||
|
.LocalIP dd ?
|
||||||
|
.RemoteIP dd ?
|
||||||
|
.SequenceNumber dd ?
|
||||||
|
|
||||||
|
; todo: add options (for func 8 and 9)
|
||||||
|
|
||||||
|
.end:
|
||||||
|
ends
|
||||||
|
|
||||||
|
struct TCP_SOCKET
|
||||||
|
|
||||||
|
.LocalPort dw ? ; In INET byte order
|
||||||
|
.RemotePort dw ? ; In INET byte order
|
||||||
|
|
||||||
|
.backlog dw ? ; Backlog
|
||||||
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
|
.OrigRemoteIP dd ? ; original remote IP address (used to reset to LISTEN state)
|
||||||
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
|
.OrigRemotePort dw ? ; original remote port (used to reset to LISTEN state)
|
||||||
.rxDataCount dd ? ; rx data count
|
|
||||||
.TCBState dd ? ; TCB state
|
.TCBState dd ? ; TCB state
|
||||||
.TCBTimer dd ? ; TCB timer (seconds)
|
.TCBTimer dd ? ; TCB timer (seconds)
|
||||||
.ISS dd ? ; initial send sequence
|
.ISS dd ? ; initial send sequence
|
||||||
.IRS dd ? ; initial receive sequence
|
.IRS dd ? ; initial receive sequence
|
||||||
.SND_UNA dd ? ; sequence number of unack'ed sent Packets
|
.SND_UNA dd ? ; sequence number of unack'ed sent Packets
|
||||||
.SND_NXT dd ? ; bext send sequence number to use
|
.SND_NXT dd ? ; next send sequence number to use
|
||||||
.SND_WND dd ? ; send window
|
.SND_WND dd ? ; send window
|
||||||
.RCV_NXT dd ? ; next receive sequence number to use
|
.RCV_NXT dd ? ; next receive sequence number to use
|
||||||
.RCV_WND dd ? ; receive window
|
.RCV_WND dd ? ; receive window
|
||||||
.SEG_LEN dd ? ; segment length
|
.SEG_LEN dd ? ; segment length
|
||||||
.SEG_WND dd ? ; segment window
|
.SEG_WND dd ? ; segment window
|
||||||
.wndsizeTimer dd ? ; window size timer
|
.wndsizeTimer dd ? ; window size timer
|
||||||
.lock dd ? ; lock mutex
|
|
||||||
.backlog dw ? ; Backlog
|
.flags db ? ; packet flags
|
||||||
.rxData: ; receive data buffer here
|
|
||||||
|
.end:
|
||||||
ends
|
ends
|
||||||
|
|
||||||
MAX_backlog equ 20
|
struct UDP_SOCKET
|
||||||
|
|
||||||
; socket buffers
|
.LocalPort dw ? ; In INET byte order
|
||||||
SOCKETBUFFSIZE equ 4096 ; state + config + buffer.
|
.RemotePort dw ? ; In INET byte order
|
||||||
SOCKETHEADERSIZE equ SOCKET.rxData ; thus 4096 - SOCKETHEADERSIZE bytes data
|
|
||||||
|
.end:
|
||||||
|
ends
|
||||||
|
|
||||||
|
struct ICMP_SOCKET
|
||||||
|
|
||||||
|
.Identifier dw ? ;
|
||||||
|
|
||||||
|
.end:
|
||||||
|
|
||||||
|
ends
|
||||||
|
|
||||||
|
struct IPC_SOCKET
|
||||||
|
|
||||||
|
.ConnectedTo dd ? ; Socket number of other socket this one is connected to
|
||||||
|
|
||||||
|
.end:
|
||||||
|
|
||||||
|
ends
|
||||||
|
|
||||||
|
MAX_backlog equ 20 ; backlog for stream sockets
|
||||||
|
SOCKETBUFFSIZE equ 4096 ; in bytes
|
||||||
|
SOCKET_QUEUE_SIZE equ 10 ; maximum number ofincoming packets queued for 1 socket
|
||||||
|
|
||||||
uglobal
|
uglobal
|
||||||
net_sockets rd 2
|
net_sockets rd 2
|
||||||
@ -110,6 +146,10 @@ sys_socket:
|
|||||||
jz socket_send ; 6
|
jz socket_send ; 6
|
||||||
dec bl
|
dec bl
|
||||||
jz socket_recv ; 7
|
jz socket_recv ; 7
|
||||||
|
dec bl
|
||||||
|
; jz socket_get_opt ; 8
|
||||||
|
dec bl
|
||||||
|
; jz socket_set_opt ; 9
|
||||||
|
|
||||||
s_error:
|
s_error:
|
||||||
mov dword [esp+32],-1
|
mov dword [esp+32],-1
|
||||||
@ -139,9 +179,9 @@ socket_open:
|
|||||||
or eax, eax
|
or eax, eax
|
||||||
jz s_error
|
jz s_error
|
||||||
|
|
||||||
mov [eax + SOCKET.Domain], ecx
|
mov [eax + SOCKET_head.Domain], ecx
|
||||||
mov [eax + SOCKET.Type], edx
|
mov [eax + SOCKET_head.Type], edx
|
||||||
mov [eax + SOCKET.Protocol], esi
|
mov [eax + SOCKET_head.Protocol], esi
|
||||||
|
|
||||||
stdcall net_socket_addr_to_num, eax
|
stdcall net_socket_addr_to_num, eax
|
||||||
DEBUGF 1,", socketnumber: %u\n", eax
|
DEBUGF 1,", socketnumber: %u\n", eax
|
||||||
@ -153,6 +193,10 @@ socket_open:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------
|
;-----------------------------------------------
|
||||||
;
|
;
|
||||||
; SOCKET_bind
|
; SOCKET_bind
|
||||||
@ -176,14 +220,28 @@ socket_bind:
|
|||||||
jl s_error
|
jl s_error
|
||||||
|
|
||||||
cmp word [edx], AF_INET4
|
cmp word [edx], AF_INET4
|
||||||
jne s_error
|
je .af_inet4
|
||||||
|
|
||||||
|
cmp word [edx], AF_UNIX
|
||||||
|
je .af_unix
|
||||||
|
|
||||||
|
jmp s_error
|
||||||
|
|
||||||
|
.af_unix:
|
||||||
|
|
||||||
|
; TODO: write code here
|
||||||
|
|
||||||
|
|
||||||
|
mov dword [esp+32],0
|
||||||
|
ret
|
||||||
|
|
||||||
.af_inet4:
|
.af_inet4:
|
||||||
|
|
||||||
cmp esi, 6
|
cmp esi, 6
|
||||||
jl s_error
|
jl s_error
|
||||||
|
|
||||||
mov ecx, [eax + SOCKET.Type]
|
mov ecx, [eax + SOCKET_head.Type]
|
||||||
|
|
||||||
mov bx, word [edx + 2]
|
mov bx, word [edx + 2]
|
||||||
DEBUGF 1,"local port: %x ",bx
|
DEBUGF 1,"local port: %x ",bx
|
||||||
test bx, bx
|
test bx, bx
|
||||||
@ -194,21 +252,22 @@ socket_bind:
|
|||||||
je s_error
|
je s_error
|
||||||
jmp .got_port
|
jmp .got_port
|
||||||
|
|
||||||
.find_free:
|
.find_free:
|
||||||
|
|
||||||
call socket_find_port
|
call socket_find_port
|
||||||
test bx, bx
|
test bx, bx
|
||||||
je s_error
|
je s_error
|
||||||
|
|
||||||
.got_port:
|
.got_port:
|
||||||
DEBUGF 1,"using port: %x ",bx
|
DEBUGF 1,"using port: %x ",bx
|
||||||
mov word [eax + SOCKET.LocalPort], bx
|
mov word [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
|
||||||
|
|
||||||
mov ebx, dword [edx + 4]
|
mov ebx, dword [edx + 4]
|
||||||
mov dword [eax + SOCKET.LocalIP], ebx
|
mov dword [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP], ebx
|
||||||
|
|
||||||
DEBUGF 1,"local ip: %u.%u.%u.%u\n",\
|
DEBUGF 1,"local ip: %u.%u.%u.%u\n",\
|
||||||
[eax + SOCKET.LocalIP]:1,[eax + SOCKET.LocalIP + 1]:1,[eax + SOCKET.LocalIP + 2]:1,[eax + SOCKET.LocalIP + 3]:1
|
[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 0]:1,[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 1]:1,\
|
||||||
|
[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 2]:1,[eax + SOCKET_head.end + IPv4_SOCKET.LocalIP + 3]:1
|
||||||
|
|
||||||
mov dword [esp+32],0
|
mov dword [esp+32],0
|
||||||
ret
|
ret
|
||||||
@ -249,32 +308,33 @@ socket_connect:
|
|||||||
cmp esi, 8
|
cmp esi, 8
|
||||||
jl s_error
|
jl s_error
|
||||||
|
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_UDP
|
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP
|
||||||
je .udp
|
je .udp
|
||||||
|
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_ICMP
|
cmp [eax + SOCKET_head.Type], IP_PROTO_ICMP
|
||||||
je .icmp
|
je .icmp
|
||||||
|
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_TCP
|
cmp [eax + SOCKET_head.Type], IP_PROTO_TCP
|
||||||
je .tcp
|
je .tcp
|
||||||
|
|
||||||
jmp s_error
|
jmp s_error
|
||||||
|
|
||||||
.udp:
|
.udp:
|
||||||
|
|
||||||
mov bx , word [edx + 2]
|
mov bx , word [edx + 2]
|
||||||
mov word [eax + SOCKET.RemotePort], bx
|
mov word [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
|
||||||
DEBUGF 1,"remote port: %x ",bx
|
DEBUGF 1,"remote port: %x ",bx
|
||||||
|
|
||||||
mov ebx, dword [edx + 4]
|
mov ebx, dword [edx + 4]
|
||||||
mov dword [eax + SOCKET.RemoteIP], ebx
|
mov dword [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
|
||||||
DEBUGF 1,"remote ip: %u.%u.%u.%u\n",[edx+4]:1,[edx+5]:1,[edx+6]:1,[edx+7]:1
|
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
|
mov dword [esp+32],0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.icmp:
|
.icmp:
|
||||||
|
|
||||||
|
; TODO: write code here
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -387,7 +447,7 @@ socket_listen:
|
|||||||
mov dx , 20
|
mov dx , 20
|
||||||
.ok:
|
.ok:
|
||||||
|
|
||||||
mov [eax + SOCKET.backlog], dx
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], dx
|
||||||
|
|
||||||
; TODO: insert code for active connections like TCP
|
; TODO: insert code for active connections like TCP
|
||||||
|
|
||||||
@ -420,7 +480,21 @@ socket_accept:
|
|||||||
jz s_error
|
jz s_error
|
||||||
mov esi, eax
|
mov esi, eax
|
||||||
|
|
||||||
cmp [esi + SOCKET.backlog], 0
|
cmp word [esi + SOCKET_head.Domain], AF_INET4
|
||||||
|
je .af_inet4
|
||||||
|
|
||||||
|
jmp s_error
|
||||||
|
|
||||||
|
.af_inet4:
|
||||||
|
|
||||||
|
cmp [esi + SOCKET_head.Type], IP_PROTO_TCP
|
||||||
|
je .tcp
|
||||||
|
|
||||||
|
jmp s_error
|
||||||
|
|
||||||
|
.tcp:
|
||||||
|
|
||||||
|
cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], 0
|
||||||
jz s_error
|
jz s_error
|
||||||
|
|
||||||
call net_socket_alloc
|
call net_socket_alloc
|
||||||
@ -428,19 +502,21 @@ socket_accept:
|
|||||||
jz s_error
|
jz s_error
|
||||||
mov edi, eax
|
mov edi, eax
|
||||||
|
|
||||||
dec [esi + SOCKET.backlog]
|
dec [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog]
|
||||||
|
|
||||||
mov ecx, (SOCKET.rxData+3)/4
|
mov ecx, (SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.end+3)/4
|
||||||
|
push esi edi
|
||||||
rep movsd
|
rep movsd
|
||||||
|
pop edi esi
|
||||||
|
|
||||||
mov [edi + SOCKET.backlog], 0
|
mov [edi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.backlog], 0
|
||||||
|
|
||||||
; TODO: fill in structure in ecx
|
; TODO: fill in structure in ecx
|
||||||
|
|
||||||
mov [esi + SOCKET.RemoteIP], 0
|
mov [esi + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0
|
||||||
mov [esi + SOCKET.RemotePort], 0
|
mov [esi + SOCKET_head.end + IPv4_SOCKET.end + TCP_SOCKET.RemotePort], 0
|
||||||
|
|
||||||
stdcall net_socket_addr_to_num, eax
|
stdcall net_socket_addr_to_num, edi
|
||||||
mov [esp+32], eax
|
mov [esp+32], eax
|
||||||
|
|
||||||
ret
|
ret
|
||||||
@ -465,26 +541,23 @@ socket_close:
|
|||||||
or eax, eax
|
or eax, eax
|
||||||
jz s_error
|
jz s_error
|
||||||
|
|
||||||
|
cmp [eax + SOCKET_head.Domain], AF_INET4
|
||||||
|
jne s_error
|
||||||
|
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_UDP
|
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP
|
||||||
je .udp
|
je .udp
|
||||||
|
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_ICMP
|
cmp [eax + SOCKET_head.Type], IP_PROTO_ICMP
|
||||||
je .icmp
|
je .icmp
|
||||||
|
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_TCP
|
cmp [eax + SOCKET_head.Type], IP_PROTO_TCP
|
||||||
je .tcp
|
je .tcp
|
||||||
|
|
||||||
jmp s_error
|
jmp s_error
|
||||||
|
|
||||||
.udp:
|
.udp:
|
||||||
|
|
||||||
lea ebx, [eax + SOCKET.lock]
|
|
||||||
call wait_mutex
|
|
||||||
; TODO: mark the socket for deletion, using the mutex
|
|
||||||
|
|
||||||
stdcall net_socket_free, eax
|
stdcall net_socket_free, eax
|
||||||
|
|
||||||
mov dword [esp+32],0
|
mov dword [esp+32],0
|
||||||
ret
|
ret
|
||||||
|
|
||||||
@ -600,8 +673,8 @@ end if
|
|||||||
;
|
;
|
||||||
;
|
;
|
||||||
; IN: socket number in ecx
|
; IN: socket number in ecx
|
||||||
; addr in edx
|
; addr to buffer in edx
|
||||||
; addrlen in esi
|
; length of buffer in esi
|
||||||
; flags in edi
|
; flags in edi
|
||||||
; OUT: eax is number of bytes copied, -1 on error
|
; OUT: eax is number of bytes copied, -1 on error
|
||||||
;
|
;
|
||||||
@ -609,70 +682,46 @@ end if
|
|||||||
align 4
|
align 4
|
||||||
socket_recv:
|
socket_recv:
|
||||||
|
|
||||||
DEBUGF 1,"Socket_receive: socknum: %u sockaddr: %x, length: %u, flags: %x\n",ecx,edx,esi,edi
|
DEBUGF 1,"Socket_receive: socknum: %u bufferaddress: %x, length: %u, flags: %x\n",ecx,edx,esi,edi
|
||||||
|
|
||||||
stdcall net_socket_num_to_addr, ecx ; get real socket address
|
stdcall net_socket_num_to_addr, ecx ; get real socket address
|
||||||
or eax, eax
|
or eax, eax
|
||||||
jz s_error
|
jz s_error
|
||||||
|
|
||||||
DEBUGF 1,"real socket address:%x\n", eax
|
DEBUGF 1,"Socket pointer: %x\n", eax
|
||||||
|
|
||||||
mov dword[esp+32], -1
|
get_from_queue (eax + 2048), SOCKET_QUEUE_SIZE, 4*3, s_error
|
||||||
|
|
||||||
mov edi, edx
|
mov edi, edx
|
||||||
|
mov ecx, [esi + socket_queue_entry.data_size]
|
||||||
|
|
||||||
lea ebx, [eax + SOCKET.lock]
|
DEBUGF 1,"Got %u bytes of data\n", ecx
|
||||||
call wait_mutex
|
|
||||||
|
|
||||||
mov ecx, [eax + SOCKET.rxDataCount] ; get count of bytes
|
cmp ecx, edx
|
||||||
DEBUGF 1,"bytes in socket:%u\n", ecx
|
jle .large_enough
|
||||||
test ecx, ecx ; if count of bytes is zero..
|
DEBUGF 1,"Buffer too small...\n"
|
||||||
jz .exit ; exit function (eax will be zero)
|
jmp s_error
|
||||||
|
.large_enough:
|
||||||
|
|
||||||
cmp ecx, esi ; if buffer size is larger then the bytes of data, copy all data
|
push [esi + socket_queue_entry.data_ptr]
|
||||||
jle .copy_all_bytes
|
mov esi, [esi + socket_queue_entry.offset]
|
||||||
|
add esi, [esp]
|
||||||
|
DEBUGF 1,"Source buffer: %x, real addr: %x\n", [esp], esi
|
||||||
|
|
||||||
sub ecx, esi ; store new count (data bytes in buffer - bytes we're about to copy)
|
mov dword[esp+32+4], ecx ; return number of bytes copied
|
||||||
mov [eax + SOCKET.rxDataCount], ecx ;
|
|
||||||
push ecx
|
|
||||||
mov edx, esi
|
|
||||||
|
|
||||||
call .start_copy ; copy to the application
|
shr ecx, 1
|
||||||
|
jnc .nb
|
||||||
|
movsb
|
||||||
|
.nb: shr ecx, 1
|
||||||
|
jnc .nw
|
||||||
|
movsw
|
||||||
|
.nw: rep movsd
|
||||||
|
|
||||||
mov dword[esp+32], edx
|
call kernel_free
|
||||||
|
|
||||||
lea edi, [eax + SOCKET.rxData] ; Now shift the remaining bytes to start of buffer
|
|
||||||
lea esi, [edi + edx]
|
|
||||||
mov ecx, [esp]
|
|
||||||
shr ecx, 2 ; divide eax by 4
|
|
||||||
rep movsd ; copy all full dwords
|
|
||||||
pop ecx
|
|
||||||
and ecx, 3
|
|
||||||
rep movsb ; copy remaining bytes
|
|
||||||
|
|
||||||
.exit:
|
|
||||||
mov [eax + SOCKET.lock], 0
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.copy_all_bytes:
|
|
||||||
mov dword[esp+32], ecx
|
|
||||||
mov [eax + SOCKET.rxDataCount], 0 ; store new count (zero)
|
|
||||||
push dword .exit ; this code results in same as commented out code
|
|
||||||
|
|
||||||
.start_copy:
|
|
||||||
DEBUGF 1,"copying %u bytes\n",ecx
|
|
||||||
|
|
||||||
lea esi, [eax + SOCKET.rxData]
|
|
||||||
push ecx
|
|
||||||
shr ecx, 2 ; divide eax by 4
|
|
||||||
rep movsd
|
|
||||||
pop ecx
|
|
||||||
and ecx, 3
|
|
||||||
rep movsb ; copy the rest bytes
|
|
||||||
|
|
||||||
ret ; exit, or go back to shift remaining bytes if any
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------
|
;-----------------------------------------------
|
||||||
;
|
;
|
||||||
@ -695,84 +744,97 @@ socket_send:
|
|||||||
or eax, eax
|
or eax, eax
|
||||||
jz s_error
|
jz s_error
|
||||||
|
|
||||||
cmp word [eax + SOCKET.Domain], AF_INET4
|
cmp word [eax + SOCKET_head.Domain], AF_INET4
|
||||||
je .af_inet4
|
je .af_inet4
|
||||||
|
|
||||||
jmp s_error
|
jmp s_error
|
||||||
|
|
||||||
|
;---------
|
||||||
.af_inet4:
|
.af_inet4:
|
||||||
|
DEBUGF 1,"Socket type:%u\n", [eax + SOCKET_head.Type]:4
|
||||||
|
|
||||||
DEBUGF 1,"Socket type:%u\n", [eax + SOCKET.Type]:4
|
cmp [eax + SOCKET_head.Type], IP_PROTO_TCP
|
||||||
|
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_UDP
|
|
||||||
je .udp
|
|
||||||
|
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_ICMP
|
|
||||||
je .icmp
|
|
||||||
|
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_TCP
|
|
||||||
je .tcp
|
je .tcp
|
||||||
|
|
||||||
|
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP
|
||||||
|
je .udp
|
||||||
|
|
||||||
|
cmp [eax + SOCKET_head.Type], SOCK_RAW
|
||||||
|
je .raw
|
||||||
|
|
||||||
jmp s_error
|
jmp s_error
|
||||||
|
;--------
|
||||||
|
|
||||||
.udp:
|
.udp:
|
||||||
|
|
||||||
DEBUGF 1,"type: UDP, "
|
DEBUGF 1,"type: UDP, "
|
||||||
|
|
||||||
cmp [eax + SOCKET.LocalPort],0
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort],0
|
||||||
jne .port_ok
|
jne @f
|
||||||
|
|
||||||
push esi
|
push esi
|
||||||
mov ecx, [eax + SOCKET.Type]
|
mov ecx, [eax + SOCKET_head.Type]
|
||||||
call socket_find_port
|
call socket_find_port
|
||||||
test bx, bx
|
test bx, bx
|
||||||
pop esi
|
pop esi
|
||||||
je s_error
|
je s_error
|
||||||
mov [eax + SOCKET.LocalPort], bx
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
|
||||||
|
|
||||||
.port_ok:
|
@@:
|
||||||
|
|
||||||
mov ecx, esi
|
mov ecx, esi
|
||||||
mov esi, edx
|
mov esi, edx
|
||||||
mov edx, dword [eax + SOCKET.LocalPort] ; load local port and remote port at once
|
|
||||||
DEBUGF 1,"local port: %x, remote port: %x\n",[eax + SOCKET.LocalPort]:4, [eax + SOCKET.RemotePort]:4
|
|
||||||
mov ebx, [eax + SOCKET.LocalIP]
|
|
||||||
mov eax, [eax + SOCKET.RemoteIP]
|
|
||||||
|
|
||||||
call UDP_create_packet
|
call UDP_socket_send
|
||||||
|
|
||||||
mov [esp+32], eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
.icmp:
|
|
||||||
; note: for ICMP sockets the SOCKET.LocalPort is used as the 'Identifier' value for ICMP packets
|
|
||||||
; the application must add the header to the data, the kernel will fill in 'identifier' and 'checksum'
|
|
||||||
|
|
||||||
sub ecx, ICMP_Packet.Data
|
|
||||||
mov esi, edx
|
|
||||||
push ax
|
|
||||||
call IPv4_get_frgmnt_num
|
|
||||||
mov dx, ax
|
|
||||||
pop ax
|
|
||||||
shl edx, 16
|
|
||||||
mov dh , [esi + ICMP_Packet.Type]
|
|
||||||
mov dl , [esi + ICMP_Packet.Code]
|
|
||||||
mov di , [esi + ICMP_Packet.Identifier]
|
|
||||||
; mov [eax + SOCKET.LocalPort], di ; Set localport to the identifier number, so we can receive reply's
|
|
||||||
shl edi, 16
|
|
||||||
mov di , [esi + ICMP_Packet.SequenceNumber]
|
|
||||||
add esi, ICMP_Packet.Data
|
|
||||||
mov ebx, [eax + SOCKET.LocalIP]
|
|
||||||
mov eax, [eax + SOCKET.RemoteIP]
|
|
||||||
call ICMP_create_packet
|
|
||||||
|
|
||||||
mov [esp+32], eax
|
mov [esp+32], eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.tcp:
|
.tcp:
|
||||||
|
|
||||||
|
mov [esp+32], eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;--------
|
||||||
|
.raw:
|
||||||
|
cmp [eax + SOCKET_head.Protocol], IP_PROTO_IP
|
||||||
|
je .raw_ip
|
||||||
|
|
||||||
|
cmp [eax + SOCKET_head.Protocol], IP_PROTO_ICMP
|
||||||
|
je .raw_icmp
|
||||||
|
|
||||||
|
jmp s_error
|
||||||
|
;--------
|
||||||
|
|
||||||
|
|
||||||
|
.raw_ip:
|
||||||
|
|
||||||
|
mov [esp+32], eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
.raw_icmp:
|
||||||
|
|
||||||
|
; sub ecx, ICMP_Packet.Data
|
||||||
|
; mov esi, edx
|
||||||
|
; push ax
|
||||||
|
; call IPv4_get_frgmnt_num
|
||||||
|
; mov dx, ax
|
||||||
|
; pop ax
|
||||||
|
; shl edx, 16
|
||||||
|
; mov dh , [esi + ICMP_Packet.Type]
|
||||||
|
; mov dl , [esi + ICMP_Packet.Code]
|
||||||
|
; mov di , [esi + ICMP_Packet.Identifier]
|
||||||
|
; mov [eax + SOCKET.LocalPort], di ; Set localport to the identifier number, so we can receive reply's
|
||||||
|
; shl edi, 16
|
||||||
|
; mov di , [esi + ICMP_Packet.SequenceNumber]
|
||||||
|
; add esi, ICMP_Packet.Data
|
||||||
|
; mov ebx, [eax + SOCKET.LocalIP]
|
||||||
|
; mov eax, [eax + SOCKET.RemoteIP]
|
||||||
|
; call ICMP_create_packet
|
||||||
|
|
||||||
|
mov [esp+32], eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -812,15 +874,15 @@ socket_find_port:
|
|||||||
mov esi, net_sockets
|
mov esi, net_sockets
|
||||||
|
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov esi, [esi + SOCKET.NextPtr]
|
mov esi, [esi + SOCKET_head.NextPtr]
|
||||||
or esi, esi
|
or esi, esi
|
||||||
jz .port_ok
|
jz .port_ok
|
||||||
|
|
||||||
cmp [esi + SOCKET.Type], ecx
|
cmp [esi + SOCKET_head.Type], ecx
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
rol bx, 8
|
rol bx, 8
|
||||||
cmp [esi + SOCKET.LocalPort], bx
|
cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
|
||||||
rol bx, 8 ; this doesnt change the zero flag, does it ?
|
rol bx, 8 ; this doesnt change the zero flag, does it ?
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
@ -852,14 +914,14 @@ socket_check_port:
|
|||||||
mov esi, net_sockets
|
mov esi, net_sockets
|
||||||
|
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov esi, [esi + SOCKET.NextPtr]
|
mov esi, [esi + SOCKET_head.NextPtr]
|
||||||
or esi, esi
|
or esi, esi
|
||||||
jz .port_ok
|
jz .port_ok
|
||||||
|
|
||||||
cmp [esi + SOCKET.Type], ecx
|
cmp [esi + SOCKET_head.Type], ecx
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
cmp [esi + SOCKET.LocalPort], bx
|
cmp [esi + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
xor ebx, ebx
|
xor ebx, ebx
|
||||||
@ -868,19 +930,18 @@ socket_check_port:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------
|
;-----------------------------------------------
|
||||||
;
|
;
|
||||||
; SOCKET_internal_receiver
|
; SOCKET_internal_receiver
|
||||||
;
|
;
|
||||||
; Checks if any socket wants the received data
|
; Updates a socket with received data
|
||||||
; If so, update the socket
|
|
||||||
;
|
;
|
||||||
; IN: eax = socket number
|
; Note: the mutex must already be set !
|
||||||
; ecx = number of bytes
|
;
|
||||||
; esi = pointer to beginning of data
|
; IN: eax = socket ptr
|
||||||
; dx = Remote port (in INET byte order)
|
; ecx = size
|
||||||
; edi = IP address of sender
|
; esi = pointer to buffer
|
||||||
|
; edi = offset
|
||||||
;
|
;
|
||||||
; OUT: xxx
|
; OUT: xxx
|
||||||
;
|
;
|
||||||
@ -888,39 +949,20 @@ socket_check_port:
|
|||||||
align 4
|
align 4
|
||||||
socket_internal_receiver:
|
socket_internal_receiver:
|
||||||
|
|
||||||
DEBUGF 1,"internal socket receiver\n"
|
DEBUGF 1,"Internal socket receiver: buffer %x, offset: %x\n", esi, edi
|
||||||
|
|
||||||
lea ebx, [eax + SOCKET.lock]
|
push edi ; offset
|
||||||
call wait_mutex
|
push ecx ; size
|
||||||
|
push esi ; data_ptr
|
||||||
|
mov esi, esp
|
||||||
|
add_to_queue (eax + 2048), SOCKET_QUEUE_SIZE, 3*4, .full
|
||||||
|
DEBUGF 1,"Queued packet successfully\n"
|
||||||
|
add esp, 4*3
|
||||||
|
|
||||||
mov [eax + SOCKET.RemotePort], dx ; update remote port number
|
mov [eax + SOCKET_head.lock], 0
|
||||||
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
|
; flag an event to the application
|
||||||
mov edx, [eax + SOCKET.PID] ; get socket owner PID
|
mov edx, [eax + SOCKET_head.PID] ; get socket owner PID
|
||||||
mov ecx, 1
|
mov ecx, 1
|
||||||
mov esi, TASK_DATA + TASKDATA.pid
|
mov esi, TASK_DATA + TASKDATA.pid
|
||||||
|
|
||||||
@ -935,18 +977,20 @@ socket_internal_receiver:
|
|||||||
|
|
||||||
.found_pid:
|
.found_pid:
|
||||||
shl ecx, 8
|
shl ecx, 8
|
||||||
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
|
or [ecx + SLOT_BASE + APPDATA.event_mask], EVENT_NETWORK ; stack event
|
||||||
mov [check_idle_semaphore], 200
|
mov [check_idle_semaphore], 200
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.dump:
|
.full:
|
||||||
mov [eax + SOCKET.lock], 0
|
DEBUGF 1,"Socket %x is full!\n",eax
|
||||||
|
mov [eax + SOCKET_head.lock], 0
|
||||||
|
call kernel_free
|
||||||
|
add esp, 8
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Allocate memory for socket data and put new socket into the list
|
; Allocate memory for socket data and put new socket into the list
|
||||||
; Newly created socket is initialized with calling PID and number and
|
; Newly created socket is initialized with calling PID and number and
|
||||||
; put into beginning of list (which is a fastest way).
|
; put into beginning of list (which is a fastest way).
|
||||||
@ -963,27 +1007,30 @@ proc net_socket_alloc stdcall uses ebx ecx edx edi
|
|||||||
; zero-initialize allocated memory
|
; zero-initialize allocated memory
|
||||||
push eax
|
push eax
|
||||||
mov edi, eax
|
mov edi, eax
|
||||||
|
|
||||||
mov ecx, SOCKETBUFFSIZE / 4
|
mov ecx, SOCKETBUFFSIZE / 4
|
||||||
; cld
|
; cld
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
rep stosd
|
rep stosd
|
||||||
pop eax
|
pop eax
|
||||||
|
|
||||||
|
init_queue (eax + 2048)
|
||||||
|
|
||||||
; add socket to the list by changing pointers
|
; add socket to the list by changing pointers
|
||||||
mov ebx, net_sockets
|
mov ebx, net_sockets
|
||||||
push [ebx + SOCKET.NextPtr]
|
push [ebx + SOCKET_head.NextPtr]
|
||||||
mov [ebx + SOCKET.NextPtr], eax
|
mov [ebx + SOCKET_head.NextPtr], eax
|
||||||
mov [eax + SOCKET.PrevPtr], ebx
|
mov [eax + SOCKET_head.PrevPtr], ebx
|
||||||
pop ebx
|
pop ebx
|
||||||
mov [eax + SOCKET.NextPtr], ebx
|
mov [eax + SOCKET_head.NextPtr], ebx
|
||||||
or ebx, ebx
|
or ebx, ebx
|
||||||
jz @f
|
jz @f
|
||||||
mov [ebx + SOCKET.PrevPtr], eax
|
mov [ebx + SOCKET_head.PrevPtr], eax
|
||||||
|
|
||||||
@@: ; set socket owner PID to the one of calling process
|
@@: ; set socket owner PID to the one of calling process
|
||||||
mov ebx, [TASK_BASE]
|
mov ebx, [TASK_BASE]
|
||||||
mov ebx, [ebx + TASKDATA.pid]
|
mov ebx, [ebx + TASKDATA.pid]
|
||||||
mov [eax + SOCKET.PID], ebx
|
mov [eax + SOCKET_head.PID], ebx
|
||||||
|
|
||||||
; find first free socket number and use it
|
; find first free socket number and use it
|
||||||
;mov edx, ebx
|
;mov edx, ebx
|
||||||
@ -992,10 +1039,10 @@ proc net_socket_alloc stdcall uses ebx ecx edx edi
|
|||||||
.next_socket_number:
|
.next_socket_number:
|
||||||
inc ecx
|
inc ecx
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov ebx, [ebx + SOCKET.NextPtr]
|
mov ebx, [ebx + SOCKET_head.NextPtr]
|
||||||
or ebx, ebx
|
or ebx, ebx
|
||||||
jz .last_socket_number
|
jz .last_socket_number
|
||||||
cmp [ebx + SOCKET.Number], ecx
|
cmp [ebx + SOCKET_head.Number], ecx
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
;cmp [ebx + SOCKET.PID], edx
|
;cmp [ebx + SOCKET.PID], edx
|
||||||
;jne .next_socket
|
;jne .next_socket
|
||||||
@ -1003,7 +1050,7 @@ proc net_socket_alloc stdcall uses ebx ecx edx edi
|
|||||||
jmp .next_socket_number
|
jmp .next_socket_number
|
||||||
|
|
||||||
.last_socket_number:
|
.last_socket_number:
|
||||||
mov [eax + SOCKET.Number], ecx
|
mov [eax + SOCKET_head.Number], ecx
|
||||||
|
|
||||||
.exit:
|
.exit:
|
||||||
ret
|
ret
|
||||||
@ -1025,7 +1072,7 @@ proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD
|
|||||||
;mov ecx, [TASK_BASE]
|
;mov ecx, [TASK_BASE]
|
||||||
;mov ecx, [ecx + TASKDATA.pid]
|
;mov ecx, [ecx + TASKDATA.pid]
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov ebx, [ebx + SOCKET.NextPtr]
|
mov ebx, [ebx + SOCKET_head.NextPtr]
|
||||||
or ebx, ebx
|
or ebx, ebx
|
||||||
jz .error
|
jz .error
|
||||||
cmp ebx, eax
|
cmp ebx, eax
|
||||||
@ -1035,12 +1082,15 @@ proc net_socket_free stdcall uses ebx ecx edx, sockAddr:DWORD
|
|||||||
|
|
||||||
; okay, we found the correct one
|
; okay, we found the correct one
|
||||||
; remove it from the list first, changing pointers
|
; remove it from the list first, changing pointers
|
||||||
mov ebx, [eax + SOCKET.NextPtr]
|
mov ebx, [eax + SOCKET_head.NextPtr]
|
||||||
mov eax, [eax + SOCKET.PrevPtr]
|
mov eax, [eax + SOCKET_head.PrevPtr]
|
||||||
mov [eax + SOCKET.NextPtr], ebx
|
mov [eax + SOCKET_head.NextPtr], ebx
|
||||||
or ebx, ebx
|
or ebx, ebx
|
||||||
jz @f
|
jz @f
|
||||||
mov [ebx + SOCKET.PrevPtr], eax
|
mov [ebx + SOCKET_head.PrevPtr], eax
|
||||||
|
|
||||||
|
lea ebx, [eax + SOCKET_head.lock]
|
||||||
|
call wait_mutex
|
||||||
|
|
||||||
@@: ; and finally free the memory structure used
|
@@: ; and finally free the memory structure used
|
||||||
stdcall kernel_free, [sockAddr]
|
stdcall kernel_free, [sockAddr]
|
||||||
@ -1070,10 +1120,10 @@ proc net_socket_num_to_addr stdcall uses ebx ecx, sockNum:DWORD
|
|||||||
;mov ecx, [TASK_BASE]
|
;mov ecx, [TASK_BASE]
|
||||||
;mov ecx, [ecx + TASKDATA.pid]
|
;mov ecx, [ecx + TASKDATA.pid]
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov ebx, [ebx + SOCKET.NextPtr]
|
mov ebx, [ebx + SOCKET_head.NextPtr]
|
||||||
or ebx, ebx
|
or ebx, ebx
|
||||||
jz .error
|
jz .error
|
||||||
cmp [ebx + SOCKET.Number], eax
|
cmp [ebx + SOCKET_head.Number], eax
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
;cmp [ebx + SOCKET.PID], ecx
|
;cmp [ebx + SOCKET.PID], ecx
|
||||||
;jne .next_socket
|
;jne .next_socket
|
||||||
@ -1106,7 +1156,7 @@ proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD
|
|||||||
;mov ecx, [TASK_BASE]
|
;mov ecx, [TASK_BASE]
|
||||||
;mov ecx, [ecx + TASKDATA.pid]
|
;mov ecx, [ecx + TASKDATA.pid]
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov ebx, [ebx + SOCKET.NextPtr]
|
mov ebx, [ebx + SOCKET_head.NextPtr]
|
||||||
or ebx, ebx
|
or ebx, ebx
|
||||||
jz .error
|
jz .error
|
||||||
cmp ebx, eax
|
cmp ebx, eax
|
||||||
@ -1115,7 +1165,7 @@ proc net_socket_addr_to_num stdcall uses ebx ecx, sockAddr:DWORD
|
|||||||
;jne .next_socket
|
;jne .next_socket
|
||||||
|
|
||||||
; okay, we found the correct one
|
; okay, we found the correct one
|
||||||
mov eax, [ebx + SOCKET.Number]
|
mov eax, [ebx + SOCKET_head.Number]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
|
@ -33,7 +33,7 @@ ETHER equ 1337
|
|||||||
ETHER_ARP equ 0x0608
|
ETHER_ARP equ 0x0608
|
||||||
|
|
||||||
;AF_UNSPEC equ 0
|
;AF_UNSPEC equ 0
|
||||||
;AF_UNIX equ 1
|
AF_UNIX equ 1
|
||||||
AF_INET4 equ 2
|
AF_INET4 equ 2
|
||||||
;AF_AX25 equ 3
|
;AF_AX25 equ 3
|
||||||
;AF_IPX equ 4
|
;AF_IPX equ 4
|
||||||
@ -64,7 +64,7 @@ include "ARP.inc"
|
|||||||
include "IPv4.inc"
|
include "IPv4.inc"
|
||||||
include "ethernet.inc"
|
include "ethernet.inc"
|
||||||
include "socket.inc"
|
include "socket.inc"
|
||||||
;include "tcp.inc"
|
include "tcp.inc"
|
||||||
include "udp.inc"
|
include "udp.inc"
|
||||||
include "icmp.inc"
|
include "icmp.inc"
|
||||||
|
|
||||||
@ -86,6 +86,7 @@ stack_init:
|
|||||||
call IPv4_init
|
call IPv4_init
|
||||||
call ARP_init
|
call ARP_init
|
||||||
call UDP_init
|
call UDP_init
|
||||||
|
call TCP_init
|
||||||
call ICMP_init
|
call ICMP_init
|
||||||
call socket_init
|
call socket_init
|
||||||
|
|
||||||
@ -115,20 +116,20 @@ stack_handler:
|
|||||||
cmp [ETH_RUNNING], 0
|
cmp [ETH_RUNNING], 0
|
||||||
je .exit
|
je .exit
|
||||||
|
|
||||||
call ETH_handler ; handle all queued ethernet packets
|
; Test for 10ms tick
|
||||||
call ETH_send_queued
|
|
||||||
|
|
||||||
; Test for 10ms tick, call tcp timer
|
|
||||||
mov eax, [timer_ticks]
|
mov eax, [timer_ticks]
|
||||||
cmp eax, [last_1hsTick]
|
cmp eax, [last_1hsTick]
|
||||||
je .exit
|
je .exit
|
||||||
|
|
||||||
mov [last_1hsTick], eax
|
mov [last_1hsTick], eax
|
||||||
; call tcp_tx_handler
|
|
||||||
|
call ETH_handler ; handle all queued ethernet packets
|
||||||
|
call ETH_send_queued
|
||||||
|
call TCP_send_queued
|
||||||
|
|
||||||
.sec_tick:
|
.sec_tick:
|
||||||
|
|
||||||
; Test for 1 second event, call 1s timer functions
|
; Test for 1 second event
|
||||||
mov al, 0x0 ;second
|
mov al, 0x0 ;second
|
||||||
out 0x70, al
|
out 0x70, al
|
||||||
in al, 0x71
|
in al, 0x71
|
||||||
@ -139,48 +140,84 @@ stack_handler:
|
|||||||
|
|
||||||
call ARP_decrease_entry_ttls
|
call ARP_decrease_entry_ttls
|
||||||
call IPv4_decrease_fragment_ttls
|
call IPv4_decrease_fragment_ttls
|
||||||
; call tcp_tcb_handler
|
call TCP_decrease_socket_ttls
|
||||||
|
|
||||||
.exit:
|
.exit:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
;; Checksum [by Johnny_B]
|
|
||||||
;; IN:
|
|
||||||
;; buf_ptr=POINTER to buffer
|
|
||||||
;; buf_size=SIZE of buffer
|
|
||||||
;; OUT:
|
|
||||||
;; AX=16-bit checksum
|
|
||||||
;; Saves all used registers
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
||||||
proc checksum_jb stdcall uses ebx esi ecx,\
|
|
||||||
buf_ptr:DWORD, buf_size:DWORD
|
|
||||||
|
|
||||||
xor eax, eax
|
|
||||||
xor ebx, ebx ;accumulator
|
|
||||||
mov esi, dword[buf_ptr]
|
|
||||||
mov ecx, dword[buf_size]
|
|
||||||
shr ecx, 1 ; ecx=ecx/2
|
|
||||||
jnc @f ; if CF==0 then size is even number
|
|
||||||
mov bh, byte[esi + ecx*2]
|
|
||||||
@@:
|
|
||||||
cld
|
|
||||||
|
|
||||||
.loop:
|
;-----------------------------------------------------------------
|
||||||
lodsw ;eax=word[esi],esi=esi+2
|
;
|
||||||
xchg ah,al ;cause must be a net byte-order
|
; checksum_1
|
||||||
add ebx, eax
|
;
|
||||||
loop .loop
|
; This is the first of two functions needed to calculate the TCP checksum.
|
||||||
|
;
|
||||||
|
; IN: edx = start offeset for semi-checksum
|
||||||
|
; esi = pointer to data
|
||||||
|
; ecx = data size
|
||||||
|
; OUT: edx = semi-checksum
|
||||||
|
;
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
|
||||||
mov eax, ebx
|
align 4
|
||||||
shr eax, 16
|
checksum_1:
|
||||||
add ax, bx
|
|
||||||
not ax
|
|
||||||
|
|
||||||
ret
|
xor eax, eax
|
||||||
endp
|
shr ecx, 1
|
||||||
|
pushf
|
||||||
|
.loop:
|
||||||
|
lodsw
|
||||||
|
xchg al, ah
|
||||||
|
add edx, eax
|
||||||
|
loop .loop
|
||||||
|
|
||||||
|
popf
|
||||||
|
jnc .end
|
||||||
|
|
||||||
|
lodsb
|
||||||
|
shl ax, 8
|
||||||
|
add edx, eax
|
||||||
|
|
||||||
|
.end:
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
;
|
||||||
|
; checksum_2
|
||||||
|
;
|
||||||
|
; This function calculates the final ip/tcp/udp checksum for you
|
||||||
|
;
|
||||||
|
; IN: edx = semi-checksum
|
||||||
|
; OUT: dx = checksum (in INET byte order)
|
||||||
|
;
|
||||||
|
;-----------------------------------------------------------------
|
||||||
|
|
||||||
|
align 4
|
||||||
|
checksum_2:
|
||||||
|
|
||||||
|
mov ecx, edx
|
||||||
|
shr ecx, 16
|
||||||
|
and edx, 0xffff
|
||||||
|
add edx, ecx
|
||||||
|
mov eax, edx
|
||||||
|
shr eax, 16
|
||||||
|
add edx, eax
|
||||||
|
|
||||||
|
not dx
|
||||||
|
jnz .not_zero
|
||||||
|
dec dx
|
||||||
|
.not_zero:
|
||||||
|
xchg dl, dh
|
||||||
|
|
||||||
|
DEBUGF 1,"Checksum: %x\n",dx
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -250,6 +287,14 @@ sys_network:
|
|||||||
jmp .return
|
jmp .return
|
||||||
|
|
||||||
@@:
|
@@:
|
||||||
|
dec bl ; 4 = Get driver pointer
|
||||||
|
jnz @f
|
||||||
|
|
||||||
|
; ..;
|
||||||
|
|
||||||
|
|
||||||
|
@@:
|
||||||
|
; ... ; 5 Get driver name
|
||||||
|
|
||||||
.doesnt_exist:
|
.doesnt_exist:
|
||||||
DEBUGF 1,"sys_network: invalid device/function specified!\n"
|
DEBUGF 1,"sys_network: invalid device/function specified!\n"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -75,7 +75,33 @@ align 4
|
|||||||
UDP_handler:
|
UDP_handler:
|
||||||
|
|
||||||
DEBUGF 1,"UDP_Handler\n"
|
DEBUGF 1,"UDP_Handler\n"
|
||||||
; TODO: First validate the header & checksum!
|
; First validate, checksum:
|
||||||
|
|
||||||
|
DEBUGF 1,"Real UDP checksum: %x\n", [edx + UDP_Packet.Checksum]:4
|
||||||
|
mov [edx + UDP_Packet.Checksum], 0
|
||||||
|
|
||||||
|
pusha
|
||||||
|
|
||||||
|
rol cx, 8
|
||||||
|
push cx
|
||||||
|
rol cx, 8
|
||||||
|
push word IP_PROTO_UDP shl 8
|
||||||
|
push edi
|
||||||
|
push esi
|
||||||
|
|
||||||
|
mov esi, edx
|
||||||
|
xor edx, edx
|
||||||
|
call checksum_1
|
||||||
|
; Checksum for pseudoheader
|
||||||
|
mov ecx, 12
|
||||||
|
mov esi, esp
|
||||||
|
call checksum_1
|
||||||
|
add esp, 12
|
||||||
|
call checksum_2
|
||||||
|
|
||||||
|
popa
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; Look for a socket where
|
; Look for a socket where
|
||||||
; IP Packet UDP Destination Port = local Port
|
; IP Packet UDP Destination Port = local Port
|
||||||
@ -85,14 +111,14 @@ UDP_handler:
|
|||||||
.try_more:
|
.try_more:
|
||||||
mov bx , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
|
mov bx , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov eax, [eax + SOCKET.NextPtr]
|
mov eax, [eax + SOCKET_head.NextPtr]
|
||||||
or eax, eax
|
or eax, eax
|
||||||
jz .dump
|
jz .dump
|
||||||
cmp [eax + SOCKET.Domain], AF_INET4
|
cmp [eax + SOCKET_head.Domain], AF_INET4
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
cmp [eax + SOCKET.Type], IP_PROTO_UDP
|
cmp [eax + SOCKET_head.Type], IP_PROTO_UDP
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
cmp [eax + SOCKET.LocalPort], bx
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort], bx
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
DEBUGF 1,"found socket with matching domain, type and localport\n"
|
DEBUGF 1,"found socket with matching domain, type and localport\n"
|
||||||
@ -101,12 +127,12 @@ UDP_handler:
|
|||||||
; I will accept the first incoming response to be the one
|
; 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
|
; I bind to, if the socket is opened with a destination IP address of
|
||||||
; 255.255.255.255
|
; 255.255.255.255
|
||||||
cmp [eax + SOCKET.RemoteIP], 0xffffffff
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], 0xffffffff
|
||||||
je .ok1
|
je .ok1
|
||||||
|
|
||||||
mov ebx, [esp]
|
mov ebx, [esp]
|
||||||
mov ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet FIXME
|
mov ebx, [ebx + ETH_FRAME.Data + IPv4_Packet.SourceAddress] ; get the Source address from the IP Packet FIXME
|
||||||
cmp [eax + SOCKET.RemoteIP], ebx
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], ebx
|
||||||
jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
|
jne .try_more ; Quit if the source IP is not valid, check for more sockets with this IP/PORT combination
|
||||||
|
|
||||||
|
|
||||||
@ -115,10 +141,10 @@ UDP_handler:
|
|||||||
|
|
||||||
mov bx, [edx + UDP_Packet.SourcePort] ; Remote port must be 0, or equal to sourceport of packet
|
mov bx, [edx + UDP_Packet.SourcePort] ; Remote port must be 0, or equal to sourceport of packet
|
||||||
|
|
||||||
cmp [eax + SOCKET.RemotePort], 0
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], 0
|
||||||
je .ok2
|
je .ok2
|
||||||
|
|
||||||
cmp [eax + SOCKET.RemotePort], bx
|
cmp [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], bx
|
||||||
jne .dump
|
jne .dump
|
||||||
|
|
||||||
.ok2:
|
.ok2:
|
||||||
@ -130,10 +156,21 @@ UDP_handler:
|
|||||||
sub cx , UDP_Packet.Data
|
sub cx , UDP_Packet.Data
|
||||||
mov dx , bx
|
mov dx , bx
|
||||||
|
|
||||||
call socket_internal_receiver
|
|
||||||
|
|
||||||
|
lea ebx, [eax + SOCKET_head.lock]
|
||||||
|
call wait_mutex
|
||||||
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort], dx ; update remote port number
|
||||||
|
mov [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP], edi
|
||||||
inc [UDP_PACKETS_RX]
|
inc [UDP_PACKETS_RX]
|
||||||
|
|
||||||
|
pop edi
|
||||||
|
add esp, 4
|
||||||
|
|
||||||
|
sub esi, edi
|
||||||
|
xchg esi, edi
|
||||||
|
jmp socket_internal_receiver
|
||||||
|
|
||||||
|
|
||||||
.dump:
|
.dump:
|
||||||
DEBUGF 1,"Dumping UDP packet\n"
|
DEBUGF 1,"Dumping UDP packet\n"
|
||||||
call kernel_free
|
call kernel_free
|
||||||
@ -146,69 +183,93 @@ UDP_handler:
|
|||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; Note: UDP works only on top of IP protocol :)
|
; UDP_socket_send
|
||||||
;
|
;
|
||||||
; IN: eax = dest ip
|
; IN: eax = socket pointer
|
||||||
; ebx = source ip
|
; ecx = number of bytes to send
|
||||||
; ecx = data length
|
; esi = pointer to data
|
||||||
; edx = remote port shl 16 + local port (both in INET order)
|
|
||||||
; esi = data offset
|
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
|
|
||||||
UDP_create_packet:
|
align 4
|
||||||
|
UDP_socket_send:
|
||||||
|
|
||||||
|
mov edx, dword [eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort] ; load local port and remote port at once
|
||||||
|
DEBUGF 1,"local port: %x, remote port: %x\n",\
|
||||||
|
[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.LocalPort]:4,\
|
||||||
|
[eax + SOCKET_head.end + IPv4_SOCKET.end + UDP_SOCKET.RemotePort]:4
|
||||||
|
mov ebx, [eax + SOCKET_head.end + IPv4_SOCKET.LocalIP]
|
||||||
|
mov eax, [eax + SOCKET_head.end + IPv4_SOCKET.RemoteIP]
|
||||||
|
|
||||||
DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
|
DEBUGF 1,"Create UDP Packet (size=%u)\n",ecx
|
||||||
|
|
||||||
push edx esi
|
|
||||||
|
|
||||||
add ecx, UDP_Packet.Data
|
|
||||||
mov di , IP_PROTO_UDP
|
mov di , IP_PROTO_UDP
|
||||||
|
|
||||||
; dx = fragment id
|
sub esp, 8 ; reserve some place in stack for later
|
||||||
|
|
||||||
|
; Create the pseudoheader in stack,
|
||||||
|
; (now that we still have all the variables that are needed.)
|
||||||
|
push dword IP_PROTO_UDP shl 8
|
||||||
|
push eax
|
||||||
|
push ebx
|
||||||
|
|
||||||
|
add ecx, UDP_Packet.Data
|
||||||
|
|
||||||
|
; TODO: fill in: dx = fragment id
|
||||||
|
|
||||||
|
push edx esi
|
||||||
call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6
|
call IPv4_create_packet ; TODO: figure out a way to choose between IPv4 and IPv6
|
||||||
cmp edi, -1
|
cmp edi, -1
|
||||||
je .fail
|
je .fail
|
||||||
|
|
||||||
mov byte[edi + UDP_Packet.Length], ch
|
mov [esp + 8 + 12], eax ; pointer to buffer start
|
||||||
mov byte[edi + UDP_Packet.Length+1], cl
|
mov [esp + 8 + 12 + 4], edx ; buffer size
|
||||||
sub ecx , UDP_Packet.Data
|
|
||||||
|
rol cx, 8
|
||||||
|
mov [edi + UDP_Packet.Length], cx
|
||||||
|
mov [esp + 8 + 10], cx
|
||||||
|
ror cx, 8
|
||||||
|
|
||||||
pop esi
|
pop esi
|
||||||
push edi
|
push edi ecx
|
||||||
|
sub ecx, UDP_Packet.Data
|
||||||
add edi, UDP_Packet.Data
|
add edi, UDP_Packet.Data
|
||||||
push cx
|
|
||||||
shr ecx, 2
|
shr ecx, 2
|
||||||
rep movsd
|
rep movsd
|
||||||
pop cx
|
mov ecx, [esp]
|
||||||
and cx , 3
|
and cx , 3
|
||||||
rep movsb
|
rep movsb
|
||||||
pop edi
|
pop ecx edi
|
||||||
|
|
||||||
pop ecx
|
pop dword [edi + UDP_Packet.SourcePort] ; fill in both portnumbers
|
||||||
mov dword [edi + UDP_Packet.SourcePort], ecx ; notice: we write both port's at once
|
mov [edi + UDP_Packet.Checksum], 0 ; set it to zero, to calculate checksum
|
||||||
|
|
||||||
mov [edi + UDP_Packet.Checksum], 0
|
; Checksum for UDP header + data
|
||||||
|
xor edx, edx
|
||||||
; TODO: calculate checksum using Pseudo-header (However, using a 0 as checksum shouldnt generate any errors :)
|
mov esi, edi
|
||||||
|
call checksum_1
|
||||||
|
; Checksum for pseudoheader
|
||||||
|
mov ecx, 12
|
||||||
|
mov esi, esp
|
||||||
|
call checksum_1
|
||||||
|
add esp, 12 ; remove the pseudoheader from stack
|
||||||
|
; Now create the final checksum and store it in UDP header
|
||||||
|
call checksum_2
|
||||||
|
mov [edi + UDP_Packet.Checksum], dx
|
||||||
|
|
||||||
inc [UDP_PACKETS_TX]
|
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 ;
|
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx ;
|
||||||
jmp ETH_Sender ;
|
jmp ETH_sender ;
|
||||||
|
|
||||||
.exit:
|
|
||||||
ret
|
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
; todo: queue the packet
|
; todo: queue the packet
|
||||||
add esp, 8
|
add esp, 8+12+8
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
;---------------------------------------------------------------------------
|
;---------------------------------------------------------------------------
|
||||||
;
|
;
|
||||||
; UDP_API
|
; UDP_API
|
||||||
|
Loading…
Reference in New Issue
Block a user