Subversion Repositories Kolibri OS

Rev

Rev 5391 | Rev 5586 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2010-2015. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  zeroconfig.asm - Zeroconfig service for KolibriOS              ;;
  7. ;;                                                                 ;;
  8. ;;  Written by hidnplayr@kolibrios.org                             ;;
  9. ;;    Some code contributed by Derpenguin                          ;;
  10. ;;                                                                 ;;
  11. ;;  DHCP code is based on that by Mike Hibbet                      ;;
  12. ;;      (DHCP client for menuetos)                                 ;;
  13. ;;                                                                 ;;
  14. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  15. ;;             Version 2, June 1991                                ;;
  16. ;;                                                                 ;;
  17. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  18.  
  19. format binary as ""
  20.  
  21. ; CONFIGURATION
  22.  
  23. TIMEOUT                 = 3             ; in seconds
  24. BUFFER                  = 1024          ; in bytes
  25. DHCP_TRIES              = 3             ; number of times to try contacting DHCP server
  26. __DEBUG__               = 1             ; enable/disable
  27. __DEBUG_LEVEL__         = 2             ; 1 = all, 2 = errors
  28.  
  29. ; CONFIGURATION FOR LINK-LOCAL
  30.  
  31. PROBE_WAIT              = 1             ; second  (initial random delay)
  32. PROBE_MIN               = 1             ; second  (minimum delay till repeated probe)
  33. PROBE_MAX               = 2             ; seconds (maximum delay till repeated probe)
  34. PROBE_NUM               = 3             ;         (number of probe packets)
  35.  
  36. ANNOUNCE_NUM            = 2             ;         (number of announcement packets)
  37. ANNOUNCE_INTERVAL       = 2             ; seconds (time between announcement packets)
  38. ANNOUNCE_WAIT           = 2             ; seconds (delay before announcing)
  39.  
  40. MAX_CONFLICTS           = 10            ;         (max conflicts before rate limiting)
  41.  
  42. RATE_LIMIT_INTERVAL     = 60            ; seconds (delay between successive attempts)
  43.  
  44. DEFEND_INTERVAL         = 10            ; seconds (min. wait between defensive ARPs)
  45.  
  46. use32
  47.         org     0x0
  48.  
  49.         db      'MENUET01'              ; 8 byte id
  50.         dd      0x01                    ; header version
  51.         dd      START                   ; start of code
  52.         dd      IM_END                  ; size of image
  53.         dd      (I_END+0x100)           ; memory for app
  54.         dd      (I_END+0x100)           ; esp
  55.         dd      0, 0                    ; I_Param, I_Path
  56.  
  57.  
  58. include '../../proc32.inc'
  59. include '../../macros.inc'
  60. include '../../debug-fdo.inc'
  61. include '../../network.inc'
  62. include 'dhcp.inc'
  63. include '../../dll.inc'
  64.  
  65. START:
  66.         mcall   68, 11
  67.  
  68.         stdcall dll.Load,@IMPORT
  69.         or      eax, eax
  70.         jnz     fail
  71.  
  72.         DEBUGF  2,"Zero-config service loaded\n"
  73.  
  74.         mcall   40, EVM_STACK2
  75.  
  76. wait_for_link_up:
  77.         mov     bh, [device]
  78.         mov     bl, 0           ; Get device type
  79.         mcall   74
  80.         cmp     eax, 1          ; Ethernet
  81.         jne     .wait
  82.  
  83.         mov     bl, 10          ; Get Link status
  84.         mcall   74
  85.         test    eax, eax
  86.         jnz     .go
  87.  
  88.   .wait:
  89.         mcall   10
  90.         jmp     wait_for_link_up
  91.  
  92.   .go:
  93.         mov     ebx, API_ETH + 0
  94.         mov     bh, [device]
  95.         mcall   76              ; get MAC of the ethernet interface
  96.         mov     word[MAC], bx
  97.         mov     dword[MAC+2], eax
  98.         DEBUGF  1,"MAC: %x-%x-%x-%x-%x-%x\n", [MAC+0]:2, [MAC+1]:2, [MAC+2]:2, [MAC+3]:2, [MAC+4]:2, [MAC+5]:2
  99.  
  100.         invoke  ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0
  101.  
  102.         cmp     dword[inibuf], 'stat'
  103.         je      static
  104.         jmp     try_dhcp
  105.  
  106. wait_for_link_down:
  107. ; TODO: detect ARP conflicts
  108.  
  109.         mcall   40, EVM_STACK2
  110.   .loop:
  111.         mcall   10
  112.         mov     bh, [device]
  113.         mov     bl, 0           ; Get device type
  114.         mcall   74
  115.         cmp     eax, 0          ; No device
  116.         je      .down
  117.  
  118.         mov     bl, 10          ; Get Link status
  119.         mcall   74
  120.         test    eax, eax
  121.         jnz     .loop
  122.  
  123.   .down:
  124.         xor     ecx, ecx
  125.         mov     ebx, API_IPv4 + 3
  126.         mov     bh, [device]
  127.         mcall   76              ; ip
  128.         mov     bl, 5
  129.         mcall   76              ; dns
  130.         mov     bl, 7
  131.         mcall   76              ; subnet
  132.         mov     bl, 9
  133.         mcall   76              ; gateway
  134.  
  135.         jmp     wait_for_link_up
  136.  
  137. static:
  138.         DEBUGF  1,"Applying Static IP settings\n"
  139.  
  140.         invoke  ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0
  141.         mov     edx, inibuf
  142.         call    ip_str_to_dword
  143.         mov     ecx, edx
  144.         mov     ebx, API_IPv4 + 3       ; set IP
  145.         mov     bh, [device]
  146.         mcall   76
  147.  
  148.         invoke  ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0
  149.         mov     edx, inibuf
  150.         call    ip_str_to_dword
  151.         mov     ecx, edx
  152.         mov     ebx, API_IPv4 + 9       ; set gateway
  153.         mov     bh, [device]
  154.         mcall   76
  155.  
  156.         invoke  ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0
  157.         mov     edx, inibuf
  158.         call    ip_str_to_dword
  159.         mov     ecx, edx
  160.         mov     ebx, API_IPv4 + 5       ; set DNS
  161.         mov     bh, [device]
  162.         mcall   76
  163.  
  164.         invoke  ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0
  165.         mov     edx, inibuf
  166.         call    ip_str_to_dword
  167.         mov     ecx, edx
  168.         mov     ebx, API_IPv4 + 7       ; set subnet
  169.         mov     bh, [device]
  170.         mcall   76
  171.  
  172.         mov     [notify_struct.msg], str_connected
  173.         mcall   70, notify_struct
  174.         jmp     wait_for_link_down
  175.  
  176.  
  177. try_dhcp:
  178.  
  179.         DEBUGF  2,"Trying to contact DHCP server\n"
  180.  
  181.         mcall   40, EVM_STACK
  182.  
  183.         mcall   75, 0, AF_INET4, SOCK_DGRAM, 0          ; open socket (parameters: domain, type, reserved)
  184.         cmp     eax, -1
  185.         je      socket_error
  186.         mov     [socketNum], eax
  187.  
  188.         DEBUGF  1,"Socket %x opened\n", eax
  189.  
  190.         mcall   75, 2, [socketNum], sockaddr1, 18       ; bind socket to local port 68
  191.         cmp     eax, -1
  192.         je      socket_error
  193.  
  194.         DEBUGF  1,"Socket Bound to local port 68\n"
  195.  
  196.         mcall   75, 4, [socketNum], sockaddr2, 18       ; connect to 255.255.255.255 on port 67
  197.         cmp     eax, -1
  198.         je      socket_error
  199.  
  200.         DEBUGF  1,"Connected to 255.255.255.255 on port 67\n"
  201.  
  202.         mov     [dhcpMsgType_tx], 0x01                  ; DHCP discover
  203.         mov     [dhcpLease], esi                        ; esi is still -1 (-1 = forever)
  204.  
  205.         call    random
  206.         mov     [dhcpXID], eax
  207.  
  208. build_request:                                          ; Creates a DHCP request packet.
  209.  
  210.         DEBUGF  1,"Building request\n"
  211.  
  212.         mcall   26, 9                                   ; Get system time
  213.         imul    eax, 100
  214.         mov     [currTime], eax
  215.  
  216.         mov     [tries], DHCP_TRIES
  217.  
  218.         stdcall mem.Alloc, BUFFER
  219.         test    eax, eax
  220.         jz      dhcp_fail2
  221.         mov     [dhcpMsg], eax
  222.  
  223.         ; Fill buffer with zeros
  224.         mov     edi, eax
  225.         mov     ecx, BUFFER
  226.         xor     eax, eax
  227.         rep     stosb
  228.  
  229.         mov     edx, [dhcpMsg]
  230.  
  231.         ; Boot protocol legacy
  232.         mov     [edx], byte 0x01                ; Boot request
  233.         mov     [edx+1], byte 0x01              ; Ethernet
  234.         mov     [edx+2], byte 0x06              ; Ethernet h/w len
  235.         mov     eax, [dhcpXID]
  236.         mov     [edx+4], eax                    ; xid
  237.         mov     eax, [currTime]
  238.         mov     [edx+8], eax                    ; secs, our uptime
  239.         mov     [edx+10], byte 0x80             ; broadcast flag set
  240.         mov     eax, dword [MAC]                ; first 4 bytes of MAC
  241.         mov     [edx+28],dword eax
  242.         mov     ax, word [MAC+4]                ; last 2 bytes of MAC
  243.         mov     [edx+32],word ax
  244.  
  245.         ; DHCP extension
  246.         mov     [edx+236], dword 0x63538263     ; magic cookie
  247.         mov     [edx+240], word 0x0135          ; option DHCP msg type
  248.         mov     al, [dhcpMsgType_tx]
  249.         mov     [edx+240+2], al
  250.         mov     [edx+240+3], word 0x0433        ; option Lease time = infinity
  251.         mov     eax, [dhcpLease]
  252.         mov     [edx+240+5], eax
  253.         mov     [edx+240+9], word 0x0432        ; option requested IP address
  254.         mov     eax, [dhcp.ip]
  255.         mov     [edx+240+11], eax
  256.         mov     [edx+240+15], word 0x0437       ; option request list
  257.         mov     [edx+240+17], dword 0x0f060301
  258.  
  259.         cmp     [dhcpMsgType_tx], 0x01          ; Check which msg we are sending
  260.         jne     .options
  261.  
  262.         mov     [edx+240+21], byte 0xff         ; end of options marker
  263.  
  264.         mov     [dhcpMsgLen], 262               ; length
  265.         jmp     send_dhcpmsg
  266.  
  267.   .options:
  268.         mov     [edx+240+21], word 0x0436       ; server IP
  269.         mov     eax, [dhcpServerIP]
  270.         mov     [edx+240+23], eax
  271.  
  272.         mov     [edx+240+27], byte 0xff         ; end of options marker
  273.  
  274.         mov     [dhcpMsgLen], 268               ; length
  275.  
  276. send_dhcpmsg:
  277.         DEBUGF  1,"Sending DHCP discover/request\n"
  278.         mcall   75, 6, [socketNum], [dhcpMsg], [dhcpMsgLen]             ; write to socket (send broadcast request)
  279.  
  280. ; Wait for data
  281.         mcall   26, 9
  282.         add     eax, TIMEOUT*100
  283.         mov     [timeout], eax
  284.   .wait:
  285.         mcall   23, TIMEOUT
  286.  
  287. read_data:                                                              ; we have data - this will be the response
  288.         mcall   75, 7, [socketNum], [dhcpMsg], BUFFER, MSG_DONTWAIT     ; read data from socket
  289.         cmp     eax, -1
  290.         jne     .got_data
  291.  
  292.         mcall   26, 9
  293.         cmp     eax, [timeout]
  294.         jb      send_dhcpmsg.wait
  295.  
  296.         DEBUGF  2,"No answer from DHCP server\n"
  297.         dec     [tries]
  298.         jnz     send_dhcpmsg                    ; try again
  299.         stdcall mem.Free, [dhcpMsg]
  300.         jmp     dhcp_fail
  301.  
  302.   .got_data:
  303.         DEBUGF  1,"%d bytes received\n", eax
  304.         mov     [dhcpMsgLen], eax
  305.  
  306. ; depending on which msg we sent, handle the response
  307. ; accordingly.
  308. ; If the response is to a dhcp discover, then:
  309. ;  1) If response is DHCP OFFER then
  310. ;  1.1) record server IP, lease time & IP address.
  311. ;  1.2) send a request packet
  312. ; If the response is to a dhcp request, then:
  313. ;  1) If the response is DHCP ACK then
  314. ;  1.1) extract the DNS & subnet fields. Set them in the stack
  315.  
  316.         cmp     [dhcpMsgType_tx], 0x01          ; did we send a discover?
  317.         je      discover_sent
  318.  
  319.         cmp     [dhcpMsgType_tx], 0x03          ; did we send a request?
  320.         je      request_sent
  321.  
  322.         ; we should never reach here ;)
  323.         stdcall mem.Free, [dhcpMsg]
  324.         jmp     fail
  325.  
  326. discover_sent:
  327.         call    parse_response
  328.         cmp     [dhcpMsgType_rx], 0x02          ; Was the response an offer?
  329.         jne     read_data
  330.  
  331.         DEBUGF  1, "Got offer, making request\n"
  332.         mov     [dhcpMsgType_tx], 0x03          ; make it a request
  333.         jmp     build_request
  334.  
  335. request_sent:
  336.         call    parse_response
  337.         cmp     [dhcpMsgType_rx], 0x05          ; Was the response an ACK? It should be
  338.         jne     read_data                       ; NO - read next packets
  339.  
  340.         DEBUGF  2, "IP assigned by DHCP server successfully\n"
  341.  
  342.         mov     [notify_struct.msg], str_connected
  343.         mcall   70, notify_struct
  344.  
  345.         mcall   close, [socketNum]
  346.  
  347.         mov     ebx, API_IPv4 + 3
  348.         mov     bh, [device]
  349.         mcall   76, , [dhcp.ip]                 ; ip
  350.         mov     bl, 5
  351.         mcall   76, , [dhcp.dns]                ; dns
  352.         mov     bl, 7
  353.         mcall   76, , [dhcp.subnet]             ; subnet
  354.         mov     bl, 9
  355.         mcall   76, , [dhcp.gateway]            ; gateway
  356.  
  357.         jmp     wait_for_link_down
  358.  
  359.  
  360. ;***************************************************************************
  361. ;   Function
  362. ;      parseResponse
  363. ;
  364. ;   Description
  365. ;      extracts the fields ( client IP address and options ) from
  366. ;      a DHCP response
  367. ;      The values go into
  368. ;       dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP,
  369. ;       dhcpDNSIP, dhcpSubnet
  370. ;      The message is stored in dhcpMsg
  371. ;
  372. ;***************************************************************************
  373. parse_response:
  374.  
  375.         DEBUGF  1,"Parsing response\n"
  376.         mov     edx, [dhcpMsg]
  377.         mov     [dhcpMsgType_rx], 0
  378.  
  379. ; Verify if session ID matches
  380.         mov     eax, [dhcpXID]
  381.         cmp     dword[edx+4], eax
  382.         jne     .done
  383.  
  384.         push    dword [edx+16]
  385.         pop     [dhcp.ip]
  386.         DEBUGF  1,"Client: %u.%u.%u.%u\n", [edx+16]:1, [edx+17]:1, [edx+18]:1, [edx+19]:1
  387.  
  388. ; TODO: check if there really are options
  389.  
  390.         mov     al, 240                         ; Point to first option
  391.         movzx   ecx, al
  392.  
  393.   .next_option:
  394.         add     edx, ecx
  395.  
  396.         mov     al, [edx]                       ; get message identifier
  397.  
  398.         cmp     al, 0xff                        ; End of options?
  399.         je      .done
  400.  
  401.         cmp     al, 0
  402.         je      .pad
  403.  
  404. ; TODO: check if we still are inside the buffer
  405.  
  406.         inc     edx
  407.         movzx   ecx, byte [edx]                 ; get data length
  408.         inc     edx                             ; point to data
  409.  
  410.         cmp     al, dhcp_msg_type               ; Msg type is a single byte option
  411.         je      .msgtype
  412.  
  413.         cmp     al, dhcp_dhcp_server_id
  414.         je      .server
  415.  
  416.         cmp     al, dhcp_address_time
  417.         je      .lease
  418.  
  419.         cmp     al, dhcp_subnet_mask
  420.         je      .subnet
  421.  
  422.         cmp     al, dhcp_router
  423.         je      .router
  424.  
  425.         cmp     al, dhcp_domain_server
  426.         je      .dns
  427.  
  428.         DEBUGF  1,"Unsupported DHCP option: %u\n", al
  429.  
  430.         jmp     .next_option
  431.  
  432.   .pad:
  433.         xor     ecx, ecx
  434.         inc     ecx
  435.         jmp     .next_option
  436.  
  437.   .msgtype:
  438.         mov     al, [edx]
  439.         mov     [dhcpMsgType_rx], al
  440.  
  441.         DEBUGF  1,"DHCP Msg type: %u\n", al
  442.         jmp     .next_option                    ; Get next option
  443.  
  444.   .server:
  445.         mov     eax, [edx]
  446.         mov     [dhcpServerIP], eax
  447.         DEBUGF  1,"Server: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
  448.         jmp     .next_option
  449.  
  450.   .lease:
  451.         pusha
  452.         mov     eax,[edx]
  453.         bswap   eax
  454.         mov     [dhcpLease],eax
  455.         DEBUGF  1,"Lease: %d\n",eax
  456.         popa
  457.         jmp     .next_option
  458.  
  459.   .subnet:
  460.         push    dword [edx]
  461.         pop     [dhcp.subnet]
  462.         DEBUGF  1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
  463.         jmp     .next_option
  464.  
  465.   .router:
  466.         push    dword [edx]
  467.         pop     [dhcp.gateway]
  468.         DEBUGF  1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
  469.         jmp     .next_option
  470.  
  471.   .dns:
  472.         push    dword [edx]
  473.         pop     [dhcp.dns]
  474.         DEBUGF  1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1
  475.         jmp     .next_option
  476.  
  477.   .done:
  478.         stdcall mem.Free, [dhcpMsg]
  479.         ret
  480.  
  481.  
  482. dhcp_fail:
  483.  
  484.         mcall   close, [socketNum]
  485.  
  486. dhcp_fail2:
  487.         DEBUGF  1,"DHCP failed\n"
  488.  
  489.  
  490. link_local:
  491.         call    random
  492.         mov     cx, ax
  493.         shl     ecx, 16
  494.         mov     cx, 0xfea9                              ; IP 169.254.0.0 link local net, see RFC3927
  495.         mov     ebx, API_IPv4 + 3
  496.         mov     bh, [device]
  497.         mcall   76, , ecx                               ; mask is 255.255.0.0
  498.         DEBUGF  2,"Link Local IP assigned: 169.254.%u.%u\n", [generator+0]:1, [generator+1]:1
  499.         mov     bl, 7
  500.         mcall   76, , 0xffff
  501.         mov     bl, 9
  502.         mcall   76, , 0x0
  503.         mov     bl, 5
  504.         mcall   76, , 0x0
  505.  
  506.         mcall   5, PROBE_WAIT*100
  507.  
  508.         xor     esi, esi
  509.    probe_loop:
  510.         call    random                                  ; create a pseudo random number in eax (seeded by MAC)
  511.  
  512.         cmp     al, PROBE_MIN*100                       ; check if al is bigger then PROBE_MIN
  513.         jae     @f                                      ; all ok
  514.         add     al, (PROBE_MAX-PROBE_MIN)*100           ; al is too small
  515.    @@:
  516.  
  517.         cmp     al, PROBE_MAX*100
  518.         jbe     @f
  519.         sub     al, (PROBE_MAX-PROBE_MIN)*100
  520.    @@:
  521.  
  522.         movzx   ebx,al
  523.         DEBUGF  1,"Waiting %u0ms\n",ebx
  524.         mcall   5
  525.  
  526.         DEBUGF  1,"Sending Probe\n"
  527.         mov     ebx, API_ARP + 6
  528.         mov     bh, [device]
  529.         mcall   76
  530.         inc     esi
  531.  
  532.         cmp     esi, PROBE_NUM
  533.         jb      probe_loop
  534.  
  535. ; now we wait further ANNOUNCE_WAIT seconds and send ANNOUNCE_NUM ARP announces. If any other host has assingned
  536. ; IP within this time, we should create another adress, that have to be done later
  537.  
  538.         DEBUGF  1,"Waiting %us\n", ANNOUNCE_WAIT
  539.         mcall   5, ANNOUNCE_WAIT*100
  540.         xor   esi, esi
  541.    announce_loop:
  542.  
  543.         DEBUGF  1,"Sending Announce\n"
  544.         mov     ebx, API_ARP + 6
  545.         mov     bh, [device]
  546.         mcall   76
  547.  
  548.         inc     esi
  549.         cmp     esi,ANNOUNCE_NUM
  550.         je      @f
  551.  
  552.         DEBUGF  1,"Waiting %us\n", ANNOUNCE_INTERVAL
  553.         mcall   5, ANNOUNCE_INTERVAL*100
  554.         jmp     announce_loop
  555.    @@:
  556.         jmp     wait_for_link_down
  557.  
  558.  
  559. socket_error:
  560.         DEBUGF  2,"Socket error\n"
  561. fail:
  562.         DEBUGF  2,"Zeroconf failed!\n"
  563.         mcall   -1
  564.  
  565.  
  566. random:  ; Pseudo random actually
  567.  
  568.         mov     eax, [generator]
  569.         add     eax, -43ab45b5h
  570.         ror     eax, 1
  571.         bswap   eax
  572.         xor     eax, dword[MAC]
  573.         ror     eax, 1
  574.         xor     eax, dword[MAC+2]
  575.         mov     [generator], eax
  576.  
  577.         ret
  578.  
  579.  
  580.  
  581. ip_str_to_dword:
  582.     push    edx
  583.  
  584.     ; This code validates if the query is an IP containing 4 numbers and 3 dots
  585.  
  586.     xor     al, al            ; make al (dot count) zero
  587.  
  588.    @@:
  589.     cmp     byte[edx],'0'     ; check if this byte is a number, if not jump to no_IP
  590.     jl      no_IP             ;
  591.     cmp     byte[edx],'9'     ;
  592.     jg      no_IP             ;
  593.  
  594.     inc     edx               ; the byte was a number, so lets check the next byte
  595.  
  596.     cmp     byte[edx],0       ; is this byte zero? (have we reached end of query?)
  597.     jz      @f                ; jump to next @@ then
  598.     cmp     byte[edx],':'
  599.     jz      @f
  600.  
  601.     cmp     byte[edx],'.'     ; is this byte a dot?
  602.     jne     @r                ; if not, jump to previous @@
  603.  
  604.     inc     al                ; the byte was a dot so increment al(dot count)
  605.     inc     edx               ; next byte
  606.     jmp     @r                ; lets check for numbers again (jump to previous @@)
  607.  
  608.    @@:                        ; we reach this when end of query reached
  609.     cmp     al,3              ; check if there where 3 dots
  610.     jnz     no_IP             ; if not, jump to no_IP
  611.  
  612.     ; The following code will convert this IP into a dword and output it in eax
  613.     ; If there is also a port number specified, this will be returned in ebx, otherwise ebx is -1
  614.  
  615.     pop     esi               ; edx (query address) was pushed onto stack and is now popped in esi
  616.  
  617.     xor     edx, edx          ; result
  618.     xor     eax, eax          ; current character
  619.     xor     ebx, ebx          ; current byte
  620.  
  621.   .outer_loop:
  622.     shl     edx, 8
  623.     add     edx, ebx
  624.     xor     ebx, ebx
  625.   .inner_loop:
  626.     lodsb
  627.     test    eax, eax
  628.     jz      .finish
  629.     cmp     al, '.'
  630.     jz      .outer_loop
  631.     sub     eax, '0'
  632.     imul    ebx, 10
  633.     add     ebx, eax
  634.     jmp     .inner_loop
  635.   .finish:
  636.     shl     edx, 8
  637.     add     edx, ebx
  638.  
  639.     bswap   edx               ; we want little endian order
  640.  
  641.     ret
  642.  
  643. no_IP:
  644.     pop     edx
  645.     xor     edx, edx
  646.  
  647.     ret
  648.  
  649. ; DATA AREA
  650.  
  651. align 16
  652. @IMPORT:
  653.  
  654. library \
  655.         libini,'libini.obj'
  656.  
  657. import  libini, \
  658.         ini.get_str,'ini_get_str'
  659.  
  660. include_debug_strings
  661.  
  662. str_ip          db 'ip', 0
  663. str_subnet      db 'subnet', 0
  664. str_gateway     db 'gateway', 0
  665. str_dns         db 'dns', 0
  666. str_ipconfig    db 'ipconfig', 0
  667. str_type        db 'type', 0
  668.  
  669.  
  670. sockaddr1:
  671.  
  672.         dw AF_INET4
  673.         dw 68 shl 8     ; local port
  674.         dd 0            ; local IP
  675.  
  676.         rb 10
  677.  
  678.  
  679. sockaddr2:
  680.  
  681.         dw AF_INET4
  682.         dw 67 shl 8     ; destination port
  683.         dd -1           ; destination IP
  684.  
  685.         rb 10
  686.  
  687. notify_struct:
  688.         dd 7            ; run application
  689.         dd 0
  690.  .msg   dd 0
  691.         dd 0
  692.         dd 0
  693.         db '/sys/@notify', 0
  694.  
  695. str_connected   db '"You are now connected to the network." -N', 0
  696.  
  697. path            db '/sys/settings/network.ini',0
  698.  
  699. IM_END:
  700.  
  701. device          db 1
  702. inibuf          rb 16
  703. tries           db ?
  704.  
  705. dhcpMsgType_tx  db ?    ; sent
  706. dhcpMsgType_rx  db ?    ; received
  707. dhcpXID         dd ?
  708. dhcpLease       dd ?
  709. dhcpServerIP    dd ?
  710.  
  711. dhcp:
  712. .ip             dd ?
  713. .subnet         dd ?
  714. .dns            dd ?
  715. .gateway        dd ?
  716.  
  717.  
  718. dhcpMsgLen      dd ?
  719. socketNum       dd ?
  720.  
  721. MAC             dp ?
  722.  
  723. currTime        dd ?
  724. generator       dd ?
  725.  
  726. dhcpMsg         dd ?
  727.  
  728. timeout         dd ?
  729.  
  730. I_END: