diff --git a/programs/network/autodhcp/trunk/ETH.INC b/programs/network/autodhcp/trunk/ETH.INC index c20f04357d..889b5a8c03 100644 --- a/programs/network/autodhcp/trunk/ETH.INC +++ b/programs/network/autodhcp/trunk/ETH.INC @@ -1,7 +1,7 @@ ; ; ETH.INC ; -; made by hidnplayr (hidnplayr@gmail.com) for KolibriOS +; made by hidnplayr (hidnplayr@kolibrios.org) for KolibriOS ; ; The given code before every macro is only a simple example ; @@ -10,7 +10,7 @@ ; ; v1.0: august 2006 original release ; v1.1: december 2006 bugfixes and improvements -; v1.2: februari 2007 more bugfixes and improvements +; v1.2: february 2007 more bugfixes and improvements macro mov arg1,arg2 { if arg1 eq arg2 @@ -339,51 +339,12 @@ macro eth.wait_for_data socket,TIMEOUT,abort { } -; The function 'resolve' resolves the address in edx and puts the resulting IP in eax. -; When the input is an IP-adress, the function will output this IP in eax. -; If something goes wrong, the result in eax should be 0 -; -; example: -; -; resolve query1,IP,PORT -; resolve '192.168.0.1',IP,PORT -; resolve query2,IP,PORT -; -; query1 db 'www.google.com',0 -; query2 db '49.78.84.45',0 -; IP dd ? -; PORT dd ? -macro resolve query,result { - -if query eqtype 0 - mov edx,query -else - local ..string, ..label - jmp ..label - ..string db query,0 - ..label: - mov edx,..string -end if - -call __resolve - -mov result,eax - -} - -if used __resolve - -__resolve: - -if __DEBUG__ eq 1 -DEBUGF 1,'DNS: Resolving started\n' -end if +Ip2dword: + push edx ; This code validates if the query is an IP containing 4 numbers and 3 dots - - push edx ; push edx (query address) onto stack xor al, al ; make al (dot count) zero @@: @@ -408,7 +369,7 @@ end if @@: ; 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 (this is where the DNS will take over) + 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 @@ -438,189 +399,15 @@ end if add edx, ebx bswap edx ; we want little endian order - mov eax, edx ret - no_IP: - pop edx - - ; The query is not an IP address, we will send the query to a DNS server and hope for answer ;) -if __DEBUG__ eq 1 - DEBUGF 1,'DNS: The query is no ip, Building request string from:%u\n',edx -end if - - ; Build the request string - mov eax, 0x00010100 - mov [dnsMsg], eax - mov eax, 0x00000100 - mov [dnsMsg+4], eax - mov eax, 0x00000000 - mov [dnsMsg+8], eax - - ; domain name goes in at dnsMsg+12 - mov esi, dnsMsg + 12 ; location of label length - mov edi, dnsMsg + 13 ; label start - mov ecx, 12 ; total string length so far - -td002: - mov [esi], byte 0 - inc ecx - -td0021: - mov al, [edx] - - cmp al, 0 - je td001 ; we have finished the string translation - - cmp al, '.' - je td004 ; we have finished the label - - inc byte [esi] - inc ecx - mov [edi], al - inc edi - inc edx - jmp td0021 - -td004: - mov esi, edi - inc edi - inc edx - jmp td002 - - ; write label len + label text -td001: - mov [edi], byte 0 - inc ecx - inc edi - mov [edi], dword 0x01000100 - add ecx, 4 - - mov [dnsMsgLen], ecx ; We'll need the length of the message when we send it - ; Now, lets send this and wait for an answer - - eth.search_port 1024,edx ; Find a free port starting from 1025 and store in edx - eth.get_DNS esi ; Read DNS IP from stack into esi - eth.open_udp edx,53,esi,[socketNum] ; First, open socket -if __DEBUG__ eq 1 - DEBUGF 1,'DNS: Socket opened: %u (port %u)\n',[socketNum],ecx -end if - eth.write_udp [socketNum],[dnsMsgLen],dnsMsg ; Write to socket ( request DNS lookup ) -if __DEBUG__ eq 1 - DEBUGF 1,'DNS: Data written, length:%u offset:%u\n',[dnsMsgLen],dnsMsg - DEBUGF 1,'DNS: Waiting for data: (timeout is %us)\n',TIMEOUT -end if - eth.wait_for_data [socketNum],TIMEOUT,abort ; Now, we wait for data from remote - eth.read_data dword[socketNum],dnsMsg,dword[dnsMsgLen],dnsMsg+BUFFER ; Read the data into the buffer -if __DEBUG__ eq 1 - DEBUGF 1,'Data received, offset:%u buffer size:%u length:%u\n',dnsMsg,BUFFER,esi-dnsMsg -end if - eth.close_udp [socketNum] ; We're done, close the socket -if __DEBUG__ eq 1 - DEBUGF 1,'Closed Socket\n' -end if - - ; Now parse the message to get the host IP. Man, this is complicated. It's described in RFC 1035 - ; 1) Validate that we have an answer with > 0 responses - ; 2) Find the answer record with TYPE 0001 ( host IP ) - ; 3) Finally, copy the IP address to the display - ; Note: The response is in dnsMsg, the end of the buffer is pointed to by [dnsMsgLen] - - mov esi, dnsMsg - - mov al, [esi+2] ; Is this a response to my question? - and al, 0x80 - cmp al, 0x80 - jne abort -if __DEBUG__ eq 1 - DEBUGF 1,'DNS: It was a response to my question\n' -end if - - mov al, [esi+3] ; Were there any errors? - and al, 0x0F - cmp al, 0x00 - jne abort - -if __DEBUG__ eq 1 - DEBUGF 1,'DNS: There were no errors\n' -end if - - mov ax, [esi+6] ; Is there ( at least 1 ) answer? - cmp ax, 0x00 - je abort - - ; Header validated. Scan through and get my answer - add esi, 12 ; Skip to the question field - call skipName ; Skip through the question field - add esi, 4 ; skip past the questions qtype, qclass - -ctr002z: - ; Now at the answer. There may be several answers, find the right one ( TYPE = 0x0001 ) - call skipName - mov ax, [esi] - cmp ax, 0x0100 ; Is this the IP address answer? - jne ctr002c - add esi, 10 ; Yes! Point eax to the first byte of the IP address - mov eax,[esi] + xor edx, edx ret -ctr002c: ; Skip through the answer, move to the next - add esi, 8 - movzx eax, byte [esi+1] - mov ah, [esi] - add esi, eax - add esi, 2 - - cmp esi, [dnsMsgLen] ; Have we reached the end of the msg? This is an error condition, should not happen - jl ctr002z ; Check next answer - -abort: -if __DEBUG__ eq 1 - DEBUGF 1,'DNS: Something went wrong, aborting\n' -end if - xor eax,eax - - ret - - -skipName: - ; Increment esi to the first byte past the name field - ; Names may use compressed labels. Normally do. - ; RFC 1035 page 30 gives details - mov al, [esi] - cmp al, 0 - je sn_exit - and al, 0xc0 - cmp al, 0xc0 - je sn001 - - movzx eax, byte [esi] - inc eax - add esi, eax - jmp skipName - -sn001: - add esi, 2 ; A pointer is always at the end - ret - -sn_exit: - inc esi - ret - -dnsMsgLen: dd 0 -socketNum: dd 0xFFFF - -if ~defined dnsMsg -dnsMsg: rb BUFFER -end if - -end if - - diff --git a/programs/network/autodhcp/trunk/common.inc b/programs/network/autodhcp/trunk/common.inc deleted file mode 100644 index 7502591491..0000000000 --- a/programs/network/autodhcp/trunk/common.inc +++ /dev/null @@ -1,17 +0,0 @@ -macro wait time { - mov ebx,time - mov eax,5 - mcall -} - -macro get_time_counter result { - mov eax,26 - mov ebx,9 - mcall - mov result,eax -} - -macro exit { - or eax,-1 - mcall -} \ No newline at end of file diff --git a/programs/network/autodhcp/trunk/dll.inc b/programs/network/autodhcp/trunk/dll.inc new file mode 100644 index 0000000000..6ceb2d514d --- /dev/null +++ b/programs/network/autodhcp/trunk/dll.inc @@ -0,0 +1,157 @@ +;----------------------------------------------------------------------------- +proc mem.Alloc size ;///////////////////////////////////////////////////////// +;----------------------------------------------------------------------------- + push ebx ecx + mov eax,[size] + lea ecx,[eax+4+4095] + and ecx,not 4095 + mcall 68,12 + add ecx,-4 + mov [eax],ecx + add eax,4 + pop ecx ebx + ret +endp + +;----------------------------------------------------------------------------- +proc mem.ReAlloc mptr,size;/////////////////////////////////////////////////// +;----------------------------------------------------------------------------- + push ebx ecx esi edi eax + mov eax,[mptr] + mov ebx,[size] + or eax,eax + jz @f + lea ecx,[ebx+4+4095] + and ecx,not 4095 + add ecx,-4 + cmp ecx,[eax-4] + je .exit + @@: mov eax,ebx + call mem.Alloc + xchg eax,[esp] + or eax,eax + jz .exit + mov esi,eax + xchg eax,[esp] + mov edi,eax + mov ecx,[esi-4] + cmp ecx,[edi-4] + jbe @f + mov ecx,[edi-4] + @@: add ecx,3 + shr ecx,2 + cld + rep movsd + xchg eax,[esp] + call mem.Free + .exit: + pop eax edi esi ecx ebx + ret +endp + +;----------------------------------------------------------------------------- +proc mem.Free mptr ;////////////////////////////////////////////////////////// +;----------------------------------------------------------------------------- + mov eax,[mptr] + or eax,eax + jz @f + push ebx ecx + lea ecx,[eax-4] + mcall 68,13 + pop ecx ebx + @@: ret +endp + + +proc dll.Load, import_table:dword + mov esi,[import_table] + .next_lib: mov edx,[esi] + or edx,edx + jz .exit + push esi + mov esi,[esi+4] + mov edi,s_libdir.fname + @@: lodsb + stosb + or al,al + jnz @b + mcall 68,19,s_libdir + or eax,eax + jz .fail + stdcall dll.Link,eax,edx + stdcall dll.Init,[eax+4] + pop esi + add esi,8 + jmp .next_lib + .exit: xor eax,eax + ret + .fail: add esp,4 + xor eax,eax + inc eax + ret +endp + +proc dll.Link, exp:dword,imp:dword + push eax + mov esi,[imp] + test esi,esi + jz .done + .next: lodsd + test eax,eax + jz .done + stdcall dll.GetProcAddress,[exp],eax + or eax,eax + jz @f + mov [esi-4],eax + jmp .next + @@: mov dword[esp],0 + .done: pop eax + ret +endp + +proc dll.Init, dllentry:dword + pushad + mov eax,mem.Alloc + mov ebx,mem.Free + mov ecx,mem.ReAlloc + mov edx,dll.Load + stdcall [dllentry] + popad + ret +endp + +proc dll.GetProcAddress, exp:dword,sz_name:dword + mov edx,[exp] + xor eax,eax + .next: or edx,edx + jz .end + cmp dword[edx],0 + jz .end + stdcall strcmp,[edx],[sz_name] + test eax,eax + jz .ok + add edx,8 + jmp .next + .ok: mov eax,[edx+4] + .end: ret +endp + +proc strcmp, str1:dword,str2:dword + push esi edi + mov esi,[str1] + mov edi,[str2] + xor eax,eax + @@: lodsb + scasb + jne .fail + or al,al + jnz @b + jmp .ok + .fail: or eax,-1 + .ok: pop edi esi + ret +endp + +s_libdir: + db '/sys/lib/' + .fname rb 32 diff --git a/programs/network/autodhcp/trunk/events.inc b/programs/network/autodhcp/trunk/events.inc deleted file mode 100644 index e7014783d8..0000000000 --- a/programs/network/autodhcp/trunk/events.inc +++ /dev/null @@ -1,49 +0,0 @@ - -macro set_event_mask mask { - mov ebx, mask - mov eax, 40 - mcall -} - -macro wait_for_event { - mov eax, 10 - mcall -} - -macro check_for_event { - mov eax, 11 - mcall -} - -macro wait_for_event_timeout timeout { - mov ebx,timeout - mov eax, 23 - mcall -} - - -event_redraw equ 1 shl 0 -event_keyboard equ 1 shl 1 -event_button equ 1 shl 2 -event_background equ 1 shl 4 -event_mouse equ 1 shl 5 -event_ipc equ 1 shl 6 -event_network equ 1 shl 7 -event_debug equ 1 shl 8 -event_irq0 equ 1 shl 15 -event_irq1 equ 1 shl 16 -event_irq2 equ 1 shl 17 -event_irq3 equ 1 shl 18 -event_irq4 equ 1 shl 19 -event_irq5 equ 1 shl 20 -event_irq6 equ 1 shl 21 -event_irq7 equ 1 shl 22 -event_irq8 equ 1 shl 23 -event_irq9 equ 1 shl 24 -event_irq10 equ 1 shl 25 -event_irq11 equ 1 shl 26 -event_irq12 equ 1 shl 27 -event_irq13 equ 1 shl 28 -event_irq14 equ 1 shl 29 -event_irq15 equ 1 shl 30 - diff --git a/programs/network/autodhcp/trunk/autodhcp.asm b/programs/network/autodhcp/trunk/zeroconf.asm similarity index 73% rename from programs/network/autodhcp/trunk/autodhcp.asm rename to programs/network/autodhcp/trunk/zeroconf.asm index 04b3709915..c8835b21f2 100644 --- a/programs/network/autodhcp/trunk/autodhcp.asm +++ b/programs/network/autodhcp/trunk/zeroconf.asm @@ -1,9 +1,9 @@ -; Automated dhcp client -; v 1.3 +; Zero-config +; v 1.4 ; -; with thanks to authors of DHCP client for menuetos: Mike Hibbet +; DHCP code is based on that by Mike Hibbet (DHCP client for menuetos) ; -; by HidnPlayr & Derpenguin +; Written by HidnPlayr & Derpenguin use32 org 0x0 @@ -14,7 +14,7 @@ use32 dd IM_END ; size of image dd I_END ; memory for app dd I_END ; esp - dd 0x0 , 0x0 ; I_Param , I_Icon + dd 0x0 , path ; I_Param , I_Icon ; CONFIGURATION @@ -41,25 +41,25 @@ RATE_LIMIT_INTERVAL equ 60 ; seconds (delay between successive attempts) DEFEND_INTERVAL equ 10 ; seconds (min. wait between defensive ARPs) -include '..\..\..\macros.inc' +include '../../../proc32.inc' +include '../../../macros.inc' include 'eth.inc' include 'debug-fdo.inc' include 'dhcp.inc' -include 'events.inc' -include 'common.inc' - +include 'dll.inc' START: ; start of execution - set_event_mask event_network + mcall 40, 0 + eth.set_network_drv 0x00000383 - DEBUGF 1,"Stack Initialized.\n" + DEBUGF 1,"Zero-config service:\n" eth.status eax ; Read the Stack status test eax,eax ; if eax is zero, no driver was found jnz @f - DEBUGF 1,"No Card detected\n" + DEBUGF 1,"No Card found!\n" jmp close @@: @@ -68,15 +68,65 @@ START: ; start of execution eth.check_cable eax test al,al jnz @f - DEBUGF 1,"Ethernet Cable not connected\n" - wait 500 ; loop until cable is connected (check every 5 sec) + DEBUGF 1,"Cable disconnected!\n" + mcall 5, 500 ; loop until cable is connected (check every 5 sec) jmp @r @@: - DEBUGF 1,"Ethernet Cable status: %d\n",al - eth.read_mac MAC - DEBUGF 1,"MAC address: %x-%x-%x-%x-%x-%x\n",[MAC]:2,[MAC+1]:2,[MAC+2]:2,[MAC+3]:2,[MAC+4]:2,[MAC+5]:2 + 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] + dec edi + + mov esi, filename + mov ecx, 5 + rep movsb + + mcall 64,1,I_END_2 + mcall 68,11 + + stdcall dll.Load,@IMPORT + or eax,eax + jnz skip_ini + + + invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0 + + 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 + eth.set_IP edx + + invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0 + mov edx, inibuf + call Ip2dword + eth.set_GATEWAY edx + + invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0 + mov edx, inibuf + call Ip2dword + eth.set_DNS edx + + invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0 + mov edx, inibuf + call Ip2dword + eth.set_SUBNET edx + + + mcall -1 + + +skip_ini: eth.check_port 68,eax ; Check if port 68 is available cmp eax,1 @@ -87,23 +137,28 @@ START: ; start of execution @@: eth.open_udp 68,67,-1,[socketNum] ; open socket (local,remote,ip,socket) - DEBUGF 1,"Socket opened: %d\n",eax ; Setup the first msg we will send mov byte [dhcpMsgType], 0x01 ; DHCP discover mov dword [dhcpLease], esi ; esi is still -1 (-1 = forever) - get_time_counter eax + mcall 26, 9 imul eax,100 mov [currTime],eax buildRequest: ; Creates a DHCP request packet. - xor eax,eax ; Clear dhcpMsg to all zeros - mov edi,dhcpMsg + stdcall mem.Alloc, BUFFER + mov [dhcpMsg], eax + test eax,eax + jz apipa + + + mov edi, eax mov ecx,BUFFER + xor eax,eax cld rep stosb - mov edx, dhcpMsg + mov edx,[dhcpMsg] mov [edx], byte 0x01 ; Boot request mov [edx+1], byte 0x01 ; Ethernet @@ -147,9 +202,9 @@ request_options: mov [dhcpMsgLen], dword 268 send_request: - eth.write_udp [socketNum],[dhcpMsgLen],dhcpMsg ; write to socket ( send broadcast request ) + eth.write_udp [socketNum],[dhcpMsgLen],[dhcpMsg] ; write to socket ( send broadcast request ) - mov eax, dhcpMsg ; Setup the DHCP buffer to receive response + mov eax, [dhcpMsg] ; Setup the DHCP buffer to receive response mov [dhcpMsgLen], eax ; Used as a pointer to the data mov eax,23 ; wait here for event (data from remote) @@ -167,7 +222,7 @@ send_request: read_data: ; we have data - this will be the response - eth.read_packet [socketNum], dhcpMsg, BUFFER + eth.read_packet [socketNum], [dhcpMsg], BUFFER mov [dhcpMsgLen], eax eth.close_udp [socketNum] @@ -219,7 +274,7 @@ request: ;*************************************************************************** parseResponse: DEBUGF 1,"Data received, parsing response\n" - mov edx, dhcpMsg + mov edx, [dhcpMsg] pusha eth.set_IP [edx+16] @@ -313,6 +368,9 @@ pr_exit: jmp close apipa: + stdcall mem.Free, [dhcpMsg] + +link_local: call random mov ecx,0xfea9 ; IP 169.254.0.0 link local net, see RFC3927 mov cx,ax @@ -322,7 +380,7 @@ apipa: eth.set_GATEWAY 0x0 eth.set_DNS 0x0 - wait PROBE_WAIT*100 + mcall 5, PROBE_WAIT*100 xor esi,esi probe_loop: @@ -340,7 +398,7 @@ apipa: movzx ebx,al DEBUGF 1,"Waiting %u0ms\n",ebx - wait ebx + mcall 5 DEBUGF 1,"Sending Probe\n" ; eth.ARP_PROBE MAC @@ -353,7 +411,7 @@ apipa: ; IP within this time, we should create another adress, that have to be done later DEBUGF 1,"Waiting %us\n",ANNOUNCE_WAIT - wait ANNOUNCE_WAIT*100 + mcall 5, ANNOUNCE_WAIT*100 xor esi,esi announce_loop: @@ -365,17 +423,16 @@ apipa: je @f DEBUGF 1,"Waiting %us\n",ANNOUNCE_INTERVAL - wait ANNOUNCE_INTERVAL*100 + mcall 5, ANNOUNCE_INTERVAL*100 jmp announce_loop @@: ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;) close: - DEBUGF 1,"Exiting\n" - exit ; at last, exit + mcall -1 -random: +random: ; Pseudo random actually mov eax,[generator] add eax,-43ab45b5h @@ -390,22 +447,52 @@ ret ; DATA AREA +align 16 +@IMPORT: + +library \ + libini,'libini.obj' + +import libini, \ + ini.get_str,'ini.get_str',\ + ini.set_str,'ini.set_str',\ + ini.get_int,'ini.get_int',\ + ini.set_int,'ini.set_int',\ + ini.enum_sections,'ini.enum_sections',\ + ini.enum_keys,'ini.enum_keys' + include_debug_strings +filename db '.ini',0 +str_ip db 'ip',0 +str_subnet db 'subnet',0 +str_gateway db 'gateway',0 +str_dns db 'dns',0 +str_ipconfig db 'ipconfig',0 +str_type db 'type',0 + + IM_END: -dhcpClientIP dd 0 -dhcpMsgType db 0 -dhcpLease dd 0 -dhcpServerIP dd 0 +inibuf rb 16 -dhcpMsgLen dd 0 -socketNum dd 0 +dhcpClientIP dd ? +dhcpMsgType db ? +dhcpLease dd ? +dhcpServerIP dd ? -MAC rb 6 -currTime dd 0 -renewTime dd 0 -generator dd 0 +dhcpMsgLen dd ? +socketNum dd ? + +MAC dp ? +currTime dd ? +renewTime dd ? +generator dd ? + +dhcpMsg dd ? + +I_END_2: + +path rb 1024+5 -dhcpMsg rb BUFFER I_END: \ No newline at end of file diff --git a/programs/network/autodhcp/trunk/zeroconf.ini b/programs/network/autodhcp/trunk/zeroconf.ini new file mode 100644 index 0000000000..7d57752210 --- /dev/null +++ b/programs/network/autodhcp/trunk/zeroconf.ini @@ -0,0 +1,9 @@ +[ipconfig] +; type should be static or zeroconf +; zeroconf means the service first tries to contact a DHCP server +; If dhcp is not available, it switches to link-local +type = static +ip = 192.168.1.150 +gateway = 192.168.1.1 +dns = 192.168.1.1 +subnet = 255.255.255.0 \ No newline at end of file