Subversion Repositories Kolibri OS

Rev

Rev 3340 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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