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