Subversion Repositories Kolibri OS

Rev

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.  
  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:
  781.