forked from KolibriOS/kolibrios
small updates and fixes in net branch
git-svn-id: svn://kolibrios.org@2308 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
df1f1777ac
commit
63bc53c598
File diff suppressed because it is too large
Load Diff
@ -21,87 +21,87 @@ $Revision$
|
|||||||
|
|
||||||
; ICMP types & codes
|
; ICMP types & codes
|
||||||
|
|
||||||
ICMP_ECHOREPLY equ 0 ; echo reply message
|
ICMP_ECHOREPLY equ 0 ; echo reply message
|
||||||
|
|
||||||
ICMP_UNREACH equ 3
|
ICMP_UNREACH equ 3
|
||||||
ICMP_UNREACH_NET equ 0 ; bad net
|
ICMP_UNREACH_NET equ 0 ; bad net
|
||||||
ICMP_UNREACH_HOST equ 1 ; bad host
|
ICMP_UNREACH_HOST equ 1 ; bad host
|
||||||
ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol
|
ICMP_UNREACH_PROTOCOL equ 2 ; bad protocol
|
||||||
ICMP_UNREACH_PORT equ 3 ; bad port
|
ICMP_UNREACH_PORT equ 3 ; bad port
|
||||||
ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop
|
ICMP_UNREACH_NEEDFRAG equ 4 ; IP_DF caused drop
|
||||||
ICMP_UNREACH_SRCFAIL equ 5 ; src route failed
|
ICMP_UNREACH_SRCFAIL equ 5 ; src route failed
|
||||||
ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net
|
ICMP_UNREACH_NET_UNKNOWN equ 6 ; unknown net
|
||||||
ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host
|
ICMP_UNREACH_HOST_UNKNOWN equ 7 ; unknown host
|
||||||
ICMP_UNREACH_ISOLATED equ 8 ; src host isolated
|
ICMP_UNREACH_ISOLATED equ 8 ; src host isolated
|
||||||
ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access
|
ICMP_UNREACH_NET_PROHIB equ 9 ; prohibited access
|
||||||
ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto
|
ICMP_UNREACH_HOST_PROHIB equ 10 ; ditto
|
||||||
ICMP_UNREACH_TOSNET equ 11 ; bad tos for net
|
ICMP_UNREACH_TOSNET equ 11 ; bad tos for net
|
||||||
ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host
|
ICMP_UNREACH_TOSHOST equ 12 ; bad tos for host
|
||||||
ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib
|
ICMP_UNREACH_FILTER_PROHIB equ 13 ; admin prohib
|
||||||
ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio.
|
ICMP_UNREACH_HOST_PRECEDENCE equ 14 ; host prec vio.
|
||||||
ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff
|
ICMP_UNREACH_PRECEDENCE_CUTOFF equ 15 ; prec cutoff
|
||||||
|
|
||||||
ICMP_SOURCEQUENCH equ 4 ; Packet lost, slow down
|
ICMP_SOURCEQUENCH equ 4 ; Packet lost, slow down
|
||||||
|
|
||||||
ICMP_REDIRECT equ 5 ; shorter route, codes:
|
ICMP_REDIRECT equ 5 ; shorter route, codes:
|
||||||
ICMP_REDIRECT_NET equ 0 ; for network
|
ICMP_REDIRECT_NET equ 0 ; for network
|
||||||
ICMP_REDIRECT_HOST equ 1 ; for host
|
ICMP_REDIRECT_HOST equ 1 ; for host
|
||||||
ICMP_REDIRECT_TOSNET equ 2 ; for tos and net
|
ICMP_REDIRECT_TOSNET equ 2 ; for tos and net
|
||||||
ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host
|
ICMP_REDIRECT_TOSHOST equ 3 ; for tos and host
|
||||||
|
|
||||||
ICMP_ALTHOSTADDR equ 6 ; alternate host address
|
ICMP_ALTHOSTADDR equ 6 ; alternate host address
|
||||||
ICMP_ECHO equ 8 ; echo service
|
ICMP_ECHO equ 8 ; echo service
|
||||||
ICMP_ROUTERADVERT equ 9 ; router advertisement
|
ICMP_ROUTERADVERT equ 9 ; router advertisement
|
||||||
ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement
|
ICMP_ROUTERADVERT_NORMAL equ 0 ; normal advertisement
|
||||||
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing
|
ICMP_ROUTERADVERT_NOROUTE_COMMON equ 16 ; selective routing
|
||||||
|
|
||||||
ICMP_ROUTERSOLICIT equ 10 ; router solicitation
|
ICMP_ROUTERSOLICIT equ 10 ; router solicitation
|
||||||
ICMP_TIMXCEED equ 11 ; time exceeded, code:
|
ICMP_TIMXCEED equ 11 ; time exceeded, code:
|
||||||
ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit
|
ICMP_TIMXCEED_INTRANS equ 0 ; ttl==0 in transit
|
||||||
ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass
|
ICMP_TIMXCEED_REASS equ 1 ; ttl==0 in reass
|
||||||
|
|
||||||
ICMP_PARAMPROB equ 12 ; ip header bad
|
ICMP_PARAMPROB equ 12 ; ip header bad
|
||||||
ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr
|
ICMP_PARAMPROB_ERRATPTR equ 0 ; error at param ptr
|
||||||
ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent
|
ICMP_PARAMPROB_OPTABSENT equ 1 ; req. opt. absent
|
||||||
ICMP_PARAMPROB_LENGTH equ 2 ; bad length
|
ICMP_PARAMPROB_LENGTH equ 2 ; bad length
|
||||||
|
|
||||||
ICMP_TSTAMP equ 13 ; timestamp request
|
ICMP_TSTAMP equ 13 ; timestamp request
|
||||||
ICMP_TSTAMPREPLY equ 14 ; timestamp reply
|
ICMP_TSTAMPREPLY equ 14 ; timestamp reply
|
||||||
ICMP_IREQ equ 15 ; information request
|
ICMP_IREQ equ 15 ; information request
|
||||||
ICMP_IREQREPLY equ 16 ; information reply
|
ICMP_IREQREPLY equ 16 ; information reply
|
||||||
ICMP_MASKREQ equ 17 ; address mask request
|
ICMP_MASKREQ equ 17 ; address mask request
|
||||||
ICMP_MASKREPLY equ 18 ; address mask reply
|
ICMP_MASKREPLY equ 18 ; address mask reply
|
||||||
ICMP_TRACEROUTE equ 30 ; traceroute
|
ICMP_TRACEROUTE equ 30 ; traceroute
|
||||||
ICMP_DATACONVERR equ 31 ; data conversion error
|
ICMP_DATACONVERR equ 31 ; data conversion error
|
||||||
ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect
|
ICMP_MOBILE_REDIRECT equ 32 ; mobile host redirect
|
||||||
ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you
|
ICMP_IPV6_WHEREAREYOU equ 33 ; IPv6 where-are-you
|
||||||
ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here
|
ICMP_IPV6_IAMHERE equ 34 ; IPv6 i-am-here
|
||||||
ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req
|
ICMP_MOBILE_REGREQUEST equ 35 ; mobile registration req
|
||||||
ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply
|
ICMP_MOBILE_REGREPLY equ 36 ; mobile registreation reply
|
||||||
ICMP_SKIP equ 39 ; SKIP
|
ICMP_SKIP equ 39 ; SKIP
|
||||||
|
|
||||||
ICMP_PHOTURIS equ 40 ; Photuris
|
ICMP_PHOTURIS equ 40 ; Photuris
|
||||||
ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index
|
ICMP_PHOTURIS_UNKNOWN_INDEX equ 1 ; unknown sec index
|
||||||
ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed
|
ICMP_PHOTURIS_AUTH_FAILED equ 2 ; auth failed
|
||||||
ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed
|
ICMP_PHOTURIS_DECRYPT_FAILED equ 3 ; decrypt failed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct ICMP_header
|
struct ICMP_header
|
||||||
|
|
||||||
Type db ?
|
Type db ?
|
||||||
Code db ?
|
Code db ?
|
||||||
Checksum dw ?
|
Checksum dw ?
|
||||||
Identifier dw ?
|
Identifier dw ?
|
||||||
SequenceNumber dw ?
|
SequenceNumber dw ?
|
||||||
|
|
||||||
ends
|
ends
|
||||||
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
uglobal
|
uglobal
|
||||||
ICMP_PACKETS_TX rd MAX_IP
|
ICMP_PACKETS_TX rd MAX_IP
|
||||||
ICMP_PACKETS_RX rd MAX_IP
|
ICMP_PACKETS_RX rd MAX_IP
|
||||||
endg
|
endg
|
||||||
|
|
||||||
|
|
||||||
@ -114,10 +114,10 @@ endg
|
|||||||
|
|
||||||
macro ICMP_init {
|
macro ICMP_init {
|
||||||
|
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
mov edi, ICMP_PACKETS_TX
|
mov edi, ICMP_PACKETS_TX
|
||||||
mov ecx, 2*MAX_IP
|
mov ecx, 2*MAX_IP
|
||||||
rep stosd
|
rep stosd
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,116 +134,116 @@ macro ICMP_init {
|
|||||||
; ebx = pointer to device struct
|
; ebx = pointer to device struct
|
||||||
; ecx = ICMP Packet size
|
; ecx = ICMP Packet size
|
||||||
; edx = ptr to ICMP Packet data
|
; edx = ptr to ICMP Packet data
|
||||||
; esi = ipv4 source address
|
; edi = ptr to ipv4 source and dest address
|
||||||
; edi = ipv4 dest address
|
;
|
||||||
; OUT: /
|
; OUT: /
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
align 4
|
align 4
|
||||||
ICMP_input:
|
ICMP_input:
|
||||||
|
|
||||||
DEBUGF 1,"ICMP_input - start\n"
|
DEBUGF 1,"ICMP_input - start\n"
|
||||||
|
|
||||||
; First, check the checksum (altough some implementations ignore it)
|
; First, check the checksum (altough some implementations ignore it)
|
||||||
|
|
||||||
push edx esi ecx
|
push edx ecx
|
||||||
push [edx + ICMP_header.Checksum]
|
push [edx + ICMP_header.Checksum]
|
||||||
mov [edx + ICMP_header.Checksum], 0
|
mov [edx + ICMP_header.Checksum], 0
|
||||||
mov esi, edx
|
mov esi, edx
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
call checksum_1
|
call checksum_1
|
||||||
call checksum_2
|
call checksum_2
|
||||||
pop si
|
pop si
|
||||||
cmp dx, si
|
cmp dx, si
|
||||||
pop ecx esi edx
|
pop ecx edx
|
||||||
jne .checksum_mismatch
|
jne .checksum_mismatch
|
||||||
|
|
||||||
cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request?
|
cmp [edx + ICMP_header.Type], ICMP_ECHO ; Is this an echo request?
|
||||||
jne .check_sockets
|
jne .check_sockets
|
||||||
|
|
||||||
; We well re-use the packet sow e can create the response as fast as possible
|
; We well re-use the packet so we can create the response as fast as possible
|
||||||
; Notice: this only works on pure ethernet (however, IP packet options are not a problem this time :)
|
; Notice: this only works on pure ethernet
|
||||||
|
|
||||||
DEBUGF 1,"ICMP_input - echo request\n"
|
DEBUGF 1,"ICMP_input - echo request\n"
|
||||||
mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply
|
mov [edx + ICMP_header.Type], ICMP_ECHOREPLY ; Change Packet type to reply
|
||||||
|
|
||||||
; Update stats (and validate device ptr)
|
; Update stats (and validate device ptr)
|
||||||
call NET_ptr_to_num
|
call NET_ptr_to_num
|
||||||
cmp edi,-1
|
cmp edi,-1
|
||||||
je .dump
|
je .dump
|
||||||
inc [ICMP_PACKETS_RX+4*edi]
|
inc [ICMP_PACKETS_RX+4*edi]
|
||||||
inc [ICMP_PACKETS_TX+4*edi]
|
inc [ICMP_PACKETS_TX+4*edi]
|
||||||
|
|
||||||
; exchange dest and source address in IP header
|
; exchange dest and source address in IP header
|
||||||
; exchange dest and source MAC in ETH header
|
; exchange dest and source MAC in ETH header
|
||||||
mov esi, [esp] ; Start of buffer
|
mov esi, [esp] ; Start of buffer
|
||||||
push dword [esi + ETH_header.DstMAC]
|
push dword [esi + ETH_header.DstMAC]
|
||||||
push dword [esi + ETH_header.SrcMAC]
|
push dword [esi + ETH_header.SrcMAC]
|
||||||
pop dword [esi + ETH_header.DstMAC]
|
pop dword [esi + ETH_header.DstMAC]
|
||||||
pop dword [esi + ETH_header.SrcMAC]
|
pop dword [esi + ETH_header.SrcMAC]
|
||||||
push word [esi + ETH_header.DstMAC + 4]
|
push word [esi + ETH_header.DstMAC + 4]
|
||||||
push word [esi + ETH_header.SrcMAC + 4]
|
push word [esi + ETH_header.SrcMAC + 4]
|
||||||
pop word [esi + ETH_header.DstMAC + 4]
|
pop word [esi + ETH_header.DstMAC + 4]
|
||||||
pop word [esi + ETH_header.SrcMAC + 4]
|
pop word [esi + ETH_header.SrcMAC + 4]
|
||||||
|
|
||||||
add esi, sizeof.ETH_header
|
add esi, sizeof.ETH_header
|
||||||
push [esi + IPv4_header.SourceAddress]
|
push [esi + IPv4_header.SourceAddress]
|
||||||
push [esi + IPv4_header.DestinationAddress]
|
push [esi + IPv4_header.DestinationAddress]
|
||||||
pop [esi + IPv4_header.SourceAddress]
|
pop [esi + IPv4_header.SourceAddress]
|
||||||
pop [esi + IPv4_header.DestinationAddress]
|
pop [esi + IPv4_header.DestinationAddress]
|
||||||
|
|
||||||
; Recalculate ip header checksum
|
; Recalculate ip header checksum
|
||||||
movzx ecx, [esi + IPv4_header.VersionAndIHL] ; Calculate IP Header length by using IHL field
|
movzx ecx, [esi + IPv4_header.VersionAndIHL] ; Calculate IP Header length by using IHL field
|
||||||
and ecx, 0x0f
|
and ecx, 0x0f
|
||||||
shl cx, 2
|
shl cx, 2
|
||||||
mov edi, ecx ; IP header length
|
mov edi, ecx ; IP header length
|
||||||
mov eax, edx ; ICMP packet start addr
|
mov eax, edx ; ICMP packet start addr
|
||||||
|
|
||||||
push esi ; Calculate the IP checksum
|
push esi ; Calculate the IP checksum
|
||||||
xor edx, edx ;
|
xor edx, edx ;
|
||||||
call checksum_1 ;
|
call checksum_1 ;
|
||||||
call checksum_2 ;
|
call checksum_2 ;
|
||||||
pop esi ;
|
pop esi ;
|
||||||
mov [esi + IPv4_header.HeaderChecksum], dx ;
|
mov [esi + IPv4_header.HeaderChecksum], dx ;
|
||||||
|
|
||||||
; Recalculate ICMP CheckSum
|
; Recalculate ICMP CheckSum
|
||||||
movzx ecx, [esi + IPv4_header.TotalLength] ; Find length of IP Packet
|
movzx ecx, [esi + IPv4_header.TotalLength] ; Find length of IP Packet
|
||||||
xchg ch, cl ;
|
xchg ch, cl ;
|
||||||
sub ecx, edi ; IP packet length - IP header length = ICMP packet length
|
sub ecx, edi ; IP packet length - IP header length = ICMP packet length
|
||||||
|
|
||||||
mov esi, eax ; Calculate ICMP checksum
|
mov esi, eax ; Calculate ICMP checksum
|
||||||
xor edx, edx ;
|
xor edx, edx ;
|
||||||
call checksum_1 ;
|
call checksum_1 ;
|
||||||
call checksum_2 ;
|
call checksum_2 ;
|
||||||
mov [eax + ICMP_header.Checksum], dx ;
|
mov [eax + ICMP_header.Checksum], dx ;
|
||||||
|
|
||||||
; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!)
|
; Transmit the packet (notice that packet ptr and packet size have been on stack since start of the procedure!)
|
||||||
call [ebx + NET_DEVICE.transmit]
|
call [ebx + NET_DEVICE.transmit]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.check_sockets:
|
.check_sockets:
|
||||||
; Look for an open ICMP socket
|
; Look for an open ICMP socket
|
||||||
; esi = sender ip
|
|
||||||
|
|
||||||
mov ebx, net_sockets
|
mov esi, [edi] ; ipv4 source address
|
||||||
|
mov ebx, net_sockets
|
||||||
.try_more:
|
.try_more:
|
||||||
; mov ax , [edx + ICMP_header.Identifier]
|
; mov ax , [edx + ICMP_header.Identifier]
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov ebx, [ebx + SOCKET.NextPtr]
|
mov ebx, [ebx + SOCKET.NextPtr]
|
||||||
or ebx, ebx
|
or ebx, ebx
|
||||||
jz .dump
|
jz .dump
|
||||||
|
|
||||||
cmp [ebx + SOCKET.Domain], AF_INET4
|
cmp [ebx + SOCKET.Domain], AF_INET4
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
cmp [ebx + SOCKET.Protocol], IP_PROTO_ICMP
|
cmp [ebx + SOCKET.Protocol], IP_PROTO_ICMP
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
cmp [ebx + IP_SOCKET.RemoteIP], esi
|
cmp [ebx + IP_SOCKET.RemoteIP], esi
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
; cmp [esi + ICMP_SOCKET.Identifier], ax
|
; cmp [esi + ICMP_SOCKET.Identifier], ax
|
||||||
; jne .next_socket
|
; jne .next_socket
|
||||||
@ -253,26 +253,26 @@ ICMP_input:
|
|||||||
; je .dump
|
; je .dump
|
||||||
; inc [ICMP_PACKETS_RX+edi]
|
; inc [ICMP_PACKETS_RX+edi]
|
||||||
|
|
||||||
DEBUGF 1,"Found valid ICMP packet for socket %x\n", ebx
|
DEBUGF 1,"Found valid ICMP packet for socket %x\n", ebx
|
||||||
|
|
||||||
mov eax, ebx
|
mov eax, ebx
|
||||||
add ebx, SOCKET.lock
|
add ebx, SOCKET.lock
|
||||||
call wait_mutex
|
call wait_mutex
|
||||||
|
|
||||||
mov esi, edx
|
mov esi, edx
|
||||||
jmp SOCKET_input
|
jmp SOCKET_input
|
||||||
|
|
||||||
|
|
||||||
.checksum_mismatch:
|
.checksum_mismatch:
|
||||||
DEBUGF 1,"ICMP_Handler - checksum mismatch\n"
|
DEBUGF 1,"ICMP_Handler - checksum mismatch\n"
|
||||||
|
|
||||||
.dump:
|
.dump:
|
||||||
DEBUGF 1,"ICMP_Handler - dumping\n"
|
DEBUGF 1,"ICMP_Handler - dumping\n"
|
||||||
|
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4 ; pop (balance stack)
|
add esp, 4 ; pop (balance stack)
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
@ -292,55 +292,55 @@ ICMP_input:
|
|||||||
align 4
|
align 4
|
||||||
ICMP_output:
|
ICMP_output:
|
||||||
|
|
||||||
DEBUGF 1,"Creating ICMP Packet\n"
|
DEBUGF 1,"Creating ICMP Packet\n"
|
||||||
|
|
||||||
push esi edi edx
|
push esi edi edx
|
||||||
|
|
||||||
mov ebx, [eax + IP_SOCKET.LocalIP]
|
mov ebx, [eax + IP_SOCKET.LocalIP]
|
||||||
mov eax, [eax + IP_SOCKET.RemoteIP]
|
mov eax, [eax + IP_SOCKET.RemoteIP]
|
||||||
add ecx, sizeof.ICMP_header
|
add ecx, sizeof.ICMP_header
|
||||||
mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL
|
mov di , IP_PROTO_ICMP SHL 8 + 128 ; TTL
|
||||||
shr edx, 16
|
shr edx, 16
|
||||||
|
|
||||||
call IPv4_output
|
call IPv4_output
|
||||||
jz .exit
|
jz .exit
|
||||||
|
|
||||||
DEBUGF 1,"full icmp packet size: %u\n", edx
|
DEBUGF 1,"full icmp packet size: %u\n", edx
|
||||||
|
|
||||||
pop eax
|
pop eax
|
||||||
mov word [edi + ICMP_header.Type], ax ; Write both type and code bytes at once
|
mov word [edi + ICMP_header.Type], ax ; Write both type and code bytes at once
|
||||||
pop eax
|
pop eax
|
||||||
mov [edi + ICMP_header.SequenceNumber], ax
|
mov [edi + ICMP_header.SequenceNumber], ax
|
||||||
shr eax, 16
|
shr eax, 16
|
||||||
mov [edi + ICMP_header.Identifier], ax
|
mov [edi + ICMP_header.Identifier], ax
|
||||||
mov [edi + ICMP_header.Checksum], 0
|
mov [edi + ICMP_header.Checksum], 0
|
||||||
|
|
||||||
push eax ebx ecx edx
|
push eax ebx ecx edx
|
||||||
mov esi, edi
|
mov esi, edi
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
call checksum_1
|
call checksum_1
|
||||||
call checksum_2
|
call checksum_2
|
||||||
mov [edi + ICMP_header.Checksum], dx
|
mov [edi + ICMP_header.Checksum], dx
|
||||||
pop edx ecx ebx eax esi
|
pop edx ecx ebx eax esi
|
||||||
|
|
||||||
sub ecx, sizeof.ICMP_header
|
sub ecx, sizeof.ICMP_header
|
||||||
add edi, sizeof.ICMP_header
|
add edi, sizeof.ICMP_header
|
||||||
push cx
|
push cx
|
||||||
shr cx , 2
|
shr cx , 2
|
||||||
rep movsd
|
rep movsd
|
||||||
pop cx
|
pop cx
|
||||||
and cx , 3
|
and cx , 3
|
||||||
rep movsb
|
rep movsb
|
||||||
|
|
||||||
sub edi, edx ;;; TODO: find a better way to remember start of packet
|
sub edi, edx ;;; TODO: find a better way to remember start of packet
|
||||||
push edx edi
|
push edx edi
|
||||||
DEBUGF 1,"Sending ICMP Packet\n"
|
DEBUGF 1,"Sending ICMP Packet\n"
|
||||||
call [ebx + NET_DEVICE.transmit]
|
call [ebx + NET_DEVICE.transmit]
|
||||||
ret
|
ret
|
||||||
.exit:
|
.exit:
|
||||||
DEBUGF 1,"Creating ICMP Packet failed\n"
|
DEBUGF 1,"Creating ICMP Packet failed\n"
|
||||||
add esp, 3*4
|
add esp, 3*4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -357,41 +357,41 @@ ICMP_output:
|
|||||||
align 4
|
align 4
|
||||||
ICMP_output_raw:
|
ICMP_output_raw:
|
||||||
|
|
||||||
DEBUGF 1,"Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
|
DEBUGF 1,"Creating ICMP Packet for socket %x, data ptr=%x\n", eax, edx
|
||||||
|
|
||||||
push edx
|
push edx
|
||||||
|
|
||||||
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
|
mov di, IP_PROTO_ICMP SHL 8 + 128 ; TTL
|
||||||
shr edx, 16
|
shr edx, 16
|
||||||
mov ebx, [eax + IP_SOCKET.LocalIP]
|
mov ebx, [eax + IP_SOCKET.LocalIP]
|
||||||
mov eax, [eax + IP_SOCKET.RemoteIP]
|
mov eax, [eax + IP_SOCKET.RemoteIP]
|
||||||
call IPv4_output
|
call IPv4_output
|
||||||
jz .exit
|
jz .exit
|
||||||
|
|
||||||
pop esi
|
pop esi
|
||||||
push edx
|
push edx
|
||||||
push eax
|
push eax
|
||||||
|
|
||||||
push edi ecx
|
push edi ecx
|
||||||
DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi
|
DEBUGF 1,"copying %u bytes from %x to %x\n", ecx, esi, edi
|
||||||
rep movsb
|
rep movsb
|
||||||
pop ecx edi
|
pop ecx edi
|
||||||
|
|
||||||
mov [edi + ICMP_header.Checksum], 0
|
mov [edi + ICMP_header.Checksum], 0
|
||||||
|
|
||||||
mov esi, edi
|
mov esi, edi
|
||||||
xor edx, edx
|
xor edx, edx
|
||||||
call checksum_1
|
call checksum_1
|
||||||
call checksum_2
|
call checksum_2
|
||||||
mov [edi + ICMP_header.Checksum], dx
|
mov [edi + ICMP_header.Checksum], dx
|
||||||
|
|
||||||
DEBUGF 1,"Sending ICMP Packet\n"
|
DEBUGF 1,"Sending ICMP Packet\n"
|
||||||
call [ebx + NET_DEVICE.transmit]
|
call [ebx + NET_DEVICE.transmit]
|
||||||
ret
|
ret
|
||||||
.exit:
|
.exit:
|
||||||
DEBUGF 1,"Creating ICMP Packet failed\n"
|
DEBUGF 1,"Creating ICMP Packet failed\n"
|
||||||
add esp, 4
|
add esp, 4
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -412,24 +412,24 @@ ICMP_output_raw:
|
|||||||
align 4
|
align 4
|
||||||
ICMP_API:
|
ICMP_API:
|
||||||
|
|
||||||
movzx eax, bh
|
movzx eax, bh
|
||||||
shl eax, 2
|
shl eax, 2
|
||||||
|
|
||||||
test bl, bl
|
test bl, bl
|
||||||
jz .packets_tx ; 0
|
jz .packets_tx ; 0
|
||||||
dec bl
|
dec bl
|
||||||
jz .packets_rx ; 1
|
jz .packets_rx ; 1
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
mov eax, -1
|
mov eax, -1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.packets_tx:
|
.packets_tx:
|
||||||
add eax, ICMP_PACKETS_TX
|
add eax, ICMP_PACKETS_TX
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.packets_rx:
|
.packets_rx:
|
||||||
add eax, ICMP_PACKETS_RX
|
add eax, ICMP_PACKETS_RX
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -16,65 +16,65 @@
|
|||||||
|
|
||||||
$Revision$
|
$Revision$
|
||||||
|
|
||||||
macro TCP_checksum IP1, IP2 {
|
macro TCP_checksum IP1, IP2 {
|
||||||
|
|
||||||
;-------------
|
;-------------
|
||||||
; Pseudoheader
|
; Pseudoheader
|
||||||
|
|
||||||
; protocol type
|
; protocol type
|
||||||
mov edx, IP_PROTO_TCP
|
mov edx, IP_PROTO_TCP
|
||||||
|
|
||||||
; source address
|
; source address
|
||||||
add dl, byte [IP1+1]
|
add dl, byte [IP1+1]
|
||||||
adc dh, byte [IP1+0]
|
adc dh, byte [IP1+0]
|
||||||
adc dl, byte [IP1+3]
|
adc dl, byte [IP1+3]
|
||||||
adc dh, byte [IP1+2]
|
adc dh, byte [IP1+2]
|
||||||
|
|
||||||
; destination address
|
; destination address
|
||||||
adc dl, byte [IP2+1]
|
adc dl, byte [IP2+1]
|
||||||
adc dh, byte [IP2+0]
|
adc dh, byte [IP2+0]
|
||||||
adc dl, byte [IP2+3]
|
adc dl, byte [IP2+3]
|
||||||
adc dh, byte [IP2+2]
|
adc dh, byte [IP2+2]
|
||||||
|
|
||||||
; size
|
; size
|
||||||
adc dl, cl
|
adc dl, cl
|
||||||
adc dh, ch
|
adc dh, ch
|
||||||
|
|
||||||
;---------------------
|
;---------------------
|
||||||
; Real header and data
|
; Real header and data
|
||||||
|
|
||||||
push esi
|
push esi
|
||||||
call checksum_1
|
call checksum_1
|
||||||
call checksum_2
|
call checksum_2
|
||||||
pop esi
|
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
|
push edi ;;;; i dont like this static use of edi
|
||||||
mov edi, [ptr + TCP_SOCKET.ISS]
|
mov edi, [ptr + TCP_SOCKET.ISS]
|
||||||
mov [ptr + TCP_SOCKET.SND_UP], edi
|
mov [ptr + TCP_SOCKET.SND_UP], edi
|
||||||
mov [ptr + TCP_SOCKET.SND_MAX], edi
|
mov [ptr + TCP_SOCKET.SND_MAX], edi
|
||||||
mov [ptr + TCP_SOCKET.SND_NXT], edi
|
mov [ptr + TCP_SOCKET.SND_NXT], edi
|
||||||
mov [ptr + TCP_SOCKET.SND_UNA], edi
|
mov [ptr + TCP_SOCKET.SND_UNA], edi
|
||||||
pop edi
|
pop edi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
macro TCP_rcvseqinit ptr {
|
macro TCP_rcvseqinit ptr {
|
||||||
|
|
||||||
push edi
|
push edi
|
||||||
mov edi, [ptr + TCP_SOCKET.IRS]
|
mov edi, [ptr + TCP_SOCKET.IRS]
|
||||||
inc edi
|
inc edi
|
||||||
mov [ptr + TCP_SOCKET.RCV_NXT], edi
|
mov [ptr + TCP_SOCKET.RCV_NXT], edi
|
||||||
mov [ptr + TCP_SOCKET.RCV_ADV], edi
|
mov [ptr + TCP_SOCKET.RCV_ADV], edi
|
||||||
pop edi
|
pop edi
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,11 +102,11 @@ macro TCP_rcvseqinit ptr {
|
|||||||
align 4
|
align 4
|
||||||
TCP_pull_out_of_band:
|
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 +128,18 @@ TCP_pull_out_of_band:
|
|||||||
align 4
|
align 4
|
||||||
TCP_drop:
|
TCP_drop:
|
||||||
|
|
||||||
DEBUGF 1,"TCP_drop\n"
|
DEBUGF 1,"TCP_drop\n"
|
||||||
|
|
||||||
cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
|
cmp [eax + TCP_SOCKET.t_state], TCPS_SYN_RECEIVED
|
||||||
jb .no_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
|
;;; TODO: update stats
|
||||||
|
|
||||||
jmp TCP_close
|
jmp TCP_close
|
||||||
|
|
||||||
.no_syn_received:
|
.no_syn_received:
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ TCP_drop:
|
|||||||
|
|
||||||
;;; TODO: check if error code is "Connection timed out' and handle accordingly
|
;;; TODO: check if error code is "Connection timed out' and handle accordingly
|
||||||
|
|
||||||
mov [eax + SOCKET.errorcode], ebx
|
mov [eax + SOCKET.errorcode], ebx
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -167,15 +167,15 @@ TCP_drop:
|
|||||||
align 4
|
align 4
|
||||||
TCP_close:
|
TCP_close:
|
||||||
|
|
||||||
DEBUGF 1,"TCP_close\n"
|
DEBUGF 1,"TCP_close\n"
|
||||||
|
|
||||||
;;; TODO: update RTT and mean deviation
|
;;; TODO: update RTT and mean deviation
|
||||||
;;; TODO: update slow start threshold
|
;;; TODO: update slow start threshold
|
||||||
;;; TODO: release connection resources
|
;;; TODO: release connection resources
|
||||||
|
|
||||||
call SOCKET_is_disconnected
|
call SOCKET_is_disconnected
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -198,26 +198,26 @@ TCP_close:
|
|||||||
align 4
|
align 4
|
||||||
TCP_outflags:
|
TCP_outflags:
|
||||||
|
|
||||||
mov edx, [eax + TCP_SOCKET.t_state]
|
mov edx, [eax + TCP_SOCKET.t_state]
|
||||||
movzx edx, byte [edx + .flaglist]
|
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:
|
.flaglist:
|
||||||
|
|
||||||
db TH_RST + TH_ACK ; TCPS_CLOSED
|
db TH_RST + TH_ACK ; TCPS_CLOSED
|
||||||
db 0 ; TCPS_LISTEN
|
db 0 ; TCPS_LISTEN
|
||||||
db TH_SYN ; TCPS_SYN_SENT
|
db TH_SYN ; TCPS_SYN_SENT
|
||||||
db TH_SYN + TH_ACK ; TCPS_SYN_RECEIVED
|
db TH_SYN + TH_ACK ; TCPS_SYN_RECEIVED
|
||||||
db TH_ACK ; TCPS_ESTABLISHED
|
db TH_ACK ; TCPS_ESTABLISHED
|
||||||
db TH_ACK ; TCPS_CLOSE_WAIT
|
db TH_ACK ; TCPS_CLOSE_WAIT
|
||||||
db TH_SYN + TH_ACK ; TCPS_FIN_WAIT_1
|
db TH_SYN + TH_ACK ; TCPS_FIN_WAIT_1
|
||||||
db TH_SYN + TH_ACK ; TCPS_CLOSING
|
db TH_SYN + TH_ACK ; TCPS_CLOSING
|
||||||
db TH_SYN + TH_ACK ; TCPS_LAST_ACK
|
db TH_SYN + TH_ACK ; TCPS_LAST_ACK
|
||||||
db TH_ACK ; TCPS_FIN_WAIT_2
|
db TH_ACK ; TCPS_FIN_WAIT_2
|
||||||
db TH_ACK ; TCPS_TIMED_WAIT
|
db TH_ACK ; TCPS_TIMED_WAIT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -237,69 +237,69 @@ TCP_outflags:
|
|||||||
align 4
|
align 4
|
||||||
TCP_respond_socket:
|
TCP_respond_socket:
|
||||||
|
|
||||||
DEBUGF 1,"TCP_respond_socket\n"
|
DEBUGF 1,"TCP_respond_socket\n"
|
||||||
|
|
||||||
;---------------------
|
;---------------------
|
||||||
; Create the IP packet
|
; Create the IP packet
|
||||||
|
|
||||||
push cx ebx
|
push cx ebx
|
||||||
mov eax, [ebx + IP_SOCKET.RemoteIP]
|
mov eax, [ebx + IP_SOCKET.RemoteIP]
|
||||||
mov ebx, [ebx + IP_SOCKET.LocalIP]
|
mov ebx, [ebx + IP_SOCKET.LocalIP]
|
||||||
mov ecx, sizeof.TCP_header
|
mov ecx, sizeof.TCP_header
|
||||||
mov di , IP_PROTO_TCP shl 8 + 128
|
mov di , IP_PROTO_TCP shl 8 + 128
|
||||||
call IPv4_output
|
call IPv4_output
|
||||||
test edi, edi
|
test edi, edi
|
||||||
jz .error
|
jz .error
|
||||||
pop esi cx
|
pop esi cx
|
||||||
push edx eax
|
push edx eax
|
||||||
|
|
||||||
;-----------------------------------------------
|
;-----------------------------------------------
|
||||||
; Fill in the TCP header by using the socket ptr
|
; Fill in the TCP header by using the socket ptr
|
||||||
|
|
||||||
mov ax, [esi + TCP_SOCKET.LocalPort]
|
mov ax, [esi + TCP_SOCKET.LocalPort]
|
||||||
rol ax, 8
|
rol ax, 8
|
||||||
stosw
|
stosw
|
||||||
mov ax, [esi + TCP_SOCKET.RemotePort]
|
mov ax, [esi + TCP_SOCKET.RemotePort]
|
||||||
rol ax, 8
|
rol ax, 8
|
||||||
stosw
|
stosw
|
||||||
mov eax, [esi + TCP_SOCKET.SND_NXT]
|
mov eax, [esi + TCP_SOCKET.SND_NXT]
|
||||||
bswap eax
|
bswap eax
|
||||||
stosd
|
stosd
|
||||||
mov eax, [esi + TCP_SOCKET.RCV_NXT]
|
mov eax, [esi + TCP_SOCKET.RCV_NXT]
|
||||||
bswap eax
|
bswap eax
|
||||||
stosd
|
stosd
|
||||||
mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset)
|
mov al, 0x50 ; Dataoffset: 20 bytes (TCP_header.DataOffset)
|
||||||
stosb
|
stosb
|
||||||
mov al, cl
|
mov al, cl
|
||||||
stosb
|
stosb
|
||||||
; mov ax, [esi + TCP_SOCKET.RCV_WND]
|
; mov ax, [esi + TCP_SOCKET.RCV_WND]
|
||||||
; rol ax, 8
|
; rol ax, 8
|
||||||
mov ax, 0x00a0 ;;;;;;; FIXME
|
mov ax, 0x00a0 ;;;;;;; FIXME
|
||||||
stosw ; window
|
stosw ; window
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
stosd ; checksum + urgentpointer
|
stosd ; checksum + urgentpointer
|
||||||
|
|
||||||
;---------------------
|
;---------------------
|
||||||
; Fill in the checksum
|
; Fill in the checksum
|
||||||
|
|
||||||
.checksum:
|
.checksum:
|
||||||
sub edi, sizeof.TCP_header
|
sub edi, sizeof.TCP_header
|
||||||
mov ecx, sizeof.TCP_header
|
mov ecx, sizeof.TCP_header
|
||||||
xchg esi, edi
|
xchg esi, edi
|
||||||
TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
|
TCP_checksum (edi + IP_SOCKET.LocalIP), (edi + IP_SOCKET.RemoteIP)
|
||||||
mov [esi+TCP_header.Checksum], dx
|
mov [esi+TCP_header.Checksum], dx
|
||||||
|
|
||||||
;--------------------
|
;--------------------
|
||||||
; And send the segment
|
; And send the segment
|
||||||
|
|
||||||
call [ebx + NET_DEVICE.transmit]
|
call [ebx + NET_DEVICE.transmit]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
DEBUGF 1,"TCP_respond failed\n"
|
DEBUGF 1,"TCP_respond failed\n"
|
||||||
add esp, 2+4
|
add esp, 2+4
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -311,70 +311,72 @@ TCP_respond_socket:
|
|||||||
;-------------------------
|
;-------------------------
|
||||||
; TCP_respond.segment:
|
; TCP_respond.segment:
|
||||||
;
|
;
|
||||||
; IN: edx = segment ptr (a previously received segment)
|
; IN: ebx = ptr to driver
|
||||||
|
; edx = segment ptr (a previously received segment)
|
||||||
|
; edi = ptr to dest and src IPv4 addresses
|
||||||
; cl = flags
|
; cl = flags
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
TCP_respond_segment:
|
TCP_respond_segment:
|
||||||
|
|
||||||
DEBUGF 1,"TCP_respond_segment\n"
|
DEBUGF 1,"TCP_respond_segment\n"
|
||||||
|
|
||||||
;---------------------
|
;---------------------
|
||||||
; Create the IP packet
|
; Create the IP packet
|
||||||
|
|
||||||
push cx edx
|
push cx edx ebx
|
||||||
mov ebx, [edx - sizeof.IPv4_header + IPv4_header.SourceAddress] ;;;; FIXME: and what if ip packet had options?!
|
mov ebx, [edi + 4]
|
||||||
mov eax, [edx - sizeof.IPv4_header + IPv4_header.DestinationAddress] ;;;
|
mov eax, [edi]
|
||||||
mov ecx, sizeof.TCP_header
|
mov ecx, sizeof.TCP_header
|
||||||
mov di , IP_PROTO_TCP shl 8 + 128
|
mov di , IP_PROTO_TCP shl 8 + 128
|
||||||
call IPv4_output
|
call IPv4_output
|
||||||
jz .error
|
jz .error
|
||||||
pop esi cx
|
pop ebx esi cx
|
||||||
|
|
||||||
push edx eax
|
push edx eax
|
||||||
|
|
||||||
;---------------------------------------------------
|
;---------------------------------------------------
|
||||||
; Fill in the TCP header by using a received segment
|
; Fill in the TCP header by using a received segment
|
||||||
|
|
||||||
mov ax, [esi + TCP_header.DestinationPort]
|
mov ax, [esi + TCP_header.DestinationPort]
|
||||||
rol ax, 8
|
rol ax, 8
|
||||||
stosw
|
stosw
|
||||||
mov ax, [esi + TCP_header.SourcePort]
|
mov ax, [esi + TCP_header.SourcePort]
|
||||||
rol ax, 8
|
rol ax, 8
|
||||||
stosw
|
stosw
|
||||||
mov eax, [esi + TCP_header.AckNumber]
|
mov eax, [esi + TCP_header.AckNumber]
|
||||||
bswap eax
|
bswap eax
|
||||||
stosd
|
stosd
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
stosd
|
stosd
|
||||||
mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header)
|
mov al, 0x50 ; Dataoffset: 20 bytes (sizeof.TCP_header)
|
||||||
stosb
|
stosb
|
||||||
mov al, cl
|
mov al, cl
|
||||||
stosb
|
stosb
|
||||||
mov ax, 1280
|
mov ax, 1280
|
||||||
rol ax, 8
|
rol ax, 8
|
||||||
stosw ; window
|
stosw ; window
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
stosd ; checksum + urgentpointer
|
stosd ; checksum + urgentpointer
|
||||||
|
|
||||||
;---------------------
|
;---------------------
|
||||||
; Fill in the checksum
|
; Fill in the checksum
|
||||||
|
|
||||||
.checksum:
|
.checksum:
|
||||||
lea esi, [edi - sizeof.TCP_header]
|
lea esi, [edi - sizeof.TCP_header]
|
||||||
mov ecx, sizeof.TCP_header
|
mov ecx, sizeof.TCP_header
|
||||||
TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\ ; FIXME
|
TCP_checksum (esi - sizeof.IPv4_header + IPv4_header.DestinationAddress),\ ; FIXME
|
||||||
(esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
|
(esi - sizeof.IPv4_header + IPv4_header.SourceAddress)
|
||||||
mov [esi+TCP_header.Checksum], dx
|
mov [esi+TCP_header.Checksum], dx
|
||||||
|
|
||||||
;--------------------
|
;--------------------
|
||||||
; And send the segment
|
; And send the segment
|
||||||
|
|
||||||
call [ebx + NET_DEVICE.transmit]
|
call [ebx + NET_DEVICE.transmit]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
DEBUGF 1,"TCP_respond failed\n"
|
DEBUGF 1,"TCP_respond failed\n"
|
||||||
add esp, 2+4
|
add esp, 2+4
|
||||||
|
|
||||||
ret
|
ret
|
@ -17,20 +17,20 @@
|
|||||||
$Revision$
|
$Revision$
|
||||||
|
|
||||||
|
|
||||||
struct UDP_Packet
|
struct UDP_Packet
|
||||||
|
|
||||||
SourcePort dw ?
|
SourcePort dw ?
|
||||||
DestinationPort dw ?
|
DestinationPort dw ?
|
||||||
Length dw ? ; Length of (UDP Header + Data)
|
Length dw ? ; Length of (UDP Header + Data)
|
||||||
Checksum dw ?
|
Checksum dw ?
|
||||||
|
|
||||||
ends
|
ends
|
||||||
|
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
uglobal
|
uglobal
|
||||||
UDP_PACKETS_TX rd MAX_IP
|
UDP_PACKETS_TX rd MAX_IP
|
||||||
UDP_PACKETS_RX rd MAX_IP
|
UDP_PACKETS_RX rd MAX_IP
|
||||||
endg
|
endg
|
||||||
|
|
||||||
|
|
||||||
@ -41,57 +41,57 @@ endg
|
|||||||
; This function resets all UDP variables
|
; This function resets all UDP variables
|
||||||
;
|
;
|
||||||
;-----------------------------------------------------------------
|
;-----------------------------------------------------------------
|
||||||
macro UDP_init {
|
macro UDP_init {
|
||||||
|
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
mov edi, UDP_PACKETS_TX
|
mov edi, UDP_PACKETS_TX
|
||||||
mov ecx, 2*MAX_IP
|
mov ecx, 2*MAX_IP
|
||||||
rep stosd
|
rep stosd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx
|
macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, destroys: ecx, edx
|
||||||
|
|
||||||
; Pseudoheader
|
; Pseudoheader
|
||||||
mov edx, IP_PROTO_UDP
|
mov edx, IP_PROTO_UDP
|
||||||
|
|
||||||
add dl, [IP1+1]
|
add dl, [IP1+1]
|
||||||
adc dh, [IP1+0]
|
adc dh, [IP1+0]
|
||||||
adc dl, [IP1+3]
|
adc dl, [IP1+3]
|
||||||
adc dh, [IP1+2]
|
adc dh, [IP1+2]
|
||||||
|
|
||||||
adc dl, [IP2+1]
|
adc dl, [IP2+1]
|
||||||
adc dh, [IP2+0]
|
adc dh, [IP2+0]
|
||||||
adc dl, [IP2+3]
|
adc dl, [IP2+3]
|
||||||
adc dh, [IP2+2]
|
adc dh, [IP2+2]
|
||||||
|
|
||||||
adc dl, cl ; byte[esi+UDP_Packet.Length+1]
|
adc dl, cl ; byte[esi+UDP_Packet.Length+1]
|
||||||
adc dh, ch ; byte[esi+UDP_Packet.Length+0]
|
adc dh, ch ; byte[esi+UDP_Packet.Length+0]
|
||||||
|
|
||||||
; Done with pseudoheader, now do real header
|
; Done with pseudoheader, now do real header
|
||||||
adc dl, byte[esi+UDP_Packet.SourcePort+1]
|
adc dl, byte[esi+UDP_Packet.SourcePort+1]
|
||||||
adc dh, byte[esi+UDP_Packet.SourcePort+0]
|
adc dh, byte[esi+UDP_Packet.SourcePort+0]
|
||||||
|
|
||||||
adc dl, byte[esi+UDP_Packet.DestinationPort+1]
|
adc dl, byte[esi+UDP_Packet.DestinationPort+1]
|
||||||
adc dh, byte[esi+UDP_Packet.DestinationPort+0]
|
adc dh, byte[esi+UDP_Packet.DestinationPort+0]
|
||||||
|
|
||||||
adc dl, byte[esi+UDP_Packet.Length+1]
|
adc dl, byte[esi+UDP_Packet.Length+1]
|
||||||
adc dh, byte[esi+UDP_Packet.Length+0]
|
adc dh, byte[esi+UDP_Packet.Length+0]
|
||||||
|
|
||||||
adc edx, 0
|
adc edx, 0
|
||||||
|
|
||||||
; Done with header, now do data
|
; Done with header, now do data
|
||||||
push esi
|
push esi
|
||||||
movzx ecx, [esi+UDP_Packet.Length]
|
movzx ecx, [esi+UDP_Packet.Length]
|
||||||
rol cx , 8
|
rol cx , 8
|
||||||
sub cx , sizeof.UDP_Packet
|
sub cx , sizeof.UDP_Packet
|
||||||
add esi, sizeof.UDP_Packet
|
add esi, sizeof.UDP_Packet
|
||||||
|
|
||||||
call checksum_1
|
call checksum_1
|
||||||
call checksum_2
|
call checksum_2
|
||||||
pop esi
|
pop esi
|
||||||
|
|
||||||
add [esi+UDP_Packet.Checksum], dx ; this final instruction will set or clear ZF :)
|
add [esi+UDP_Packet.Checksum], dx ; this final instruction will set or clear ZF :)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,9 +108,7 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, des
|
|||||||
; ebx = ptr to device struct
|
; ebx = ptr to device struct
|
||||||
; ecx = UDP Packet size
|
; ecx = UDP Packet size
|
||||||
; edx = ptr to UDP header
|
; edx = ptr to UDP header
|
||||||
;
|
; edi = ptr to ipv4 source and dest address
|
||||||
; esi = ipv4 source address
|
|
||||||
; edi = ipv4 dest address
|
|
||||||
;
|
;
|
||||||
; OUT: /
|
; OUT: /
|
||||||
;
|
;
|
||||||
@ -118,103 +116,104 @@ macro UDP_checksum IP1, IP2 { ; esi = ptr to udp packet, ecx = packet size, des
|
|||||||
align 4
|
align 4
|
||||||
UDP_input:
|
UDP_input:
|
||||||
|
|
||||||
DEBUGF 1,"UDP_input, size:%u\n", ecx
|
DEBUGF 1,"UDP_input, size:%u\n", ecx
|
||||||
|
|
||||||
; First validate, checksum:
|
; First validate, checksum:
|
||||||
neg [edx+UDP_Packet.Checksum] ; substract chechksum from 0
|
neg [edx+UDP_Packet.Checksum] ; substract chechksum from 0
|
||||||
jz .no_checksum ; if checksum is zero, it is considered valid and we continue processing
|
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
|
; otherwise, we will re-calculate the checksum and add it to this value, thus creating 0 when it is correct
|
||||||
|
|
||||||
push edx
|
push edx
|
||||||
push edi
|
push edi
|
||||||
push esi
|
push esi
|
||||||
mov esi, edx
|
mov esi, edx
|
||||||
UDP_checksum (esp), (esp+4)
|
UDP_checksum (edi), (edi+4)
|
||||||
pop edi
|
pop edi
|
||||||
pop esi ; we dont need it, but it is smaller then add esp, 4
|
pop esi ; we dont need it, but it is smaller then add esp, 4
|
||||||
pop edx
|
pop edx
|
||||||
jnz .checksum_mismatch
|
jnz .checksum_mismatch
|
||||||
|
|
||||||
.no_checksum:
|
.no_checksum:
|
||||||
DEBUGF 1,"UDP Checksum is correct\n"
|
DEBUGF 1,"UDP Checksum is correct\n"
|
||||||
|
|
||||||
; Look for a socket where
|
; Look for a socket where
|
||||||
; IP Packet UDP Destination Port = local Port
|
; IP Packet UDP Destination Port = local Port
|
||||||
; IP Packet SA = Remote IP
|
; IP Packet SA = Remote IP
|
||||||
|
|
||||||
mov eax, net_sockets
|
mov eax, net_sockets
|
||||||
.try_more:
|
.try_more:
|
||||||
mov si , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
|
mov si , [edx + UDP_Packet.DestinationPort] ; get the local port from the IP Packet's UDP header
|
||||||
rol si , 8
|
rol si , 8
|
||||||
.next_socket:
|
.next_socket:
|
||||||
mov eax, [eax + SOCKET.NextPtr]
|
mov eax, [eax + SOCKET.NextPtr]
|
||||||
or eax, eax
|
or eax, eax
|
||||||
jz .dump
|
jz .dump
|
||||||
cmp [eax + SOCKET.Domain], AF_INET4
|
cmp [eax + SOCKET.Domain], AF_INET4
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
|
cmp [eax + SOCKET.Protocol], IP_PROTO_UDP
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
cmp [eax + UDP_SOCKET.LocalPort], si
|
cmp [eax + UDP_SOCKET.LocalPort], si
|
||||||
jne .next_socket
|
jne .next_socket
|
||||||
|
|
||||||
DEBUGF 1,"using socket: %x\n", eax
|
DEBUGF 1,"using socket: %x\n", eax
|
||||||
|
|
||||||
;;; TODO: when packet is processed, check more sockets!
|
;;; TODO: when packet is processed, check more sockets!
|
||||||
|
|
||||||
cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff
|
cmp [eax + IP_SOCKET.RemoteIP], 0xffffffff
|
||||||
je @f
|
je @f
|
||||||
cmp [eax + IP_SOCKET.RemoteIP], edi ; edi is the packets source address
|
mov edi, [edi + 4] ; ipv4 source address
|
||||||
jne .try_more
|
cmp [eax + IP_SOCKET.RemoteIP], edi
|
||||||
|
jne .try_more
|
||||||
@@:
|
@@:
|
||||||
|
|
||||||
cmp [eax + UDP_SOCKET.firstpacket], 0
|
cmp [eax + UDP_SOCKET.firstpacket], 0
|
||||||
jz .updateport
|
jz .updateport
|
||||||
|
|
||||||
mov si, [edx + UDP_Packet.SourcePort]
|
mov si, [edx + UDP_Packet.SourcePort]
|
||||||
rol si, 8
|
rol si, 8
|
||||||
cmp [eax + UDP_SOCKET.RemotePort], si
|
cmp [eax + UDP_SOCKET.RemotePort], si
|
||||||
jne .dump
|
jne .dump
|
||||||
|
|
||||||
push ebx
|
push ebx
|
||||||
lea ebx, [eax + SOCKET.lock]
|
lea ebx, [eax + SOCKET.lock]
|
||||||
call wait_mutex
|
call wait_mutex
|
||||||
pop ebx
|
pop ebx
|
||||||
|
|
||||||
.updatesock:
|
.updatesock:
|
||||||
inc [UDP_PACKETS_RX]
|
inc [UDP_PACKETS_RX]
|
||||||
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
|
DEBUGF 1,"Found valid UDP packet for socket %x\n", eax
|
||||||
lea esi, [edx + sizeof.UDP_Packet]
|
lea esi, [edx + sizeof.UDP_Packet]
|
||||||
movzx ecx, [edx + UDP_Packet.Length]
|
movzx ecx, [edx + UDP_Packet.Length]
|
||||||
rol cx , 8
|
rol cx , 8
|
||||||
sub cx , sizeof.UDP_Packet
|
sub cx , sizeof.UDP_Packet
|
||||||
|
|
||||||
jmp SOCKET_input
|
jmp SOCKET_input
|
||||||
|
|
||||||
.updateport:
|
.updateport:
|
||||||
push ebx
|
push ebx
|
||||||
lea ebx, [eax + SOCKET.lock]
|
lea ebx, [eax + SOCKET.lock]
|
||||||
call wait_mutex
|
call wait_mutex
|
||||||
pop ebx
|
pop ebx
|
||||||
|
|
||||||
mov si, [edx + UDP_Packet.SourcePort]
|
mov si, [edx + UDP_Packet.SourcePort]
|
||||||
rol si, 8
|
rol si, 8
|
||||||
DEBUGF 1,"Changing remote port to: %u\n", si
|
DEBUGF 1,"Changing remote port to: %u\n", si
|
||||||
mov [eax + UDP_SOCKET.RemotePort], si
|
mov [eax + UDP_SOCKET.RemotePort], si
|
||||||
inc [eax + UDP_SOCKET.firstpacket]
|
inc [eax + UDP_SOCKET.firstpacket]
|
||||||
|
|
||||||
jmp .updatesock
|
jmp .updatesock
|
||||||
|
|
||||||
|
|
||||||
.checksum_mismatch:
|
.checksum_mismatch:
|
||||||
|
|
||||||
DEBUGF 2,"UDP_Handler - checksum mismatch\n"
|
DEBUGF 2,"UDP_Handler - checksum mismatch\n"
|
||||||
|
|
||||||
.dump:
|
.dump:
|
||||||
call kernel_free
|
call kernel_free
|
||||||
add esp, 4 ; pop (balance stack)
|
add esp, 4 ; pop (balance stack)
|
||||||
DEBUGF 2,"UDP_Handler - dumping\n"
|
DEBUGF 2,"UDP_Handler - dumping\n"
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -232,64 +231,64 @@ UDP_input:
|
|||||||
align 4
|
align 4
|
||||||
UDP_output:
|
UDP_output:
|
||||||
|
|
||||||
DEBUGF 1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi
|
DEBUGF 1,"UDP_output: socket:%x, bytes: %u, data ptr: %x\n", eax, ecx, esi
|
||||||
|
|
||||||
mov dx, [eax + UDP_SOCKET.RemotePort]
|
mov dx, [eax + UDP_SOCKET.RemotePort]
|
||||||
DEBUGF 1,"remote port: %u\n", dx
|
DEBUGF 1,"remote port: %u\n", dx
|
||||||
rol dx, 8
|
rol dx, 8
|
||||||
rol edx, 16
|
rol edx, 16
|
||||||
mov dx, [eax + UDP_SOCKET.LocalPort]
|
mov dx, [eax + UDP_SOCKET.LocalPort]
|
||||||
DEBUGF 1,"local port: %u\n", dx
|
DEBUGF 1,"local port: %u\n", dx
|
||||||
rol dx, 8
|
rol dx, 8
|
||||||
|
|
||||||
mov ebx, [eax + IP_SOCKET.LocalIP]
|
mov ebx, [eax + IP_SOCKET.LocalIP]
|
||||||
mov eax, [eax + IP_SOCKET.RemoteIP]
|
mov eax, [eax + IP_SOCKET.RemoteIP]
|
||||||
|
|
||||||
mov di, IP_PROTO_UDP shl 8 + 128
|
mov di, IP_PROTO_UDP shl 8 + 128
|
||||||
sub esp, 8 ; Data ptr and data size will be placed here
|
sub esp, 8 ; Data ptr and data size will be placed here
|
||||||
add ecx, sizeof.UDP_Packet
|
add ecx, sizeof.UDP_Packet
|
||||||
|
|
||||||
;;; TODO: fragment id
|
;;; TODO: fragment id
|
||||||
push edx esi
|
push edx esi
|
||||||
call IPv4_output
|
call IPv4_output
|
||||||
jz .fail
|
jz .fail
|
||||||
|
|
||||||
mov [esp + 8], eax ; pointer to buffer start
|
mov [esp + 8], eax ; pointer to buffer start
|
||||||
mov [esp + 8 + 4], edx ; buffer size
|
mov [esp + 8 + 4], edx ; buffer size
|
||||||
|
|
||||||
mov [edi + UDP_Packet.Length], cx
|
mov [edi + UDP_Packet.Length], cx
|
||||||
rol [edi + UDP_Packet.Length], 8
|
rol [edi + UDP_Packet.Length], 8
|
||||||
|
|
||||||
pop esi
|
pop esi
|
||||||
push edi ecx
|
push edi ecx
|
||||||
sub ecx, sizeof.UDP_Packet
|
sub ecx, sizeof.UDP_Packet
|
||||||
add edi, sizeof.UDP_Packet
|
add edi, sizeof.UDP_Packet
|
||||||
shr ecx, 2
|
shr ecx, 2
|
||||||
rep movsd
|
rep movsd
|
||||||
mov ecx, [esp]
|
mov ecx, [esp]
|
||||||
and ecx, 3
|
and ecx, 3
|
||||||
rep movsb
|
rep movsb
|
||||||
pop ecx edi
|
pop ecx edi
|
||||||
|
|
||||||
pop dword [edi + UDP_Packet.SourcePort]
|
pop dword [edi + UDP_Packet.SourcePort]
|
||||||
|
|
||||||
; Checksum
|
; Checksum
|
||||||
mov esi, edi
|
mov esi, edi
|
||||||
mov [edi + UDP_Packet.Checksum], 0
|
mov [edi + UDP_Packet.Checksum], 0
|
||||||
UDP_checksum (edi-4), (edi-8) ; TODO: fix this, IPv4 packet could have options..
|
UDP_checksum (edi-4), (edi-8) ; TODO: fix this, IPv4 packet could have options..
|
||||||
|
|
||||||
inc [UDP_PACKETS_TX]
|
inc [UDP_PACKETS_TX]
|
||||||
|
|
||||||
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx
|
DEBUGF 1,"Sending UDP Packet to device %x\n", ebx
|
||||||
|
|
||||||
call [ebx + NET_DEVICE.transmit]
|
call [ebx + NET_DEVICE.transmit]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.fail:
|
.fail:
|
||||||
DEBUGF 1,"UDP_output: failed\n"
|
DEBUGF 1,"UDP_output: failed\n"
|
||||||
add esp, 4+4+8
|
add esp, 4+4+8
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -310,24 +309,24 @@ UDP_output:
|
|||||||
align 4
|
align 4
|
||||||
UDP_API:
|
UDP_API:
|
||||||
|
|
||||||
movzx eax, bh
|
movzx eax, bh
|
||||||
shl eax, 2
|
shl eax, 2
|
||||||
|
|
||||||
test bl, bl
|
test bl, bl
|
||||||
jz .packets_tx ; 0
|
jz .packets_tx ; 0
|
||||||
dec bl
|
dec bl
|
||||||
jz .packets_rx ; 1
|
jz .packets_rx ; 1
|
||||||
|
|
||||||
.error:
|
.error:
|
||||||
mov eax, -1
|
mov eax, -1
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.packets_tx:
|
.packets_tx:
|
||||||
add eax, UDP_PACKETS_TX
|
add eax, UDP_PACKETS_TX
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.packets_rx:
|
.packets_rx:
|
||||||
add eax, UDP_PACKETS_RX
|
add eax, UDP_PACKETS_RX
|
||||||
mov eax, [eax]
|
mov eax, [eax]
|
||||||
ret
|
ret
|
||||||
|
Loading…
Reference in New Issue
Block a user