Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
31 halyavin 1
;
2
;    DNS Domain name -> IP lookup
3
;
4
;    Compile with FASM for Menuet
5
;
6
 
7
 
8
; If you like, you camd change the DNS server default by changing the
9
; IP address in the dnsServer string.
10
 
11
 
12
; Enabling debugging puts the received response to the
13
; debug board
14
DEBUGGING_ENABLED           equ     1
15
DEBUGGING_DISABLED          equ     0
16
DEBUGGING_STATE             equ     DEBUGGING_DISABLED
17
 
18
 
19
use32
485 heavyiron 20
 org	0x0
21
 db	'MENUET01'    ; header
22
 dd	0x01	      ; header version
23
 dd	START	      ; entry point
24
 dd	I_END	      ; image size
25
 dd	I_END+0x10000 ; required memory
26
 dd	I_END+0x10000 ; esp
27
 dd	0x0 , 0x0     ; I_Param , I_Path
31 halyavin 28
 
29
include 'lang.inc'
485 heavyiron 30
include '..\..\..\macros.inc'
31 halyavin 31
 
32
START:                                      ; start of execution
33
    mov     eax,40                          ; Report events
34
    mov     ebx,10000111b                   ; Stack 8 + defaults
35
    int     0x40
36
 
37
    mov     dword [prompt], p1
38
    mov     dword [promptlen], p1len - p1   ; 'waiting for command'
39
 
485 heavyiron 40
red:
31 halyavin 41
    call    draw_window                     ; at first, draw the window
42
 
43
still:
44
    mov     eax,10                          ; wait here for event
485 heavyiron 45
    mcall
31 halyavin 46
 
47
    cmp     eax,1                           ; redraw request ?
48
    jz      red
49
    cmp     eax,2                           ; key in buffer ?
50
    jz      key
51
    cmp     eax,3                           ; button in buffer ?
52
    jz      button
53
 
54
    jmp     still
55
key:                            ; Keys are not valid at this part of the
56
    mov     eax,2               ; loop. Just read it and ignore
485 heavyiron 57
    mcall
31 halyavin 58
    jmp     still
59
 
60
button:                         ; button
61
    mov     eax,17              ; get id
485 heavyiron 62
    mcall
31 halyavin 63
 
64
    cmp     ah,1                ; button id=1 ?
65
    jnz     noclose
66
 
67
    ; close socket before exiting
68
    mov     eax, 53
69
    mov     ebx, 1
70
    mov     ecx, [socketNum]
485 heavyiron 71
    mcall
31 halyavin 72
 
73
    mov     eax,0xffffffff      ; close this program
485 heavyiron 74
    mcall
31 halyavin 75
 
76
noclose:
77
    cmp     ah,3                ; Resolve address?
78
    jnz     noresolve
79
 
80
    mov     dword [prompt], p5
81
    mov     dword [promptlen], p5len - p5   ; display 'Resolving'
82
    call    draw_window
83
 
84
    call    translateData       ; Convert domain & DNS IP address
85
 
86
    call    resolveDomain
87
 
88
    jmp     still
89
 
90
 
91
noresolve:
92
    cmp     ah,4
93
    jz      f1                  ; Enter domain name
94
    cmp     ah,5
95
    jz      f2                  ; enter DNS Server IP
96
    jmp     still
97
 
98
 
99
f1:
100
    mov     [addr],dword query
101
    mov     [ya],dword 35
102
    jmp     rk
103
 
104
f2:
105
    mov     [addr],dword dnsServer
106
    mov     [ya],dword 35+16
107
 
108
rk:
109
    mov     ecx,26
110
    mov     edi,[addr]
111
    mov     al,' '
112
    rep     stosb
113
 
114
    call    print_text
115
 
116
    mov     edi,[addr]
117
 
118
f11:
119
    mov     eax,10
485 heavyiron 120
    mcall
31 halyavin 121
    cmp     eax,2
122
    jz      fbu
123
    jmp     still
124
 
125
fbu:
126
    mov     eax,2
485 heavyiron 127
    mcall  ; get key
31 halyavin 128
    shr     eax,8
129
    cmp     eax,8
130
    jnz     nobs
131
    cmp     edi,[addr]
132
    jz      f11
133
    sub     edi,1
134
    mov     [edi],byte ' '
135
    call    print_text
136
    jmp     f11
137
 
138
nobs:
139
    cmp     eax,dword 31
140
    jbe     f11
141
    cmp     eax,dword 95
142
    jb      keyok
143
    sub     eax,32
144
 
145
keyok:
146
    mov     [edi],al
147
 
148
    call    print_text
149
 
150
    add     edi,1
151
    mov     esi,[addr]
152
    add     esi,26
153
    cmp     esi,edi
154
    jnz     f11
155
 
156
    jmp  still
157
 
158
 
159
 
160
print_text:
161
    mov     eax,13
162
    mov     ebx,103*65536+26*6
163
    mov     ecx,[ya]
164
    shl     ecx,16
165
    mov     cx,8
166
    mov     edx,0x224466
485 heavyiron 167
    mcall
31 halyavin 168
 
169
    mov     eax,4
170
    mov     ebx,103*65536
171
    add     ebx,[ya]
172
    mov     ecx,0xffffff
173
    mov     edx,[addr]
174
    mov     esi,26
485 heavyiron 175
    mcall
31 halyavin 176
 
177
    ret
178
 
179
 
180
 
181
;***************************************************************************
182
;   Function
183
;      translateData
184
;
185
;   Description
186
;      Coverts the domain name and DNS IP address typed in by the user into
187
;      a format suitable for the IP layer.
188
;
189
;    The ename, in query, is converted and stored in dnsMsg
190
;      The DNS ip, in dnsServer, is converted and stored in dnsIP
191
;
192
;***************************************************************************
193
translateData:
194
 
195
    ; first, get the IP address of the DNS server
196
    ; Then, build up the request string.
197
 
198
    xor     eax, eax
199
    mov     dh, 10
200
    mov     dl, al
201
    mov     [dnsIP], eax
202
 
203
    mov     esi, dnsServer
204
    mov     edi, dnsIP
205
 
206
    mov     ecx, 4
207
 
208
td003:
209
    lodsb
210
    sub     al, '0'
211
    add     dl, al
212
    lodsb
213
    cmp     al, '.'
214
    je      ipNext
215
    cmp     al, ' '
216
    je      ipNext
217
    mov     dh, al
218
    sub     dh, '0'
219
    mov     al, 10
220
    mul     dl
221
    add     al, dh
222
    mov     dl, al
223
    lodsb
224
    cmp     al, '.'
225
    je      ipNext
226
    cmp     al, ' '
227
    je      ipNext
228
    mov     dh, al
229
    sub     dh, '0'
230
    mov     al, 10
231
    mul     dl
232
    add     al, dh
233
    mov     dl, al
234
    lodsb
235
 
236
ipNext:
237
    mov     [edi], dl
238
    inc     edi
239
    mov     dl, 0
240
    loop    td003
241
 
242
    ; Build the request string
243
 
244
 
245
    mov     eax, 0x00010100
246
    mov     [dnsMsg], eax
247
    mov     eax, 0x00000100
248
    mov     [dnsMsg+4], eax
249
    mov     eax, 0x00000000
250
    mov     [dnsMsg+8], eax
251
 
252
    ; domain name goes in at dnsMsg+12
253
    mov     esi, dnsMsg + 12        ; location of label length
254
    mov     edi, dnsMsg + 13        ; label start
255
    mov     edx, query
256
    mov     ecx, 12                  ; total string length so far
257
 
258
td002:
259
    mov     [esi], byte 0
260
    inc     ecx
261
 
262
td0021:
263
    mov     al, [edx]
264
    cmp     al, ' '
265
    je      td001                   ; we have finished the string translation
266
    cmp     al, '.'                 ; we have finished the label
267
    je      td004
268
 
269
    inc     byte [esi]
270
    inc     ecx
271
    mov     [edi], al
272
    inc     edi
273
    inc     edx
274
    jmp     td0021
275
 
276
td004:
277
    mov     esi, edi
278
    inc     edi
279
    inc     edx
280
    jmp     td002
281
 
282
 
283
 
284
    ; write label len + label text
285
 
286
td001:
287
    mov     [edi], byte 0
288
    inc     ecx
289
    inc     edi
290
    mov     [edi], dword 0x01000100
291
    add     ecx, 4
292
 
293
    mov     [dnsMsgLen], ecx
294
 
295
    ret
296
 
297
 
298
 
299
 
300
 
301
;***************************************************************************
302
;   Function
303
;      resolveDomain
304
;
305
;   Description
306
;       Sends a question to the dns server
307
;       works out the IP address from the response from the DNS server
308
;
309
;***************************************************************************
310
resolveDomain:
311
    ; Get a free port number
312
 mov     ecx, 1000  ; local port starting at 1000
313
getlp:
314
 inc     ecx
315
 push ecx
316
 mov     eax, 53
317
 mov     ebx, 9
485 heavyiron 318
 mcall
31 halyavin 319
 pop     ecx
320
 cmp     eax, 0   ; is this local port in use?
321
 jz  getlp      ; yes - so try next
322
 
323
    ; First, open socket
324
    mov     eax, 53
325
    mov     ebx, 0
326
    mov     edx, 53    ; remote port - dns
327
    mov     esi, [dnsIP]
485 heavyiron 328
    mcall
31 halyavin 329
 
330
    mov     [socketNum], eax
331
 
332
    ; write to socket ( request DNS lookup )
333
    mov     eax, 53
334
    mov     ebx, 4
335
    mov     ecx, [socketNum]
336
    mov     edx, [dnsMsgLen]
337
    mov     esi, dnsMsg
485 heavyiron 338
    mcall
31 halyavin 339
 
340
    ; Setup the DNS response buffer
341
 
342
    mov     eax, dnsMsg
343
    mov     [dnsMsgLen], eax
344
 
345
    ; now, we wait for
346
    ; UI redraw
347
    ; UI close
348
    ; or data from remote
349
 
350
ctr001:
351
    mov     eax,10                 ; wait here for event
485 heavyiron 352
    mcall
31 halyavin 353
 
354
    cmp     eax,1                  ; redraw request ?
355
    je      ctr003
356
    cmp     eax,2                  ; key in buffer ?
357
    je      ctr004
358
    cmp     eax,3                  ; button in buffer ?
359
    je      ctr005
360
 
361
 
362
    ; Any data in the UDP receive buffer?
363
    mov     eax, 53
364
    mov     ebx, 2
365
    mov     ecx, [socketNum]
485 heavyiron 366
    mcall
31 halyavin 367
 
368
    cmp     eax, 0
369
    je      ctr001
370
 
371
    ; we have data - this will be the response
372
ctr002:
373
    mov     eax, 53
374
    mov     ebx, 3
375
    mov     ecx, [socketNum]
485 heavyiron 376
    mcall                ; read byte - block (high byte)
31 halyavin 377
 
378
    ; Store the data in the response buffer
379
    mov     eax, [dnsMsgLen]
380
    mov     [eax], bl
381
    inc     dword [dnsMsgLen]
382
 
383
 
384
if DEBUGGING_STATE = DEBUGGING_ENABLED
385
    call debug_print_rx_ip
386
end if
387
 
388
    mov     eax, 53
389
    mov     ebx, 2
390
    mov     ecx, [socketNum]
485 heavyiron 391
    mcall                ; any more data?
31 halyavin 392
 
393
    cmp     eax, 0
394
    jne     ctr002              ; yes, so get it
395
 
396
    ; close socket
397
    mov     eax, 53
398
    mov     ebx, 1
399
    mov     ecx, [socketNum]
485 heavyiron 400
    mcall
31 halyavin 401
 
402
    mov     [socketNum], dword 0xFFFF
403
 
404
    ; Now parse the message to get the host IP
405
    ; Man, this is complicated. It's described in
406
    ; RFC 1035
407
 
408
    ; 1) Validate that we have an answer with > 0 responses
409
    ; 2) Find the answer record with TYPE 0001 ( host IP )
410
    ; 3) Finally, copy the IP address to the display
411
    ; Note: The response is in dnsMsg
412
    ;       The end of the buffer is pointed to by [dnsMsgLen]
413
 
414
    ; Clear the IP address text
415
    mov     [hostIP], dword 0
416
 
417
    mov     esi, dnsMsg
418
 
419
    ; Is this a response to my question?
420
    mov     al, [esi+2]
421
    and     al, 0x80
422
    cmp     al, 0x80
423
    jne     ctr002a
424
 
425
    ; Were there any errors?
426
    mov     al, [esi+3]
427
    and     al, 0x0F
428
    cmp     al, 0x00
429
    jne     ctr002a
430
 
431
    ; Is there ( at least 1 ) answer?
432
    mov     ax, [esi+6]
433
    cmp     ax, 0x00
434
    je      ctr002a
435
 
436
    ; Header validated. Scan through and get my answer
437
 
438
    add     esi, 12             ; Skip to the question field
439
 
440
    ; Skip through the question field
441
    call    skipName
442
    add     esi, 4              ; skip past the questions qtype, qclass
443
 
444
ctr002z:
445
    ; Now at the answer. There may be several answers,
446
    ; find the right one ( TYPE = 0x0001 )
447
    call    skipName
448
    mov     ax, [esi]
449
    cmp     ax, 0x0100          ; Is this the IP address answer?
450
    jne     ctr002c
451
 
452
    ; Yes! Point esi to the first byte of the IP address
453
    add     esi, 10
454
 
455
    mov     eax, [esi]
456
    mov     [hostIP], eax
457
    jmp     ctr002a             ; And exit...
458
 
459
 
460
ctr002c:                        ; Skip through the answer, move to the next
461
    add     esi, 8
462
    movzx   eax, byte [esi+1]
463
    mov     ah, [esi]
464
    add     esi, eax
465
    add     esi, 2
466
 
467
    ; Have we reached the end of the msg?
468
    ; This is an error condition, should not happen
469
    cmp     esi, [dnsMsgLen]
470
    jl      ctr002z             ; Check next answer
471
    jmp     ctr002a             ; abort
472
 
473
 
474
ctr002a:
475
    mov     dword [prompt], p4  ; Display IP address
476
    mov     dword [promptlen], p4len - p4
477
    call    draw_window
478
 
479
    jmp     ctr001
480
 
481
ctr003:                         ; redraw
482
    call    draw_window
483
    jmp     ctr001
484
 
485
ctr004:                         ; key
486
    mov     eax,2               ; just read it and ignore
485 heavyiron 487
    mcall
31 halyavin 488
    jmp     ctr001
489
 
490
ctr005:                         ; button
491
    mov     eax,17              ; get id
485 heavyiron 492
    mcall
31 halyavin 493
 
494
    ; close socket
495
    mov     eax, 53
496
    mov     ebx, 1
497
    mov     ecx, [socketNum]
485 heavyiron 498
    mcall
31 halyavin 499
 
500
    mov     [socketNum], dword 0xFFFF
501
    mov     [hostIP], dword 0
502
 
503
    mov     dword [prompt], p1
504
    mov     dword [promptlen], p1len - p1   ; 'waiting for command'
505
 
506
    call    draw_window                     ; at first, draw the window
507
 
508
    ret
509
 
510
 
511
 
512
;***************************************************************************
513
;   Function
514
;      skipName
515
;
516
;   Description
517
;       Increment esi to the first byte past the name field
518
;       Names may use compressed labels. Normally do.
519
;       RFC 1035 page 30 gives details
520
;
521
;***************************************************************************
522
skipName:
523
    mov     al, [esi]
524
    cmp     al, 0
525
    je      sn_exit
526
    and     al, 0xc0
527
    cmp     al, 0xc0
528
    je      sn001
529
 
530
    movzx   eax, byte [esi]
531
    inc     eax
532
    add     esi, eax
533
    jmp     skipName
534
 
535
sn001:
536
    add     esi, 2                          ; A pointer is always at the end
537
    ret
538
 
539
sn_exit:
540
    inc     esi
541
    ret
542
 
543
 
544
;   *********************************************
545
;   *******  WINDOW DEFINITIONS AND DRAW ********
546
;   *********************************************
547
 
548
 
549
draw_window:
550
    mov     eax,12                    ; function 12:tell os about windowdraw
551
    mov     ebx,1                     ; 1, start of draw
485 heavyiron 552
    mcall
31 halyavin 553
                                      ; DRAW WINDOW
554
    mov     eax,0                     ; function 0 : define and draw window
555
    mov     ebx,100*65536+300         ; [x start] *65536 + [x size]
556
    mov     ecx,100*65536+140         ; [y start] *65536 + [y size]
551 spraid 557
    mov     edx,0x14224466            ; color of work area RRGGBB
485 heavyiron 558
    mov     edi,title                 ; WINDOW LABEL;
559
    mcall
560
 
31 halyavin 561
    mov     eax,8                     ; Resolve
562
    mov     ebx,20*65536+190
563
    mov     ecx,79*65536+15
564
    mov     edx,3
565
    mov     esi,0x557799
485 heavyiron 566
    mcall
31 halyavin 567
 
485 heavyiron 568
    ;mov     eax,8
31 halyavin 569
    mov     ebx,270*65536+10
570
    mov     ecx,34*65536+10
485 heavyiron 571
    inc     edx
572
    mcall
31 halyavin 573
 
485 heavyiron 574
    ;mov     eax,8
31 halyavin 575
    mov     ebx,270*65536+10
576
    mov     ecx,50*65536+10
485 heavyiron 577
    inc     edx
578
    mcall
31 halyavin 579
 
580
    ; Copy the file name to the screen buffer
581
    ; file name is same length as IP address, to
582
    ; make the math easier later.
583
    cld
584
    mov     esi,query
585
    mov     edi,text+13
586
    mov     ecx,26
587
    rep     movsb
588
 
589
 
590
    ; copy the IP address to the screen buffer
591
    mov     esi,dnsServer
592
    mov     edi,text+40+13
593
    mov     ecx,26
594
    rep     movsb
595
 
596
    ; copy the prompt to the screen buffer
597
    mov     esi,[prompt]
598
    mov     edi,text+200
599
    mov     ecx,[promptlen]
600
    rep     movsb
601
 
602
    ; Re-draw the screen text
603
    cld
485 heavyiron 604
    mov     eax,4
31 halyavin 605
    mov     ebx,25*65536+35           ; draw info text with function 4
606
    mov     ecx,0xffffff
607
    mov     edx,text
608
    mov     esi,40
609
newline:
485 heavyiron 610
    mcall
31 halyavin 611
    add     ebx,16
612
    add     edx,40
613
    cmp     [edx],byte 'x'
614
    jnz     newline
615
 
616
 
617
    ; Write the host IP, if we have one
618
    mov     eax, [hostIP]
619
    cmp     eax, 0
620
    je      dw001
621
 
622
    ; We have an IP address... display it
623
    mov     edi,hostIP
624
    mov     edx,97*65536+115
625
    mov     esi,0x00ffffff
626
    mov     ebx,3*65536
627
 
628
ipdisplay:
629
    mov     eax,47
630
    movzx   ecx,byte [edi]
485 heavyiron 631
    mcall
31 halyavin 632
    add     edx,6*4*65536
633
    inc     edi
634
    cmp     edi,hostIP+4
635
    jb      ipdisplay
636
 
637
dw001:
638
    mov     eax,12                    ; function 12:tell os about windowdraw
639
    mov     ebx,2                     ; 2, end of draw
485 heavyiron 640
    mcall
31 halyavin 641
 
642
    ret
643
 
644
 
645
if DEBUGGING_STATE = DEBUGGING_ENABLED
646
;****************************************************************************
647
;    Function
648
;       debug_print_string
649
;
650
;   Description
651
;       prints a string to the debug board
652
;
653
;       esi holds ptr to msg to display
654
;
655
;       Nothing preserved; I'm assuming a pusha/popa is done before calling
656
;
657
;****************************************************************************
658
debug_print_string:
659
    mov     cl, [esi]
660
    cmp     cl, 0
661
    jnz     dps_001
662
    ret
663
 
664
dps_001:
665
    mov     eax,63
666
    mov     ebx, 1
667
    push    esi
485 heavyiron 668
    mcall
31 halyavin 669
 
670
    inc   word [ind]
671
    mov  ax, [ind]
672
    and ax, 0x1f
673
    cmp  ax, 0
674
    jne  ds1
675
 
676
    mov   cl, 13
677
    mov     eax,63
678
    mov     ebx, 1
485 heavyiron 679
    mcall
31 halyavin 680
    mov   cl, 10
681
    mov     eax,63
682
    mov     ebx, 1
485 heavyiron 683
    mcall
31 halyavin 684
 
685
 
686
ds1:
687
    pop     esi
688
    inc     esi
689
    jmp     debug_print_string
690
 
691
 
692
ind: dw 0
693
; This is used for translating hex to ASCII for display or output
694
hexchars db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
695
IP_STR              db  'xx',0
696
 
697
 
698
debug_print_rx_ip:
699
    pusha
700
    mov     edi, IP_STR
701
 
702
    xor     eax, eax
703
    mov     al, bl
704
    shr     al, 4
705
    mov     ah, [eax + hexchars]
706
    mov     [edi], ah
707
    inc     edi
708
 
709
    xor     eax, eax
710
    mov     al, bl
711
    and     al, 0x0f
712
    mov     ah, [eax + hexchars]
713
    mov     [edi], ah
714
    mov     esi, IP_STR
715
 
716
    call    debug_print_string
717
    popa
718
    ret
719
end if
720
 
721
 
722
; DATA AREA
723
 
724
addr            dd  0x0
725
ya              dd  0x0
726
 
727
text:
728
    db 'Host name  : xxxxxxxxxxxxxxx            '
729
    db 'DNS server : xxx.xxx.xxx.xxx            '
730
    db '                                        '
731
    db '     RESOLVE ADDRESS                    '
732
    db '                                        '
733
    db '                                        '
734
    db 'x <- END MARKER, DONT DELETE            '
735
 
736
 
485 heavyiron 737
title    db   'DNS Client',0
31 halyavin 738
 
739
 
740
prompt: dd 0
741
promptlen: dd 0
742
 
743
 
744
p1:             db 'Waiting for Command        '
745
p1len:
746
 
747
p4:             db 'IP Address:    .   .   .   '
748
p4len:
749
 
750
p5:             db 'Resolving...               '
751
p5len:
752
 
753
 
754
dnsServer       db  '194.145.128.1              ' ; iolfree.ie DNS
485 heavyiron 755
query           db  'WWW.MENUETOS.NET           '
31 halyavin 756
 
757
hostIP:         dd 0
758
dnsIP:          dd 0
759
dnsMsgLen:      dd 0
760
socketNum:      dd 0xFFFF
761
dnsMsg:
762
I_END: