forked from KolibriOS/kolibrios
Fixed TCP and UDP checksum in net branch.
git-svn-id: svn://kolibrios.org@2390 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
4b6a83bfa4
commit
85c176d7f5
File diff suppressed because it is too large
Load Diff
@ -16,65 +16,67 @@
|
||||
|
||||
$Revision$
|
||||
|
||||
macro TCP_checksum IP1, IP2 {
|
||||
macro TCP_checksum IP1, IP2 {
|
||||
|
||||
;-------------
|
||||
; Pseudoheader
|
||||
|
||||
; protocol type
|
||||
mov edx, IP_PROTO_TCP
|
||||
; protocol type
|
||||
mov edx, IP_PROTO_TCP
|
||||
|
||||
; source address
|
||||
add dl, byte [IP1+1]
|
||||
adc dh, byte [IP1+0]
|
||||
adc dl, byte [IP1+3]
|
||||
adc dh, byte [IP1+2]
|
||||
; source address
|
||||
add dl, byte [IP1+1]
|
||||
adc dh, byte [IP1+0]
|
||||
adc dl, byte [IP1+3]
|
||||
adc dh, byte [IP1+2]
|
||||
|
||||
; destination address
|
||||
adc dl, byte [IP2+1]
|
||||
adc dh, byte [IP2+0]
|
||||
adc dl, byte [IP2+3]
|
||||
adc dh, byte [IP2+2]
|
||||
; destination address
|
||||
adc dl, byte [IP2+1]
|
||||
adc dh, byte [IP2+0]
|
||||
adc dl, byte [IP2+3]
|
||||
adc dh, byte [IP2+2]
|
||||
|
||||
; size
|
||||
adc dl, cl
|
||||
adc dh, ch
|
||||
; size
|
||||
adc dl, cl
|
||||
adc dh, ch
|
||||
|
||||
adc edx, 0
|
||||
|
||||
;---------------------
|
||||
; Real header and data
|
||||
|
||||
push esi
|
||||
call checksum_1
|
||||
call checksum_2
|
||||
pop esi
|
||||
push esi
|
||||
call checksum_1
|
||||
call checksum_2
|
||||
pop esi
|
||||
|
||||
} ; returns in dx only
|
||||
} ; returns in dx only
|
||||
|
||||
|
||||
|
||||
|
||||
macro TCP_sendseqinit ptr {
|
||||
macro TCP_sendseqinit ptr {
|
||||
|
||||
push edi ;;;; i dont like this static use of edi
|
||||
mov edi, [ptr + TCP_SOCKET.ISS]
|
||||
mov [ptr + TCP_SOCKET.SND_UP], edi
|
||||
mov [ptr + TCP_SOCKET.SND_MAX], edi
|
||||
mov [ptr + TCP_SOCKET.SND_NXT], edi
|
||||
mov [ptr + TCP_SOCKET.SND_UNA], edi
|
||||
pop edi
|
||||
push edi ;;;; i dont like this static use of edi
|
||||
mov edi, [ptr + TCP_SOCKET.ISS]
|
||||
mov [ptr + TCP_SOCKET.SND_UP], edi
|
||||
mov [ptr + TCP_SOCKET.SND_MAX], edi
|
||||
mov [ptr + TCP_SOCKET.SND_NXT], edi
|
||||
mov [ptr + TCP_SOCKET.SND_UNA], edi
|
||||
pop edi
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
macro TCP_rcvseqinit ptr {
|
||||
macro TCP_rcvseqinit ptr {
|
||||
|
||||
push edi
|
||||
mov edi, [ptr + TCP_SOCKET.IRS]
|
||||
inc edi
|
||||
mov [ptr + TCP_SOCKET.RCV_NXT], edi
|
||||
mov [ptr + TCP_SOCKET.RCV_ADV], edi
|
||||
pop edi
|
||||
push edi
|
||||
mov edi, [ptr + TCP_SOCKET.IRS]
|
||||
inc edi
|
||||
mov [ptr + TCP_SOCKET.RCV_NXT], edi
|
||||
mov [ptr + TCP_SOCKET.RCV_ADV], edi
|
||||
pop edi
|
||||
|
||||
}
|
||||
|
||||
@ -102,11 +104,11 @@ macro TCP_rcvseqinit ptr {
|
||||
align 4
|
||||
TCP_pull_out_of_band:
|
||||
|
||||
DEBUGF 1,"TCP_pull_out_of_band\n"
|
||||
DEBUGF 1,"TCP_pull_out_of_band\n"
|
||||
|
||||
;;;; 1282-1305
|
||||
;;;; 1282-1305
|
||||
|
||||
ret
|
||||
ret
|
||||
|
||||
|
||||
|
||||
@ -128,18 +130,18 @@ TCP_pull_out_of_band:
|
||||
align 4
|
||||
TCP_drop:
|
||||
|
||||
DEBUGF 1,"TCP_drop\n"
|
||||
DEBUGF 1,"TCP_drop\n"
|
||||
|
||||
cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
|
||||
jb .no_syn_received
|
||||
cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
|
||||
jb .no_syn_received
|
||||
|
||||
mov [eax + TCP_SOCKET.t_state], TCPS_CLOSED
|
||||
mov [eax + TCP_SOCKET.t_state], TCPS_CLOSED
|
||||
|
||||
call TCP_output
|
||||
call TCP_output
|
||||
|
||||
;;; TODO: update stats
|
||||
|
||||
jmp TCP_close
|
||||
jmp TCP_close
|
||||
|
||||
.no_syn_received:
|
||||
|
||||
@ -147,7 +149,7 @@ TCP_drop:
|
||||
|
||||
;;; TODO: check if error code is "Connection timed out' and handle accordingly
|
||||
|
||||
mov [eax + SOCKET.errorcode], ebx
|
||||
mov [eax + SOCKET.errorcode], ebx
|
||||
|
||||
|
||||
|
||||
@ -167,15 +169,15 @@ TCP_drop:
|
||||
align 4
|
||||
TCP_close:
|
||||
|
||||
DEBUGF 1,"TCP_close\n"
|
||||
DEBUGF 1,"TCP_close\n"
|
||||
|
||||
;;; TODO: update RTT and mean deviation
|
||||
;;; TODO: update slow start threshold
|
||||
;;; TODO: release connection resources
|
||||
|
||||
call SOCKET_is_disconnected
|
||||
call SOCKET_is_disconnected
|
||||
|
||||
ret
|
||||
ret
|
||||
|
||||
|
||||
|
||||
@ -198,26 +200,26 @@ TCP_close:
|
||||
align 4
|
||||
TCP_outflags:
|
||||
|
||||
mov edx, [eax + TCP_SOCKET.t_state]
|
||||
movzx edx, byte [edx + .flaglist]
|
||||
mov edx, [eax + TCP_SOCKET.t_state]
|
||||
movzx edx, byte [edx + .flaglist]
|
||||
|
||||
DEBUGF 1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl
|
||||
DEBUGF 1,"TCP_outflags, socket: %x, flags: %x\n", eax, dl
|
||||
|
||||
ret
|
||||
ret
|
||||
|
||||
.flaglist:
|
||||
|
||||
db TH_RST + TH_ACK ; TCPS_CLOSED
|
||||
db 0 ; TCPS_LISTEN
|
||||
db TH_SYN ; TCPS_SYN_SENT
|
||||
db TH_SYN + TH_ACK ; TCPS_SYN_RECEIVED
|
||||
db TH_ACK ; TCPS_ESTABLISHED
|
||||
db TH_ACK ; TCPS_CLOSE_WAIT
|
||||
db TH_SYN + TH_ACK ; TCPS_FIN_WAIT_1
|
||||
db TH_SYN + TH_ACK ; TCPS_CLOSING
|
||||
db TH_SYN + TH_ACK ; TCPS_LAST_ACK
|
||||
db TH_ACK ; TCPS_FIN_WAIT_2
|
||||
db TH_ACK ; TCPS_TIMED_WAIT
|
||||
db TH_RST + TH_ACK ; TCPS_CLOSED
|
||||
db 0 ; TCPS_LISTEN
|
||||
db TH_SYN ; TCPS_SYN_SENT
|
||||
db TH_SYN + TH_ACK ; TCPS_SYN_RECEIVED
|
||||
db TH_ACK ; TCPS_ESTABLISHED
|
||||
db TH_ACK ; TCPS_CLOSE_WAIT
|
||||
db TH_SYN + TH_ACK ; TCPS_FIN_WAIT_1
|
||||
db TH_SYN + TH_ACK ; TCPS_CLOSING
|
||||
db TH_SYN + TH_ACK ; TCPS_LAST_ACK
|
||||
db TH_ACK ; TCPS_FIN_WAIT_2
|
||||
db TH_ACK ; TCPS_TIMED_WAIT
|
||||
|
||||
|
||||
|
||||
@ -237,69 +239,69 @@ TCP_outflags:
|
||||
align 4
|
||||
TCP_respond_socket:
|
||||
|
||||
DEBUGF 1,"TCP_respond_socket\n"
|
||||
DEBUGF 1,"TCP_respond_socket\n"
|
||||
|
||||
;---------------------
|
||||
; Create the IP packet
|
||||
|
||||
push cx ebx
|
||||
mov eax, [ebx + IP_SOCKET.RemoteIP]
|
||||
mov ebx, [ebx + IP_SOCKET.LocalIP]
|
||||
mov ecx, sizeof.TCP_header
|
||||
mov di , IP_PROTO_TCP shl 8 + 128
|
||||
call IPv4_output
|
||||
test edi, edi
|
||||
jz .error
|
||||
pop esi cx
|
||||
push edx eax
|
||||
push cx ebx
|
||||
mov eax, [ebx + IP_SOCKET.RemoteIP]
|
||||
mov ebx, [ebx + IP_SOCKET.LocalIP]
|
||||
mov ecx, sizeof.TCP_header
|
||||
mov di , IP_PROTO_TCP shl 8 + 128
|
||||
call IPv4_output
|
||||
test edi, edi
|
||||
jz .error
|
||||
pop esi cx
|
||||
push edx eax
|
||||
|
||||
;-----------------------------------------------
|
||||
; Fill in the TCP header by using the socket ptr
|
||||
|
||||
mov ax, [esi + TCP_SOCKET.LocalPort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov ax, [esi + TCP_SOCKET.RemotePort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov eax, [esi + TCP_SOCKET.SND_NXT]
|
||||
bswap eax
|
||||
stosd
|
||||
mov eax, [esi + TCP_SOCKET.RCV_NXT]
|
||||
bswap eax
|
||||
stosd
|
||||
mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset)
|
||||
stosb
|
||||
mov al, cl
|
||||
stosb
|
||||
mov ax, [esi + TCP_SOCKET.LocalPort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov ax, [esi + TCP_SOCKET.RemotePort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov eax, [esi + TCP_SOCKET.SND_NXT]
|
||||
bswap eax
|
||||
stosd
|
||||
mov eax, [esi + TCP_SOCKET.RCV_NXT]
|
||||
bswap eax
|
||||
stosd
|
||||
mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset)
|
||||
stosb
|
||||
mov al, cl
|
||||
stosb
|
||||
; mov ax, [esi + TCP_SOCKET.RCV_WND]
|
||||
; rol ax, 8
|
||||
mov ax, 0x00a0 ;;;;;;; FIXME
|
||||
stosw ; window
|
||||
xor eax, eax
|
||||
stosd ; checksum + urgentpointer
|
||||
mov ax, 0x00a0 ;;;;;;; FIXME
|
||||
stosw ; window
|
||||
xor eax, eax
|
||||
stosd ; checksum + urgentpointer
|
||||
|
||||
;---------------------
|
||||
; Fill in the checksum
|
||||
|
||||
.checksum:
|
||||
sub edi, sizeof.TCP_header
|
||||
mov ecx, sizeof.TCP_header
|
||||
xchg esi, edi
|
||||
TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
|
||||
mov [esi+TCP_header.Checksum], dx
|
||||
sub edi, sizeof.TCP_header
|
||||
mov ecx, sizeof.TCP_header
|
||||
xchg esi, edi
|
||||
TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
|
||||
mov [esi+TCP_header.Checksum], dx
|
||||
|
||||
;--------------------
|
||||
; And send the segment
|
||||
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
|
||||
.error:
|
||||
DEBUGF 1,"TCP_respond failed\n"
|
||||
add esp, 2+4
|
||||
DEBUGF 1,"TCP_respond failed\n"
|
||||
add esp, 2+4
|
||||
|
||||
ret
|
||||
ret
|
||||
|
||||
|
||||
|
||||
@ -319,67 +321,67 @@ TCP_respond_socket:
|
||||
align 4
|
||||
TCP_respond_segment:
|
||||
|
||||
DEBUGF 1,"TCP_respond_segment\n"
|
||||
DEBUGF 1,"TCP_respond_segment\n"
|
||||
|
||||
;---------------------
|
||||
; Create the IP packet
|
||||
|
||||
push cx edx ebx
|
||||
mov ebx, [edi + 4]
|
||||
mov eax, [edi]
|
||||
mov ecx, sizeof.TCP_header
|
||||
mov di , IP_PROTO_TCP shl 8 + 128
|
||||
call IPv4_output
|
||||
jz .error
|
||||
pop ebx esi cx
|
||||
push cx edx ebx
|
||||
mov ebx, [edi + 4]
|
||||
mov eax, [edi]
|
||||
mov ecx, sizeof.TCP_header
|
||||
mov di , IP_PROTO_TCP shl 8 + 128
|
||||
call IPv4_output
|
||||
jz .error
|
||||
pop ebx esi cx
|
||||
|
||||
push edx eax
|
||||
push edx eax
|
||||
|
||||
;---------------------------------------------------
|
||||
; Fill in the TCP header by using a received segment
|
||||
|
||||
mov ax, [esi + TCP_header.DestinationPort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov ax, [esi + TCP_header.SourcePort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov eax, [esi + TCP_header.AckNumber]
|
||||
bswap eax
|
||||
stosd
|
||||
xor eax, eax
|
||||
stosd
|
||||
mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header)
|
||||
stosb
|
||||
mov al, cl
|
||||
stosb
|
||||
mov ax, 1280
|
||||
rol ax, 8
|
||||
stosw ; window
|
||||
xor eax, eax
|
||||
stosd ; checksum + urgentpointer
|
||||
mov ax, [esi + TCP_header.DestinationPort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov ax, [esi + TCP_header.SourcePort]
|
||||
rol ax, 8
|
||||
stosw
|
||||
mov eax, [esi + TCP_header.AckNumber]
|
||||
bswap eax
|
||||
stosd
|
||||
xor eax, eax
|
||||
stosd
|
||||
mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header)
|
||||
stosb
|
||||
mov al, cl
|
||||
stosb
|
||||
mov ax, 1280
|
||||
rol ax, 8
|
||||
stosw ; window
|
||||
xor eax, eax
|
||||
stosd ; checksum + urgentpointer
|
||||
|
||||
;---------------------
|
||||
; Fill in the checksum
|
||||
|
||||
.checksum:
|
||||
lea esi, [edi - sizeof.TCP_header]
|
||||
mov ecx, sizeof.TCP_header
|
||||
TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\ ; FIXME
|
||||
(esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
|
||||
mov [esi+TCP_header.Checksum], dx
|
||||
lea esi, [edi - sizeof.TCP_header]
|
||||
mov ecx, sizeof.TCP_header
|
||||
TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\ ; FIXME
|
||||
(esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
|
||||
mov [esi+TCP_header.Checksum], dx
|
||||
|
||||
;--------------------
|
||||
; And send the segment
|
||||
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
call [ebx + NET_DEVICE.transmit]
|
||||
ret
|
||||
|
||||
.error:
|
||||
DEBUGF 1,"TCP_respond failed\n"
|
||||
add esp, 2+4
|
||||
DEBUGF 1,"TCP_respond failed\n"
|
||||
add esp, 2+4
|
||||
|
||||
ret
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
@ -118,14 +118,15 @@ UDP_input:
|
||||
|
||||
DEBUGF 1,"UDP_input, size:%u\n", ecx
|
||||
|
||||
; First validate, checksum
|
||||
; First validate, checksum
|
||||
|
||||
neg [esi + UDP_header.Checksum] ; substract checksum from 0
|
||||
jz .no_checksum ; if checksum is zero, it is considered valid and we continue processing
|
||||
; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
|
||||
jz .no_checksum ; if checksum is zero, it is considered valid
|
||||
|
||||
; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
|
||||
|
||||
UDP_checksum (edi), (edi+4)
|
||||
;;; jnz .checksum_mismatch
|
||||
jnz .checksum_mismatch
|
||||
|
||||
.no_checksum:
|
||||
DEBUGF 1,"UDP Checksum is correct\n"
|
||||
@ -287,7 +288,7 @@ UDP_output:
|
||||
.fail:
|
||||
DEBUGF 1,"UDP_output: failed\n"
|
||||
add esp, 4+4+8
|
||||
xor eax, eax
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user