Subversion Repositories Kolibri OS

Rev

Rev 3384 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3384 Rev 3516
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2010-2013. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2010-2013. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  zeroconfig.asm - Zeroconfig service for KolibriOS              ;;
6
;;  zeroconfig.asm - Zeroconfig service for KolibriOS              ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
9
;;    Some code contributed by Derpenguin                          ;;
9
;;    Some code contributed by Derpenguin                          ;;
10
;;                                                                 ;;
10
;;                                                                 ;;
11
;;  DHCP code is based on that by Mike Hibbet                      ;;
11
;;  DHCP code is based on that by Mike Hibbet                      ;;
12
;       (DHCP client for menuetos)                                 ;;
12
;       (DHCP client for menuetos)                                 ;;
13
;;                                                                 ;;
13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
18
 
19
format binary as ""
19
format binary as ""
20
 
20
 
21
use32
21
use32
22
               org    0x0
22
        org     0x0
23
 
23
 
24
               db     'MENUET01'            ; 8 byte id
24
        db      'MENUET01'              ; 8 byte id
25
               dd     0x01                  ; header version
25
        dd      0x01                    ; header version
26
               dd     START                 ; start of code
26
        dd      START                   ; start of code
27
               dd     IM_END                ; size of image
27
        dd      IM_END                  ; size of image
28
               dd     (I_END+0x100)         ; memory for app
28
        dd      (I_END+0x100)           ; memory for app
29
               dd     (I_END+0x100)         ; esp
29
        dd      (I_END+0x100)           ; esp
30
               dd     0x0 , path            ; I_Param , I_Icon
30
        dd      0, 0                    ; I_Param, I_Path
31
 
31
 
32
; CONFIGURATION
32
; CONFIGURATION
33
 
33
 
34
TIMEOUT             equ 60                  ; in seconds
34
TIMEOUT                 = 60            ; in seconds
35
BUFFER              equ 1024                ; in bytes
35
BUFFER                  = 1024          ; in bytes
36
__DEBUG__           equ 1                   ; enable/disable
36
__DEBUG__               = 1             ; enable/disable
37
__DEBUG_LEVEL__     equ 1                   ; 1 = all, 2 = errors
37
__DEBUG_LEVEL__         = 1             ; 1 = all, 2 = errors
38
 
38
 
39
; CONFIGURATION FOR LINK-LOCAL
39
; CONFIGURATION FOR LINK-LOCAL
40
 
40
 
41
PROBE_WAIT          equ 1                   ; second  (initial random delay)
41
PROBE_WAIT              = 1             ; second  (initial random delay)
42
PROBE_MIN           equ 1                   ; second  (minimum delay till repeated probe)
42
PROBE_MIN               = 1             ; second  (minimum delay till repeated probe)
43
PROBE_MAX           equ 2                   ; seconds (maximum delay till repeated probe)
43
PROBE_MAX               = 2             ; seconds (maximum delay till repeated probe)
44
PROBE_NUM           equ 3                   ;         (number of probe packets)
44
PROBE_NUM               = 3             ;         (number of probe packets)
45
 
45
 
46
ANNOUNCE_NUM        equ 2                   ;         (number of announcement packets)
46
ANNOUNCE_NUM            = 2             ;         (number of announcement packets)
47
ANNOUNCE_INTERVAL   equ 2                   ; seconds (time between announcement packets)
47
ANNOUNCE_INTERVAL       = 2             ; seconds (time between announcement packets)
48
ANNOUNCE_WAIT       equ 2                   ; seconds (delay before announcing)
48
ANNOUNCE_WAIT           = 2             ; seconds (delay before announcing)
49
 
49
 
50
MAX_CONFLICTS       equ 10                  ;         (max conflicts before rate limiting)
50
MAX_CONFLICTS           = 10            ;         (max conflicts before rate limiting)
51
 
51
 
52
RATE_LIMIT_INTERVAL equ 60                  ; seconds (delay between successive attempts)
52
RATE_LIMIT_INTERVAL     = 60            ; seconds (delay between successive attempts)
53
 
53
 
54
DEFEND_INTERVAL     equ 10                  ; seconds (min. wait between defensive ARPs)
54
DEFEND_INTERVAL         = 10            ; seconds (min. wait between defensive ARPs)
55
 
55
 
56
 
56
 
57
include '../proc32.inc'
57
include '../proc32.inc'
58
include '../macros.inc'
58
include '../macros.inc'
59
include '../debug-fdo.inc'
59
include '../debug-fdo.inc'
60
include '../network.inc'
60
include '../network.inc'
61
include 'dhcp.inc'
61
include 'dhcp.inc'
62
include '../dll.inc'
62
include '../dll.inc'
63
 
63
 
64
 
64
 
65
Ip2dword:
65
Ip2dword:
66
    push    edx
66
    push    edx
67
 
67
 
68
    ; This code validates if the query is an IP containing 4 numbers and 3 dots
68
    ; This code validates if the query is an IP containing 4 numbers and 3 dots
69
 
69
 
70
    xor     al, al            ; make al (dot count) zero
70
    xor     al, al            ; make al (dot count) zero
71
 
71
 
72
   @@:
72
   @@:
73
    cmp     byte[edx],'0'     ; check if this byte is a number, if not jump to no_IP
73
    cmp     byte[edx],'0'     ; check if this byte is a number, if not jump to no_IP
74
    jl      no_IP             ;
74
    jl      no_IP             ;
75
    cmp     byte[edx],'9'     ;
75
    cmp     byte[edx],'9'     ;
76
    jg      no_IP             ;
76
    jg      no_IP             ;
77
 
77
 
78
    inc     edx               ; the byte was a number, so lets check the next byte
78
    inc     edx               ; the byte was a number, so lets check the next byte
79
 
79
 
80
    cmp     byte[edx],0       ; is this byte zero? (have we reached end of query?)
80
    cmp     byte[edx],0       ; is this byte zero? (have we reached end of query?)
81
    jz      @f                ; jump to next @@ then
81
    jz      @f                ; jump to next @@ then
82
    cmp     byte[edx],':'
82
    cmp     byte[edx],':'
83
    jz      @f
83
    jz      @f
84
 
84
 
85
    cmp     byte[edx],'.'     ; is this byte a dot?
85
    cmp     byte[edx],'.'     ; is this byte a dot?
86
    jne     @r                ; if not, jump to previous @@
86
    jne     @r                ; if not, jump to previous @@
87
 
87
 
88
    inc     al                ; the byte was a dot so increment al(dot count)
88
    inc     al                ; the byte was a dot so increment al(dot count)
89
    inc     edx               ; next byte
89
    inc     edx               ; next byte
90
    jmp     @r                ; lets check for numbers again (jump to previous @@)
90
    jmp     @r                ; lets check for numbers again (jump to previous @@)
91
 
91
 
92
   @@:                        ; we reach this when end of query reached
92
   @@:                        ; we reach this when end of query reached
93
    cmp     al,3              ; check if there where 3 dots
93
    cmp     al,3              ; check if there where 3 dots
94
    jnz     no_IP             ; if not, jump to no_IP
94
    jnz     no_IP             ; if not, jump to no_IP
95
 
95
 
96
    ; The following code will convert this IP into a dword and output it in eax
96
    ; The following code will convert this IP into a dword and output it in eax
97
    ; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1
97
    ; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1
98
 
98
 
99
    pop     esi               ; edx (query address) was pushed onto stack and is now popped in esi
99
    pop     esi               ; edx (query address) was pushed onto stack and is now popped in esi
100
 
100
 
101
    xor     edx, edx          ; result
101
    xor     edx, edx          ; result
102
    xor     eax, eax          ; current character
102
    xor     eax, eax          ; current character
103
    xor     ebx, ebx          ; current byte
103
    xor     ebx, ebx          ; current byte
104
 
104
 
105
  .outer_loop:
105
  .outer_loop:
106
    shl     edx, 8
106
    shl     edx, 8
107
    add     edx, ebx
107
    add     edx, ebx
108
    xor     ebx, ebx
108
    xor     ebx, ebx
109
  .inner_loop:
109
  .inner_loop:
110
    lodsb
110
    lodsb
111
    test    eax, eax
111
    test    eax, eax
112
    jz      .finish
112
    jz      .finish
113
    cmp     al, '.'
113
    cmp     al, '.'
114
    jz      .outer_loop
114
    jz      .outer_loop
115
    sub     eax, '0'
115
    sub     eax, '0'
116
    imul    ebx, 10
116
    imul    ebx, 10
117
    add     ebx, eax
117
    add     ebx, eax
118
    jmp     .inner_loop
118
    jmp     .inner_loop
119
  .finish:
119
  .finish:
120
    shl     edx, 8
120
    shl     edx, 8
121
    add     edx, ebx
121
    add     edx, ebx
122
 
122
 
123
    bswap   edx               ; we want little endian order
123
    bswap   edx               ; we want little endian order
124
 
124
 
125
    ret
125
    ret
126
 
126
 
127
no_IP:
127
no_IP:
128
    pop     edx
128
    pop     edx
129
    xor     edx, edx
129
    xor     edx, edx
130
 
130
 
131
    ret
131
    ret
132
 
132
 
133
 
133
 
134
 
134
 
135
 
135
 
136
 
136
 
137
 
137
 
138
START:
138
START:
139
        mcall   40, EVM_STACK2
139
        mcall   40, EVM_STACK2
140
 
140
 
141
        DEBUGF  1,">Zero-config service loaded\n"
141
        DEBUGF  1,">Zero-config service loaded\n"
142
 
142
 
143
  .wait:
143
  .wait:
144
        mcall   76, API_ETH + 4 ; get MAC of ethernet interface 0
144
        mcall   76, API_ETH + 4 ; get MAC of ethernet interface 0
145
        cmp     eax, -1
145
        cmp     eax, -1
146
        jne     .start
146
        jne     .start
147
 
147
 
148
        mcall   10
148
        mcall   10
149
        jmp     .wait
149
        jmp     .wait
150
 
150
 
151
  .start:
151
  .start:
152
        mov     word[MAC], bx
152
        mov     word[MAC], bx
153
        mov     dword[MAC+2], eax
153
        mov     dword[MAC+2], eax
154
        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
154
        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
155
 
155
 
156
        mcall   40, EVM_STACK
156
        mcall   40, EVM_STACK
157
 
-
 
158
        mov     edi, path       ; Calculate the length of zero-terminated string
-
 
159
        xor     al, al
-
 
160
        mov     ecx, 1024
-
 
161
        repne   scasb
-
 
162
        dec     edi
-
 
163
 
-
 
164
        mov     esi, filename   ; append with .ini
-
 
165
        movsd
-
 
166
        movsb
-
 
167
 
-
 
168
        DEBUGF  1,"->Loading ini %s\n", path
-
 
169
 
157
 
170
        mcall   68, 11
158
        mcall   68, 11
171
 
159
 
172
        stdcall dll.Load,@IMPORT
160
        stdcall dll.Load,@IMPORT
173
        or      eax, eax
161
        or      eax, eax
174
        jnz     try_dhcp
162
        jnz     try_dhcp
175
 
163
 
176
        invoke  ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
164
        invoke  ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
177
 
165
 
178
        cmp     dword[inibuf], 'stat'
166
        cmp     dword[inibuf], 'stat'
179
        jne     try_dhcp
167
        jne     try_dhcp
180
 
168
 
181
        invoke  ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
169
        invoke  ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
182
        mov     edx, inibuf
170
        mov     edx, inibuf
183
        call    Ip2dword
171
        call    Ip2dword
184
        mcall   76, API_IPv4 + 3, edx
172
        mcall   76, API_IPv4 + 3, edx
185
 
173
 
186
        invoke  ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
174
        invoke  ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
187
        mov     edx, inibuf
175
        mov     edx, inibuf
188
        call    Ip2dword
176
        call    Ip2dword
189
        mcall   76, API_IPv4 + 9, edx
177
        mcall   76, API_IPv4 + 9, edx
190
 
178
 
191
        invoke  ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
179
        invoke  ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
192
        mov     edx, inibuf
180
        mov     edx, inibuf
193
        call    Ip2dword
181
        call    Ip2dword
194
        mcall   76, API_IPv4 + 5, edx
182
        mcall   76, API_IPv4 + 5, edx
195
 
183
 
196
        invoke  ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
184
        invoke  ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
197
        mov     edx, inibuf
185
        mov     edx, inibuf
198
        call    Ip2dword
186
        call    Ip2dword
199
        mcall   76, API_IPv4 + 7, edx
187
        mcall   76, API_IPv4 + 7, edx
200
 
188
 
201
 
189
 
202
        mcall   -1
190
        mcall   -1
203
 
191
 
204
 
192
 
205
try_dhcp:
193
try_dhcp:
206
 
194
 
207
        DEBUGF  1,"->Trying DHCP\n"
195
        DEBUGF  1,"->Trying DHCP\n"
208
 
196
 
209
        mcall   75, 0, AF_INET4, SOCK_DGRAM, 0          ; open socket (parameters: domain, type, reserved)
197
        mcall   75, 0, AF_INET4, SOCK_DGRAM, 0          ; open socket (parameters: domain, type, reserved)
210
        cmp     eax, -1
198
        cmp     eax, -1
211
        je      error
199
        je      error
212
        mov     [socketNum], eax
200
        mov     [socketNum], eax
213
 
201
 
214
        DEBUGF  1,"->Socket %x opened\n", eax
202
        DEBUGF  1,"->Socket %x opened\n", eax
215
 
203
 
216
        mcall   75, 2, [socketNum], sockaddr1, 18       ; bind socket to local port 68
204
        mcall   75, 2, [socketNum], sockaddr1, 18       ; bind socket to local port 68
217
        cmp     eax, -1
205
        cmp     eax, -1
218
        je      error
206
        je      error
219
 
207
 
220
        DEBUGF  1,"->Socket Bound to local port 68\n"
208
        DEBUGF  1,"->Socket Bound to local port 68\n"
221
 
209
 
222
        mcall   75, 4, [socketNum], sockaddr2, 18       ; connect to 255.255.255.255 on port 67
210
        mcall   75, 4, [socketNum], sockaddr2, 18       ; connect to 255.255.255.255 on port 67
223
        cmp     eax, -1
211
        cmp     eax, -1
224
        je      error
212
        je      error
225
 
213
 
226
        DEBUGF  1,"->Connected to 255.255.255.255 on port 67\n"
214
        DEBUGF  1,"->Connected to 255.255.255.255 on port 67\n"
227
 
215
 
228
        mov     [dhcpMsgType], 0x01                     ; DHCP discover
216
        mov     [dhcpMsgType], 0x01                     ; DHCP discover
229
        mov     [dhcpLease], esi                        ; esi is still -1 (-1 = forever)
217
        mov     [dhcpLease], esi                        ; esi is still -1 (-1 = forever)
230
 
218
 
231
        mcall   26, 9                                   ; Get system time
219
        mcall   26, 9                                   ; Get system time
232
        imul    eax, 100
220
        imul    eax, 100
233
        mov     [currTime], eax
221
        mov     [currTime], eax
234
 
222
 
235
build_request:                                          ; Creates a DHCP request packet.
223
build_request:                                          ; Creates a DHCP request packet.
236
 
224
 
237
        DEBUGF  1,"->Building request\n"
225
        DEBUGF  1,"->Building request\n"
238
 
226
 
239
        stdcall mem.Alloc, BUFFER
227
        stdcall mem.Alloc, BUFFER
240
        mov     [dhcpMsg], eax
228
        mov     [dhcpMsg], eax
241
        test    eax, eax
229
        test    eax, eax
242
        jz      dhcp_error
230
        jz      dhcp_error
243
 
231
 
244
            ;;; todo: skip this bullcrap
232
            ;;; todo: skip this bullcrap
245
 
233
 
246
        mov     edi, eax
234
        mov     edi, eax
247
        mov     ecx, BUFFER
235
        mov     ecx, BUFFER
248
        xor     eax, eax
236
        xor     eax, eax
249
        rep     stosb
237
        rep     stosb
250
 
238
 
251
            ;; todo: put this in a buffer instead of writing bytes and words!
239
            ;; todo: put this in a buffer instead of writing bytes and words!
252
 
240
 
253
        mov     edx, [dhcpMsg]
241
        mov     edx, [dhcpMsg]
254
 
242
 
255
        ; Boot protocol legacy
243
        ; Boot protocol legacy
256
        mov     [edx], byte 0x01                ; Boot request
244
        mov     [edx], byte 0x01                ; Boot request
257
        mov     [edx+1], byte 0x01              ; Ethernet
245
        mov     [edx+1], byte 0x01              ; Ethernet
258
        mov     [edx+2], byte 0x06              ; Ethernet h/w len
246
        mov     [edx+2], byte 0x06              ; Ethernet h/w len
259
        mov     [edx+4], dword 0x11223344       ; xid                 ;;;;;;;
247
        mov     [edx+4], dword 0x11223344       ; xid                 ;;;;;;;
260
        mov     eax, [currTime]
248
        mov     eax, [currTime]
261
        mov     [edx+8], eax                    ; secs, our uptime
249
        mov     [edx+8], eax                    ; secs, our uptime
262
        mov     [edx+10], byte 0x80             ; broadcast flag set
250
        mov     [edx+10], byte 0x80             ; broadcast flag set
263
        mov     eax, dword [MAC]                ; first 4 bytes of MAC
251
        mov     eax, dword [MAC]                ; first 4 bytes of MAC
264
        mov     [edx+28],dword eax
252
        mov     [edx+28],dword eax
265
        mov     ax, word [MAC+4]                ; last 2 bytes of MAC
253
        mov     ax, word [MAC+4]                ; last 2 bytes of MAC
266
        mov     [edx+32],word ax
254
        mov     [edx+32],word ax
267
 
255
 
268
        ; DHCP extension
256
        ; DHCP extension
269
        mov     [edx+236], dword 0x63538263     ; magic cookie
257
        mov     [edx+236], dword 0x63538263     ; magic cookie
270
        mov     [edx+240], word 0x0135          ; option DHCP msg type
258
        mov     [edx+240], word 0x0135          ; option DHCP msg type
271
        mov     al, [dhcpMsgType]
259
        mov     al, [dhcpMsgType]
272
        mov     [edx+240+2], al
260
        mov     [edx+240+2], al
273
        mov     [edx+240+3], word 0x0433        ; option Lease time = infinity
261
        mov     [edx+240+3], word 0x0433        ; option Lease time = infinity
274
        mov     eax, [dhcpLease]
262
        mov     eax, [dhcpLease]
275
        mov     [edx+240+5], eax
263
        mov     [edx+240+5], eax
276
        mov     [edx+240+9], word 0x0432        ; option requested IP address
264
        mov     [edx+240+9], word 0x0432        ; option requested IP address
277
        mov     eax, [dhcp.ip]
265
        mov     eax, [dhcp.ip]
278
        mov     [edx+240+11], eax
266
        mov     [edx+240+11], eax
279
        mov     [edx+240+15], word 0x0437       ; option request list
267
        mov     [edx+240+15], word 0x0437       ; option request list
280
        mov     [edx+240+17], dword 0x0f060301
268
        mov     [edx+240+17], dword 0x0f060301
281
 
269
 
282
        cmp     [dhcpMsgType], byte 0x01        ; Check which msg we are sending
270
        cmp     [dhcpMsgType], byte 0x01        ; Check which msg we are sending
283
        jne     request_options
271
        jne     request_options
284
 
272
 
285
        mov     [edx+240+21], byte 0xff         ; "Discover" options
273
        mov     [edx+240+21], byte 0xff         ; "Discover" options
286
 
274
 
287
        mov     [dhcpMsgLen], dword 262         ; end of options marker
275
        mov     [dhcpMsgLen], dword 262         ; end of options marker
288
        jmp     send_dhcpmsg
276
        jmp     send_dhcpmsg
289
 
277
 
290
request_options:
278
request_options:
291
        mov     [edx+240+21], word 0x0436       ; server IP
279
        mov     [edx+240+21], word 0x0436       ; server IP
292
        mov     eax, [dhcpServerIP]
280
        mov     eax, [dhcpServerIP]
293
        mov     [edx+240+23], eax
281
        mov     [edx+240+23], eax
294
 
282
 
295
        mov     [edx+240+27], byte 0xff         ; end of options marker
283
        mov     [edx+240+27], byte 0xff         ; end of options marker
296
 
284
 
297
        mov     [dhcpMsgLen], dword 268
285
        mov     [dhcpMsgLen], dword 268
298
 
286
 
299
send_dhcpmsg:
287
send_dhcpmsg:
300
        mcall   75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen]     ; write to socket ( send broadcast request )
288
        mcall   75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen]     ; write to socket ( send broadcast request )
301
 
289
 
302
        mov     eax, [dhcpMsg]                          ; Setup the DHCP buffer to receive response
290
        mov     eax, [dhcpMsg]                          ; Setup the DHCP buffer to receive response
303
        mov     [dhcpMsgLen], eax                       ; Used as a pointer to the data
291
        mov     [dhcpMsgLen], eax                       ; Used as a pointer to the data
304
 
292
 
305
        mcall   23, TIMEOUT*10                          ; wait for data
293
        mcall   23, TIMEOUT*10                          ; wait for data
306
 
294
 
307
read_data:                                              ; we have data - this will be the response
295
read_data:                                              ; we have data - this will be the response
308
        mcall   75, 7, [socketNum], [dhcpMsg], BUFFER   ; read data from socket
296
        mcall   75, 7, [socketNum], [dhcpMsg], BUFFER   ; read data from socket
309
 
297
 
310
        DEBUGF  1,"->%d bytes received\n", eax
298
        DEBUGF  1,"->%d bytes received\n", eax
311
 
299
 
312
        cmp     eax, -1
300
        cmp     eax, -1
313
        je      dhcp_error
301
        je      dhcp_error
314
 
302
 
315
        mov     [dhcpMsgLen], eax
303
        mov     [dhcpMsgLen], eax
316
 
304
 
317
; depending on which msg we sent, handle the response
305
; depending on which msg we sent, handle the response
318
; accordingly.
306
; accordingly.
319
; If the response is to a dhcp discover, then:
307
; If the response is to a dhcp discover, then:
320
;  1) If response is DHCP OFFER then
308
;  1) If response is DHCP OFFER then
321
;  1.1) record server IP, lease time & IP address.
309
;  1.1) record server IP, lease time & IP address.
322
;  1.2) send a request packet
310
;  1.2) send a request packet
323
; If the response is to a dhcp request, then:
311
; If the response is to a dhcp request, then:
324
;  1) If the response is DHCP ACK then
312
;  1) If the response is DHCP ACK then
325
;  1.1) extract the DNS & subnet fields. Set them in the stack
313
;  1.1) extract the DNS & subnet fields. Set them in the stack
326
 
314
 
327
        cmp     [dhcpMsgType], 0x01             ; did we send a discover?
315
        cmp     [dhcpMsgType], 0x01             ; did we send a discover?
328
        je      discover
316
        je      discover
329
 
317
 
330
        cmp     [dhcpMsgType], 0x03             ; did we send a request?
318
        cmp     [dhcpMsgType], 0x03             ; did we send a request?
331
        je      request
319
        je      request
332
 
320
 
333
        call    dhcp_end                        ; we should never reach here ;)
321
        call    dhcp_end                        ; we should never reach here ;)
334
        jmp     exit
322
        jmp     exit
335
 
323
 
336
discover:
324
discover:
337
        call    parse_response
325
        call    parse_response
338
 
326
 
339
        cmp     [dhcpMsgType], 0x02             ; Was the response an offer?
327
        cmp     [dhcpMsgType], 0x02             ; Was the response an offer?
340
        je      send_request
328
        je      send_request
341
 
329
 
342
        call    dhcp_end
330
        call    dhcp_end
343
        jmp     link_local
331
        jmp     link_local
344
 
332
 
345
send_request:
333
send_request:
346
        mov     [dhcpMsgType], 0x03             ; make it a request
334
        mov     [dhcpMsgType], 0x03             ; make it a request
347
        jmp     build_request
335
        jmp     build_request
348
 
336
 
349
request:
337
request:
350
        call    parse_response
338
        call    parse_response
351
 
339
 
352
        cmp     [dhcpMsgType], 0x05             ; Was the response an ACK? It should be
340
        cmp     [dhcpMsgType], 0x05             ; Was the response an ACK? It should be
353
        jne     read_data                       ; NO - read next packets
341
        jne     read_data                       ; NO - read next packets
354
 
342
 
355
        call    dhcp_end
343
        call    dhcp_end
356
 
344
 
357
        mcall   76, API_IPv4 + 3, [dhcp.ip]             ; ip
345
        mcall   76, API_IPv4 + 3, [dhcp.ip]             ; ip
358
        mcall   76, API_IPv4 + 5, [dhcp.dns]            ; dns
346
        mcall   76, API_IPv4 + 5, [dhcp.dns]            ; dns
359
        mcall   76, API_IPv4 + 7, [dhcp.subnet]         ; subnet
347
        mcall   76, API_IPv4 + 7, [dhcp.subnet]         ; subnet
360
        mcall   76, API_IPv4 + 9, [dhcp.gateway]        ; gateway
348
        mcall   76, API_IPv4 + 9, [dhcp.gateway]        ; gateway
361
 
349
 
362
        jmp     exit
350
        jmp     exit
363
 
351
 
364
dhcp_end:
352
dhcp_end:
365
        mcall   close, [socketNum]
353
        mcall   close, [socketNum]
366
        stdcall mem.Free, [dhcpMsg]
354
        stdcall mem.Free, [dhcpMsg]
367
 
355
 
368
        ret
356
        ret
369
 
357
 
370
;***************************************************************************
358
;***************************************************************************
371
;   Function
359
;   Function
372
;      parseResponse
360
;      parseResponse
373
;
361
;
374
;   Description
362
;   Description
375
;      extracts the fields ( client IP address and options ) from
363
;      extracts the fields ( client IP address and options ) from
376
;      a DHCP response
364
;      a DHCP response
377
;      The values go into
365
;      The values go into
378
;       dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP,
366
;       dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP,
379
;       dhcpDNSIP, dhcpSubnet
367
;       dhcpDNSIP, dhcpSubnet
380
;      The message is stored in dhcpMsg
368
;      The message is stored in dhcpMsg
381
;
369
;
382
;***************************************************************************
370
;***************************************************************************
383
parse_response:
371
parse_response:
384
 
372
 
385
        DEBUGF  1,"Data received, parsing response\n"
373
        DEBUGF  1,"Data received, parsing response\n"
386
        mov     edx, [dhcpMsg]
374
        mov     edx, [dhcpMsg]
387
 
375
 
388
        push    dword [edx+16]
376
        push    dword [edx+16]
389
        pop     [dhcp.ip]
377
        pop     [dhcp.ip]
390
        DEBUGF  1,"Client: %u.%u.%u.%u\n", [edx+16]:1, [edx+17]:1, [edx+18]:1, [edx+19]:1
378
        DEBUGF  1,"Client: %u.%u.%u.%u\n", [edx+16]:1, [edx+17]:1, [edx+18]:1, [edx+19]:1
391
 
379
 
392
; TODO: check if there really are options
380
; TODO: check if there really are options
393
 
381
 
394
        mov     al, 240                         ; Point to first option
382
        mov     al, 240                         ; Point to first option
395
        movzx   ecx, al
383
        movzx   ecx, al
396
 
384
 
397
  .next_option:
385
  .next_option:
398
        add     edx, ecx
386
        add     edx, ecx
399
 
387
 
400
        mov     al, [edx]                       ; get message identifier
388
        mov     al, [edx]                       ; get message identifier
401
 
389
 
402
        cmp     al, 0xff                        ; End of options?
390
        cmp     al, 0xff                        ; End of options?
403
        je      .done
391
        je      .done
404
 
392
 
405
        cmp     al, 0
393
        cmp     al, 0
406
        je      .pad
394
        je      .pad
407
 
395
 
408
; TODO: check if we still are inside the buffer
396
; TODO: check if we still are inside the buffer
409
 
397
 
410
        inc     edx
398
        inc     edx
411
        movzx   ecx, byte [edx]                 ; get data length
399
        movzx   ecx, byte [edx]                 ; get data length
412
        inc     edx                             ; point to data
400
        inc     edx                             ; point to data
413
 
401
 
414
        cmp     al, dhcp_msg_type               ; Msg type is a single byte option
402
        cmp     al, dhcp_msg_type               ; Msg type is a single byte option
415
        je      .msgtype
403
        je      .msgtype
416
 
404
 
417
        cmp     al, dhcp_dhcp_server_id
405
        cmp     al, dhcp_dhcp_server_id
418
        je      .server
406
        je      .server
419
 
407
 
420
        cmp     al, dhcp_address_time
408
        cmp     al, dhcp_address_time
421
        je      .lease
409
        je      .lease
422
 
410
 
423
        cmp     al, dhcp_subnet_mask
411
        cmp     al, dhcp_subnet_mask
424
        je      .subnet
412
        je      .subnet
425
 
413
 
426
        cmp     al, dhcp_router
414
        cmp     al, dhcp_router
427
        je      .router
415
        je      .router
428
 
416
 
429
        cmp     al, dhcp_domain_server
417
        cmp     al, dhcp_domain_server
430
        je      .dns
418
        je      .dns
431
 
419
 
432
        DEBUGF  1,"Unsupported DHCP option: %u\n", al
420
        DEBUGF  1,"Unsupported DHCP option: %u\n", al
433
 
421
 
434
        jmp     .next_option
422
        jmp     .next_option
435
 
423
 
436
  .pad:
424
  .pad:
437
        xor     ecx, ecx
425
        xor     ecx, ecx
438
        inc     ecx
426
        inc     ecx
439
        jmp     .next_option
427
        jmp     .next_option
440
 
428
 
441
  .msgtype:
429
  .msgtype:
442
        mov     al, [edx]
430
        mov     al, [edx]
443
        mov     [dhcpMsgType], al
431
        mov     [dhcpMsgType], al
444
 
432
 
445
        DEBUGF  1,"DHCP Msg type: %u\n", al
433
        DEBUGF  1,"DHCP Msg type: %u\n", al
446
        jmp     .next_option                    ; Get next option
434
        jmp     .next_option                    ; Get next option
447
 
435
 
448
  .server:
436
  .server:
449
        mov     eax, [edx]
437
        mov     eax, [edx]
450
        mov     [dhcpServerIP], eax
438
        mov     [dhcpServerIP], eax
451
        DEBUGF  1,"Server: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
439
        DEBUGF  1,"Server: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
452
        jmp     .next_option
440
        jmp     .next_option
453
 
441
 
454
  .lease:
442
  .lease:
455
        pusha
443
        pusha
456
        mov     eax,[edx]
444
        mov     eax,[edx]
457
        bswap   eax
445
        bswap   eax
458
        mov     [dhcpLease],eax
446
        mov     [dhcpLease],eax
459
        DEBUGF  1,"lease: %d\n",eax
447
        DEBUGF  1,"lease: %d\n",eax
460
        popa
448
        popa
461
        jmp     .next_option
449
        jmp     .next_option
462
 
450
 
463
  .subnet:
451
  .subnet:
464
        push    dword [edx]
452
        push    dword [edx]
465
        pop     [dhcp.subnet]
453
        pop     [dhcp.subnet]
466
        DEBUGF  1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
454
        DEBUGF  1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
467
        jmp     .next_option
455
        jmp     .next_option
468
 
456
 
469
  .router:
457
  .router:
470
        push    dword [edx]
458
        push    dword [edx]
471
        pop     [dhcp.gateway]
459
        pop     [dhcp.gateway]
472
        DEBUGF  1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
460
        DEBUGF  1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
473
        jmp     .next_option
461
        jmp     .next_option
474
 
462
 
475
  .dns:
463
  .dns:
476
        push    dword [edx]
464
        push    dword [edx]
477
        pop     [dhcp.dns]
465
        pop     [dhcp.dns]
478
        DEBUGF  1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
466
        DEBUGF  1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
479
        jmp     .next_option
467
        jmp     .next_option
480
 
468
 
481
  .done:
469
  .done:
482
        ret
470
        ret
483
 
471
 
484
 
472
 
485
 
473
 
486
dhcp_error:
474
dhcp_error:
487
        call    dhcp_end
475
        call    dhcp_end
488
 
476
 
489
link_local:
477
link_local:
490
        call    random
478
        call    random
491
        mov     cx, ax
479
        mov     cx, ax
492
        shl     ecx, 16
480
        shl     ecx, 16
493
        mov     cx, 0xfea9                              ; IP 169.254.0.0 link local net, see RFC3927
481
        mov     cx, 0xfea9                              ; IP 169.254.0.0 link local net, see RFC3927
494
        mcall   76, API_IPv4 + 3, ecx                   ; mask is 255.255.0.0
482
        mcall   76, API_IPv4 + 3, ecx                   ; mask is 255.255.0.0
495
        DEBUGF  1,"Link Local IP assinged: 169.254.%u.%u\n", [generator+0]:1, [generator+1]:1
483
        DEBUGF  1,"Link Local IP assinged: 169.254.%u.%u\n", [generator+0]:1, [generator+1]:1
496
        mcall   76, API_IPv4 + 7, 0xffff
484
        mcall   76, API_IPv4 + 7, 0xffff
497
        mcall   76, API_IPv4 + 9, 0x0
485
        mcall   76, API_IPv4 + 9, 0x0
498
        mcall   76, API_IPv4 + 5, 0x0
486
        mcall   76, API_IPv4 + 5, 0x0
499
 
487
 
500
        mcall   5, PROBE_WAIT*100
488
        mcall   5, PROBE_WAIT*100
501
 
489
 
502
        xor     esi, esi
490
        xor     esi, esi
503
   probe_loop:
491
   probe_loop:
504
        call    random                                  ; create a pseudo random number in eax (seeded by MAC)
492
        call    random                                  ; create a pseudo random number in eax (seeded by MAC)
505
 
493
 
506
        cmp     al, PROBE_MIN*100                       ; check if al is bigger then PROBE_MIN
494
        cmp     al, PROBE_MIN*100                       ; check if al is bigger then PROBE_MIN
507
        jae     @f                                      ; all ok
495
        jae     @f                                      ; all ok
508
        add     al, (PROBE_MAX-PROBE_MIN)*100           ; al is too small
496
        add     al, (PROBE_MAX-PROBE_MIN)*100           ; al is too small
509
   @@:
497
   @@:
510
 
498
 
511
        cmp     al, PROBE_MAX*100
499
        cmp     al, PROBE_MAX*100
512
        jbe     @f
500
        jbe     @f
513
        sub     al, (PROBE_MAX-PROBE_MIN)*100
501
        sub     al, (PROBE_MAX-PROBE_MIN)*100
514
   @@:
502
   @@:
515
 
503
 
516
        movzx   ebx,al
504
        movzx   ebx,al
517
        DEBUGF  1,"Waiting %u0ms\n",ebx
505
        DEBUGF  1,"Waiting %u0ms\n",ebx
518
        mcall   5
506
        mcall   5
519
 
507
 
520
        DEBUGF  1,"Sending Probe\n"
508
        DEBUGF  1,"Sending Probe\n"
521
        mcall   76, API_ARP + 6
509
        mcall   76, API_ARP + 6
522
        inc     esi
510
        inc     esi
523
 
511
 
524
        cmp     esi, PROBE_NUM
512
        cmp     esi, PROBE_NUM
525
        jb      probe_loop
513
        jb      probe_loop
526
 
514
 
527
; now we wait further ANNOUNCE_WAIT seconds and send ANNOUNCE_NUM ARP announces. If any other host has assingned
515
; now we wait further ANNOUNCE_WAIT seconds and send ANNOUNCE_NUM ARP announces. If any other host has assingned
528
; IP within this time, we should create another adress, that have to be done later
516
; IP within this time, we should create another adress, that have to be done later
529
 
517
 
530
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_WAIT
518
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_WAIT
531
        mcall   5, ANNOUNCE_WAIT*100
519
        mcall   5, ANNOUNCE_WAIT*100
532
        xor   esi, esi
520
        xor   esi, esi
533
   announce_loop:
521
   announce_loop:
534
 
522
 
535
        DEBUGF  1,"Sending Announce\n"
523
        DEBUGF  1,"Sending Announce\n"
536
        mcall   76, API_ARP + 6
524
        mcall   76, API_ARP + 6
537
 
525
 
538
        inc     esi
526
        inc     esi
539
        cmp     esi,ANNOUNCE_NUM
527
        cmp     esi,ANNOUNCE_NUM
540
        je      @f
528
        je      @f
541
 
529
 
542
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_INTERVAL
530
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_INTERVAL
543
        mcall   5, ANNOUNCE_INTERVAL*100
531
        mcall   5, ANNOUNCE_INTERVAL*100
544
        jmp     announce_loop
532
        jmp     announce_loop
545
   @@:
533
   @@:
546
 
534
 
547
 
535
 
548
error:
536
error:
549
        DEBUGF  1,"Socket error\n"
537
        DEBUGF  1,"Socket error\n"
550
exit:   ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
538
exit:   ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
551
        mcall   -1
539
        mcall   -1
552
 
540
 
553
 
541
 
554
random:  ; Pseudo random actually
542
random:  ; Pseudo random actually
555
 
543
 
556
        mov     eax, [generator]
544
        mov     eax, [generator]
557
        add     eax, -43ab45b5h
545
        add     eax, -43ab45b5h
558
        ror     eax, 1
546
        ror     eax, 1
559
        bswap   eax
547
        bswap   eax
560
        xor     eax, dword[MAC]
548
        xor     eax, dword[MAC]
561
        ror     eax, 1
549
        ror     eax, 1
562
        xor     eax, dword[MAC+2]
550
        xor     eax, dword[MAC+2]
563
        mov     [generator], eax
551
        mov     [generator], eax
564
 
552
 
565
        ret
553
        ret
566
 
554
 
567
; DATA AREA
555
; DATA AREA
568
 
556
 
569
align 16
557
align 16
570
@IMPORT:
558
@IMPORT:
571
 
559
 
572
library \
560
library \
573
        libini,'libini.obj'
561
        libini,'libini.obj'
574
 
562
 
575
import  libini, \
563
import  libini, \
576
        ini.get_str,'ini_get_str'
564
        ini.get_str,'ini_get_str'
577
 
565
 
578
include_debug_strings
566
include_debug_strings
579
 
-
 
580
filename        db '.ini', 0
567
 
581
str_ip          db 'ip', 0
568
str_ip          db 'ip', 0
582
str_subnet      db 'subnet', 0
569
str_subnet      db 'subnet', 0
583
str_gateway     db 'gateway', 0
570
str_gateway     db 'gateway', 0
584
str_dns         db 'dns', 0
571
str_dns         db 'dns', 0
585
str_ipconfig    db 'ipconfig', 0
572
str_ipconfig    db 'ipconfig', 0
586
str_type        db 'type', 0
573
str_type        db 'type', 0
587
 
574
 
588
 
575
 
589
sockaddr1:
576
sockaddr1:
590
 
577
 
591
        dw AF_INET4
578
        dw AF_INET4
592
        dw 68 shl 8     ; local port
579
        dw 68 shl 8     ; local port
593
        dd 0            ; local IP
580
        dd 0            ; local IP
594
 
581
 
595
        rb 10
582
        rb 10
596
 
583
 
597
 
584
 
598
sockaddr2:
585
sockaddr2:
599
 
586
 
600
        dw AF_INET4
587
        dw AF_INET4
601
        dw 67 shl 8     ; destination port
588
        dw 67 shl 8     ; destination port
602
        dd -1           ; destination IP
589
        dd -1           ; destination IP
603
 
590
 
604
        rb 10
591
        rb 10
-
 
592
 
605
 
593
path            db  '/sys/network.ini'
606
 
594
 
607
IM_END:
595
IM_END:
608
 
596
 
609
inibuf          rb 16
597
inibuf          rb 16
610
 
598
 
611
dhcpMsgType     db  ?
599
dhcpMsgType     db  ?
612
dhcpLease       dd  ?
600
dhcpLease       dd  ?
613
dhcpServerIP    dd  ?
601
dhcpServerIP    dd  ?
614
 
602
 
615
dhcp:
603
dhcp:
616
.ip             dd  ?
604
.ip             dd  ?
617
.subnet         dd  ?
605
.subnet         dd  ?
618
.dns            dd  ?
606
.dns            dd  ?
619
.gateway        dd  ?
607
.gateway        dd  ?
620
 
608
 
621
 
609
 
622
dhcpMsgLen      dd  ?
610
dhcpMsgLen      dd  ?
623
socketNum       dd  ?
611
socketNum       dd  ?
624
 
612
 
625
MAC             dp  ?
613
MAC             dp  ?
626
 
614
 
627
currTime        dd  ?
615
currTime        dd  ?
628
generator       dd  ?
616
generator       dd  ?
629
 
617
 
630
dhcpMsg         dd  ?
618
dhcpMsg         dd  ?
631
 
-
 
632
I_END_2:
-
 
633
 
-
 
634
path            rb  1024+5
-
 
635
 
-
 
636
                rb  65536
-
 
637
 
619
 
638
I_END:
620
I_END: