Updated API so applications can easily send ARP announcements, keep track of ARP conflicts.

Zeroconfig now supports padding option and sends ARP announcements if needed. Also some refactoring/cleanup.


git-svn-id: svn://kolibrios.org@3200 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
hidnplayr 2013-01-27 20:03:18 +00:00
parent 14192f7dba
commit a8ad5846a9
3 changed files with 478 additions and 415 deletions

View File

@ -1,6 +1,6 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;; ;; ;;
;; Copyright (C) KolibriOS team 2010-2012. All rights reserved. ;; ;; Copyright (C) KolibriOS team 2010-2013. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;; ;; Distributed under terms of the GNU General Public License ;;
;; ;; ;; ;;
;; netstat.asm - Network Status Tool for KolibriOS ;; ;; netstat.asm - Network Status Tool for KolibriOS ;;
@ -10,18 +10,13 @@
;; GNU GENERAL PUBLIC LICENSE ;; ;; GNU GENERAL PUBLIC LICENSE ;;
;; Version 2, June 1991 ;; ;; Version 2, June 1991 ;;
;; ;; ;; ;;
;; ;;
;; 0.1 - 22 sept 2009 - initial release ;;
;; 0.2 - 9 july 2012 - converted to new sysfunc numbers ;;
;; 0.3 - 13 july 2012 - work with multiple network interfaces ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
format binary as "" format binary as ""
use32 use32
org 0x0 org 0x0
db 'MENUET01' ; 8 byte id db 'MENUET01' ; 8 byte id
dd 0x01 ; header version dd 0x01 ; header version
@ -35,11 +30,11 @@ include '..\macros.inc'
include '..\network.inc' include '..\network.inc'
START: START:
mcall 40, 101b mcall 40, EVM_REDRAW + EVM_BUTTON
redraw: redraw:
mcall 12, 1 mcall 12, 1
mcall 0, 100 shl 16 + 600, 100 shl 16 + 240, 0x34bcbcbc , , name ; draw window mcall 0, 100 shl 16 + 600, 100 shl 16 + 240, 0x34bcbcbc, , name ; draw window
call draw_interfaces call draw_interfaces
@ -167,6 +162,9 @@ redraw:
add ebx, 18 add ebx, 18
mov edx, str_arp mov edx, str_arp
mcall mcall
add ebx, 18
mov edx, str_conflicts
mcall
jmp end_of_draw jmp end_of_draw
@ -184,221 +182,239 @@ end_of_draw:
draw_stats: draw_stats:
cmp [mode], 101 cmp [mode], 101
jne not_101 jne not_101
mov ebx, API_ETH mov ebx, API_ETH
mov bh, [device] mov bh, [device]
@@: @@:
push ebx push ebx
mcall 76 mcall 76
pop ebx pop ebx
push eax push eax
inc bl inc bl
cmp bl, 3 cmp bl, 3
jle @r jbe @r
inc bl ;5 inc bl ;5
inc bl ;6 inc bl ;6
@@: @@:
push ebx push ebx
mcall 76 mcall 76
pop ebx pop ebx
push eax
inc bl
cmp bl, 7
jle @r
mov eax, 47 push eax
mov ebx, 0x000a0000 inc bl
mov esi, 0x40000000 cmp bl, 7
mov edi, 0x00bcbcbc jbe @r
mov edx, 135 shl 16 + 75 + 6*18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 2*18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
jmp mainloop mov ebx, 0x000a0000
pop ecx
mov edx, 135 shl 16 + 75 + 6*18
mov esi, 0x40000000
mov edi, 0x00bcbcbc
mcall 47
sub edx, 18
pop ecx
mcall
sub edx, 2*18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
jmp mainloop
not_101: not_101:
cmp [mode], 102 cmp [mode], 102
jne not_102 jne not_102
mov ebx, API_IPv4 mov ebx, API_IPv4
mov bh, [device] mov bh, [device]
push ebx push ebx
mcall 76 mcall 76
pop ebx pop ebx
push eax push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
mov eax, 47 inc bl
mov ebx, 0x000a0000 push ebx
mov esi, 0x40000000 mcall 76
mov edi, 0x00bcbcbc pop ebx
mov edx, 135 shl 16 + 75 + 18 push eax
pop ecx
mcall
sub edx, 18
pop ecx
mcall
jmp mainloop
not_102: mov ebx, 0x000a0000
pop ecx
mov edx, 135 shl 16 + 75 + 18
mov esi, 0x40000000
mov edi, 0x00bcbcbc
mcall 47
cmp [mode], 103 sub edx, 18
jne not_103 pop ecx
mcall
mov ebx, API_ARP jmp mainloop
mov bh, [device]
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
mov eax, 47
mov ebx, 0x000a0000
mov esi, 0x40000000
mov edi, 0x00bcbcbc
mov edx, 135 shl 16 + 75 + 2*18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
jmp mainloop not_102:
cmp [mode], 103
jne not_103
mov ebx, API_ARP
mov bh, [device]
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
mov bl, 7
push ebx
mcall 76
pop ebx
push eax
mov ebx, 0x000a0000
pop ecx
mov edx, 135 shl 16 + 75 + 3*18
mov esi, 0x40000000
mov edi, 0x00bcbcbc
mcall 47
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
sub edx, 18
pop ecx
mcall
jmp mainloop
not_103: not_103:
cmp [mode], 104 cmp [mode], 104
jne not_104 jne not_104
mov ebx, API_ICMP mov ebx, API_ICMP
mov bh, [device] mov bh, [device]
push ebx push ebx
mcall 76 mcall 76
pop ebx pop ebx
push eax push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
mov eax, 47 inc bl
mov ebx, 0x000a0000 push ebx
mov esi, 0x40000000 mcall 76
mov edi, 0x00bcbcbc pop ebx
mov edx, 135 shl 16 + 75 + 18 push eax
pop ecx
mcall
sub edx, 18
pop ecx
mcall
jmp mainloop mov ebx, 0x000a0000
pop ecx
mov edx, 135 shl 16 + 75 + 18
mov esi, 0x40000000
mov edi, 0x00bcbcbc
mcall 47
sub edx, 18
pop ecx
mcall
jmp mainloop
not_104: not_104:
cmp [mode], 105 cmp [mode], 105
jne not_105 jne not_105
mov ebx, API_UDP mov ebx, API_UDP
mov bh, [device] mov bh, [device]
push ebx push ebx
mcall 76 mcall 76
pop ebx pop ebx
push eax push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
mov eax, 47 inc bl
mov ebx, 0x000a0000 push ebx
mov esi, 0x40000000 mcall 76
mov edi, 0x00bcbcbc pop ebx
mov edx, 135 shl 16 + 75 + 18 push eax
pop ecx
mcall
sub edx, 18
pop ecx
mcall
jmp mainloop mov ebx, 0x000a0000
pop ecx
mov edx, 135 shl 16 + 75 + 18
mov esi, 0x40000000
mov edi, 0x00bcbcbc
mcall 47
sub edx, 18
pop ecx
mcall
jmp mainloop
not_105: not_105:
cmp [mode], 106 cmp [mode], 106
jne not_106 jne not_106
mov ebx, API_TCP mov ebx, API_TCP
mov bh, [device] mov bh, [device]
push ebx push ebx
mcall 76 mcall 76
pop ebx pop ebx
push eax push eax
inc bl
push ebx
mcall 76
pop ebx
push eax
inc bl
mov eax, 47 inc bl
mov ebx, 0x000a0000 push ebx
mov esi, 0x40000000 mcall 76
mov edi, 0x00bcbcbc pop ebx
mov edx, 135 shl 16 + 75 + 18 push eax
pop ecx
mcall
sub edx, 18
pop ecx
mcall
jmp mainloop mov ebx, 0x000a0000
pop ecx
mov edx, 135 shl 16 + 75 + 18
mov esi, 0x40000000
mov edi, 0x00bcbcbc
mcall 47
sub edx, 18
pop ecx
mcall
jmp mainloop
not_106: not_106:
@ -568,6 +584,7 @@ str_dns db 'DNS address:', 0
str_subnet db 'Subnet mask:', 0 str_subnet db 'Subnet mask:', 0
str_gateway db 'Standard gateway:', 0 str_gateway db 'Standard gateway:', 0
str_arp db 'ARP entrys:', 0 str_arp db 'ARP entrys:', 0
str_conflicts db 'ARP conflicts:', 0
str_unknown db 'unknown', 0 str_unknown db 'unknown', 0
namebuf rb 64 namebuf rb 64

View File

@ -1,9 +1,20 @@
; Zero-config ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; v 1.4 ;; ;;
; ;; Copyright (C) KolibriOS team 2010-2013. All rights reserved. ;;
; DHCP code is based on that by Mike Hibbet (DHCP client for menuetos) ;; Distributed under terms of the GNU General Public License ;;
; ;; ;;
; Written by HidnPlayr & Derpenguin ;; 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 "" format binary as ""
@ -20,7 +31,6 @@ use32
; CONFIGURATION ; CONFIGURATION
TIMEOUT equ 60 ; in seconds TIMEOUT equ 60 ; in seconds
BUFFER equ 1024 ; in bytes BUFFER equ 1024 ; in bytes
__DEBUG__ equ 1 ; enable/disable __DEBUG__ equ 1 ; enable/disable
@ -92,11 +102,11 @@ Ip2dword:
xor eax, eax ; current character xor eax, eax ; current character
xor ebx, ebx ; current byte xor ebx, ebx ; current byte
.outer_loop: .outer_loop:
shl edx, 8 shl edx, 8
add edx, ebx add edx, ebx
xor ebx, ebx xor ebx, ebx
.inner_loop: .inner_loop:
lodsb lodsb
test eax, eax test eax, eax
jz .finish jz .finish
@ -106,7 +116,7 @@ Ip2dword:
imul ebx, 10 imul ebx, 10
add ebx, eax add ebx, eax
jmp .inner_loop jmp .inner_loop
.finish: .finish:
shl edx, 8 shl edx, 8
add edx, ebx add edx, ebx
@ -125,14 +135,13 @@ no_IP:
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 cmp eax, -1
je exit je exit
@ -141,94 +150,90 @@ START: ; start of execution
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 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
mov edi, path ; Calculate the length of zero-terminated string xor al, al
xor al , al
mov ecx, 1024 mov ecx, 1024
repnz scas byte[es:edi] repne scasb
dec edi dec edi
mov esi, filename mov esi, filename ; append with .ini
movsd movsd
movsb movsb
DEBUGF 1,"->path to ini: %s\n", path DEBUGF 1,"->Loading ini %s\n", path
mcall 68,11 mcall 68, 11
stdcall dll.Load,@IMPORT stdcall dll.Load,@IMPORT
or eax,eax or eax, eax
jnz skip_ini jnz try_dhcp
invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
cmp dword[inibuf], 'stat'
jne try_dhcp
invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 76, API_IPv4 + 3, edx
invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 76, API_IPv4 + 9, edx
invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 76, API_IPv4 + 5, edx
invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 76, API_IPv4 + 7, edx
invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0 mcall -1
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
mcall 76, API_IPv4 + 3, edx
invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 76, API_IPv4 + 9, edx
invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 76, API_IPv4 + 5, edx
invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
mov edx, inibuf
call Ip2dword
mcall 76, API_IPv4 + 7, edx
mcall -1 try_dhcp:
DEBUGF 1,"->Trying DHCP\n"
skip_ini: mcall 75, 0, AF_INET4, SOCK_DGRAM, 0 ; open socket (parameters: domain, type, reserved)
cmp eax, -1
je error
mov [socketNum], eax
DEBUGF 1,"->Skip ini\n" DEBUGF 1,"->Socket %x opened\n", eax
mcall 75, 0, AF_INET4, SOCK_DGRAM, 0 ; open socket (parameters: domain, type, reserved) mcall 75, 2, [socketNum], sockaddr1, 18 ; bind socket to local port 68
cmp eax, -1 cmp eax, -1
je error je error
mov [socketNum], eax
DEBUGF 1,"->socket %x opened\n", eax
mcall 75, 2, [socketNum], sockaddr1, 18 ; bind socket to local port 68
cmp eax, -1
je error
DEBUGF 1,"->Socket Bound to local port 68\n" DEBUGF 1,"->Socket Bound to local port 68\n"
mcall 75, 4, [socketNum], sockaddr2, 18 ; connect to 255.255.255.255 on port 67 mcall 75, 4, [socketNum], sockaddr2, 18 ; connect to 255.255.255.255 on port 67
cmp eax, -1 cmp eax, -1
je error je error
DEBUGF 1,"->Connected to 255.255.255.255 on port 67\n" DEBUGF 1,"->Connected to 255.255.255.255 on port 67\n"
mov byte [dhcpMsgType], 0x01 ; DHCP discover mov [dhcpMsgType], 0x01 ; DHCP discover
mov dword [dhcpLease], esi ; esi is still -1 (-1 = forever) mov [dhcpLease], esi ; esi is still -1 (-1 = forever)
mcall 26, 9 mcall 26, 9 ; Get system time
imul eax,100 imul eax, 100
mov [currTime],eax mov [currTime], eax
buildRequest: ; Creates a DHCP request packet. build_request: ; Creates a DHCP request packet.
DEBUGF 1,"->Building request\n" DEBUGF 1,"->Building request\n"
stdcall mem.Alloc, BUFFER stdcall mem.Alloc, BUFFER
mov [dhcpMsg], eax mov [dhcpMsg], eax
test eax,eax test eax, eax
jz apipa jz apipa
;;; todo: skip this bullcrap ;;; todo: skip this bullcrap
@ -236,18 +241,17 @@ buildRequest: ; Creates a DHCP request packet.
mov edi, eax mov edi, eax
mov ecx, BUFFER mov ecx, BUFFER
xor eax, eax xor eax, eax
cld
rep stosb rep stosb
;; todo: put this in a buffer instead of writing bytes and words! ;; todo: put this in a buffer instead of writing bytes and words!
mov edx,[dhcpMsg] mov edx, [dhcpMsg]
mov [edx], byte 0x01 ; Boot request mov [edx], byte 0x01 ; Boot request
mov [edx+1], byte 0x01 ; Ethernet mov [edx+1], byte 0x01 ; Ethernet
mov [edx+2], byte 0x06 ; Ethernet h/w len mov [edx+2], byte 0x06 ; Ethernet h/w len
mov [edx+4], dword 0x11223344 ; xid ;;;;;;; mov [edx+4], dword 0x11223344 ; xid ;;;;;;;
mov eax,[currTime] mov eax, [currTime]
mov [edx+8], eax ; secs, our uptime mov [edx+8], eax ; secs, our uptime
mov [edx+10], byte 0x80 ; broadcast flag set mov [edx+10], byte 0x80 ; broadcast flag set
mov eax, dword [MAC] ; first 4 bytes of MAC mov eax, dword [MAC] ; first 4 bytes of MAC
@ -273,7 +277,7 @@ buildRequest: ; Creates a DHCP request packet.
mov [edx+240+21], byte 0xff ; "Discover" options mov [edx+240+21], byte 0xff ; "Discover" options
mov [dhcpMsgLen], dword 262 ; end of options marker mov [dhcpMsgLen], dword 262 ; end of options marker
jmp send_request jmp send_dhcpmsg
request_options: request_options:
mov [edx+240+21], word 0x0436 ; server IP mov [edx+240+21], word 0x0436 ; server IP
@ -284,7 +288,7 @@ request_options:
mov [dhcpMsgLen], dword 268 mov [dhcpMsgLen], dword 268
send_request: send_dhcpmsg:
mcall 75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen] ; write to socket ( send broadcast request ) mcall 75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen] ; 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
@ -302,44 +306,58 @@ read_data: ; we have data - this wi
mov [dhcpMsgLen], eax mov [dhcpMsgLen], eax
; depending on which msg we sent, handle the response ; depending on which msg we sent, handle the response
; accordingly. ; accordingly.
; If the response is to a dhcp discover, then: ; If the response is to a dhcp discover, then:
; 1) If response is DHCP OFFER then ; 1) If response is DHCP OFFER then
; 1.1) record server IP, lease time & IP address. ; 1.1) record server IP, lease time & IP address.
; 1.2) send a request packet ; 1.2) send a request packet
; If the response is to a dhcp request, then: ; If the response is to a dhcp request, then:
; 1) If the response is DHCP ACK then ; 1) If the response is DHCP ACK then
; 1.1) extract the DNS & subnet fields. Set them in the stack ; 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 je discover
cmp [dhcpMsgType], byte 0x03 ; did we send a request?
je request
jmp exit ; really unknown, what we did cmp [dhcpMsgType], 0x03 ; did we send a request?
je request
call dhcp_end ; we should never reach here ;)
jmp exit
discover: discover:
call parseResponse call parse_response
cmp [dhcpMsgType], byte 0x02 ; Was the response an offer? cmp [dhcpMsgType], 0x02 ; Was the response an offer?
jne apipa ; NO - so we do zeroconf je send_request
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: request:
call parseResponse call parse_response
call dhcp_end
cmp [dhcpMsgType], byte 0x05 ; Was the response an ACK? It should be cmp [dhcpMsgType], 0x05 ; Was the response an ACK? It should be
jne apipa ; NO - so we do zeroconf jne link_local ; NO - so we do link-local
mcall 76, API_IPv4 + 3, [dhcp.ip] ; ip mcall 76, API_IPv4 + 3, [dhcp.ip] ; ip
mcall 76, API_IPv4 + 5, [dhcp.dns] ; dns mcall 76, API_IPv4 + 5, [dhcp.dns] ; dns
mcall 76, API_IPv4 + 7, [dhcp.subnet] ; subnet mcall 76, API_IPv4 + 7, [dhcp.subnet] ; subnet
mcall 76, API_IPv4 + 9, [dhcp.gateway] ; gateway mcall 76, API_IPv4 + 9, [dhcp.gateway] ; gateway
jmp exit jmp exit
dhcp_end:
mcall close, [socketNum]
stdcall mem.Free, [dhcpMsg]
ret
;*************************************************************************** ;***************************************************************************
; Function ; Function
; parseResponse ; parseResponse
@ -353,175 +371,190 @@ request:
; The message is stored in dhcpMsg ; The message is stored in dhcpMsg
; ;
;*************************************************************************** ;***************************************************************************
parseResponse: parse_response:
DEBUGF 1,"Data received, parsing response\n"
mov edx, [dhcpMsg]
push dword [edx+16] DEBUGF 1,"Data received, parsing response\n"
pop [dhcp.ip] mov edx, [dhcpMsg]
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 push dword [edx+16]
xor ecx, ecx pop [dhcp.ip]
DEBUGF 1,"Client: %u.%u.%u.%u\n", [edx+16]:1, [edx+17]:1, [edx+18]:1, [edx+19]:1
next_option: ; TODO: check if there really are options
add edx, ecx
pr001:
mov al, [edx]
cmp al, 0xff ; End of options?
je pr_exit
cmp al, dhcp_msg_type ; Msg type is a single byte option mov al, 240 ; Point to first option
jne @f movzx ecx, al
mov al, [edx+2] .next_option:
mov [dhcpMsgType], al add edx, ecx
DEBUGF 1,"DHCP Msg type: %u\n", al mov al, [edx] ; get message identifier
add edx, 3 cmp al, 0xff ; End of options?
jmp pr001 ; Get next option je .done
@@: cmp al, 0
inc edx je .pad
movzx ecx, byte [edx]
inc edx ; point to data
cmp al, dhcp_dhcp_server_id ; server ip ; TODO: check if we still are inside the buffer
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
@@: inc edx
cmp al, dhcp_address_time movzx ecx, byte [edx] ; get data length
jne @f inc edx ; point to data
pusha cmp al, dhcp_msg_type ; Msg type is a single byte option
mov eax,[edx] je .msgtype
bswap eax
mov [dhcpLease],eax
DEBUGF 1,"lease: %d\n",eax
popa
jmp next_option cmp al, dhcp_dhcp_server_id
je .server
@@: cmp al, dhcp_address_time
cmp al, dhcp_subnet_mask je .lease
jne @f
push dword [edx] cmp al, dhcp_subnet_mask
pop [dhcp.subnet] je .subnet
DEBUGF 1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
jmp next_option
@@: cmp al, dhcp_router
cmp al, dhcp_router je .router
jne @f
push dword [edx] cmp al, dhcp_domain_server
pop [dhcp.gateway] je .dns
DEBUGF 1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
jmp next_option
DEBUGF 1,"Unsupported DHCP option: %u\n", al
@@: jmp .next_option
cmp al, dhcp_domain_server
jne next_option
push dword [edx] .pad:
pop [dhcp.dns] xor ecx, ecx
DEBUGF 1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1 inc ecx
jmp next_option jmp .next_option
pr_exit: .msgtype:
mov al, [edx]
mov [dhcpMsgType], al
DEBUGF 1,"DHCP Msg type: %u\n", al
jmp .next_option ; Get next option
.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
.lease:
pusha
mov eax,[edx]
bswap eax
mov [dhcpLease],eax
DEBUGF 1,"lease: %d\n",eax
popa
jmp .next_option
.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
.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
.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
.done:
ret ret
; DEBUGF 1,"Sending ARP announce\n"
;;;
apipa: apipa:
mcall close, [socketNum] mcall close, [socketNum]
stdcall mem.Free, [dhcpMsg] stdcall mem.Free, [dhcpMsg]
link_local: link_local:
call random call random
mov ecx,0xfea9 ; IP 169.254.0.0 link local net, see RFC3927 mov ecx, 0xfea9 ; IP 169.254.0.0 link local net, see RFC3927
mov cx,ax mov cx, ax
mcall 76, API_IPv4 + 3, ecx ; mask is 255.255.0.0 mcall 76, API_IPv4 + 3, ecx ; mask is 255.255.0.0
DEBUGF 1,"Link Local IP assinged: 169.254.%u.%u\n",[generator+2]:1,[generator+3]:1 DEBUGF 1,"Link Local IP assinged: 169.254.%u.%u\n", [generator+2]:1, [generator+3]:1
mcall 76, API_IPv4 + 5, 0xffff mcall 76, API_IPv4 + 5, 0xffff
mcall 76, API_IPv4 + 9, 0x0 mcall 76, API_IPv4 + 9, 0x0
mcall 76, API_IPv4 + 7, 0x0 mcall 76, API_IPv4 + 7, 0x0
mcall 5, PROBE_WAIT*100 mcall 5, PROBE_WAIT*100
xor esi,esi xor esi, esi
probe_loop: probe_loop:
call random ; create a pseudo random number in eax (seeded by MAC) 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 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 add al, (PROBE_MAX-PROBE_MIN)*100 ; al is too small
@@: @@:
cmp al,PROBE_MAX*100 cmp al, PROBE_MAX*100
jle @f jbe @f
sub al,(PROBE_MAX-PROBE_MIN)*100 sub al, (PROBE_MAX-PROBE_MIN)*100
@@: @@:
movzx ebx,al movzx ebx,al
DEBUGF 1,"Waiting %u0ms\n",ebx DEBUGF 1,"Waiting %u0ms\n",ebx
mcall 5 mcall 5
DEBUGF 1,"Sending Probe\n" DEBUGF 1,"Sending Probe\n"
; eth.ARP_PROBE MAC mcall 76, API_ARP + 6
inc esi inc esi
cmp esi,PROBE_NUM 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 ; 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 ; IP within this time, we should create another adress, that have to be done later
DEBUGF 1,"Waiting %us\n",ANNOUNCE_WAIT DEBUGF 1,"Waiting %us\n", ANNOUNCE_WAIT
mcall 5, ANNOUNCE_WAIT*100 mcall 5, ANNOUNCE_WAIT*100
xor esi,esi xor esi, esi
announce_loop: announce_loop:
DEBUGF 1,"Sending Announce\n" DEBUGF 1,"Sending Announce\n"
; eth.ARP_ANNOUNCE MAC mcall 76, API_ARP + 6
inc esi inc esi
cmp esi,ANNOUNCE_NUM cmp esi,ANNOUNCE_NUM
je @f je @f
DEBUGF 1,"Waiting %us\n",ANNOUNCE_INTERVAL DEBUGF 1,"Waiting %us\n", ANNOUNCE_INTERVAL
mcall 5, ANNOUNCE_INTERVAL*100 mcall 5, ANNOUNCE_INTERVAL*100
jmp announce_loop jmp announce_loop
@@: @@:
; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
error: error:
exit: DEBUGF 1,"Socket error\n"
mcall -1 exit: ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
mcall -1
random: ; Pseudo random actually random: ; Pseudo random actually
mov eax,[generator] mov eax, [generator]
add eax,-43ab45b5h add eax, -43ab45b5h
ror eax,1 ror eax, 1
bswap eax bswap eax
xor eax,dword[MAC] xor eax, dword[MAC]
ror eax,1 ror eax, 1
xor eax,dword[MAC+2] xor eax, dword[MAC+2]
mov [generator],eax mov [generator], eax
ret ret
; DATA AREA ; DATA AREA
@ -536,13 +569,13 @@ import libini, \
include_debug_strings include_debug_strings
filename db '.ini',0 filename db '.ini', 0
str_ip db 'ip',0 str_ip db 'ip', 0
str_subnet db 'subnet',0 str_subnet db 'subnet', 0
str_gateway db 'gateway',0 str_gateway db 'gateway', 0
str_dns db 'dns',0 str_dns db 'dns', 0
str_ipconfig db 'ipconfig',0 str_ipconfig db 'ipconfig', 0
str_type db 'type',0 str_type db 'type', 0
sockaddr1: sockaddr1:
@ -584,7 +617,6 @@ socketNum dd ?
MAC dp ? MAC dp ?
currTime dd ? currTime dd ?
renewTime dd ?
generator dd ? generator dd ?
dhcpMsg dd ? dhcpMsg dd ?

View File

@ -64,6 +64,7 @@ uglobal
ARP_PACKETS_TX rd MAX_NET_DEVICES ARP_PACKETS_TX rd MAX_NET_DEVICES
ARP_PACKETS_RX rd MAX_NET_DEVICES ARP_PACKETS_RX rd MAX_NET_DEVICES
ARP_CONFLICTS rd MAX_NET_DEVICES
endg endg
@ -83,7 +84,7 @@ macro ARP_init {
mov [NumARP], eax mov [NumARP], eax
mov edi, ARP_PACKETS_TX mov edi, ARP_PACKETS_TX
mov ecx, 2*MAX_NET_DEVICES mov ecx, 3*MAX_NET_DEVICES
rep stosd rep stosd
} }
@ -282,6 +283,7 @@ ARP_input:
ret ret
.collision: .collision:
inc [ARP_CONFLICTS + 4*edi]
DEBUGF 1,"ARP_input: IP address conflict detected!\n" DEBUGF 1,"ARP_input: IP address conflict detected!\n"
.exit: .exit:
@ -566,6 +568,8 @@ ARP_api:
dd .read ; 3 dd .read ; 3
dd .write ; 4 dd .write ; 4
dd .remove ; 5 dd .remove ; 5
dd .send_announce ; 6
dd .conflicts ; 7
.number = ($ - .table) / 4 - 1 .number = ($ - .table) / 4 - 1
.error: .error:
@ -580,6 +584,10 @@ ARP_api:
mov eax, [ARP_PACKETS_RX + eax] mov eax, [ARP_PACKETS_RX + eax]
ret ret
.conflicts:
mov eax, [ARP_CONFLICTS + eax]
ret
.entries: .entries:
mov eax, [NumARP] mov eax, [NumARP]
ret ret
@ -600,7 +608,7 @@ ARP_api:
.write: .write:
; esi = pointer to buffer ; esi = pointer to buffer
call ARP_add_entry ;out: eax = entry number, -1 on error call ARP_add_entry ; out: eax = entry number, -1 on error
ret ret
.remove: .remove:
@ -612,3 +620,9 @@ ARP_api:
call ARP_del_entry call ARP_del_entry
ret ret
.send_announce:
mov edi, eax
mov eax, [IP_LIST + eax]
call ARP_output_request ; now send a gratuitous ARP
ret