DNS Identification.

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

DNS Identification.

Post by 01000101 »

Hey,
I FINALLY begin writing the non-filtering protocols into my TCP/IP stack and yesterday I implemented DHCP, ICMP, ARP, and IGMP. Now I need to get my OS to dish out a DNS name.

In the DHCP Request packet I sent the 'Fully-Qualified Domain Name' option with the variable of 'dins' to the DHCP server (router), and it ACK'd it, but yet when I type in the command prompt 'ping dins' it never translates to my local IP. Should I be using a partially qualified domain name instead as it is local and under the 'domain' of the router, or should it indeed be a fully qualified one.

Also, is there more to registering a local name than just providing it in the DHCP? I have been examining packets from my MS machine once it DHCPs and gets it's DNS name translated, but I'm not seeing anything useful.

Thanks.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

This may help http://www.freeos.com/articles/3956/
Also this

Code: Select all

;
;    DNS Domain name -> IP lookup
;
;    Compile with FASM for Menuet
;


; If you like, you camd change the DNS server default by changing the
; IP address in the dnsServer string.


; Enabling debugging puts the received response to the
; debug board
DEBUGGING_ENABLED           equ     1
DEBUGGING_DISABLED          equ     0
DEBUGGING_STATE             equ     DEBUGGING_DISABLED


use32
 org	0x0
 db	'MENUET01'    ; header
 dd	0x01	      ; header version
 dd	START	      ; entry point
 dd	I_END	      ; image size
 dd	I_END+0x10000 ; required memory
 dd	I_END+0x10000 ; esp
 dd	0x0 , 0x0     ; I_Param , I_Path

include 'lang.inc'
include '..\..\macros.inc'

START:                                      ; start of execution
    mov     eax,40                          ; Report events
    mov     ebx,10000111b                   ; Stack 8 + defaults
    int     0x40

    mov     dword [prompt], p1
    mov     dword [promptlen], p1len - p1   ; 'waiting for command'

red:
    call    draw_window                     ; at first, draw the window

still:
    mov     eax,10                          ; wait here for event
    mcall

    cmp     eax,1                           ; redraw request ?
    jz      red
    cmp     eax,2                           ; key in buffer ?
    jz      key
    cmp     eax,3                           ; button in buffer ?
    jz      button

    jmp     still
key:                            ; Keys are not valid at this part of the
    mov     eax,2               ; loop. Just read it and ignore
    mcall
    jmp     still

button:                         ; button
    mov     eax,17              ; get id
    mcall

    cmp     ah,1                ; button id=1 ?
    jnz     noclose

    ; close socket before exiting
    mov     eax, 53
    mov     ebx, 1
    mov     ecx, [socketNum]
    mcall

    mov     eax,0xffffffff      ; close this program
    mcall

noclose:
    cmp     ah,3                ; Resolve address?
    jnz     noresolve

    mov     dword [prompt], p5
    mov     dword [promptlen], p5len - p5   ; display 'Resolving'
    call    draw_window

    call    translateData       ; Convert domain & DNS IP address

    call    resolveDomain

    jmp     still


noresolve:
    cmp     ah,4
    jz      f1                  ; Enter domain name
    cmp     ah,5
    jz      f2                  ; enter DNS Server IP
    jmp     still


f1:
    mov     [addr],dword query
    mov     [ya],dword 35
    jmp     rk

f2:
    mov     [addr],dword dnsServer
    mov     [ya],dword 35+16

rk:
    mov     ecx,26
    mov     edi,[addr]
    mov     al,' '
    rep     stosb

    call    print_text

    mov     edi,[addr]

f11:
    mov     eax,10
    mcall
    cmp     eax,2
    jz      fbu
    jmp     still

fbu:
    mov     eax,2
    mcall  ; get key
    shr     eax,8
    cmp     eax,8
    jnz     nobs
    cmp     edi,[addr]
    jz      f11
    sub     edi,1
    mov     [edi],byte ' '
    call    print_text
    jmp     f11

nobs:
    cmp     eax,dword 31
    jbe     f11
    cmp     eax,dword 95
    jb      keyok
    sub     eax,32

keyok:
    mov     [edi],al

    call    print_text

    add     edi,1
    mov     esi,[addr]
    add     esi,26
    cmp     esi,edi
    jnz     f11

    jmp  still



print_text:
    mov     eax,13
    mov     ebx,103*65536+26*6
    mov     ecx,[ya]
    shl     ecx,16
    mov     cx,8
    mov     edx,0x224466
    mcall

    mov     eax,4
    mov     ebx,103*65536
    add     ebx,[ya]
    mov     ecx,0xffffff
    mov     edx,[addr]
    mov     esi,26
    mcall

    ret



;***************************************************************************
;   Function
;      translateData
;
;   Description
;      Coverts the domain name and DNS IP address typed in by the user into
;      a format suitable for the IP layer.
;
;    The ename, in query, is converted and stored in dnsMsg
;      The DNS ip, in dnsServer, is converted and stored in dnsIP
;
;***************************************************************************
translateData:

    ; first, get the IP address of the DNS server
    ; Then, build up the request string.

    xor     eax, eax
    mov     dh, 10
    mov     dl, al
    mov     [dnsIP], eax

    mov     esi, dnsServer
    mov     edi, dnsIP

    mov     ecx, 4

td003:
    lodsb
    sub     al, '0'
    add     dl, al
    lodsb
    cmp     al, '.'
    je      ipNext
    cmp     al, ' '
    je      ipNext
    mov     dh, al
    sub     dh, '0'
    mov     al, 10
    mul     dl
    add     al, dh
    mov     dl, al
    lodsb
    cmp     al, '.'
    je      ipNext
    cmp     al, ' '
    je      ipNext
    mov     dh, al
    sub     dh, '0'
    mov     al, 10
    mul     dl
    add     al, dh
    mov     dl, al
    lodsb

ipNext:
    mov     [edi], dl
    inc     edi
    mov     dl, 0
    loop    td003

    ; Build the request string


    mov     eax, 0x00010100
    mov     [dnsMsg], eax
    mov     eax, 0x00000100
    mov     [dnsMsg+4], eax
    mov     eax, 0x00000000
    mov     [dnsMsg+8], eax

    ; domain name goes in at dnsMsg+12
    mov     esi, dnsMsg + 12        ; location of label length
    mov     edi, dnsMsg + 13        ; label start
    mov     edx, query
    mov     ecx, 12                  ; total string length so far

td002:
    mov     [esi], byte 0
    inc     ecx

td0021:
    mov     al, [edx]
    cmp     al, ' '
    je      td001                   ; we have finished the string translation
    cmp     al, '.'                 ; we have finished the label
    je      td004

    inc     byte [esi]
    inc     ecx
    mov     [edi], al
    inc     edi
    inc     edx
    jmp     td0021

td004:
    mov     esi, edi
    inc     edi
    inc     edx
    jmp     td002



    ; write label len + label text

td001:
    mov     [edi], byte 0
    inc     ecx
    inc     edi
    mov     [edi], dword 0x01000100
    add     ecx, 4

    mov     [dnsMsgLen], ecx

    ret





;***************************************************************************
;   Function
;      resolveDomain
;
;   Description
;       Sends a question to the dns server
;       works out the IP address from the response from the DNS server
;
;***************************************************************************
resolveDomain:
    ; Get a free port number
 mov     ecx, 1000  ; local port starting at 1000
getlp:
 inc     ecx
 push ecx
 mov     eax, 53
 mov     ebx, 9
 mcall
 pop     ecx
 cmp     eax, 0   ; is this local port in use?
 jz  getlp      ; yes - so try next

    ; First, open socket
    mov     eax, 53
    mov     ebx, 0
    mov     edx, 53    ; remote port - dns
    mov     esi, [dnsIP]
    mcall

    mov     [socketNum], eax

    ; write to socket ( request DNS lookup )
    mov     eax, 53
    mov     ebx, 4
    mov     ecx, [socketNum]
    mov     edx, [dnsMsgLen]
    mov     esi, dnsMsg
    mcall

    ; Setup the DNS response buffer

    mov     eax, dnsMsg
    mov     [dnsMsgLen], eax

    ; now, we wait for
    ; UI redraw
    ; UI close
    ; or data from remote

ctr001:
    mov     eax,10                 ; wait here for event
    mcall

    cmp     eax,1                  ; redraw request ?
    je      ctr003
    cmp     eax,2                  ; key in buffer ?
    je      ctr004
    cmp     eax,3                  ; button in buffer ?
    je      ctr005


    ; Any data in the UDP receive buffer?
    mov     eax, 53
    mov     ebx, 2
    mov     ecx, [socketNum]
    mcall

    cmp     eax, 0
    je      ctr001

    ; we have data - this will be the response
ctr002:
    mov     eax, 53
    mov     ebx, 3
    mov     ecx, [socketNum]
    mcall                ; read byte - block (high byte)

    ; Store the data in the response buffer
    mov     eax, [dnsMsgLen]
    mov     [eax], bl
    inc     dword [dnsMsgLen]


if DEBUGGING_STATE = DEBUGGING_ENABLED
    call debug_print_rx_ip
end if

    mov     eax, 53
    mov     ebx, 2
    mov     ecx, [socketNum]
    mcall                ; any more data?

    cmp     eax, 0
    jne     ctr002              ; yes, so get it

    ; close socket
    mov     eax, 53
    mov     ebx, 1
    mov     ecx, [socketNum]
    mcall

    mov     [socketNum], dword 0xFFFF

    ; Now parse the message to get the host IP
    ; Man, this is complicated. It's described in
    ; RFC 1035

    ; 1) Validate that we have an answer with > 0 responses
    ; 2) Find the answer record with TYPE 0001 ( host IP )
    ; 3) Finally, copy the IP address to the display
    ; Note: The response is in dnsMsg
    ;       The end of the buffer is pointed to by [dnsMsgLen]

    ; Clear the IP address text
    mov     [hostIP], dword 0

    mov     esi, dnsMsg

    ; Is this a response to my question?
    mov     al, [esi+2]
    and     al, 0x80
    cmp     al, 0x80
    jne     ctr002a

    ; Were there any errors?
    mov     al, [esi+3]
    and     al, 0x0F
    cmp     al, 0x00
    jne     ctr002a

    ; Is there ( at least 1 ) answer?
    mov     ax, [esi+6]
    cmp     ax, 0x00
    je      ctr002a

    ; Header validated. Scan through and get my answer

    add     esi, 12             ; Skip to the question field

    ; Skip through the question field
    call    skipName
    add     esi, 4              ; skip past the questions qtype, qclass

ctr002z:
    ; Now at the answer. There may be several answers,
    ; find the right one ( TYPE = 0x0001 )
    call    skipName
    mov     ax, [esi]
    cmp     ax, 0x0100          ; Is this the IP address answer?
    jne     ctr002c

    ; Yes! Point esi to the first byte of the IP address
    add     esi, 10

    mov     eax, [esi]
    mov     [hostIP], eax
    jmp     ctr002a             ; And exit...


ctr002c:                        ; Skip through the answer, move to the next
    add     esi, 8
    movzx   eax, byte [esi+1]
    mov     ah, [esi]
    add     esi, eax
    add     esi, 2

    ; Have we reached the end of the msg?
    ; This is an error condition, should not happen
    cmp     esi, [dnsMsgLen]
    jl      ctr002z             ; Check next answer
    jmp     ctr002a             ; abort


ctr002a:
    mov     dword [prompt], p4  ; Display IP address
    mov     dword [promptlen], p4len - p4
    call    draw_window

    jmp     ctr001

ctr003:                         ; redraw
    call    draw_window
    jmp     ctr001

ctr004:                         ; key
    mov     eax,2               ; just read it and ignore
    mcall
    jmp     ctr001

ctr005:                         ; button
    mov     eax,17              ; get id
    mcall

    ; close socket
    mov     eax, 53
    mov     ebx, 1
    mov     ecx, [socketNum]
    mcall

    mov     [socketNum], dword 0xFFFF
    mov     [hostIP], dword 0

    mov     dword [prompt], p1
    mov     dword [promptlen], p1len - p1   ; 'waiting for command'

    call    draw_window                     ; at first, draw the window

    ret



;***************************************************************************
;   Function
;      skipName
;
;   Description
;       Increment esi to the first byte past the name field
;       Names may use compressed labels. Normally do.
;       RFC 1035 page 30 gives details
;
;***************************************************************************
skipName:
    mov     al, [esi]
    cmp     al, 0
    je      sn_exit
    and     al, 0xc0
    cmp     al, 0xc0
    je      sn001

    movzx   eax, byte [esi]
    inc     eax
    add     esi, eax
    jmp     skipName

sn001:
    add     esi, 2                          ; A pointer is always at the end
    ret

sn_exit:
    inc     esi
    ret


;   *********************************************
;   *******  WINDOW DEFINITIONS AND DRAW ********
;   *********************************************


draw_window:
    mov     eax,12                    ; function 12:tell os about windowdraw
    mov     ebx,1                     ; 1, start of draw
    mcall
                                      ; DRAW WINDOW
    mov     eax,0                     ; function 0 : define and draw window
    mov     ebx,100*65536+300         ; [x start] *65536 + [x size]
    mov     ecx,100*65536+140         ; [y start] *65536 + [y size]
    mov     edx,0x14224466            ; color of work area RRGGBB
    mov     edi,title                 ; WINDOW LABEL;
    mcall

    mov     eax,8                     ; Resolve
    mov     ebx,20*65536+190
    mov     ecx,79*65536+15
    mov     edx,3
    mov     esi,0x557799
    mcall

    ;mov     eax,8
    mov     ebx,270*65536+10
    mov     ecx,34*65536+10
    inc     edx
    mcall

    ;mov     eax,8
    mov     ebx,270*65536+10
    mov     ecx,50*65536+10
    inc     edx
    mcall

    ; Copy the file name to the screen buffer
    ; file name is same length as IP address, to
    ; make the math easier later.
    cld
    mov     esi,query
    mov     edi,text+13
    mov     ecx,26
    rep     movsb


    ; copy the IP address to the screen buffer
    mov     esi,dnsServer
    mov     edi,text+40+13
    mov     ecx,26
    rep     movsb

    ; copy the prompt to the screen buffer
    mov     esi,[prompt]
    mov     edi,text+200
    mov     ecx,[promptlen]
    rep     movsb

    ; Re-draw the screen text
    cld
    mov     eax,4
    mov     ebx,25*65536+35           ; draw info text with function 4
    mov     ecx,0xffffff
    mov     edx,text
    mov     esi,40
newline:
    mcall
    add     ebx,16
    add     edx,40
    cmp     [edx],byte 'x'
    jnz     newline


    ; Write the host IP, if we have one
    mov     eax, [hostIP]
    cmp     eax, 0
    je      dw001

    ; We have an IP address... display it
    mov     edi,hostIP
    mov     edx,97*65536+115
    mov     esi,0x00ffffff
    mov     ebx,3*65536

ipdisplay:
    mov     eax,47
    movzx   ecx,byte [edi]
    mcall
    add     edx,6*4*65536
    inc     edi
    cmp     edi,hostIP+4
    jb      ipdisplay

dw001:
    mov     eax,12                    ; function 12:tell os about windowdraw
    mov     ebx,2                     ; 2, end of draw
    mcall

    ret


if DEBUGGING_STATE = DEBUGGING_ENABLED
;****************************************************************************
;    Function
;       debug_print_string
;
;   Description
;       prints a string to the debug board
;
;       esi holds ptr to msg to display
;
;       Nothing preserved; I'm assuming a pusha/popa is done before calling
;
;****************************************************************************
debug_print_string:
    mov     cl, [esi]
    cmp     cl, 0
    jnz     dps_001
    ret

dps_001:
    mov     eax,63
    mov     ebx, 1
    push    esi
    mcall

    inc   word [ind]
    mov  ax, [ind]
    and ax, 0x1f
    cmp  ax, 0
    jne  ds1

    mov   cl, 13
    mov     eax,63
    mov     ebx, 1
    mcall
    mov   cl, 10
    mov     eax,63
    mov     ebx, 1
    mcall


ds1:
    pop     esi
    inc     esi
    jmp     debug_print_string


ind: dw 0
; This is used for translating hex to ASCII for display or output
hexchars db '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
IP_STR              db  'xx',0


debug_print_rx_ip:
    pusha
    mov     edi, IP_STR

    xor     eax, eax
    mov     al, bl
    shr     al, 4
    mov     ah, [eax + hexchars]
    mov     [edi], ah
    inc     edi

    xor     eax, eax
    mov     al, bl
    and     al, 0x0f
    mov     ah, [eax + hexchars]
    mov     [edi], ah
    mov     esi, IP_STR

    call    debug_print_string
    popa
    ret
end if


; DATA AREA

addr            dd  0x0
ya              dd  0x0

text:
    db 'Host name  : xxxxxxxxxxxxxxx            '
    db 'DNS server : xxx.xxx.xxx.xxx            '
    db '                                        '
    db '     RESOLVE ADDRESS                    '
    db '                                        '
    db '                                        '
    db 'x <- END MARKER, DONT DELETE            '


title    db   'DNS Client',0


prompt: dd 0
promptlen: dd 0


p1:             db 'Waiting for Command        '
p1len:

p4:             db 'IP Address:    .   .   .   '
p4len:

p5:             db 'Resolving...               '
p5len:


dnsServer       db  '194.145.128.1              ' ; iolfree.ie DNS
query           db  'WWW.MENUETOS.NET           '

hostIP:         dd 0
dnsIP:          dd 0
dnsMsgLen:      dd 0
socketNum:      dd 0xFFFF
dnsMsg:
I_END:

User avatar
01000101
Member
Member
Posts: 1599
Joined: Fri Jun 22, 2007 12:47 pm
Contact:

Post by 01000101 »

I'm actually not wishing to implement a DNS resolution function in my OS, but rather notify the real DNS server (router) of my OS's domain name so that it can dish it out to any other computers that request it.
Post Reply