Subversion Repositories Kolibri OS

Rev

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

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