Subversion Repositories Kolibri OS

Rev

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

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