Subversion Repositories Kolibri OS

Rev

Rev 109 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
31 halyavin 1
;
2
;    DHCP Client
3
;
4
;    Compile with FASM for Menuet
5
;
6
 
7
include 'lang.inc'
485 heavyiron 8
include '..\..\..\macros.inc'
31 halyavin 9
 
10
use32
11
 
485 heavyiron 12
               org    0x0
31 halyavin 13
 
485 heavyiron 14
	       db     'MENUET01'	    ; 8 byte id
15
	       dd     0x01		    ; header version
16
	       dd     START		    ; start of code
17
	       dd     I_END		    ; size of image
18
	       dd     I_END+0x8000	    ; memory for app
19
	       dd     I_END+0x8000	    ; esp
20
	       dd     0x0 , 0x0 	    ; I_Param , I_Icon
31 halyavin 21
 
22
 
23
START:                                      ; start of execution
24
    mov     eax,40                          ; Report events
25
    mov     ebx,10000111b                   ; Stack 8 + defaults
26
    int     0x40
27
 
485 heavyiron 28
red:                            ; redraw
31 halyavin 29
    call    draw_window                     ; at first, draw the window
30
 
31
still:
32
    mov     eax,10                          ; wait here for event
485 heavyiron 33
    mcall
31 halyavin 34
 
35
    cmp     eax,1                           ; redraw request ?
36
    jz      red
37
    cmp     eax,2                           ; key in buffer ?
38
    jz      key
39
    cmp     eax,3                           ; button in buffer ?
40
    jz      button
41
 
42
    jmp     still
43
key:                            ; Keys are not valid at this part of the
44
    mov     eax,2               ; loop. Just read it and ignore
485 heavyiron 45
    mcall
31 halyavin 46
    jmp     still
47
 
48
button:                         ; button
49
    mov     eax,17              ; get id
485 heavyiron 50
    mcall
31 halyavin 51
 
52
    cmp     ah,1                ; button id=1 ?
53
    jnz     noclose
54
 
55
    ; close socket before exiting
56
    mov     eax, 53
57
    mov     ebx, 1
58
    mov     ecx, [socketNum]
485 heavyiron 59
    mcall
31 halyavin 60
 
61
    mov     eax,0xffffffff      ; close this program
485 heavyiron 62
    mcall
31 halyavin 63
 
64
noclose:
65
    cmp     ah,3                ; Resolve address?
66
    jnz     still
67
 
68
    call    draw_window
69
 
70
    call    contactDHCPServer
71
 
72
    jmp     still
73
 
74
 
75
;***************************************************************************
76
;   Function
77
;      parseResponse
78
;
79
;   Description
80
;      extracts the fields ( client IP address and options ) from
81
;      a DHCP response
82
;      The values go into
83
;       dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP,
84
;       dhcpDNSIP, dhcpSubnet
85
;      The message is stored in dhcpMsg
86
;
87
;***************************************************************************
88
parseResponse:
89
    mov     edx, dhcpMsg
90
 
91
    mov     eax, [edx+16]
92
    mov     [dhcpClientIP], eax
93
 
94
    ; Scan options
95
 
96
    add     edx, 240        ; Point to first option
97
 
98
pr001:
99
    ; Get option id
100
    mov     al, [edx]
101
    cmp     al, 0xff        ; End of options?
102
    je      pr_exit
103
 
104
    cmp     al, 53          ; Msg type is a single byte option
105
    jne     pr002
106
 
107
    mov     al, [edx+2]
108
    mov     [dhcpMsgType], al
109
    add     edx, 3
110
    jmp     pr001           ; Get next option
111
 
112
pr002:
113
    ; All other (accepted) options are 4 bytes in length
114
    inc     edx
115
    movzx   ecx, byte [edx]
116
    inc     edx             ; point to data
117
 
118
    cmp     al, 54          ; server id
119
    jne     pr0021
120
    mov     eax, [edx]      ; All options are 4 bytes, so get it
121
    mov     [dhcpServerIP], eax
122
    jmp     pr003
123
 
124
pr0021:
125
    cmp     al, 51          ; lease
126
    jne     pr0022
127
    mov     eax, [edx]      ; All options are 4 bytes, so get it
128
    mov     [dhcpLease], eax
129
    jmp     pr003
130
 
131
pr0022:
132
    cmp     al, 1           ; subnet mask
133
    jne     pr0023
134
    mov     eax, [edx]      ; All options are 4 bytes, so get it
135
    mov     [dhcpSubnet], eax
136
    jmp     pr003
137
 
138
pr0023:
139
    cmp     al, 6           ; dns ip
140
    jne     pr0024
141
    mov     eax, [edx]      ; All options are 4 bytes, so get it
142
    mov     [dhcpDNSIP], eax
143
 
144
pr0024:
145
    cmp     al, 3           ; gateway ip
146
    jne     pr003
147
    mov     eax, [edx]      ; All options are 4 bytes, so get it
148
    mov     [dhcpGateway], eax
149
 
150
pr003:
151
    add     edx, ecx
152
    jmp     pr001
153
 
154
pr_exit:
155
    ret
156
 
157
 
158
;***************************************************************************
159
;   Function
160
;      buildRequest
161
;
162
;   Description
163
;      Creates a DHCP request packet.
164
;
165
;***************************************************************************
166
buildRequest:
167
    ; Clear dhcpMsg to all zeros
168
    xor     eax,eax
169
    mov     edi,dhcpMsg
170
    mov     ecx,512
171
    cld
172
    rep     stosb
173
 
174
    mov     edx, dhcpMsg
175
 
176
    mov     [edx], byte 0x01                ; Boot request
177
    mov     [edx+1], byte 0x01              ; Ethernet
178
    mov     [edx+2], byte 0x06              ; Ethernet h/w len
179
    mov     [edx+4], dword 0x11223344       ; xid
180
    mov     [edx+10], byte 0x80             ; broadcast flag set
181
    mov     [edx+236], dword 0x63538263     ; magic number
182
 
183
    ; option DHCP msg type
184
    mov     [edx+240], word 0x0135
185
    mov     al, [dhcpMsgType]
186
    mov     [edx+240+2], al
187
 
188
    ; option Lease time = infinity
189
    mov     [edx+240+3], word 0x0433
190
    mov     eax, [dhcpLease]
191
    mov     [edx+240+5], eax
192
 
193
    ; option requested IP address
194
    mov     [edx+240+9], word 0x0432
195
    mov     eax, [dhcpClientIP]
196
    mov     [edx+240+11], eax
197
 
198
    ; option request list
199
    mov     [edx+240+15], word 0x0437
200
    mov     [edx+240+17], dword 0x0f060301
201
 
202
    ; Check which msg we are sending
203
    cmp     [dhcpMsgType], byte 0x01
204
    jne     br001
205
 
206
    ; "Discover" options
207
    ; end of options marker
208
    mov     [edx+240+21], byte 0xff
209
 
210
    mov     [dhcpMsgLen], dword 262
211
    jmp     br_exit
212
 
213
br001:
214
    ; "Request" options
215
 
216
    ; server IP
217
    mov     [edx+240+21], word 0x0436
218
    mov     eax, [dhcpServerIP]
219
    mov     [edx+240+23], eax
220
 
221
    ; end of options marker
222
    mov     [edx+240+27], byte 0xff
223
 
224
    mov     [dhcpMsgLen], dword 268
225
 
226
br_exit:
227
    ret
228
 
229
 
230
 
231
;***************************************************************************
232
;   Function
233
;      contactDHCPServer
234
;
235
;   Description
236
;       negotiates settings with a DHCP server
237
;
238
;***************************************************************************
239
contactDHCPServer:
240
    ; First, open socket
241
    mov     eax, 53
242
    mov     ebx, 0
243
    mov     ecx, 68                 ; local port dhcp client
244
    mov     edx, 67                 ; remote port - dhcp server
245
    mov     esi, 0xffffffff         ; broadcast
485 heavyiron 246
    mcall
31 halyavin 247
 
248
    mov     [socketNum], eax
249
 
250
    ; Setup the first msg we will send
251
    mov     [dhcpMsgType], byte 0x01 ; DHCP discover
252
    mov     [dhcpLease], dword 0xffffffff
253
    mov     [dhcpClientIP], dword 0
254
    mov     [dhcpServerIP], dword 0
255
 
256
    call    buildRequest
257
 
258
ctr000:
259
    ; write to socket ( send broadcast request )
260
    mov     eax, 53
261
    mov     ebx, 4
262
    mov     ecx, [socketNum]
263
    mov     edx, [dhcpMsgLen]
264
    mov     esi, dhcpMsg
485 heavyiron 265
    mcall
31 halyavin 266
 
267
    ; Setup the DHCP buffer to receive response
268
 
269
    mov     eax, dhcpMsg
270
    mov     [dhcpMsgLen], eax      ; Used as a pointer to the data
271
 
272
    ; now, we wait for
273
    ; UI redraw
274
    ; UI close
275
    ; or data from remote
276
 
277
ctr001:
278
    mov     eax,10                 ; wait here for event
485 heavyiron 279
    mcall
31 halyavin 280
 
281
    cmp     eax,1                  ; redraw request ?
282
    je      ctr003
283
    cmp     eax,2                  ; key in buffer ?
284
    je      ctr004
285
    cmp     eax,3                  ; button in buffer ?
286
    je      ctr005
287
 
288
 
289
    ; Any data in the UDP receive buffer?
290
    mov     eax, 53
291
    mov     ebx, 2
292
    mov     ecx, [socketNum]
485 heavyiron 293
    mcall
31 halyavin 294
 
295
    cmp     eax, 0
296
    je      ctr001
297
 
298
    ; we have data - this will be the response
299
ctr002:
300
    mov     eax, 53
301
    mov     ebx, 3
302
    mov     ecx, [socketNum]
485 heavyiron 303
    mcall                ; read byte - block (high byte)
31 halyavin 304
 
305
    ; Store the data in the response buffer
306
    mov     eax, [dhcpMsgLen]
307
    mov     [eax], bl
308
    inc     dword [dhcpMsgLen]
309
 
310
    mov     eax, 53
311
    mov     ebx, 2
312
    mov     ecx, [socketNum]
485 heavyiron 313
    mcall                ; any more data?
31 halyavin 314
 
315
    cmp     eax, 0
316
    jne     ctr002              ; yes, so get it
317
 
318
    ; depending on which msg we sent, handle the response
319
    ; accordingly.
320
    ; If the response is to a dhcp discover, then:
321
    ;  1) If response is DHCP OFFER then
322
    ;  1.1) record server IP, lease time & IP address.
323
    ;  1.2) send a request packet
324
    ;  2) else exit ( display error )
325
    ; If the response is to a dhcp request, then:
326
    ;  1) If the response is DHCP ACK then
327
    ;  1.1) extract the DNS & subnet fields. Set them in the stack
328
    ;  2) else exit ( display error )
329
 
330
 
331
    cmp     [dhcpMsgType], byte 0x01    ; did we send a discover?
332
    je      ctr007
333
    cmp     [dhcpMsgType], byte 0x03    ; did we send a request?
334
    je      ctr008
335
 
336
    ; should never get here - we only send discover or request
337
    jmp     ctr006
338
 
339
ctr007:
340
    call    parseResponse
341
 
342
    ; Was the response an offer? It should be
343
    cmp     [dhcpMsgType], byte 0x02
344
    jne     ctr006                  ; NO - so quit
345
 
346
    ; send request
347
    mov     [dhcpMsgType], byte 0x03 ; DHCP request
348
    call    buildRequest
349
    jmp     ctr000
350
 
351
ctr008:
352
    call    parseResponse
353
 
354
    ; Was the response an ACK? It should be
355
    cmp     [dhcpMsgType], byte 0x05
356
    jne     ctr006                  ; NO - so quit
357
 
358
    ; Set or display addresses here...
359
 
360
ctr006:
361
    ; close socket
362
    mov     eax, 53
363
    mov     ebx, 1
364
    mov     ecx, [socketNum]
485 heavyiron 365
    mcall
31 halyavin 366
 
367
    mov     [socketNum], dword 0xFFFF
368
 
369
    call    draw_window
370
 
371
    jmp     ctr001
372
 
373
ctr003:                         ; redraw
374
    call    draw_window
375
    jmp     ctr001
376
 
377
ctr004:                         ; key
378
    mov     eax,2               ; just read it and ignore
485 heavyiron 379
    mcall
31 halyavin 380
    jmp     ctr001
381
 
382
ctr005:                         ; button
383
    mov     eax,17              ; get id
485 heavyiron 384
    mcall
31 halyavin 385
 
386
    ; close socket
387
    mov     eax, 53
388
    mov     ebx, 1
389
    mov     ecx, [socketNum]
485 heavyiron 390
    mcall
31 halyavin 391
 
392
    mov     [socketNum], dword 0xFFFF
393
 
394
    call    draw_window                     ; at first, draw the window
395
 
396
    ret
397
 
398
 
399
 
400
 
401
;   *********************************************
402
;   *******  WINDOW DEFINITIONS AND DRAW ********
403
;   *********************************************
404
 
405
 
406
; Pass in the IP address in edi
407
; row to display in [ya]
408
drawIP:
409
;    mov     edi,hostIP
410
    mov     ecx, edi
411
    add     ecx, 4
412
    mov     edx,[ya]
413
    add     edx, 97*65536
414
    mov     esi,0x00ffffff
415
    mov     ebx,3*65536
416
 
417
ipdisplay:
418
    mov     eax,47
419
    push    ecx
420
    movzx   ecx,byte [edi]
485 heavyiron 421
    mcall
31 halyavin 422
    pop     ecx
423
    add     edx,6*4*65536
424
    inc     edi
425
    cmp     edi,ecx
426
    jb      ipdisplay
427
    ret
428
 
429
 
430
drawDHMS:
431
 
432
    mov     eax,[edi]
433
    bswap   eax
434
 
435
    mov     esi,dhms
436
    mov     ecx,16
437
    mov     edi,text+40*4+12
438
    cmp     eax,0xffffffff
439
    jne     nforever
440
    mov     esi,forever
441
    cld
442
    rep     movsb
443
    ret
444
   nforever:
445
    cld
446
    rep     movsb
447
 
448
    mov     ecx,28
449
    xor     edx,edx
450
    mov     ebx,60
451
    div     ebx
452
    call    displayDHMS
453
    xor     edx,edx
454
    div     ebx
455
    call    displayDHMS
456
    xor     edx,edx
457
    mov     ebx,24
458
    div     ebx
459
    call    displayDHMS
460
    mov     edx,eax
461
    call    displayDHMS
462
 
463
    ret
464
 
465
 
466
displayDHMS:
467
 
468
    pusha
469
    mov     eax,47
470
    mov     ebx,3*65536
471
    mov     edx,ecx
472
    imul    edx,6
473
    shl     edx,16
474
    add     edx,1*65536+99
475
    mov     ecx,[esp+20]
476
    mov     esi,0xffffff
485 heavyiron 477
    mcall
31 halyavin 478
    popa
479
    sub     ecx,4
480
    ret
481
 
482
 
483
draw_window:
484
 
485
    mov     eax,12                    ; function 12:tell os about windowdraw
486
    mov     ebx,1                     ; 1, start of draw
485 heavyiron 487
    mcall
31 halyavin 488
                                      ; DRAW WINDOW
489
    mov     eax,0                     ; function 0 : define and draw window
490
    mov     ebx,100*65536+300         ; [x start] *65536 + [x size]
491
    mov     ecx,100*65536+156         ; [y start] *65536 + [y size]
485 heavyiron 492
    mov     edx,0x13224466            ; color of work area RRGGBB
493
    mov     edi,title                 ; WINDOW LABEL
494
    mcall
495
 
31 halyavin 496
    mov     eax,8                     ; Resolve
497
    mov     ebx,20*65536+90
498
    mov     ecx,127*65536+15
499
    mov     edx,3
500
    mov     esi,0x557799
485 heavyiron 501
    mcall
31 halyavin 502
 
503
    ; Pass in the IP address in edi
504
    ; row to display in [ya]
505
    mov     edi, dhcpClientIP
506
    mov     eax, 35
507
    mov     [ya], eax
508
    call    drawIP
509
    mov     edi, dhcpGateway
510
    mov     eax, 35 + 16
511
    mov     [ya], eax
512
    call    drawIP
513
    mov     edi, dhcpSubnet
514
    mov     eax, 35 + 32
515
    mov     [ya], eax
516
    call    drawIP
517
    mov     edi, dhcpDNSIP
518
    mov     eax, 35 + 48
519
    mov     [ya], eax
520
    call    drawIP
521
    mov     edi, dhcpLease
522
    call    drawDHMS
523
 
524
    ; Re-draw the screen text
525
    cld
485 heavyiron 526
    mov     eax,4
31 halyavin 527
    mov     ebx,25*65536+35           ; draw info text with function 4
528
    mov     ecx,0xffffff
529
    mov     edx,text
530
    mov     esi,40
531
newline:
485 heavyiron 532
    mcall
31 halyavin 533
    add     ebx,16
534
    add     edx,40
535
    cmp     [edx],byte 'x'
536
    jnz     newline
537
 
538
 
539
    mov     eax,12                    ; function 12:tell os about windowdraw
540
    mov     ebx,2                     ; 2, end of draw
485 heavyiron 541
    mcall
31 halyavin 542
 
543
    ret
544
 
545
 
546
 
547
; DATA AREA
548
 
549
ya              dd  0x0
550
 
551
text:
552
    db 'Client IP :    .   .   .                '
553
    db 'Gateway IP:    .   .   .                '
554
    db 'Subnet    :    .   .   .                '
555
    db 'DNS IP    :    .   .   .                '
556
    db 'Lease Time:    d   h   m   s            '
557
    db '                                        '
558
    db ' SEND REQUEST                           '
559
    db 'x <- END MARKER, DONT DELETE            '
560
 
561
 
562
dhms      db   '   d   h   m   s'
563
forever   db   'Forever         '
564
 
485 heavyiron 565
title   db   'DHCP Client Test',0
31 halyavin 566
 
567
dhcpMsgType:    db  0
568
dhcpLease:      dd  0
569
dhcpClientIP:   dd  0
570
dhcpServerIP:   dd  0
571
dhcpDNSIP:      dd  0
572
dhcpSubnet:     dd  0
573
dhcpGateway:    dd  0
574
 
575
dhcpMsgLen:     dd  0
576
socketNum:      dd  0xFFFF
577
dhcpMsg:
578
I_END:
579