Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3200 → Rev 3199

/kernel/branches/net/applications/zeroconf/zeroconf.asm
1,20 → 1,9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2010-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;; zeroconfig.asm - Zeroconfig service for KolibriOS ;;
;; ;;
;; Written by hidnplayr@kolibrios.org ;;
;; Some code contributed by Derpenguin ;;
;; ;;
;; DHCP code is based on that by Mike Hibbet ;;
; (DHCP client for menuetos) ;;
;; ;;
;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Zero-config
; v 1.4
;
; DHCP code is based on that by Mike Hibbet (DHCP client for menuetos)
;
; Written by HidnPlayr & Derpenguin
 
format binary as ""
 
31,6 → 20,7
 
; CONFIGURATION
 
 
TIMEOUT equ 60 ; in seconds
BUFFER equ 1024 ; in bytes
__DEBUG__ equ 1 ; enable/disable
135,13 → 125,14
 
 
 
START:
START: ; start of execution
 
mcall 40, EVM_STACK ; network event
mcall 40, 1 shl 7 ; network event
 
DEBUGF 1,">Zero-config service loaded\n"
DEBUGF 1,">Zero-config service:\n"
 
mcall 76, API_ETH + 4 ; get MAC of ethernet interface 0
mcall 76, API_ETH + 4
 
cmp eax, -1
je exit
 
150,29 → 141,33
 
DEBUGF 1,"->MAC: %x-%x-%x-%x-%x-%x\n",[MAC]:2,[MAC+1]:2,[MAC+2]:2,[MAC+3]:2,[MAC+4]:2,[MAC+5]:2
 
cld
mov edi, path ; Calculate the length of zero-terminated string
xor al, al
mov ecx, 1024
repne scasb
repnz scas byte[es:edi]
dec edi
 
mov esi, filename ; append with .ini
mov esi, filename
movsd
movsb
 
DEBUGF 1,"->Loading ini %s\n", path
DEBUGF 1,"->path to ini: %s\n", path
 
mcall 68, 11
 
stdcall dll.Load,@IMPORT
or eax, eax
jnz try_dhcp
jnz skip_ini
 
 
invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
 
cmp dword[inibuf], 'stat'
jne try_dhcp
mov eax,dword[inibuf]
 
cmp eax,'stat'
jne skip_ini
 
invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
197,9 → 192,9
mcall -1
 
 
try_dhcp:
skip_ini:
 
DEBUGF 1,"->Trying DHCP\n"
DEBUGF 1,"->Skip ini\n"
 
mcall 75, 0, AF_INET4, SOCK_DGRAM, 0 ; open socket (parameters: domain, type, reserved)
cmp eax, -1
206,7 → 201,7
je error
mov [socketNum], eax
 
DEBUGF 1,"->Socket %x opened\n", eax
DEBUGF 1,"->socket %x opened\n", eax
 
mcall 75, 2, [socketNum], sockaddr1, 18 ; bind socket to local port 68
cmp eax, -1
220,14 → 215,14
 
DEBUGF 1,"->Connected to 255.255.255.255 on port 67\n"
 
mov [dhcpMsgType], 0x01 ; DHCP discover
mov [dhcpLease], esi ; esi is still -1 (-1 = forever)
mov byte [dhcpMsgType], 0x01 ; DHCP discover
mov dword [dhcpLease], esi ; esi is still -1 (-1 = forever)
 
mcall 26, 9 ; Get system time
mcall 26, 9
imul eax, 100
mov [currTime], eax
 
build_request: ; Creates a DHCP request packet.
buildRequest: ; Creates a DHCP request packet.
 
DEBUGF 1,"->Building request\n"
 
241,6 → 236,7
mov edi, eax
mov ecx, BUFFER
xor eax, eax
cld
rep stosb
 
;; todo: put this in a buffer instead of writing bytes and words!
277,7 → 273,7
mov [edx+240+21], byte 0xff ; "Discover" options
 
mov [dhcpMsgLen], dword 262 ; end of options marker
jmp send_dhcpmsg
jmp send_request
 
request_options:
mov [edx+240+21], word 0x0436 ; server IP
288,7 → 284,7
 
mov [dhcpMsgLen], dword 268
 
send_dhcpmsg:
send_request:
mcall 75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen] ; write to socket ( send broadcast request )
 
mov eax, [dhcpMsg] ; Setup the DHCP buffer to receive response
316,34 → 312,26
; 1) If the response is DHCP ACK then
; 1.1) extract the DNS & subnet fields. Set them in the stack
 
cmp [dhcpMsgType], 0x01 ; did we send a discover?
cmp [dhcpMsgType], byte 0x01 ; did we send a discover?
je discover
 
cmp [dhcpMsgType], 0x03 ; did we send a request?
cmp [dhcpMsgType], byte 0x03 ; did we send a request?
je request
 
call dhcp_end ; we should never reach here ;)
jmp exit
jmp exit ; really unknown, what we did
 
discover:
call parse_response
call parseResponse
 
cmp [dhcpMsgType], 0x02 ; Was the response an offer?
je send_request
cmp [dhcpMsgType], byte 0x02 ; Was the response an offer?
jne apipa ; NO - so we do zeroconf
mov [dhcpMsgType], byte 0x03 ; DHCP request
jmp buildRequest
 
call dhcp_end
jmp link_local
 
send_request:
mov [dhcpMsgType], 0x03 ; make it a request
jmp build_request
 
request:
call parse_response
call dhcp_end
call parseResponse
 
cmp [dhcpMsgType], 0x05 ; Was the response an ACK? It should be
jne link_local ; NO - so we do link-local
cmp [dhcpMsgType], byte 0x05 ; Was the response an ACK? It should be
jne apipa ; NO - so we do zeroconf
 
mcall 76, API_IPv4 + 3, [dhcp.ip] ; ip
mcall 76, API_IPv4 + 5, [dhcp.dns] ; dns
352,12 → 340,6
 
jmp exit
 
dhcp_end:
mcall close, [socketNum]
stdcall mem.Free, [dhcpMsg]
 
ret
 
;***************************************************************************
; Function
; parseResponse
371,8 → 353,7
; The message is stored in dhcpMsg
;
;***************************************************************************
parse_response:
 
parseResponse:
DEBUGF 1,"Data received, parsing response\n"
mov edx, [dhcpMsg]
 
380,69 → 361,43
pop [dhcp.ip]
DEBUGF 1,"Client: %u.%u.%u.%u\n", [edx+16]:1, [edx+17]:1, [edx+18]:1, [edx+19]:1
 
; TODO: check if there really are options
add edx, 240 ; Point to first option
xor ecx, ecx
 
mov al, 240 ; Point to first option
movzx ecx, al
 
.next_option:
next_option:
add edx, ecx
pr001:
mov al, [edx]
cmp al, 0xff ; End of options?
je pr_exit
 
mov al, [edx] ; get message identifier
cmp al, dhcp_msg_type ; Msg type is a single byte option
jne @f
 
cmp al, 0xff ; End of options?
je .done
mov al, [edx+2]
mov [dhcpMsgType], al
 
cmp al, 0
je .pad
DEBUGF 1,"DHCP Msg type: %u\n", al
 
; TODO: check if we still are inside the buffer
add edx, 3
jmp pr001 ; Get next option
 
@@:
inc edx
movzx ecx, byte [edx] ; get data length
movzx ecx, byte [edx]
inc edx ; point to data
 
cmp al, dhcp_msg_type ; Msg type is a single byte option
je .msgtype
 
cmp al, dhcp_dhcp_server_id
je .server
 
cmp al, dhcp_address_time
je .lease
 
cmp al, dhcp_subnet_mask
je .subnet
 
cmp al, dhcp_router
je .router
 
cmp al, dhcp_domain_server
je .dns
 
DEBUGF 1,"Unsupported DHCP option: %u\n", al
 
jmp .next_option
 
.pad:
xor ecx, ecx
inc ecx
jmp .next_option
 
.msgtype:
mov al, [edx]
mov [dhcpMsgType], al
 
DEBUGF 1,"DHCP Msg type: %u\n", al
jmp .next_option ; Get next option
 
.server:
cmp al, dhcp_dhcp_server_id ; server ip
jne @f
mov eax, [edx]
mov [dhcpServerIP], eax
DEBUGF 1,"Server: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
jmp .next_option
jmp next_option
 
.lease:
@@:
cmp al, dhcp_address_time
jne @f
 
pusha
mov eax,[edx]
bswap eax
449,29 → 404,43
mov [dhcpLease],eax
DEBUGF 1,"lease: %d\n",eax
popa
jmp .next_option
 
.subnet:
jmp next_option
 
@@:
cmp al, dhcp_subnet_mask
jne @f
 
push dword [edx]
pop [dhcp.subnet]
DEBUGF 1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
jmp .next_option
jmp next_option
 
.router:
@@:
cmp al, dhcp_router
jne @f
 
push dword [edx]
pop [dhcp.gateway]
DEBUGF 1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
jmp .next_option
jmp next_option
 
.dns:
 
@@:
cmp al, dhcp_domain_server
jne next_option
 
push dword [edx]
pop [dhcp.dns]
DEBUGF 1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
jmp .next_option
jmp next_option
 
.done:
pr_exit:
 
ret
 
; DEBUGF 1,"Sending ARP announce\n"
;;;
 
 
apipa:
478,7 → 447,6
mcall close, [socketNum]
stdcall mem.Free, [dhcpMsg]
 
 
link_local:
call random
mov ecx, 0xfea9 ; IP 169.254.0.0 link local net, see RFC3927
496,12 → 464,12
call random ; create a pseudo random number in eax (seeded by MAC)
 
cmp al, PROBE_MIN*100 ; check if al is bigger then PROBE_MIN
jae @f ; all ok
jge @f ; all ok
add al, (PROBE_MAX-PROBE_MIN)*100 ; al is too small
@@:
 
cmp al, PROBE_MAX*100
jbe @f
jle @f
sub al, (PROBE_MAX-PROBE_MIN)*100
@@:
 
510,11 → 478,11
mcall 5
 
DEBUGF 1,"Sending Probe\n"
mcall 76, API_ARP + 6
; eth.ARP_PROBE MAC
inc esi
 
cmp esi, PROBE_NUM
jb probe_loop
jl probe_loop
 
; now we wait further ANNOUNCE_WAIT seconds and send ANNOUNCE_NUM ARP announces. If any other host has assingned
; IP within this time, we should create another adress, that have to be done later
525,7 → 493,7
announce_loop:
 
DEBUGF 1,"Sending Announce\n"
mcall 76, API_ARP + 6
; eth.ARP_ANNOUNCE MAC
 
inc esi
cmp esi,ANNOUNCE_NUM
535,11 → 503,10
mcall 5, ANNOUNCE_INTERVAL*100
jmp announce_loop
@@:
; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
 
 
error:
DEBUGF 1,"Socket error\n"
exit: ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
exit:
mcall -1
 
 
617,6 → 584,7
MAC dp ?
 
currTime dd ?
renewTime dd ?
generator dd ?
 
dhcpMsg dd ?