Subversion Repositories Kolibri OS

Rev

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

  1. ;
  2. ;    DHCP Client
  3. ;
  4. ;    Compile with FASM for Menuet
  5. ;
  6.  
  7. include 'lang.inc'
  8. include 'macros.inc'
  9.  
  10. use32
  11.  
  12.                 org     0x0
  13.  
  14.                 db      'MENUET00'              ; 8 byte id
  15.                 dd      38                      ; required os
  16.                 dd      START                   ; program start
  17.                 dd      I_END                   ; program image size
  18.                 dd      0x100000                ; required amount of memory
  19.                 dd      0x00000000              ; reserved=no extended header
  20.  
  21.  
  22. START:                                      ; start of execution
  23.     mov     eax,40                          ; Report events
  24.     mov     ebx,10000111b                   ; Stack 8 + defaults
  25.     int     0x40
  26.  
  27.     call    draw_window                     ; at first, draw the window
  28.  
  29. still:
  30.     mov     eax,10                          ; wait here for event
  31.     int     0x40
  32.  
  33.     cmp     eax,1                           ; redraw request ?
  34.     jz      red
  35.     cmp     eax,2                           ; key in buffer ?
  36.     jz      key
  37.     cmp     eax,3                           ; button in buffer ?
  38.     jz      button
  39.  
  40.     jmp     still
  41.  
  42. red:                            ; redraw
  43.     call    draw_window
  44.     jmp     still
  45.  
  46. key:                            ; Keys are not valid at this part of the
  47.     mov     eax,2               ; loop. Just read it and ignore
  48.     int     0x40
  49.     jmp     still
  50.  
  51. button:                         ; button
  52.     mov     eax,17              ; get id
  53.     int     0x40
  54.  
  55.     cmp     ah,1                ; button id=1 ?
  56.     jnz     noclose
  57.  
  58.     ; close socket before exiting
  59.     mov     eax, 53
  60.     mov     ebx, 1
  61.     mov     ecx, [socketNum]
  62.     int     0x40
  63.  
  64.     mov     eax,0xffffffff      ; close this program
  65.     int     0x40
  66.  
  67. noclose:
  68.     cmp     ah,3                ; Resolve address?
  69.     jnz     still
  70.  
  71.     call    draw_window
  72.  
  73.     call    contactDHCPServer
  74.  
  75.     jmp     still
  76.  
  77.  
  78. ;***************************************************************************
  79. ;   Function
  80. ;      parseResponse
  81. ;
  82. ;   Description
  83. ;      extracts the fields ( client IP address and options ) from
  84. ;      a DHCP response
  85. ;      The values go into
  86. ;       dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP,
  87. ;       dhcpDNSIP, dhcpSubnet
  88. ;      The message is stored in dhcpMsg
  89. ;
  90. ;***************************************************************************
  91. parseResponse:
  92.     mov     edx, dhcpMsg
  93.  
  94.     mov     eax, [edx+16]
  95.     mov     [dhcpClientIP], eax
  96.  
  97.     ; Scan options
  98.  
  99.     add     edx, 240        ; Point to first option
  100.  
  101. pr001:
  102.     ; Get option id
  103.     mov     al, [edx]
  104.     cmp     al, 0xff        ; End of options?
  105.     je      pr_exit
  106.  
  107.     cmp     al, 53          ; Msg type is a single byte option
  108.     jne     pr002
  109.  
  110.     mov     al, [edx+2]
  111.     mov     [dhcpMsgType], al
  112.     add     edx, 3
  113.     jmp     pr001           ; Get next option
  114.  
  115. pr002:
  116.     ; All other (accepted) options are 4 bytes in length
  117.     inc     edx
  118.     movzx   ecx, byte [edx]
  119.     inc     edx             ; point to data
  120.  
  121.     cmp     al, 54          ; server id
  122.     jne     pr0021
  123.     mov     eax, [edx]      ; All options are 4 bytes, so get it
  124.     mov     [dhcpServerIP], eax
  125.     jmp     pr003
  126.  
  127. pr0021:
  128.     cmp     al, 51          ; lease
  129.     jne     pr0022
  130.     mov     eax, [edx]      ; All options are 4 bytes, so get it
  131.     mov     [dhcpLease], eax
  132.     jmp     pr003
  133.  
  134. pr0022:
  135.     cmp     al, 1           ; subnet mask
  136.     jne     pr0023
  137.     mov     eax, [edx]      ; All options are 4 bytes, so get it
  138.     mov     [dhcpSubnet], eax
  139.     jmp     pr003
  140.  
  141. pr0023:
  142.     cmp     al, 6           ; dns ip
  143.     jne     pr0024
  144.     mov     eax, [edx]      ; All options are 4 bytes, so get it
  145.     mov     [dhcpDNSIP], eax
  146.  
  147. pr0024:
  148.     cmp     al, 3           ; gateway ip
  149.     jne     pr003
  150.     mov     eax, [edx]      ; All options are 4 bytes, so get it
  151.     mov     [dhcpGateway], eax
  152.  
  153. pr003:
  154.     add     edx, ecx
  155.     jmp     pr001
  156.  
  157. pr_exit:
  158.     ret
  159.  
  160.  
  161. ;***************************************************************************
  162. ;   Function
  163. ;      buildRequest
  164. ;
  165. ;   Description
  166. ;      Creates a DHCP request packet.
  167. ;
  168. ;***************************************************************************
  169. buildRequest:
  170.     ; Clear dhcpMsg to all zeros
  171.     xor     eax,eax
  172.     mov     edi,dhcpMsg
  173.     mov     ecx,512
  174.     cld
  175.     rep     stosb
  176.  
  177.     mov     edx, dhcpMsg
  178.  
  179.     mov     [edx], byte 0x01                ; Boot request
  180.     mov     [edx+1], byte 0x01              ; Ethernet
  181.     mov     [edx+2], byte 0x06              ; Ethernet h/w len
  182.     mov     [edx+4], dword 0x11223344       ; xid
  183.     mov     [edx+10], byte 0x80             ; broadcast flag set
  184.     mov     [edx+236], dword 0x63538263     ; magic number
  185.  
  186.     ; option DHCP msg type
  187.     mov     [edx+240], word 0x0135
  188.     mov     al, [dhcpMsgType]
  189.     mov     [edx+240+2], al
  190.  
  191.     ; option Lease time = infinity
  192.     mov     [edx+240+3], word 0x0433
  193.     mov     eax, [dhcpLease]
  194.     mov     [edx+240+5], eax
  195.  
  196.     ; option requested IP address
  197.     mov     [edx+240+9], word 0x0432
  198.     mov     eax, [dhcpClientIP]
  199.     mov     [edx+240+11], eax
  200.  
  201.     ; option request list
  202.     mov     [edx+240+15], word 0x0437
  203.     mov     [edx+240+17], dword 0x0f060301
  204.  
  205.     ; Check which msg we are sending
  206.     cmp     [dhcpMsgType], byte 0x01
  207.     jne     br001
  208.  
  209.     ; "Discover" options
  210.     ; end of options marker
  211.     mov     [edx+240+21], byte 0xff
  212.  
  213.     mov     [dhcpMsgLen], dword 262
  214.     jmp     br_exit
  215.  
  216. br001:
  217.     ; "Request" options
  218.  
  219.     ; server IP
  220.     mov     [edx+240+21], word 0x0436
  221.     mov     eax, [dhcpServerIP]
  222.     mov     [edx+240+23], eax
  223.  
  224.     ; end of options marker
  225.     mov     [edx+240+27], byte 0xff
  226.  
  227.     mov     [dhcpMsgLen], dword 268
  228.  
  229. br_exit:
  230.     ret
  231.  
  232.  
  233.  
  234. ;***************************************************************************
  235. ;   Function
  236. ;      contactDHCPServer
  237. ;
  238. ;   Description
  239. ;       negotiates settings with a DHCP server
  240. ;
  241. ;***************************************************************************
  242. contactDHCPServer:
  243.     ; First, open socket
  244.     mov     eax, 53
  245.     mov     ebx, 0
  246.     mov     ecx, 68                 ; local port dhcp client
  247.     mov     edx, 67                 ; remote port - dhcp server
  248.     mov     esi, 0xffffffff         ; broadcast
  249.     int     0x40
  250.  
  251.     mov     [socketNum], eax
  252.  
  253.     ; Setup the first msg we will send
  254.     mov     [dhcpMsgType], byte 0x01 ; DHCP discover
  255.     mov     [dhcpLease], dword 0xffffffff
  256.     mov     [dhcpClientIP], dword 0
  257.     mov     [dhcpServerIP], dword 0
  258.  
  259.     call    buildRequest
  260.  
  261. ctr000:
  262.     ; write to socket ( send broadcast request )
  263.     mov     eax, 53
  264.     mov     ebx, 4
  265.     mov     ecx, [socketNum]
  266.     mov     edx, [dhcpMsgLen]
  267.     mov     esi, dhcpMsg
  268.     int     0x40
  269.  
  270.     ; Setup the DHCP buffer to receive response
  271.  
  272.     mov     eax, dhcpMsg
  273.     mov     [dhcpMsgLen], eax      ; Used as a pointer to the data
  274.  
  275.     ; now, we wait for
  276.     ; UI redraw
  277.     ; UI close
  278.     ; or data from remote
  279.  
  280. ctr001:
  281.     mov     eax,10                 ; wait here for event
  282.     int     0x40
  283.  
  284.     cmp     eax,1                  ; redraw request ?
  285.     je      ctr003
  286.     cmp     eax,2                  ; key in buffer ?
  287.     je      ctr004
  288.     cmp     eax,3                  ; button in buffer ?
  289.     je      ctr005
  290.  
  291.  
  292.     ; Any data in the UDP receive buffer?
  293.     mov     eax, 53
  294.     mov     ebx, 2
  295.     mov     ecx, [socketNum]
  296.     int     0x40
  297.  
  298.     cmp     eax, 0
  299.     je      ctr001
  300.  
  301.     ; we have data - this will be the response
  302. ctr002:
  303.     mov     eax, 53
  304.     mov     ebx, 3
  305.     mov     ecx, [socketNum]
  306.     int     0x40                ; read byte - block (high byte)
  307.  
  308.     ; Store the data in the response buffer
  309.     mov     eax, [dhcpMsgLen]
  310.     mov     [eax], bl
  311.     inc     dword [dhcpMsgLen]
  312.  
  313.     mov     eax, 53
  314.     mov     ebx, 2
  315.     mov     ecx, [socketNum]
  316.     int     0x40                ; any more data?
  317.  
  318.     cmp     eax, 0
  319.     jne     ctr002              ; yes, so get it
  320.  
  321.     ; depending on which msg we sent, handle the response
  322.     ; accordingly.
  323.     ; If the response is to a dhcp discover, then:
  324.     ;  1) If response is DHCP OFFER then
  325.     ;  1.1) record server IP, lease time & IP address.
  326.     ;  1.2) send a request packet
  327.     ;  2) else exit ( display error )
  328.     ; If the response is to a dhcp request, then:
  329.     ;  1) If the response is DHCP ACK then
  330.     ;  1.1) extract the DNS & subnet fields. Set them in the stack
  331.     ;  2) else exit ( display error )
  332.  
  333.  
  334.     cmp     [dhcpMsgType], byte 0x01    ; did we send a discover?
  335.     je      ctr007
  336.     cmp     [dhcpMsgType], byte 0x03    ; did we send a request?
  337.     je      ctr008
  338.  
  339.     ; should never get here - we only send discover or request
  340.     jmp     ctr006
  341.  
  342. ctr007:
  343.     call    parseResponse
  344.  
  345.     ; Was the response an offer? It should be
  346.     cmp     [dhcpMsgType], byte 0x02
  347.     jne     ctr006                  ; NO - so quit
  348.  
  349.     ; send request
  350.     mov     [dhcpMsgType], byte 0x03 ; DHCP request
  351.     call    buildRequest
  352.     jmp     ctr000
  353.  
  354. ctr008:
  355.     call    parseResponse
  356.  
  357.     ; Was the response an ACK? It should be
  358.     cmp     [dhcpMsgType], byte 0x05
  359.     jne     ctr006                  ; NO - so quit
  360.  
  361.     ; Set or display addresses here...
  362.  
  363. ctr006:
  364.     ; close socket
  365.     mov     eax, 53
  366.     mov     ebx, 1
  367.     mov     ecx, [socketNum]
  368.     int     0x40
  369.  
  370.     mov     [socketNum], dword 0xFFFF
  371.  
  372.     call    draw_window
  373.  
  374.     jmp     ctr001
  375.  
  376. ctr003:                         ; redraw
  377.     call    draw_window
  378.     jmp     ctr001
  379.  
  380. ctr004:                         ; key
  381.     mov     eax,2               ; just read it and ignore
  382.     int     0x40
  383.     jmp     ctr001
  384.  
  385. ctr005:                         ; button
  386.     mov     eax,17              ; get id
  387.     int     0x40
  388.  
  389.     ; close socket
  390.     mov     eax, 53
  391.     mov     ebx, 1
  392.     mov     ecx, [socketNum]
  393.     int     0x40
  394.  
  395.     mov     [socketNum], dword 0xFFFF
  396.  
  397.     call    draw_window                     ; at first, draw the window
  398.  
  399.     ret
  400.  
  401.  
  402.  
  403.  
  404. ;   *********************************************
  405. ;   *******  WINDOW DEFINITIONS AND DRAW ********
  406. ;   *********************************************
  407.  
  408.  
  409. ; Pass in the IP address in edi
  410. ; row to display in [ya]
  411. drawIP:
  412. ;    mov     edi,hostIP
  413.     mov     ecx, edi
  414.     add     ecx, 4
  415.     mov     edx,[ya]
  416.     add     edx, 97*65536
  417.     mov     esi,0x00ffffff
  418.     mov     ebx,3*65536
  419.  
  420. ipdisplay:
  421.     mov     eax,47
  422.     push    ecx
  423.     movzx   ecx,byte [edi]
  424.     int     0x40
  425.     pop     ecx
  426.     add     edx,6*4*65536
  427.     inc     edi
  428.     cmp     edi,ecx
  429.     jb      ipdisplay
  430.     ret
  431.  
  432.  
  433. drawDHMS:
  434.  
  435.     mov     eax,[edi]
  436.     bswap   eax
  437.  
  438.     mov     esi,dhms
  439.     mov     ecx,16
  440.     mov     edi,text+40*4+12
  441.     cmp     eax,0xffffffff
  442.     jne     nforever
  443.     mov     esi,forever
  444.     cld
  445.     rep     movsb
  446.     ret
  447.    nforever:
  448.     cld
  449.     rep     movsb
  450.  
  451.     mov     ecx,28
  452.     xor     edx,edx
  453.     mov     ebx,60
  454.     div     ebx
  455.     call    displayDHMS
  456.     xor     edx,edx
  457.     div     ebx
  458.     call    displayDHMS
  459.     xor     edx,edx
  460.     mov     ebx,24
  461.     div     ebx
  462.     call    displayDHMS
  463.     mov     edx,eax
  464.     call    displayDHMS
  465.  
  466.     ret
  467.  
  468.  
  469. displayDHMS:
  470.  
  471.     pusha
  472.     mov     eax,47
  473.     mov     ebx,3*65536
  474.     mov     edx,ecx
  475.     imul    edx,6
  476.     shl     edx,16
  477.     add     edx,1*65536+99
  478.     mov     ecx,[esp+20]
  479.     mov     esi,0xffffff
  480.     int     0x40
  481.     popa
  482.     sub     ecx,4
  483.     ret
  484.  
  485.  
  486. draw_window:
  487.  
  488.     mov     eax,12                    ; function 12:tell os about windowdraw
  489.     mov     ebx,1                     ; 1, start of draw
  490.     int     0x40
  491.                                       ; DRAW WINDOW
  492.     mov     eax,0                     ; function 0 : define and draw window
  493.     mov     ebx,100*65536+300         ; [x start] *65536 + [x size]
  494.     mov     ecx,100*65536+156         ; [y start] *65536 + [y size]
  495.     mov     edx,0x03224466            ; color of work area RRGGBB
  496.     mov     esi,0x00334455            ; color of grab bar  RRGGBB,8->color gl
  497.     mov     edi,0x00ddeeff            ; color of frames    RRGGBB
  498.     int     0x40
  499.                                       ; WINDOW LABEL
  500.     mov     eax,4                     ; function 4 : write text to window
  501.     mov     ebx,8*65536+8             ; [x start] *65536 + [y start]
  502.     mov     ecx,0x00ffffff            ; color of text RRGGBB
  503.     mov     edx,labelt                ; pointer to text beginning
  504.     mov     esi,labellen-labelt       ; text length
  505.     int     0x40
  506.  
  507.     mov     eax,8                     ; Resolve
  508.     mov     ebx,20*65536+90
  509.     mov     ecx,127*65536+15
  510.     mov     edx,3
  511.     mov     esi,0x557799
  512.     int     0x40
  513.  
  514.     ; Pass in the IP address in edi
  515.     ; row to display in [ya]
  516.     mov     edi, dhcpClientIP
  517.     mov     eax, 35
  518.     mov     [ya], eax
  519.     call    drawIP
  520.     mov     edi, dhcpGateway
  521.     mov     eax, 35 + 16
  522.     mov     [ya], eax
  523.     call    drawIP
  524.     mov     edi, dhcpSubnet
  525.     mov     eax, 35 + 32
  526.     mov     [ya], eax
  527.     call    drawIP
  528.     mov     edi, dhcpDNSIP
  529.     mov     eax, 35 + 48
  530.     mov     [ya], eax
  531.     call    drawIP
  532.     mov     edi, dhcpLease
  533.     call    drawDHMS
  534.  
  535.     ; Re-draw the screen text
  536.     cld
  537.     mov     ebx,25*65536+35           ; draw info text with function 4
  538.     mov     ecx,0xffffff
  539.     mov     edx,text
  540.     mov     esi,40
  541.  
  542. newline:
  543.     mov     eax,4
  544.     int     0x40
  545.     add     ebx,16
  546.     add     edx,40
  547.     cmp     [edx],byte 'x'
  548.     jnz     newline
  549.  
  550.  
  551.     mov     eax,12                    ; function 12:tell os about windowdraw
  552.     mov     ebx,2                     ; 2, end of draw
  553.     int     0x40
  554.  
  555.     ret
  556.  
  557.  
  558.  
  559. ; DATA AREA
  560.  
  561. ya              dd  0x0
  562.  
  563. text:
  564.     db 'Client IP :    .   .   .                '
  565.     db 'Gateway IP:    .   .   .                '
  566.     db 'Subnet    :    .   .   .                '
  567.     db 'DNS IP    :    .   .   .                '
  568.     db 'Lease Time:    d   h   m   s            '
  569.     db '                                        '
  570.     db ' SEND REQUEST                           '
  571.     db 'x <- END MARKER, DONT DELETE            '
  572.  
  573.  
  574. dhms      db   '   d   h   m   s'
  575. forever   db   'Forever         '
  576.  
  577. labelt:   db   'DHCP Client Test'
  578. labellen:
  579.  
  580. dhcpMsgType:    db  0
  581. dhcpLease:      dd  0
  582. dhcpClientIP:   dd  0
  583. dhcpServerIP:   dd  0
  584. dhcpDNSIP:      dd  0
  585. dhcpSubnet:     dd  0
  586. dhcpGateway:    dd  0
  587.  
  588. dhcpMsgLen:     dd  0
  589. socketNum:      dd  0xFFFF
  590. dhcpMsg:
  591. I_END:
  592.  
  593.  
  594.  
  595.  
  596.