Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 3199 → Rev 3200

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