Subversion Repositories Kolibri OS

Rev

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

Rev 4804 Rev 4805
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2010-2014. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2010-2014. 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  2,"Zero-config service loaded\n"
142
        DEBUGF  2,"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
        mov     ecx, edx
175
        mov     ecx, edx
176
        mov     ebx, API_IPv4 + 3       ; set IP
176
        mov     ebx, API_IPv4 + 3       ; set IP
177
        mov     bh, [device]
177
        mov     bh, [device]
178
        mcall   76
178
        mcall   76
179
 
179
 
180
        invoke  ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
180
        invoke  ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
181
        mov     edx, inibuf
181
        mov     edx, inibuf
182
        call    Ip2dword
182
        call    Ip2dword
183
        mov     ecx, edx
183
        mov     ecx, edx
184
        mov     ebx, API_IPv4 + 9       ; set gateway
184
        mov     ebx, API_IPv4 + 9       ; set gateway
185
        mov     bh, [device]
185
        mov     bh, [device]
186
        mcall   76
186
        mcall   76
187
 
187
 
188
        invoke  ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
188
        invoke  ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
189
        mov     edx, inibuf
189
        mov     edx, inibuf
190
        call    Ip2dword
190
        call    Ip2dword
191
        mov     ecx, edx
191
        mov     ecx, edx
192
        mov     ebx, API_IPv4 + 5       ; set DNS
192
        mov     ebx, API_IPv4 + 5       ; set DNS
193
        mov     bh, [device]
193
        mov     bh, [device]
194
        mcall   76
194
        mcall   76
195
 
195
 
196
        invoke  ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
196
        invoke  ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
197
        mov     edx, inibuf
197
        mov     edx, inibuf
198
        call    Ip2dword
198
        call    Ip2dword
199
        mov     ecx, edx
199
        mov     ecx, edx
200
        mov     ebx, API_IPv4 + 7       ; set subnet
200
        mov     ebx, API_IPv4 + 7       ; set subnet
201
        mov     bh, [device]
201
        mov     bh, [device]
202
        mcall   76
202
        mcall   76
203
 
203
 
204
 
204
 
205
        mcall   -1
205
        mcall   -1
206
 
206
 
207
 
207
 
208
try_dhcp:
208
try_dhcp:
209
 
209
 
210
        DEBUGF  2,"Trying to contact DHCP server\n"
210
        DEBUGF  2,"Trying to contact DHCP server\n"
211
 
211
 
212
        mcall   75, 0, AF_INET4, SOCK_DGRAM, 0          ; open socket (parameters: domain, type, reserved)
212
        mcall   75, 0, AF_INET4, SOCK_DGRAM, 0          ; open socket (parameters: domain, type, reserved)
213
        cmp     eax, -1
213
        cmp     eax, -1
214
        je      error
214
        je      error
215
        mov     [socketNum], eax
215
        mov     [socketNum], eax
216
 
216
 
217
        DEBUGF  1,"Socket %x opened\n", eax
217
        DEBUGF  1,"Socket %x opened\n", eax
218
 
218
 
219
        mcall   75, 2, [socketNum], sockaddr1, 18       ; bind socket to local port 68
219
        mcall   75, 2, [socketNum], sockaddr1, 18       ; bind socket to local port 68
220
        cmp     eax, -1
220
        cmp     eax, -1
221
        je      error
221
        je      error
222
 
222
 
223
        DEBUGF  1,"Socket Bound to local port 68\n"
223
        DEBUGF  1,"Socket Bound to local port 68\n"
224
 
224
 
225
        mcall   75, 4, [socketNum], sockaddr2, 18       ; connect to 255.255.255.255 on port 67
225
        mcall   75, 4, [socketNum], sockaddr2, 18       ; connect to 255.255.255.255 on port 67
226
        cmp     eax, -1
226
        cmp     eax, -1
227
        je      error
227
        je      error
228
 
228
 
229
        DEBUGF  1,"Connected to 255.255.255.255 on port 67\n"
229
        DEBUGF  1,"Connected to 255.255.255.255 on port 67\n"
230
 
230
 
231
        mov     [dhcpMsgType], 0x01                     ; DHCP discover
231
        mov     [dhcpMsgType], 0x01                     ; DHCP discover
232
        mov     [dhcpLease], esi                        ; esi is still -1 (-1 = forever)
232
        mov     [dhcpLease], esi                        ; esi is still -1 (-1 = forever)
233
 
233
 
234
        mcall   26, 9                                   ; Get system time
234
        mcall   26, 9                                   ; Get system time
235
        imul    eax, 100
235
        imul    eax, 100
236
        mov     [currTime], eax
236
        mov     [currTime], eax
237
 
237
 
238
build_request:                                          ; Creates a DHCP request packet.
238
build_request:                                          ; Creates a DHCP request packet.
239
 
239
 
240
        mov     [tries], DHCP_TRIES
240
        mov     [tries], DHCP_TRIES
241
 
241
 
242
        DEBUGF  1,"Building request\n"
242
        DEBUGF  1,"Building request\n"
243
 
243
 
244
        stdcall mem.Alloc, BUFFER
244
        stdcall mem.Alloc, BUFFER
245
        mov     [dhcpMsg], eax
245
        mov     [dhcpMsg], eax
246
        test    eax, eax
246
        test    eax, eax
247
        jz      dhcp_error
247
        jz      dhcp_error
248
 
248
 
249
            ;;; todo: skip this bullcrap
249
            ;;; todo: skip this bullcrap
250
 
250
 
251
        mov     edi, eax
251
        mov     edi, eax
252
        mov     ecx, BUFFER
252
        mov     ecx, BUFFER
253
        xor     eax, eax
253
        xor     eax, eax
254
        rep     stosb
254
        rep     stosb
255
 
255
 
256
            ;; todo: put this in a buffer instead of writing bytes and words!
256
            ;; todo: put this in a buffer instead of writing bytes and words!
257
 
257
 
258
        mov     edx, [dhcpMsg]
258
        mov     edx, [dhcpMsg]
259
 
259
 
260
        ; Boot protocol legacy
260
        ; Boot protocol legacy
261
        mov     [edx], byte 0x01                ; Boot request
261
        mov     [edx], byte 0x01                ; Boot request
262
        mov     [edx+1], byte 0x01              ; Ethernet
262
        mov     [edx+1], byte 0x01              ; Ethernet
263
        mov     [edx+2], byte 0x06              ; Ethernet h/w len
263
        mov     [edx+2], byte 0x06              ; Ethernet h/w len
264
        mov     [edx+4], dword 0x11223344       ; xid                 ;;;;;;;
264
        mov     [edx+4], dword 0x11223344       ; xid                 ;;;;;;;
265
        mov     eax, [currTime]
265
        mov     eax, [currTime]
266
        mov     [edx+8], eax                    ; secs, our uptime
266
        mov     [edx+8], eax                    ; secs, our uptime
267
        mov     [edx+10], byte 0x80             ; broadcast flag set
267
        mov     [edx+10], byte 0x80             ; broadcast flag set
268
        mov     eax, dword [MAC]                ; first 4 bytes of MAC
268
        mov     eax, dword [MAC]                ; first 4 bytes of MAC
269
        mov     [edx+28],dword eax
269
        mov     [edx+28],dword eax
270
        mov     ax, word [MAC+4]                ; last 2 bytes of MAC
270
        mov     ax, word [MAC+4]                ; last 2 bytes of MAC
271
        mov     [edx+32],word ax
271
        mov     [edx+32],word ax
272
 
272
 
273
        ; DHCP extension
273
        ; DHCP extension
274
        mov     [edx+236], dword 0x63538263     ; magic cookie
274
        mov     [edx+236], dword 0x63538263     ; magic cookie
275
        mov     [edx+240], word 0x0135          ; option DHCP msg type
275
        mov     [edx+240], word 0x0135          ; option DHCP msg type
276
        mov     al, [dhcpMsgType]
276
        mov     al, [dhcpMsgType]
277
        mov     [edx+240+2], al
277
        mov     [edx+240+2], al
278
        mov     [edx+240+3], word 0x0433        ; option Lease time = infinity
278
        mov     [edx+240+3], word 0x0433        ; option Lease time = infinity
279
        mov     eax, [dhcpLease]
279
        mov     eax, [dhcpLease]
280
        mov     [edx+240+5], eax
280
        mov     [edx+240+5], eax
281
        mov     [edx+240+9], word 0x0432        ; option requested IP address
281
        mov     [edx+240+9], word 0x0432        ; option requested IP address
282
        mov     eax, [dhcp.ip]
282
        mov     eax, [dhcp.ip]
283
        mov     [edx+240+11], eax
283
        mov     [edx+240+11], eax
284
        mov     [edx+240+15], word 0x0437       ; option request list
284
        mov     [edx+240+15], word 0x0437       ; option request list
285
        mov     [edx+240+17], dword 0x0f060301
285
        mov     [edx+240+17], dword 0x0f060301
286
 
286
 
287
        cmp     [dhcpMsgType], 0x01             ; Check which msg we are sending
287
        cmp     [dhcpMsgType], 0x01             ; Check which msg we are sending
288
        jne     request_options
288
        jne     request_options
289
 
289
 
290
        mov     [edx+240+21], byte 0xff         ; end of options marker
290
        mov     [edx+240+21], byte 0xff         ; end of options marker
291
 
291
 
292
        mov     [dhcpMsgLen], 262               ; length
292
        mov     [dhcpMsgLen], 262               ; length
293
        jmp     send_dhcpmsg
293
        jmp     send_dhcpmsg
294
 
294
 
295
request_options:
295
request_options:
296
        mov     [edx+240+21], word 0x0436       ; server IP
296
        mov     [edx+240+21], word 0x0436       ; server IP
297
        mov     eax, [dhcpServerIP]
297
        mov     eax, [dhcpServerIP]
298
        mov     [edx+240+23], eax
298
        mov     [edx+240+23], eax
299
 
299
 
300
        mov     [edx+240+27], byte 0xff         ; end of options marker
300
        mov     [edx+240+27], byte 0xff         ; end of options marker
301
 
301
 
302
        mov     [dhcpMsgLen], 268               ; length
302
        mov     [dhcpMsgLen], 268               ; length
303
 
303
 
304
send_dhcpmsg:
304
send_dhcpmsg:
305
        DEBUGF  1,"Sending DHCP discover/request\n"
305
        DEBUGF  1,"Sending DHCP discover/request\n"
306
        mcall   75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen]     ; write to socket ( send broadcast request )
306
        mcall   75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen]     ; write to socket ( send broadcast request )
-
 
307
        mcall   26, 9
-
 
308
        add     eax, TIMEOUT*100
-
 
309
        mov     [timeout], eax
307
  .wait:
310
  .wait:
308
        mcall   23, TIMEOUT*100                                 ; wait for data
311
        mcall   23, TIMEOUT                                             ; wait for data
309
 
312
 
310
read_data:                                                      ; we have data - this will be the response
313
read_data:                                                              ; we have data - this will be the response
311
        mcall   75, 7, [socketNum], [dhcpMsg], BUFFER, MSG_DONTWAIT     ; read data from socket
314
        mcall   75, 7, [socketNum], [dhcpMsg], BUFFER, MSG_DONTWAIT     ; read data from socket
312
        cmp     eax, -1
315
        cmp     eax, -1
313
        jne     @f
316
        jne     @f
-
 
317
 
-
 
318
        mcall   26, 9
314
        cmp     ebx, 6  ; EWOULDBLOCK
319
        cmp     eax, [timeout]
315
        je      send_dhcpmsg.wait
320
        jb      send_dhcpmsg.wait
-
 
321
 
316
        DEBUGF  2,"No answer from DHCP server\n"
322
        DEBUGF  2,"No answer from DHCP server\n"
317
        dec     [tries]
323
        dec     [tries]
318
        jnz     send_dhcpmsg                    ; try again
324
        jnz     send_dhcpmsg                    ; try again
319
        jmp     dhcp_error                      ; fail
325
        jmp     dhcp_error                      ; fail
320
 
326
 
321
  @@:
327
  @@:
322
        DEBUGF  1,"%d bytes received\n", eax
328
        DEBUGF  1,"%d bytes received\n", eax
323
        mov     [dhcpMsgLen], eax
329
        mov     [dhcpMsgLen], eax
324
 
330
 
325
; depending on which msg we sent, handle the response
331
; depending on which msg we sent, handle the response
326
; accordingly.
332
; accordingly.
327
; If the response is to a dhcp discover, then:
333
; If the response is to a dhcp discover, then:
328
;  1) If response is DHCP OFFER then
334
;  1) If response is DHCP OFFER then
329
;  1.1) record server IP, lease time & IP address.
335
;  1.1) record server IP, lease time & IP address.
330
;  1.2) send a request packet
336
;  1.2) send a request packet
331
; If the response is to a dhcp request, then:
337
; If the response is to a dhcp request, then:
332
;  1) If the response is DHCP ACK then
338
;  1) If the response is DHCP ACK then
333
;  1.1) extract the DNS & subnet fields. Set them in the stack
339
;  1.1) extract the DNS & subnet fields. Set them in the stack
334
 
340
 
335
        cmp     [dhcpMsgType], 0x01             ; did we send a discover?
341
        cmp     [dhcpMsgType], 0x01             ; did we send a discover?
336
        je      discover
342
        je      discover
337
 
343
 
338
        cmp     [dhcpMsgType], 0x03             ; did we send a request?
344
        cmp     [dhcpMsgType], 0x03             ; did we send a request?
339
        je      request
345
        je      request
340
 
346
 
341
        call    dhcp_end                        ; we should never reach here ;)
347
        call    dhcp_end                        ; we should never reach here ;)
342
        jmp     exit
348
        jmp     exit
343
 
349
 
344
discover:
350
discover:
345
        call    parse_response
351
        call    parse_response
346
 
352
 
347
        cmp     [dhcpMsgType2], 0x02            ; Was the response an offer?
353
        cmp     [dhcpMsgType2], 0x02            ; Was the response an offer?
348
        je      send_request
354
        je      send_request
349
 
355
 
350
        call    dhcp_end
356
        call    dhcp_end
351
        jmp     link_local
357
        jmp     link_local
352
 
358
 
353
send_request:
359
send_request:
354
        DEBUGF  1, "Got offer, making request\n"
360
        DEBUGF  1, "Got offer, making request\n"
355
        mov     [dhcpMsgType], 0x03             ; make it a request
361
        mov     [dhcpMsgType], 0x03             ; make it a request
356
        jmp     build_request
362
        jmp     build_request
357
 
363
 
358
request:
364
request:
359
        call    parse_response
365
        call    parse_response
360
 
366
 
361
        cmp     [dhcpMsgType2], 0x05            ; Was the response an ACK? It should be
367
        cmp     [dhcpMsgType2], 0x05            ; Was the response an ACK? It should be
362
        jne     read_data                       ; NO - read next packets
368
        jne     read_data                       ; NO - read next packets
363
 
369
 
364
        DEBUGF  2, "Setting IP using DHCP\n"
370
        DEBUGF  2, "Setting IP using DHCP\n"
365
 
371
 
366
        mov     [notify_struct.msg], str_connected
372
        mov     [notify_struct.msg], str_connected
367
        mcall   70, notify_struct
373
        mcall   70, notify_struct
368
        call    dhcp_end
374
        call    dhcp_end
369
 
375
 
370
        mov     ebx, API_IPv4 + 3
376
        mov     ebx, API_IPv4 + 3
371
        mov     bh, [device]
377
        mov     bh, [device]
372
        mcall   76, , [dhcp.ip]                 ; ip
378
        mcall   76, , [dhcp.ip]                 ; ip
373
        mov     bl, 5
379
        mov     bl, 5
374
        mcall   76, , [dhcp.dns]                ; dns
380
        mcall   76, , [dhcp.dns]                ; dns
375
        mov     bl, 7
381
        mov     bl, 7
376
        mcall   76, , [dhcp.subnet]             ; subnet
382
        mcall   76, , [dhcp.subnet]             ; subnet
377
        mov     bl, 9
383
        mov     bl, 9
378
        mcall   76, , [dhcp.gateway]            ; gateway
384
        mcall   76, , [dhcp.gateway]            ; gateway
379
 
385
 
380
        jmp     exit
386
        jmp     exit
381
 
387
 
382
dhcp_end:
388
dhcp_end:
383
        mcall   close, [socketNum]
389
        mcall   close, [socketNum]
384
        stdcall mem.Free, [dhcpMsg]
390
        stdcall mem.Free, [dhcpMsg]
385
 
391
 
386
        ret
392
        ret
387
 
393
 
388
;***************************************************************************
394
;***************************************************************************
389
;   Function
395
;   Function
390
;      parseResponse
396
;      parseResponse
391
;
397
;
392
;   Description
398
;   Description
393
;      extracts the fields ( client IP address and options ) from
399
;      extracts the fields ( client IP address and options ) from
394
;      a DHCP response
400
;      a DHCP response
395
;      The values go into
401
;      The values go into
396
;       dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP,
402
;       dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP,
397
;       dhcpDNSIP, dhcpSubnet
403
;       dhcpDNSIP, dhcpSubnet
398
;      The message is stored in dhcpMsg
404
;      The message is stored in dhcpMsg
399
;
405
;
400
;***************************************************************************
406
;***************************************************************************
401
parse_response:
407
parse_response:
402
 
408
 
403
        DEBUGF  1,"Data received, parsing response\n"
409
        DEBUGF  1,"Data received, parsing response\n"
404
        mov     edx, [dhcpMsg]
410
        mov     edx, [dhcpMsg]
405
        mov     [dhcpMsgType2], 0
411
        mov     [dhcpMsgType2], 0
406
 
412
 
407
        push    dword [edx+16]
413
        push    dword [edx+16]
408
        pop     [dhcp.ip]
414
        pop     [dhcp.ip]
409
        DEBUGF  1,"Client: %u.%u.%u.%u\n", [edx+16]:1, [edx+17]:1, [edx+18]:1, [edx+19]:1
415
        DEBUGF  1,"Client: %u.%u.%u.%u\n", [edx+16]:1, [edx+17]:1, [edx+18]:1, [edx+19]:1
410
 
416
 
411
; TODO: check if there really are options
417
; TODO: check if there really are options
412
 
418
 
413
        mov     al, 240                         ; Point to first option
419
        mov     al, 240                         ; Point to first option
414
        movzx   ecx, al
420
        movzx   ecx, al
415
 
421
 
416
  .next_option:
422
  .next_option:
417
        add     edx, ecx
423
        add     edx, ecx
418
 
424
 
419
        mov     al, [edx]                       ; get message identifier
425
        mov     al, [edx]                       ; get message identifier
420
 
426
 
421
        cmp     al, 0xff                        ; End of options?
427
        cmp     al, 0xff                        ; End of options?
422
        je      .done
428
        je      .done
423
 
429
 
424
        cmp     al, 0
430
        cmp     al, 0
425
        je      .pad
431
        je      .pad
426
 
432
 
427
; TODO: check if we still are inside the buffer
433
; TODO: check if we still are inside the buffer
428
 
434
 
429
        inc     edx
435
        inc     edx
430
        movzx   ecx, byte [edx]                 ; get data length
436
        movzx   ecx, byte [edx]                 ; get data length
431
        inc     edx                             ; point to data
437
        inc     edx                             ; point to data
432
 
438
 
433
        cmp     al, dhcp_msg_type               ; Msg type is a single byte option
439
        cmp     al, dhcp_msg_type               ; Msg type is a single byte option
434
        je      .msgtype
440
        je      .msgtype
435
 
441
 
436
        cmp     al, dhcp_dhcp_server_id
442
        cmp     al, dhcp_dhcp_server_id
437
        je      .server
443
        je      .server
438
 
444
 
439
        cmp     al, dhcp_address_time
445
        cmp     al, dhcp_address_time
440
        je      .lease
446
        je      .lease
441
 
447
 
442
        cmp     al, dhcp_subnet_mask
448
        cmp     al, dhcp_subnet_mask
443
        je      .subnet
449
        je      .subnet
444
 
450
 
445
        cmp     al, dhcp_router
451
        cmp     al, dhcp_router
446
        je      .router
452
        je      .router
447
 
453
 
448
        cmp     al, dhcp_domain_server
454
        cmp     al, dhcp_domain_server
449
        je      .dns
455
        je      .dns
450
 
456
 
451
        DEBUGF  1,"Unsupported DHCP option: %u\n", al
457
        DEBUGF  1,"Unsupported DHCP option: %u\n", al
452
 
458
 
453
        jmp     .next_option
459
        jmp     .next_option
454
 
460
 
455
  .pad:
461
  .pad:
456
        xor     ecx, ecx
462
        xor     ecx, ecx
457
        inc     ecx
463
        inc     ecx
458
        jmp     .next_option
464
        jmp     .next_option
459
 
465
 
460
  .msgtype:
466
  .msgtype:
461
        mov     al, [edx]
467
        mov     al, [edx]
462
        mov     [dhcpMsgType2], al
468
        mov     [dhcpMsgType2], al
463
 
469
 
464
        DEBUGF  1,"DHCP Msg type: %u\n", al
470
        DEBUGF  1,"DHCP Msg type: %u\n", al
465
        jmp     .next_option                    ; Get next option
471
        jmp     .next_option                    ; Get next option
466
 
472
 
467
  .server:
473
  .server:
468
        mov     eax, [edx]
474
        mov     eax, [edx]
469
        mov     [dhcpServerIP], eax
475
        mov     [dhcpServerIP], eax
470
        DEBUGF  1,"Server: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
476
        DEBUGF  1,"Server: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
471
        jmp     .next_option
477
        jmp     .next_option
472
 
478
 
473
  .lease:
479
  .lease:
474
        pusha
480
        pusha
475
        mov     eax,[edx]
481
        mov     eax,[edx]
476
        bswap   eax
482
        bswap   eax
477
        mov     [dhcpLease],eax
483
        mov     [dhcpLease],eax
478
        DEBUGF  1,"lease: %d\n",eax
484
        DEBUGF  1,"lease: %d\n",eax
479
        popa
485
        popa
480
        jmp     .next_option
486
        jmp     .next_option
481
 
487
 
482
  .subnet:
488
  .subnet:
483
        push    dword [edx]
489
        push    dword [edx]
484
        pop     [dhcp.subnet]
490
        pop     [dhcp.subnet]
485
        DEBUGF  1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
491
        DEBUGF  1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
486
        jmp     .next_option
492
        jmp     .next_option
487
 
493
 
488
  .router:
494
  .router:
489
        push    dword [edx]
495
        push    dword [edx]
490
        pop     [dhcp.gateway]
496
        pop     [dhcp.gateway]
491
        DEBUGF  1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
497
        DEBUGF  1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
492
        jmp     .next_option
498
        jmp     .next_option
493
 
499
 
494
  .dns:
500
  .dns:
495
        push    dword [edx]
501
        push    dword [edx]
496
        pop     [dhcp.dns]
502
        pop     [dhcp.dns]
497
        DEBUGF  1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
503
        DEBUGF  1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
498
        jmp     .next_option
504
        jmp     .next_option
499
 
505
 
500
  .done:
506
  .done:
501
        ret
507
        ret
502
 
508
 
503
 
509
 
504
 
510
 
505
dhcp_error:
511
dhcp_error:
506
        call    dhcp_end
512
        call    dhcp_end
507
 
513
 
508
link_local:
514
link_local:
509
        call    random
515
        call    random
510
        mov     cx, ax
516
        mov     cx, ax
511
        shl     ecx, 16
517
        shl     ecx, 16
512
        mov     cx, 0xfea9                              ; IP 169.254.0.0 link local net, see RFC3927
518
        mov     cx, 0xfea9                              ; IP 169.254.0.0 link local net, see RFC3927
513
        mov     ebx, API_IPv4 + 3
519
        mov     ebx, API_IPv4 + 3
514
        mov     bh, [device]
520
        mov     bh, [device]
515
        mcall   76, , ecx                   ; mask is 255.255.0.0
521
        mcall   76, , ecx                   ; mask is 255.255.0.0
516
        DEBUGF  2,"Link Local IP assigned: 169.254.%u.%u\n", [generator+0]:1, [generator+1]:1
522
        DEBUGF  2,"Link Local IP assigned: 169.254.%u.%u\n", [generator+0]:1, [generator+1]:1
517
        mov     bl, 7
523
        mov     bl, 7
518
        mcall   76, , 0xffff
524
        mcall   76, , 0xffff
519
        mov     bl, 9
525
        mov     bl, 9
520
        mcall   76, , 0x0
526
        mcall   76, , 0x0
521
        mov     bl, 5
527
        mov     bl, 5
522
        mcall   76, , 0x0
528
        mcall   76, , 0x0
523
 
529
 
524
        mcall   5, PROBE_WAIT*100
530
        mcall   5, PROBE_WAIT*100
525
 
531
 
526
        xor     esi, esi
532
        xor     esi, esi
527
   probe_loop:
533
   probe_loop:
528
        call    random                                  ; create a pseudo random number in eax (seeded by MAC)
534
        call    random                                  ; create a pseudo random number in eax (seeded by MAC)
529
 
535
 
530
        cmp     al, PROBE_MIN*100                       ; check if al is bigger then PROBE_MIN
536
        cmp     al, PROBE_MIN*100                       ; check if al is bigger then PROBE_MIN
531
        jae     @f                                      ; all ok
537
        jae     @f                                      ; all ok
532
        add     al, (PROBE_MAX-PROBE_MIN)*100           ; al is too small
538
        add     al, (PROBE_MAX-PROBE_MIN)*100           ; al is too small
533
   @@:
539
   @@:
534
 
540
 
535
        cmp     al, PROBE_MAX*100
541
        cmp     al, PROBE_MAX*100
536
        jbe     @f
542
        jbe     @f
537
        sub     al, (PROBE_MAX-PROBE_MIN)*100
543
        sub     al, (PROBE_MAX-PROBE_MIN)*100
538
   @@:
544
   @@:
539
 
545
 
540
        movzx   ebx,al
546
        movzx   ebx,al
541
        DEBUGF  1,"Waiting %u0ms\n",ebx
547
        DEBUGF  1,"Waiting %u0ms\n",ebx
542
        mcall   5
548
        mcall   5
543
 
549
 
544
        DEBUGF  1,"Sending Probe\n"
550
        DEBUGF  1,"Sending Probe\n"
545
        mov     ebx, API_ARP + 6
551
        mov     ebx, API_ARP + 6
546
        mov     bh, [device]
552
        mov     bh, [device]
547
        mcall   76
553
        mcall   76
548
        inc     esi
554
        inc     esi
549
 
555
 
550
        cmp     esi, PROBE_NUM
556
        cmp     esi, PROBE_NUM
551
        jb      probe_loop
557
        jb      probe_loop
552
 
558
 
553
; now we wait further ANNOUNCE_WAIT seconds and send ANNOUNCE_NUM ARP announces. If any other host has assingned
559
; now we wait further ANNOUNCE_WAIT seconds and send ANNOUNCE_NUM ARP announces. If any other host has assingned
554
; IP within this time, we should create another adress, that have to be done later
560
; IP within this time, we should create another adress, that have to be done later
555
 
561
 
556
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_WAIT
562
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_WAIT
557
        mcall   5, ANNOUNCE_WAIT*100
563
        mcall   5, ANNOUNCE_WAIT*100
558
        xor   esi, esi
564
        xor   esi, esi
559
   announce_loop:
565
   announce_loop:
560
 
566
 
561
        DEBUGF  1,"Sending Announce\n"
567
        DEBUGF  1,"Sending Announce\n"
562
        mov     ebx, API_ARP + 6
568
        mov     ebx, API_ARP + 6
563
        mov     bh, [device]
569
        mov     bh, [device]
564
        mcall   76
570
        mcall   76
565
 
571
 
566
        inc     esi
572
        inc     esi
567
        cmp     esi,ANNOUNCE_NUM
573
        cmp     esi,ANNOUNCE_NUM
568
        je      @f
574
        je      @f
569
 
575
 
570
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_INTERVAL
576
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_INTERVAL
571
        mcall   5, ANNOUNCE_INTERVAL*100
577
        mcall   5, ANNOUNCE_INTERVAL*100
572
        jmp     announce_loop
578
        jmp     announce_loop
573
   @@:
579
   @@:
-
 
580
        jmp     exit
574
 
581
 
575
 
582
 
576
error:
583
error:
577
        DEBUGF  2,"Socket error\n"
584
        DEBUGF  2,"Socket error\n"
578
exit:   ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
585
exit:   ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;)
579
        DEBUGF  2,"Exiting\n"
586
        DEBUGF  2,"Exiting\n"
580
        mcall   -1
587
        mcall   -1
581
 
588
 
582
 
589
 
583
random:  ; Pseudo random actually
590
random:  ; Pseudo random actually
584
 
591
 
585
        mov     eax, [generator]
592
        mov     eax, [generator]
586
        add     eax, -43ab45b5h
593
        add     eax, -43ab45b5h
587
        ror     eax, 1
594
        ror     eax, 1
588
        bswap   eax
595
        bswap   eax
589
        xor     eax, dword[MAC]
596
        xor     eax, dword[MAC]
590
        ror     eax, 1
597
        ror     eax, 1
591
        xor     eax, dword[MAC+2]
598
        xor     eax, dword[MAC+2]
592
        mov     [generator], eax
599
        mov     [generator], eax
593
 
600
 
594
        ret
601
        ret
595
 
602
 
596
; DATA AREA
603
; DATA AREA
597
 
604
 
598
align 16
605
align 16
599
@IMPORT:
606
@IMPORT:
600
 
607
 
601
library \
608
library \
602
        libini,'libini.obj'
609
        libini,'libini.obj'
603
 
610
 
604
import  libini, \
611
import  libini, \
605
        ini.get_str,'ini_get_str'
612
        ini.get_str,'ini_get_str'
606
 
613
 
607
include_debug_strings
614
include_debug_strings
608
 
615
 
609
str_ip          db 'ip', 0
616
str_ip          db 'ip', 0
610
str_subnet      db 'subnet', 0
617
str_subnet      db 'subnet', 0
611
str_gateway     db 'gateway', 0
618
str_gateway     db 'gateway', 0
612
str_dns         db 'dns', 0
619
str_dns         db 'dns', 0
613
str_ipconfig    db 'ipconfig', 0
620
str_ipconfig    db 'ipconfig', 0
614
str_type        db 'type', 0
621
str_type        db 'type', 0
615
 
622
 
616
 
623
 
617
sockaddr1:
624
sockaddr1:
618
 
625
 
619
        dw AF_INET4
626
        dw AF_INET4
620
        dw 68 shl 8     ; local port
627
        dw 68 shl 8     ; local port
621
        dd 0            ; local IP
628
        dd 0            ; local IP
622
 
629
 
623
        rb 10
630
        rb 10
624
 
631
 
625
 
632
 
626
sockaddr2:
633
sockaddr2:
627
 
634
 
628
        dw AF_INET4
635
        dw AF_INET4
629
        dw 67 shl 8     ; destination port
636
        dw 67 shl 8     ; destination port
630
        dd -1           ; destination IP
637
        dd -1           ; destination IP
631
 
638
 
632
        rb 10
639
        rb 10
633
 
640
 
634
notify_struct:
641
notify_struct:
635
        dd 7            ; run application
642
        dd 7            ; run application
636
        dd 0
643
        dd 0
637
 .msg   dd 0
644
 .msg   dd 0
638
        dd 0
645
        dd 0
639
        dd 0
646
        dd 0
640
        db '/sys/@notify', 0
647
        db '/sys/@notify', 0
641
 
648
 
642
str_connected   db '"You are now connected to the network." -N', 0
649
str_connected   db '"You are now connected to the network." -N', 0
643
path            db '/sys/settings/network.ini',0
650
path            db '/sys/settings/network.ini',0
644
 
651
 
645
IM_END:
652
IM_END:
646
 
653
 
647
device          db 1
654
device          db 1
648
inibuf          rb 16
655
inibuf          rb 16
649
tries           db ?
656
tries           db ?
650
 
657
 
651
dhcpMsgType     db ?    ; sent
658
dhcpMsgType     db ?    ; sent
652
dhcpMsgType2    db ?    ; received
659
dhcpMsgType2    db ?    ; received
653
dhcpLease       dd ?
660
dhcpLease       dd ?
654
dhcpServerIP    dd ?
661
dhcpServerIP    dd ?
655
 
662
 
656
dhcp:
663
dhcp:
657
.ip             dd ?
664
.ip             dd ?
658
.subnet         dd ?
665
.subnet         dd ?
659
.dns            dd ?
666
.dns            dd ?
660
.gateway        dd ?
667
.gateway        dd ?
661
 
668
 
662
 
669
 
663
dhcpMsgLen      dd ?
670
dhcpMsgLen      dd ?
664
socketNum       dd ?
671
socketNum       dd ?
665
 
672
 
666
MAC             dp ?
673
MAC             dp ?
667
 
674
 
668
currTime        dd ?
675
currTime        dd ?
669
generator       dd ?
676
generator       dd ?
670
 
677
 
671
dhcpMsg         dd ?
678
dhcpMsg         dd ?
-
 
679
 
-
 
680
timeout         dd ?
672
 
681
 
673
I_END:
682
I_END: