Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 5391 → Rev 5390

/programs/network/zeroconf/zeroconf.asm
1,6 → 1,6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2010-2015. All rights reserved. ;;
;; Copyright (C) KolibriOS team 2010-2014. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; zeroconfig.asm - Zeroconfig service for KolibriOS ;;
62,84 → 62,116
include 'dhcp.inc'
include '../../dll.inc'
 
START:
mcall 68, 11
 
stdcall dll.Load,@IMPORT
or eax, eax
jnz fail
Ip2dword:
push edx
 
DEBUGF 2,"Zero-config service loaded\n"
; This code validates if the query is an IP containing 4 numbers and 3 dots
 
mcall 40, EVM_STACK2
xor al, al ; make al (dot count) zero
 
wait_for_link_up:
mov bh, [device]
mov bl, 0 ; Get device type
mcall 74
cmp eax, 1 ; Ethernet
jne .wait
@@:
cmp byte[edx],'0' ; check if this byte is a number, if not jump to no_IP
jl no_IP ;
cmp byte[edx],'9' ;
jg no_IP ;
 
mov bl, 10 ; Get Link status
mcall 74
inc edx ; the byte was a number, so lets check the next byte
 
cmp byte[edx],0 ; is this byte zero? (have we reached end of query?)
jz @f ; jump to next @@ then
cmp byte[edx],':'
jz @f
 
cmp byte[edx],'.' ; is this byte a dot?
jne @r ; if not, jump to previous @@
 
inc al ; the byte was a dot so increment al(dot count)
inc edx ; next byte
jmp @r ; lets check for numbers again (jump to previous @@)
 
@@: ; we reach this when end of query reached
cmp al,3 ; check if there where 3 dots
jnz no_IP ; if not, jump to no_IP
 
; The following code will convert this IP into a dword and output it in eax
; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1
 
pop esi ; edx (query address) was pushed onto stack and is now popped in esi
 
xor edx, edx ; result
xor eax, eax ; current character
xor ebx, ebx ; current byte
 
.outer_loop:
shl edx, 8
add edx, ebx
xor ebx, ebx
.inner_loop:
lodsb
test eax, eax
jnz .go
jz .finish
cmp al, '.'
jz .outer_loop
sub eax, '0'
imul ebx, 10
add ebx, eax
jmp .inner_loop
.finish:
shl edx, 8
add edx, ebx
 
bswap edx ; we want little endian order
 
ret
 
no_IP:
pop edx
xor edx, edx
 
ret
 
 
 
 
 
 
START:
mcall 40, EVM_STACK2
 
DEBUGF 2,"Zero-config service loaded\n"
 
.wait:
mov ebx, API_ETH + 0
mov bh, [device]
mcall 76 ; get MAC of ethernet interface 1
cmp eax, -1
jne .start
 
mcall 10
jmp wait_for_link_up
jmp .wait
 
.go:
mov ebx, API_ETH + 0
mov bh, [device]
mcall 76 ; get MAC of the ethernet interface
.start:
mov word[MAC], bx
mov dword[MAC+2], eax
DEBUGF 1,"MAC: %x-%x-%x-%x-%x-%x\n", [MAC+0]:2, [MAC+1]:2, [MAC+2]:2, [MAC+3]:2, [MAC+4]:2, [MAC+5]:2
 
invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
mcall 40, EVM_STACK
 
cmp dword[inibuf], 'stat'
je static
jmp try_dhcp
mcall 68, 11
 
wait_for_link_down:
; TODO: detect ARP conflicts
stdcall dll.Load,@IMPORT
or eax, eax
jnz try_dhcp
 
mcall 40, EVM_STACK2
.loop:
mcall 10
mov bh, [device]
mov bl, 0 ; Get device type
mcall 74
cmp eax, 0 ; No device
je .down
invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
 
mov bl, 10 ; Get Link status
mcall 74
test eax, eax
jnz .loop
cmp dword[inibuf], 'stat'
jne try_dhcp
 
.down:
xor ecx, ecx
mov ebx, API_IPv4 + 3
mov bh, [device]
mcall 76 ; ip
mov bl, 5
mcall 76 ; dns
mov bl, 7
mcall 76 ; subnet
mov bl, 9
mcall 76 ; gateway
 
jmp wait_for_link_up
 
static:
DEBUGF 1,"Applying Static IP settings\n"
 
invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
mov edx, inibuf
call ip_str_to_dword
call Ip2dword
mov ecx, edx
mov ebx, API_IPv4 + 3 ; set IP
mov bh, [device]
147,7 → 179,7
 
invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
mov edx, inibuf
call ip_str_to_dword
call Ip2dword
mov ecx, edx
mov ebx, API_IPv4 + 9 ; set gateway
mov bh, [device]
155,7 → 187,7
 
invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
mov edx, inibuf
call ip_str_to_dword
call Ip2dword
mov ecx, edx
mov ebx, API_IPv4 + 5 ; set DNS
mov bh, [device]
163,26 → 195,23
 
invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
mov edx, inibuf
call ip_str_to_dword
call Ip2dword
mov ecx, edx
mov ebx, API_IPv4 + 7 ; set subnet
mov bh, [device]
mcall 76
 
mov [notify_struct.msg], str_connected
mcall 70, notify_struct
jmp wait_for_link_down
 
mcall -1
 
 
try_dhcp:
 
DEBUGF 2,"Trying to contact DHCP server\n"
 
mcall 40, EVM_STACK
 
mcall 75, 0, AF_INET4, SOCK_DGRAM, 0 ; open socket (parameters: domain, type, reserved)
cmp eax, -1
je socket_error
je error
mov [socketNum], eax
 
DEBUGF 1,"Socket %x opened\n", eax
189,13 → 218,13
 
mcall 75, 2, [socketNum], sockaddr1, 18 ; bind socket to local port 68
cmp eax, -1
je socket_error
je error
 
DEBUGF 1,"Socket Bound to local port 68\n"
 
mcall 75, 4, [socketNum], sockaddr2, 18 ; connect to 255.255.255.255 on port 67
cmp eax, -1
je socket_error
je error
 
DEBUGF 1,"Connected to 255.255.255.255 on port 67\n"
 
213,16 → 242,18
DEBUGF 1,"Building request\n"
 
stdcall mem.Alloc, BUFFER
mov [dhcpMsg], eax
test eax, eax
jz dhcp_fail2
mov [dhcpMsg], eax
jz dhcp_error
 
;;; todo: skip this bullcrap
 
mov edi, eax
mov ecx, BUFFER
xor eax, eax
rep stosb
 
;; todo: put this in one buffer we can copy, instead of writing bytes and words!
;; todo: put this in a buffer instead of writing bytes and words!
 
mov edx, [dhcpMsg]
 
230,7 → 261,7
mov [edx], byte 0x01 ; Boot request
mov [edx+1], byte 0x01 ; Ethernet
mov [edx+2], byte 0x06 ; Ethernet h/w len
mov [edx+4], dword 0x11223344 ; xid ;;;;;;; FIXME
mov [edx+4], dword 0x11223344 ; xid ;;;;;;;
mov eax, [currTime]
mov [edx+8], eax ; secs, our uptime
mov [edx+10], byte 0x80 ; broadcast flag set
277,7 → 308,7
add eax, TIMEOUT*100
mov [timeout], eax
.wait:
mcall 23, TIMEOUT ; wait for data (with timeout)
mcall 23, TIMEOUT ; wait for data
 
read_data: ; we have data - this will be the response
mcall 75, 7, [socketNum], [dhcpMsg], BUFFER, MSG_DONTWAIT ; read data from socket
291,7 → 322,7
DEBUGF 2,"No answer from DHCP server\n"
dec [tries]
jnz send_dhcpmsg ; try again
jmp dhcp_fail
jmp dhcp_error ; fail
 
@@:
DEBUGF 1,"%d bytes received\n", eax
313,15 → 344,19
cmp [dhcpMsgType], 0x03 ; did we send a request?
je request
 
; we should never reach here ;)
jmp fail
call dhcp_end ; we should never reach here ;)
jmp exit
 
discover:
call parse_response
 
cmp [dhcpMsgType2], 0x02 ; Was the response an offer?
jne dhcp_fail
je send_request
 
call dhcp_end
jmp link_local
 
send_request:
DEBUGF 1, "Got offer, making request\n"
mov [dhcpMsgType], 0x03 ; make it a request
jmp build_request
332,11 → 367,11
cmp [dhcpMsgType2], 0x05 ; Was the response an ACK? It should be
jne read_data ; NO - read next packets
 
DEBUGF 2, "IP assigned by DHCP server successfully\n"
DEBUGF 2, "Setting IP using DHCP\n"
 
mov [notify_struct.msg], str_connected
mcall 70, notify_struct
call dhcp_fail
call dhcp_end
 
mov ebx, API_IPv4 + 3
mov bh, [device]
348,9 → 383,14
mov bl, 9
mcall 76, , [dhcp.gateway] ; gateway
 
jmp wait_for_link_down
jmp exit
 
dhcp_end:
mcall close, [socketNum]
stdcall mem.Free, [dhcpMsg]
 
ret
 
;***************************************************************************
; Function
; parseResponse
441,7 → 481,7
mov eax,[edx]
bswap eax
mov [dhcpLease],eax
DEBUGF 1,"Lease: %d\n",eax
DEBUGF 1,"lease: %d\n",eax
popa
jmp .next_option
 
466,13 → 506,10
.done:
ret
 
dhcp_fail:
 
mcall close, [socketNum]
stdcall mem.Free, [dhcpMsg]
 
dhcp_fail2:
DEBUGF 1,"DHCP failed\n"
dhcp_error:
call dhcp_end
 
link_local:
call random
540,13 → 577,13
mcall 5, ANNOUNCE_INTERVAL*100
jmp announce_loop
@@:
jmp wait_for_link_down
jmp exit
 
 
socket_error:
error:
DEBUGF 2,"Socket error\n"
fail:
DEBUGF 2,"Zeroconf failed!\n"
exit: ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
DEBUGF 2,"Exiting\n"
mcall -1
 
 
563,76 → 600,6
 
ret
 
 
 
ip_str_to_dword:
push edx
 
; This code validates if the query is an IP containing 4 numbers and 3 dots
 
xor al, al ; make al (dot count) zero
 
@@:
cmp byte[edx],'0' ; check if this byte is a number, if not jump to no_IP
jl no_IP ;
cmp byte[edx],'9' ;
jg no_IP ;
 
inc edx ; the byte was a number, so lets check the next byte
 
cmp byte[edx],0 ; is this byte zero? (have we reached end of query?)
jz @f ; jump to next @@ then
cmp byte[edx],':'
jz @f
 
cmp byte[edx],'.' ; is this byte a dot?
jne @r ; if not, jump to previous @@
 
inc al ; the byte was a dot so increment al(dot count)
inc edx ; next byte
jmp @r ; lets check for numbers again (jump to previous @@)
 
@@: ; we reach this when end of query reached
cmp al,3 ; check if there where 3 dots
jnz no_IP ; if not, jump to no_IP
 
; The following code will convert this IP into a dword and output it in eax
; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1
 
pop esi ; edx (query address) was pushed onto stack and is now popped in esi
 
xor edx, edx ; result
xor eax, eax ; current character
xor ebx, ebx ; current byte
 
.outer_loop:
shl edx, 8
add edx, ebx
xor ebx, ebx
.inner_loop:
lodsb
test eax, eax
jz .finish
cmp al, '.'
jz .outer_loop
sub eax, '0'
imul ebx, 10
add ebx, eax
jmp .inner_loop
.finish:
shl edx, 8
add edx, ebx
 
bswap edx ; we want little endian order
 
ret
 
no_IP:
pop edx
xor edx, edx
 
ret
 
; DATA AREA
 
align 16