Subversion Repositories Kolibri OS

Rev

Rev 5419 | Rev 5587 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5419 Rev 5586
Line 41... Line 41...
41
 
41
 
Line 42... Line 42...
42
RATE_LIMIT_INTERVAL     = 60            ; seconds (delay between successive attempts)
42
RATE_LIMIT_INTERVAL     = 60            ; seconds (delay between successive attempts)
Line -... Line 43...
-
 
43
 
-
 
44
DEFEND_INTERVAL         = 10            ; seconds (min. wait between defensive ARPs)
43
 
45
 
44
DEFEND_INTERVAL         = 10            ; seconds (min. wait between defensive ARPs)
46
MAX_INTERFACES          = 8
Line 45... Line 47...
45
 
47
 
46
use32
48
use32
Line 60... Line 62...
60
include '../../debug-fdo.inc'
62
include '../../debug-fdo.inc'
61
include '../../network.inc'
63
include '../../network.inc'
62
include 'dhcp.inc'
64
include 'dhcp.inc'
63
include '../../dll.inc'
65
include '../../dll.inc'
Line -... Line 66...
-
 
66
 
-
 
67
struct  dhcp_msg
-
 
68
        op              db ?    ; Operation Code
-
 
69
        htype           db ?    ; Hardware type
-
 
70
        hlen            db ?    ; Hardware address length
-
 
71
        hops            db ?
-
 
72
        xid             dd ?    ; Transaction Identifier
-
 
73
        secs            dw ?    ; Seconds since boot
-
 
74
        flags           dw ?
-
 
75
        ciaddr          dd ?    ; Client IP address
-
 
76
        yiaddr          dd ?    ; "Your" IP address
-
 
77
        siaddr          dd ?    ; Server IP address
-
 
78
        giaddr          dd ?    ; Gateway IP address
-
 
79
        chaddr          rb 16   ; Client hardware address
-
 
80
        sname           rb 64   ; Server name
-
 
81
        file            rb 128  ; boot filename
-
 
82
        cookie          dd ?    ; Magic cookie (0x63538263)
-
 
83
        options         rb 512
-
 
84
ends
-
 
85
 
-
 
86
struct  interface
-
 
87
        number          dd ?
-
 
88
        state           dd ?    ; 0 - disconnected, 1 - connected
-
 
89
        mode            dd ?    ; 0 - static, 1 - dhcp, 2 - auto (zero config)
-
 
90
        tries           dd ?
-
 
91
        lease           dd ?
-
 
92
        ServerIP        dd ?
-
 
93
        ip              dd ?
-
 
94
        subnet          dd ?
-
 
95
        dns             dd ?
-
 
96
        gateway         dd ?
-
 
97
        socketNum       dd ?
-
 
98
        timeout         dd ?
-
 
99
        ip_conflicts    dd ?
-
 
100
ends
64
 
101
 
65
START:
102
START:
Line 66... Line 103...
66
        mcall   68, 11
103
        mcall   68, 11                  ; init heap
67
 
104
 
68
        stdcall dll.Load,@IMPORT
105
        stdcall dll.Load, @IMPORT       ; load libraries
Line 69... Line 106...
69
        or      eax, eax
106
        or      eax, eax
Line -... Line 107...
-
 
107
        jnz     exit_immediately
-
 
108
 
-
 
109
        DEBUGF  2, "Zero-config service loaded\n"
-
 
110
 
-
 
111
        mcall   40, EVM_STACK2          ; We only want low-level network events
-
 
112
 
-
 
113
; Set up interface list
-
 
114
        mov     edi, device_list
-
 
115
        xor     ebx, ebx
-
 
116
  @@:
-
 
117
        inc     ebx
-
 
118
        mov     eax, ebx
70
        jnz     fail
119
        stosd
-
 
120
        mov     ecx, sizeof.interface/4-1
-
 
121
        xor     eax,eax
-
 
122
        rep stosd
-
 
123
        cmp     ebx, MAX_INTERFACES
-
 
124
        jb      @b
-
 
125
 
-
 
126
        mov     ebp, device_list
-
 
127
mainloop:
-
 
128
        cmp     [ebp + interface.state], 0
-
 
129
        je      .link_up?
-
 
130
        jmp     .maintain_link
-
 
131
 
-
 
132
  .next:
-
 
133
        cmp     [ebp + interface.number], MAX_INTERFACES
-
 
134
        je      .wait
-
 
135
        add     ebp, sizeof.interface
-
 
136
        jmp     mainloop
-
 
137
 
Line 71... Line 138...
71
 
138
  .wait:
72
        DEBUGF  2,"Zero-config service loaded\n"
139
        mcall   10                      ; Wait for event
73
 
140
        mov     ebp, device_list
74
        mcall   40, EVM_STACK2
141
        jmp     mainloop
75
 
142
 
76
wait_for_link_up:
143
  .link_up?:
Line 77... Line 144...
77
        mov     bh, [device]
144
        mov     bh, byte[ebp + interface.number]
78
        mov     bl, 0           ; Get device type
145
        mov     bl, 0                   ; Get device type
79
        mcall   74
146
        mcall   74
80
        cmp     eax, 1          ; Ethernet
147
        cmp     eax, 1                  ; Ethernet
Line -... Line 148...
-
 
148
        jne     mainloop.next
-
 
149
 
-
 
150
        mov     bl, 10                  ; Get Link status
-
 
151
        mcall   74
-
 
152
        test    eax, eax
-
 
153
        jz      mainloop.next
81
        jne     .wait
154
 
82
 
155
        mov     [ebp + interface.state], 1
-
 
156
 
83
        mov     bl, 10          ; Get Link status
157
        call    create_str_ini_int
-
 
158
 
Line 84... Line -...
84
        mcall   74
-
 
85
        test    eax, eax
159
; Try to read settings from .ini file
86
        jnz     .go
160
        invoke  ini.get_str, ini_path, str_ini_int, str_ip_type, inibuf, 16, str_null
87
 
161
        test    eax, eax
88
  .wait:
162
        jz      @f
89
        mcall   10
163
; If settings not found, use default settings from 'ip?' section
90
        jmp     wait_for_link_up
164
        mov     dword[str_ini_int], 'ip?'
91
 
-
 
92
  .go:
165
  @@:
-
 
166
 
Line -... Line 167...
-
 
167
        mov     ebx, API_ETH + 0
-
 
168
        mov     bh, byte[ebp + interface.number]
-
 
169
        mcall   76                      ; get MAC of the ethernet interface
-
 
170
        mov     word[tx_msg.chaddr], bx
-
 
171
        mov     dword[tx_msg.chaddr+2], eax
-
 
172
        DEBUGF  1, "MAC: %x-%x-%x-%x-%x-%x\n", \
93
        mov     ebx, API_ETH + 0
173
        [tx_msg.chaddr+0]:2, [tx_msg.chaddr+1]:2, [tx_msg.chaddr+2]:2, \
94
        mov     bh, [device]
174
        [tx_msg.chaddr+3]:2, [tx_msg.chaddr+4]:2, [tx_msg.chaddr+5]:2
-
 
175
 
-
 
176
        invoke  ini.get_str, ini_path, str_ini_int, str_ip_type, inibuf, 16, str_null
95
        mcall   76              ; get MAC of the ethernet interface
177
        test    eax, eax
-
 
178
        jnz     .fail
-
 
179
        mov     eax, dword[inibuf]
-
 
180
        or      eax, 0x20202020
-
 
181
        mov     [ebp + interface.mode], 0
-
 
182
        cmp     eax, 'stat'
-
 
183
        je      static
-
 
184
        mov     [ebp + interface.mode], 1
96
        mov     word[MAC], bx
185
        cmp     eax, 'dhcp'
97
        mov     dword[MAC+2], eax
186
        je      dhcp
-
 
187
        mov     [ebp + interface.mode], 2
98
        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
188
        cmp     eax, 'auto'
-
 
189
        je      dhcp
-
 
190
 
-
 
191
  .fail:
-
 
192
        DEBUGF  2, "Invalid network.ini settings\n"
-
 
193
        mcall   -1                      ; Give up
-
 
194
 
-
 
195
  .maintain_link:
-
 
196
 
-
 
197
; Check for IP conflicts
-
 
198
        mov     ebx, API_ARP
-
 
199
        mov     bh, byte[ebp + interface.number]
-
 
200
        mov     bl, 7
Line 99... Line 201...
99
 
201
        mcall   76                      ; Number of IP conflicts
100
        invoke  ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
-
 
101
 
-
 
102
        cmp     dword[inibuf], 'stat'
202
        cmp     eax, [ebp + interface.ip_conflicts]
103
        je      static
203
        je      @f
104
        jmp     try_dhcp
204
        mov     [ebp + interface.ip_conflicts], eax
105
 
205
        DEBUGF  2, "IP address conflict on interface %u\n", [ebp + interface.number]
106
wait_for_link_down:
206
        ; Notify user of the IP address conflict
Line -... Line 207...
-
 
207
        mov     [notify_struct.msg], str_conflict
107
; TODO: detect ARP conflicts
208
        mcall   70, notify_struct
108
 
209
  @@:
109
        mcall   40, EVM_STACK2
210
 
110
  .loop:
211
; Check if device is still there
Line 111... Line 212...
111
        mcall   10
212
        mov     bh, byte[ebp + interface.number]
-
 
213
        mov     bl, 0                   ; Get device type
-
 
214
        mcall   74
-
 
215
        test    eax, eax                ; No device
-
 
216
        jz      .link_down
-
 
217
 
-
 
218
; Check if link is still there
-
 
219
        mov     bl, 10                  ; Get Link status
112
        mov     bh, [device]
220
        mcall   74
113
        mov     bl, 0           ; Get device type
221
        test    eax, eax
114
        mcall   74
222
        jnz     .next
115
        cmp     eax, 0          ; No device
223
 
116
        je      .down
224
  .link_down:
117
 
225
        mov     [ebp + interface.state], 0
118
        mov     bl, 10          ; Get Link status
226
 
119
        mcall   74
227
; Notify user that the link is down
120
        test    eax, eax
228
        mov     [notify_struct.msg], str_disconnected
121
        jnz     .loop
229
        mcall   70, notify_struct
Line -... Line 230...
-
 
230
 
-
 
231
; CHECKME: should we do this in kernel instead? Should we even do this at all?
-
 
232
        xor     ecx, ecx
-
 
233
        mov     ebx, API_IPv4 + 3
-
 
234
        mov     bh, byte[ebp + interface.number]
-
 
235
        mcall   76                      ; ip
-
 
236
        mov     bl, 5
-
 
237
        mcall   76                      ; dns
-
 
238
        mov     bl, 7
-
 
239
        mcall   76                      ; subnet
-
 
240
        mov     bl, 9
-
 
241
        mcall   76                      ; gateway
-
 
242
 
-
 
243
        jmp     .next
-
 
244
 
-
 
245
link_up:
-
 
246
 
122
 
247
; Read number of previous IP conflicts
Line 123... Line 248...
123
  .down:
248
        mov     ebx, API_ARP
124
        xor     ecx, ecx
249
        mov     bh, byte[ebp + interface.number]
Line 125... Line 250...
125
        mov     ebx, API_IPv4 + 3
250
        mov     bl, 7
126
        mov     bh, [device]
251
        mcall   76
127
        mcall   76              ; ip
252
        mov     [ebp + interface.ip_conflicts], eax
128
        mov     bl, 5
-
 
129
        mcall   76              ; dns
253
 
130
        mov     bl, 7
254
; Notify user that the link is up and running
131
        mcall   76              ; subnet
255
        mov     [notify_struct.msg], str_connected
Line 132... Line 256...
132
        mov     bl, 9
256
        mcall   70, notify_struct
133
        mcall   76              ; gateway
257
 
134
 
258
  .fail:
135
        jmp     wait_for_link_up
-
 
136
 
259
        mcall   40, EVM_STACK2
137
static:
260
        jmp     mainloop.next
138
        DEBUGF  1,"Applying Static IP settings\n"
261
 
Line 139... Line 262...
139
 
262
static:
140
        invoke  ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
263
        DEBUGF  1, "Applying Static IP settings\n"
141
        mov     edx, inibuf
264
 
142
        call    ip_str_to_dword
-
 
143
        mov     ecx, edx
265
        invoke  ini.get_str, ini_path, str_ini_int, str_ip, inibuf, 16, str_null
144
        mov     ebx, API_IPv4 + 3       ; set IP
266
        mov     esi, inibuf
145
        mov     bh, [device]
267
        call    ip_str_to_dword
Line -... Line 268...
-
 
268
        mov     ebx, API_IPv4 + 3       ; set IP
146
        mcall   76
269
        mov     bh, byte[ebp + interface.number]
147
 
270
        mcall   76
148
        invoke  ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
271
 
149
        mov     edx, inibuf
-
 
150
        call    ip_str_to_dword
272
        invoke  ini.get_str, ini_path, str_ini_int, str_subnet, inibuf, 16, str_null
151
        mov     ecx, edx
273
        mov     esi, inibuf
152
        mov     ebx, API_IPv4 + 9       ; set gateway
274
        call    ip_str_to_dword
Line 153... Line -...
153
        mov     bh, [device]
-
 
154
        mcall   76
-
 
155
 
275
        mov     ebx, API_IPv4 + 7       ; set subnet
Line 156... Line 276...
156
        invoke  ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
276
        mov     bh, byte[ebp + interface.number]
Line 157... Line 277...
157
        mov     edx, inibuf
277
        mcall   76
Line 158... Line 278...
158
        call    ip_str_to_dword
278
 
Line 159... Line 279...
159
        mov     ecx, edx
279
        invoke  ini.get_str, ini_path, str_ini_int, str_gateway, inibuf, 16, str_null
160
        mov     ebx, API_IPv4 + 5       ; set DNS
280
        mov     esi, inibuf
161
        mov     bh, [device]
281
        call    ip_str_to_dword
162
        mcall   76
282
        mov     ebx, API_IPv4 + 9       ; set gateway
Line 163... Line 283...
163
 
283
        mov     bh, byte[ebp + interface.number]
Line 164... Line 284...
164
        invoke  ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
284
        mcall   76
165
        mov     edx, inibuf
285
 
166
        call    ip_str_to_dword
286
  .dns:
Line 167... Line 287...
167
        mov     ecx, edx
287
        invoke  ini.get_str, ini_path, str_ini_int, str_dns, inibuf, 16, str_null
Line -... Line 288...
-
 
288
        mov     esi, inibuf
-
 
289
        call    ip_str_to_dword
-
 
290
        mov     ebx, API_IPv4 + 5       ; set DNS
-
 
291
        mov     bh, byte[ebp + interface.number]
-
 
292
        mcall   76
-
 
293
 
-
 
294
        jmp     link_up
-
 
295
 
-
 
296
 
-
 
297
dhcp:
-
 
298
 
168
        mov     ebx, API_IPv4 + 7       ; set subnet
299
        DEBUGF  2, "Trying to contact DHCP server\n"
169
        mov     bh, [device]
300
 
170
        mcall   76
301
        mcall   40, EVM_STACK
Line 171... Line 302...
171
 
302
 
Line 172... Line 303...
172
        mov     [notify_struct.msg], str_connected
303
        mcall   75, 0, AF_INET4, SOCK_DGRAM, 0                          ; open socket (parameters: domain, type, reserved)
173
        mcall   70, notify_struct
304
        cmp     eax, -1
-
 
305
        je      dhcp_error
-
 
306
        mov     [ebp + interface.socketNum], eax
-
 
307
 
Line 174... Line 308...
174
        jmp     wait_for_link_down
308
        DEBUGF  1, "Socket %x opened\n", eax
-
 
309
 
175
 
310
        mcall   75, 2, [ebp + interface.socketNum], sock_local, 18      ; bind socket to local port 68
Line 176... Line 311...
176
 
311
        cmp     eax, -1
Line 177... Line 312...
177
try_dhcp:
312
        je      socket_error
Line 178... Line -...
178
 
-
 
179
        DEBUGF  2,"Trying to contact DHCP server\n"
-
 
180
 
313
 
Line -... Line 314...
-
 
314
        DEBUGF  1, "Socket Bound to local port 68\n"
-
 
315
 
-
 
316
        pushd   [ebp + interface.number]
-
 
317
        pushd   4                       ; length of option
-
 
318
        pushd   1 shl 9                 ; SO_BINDTODEVICE
-
 
319
        pushd   0                       ; SOL_SOCKET
-
 
320
        mcall   75, 8, [ebp + interface.socketNum], esp
-
 
321
        add     esp, 16
-
 
322
        cmp     eax, -1
181
        mcall   40, EVM_STACK
323
        je      socket_error
-
 
324
 
Line 182... Line -...
182
 
-
 
183
        mcall   75, 0, AF_INET4, SOCK_DGRAM, 0          ; open socket (parameters: domain, type, reserved)
-
 
184
        cmp     eax, -1
325
        DEBUGF  1, "Socket Bound to local interface %u\n", [ebp + interface.number]
185
        je      socket_error
326
 
Line 186... Line -...
186
        mov     [socketNum], eax
-
 
187
 
327
        mcall   75, 4, [ebp + interface.socketNum], sock_remote, 18     ; connect to 255.255.255.255 on port 67
188
        DEBUGF  1,"Socket %x opened\n", eax
328
        cmp     eax, -1
189
 
329
        je      socket_error
190
        mcall   75, 2, [socketNum], sockaddr1, 18       ; bind socket to local port 68
-
 
Line -... Line 330...
-
 
330
 
191
        cmp     eax, -1
331
        DEBUGF  1, "Connected to 255.255.255.255 on port 67\n"
Line 192... Line -...
192
        je      socket_error
-
 
193
 
332
 
194
        DEBUGF  1,"Socket Bound to local port 68\n"
-
 
195
 
-
 
196
        mcall   75, 4, [socketNum], sockaddr2, 18       ; connect to 255.255.255.255 on port 67
-
 
197
        cmp     eax, -1
-
 
198
        je      socket_error
333
        ; Read preferred IP address from settings file
199
 
-
 
200
        DEBUGF  1,"Connected to 255.255.255.255 on port 67\n"
-
 
201
 
-
 
202
        mov     [dhcpMsgType_tx], 0x01                  ; DHCP discover
334
        invoke  ini.get_str, ini_path, str_ini_int, str_ip, inibuf, 16, str_null
203
        mov     [dhcpLease], esi                        ; esi is still -1 (-1 = forever)
-
 
204
 
-
 
Line 205... Line -...
205
        call    random
-
 
206
        mov     [dhcpXID], eax
-
 
207
 
-
 
208
build_request:                                          ; Creates a DHCP request packet.
-
 
209
 
-
 
210
        DEBUGF  1,"Building request\n"
-
 
211
 
-
 
212
        mcall   26, 9                                   ; Get system time
-
 
213
        imul    eax, 100
-
 
214
        mov     [currTime], eax
-
 
215
 
-
 
216
        mov     [tries], DHCP_TRIES
335
        mov     esi, inibuf
217
 
336
        call    ip_str_to_dword
218
        stdcall mem.Alloc, BUFFER
-
 
219
        test    eax, eax
-
 
220
        jz      dhcp_fail2
-
 
221
        mov     [dhcpMsg], eax
-
 
222
 
-
 
223
        ; Fill buffer with zeros
-
 
224
        mov     edi, eax
-
 
225
        mov     ecx, BUFFER
-
 
226
        xor     eax, eax
-
 
227
        rep     stosb
-
 
228
 
-
 
229
        mov     edx, [dhcpMsg]
-
 
230
 
-
 
231
        ; Boot protocol legacy
-
 
232
        mov     [edx], byte 0x01                ; Boot request
-
 
233
        mov     [edx+1], byte 0x01              ; Ethernet
-
 
234
        mov     [edx+2], byte 0x06              ; Ethernet h/w len
-
 
235
        mov     eax, [dhcpXID]
-
 
236
        mov     [edx+4], eax                    ; xid
-
 
237
        mov     eax, [currTime]
-
 
238
        mov     [edx+8], eax                    ; secs, our uptime
-
 
Line -... Line 337...
-
 
337
        mov     [ebp + interface.ip], ecx
-
 
338
 
-
 
339
        call    random
-
 
340
        mov     [tx_msg.xid], eax                                       ; randomize session ID
-
 
341
        mov     [tx_msg_type], 1                                        ; DHCP discover
-
 
342
 
-
 
343
build_dhcp_packet:
-
 
344
 
-
 
345
        DEBUGF  1, "Building DHCP packet\n"
-
 
346
 
-
 
347
        mov     [ebp + interface.tries], DHCP_TRIES
-
 
348
 
-
 
349
        ; Boot protocol legacy
-
 
350
        mov     [tx_msg.op], 1                                          ; Boot request
-
 
351
        mov     [tx_msg.htype], 1                                       ; Ethernet
-
 
352
        mov     [tx_msg.hlen], 6                                        ; Ethernet address h/w len
-
 
353
        mov     [tx_msg.hops], 0
-
 
354
        mcall   26, 9                                                   ; Time since boot
-
 
355
        xor     edx, edx
-
 
356
        mov     ebx, 100
-
 
357
        div     ebx                                                     ; Divide by 100 to get number of seconds
-
 
358
        mov     [tx_msg.secs], ax
-
 
359
        mov     [tx_msg.flags], 0
239
        mov     [edx+10], byte 0x80             ; broadcast flag set
360
 
240
        mov     eax, dword [MAC]                ; first 4 bytes of MAC
361
        ; DHCP extension
241
        mov     [edx+28],dword eax
362
        mov     [tx_msg.cookie], 0x63538263                             ; magic cookie
242
        mov     ax, word [MAC+4]                ; last 2 bytes of MAC
363
 
-
 
364
        mov     word[tx_msg+240], 0x0135                                ; option DHCP msg type
243
        mov     [edx+32],word ax
365
        mov     al,[tx_msg_type]
244
 
366
        mov     [tx_msg+240+2], al
245
        ; DHCP extension
-
 
246
        mov     [edx+236], dword 0x63538263     ; magic cookie
367
 
-
 
368
        mov     word[tx_msg+240+3], 0x0433                              ; option Lease time
247
        mov     [edx+240], word 0x0135          ; option DHCP msg type
369
        mov     dword[tx_msg+240+5], -1                                 ; infinite
248
        mov     al, [dhcpMsgType_tx]
370
 
249
        mov     [edx+240+2], al
371
        mov     word[tx_msg+240+9], 0x0432                              ; option requested IP address
Line 250... Line 372...
250
        mov     [edx+240+3], word 0x0433        ; option Lease time = infinity
372
        mov     eax,[ebp + interface.ip]
251
        mov     eax, [dhcpLease]
373
        mov     [tx_msg+240+11], eax
-
 
374
 
252
        mov     [edx+240+5], eax
375
        mov     word[tx_msg+240+15], 0x0437                             ; option request list
Line 253... Line 376...
253
        mov     [edx+240+9], word 0x0432        ; option requested IP address
376
        mov     dword[tx_msg+240+17], 0x0f060301
254
        mov     eax, [dhcp.ip]
377
 
255
        mov     [edx+240+11], eax
-
 
256
        mov     [edx+240+15], word 0x0437       ; option request list
378
        cmp     [tx_msg_type], 1                                        ; Check which msg we are sending
257
        mov     [edx+240+17], dword 0x0f060301
379
        jne     .request
Line 258... Line 380...
258
 
380
 
259
        cmp     [dhcpMsgType_tx], 0x01          ; Check which msg we are sending
381
        mov     byte[tx_msg+240+21], 0xff                               ; end of options marker
260
        jne     .options
382
 
Line 261... Line 383...
261
 
383
        mov     [tx_msg_len], 262                                       ; length
262
        mov     [edx+240+21], byte 0xff         ; end of options marker
384
        jmp     send_dhcp_packet
263
 
385
 
264
        mov     [dhcpMsgLen], 262               ; length
386
  .request:
Line 311... Line 433...
311
;  1.2) send a request packet
433
;  1.2) send a request packet
312
; If the response is to a dhcp request, then:
434
; If the response is to a dhcp request, then:
313
;  1) If the response is DHCP ACK then
435
;  1) If the response is DHCP ACK then
314
;  1.1) extract the DNS & subnet fields. Set them in the stack
436
;  1.1) extract the DNS & subnet fields. Set them in the stack
Line 315... Line 437...
315
 
437
 
316
        cmp     [dhcpMsgType_tx], 0x01          ; did we send a discover?
438
        cmp     [tx_msg_type], 1                ; did we send a discover?
317
        je      discover_sent
-
 
318
 
439
        je      discover_sent
319
        cmp     [dhcpMsgType_tx], 0x03          ; did we send a request?
440
        cmp     [tx_msg_type], 3                ; did we send a request?
320
        je      request_sent
-
 
321
 
-
 
322
        ; we should never reach here ;)
-
 
323
        stdcall mem.Free, [dhcpMsg]
441
        je      request_sent
Line 324... Line 442...
324
        jmp     fail
442
        jmp     exit_immediately
325
 
443
 
326
discover_sent:
444
discover_sent:
327
        call    parse_response
445
        call    parse_dhcp_reply
Line 328... Line 446...
328
        cmp     [dhcpMsgType_rx], 0x02          ; Was the response an offer?
446
        cmp     [rx_msg_type], 2                ; Was the response an offer?
329
        jne     read_data
447
        jne     read_packet
330
 
448
 
Line 331... Line 449...
331
        DEBUGF  1, "Got offer, making request\n"
449
        DEBUGF  1, "Got offer, making request\n"
332
        mov     [dhcpMsgType_tx], 0x03          ; make it a request
450
        mov     [tx_msg_type], 3                ; make it a request
333
        jmp     build_request
451
        jmp     build_dhcp_packet
334
 
452
 
Line 335... Line 453...
335
request_sent:
453
request_sent:
Line 336... Line -...
336
        call    parse_response
-
 
337
        cmp     [dhcpMsgType_rx], 0x05          ; Was the response an ACK? It should be
-
 
338
        jne     read_data                       ; NO - read next packets
-
 
339
 
454
        call    parse_dhcp_reply
Line 340... Line 455...
340
        DEBUGF  2, "IP assigned by DHCP server successfully\n"
455
        cmp     [rx_msg_type], 5                ; Was the response an ACK? It should be
341
 
456
        jne     read_packet                     ; NO - read next packets
342
        mov     [notify_struct.msg], str_connected
457
 
343
        mcall   70, notify_struct
458
        DEBUGF  2, "IP assigned by DHCP server successfully\n"
344
 
-
 
345
        mcall   close, [socketNum]
-
 
346
 
459
 
347
        mov     ebx, API_IPv4 + 3
460
        mcall   close, [ebp + interface.socketNum]
348
        mov     bh, [device]
461
 
-
 
462
        mov     ebx, API_IPv4 + 3
-
 
463
        mov     bh, byte[ebp + interface.number]
-
 
464
        mcall   76, , [ebp + interface.ip]            ; ip
-
 
465
        mov     bl, 5
-
 
466
        mcall   76, , [ebp + interface.subnet]        ; subnet
-
 
467
        mov     bl, 9
-
 
468
        mcall   76, , [ebp + interface.gateway]       ; gateway
-
 
469
 
-
 
470
        invoke  ini.get_str, ini_path, str_ini_int, str_dns_type, inibuf, 16, str_null
-
 
471
        test    eax, eax
-
 
472
        jnz     @f
Line 349... Line 473...
349
        mcall   76, , [dhcp.ip]                 ; ip
473
        mov     eax, dword[inibuf]
Line 350... Line -...
350
        mov     bl, 5
-
 
351
        mcall   76, , [dhcp.dns]                ; dns
-
 
352
        mov     bl, 7
-
 
353
        mcall   76, , [dhcp.subnet]             ; subnet
-
 
354
        mov     bl, 9
-
 
355
        mcall   76, , [dhcp.gateway]            ; gateway
-
 
356
 
-
 
357
        jmp     wait_for_link_down
-
 
358
 
-
 
359
 
-
 
360
;***************************************************************************
-
 
361
;   Function
-
 
362
;      parseResponse
-
 
363
;
474
        or      eax, 0x202020
Line 364... Line 475...
364
;   Description
475
        cmp     eax, 'stat'
365
;      extracts the fields ( client IP address and options ) from
-
 
366
;      a DHCP response
476
        je      static.dns
Line 367... Line 477...
367
;      The values go into
477
  @@:
368
;       dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP,
478
        mcall   76, , [ebp + interface.dns]           ; dns
369
;       dhcpDNSIP, dhcpSubnet
479
        mov     bl, 7
370
;      The message is stored in dhcpMsg
480
 
Line 371... Line 481...
371
;
481
        jmp     link_up
372
;***************************************************************************
482
 
373
parse_response:
483
 
-
 
484
parse_dhcp_reply:
Line 374... Line 485...
374
 
485
 
375
        DEBUGF  1,"Parsing response\n"
-
 
376
        mov     edx, [dhcpMsg]
486
        DEBUGF  1, "Parsing response\n"
377
        mov     [dhcpMsgType_rx], 0
487
        mov     [rx_msg_type], 0
Line -... Line 488...
-
 
488
 
-
 
489
; Verify if session ID matches
-
 
490
        mov     eax, [tx_msg.xid]
378
 
491
        cmp     [rx_msg.xid], eax
-
 
492
        jne     .done
379
; Verify if session ID matches
493
 
Line 380... Line 494...
380
        mov     eax, [dhcpXID]
494
        pushd   [rx_msg.yiaddr]
381
        cmp     dword[edx+4], eax
-
 
-
 
495
        pop     [ebp + interface.ip]
382
        jne     .done
496
        DEBUGF  1, "Client: %u.%u.%u.%u\n", \
383
 
497
        [rx_msg.yiaddr]:1, [rx_msg.yiaddr+1]:1, [rx_msg.yiaddr+2]:1, [rx_msg.yiaddr+3]:1
-
 
498
 
-
 
499
; Verify magic cookie
Line 384... Line -...
384
        push    dword [edx+16]
-
 
385
        pop     [dhcp.ip]
-
 
386
        DEBUGF  1,"Client: %u.%u.%u.%u\n", [edx+16]:1, [edx+17]:1, [edx+18]:1, [edx+19]:1
-
 
387
 
-
 
388
; TODO: check if there really are options
-
 
389
 
-
 
390
        mov     al, 240                         ; Point to first option
500
        cmp     [rx_msg.cookie], 0x63538263
391
        movzx   ecx, al
501
        jne     .done
392
 
-
 
393
  .next_option:
502
 
394
        add     edx, ecx
503
; Parse the DHCP options
395
 
-
 
396
        mov     al, [edx]                       ; get message identifier
504
        lea     esi, [rx_msg]
397
 
505
        mov     ecx, 240                        ; point to the first option
398
        cmp     al, 0xff                        ; End of options?
-
 
399
        je      .done
506
  .next_option:
400
 
507
; TODO: check if we still are inside the buffer!
401
        cmp     al, 0
-
 
402
        je      .pad
508
        add     esi, ecx
403
 
509
 
404
; TODO: check if we still are inside the buffer
-
 
405
 
510
        lodsb                                   ; get message identifier
406
        inc     edx
511
        mov     bl, al
407
        movzx   ecx, byte [edx]                 ; get data length
-
 
408
        inc     edx                             ; point to data
512
        cmp     bl, 0xff                        ; End of options?
409
 
513
        je      .done
Line 410... Line 514...
410
        cmp     al, dhcp_msg_type               ; Msg type is a single byte option
514
        test    bl, bl
411
        je      .msgtype
-
 
412
 
515
        jz      .pad
Line 413... Line 516...
413
        cmp     al, dhcp_dhcp_server_id
516
 
414
        je      .server
517
        lodsb                                   ; load data length
415
 
518
        movzx   ecx, al
416
        cmp     al, dhcp_address_time
519
        cmp     bl, dhcp_msg_type               ; Msg type is a single byte option
Line 417... Line 520...
417
        je      .lease
520
        je      .msgtype
418
 
521
        cmp     bl, dhcp_dhcp_server_id
419
        cmp     al, dhcp_subnet_mask
522
        je      .server
Line 420... Line 523...
420
        je      .subnet
523
        cmp     bl, dhcp_address_time
421
 
524
        je      .lease
Line 422... Line 525...
422
        cmp     al, dhcp_router
525
        cmp     bl, dhcp_subnet_mask
423
        je      .router
526
        je      .subnet
424
 
527
        cmp     bl, dhcp_router
425
        cmp     al, dhcp_domain_server
528
        je      .router
426
        je      .dns
529
        cmp     bl, dhcp_domain_server
Line 427... Line 530...
427
 
530
        je      .dns
428
        DEBUGF  1,"Unsupported DHCP option: %u\n", al
531
 
429
 
532
        DEBUGF  1, "Unsupported DHCP option: %u\n", bl
430
        jmp     .next_option
533
        jmp     .next_option
431
 
534
 
432
  .pad:
535
  .pad:
433
        xor     ecx, ecx
536
        xor     ecx, ecx
434
        inc     ecx
537
        inc     ecx
Line 435... Line 538...
435
        jmp     .next_option
538
        jmp     .next_option
436
 
539
 
437
  .msgtype:
540
  .msgtype:
438
        mov     al, [edx]
541
        mov     al, [esi]
439
        mov     [dhcpMsgType_rx], al
542
        mov     [rx_msg_type], al
Line 440... Line 543...
440
 
543
 
441
        DEBUGF  1,"DHCP Msg type: %u\n", al
544
        DEBUGF  1, "DHCP Msg type: %u\n", al
442
        jmp     .next_option                    ; Get next option
545
        jmp     .next_option                    ; Get next option
443
 
546
 
444
  .server:
547
  .server:
Line 445... Line 548...
445
        mov     eax, [edx]
548
        pushd   [esi]
446
        mov     [dhcpServerIP], eax
549
        pop     [ebp + interface.ServerIP]
447
        DEBUGF  1,"Server: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
550
        DEBUGF  1, "Server: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
448
        jmp     .next_option
551
        jmp     .next_option
449
 
552
 
Line 450... Line 553...
450
  .lease:
553
  .lease:
451
        pusha
-
 
452
        mov     eax,[edx]
554
        pusha
Line -... Line 555...
-
 
555
        mov     eax,[esi]
-
 
556
        bswap   eax
-
 
557
        mov     [ebp + interface.lease], eax
-
 
558
        DEBUGF  1, "Lease: %d\n", eax
-
 
559
        popa
-
 
560
        jmp     .next_option
Line 453... Line 561...
453
        bswap   eax
561
 
-
 
562
  .subnet:
Line 454... Line -...
454
        mov     [dhcpLease],eax
-
 
455
        DEBUGF  1,"Lease: %d\n",eax
-
 
456
        popa
563
        pushd   [esi]
457
        jmp     .next_option
564
        pop     [ebp + interface.subnet]
458
 
-
 
-
 
565
        DEBUGF  1, "Subnet: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
-
 
566
        jmp     .next_option
Line 459... Line 567...
459
  .subnet:
567
 
-
 
568
  .router:
-
 
569
        pushd   [esi]
-
 
570
        pop     [ebp + interface.gateway]
460
        push    dword [edx]
571
        DEBUGF  1, "Gateway: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
461
        pop     [dhcp.subnet]
572
        jmp     .next_option
462
        DEBUGF  1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
573
 
463
        jmp     .next_option
574
  .dns:
464
 
575
        pushd   [esi]
465
  .router:
576
        pop     [ebp + interface.dns]
466
        push    dword [edx]
577
        DEBUGF  1, "DNS: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
467
        pop     [dhcp.gateway]
578
        jmp     .next_option
468
        DEBUGF  1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
579
 
469
        jmp     .next_option
580
  .done:
470
 
581
        ret
471
  .dns:
582
 
472
        push    dword [edx]
583
exit_immediately:
473
        pop     [dhcp.dns]
584
        DEBUGF  2, "Zeroconf failed!\n"
Line 474... Line -...
474
        DEBUGF  1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
-
 
475
        jmp     .next_option
-
 
476
 
-
 
477
  .done:
-
 
478
        stdcall mem.Free, [dhcpMsg]
-
 
479
        ret
-
 
480
 
-
 
481
 
-
 
482
dhcp_fail:
-
 
483
 
-
 
484
        mcall   close, [socketNum]
-
 
485
 
-
 
486
dhcp_fail2:
-
 
487
        DEBUGF  1,"DHCP failed\n"
-
 
488
 
-
 
489
 
-
 
490
link_local:
-
 
491
        call    random
-
 
492
        mov     cx, ax
-
 
493
        shl     ecx, 16
-
 
494
        mov     cx, 0xfea9                              ; IP 169.254.0.0 link local net, see RFC3927
-
 
495
        mov     ebx, API_IPv4 + 3
-
 
496
        mov     bh, [device]
-
 
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
-
 
499
        mov     bl, 7
-
 
500
        mcall   76, , 0xffff
-
 
501
        mov     bl, 9
-
 
502
        mcall   76, , 0x0
-
 
503
        mov     bl, 5
-
 
504
        mcall   76, , 0x0
-
 
505
 
-
 
506
        mcall   5, PROBE_WAIT*100
-
 
507
 
-
 
508
        xor     esi, esi
-
 
509
   probe_loop:
-
 
510
        call    random                                  ; create a pseudo random number in eax (seeded by MAC)
-
 
511
 
-
 
512
        cmp     al, PROBE_MIN*100                       ; check if al is bigger then PROBE_MIN
-
 
513
        jae     @f                                      ; all ok
-
 
514
        add     al, (PROBE_MAX-PROBE_MIN)*100           ; al is too small
-
 
515
   @@:
-
 
516
 
-
 
517
        cmp     al, PROBE_MAX*100
-
 
518
        jbe     @f
-
 
519
        sub     al, (PROBE_MAX-PROBE_MIN)*100
-
 
520
   @@:
-
 
521
 
-
 
522
        movzx   ebx,al
585
        mcall   -1
523
        DEBUGF  1,"Waiting %u0ms\n",ebx
-
 
524
        mcall   5
-
 
525
 
-
 
526
        DEBUGF  1,"Sending Probe\n"
-
 
527
        mov     ebx, API_ARP + 6
-
 
528
        mov     bh, [device]
-
 
529
        mcall   76
-
 
530
        inc     esi
-
 
531
 
-
 
Line 532... Line 586...
532
        cmp     esi, PROBE_NUM
586
 
Line 533... Line 587...
533
        jb      probe_loop
587
socket_error:
534
 
588
        DEBUGF  2, "Socket error!\n"
535
; now we wait further ANNOUNCE_WAIT seconds and send ANNOUNCE_NUM ARP announces. If any other host has assingned
589
 
536
; IP within this time, we should create another adress, that have to be done later
590
dhcp_fail:
537
 
591
        mcall   close, [ebp + interface.socketNum]
538
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_WAIT
592
 
539
        mcall   5, ANNOUNCE_WAIT*100
593
dhcp_error:
540
        xor   esi, esi
594
        DEBUGF  1, "DHCP failed\n"
Line 541... Line 595...
541
   announce_loop:
595
        cmp     [ebp + interface.mode], 2               ; zero config mode?
Line 542... Line 596...
542
 
596
        jne     link_up
-
 
597
 
-
 
598
link_local:
-
 
599
 
-
 
600
; TODO: send ARP probes before setting the IP address in stack!
-
 
601
 
-
 
602
        call    random
-
 
603
        mov     cx, ax
543
        DEBUGF  1,"Sending Announce\n"
604
        shl     ecx, 16
544
        mov     ebx, API_ARP + 6
-
 
545
        mov     bh, [device]
605
        mov     cx, 0xfea9                              ; IP 169.254.0.0 link local net, see RFC3927
546
        mcall   76
-
 
547
 
606
        mov     ebx, API_IPv4 + 3
548
        inc     esi
-
 
549
        cmp     esi,ANNOUNCE_NUM
607
        mov     bh, byte[ebp + interface.number]
550
        je      @f
-
 
551
 
-
 
552
        DEBUGF  1,"Waiting %us\n", ANNOUNCE_INTERVAL
-
 
553
        mcall   5, ANNOUNCE_INTERVAL*100
608
        mcall   76, , ecx                               ; mask is 255.255.0.0
554
        jmp     announce_loop
-
 
555
   @@:
-
 
556
        jmp     wait_for_link_down
609
        DEBUGF  2, "Link Local IP assigned: 169.254.%u.%u\n", [generator+0]:1, [generator+1]:1
557
 
-
 
558
 
-
 
559
socket_error:
610
        mov     bl, 7
560
        DEBUGF  2,"Socket error\n"
611
        mcall   76, , 0xffff
561
fail:
-
 
562
        DEBUGF  2,"Zeroconf failed!\n"
612
        mov     bl, 9
563
        mcall   -1
613
        mcall   76, , 0x0
Line 564... Line -...
564
 
-
 
565
 
614
        mov     bl, 5
566
random:  ; Pseudo random actually
-
 
Line 567... Line -...
567
 
-
 
568
        mov     eax, [generator]
-
 
569
        add     eax, -43ab45b5h
-
 
Line 570... Line -...
570
        ror     eax, 1
-
 
571
        bswap   eax
-
 
Line 572... Line 615...
572
        xor     eax, dword[MAC]
615
        mcall   76, , 0x0
-
 
616
 
Line 573... Line 617...
573
        ror     eax, 1
617
        jmp     link_up
574
        xor     eax, dword[MAC+2]
-
 
575
        mov     [generator], eax
-
 
Line 576... Line -...
576
 
-
 
577
        ret
-
 
578
 
-
 
579
 
618
 
580
 
619
 
581
ip_str_to_dword:
620
random:  ; Pseudo random actually
582
    push    edx
621
 
583
 
622
        mov     eax,[generator]
584
    ; This code validates if the query is an IP containing 4 numbers and 3 dots
623
        add     eax, -43ab45b5h
585
 
624
        ror     eax, 1
586
    xor     al, al            ; make al (dot count) zero
625
        bswap   eax
-
 
626
        xor     eax, dword[tx_msg.chaddr]
-
 
627
        ror     eax, 1
-
 
628
        xor     eax, dword[tx_msg.chaddr+2]
587
 
629
        mov     [generator], eax
-
 
630
 
-
 
631
        ret
-
 
632
 
-
 
633
 
-
 
634
 
-
 
635
create_str_ini_int:
588
   @@:
636
        mov     eax, [ebp + interface.number]
-
 
637
        mov     ebx, 10
-
 
638
        xor     edx, edx
-
 
639
        push    0
-
 
640
  @@:
-
 
641
        div     ebx
-
 
642
        add     dl, '0'
589
    cmp     byte[edx],'0'     ; check if this byte is a number, if not jump to no_IP
643
        push    edx
590
    jl      no_IP             ;
644
        test    eax, eax
591
    cmp     byte[edx],'9'     ;
-
 
592
    jg      no_IP             ;
-
 
593
 
-
 
594
    inc     edx               ; the byte was a number, so lets check the next byte
645
        jnz     @r
595
 
-
 
596
    cmp     byte[edx],0       ; is this byte zero? (have we reached end of query?)
646
  @@:
Line 597... Line 647...
597
    jz      @f                ; jump to next @@ then
647
        mov     edi, str_ini_int+2
598
    cmp     byte[edx],':'
-
 
599
    jz      @f
648
  @@:
600
 
-
 
601
    cmp     byte[edx],'.'     ; is this byte a dot?
649
        pop     eax
Line 602... Line 650...
602
    jne     @r                ; if not, jump to previous @@
650
        stosb
Line 603... Line 651...
603
 
651
        test    eax, eax
Line 653... Line 701...
653
 
701
 
654
library \
702
library \
Line 655... Line 703...
655
        libini,'libini.obj'
703
        libini,         'libini.obj'
656
 
704
 
-
 
705
import  libini, \
Line 657... Line 706...
657
import  libini, \
706
        ini.get_str,    'ini_get_str',\
Line 658... Line 707...
658
        ini.get_str,'ini_get_str'
707
        ini.set_str,    'ini_set_str'
659
 
708
 
660
include_debug_strings
709
include_debug_strings
661
 
710
 
662
str_ip          db 'ip', 0
-
 
663
str_subnet      db 'subnet', 0
-
 
Line -... Line 711...
-
 
711
str_ip          db 'ip', 0
-
 
712
str_subnet      db 'subnet', 0
Line -... Line 713...
-
 
713
str_gateway     db 'gateway', 0
664
str_gateway     db 'gateway', 0
714
str_dns         db 'dns', 0
Line -... Line 715...
-
 
715
 
-
 
716
str_ip_type     db 'ip_type', 0
-
 
717
str_dns_type    db 'dns_type', 0
665
str_dns         db 'dns', 0
718
 
666
str_ipconfig    db 'ipconfig', 0
719
str_ini_int     db 'ip1', 0
667
str_type        db 'type', 0
720
                rb 10
668
 
-
 
669
 
721
 
Line 670... Line 722...
670
sockaddr1:
722
str_null        db 0
671
 
-
 
672
        dw AF_INET4
723
 
673
        dw 68 shl 8     ; local port
724
sock_local:
674
        dd 0            ; local IP
725
        dw AF_INET4
675
 
-
 
676
        rb 10
726
        dw 68 shl 8     ; local port
Line 677... Line 727...
677
 
727
        dd 0            ; local IP
678
 
728
        rb 10
679
sockaddr2:
729
 
Line 691... Line 741...
691
        dd 0
741
        dd 0
692
        dd 0
742
        dd 0
693
        db '/sys/@notify', 0
743
        db '/sys/@notify', 0
Line 694... Line 744...
694
 
744
 
-
 
745
str_connected           db '"You are now connected to the network." -N', 0
-
 
746
str_disconnected        db '"You are now disconnected from the network." -N', 0
Line 695... Line 747...
695
str_connected   db '"You are now connected to the network." -N', 0
747
str_conflict            db '"An IP address conflict has been detected on the network." -W', 0
Line 696... Line 748...
696
 
748
 
Line 697... Line -...
697
path            db '/sys/settings/network.ini',0
-
 
698
 
-
 
699
IM_END:
-
 
700
 
-
 
701
device          db 1
-
 
702
inibuf          rb 16
-
 
703
tries           db ?
-
 
704
 
-
 
705
dhcpMsgType_tx  db ?    ; sent
-
 
706
dhcpMsgType_rx  db ?    ; received
-
 
707
dhcpXID         dd ?
-
 
708
dhcpLease       dd ?
-
 
709
dhcpServerIP    dd ?
-
 
710
 
-
 
711
dhcp:
-
 
712
.ip             dd ?
-
 
713
.subnet         dd ?
-
 
714
.dns            dd ?
-
 
715
.gateway        dd ?
-
 
716
 
-
 
717
 
-
 
718
dhcpMsgLen      dd ?
-
 
719
socketNum       dd ?
-
 
720
 
749
ini_path                db '/sys/settings/network.ini',0
Line -... Line 750...
-
 
750
 
-
 
751
IM_END:
-
 
752
 
721
MAC             dp ?
753
generator       dd ?
-
 
754
 
-
 
755
inibuf          rb 16
-
 
756
 
-
 
757
tx_msg_len      dd ?
Line 722... Line 758...
722
 
758
rx_msg_len      dd ?
Line 723... Line 759...
723
currTime        dd ?
759
tx_msg_type     db ?
724
generator       dd ?
760
rx_msg_type     db ?