Subversion Repositories Kolibri OS

Rev

Rev 551 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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.  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
  28.  
  29. include 'lang.inc'
  30. include 'macros.inc'
  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.  
  40. red:
  41.     call    draw_window                     ; at first, draw the window
  42.  
  43. still:
  44.     mov     eax,10                          ; wait here for event
  45.     mcall
  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
  57.     mcall
  58.     jmp     still
  59.  
  60. button:                         ; button
  61.     mov     eax,17              ; get id
  62.     mcall
  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]
  71.     mcall
  72.  
  73.     mov     eax,0xffffffff      ; close this program
  74.     mcall
  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
  120.     mcall
  121.     cmp     eax,2
  122.     jz      fbu
  123.     jmp     still
  124.  
  125. fbu:
  126.     mov     eax,2
  127.     mcall  ; get key
  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
  167.     mcall
  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
  175.     mcall
  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
  318.  mcall
  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]
  328.     mcall
  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
  338.     mcall
  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
  352.     mcall
  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]
  366.     mcall
  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]
  376.     mcall                ; read byte - block (high byte)
  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]
  391.     mcall                ; any more data?
  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]
  400.     mcall
  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
  487.     mcall
  488.     jmp     ctr001
  489.  
  490. ctr005:                         ; button
  491.     mov     eax,17              ; get id
  492.     mcall
  493.  
  494.     ; close socket
  495.     mov     eax, 53
  496.     mov     ebx, 1
  497.     mov     ecx, [socketNum]
  498.     mcall
  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
  552.     mcall
  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]
  557.     mov     edx,0x14224466            ; color of work area RRGGBB
  558.     mov     edi,title                 ; WINDOW LABEL;
  559.     mcall
  560.  
  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
  566.     mcall
  567.  
  568.     ;mov     eax,8
  569.     mov     ebx,270*65536+10
  570.     mov     ecx,34*65536+10
  571.     inc     edx
  572.     mcall
  573.  
  574.     ;mov     eax,8
  575.     mov     ebx,270*65536+10
  576.     mov     ecx,50*65536+10
  577.     inc     edx
  578.     mcall
  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
  604.     mov     eax,4
  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:
  610.     mcall
  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]
  631.     mcall
  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
  640.     mcall
  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
  668.     mcall
  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
  679.     mcall
  680.     mov   cl, 10
  681.     mov     eax,63
  682.     mov     ebx, 1
  683.     mcall
  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.  
  729.     if lang eq ru
  730.     db 'ˆ¬ï å®áâ   : xxxxxxxxxxxxxxx            '
  731.     db 'DNS á¥à¢¥à : xxx.xxx.xxx.xxx            '
  732.     db '                                        '
  733.     db '       ®«ãç¨âì  ¤à¥á                   '
  734.     db '                                        '
  735.     db '                                        '
  736.     db 'x <- END MARKER, DONT DELETE            '
  737.  
  738.     else
  739.     db 'Host name  : xxxxxxxxxxxxxxx            '
  740.     db 'DNS server : xxx.xxx.xxx.xxx            '
  741.     db '                                        '
  742.     db '     RESOLVE ADDRESS                    '
  743.     db '                                        '
  744.     db '                                        '
  745.     db 'x <- END MARKER, DONT DELETE            '
  746.     end if
  747.  
  748. if lang eq ru
  749. title    db   'DNS Š«¨¥­â',0
  750.  
  751. else
  752. title    db   'DNS Client',0
  753. end if
  754.  
  755.  
  756. prompt: dd 0
  757. promptlen: dd 0
  758.  
  759.  
  760. if lang eq ru
  761. p1:             db '†¤ã ª®¬ ­¤ë                '
  762. p1len:
  763.  
  764.  
  765. else
  766. p1:             db 'Waiting for Command        '
  767. p1len:
  768. end if
  769.  
  770. p4:             db 'IP Address:    .   .   .   '
  771. p4len:
  772.  
  773. p5:             db 'Resolving...               '
  774. p5len:
  775.  
  776.  
  777. dnsServer       db  '194.145.128.1              ' ; iolfree.ie DNS
  778. query           db  'WWW.MENUETOS.NET           '
  779.  
  780. hostIP:         dd 0
  781. dnsIP:          dd 0
  782. dnsMsgLen:      dd 0
  783. socketNum:      dd 0xFFFF
  784. dnsMsg:
  785. I_END:
  786.