Subversion Repositories Kolibri OS

Rev

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