Subversion Repositories Kolibri OS

Rev

Rev 6123 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 6123 Rev 6228
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2010-2016. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2010-2016. All rights reserved.    ;;
4
;; Distributed under terms of the GNU General Public License       ;;
4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
5
;;                                                                 ;;
6
;;  zeroconfig.asm - Zeroconfig service for KolibriOS              ;;
6
;;  zeroconfig.asm - Zeroconfig service for KolibriOS              ;;
7
;;                                                                 ;;
7
;;                                                                 ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
8
;;  Written by hidnplayr@kolibrios.org                             ;;
9
;;    Some code contributed by Derpenguin                          ;;
9
;;    Some code contributed by Derpenguin                          ;;
10
;;                                                                 ;;
10
;;                                                                 ;;
11
;;  DHCP code is based on that by Mike Hibbet                      ;;
11
;;  DHCP code is based on that by Mike Hibbet                      ;;
12
;;      (DHCP client for menuetos)                                 ;;
12
;;      (DHCP client for menuetos)                                 ;;
13
;;                                                                 ;;
13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June 1991                                ;;
15
;;             Version 2, June 1991                                ;;
16
;;                                                                 ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
18
 
19
format binary as ""
19
format binary as ""
20
 
20
 
21
; CONFIGURATION
21
; CONFIGURATION
22
 
22
 
23
TIMEOUT                 = 5             ; in seconds
23
TIMEOUT                 = 5             ; in seconds
24
BUFFER                  = 1024          ; in bytes
24
BUFFER                  = 1024          ; in bytes
25
DHCP_TRIES              = 3             ; number of times to try contacting DHCP server
25
DHCP_TRIES              = 3             ; number of times to try contacting DHCP server
26
__DEBUG__               = 1             ; enable/disable
26
__DEBUG__               = 1             ; enable/disable
27
__DEBUG_LEVEL__         = 2             ; 1 = all, 2 = errors
27
__DEBUG_LEVEL__         = 2             ; 1 = all, 2 = errors
28
 
28
 
29
; CONFIGURATION FOR LINK-LOCAL
29
; CONFIGURATION FOR LINK-LOCAL
30
 
30
 
31
PROBE_WAIT              = 1             ; second  (initial random delay)
31
PROBE_WAIT              = 1             ; second  (initial random delay)
32
PROBE_MIN               = 1             ; second  (minimum delay till repeated probe)
32
PROBE_MIN               = 1             ; second  (minimum delay till repeated probe)
33
PROBE_MAX               = 2             ; seconds (maximum delay till repeated probe)
33
PROBE_MAX               = 2             ; seconds (maximum delay till repeated probe)
34
PROBE_NUM               = 3             ;         (number of probe packets)
34
PROBE_NUM               = 3             ;         (number of probe packets)
35
 
35
 
36
ANNOUNCE_NUM            = 2             ;         (number of announcement packets)
36
ANNOUNCE_NUM            = 2             ;         (number of announcement packets)
37
ANNOUNCE_INTERVAL       = 2             ; seconds (time between announcement packets)
37
ANNOUNCE_INTERVAL       = 2             ; seconds (time between announcement packets)
38
ANNOUNCE_WAIT           = 2             ; seconds (delay before announcing)
38
ANNOUNCE_WAIT           = 2             ; seconds (delay before announcing)
39
 
39
 
40
MAX_CONFLICTS           = 10            ;         (max conflicts before rate limiting)
40
MAX_CONFLICTS           = 10            ;         (max conflicts before rate limiting)
41
 
41
 
42
RATE_LIMIT_INTERVAL     = 60            ; seconds (delay between successive attempts)
42
RATE_LIMIT_INTERVAL     = 60            ; seconds (delay between successive attempts)
43
 
43
 
44
DEFEND_INTERVAL         = 10            ; seconds (min. wait between defensive ARPs)
44
DEFEND_INTERVAL         = 10            ; seconds (min. wait between defensive ARPs)
45
 
45
 
46
MAX_INTERFACES          = 8
46
MAX_INTERFACES          = 8
47
 
47
 
48
use32
48
use32
49
        org     0x0
49
        org     0x0
50
 
50
 
51
        db      'MENUET01'              ; 8 byte id
51
        db      'MENUET01'              ; 8 byte id
52
        dd      0x01                    ; header version
52
        dd      0x01                    ; header version
53
        dd      START                   ; start of code
53
        dd      START                   ; start of code
54
        dd      IM_END                  ; size of image
54
        dd      IM_END                  ; size of image
55
        dd      (I_END+0x100)           ; memory for app
55
        dd      (I_END+0x100)           ; memory for app
56
        dd      (I_END+0x100)           ; esp
56
        dd      (I_END+0x100)           ; esp
57
        dd      0, 0                    ; I_Param, I_Path
57
        dd      0, 0                    ; I_Param, I_Path
58
 
58
 
59
 
59
 
60
include '../../proc32.inc'
60
include '../../proc32.inc'
61
include '../../macros.inc'
61
include '../../macros.inc'
62
include '../../debug-fdo.inc'
62
include '../../debug-fdo.inc'
63
include '../../network.inc'
63
include '../../network.inc'
64
include 'dhcp.inc'
64
include 'dhcp.inc'
65
include '../../dll.inc'
65
include '../../dll.inc'
66
 
66
 
67
struct  dhcp_msg
67
struct  dhcp_msg
68
        op              db ?    ; Operation Code
68
        op              db ?    ; Operation Code
69
        htype           db ?    ; Hardware type
69
        htype           db ?    ; Hardware type
70
        hlen            db ?    ; Hardware address length
70
        hlen            db ?    ; Hardware address length
71
        hops            db ?
71
        hops            db ?
72
        xid             dd ?    ; Transaction Identifier
72
        xid             dd ?    ; Transaction Identifier
73
        secs            dw ?    ; Seconds since boot
73
        secs            dw ?    ; Seconds since boot
74
        flags           dw ?
74
        flags           dw ?
75
        ciaddr          dd ?    ; Client IP address
75
        ciaddr          dd ?    ; Client IP address
76
        yiaddr          dd ?    ; "Your" IP address
76
        yiaddr          dd ?    ; "Your" IP address
77
        siaddr          dd ?    ; Server IP address
77
        siaddr          dd ?    ; Server IP address
78
        giaddr          dd ?    ; Gateway IP address
78
        giaddr          dd ?    ; Gateway IP address
79
        chaddr          rb 16   ; Client hardware address
79
        chaddr          rb 16   ; Client hardware address
80
        sname           rb 64   ; Server name
80
        sname           rb 64   ; Server name
81
        file            rb 128  ; boot filename
81
        file            rb 128  ; boot filename
82
        cookie          dd ?    ; Magic cookie (0x63538263)
82
        cookie          dd ?    ; Magic cookie (0x63538263)
83
        options         rb 512
83
        options         rb 512
84
ends
84
ends
85
 
85
 
86
struct  interface
86
struct  interface
87
        number          dd ?
87
        number          dd ?
88
        state           dd ?    ; 0 - disconnected, 1 - connected
88
        state           dd ?    ; 0 - disconnected, 1 - connected
89
        mode            dd ?    ; 0 - disabled, 1 - static, 2 - dhcp, 3 - auto (zero config)
89
        mode            dd ?    ; 0 - disabled, 1 - static, 2 - dhcp, 3 - auto (zero config)
90
        tries           dd ?
90
        tries           dd ?
91
        lease           dd ?
91
        lease           dd ?
92
        ServerIP        dd ?
92
        ServerIP        dd ?
93
        ip              dd ?
93
        ip              dd ?
94
        subnet          dd ?
94
        subnet          dd ?
95
        dns             dd ?
95
        dns             dd ?
96
        gateway         dd ?
96
        gateway         dd ?
97
        socketNum       dd ?
97
        socketNum       dd ?
98
        timeout         dd ?
98
        timeout         dd ?
99
        ip_conflicts    dd ?
99
        ip_conflicts    dd ?
100
ends
100
ends
101
 
101
 
102
START:
102
START:
103
        mcall   68, 11                  ; init heap
103
        mcall   68, 11                  ; init heap
104
 
104
 
105
        stdcall dll.Load, @IMPORT       ; load libraries
105
        stdcall dll.Load, @IMPORT       ; load libraries
106
        or      eax, eax
106
        or      eax, eax
107
        jnz     exit_immediately
107
        jnz     exit_immediately
108
 
108
 
109
        DEBUGF  2, "Zero-config service loaded\n"
109
        DEBUGF  2, "Zero-config service loaded\n"
110
 
110
 
111
        mcall   40, EVM_STACK2          ; We only want low-level network events
111
        mcall   40, EVM_STACK2          ; We only want low-level network events
112
 
112
 
113
; Set up interface list
113
; Set up interface list
114
        mov     edi, device_list
114
        mov     edi, device_list
115
        xor     ebx, ebx
115
        xor     ebx, ebx
116
  @@:
116
  @@:
117
        inc     ebx
117
        inc     ebx
118
        mov     eax, ebx
118
        mov     eax, ebx
119
        stosd
119
        stosd
120
        mov     ecx, sizeof.interface/4-1
120
        mov     ecx, sizeof.interface/4-1
121
        xor     eax,eax
121
        xor     eax,eax
122
        rep stosd
122
        rep stosd
123
        cmp     ebx, MAX_INTERFACES
123
        cmp     ebx, MAX_INTERFACES
124
        jb      @b
124
        jb      @b
125
 
125
 
126
        mov     ebp, device_list
126
        mov     ebp, device_list
127
mainloop:
127
mainloop:
128
        cmp     [ebp + interface.state], 0
128
        cmp     [ebp + interface.state], 0
129
        je      .link_up?
129
        je      .link_up?
130
        jmp     .maintain_link
130
        jmp     .maintain_link
131
 
131
 
132
  .next:
132
  .next:
133
        cmp     [ebp + interface.number], MAX_INTERFACES
133
        cmp     [ebp + interface.number], MAX_INTERFACES
134
        je      .wait
134
        je      .wait
135
        add     ebp, sizeof.interface
135
        add     ebp, sizeof.interface
136
        jmp     mainloop
136
        jmp     mainloop
137
 
137
 
138
  .wait:
138
  .wait:
139
        mcall   10                      ; Wait for event
139
        mcall   10                      ; Wait for event
140
        mov     ebp, device_list
140
        mov     ebp, device_list
141
        jmp     mainloop
141
        jmp     mainloop
142
 
142
 
143
  .link_up?:
143
  .link_up?:
144
        mov     bh, byte[ebp + interface.number]
144
        mov     bh, byte[ebp + interface.number]
145
        mov     bl, 0                   ; Get device type
145
        mov     bl, 0                   ; Get device type
146
        mcall   74
146
        mcall   74
147
        cmp     eax, 1                  ; Ethernet
147
        cmp     eax, 1                  ; Ethernet
148
        jne     mainloop.next
148
        jne     mainloop.next
149
 
149
 
150
        mov     bl, 10                  ; Get Link status
150
        mov     bl, 10                  ; Get Link status
151
        mcall   74
151
        mcall   74
152
        test    eax, eax
152
        test    eax, eax
153
        jz      mainloop.next
153
        jz      mainloop.next
154
 
154
 
155
        mov     [ebp + interface.state], 1
155
        mov     [ebp + interface.state], 1
156
 
156
 
157
        call    create_str_ini_int
157
        call    create_str_ini_int
158
 
158
 
159
; Try to read settings from .ini file
159
; Try to read settings from .ini file
160
        invoke  ini.get_str, ini_path, str_ini_int, str_ip_type, inibuf, 16, str_null
160
        invoke  ini.get_str, ini_path, str_ini_int, str_ip_type, inibuf, 16, str_null
161
        test    eax, eax
161
        test    eax, eax
162
        jz      @f
162
        jz      @f
163
; If settings not found, use default settings from 'ip?' section
163
; If settings not found, use default settings from 'ip?' section
164
        mov     dword[str_ini_int], 'ip?'
164
        mov     dword[str_ini_int], 'ip?'
165
  @@:
165
  @@:
166
 
166
 
167
        mov     ebx, API_ETH + 0
167
        mov     ebx, API_ETH + 0
168
        mov     bh, byte[ebp + interface.number]
168
        mov     bh, byte[ebp + interface.number]
169
        mcall   76                      ; get MAC of the ethernet interface
169
        mcall   76                      ; get MAC of the ethernet interface
170
        mov     word[tx_msg.chaddr], bx
170
        mov     word[tx_msg.chaddr], bx
171
        mov     dword[tx_msg.chaddr+2], eax
171
        mov     dword[tx_msg.chaddr+2], eax
172
        DEBUGF  1, "MAC: %x-%x-%x-%x-%x-%x\n", \
172
        DEBUGF  1, "MAC: %x-%x-%x-%x-%x-%x\n", \
173
        [tx_msg.chaddr+0]:2, [tx_msg.chaddr+1]:2, [tx_msg.chaddr+2]:2, \
173
        [tx_msg.chaddr+0]:2, [tx_msg.chaddr+1]:2, [tx_msg.chaddr+2]:2, \
174
        [tx_msg.chaddr+3]:2, [tx_msg.chaddr+4]:2, [tx_msg.chaddr+5]:2
174
        [tx_msg.chaddr+3]:2, [tx_msg.chaddr+4]:2, [tx_msg.chaddr+5]:2
175
 
175
 
176
        invoke  ini.get_str, ini_path, str_ini_int, str_ip_type, inibuf, 16, str_null
176
        invoke  ini.get_str, ini_path, str_ini_int, str_ip_type, inibuf, 16, str_null
177
        test    eax, eax
177
        test    eax, eax
178
        jnz     .invalid
178
        jnz     .invalid
179
        mov     eax, dword[inibuf]
179
        mov     eax, dword[inibuf]
180
        or      eax, 0x20202020
180
        or      eax, 0x20202020
181
        mov     [ebp + interface.mode], 0
181
        mov     [ebp + interface.mode], 0
182
        cmp     eax, 'disa'
182
        cmp     eax, 'disa'
183
        je      .next
183
        je      .next
184
        mov     [ebp + interface.mode], 1
184
        mov     [ebp + interface.mode], 1
185
        cmp     eax, 'stat'
185
        cmp     eax, 'stat'
186
        je      static
186
        je      static
187
        mov     [ebp + interface.mode], 2
187
        mov     [ebp + interface.mode], 2
188
        cmp     eax, 'dhcp'
188
        cmp     eax, 'dhcp'
189
        je      dhcp
189
        je      dhcp
190
        mov     [ebp + interface.mode], 3
190
        mov     [ebp + interface.mode], 3
191
        cmp     eax, 'auto'
191
        cmp     eax, 'auto'
192
        je      dhcp
192
        je      dhcp
193
 
193
 
194
  .invalid:
194
  .invalid:
195
        DEBUGF  2, "Invalid settings for interface: %s.\n", str_ini_int
195
        DEBUGF  2, "Invalid settings for interface: %s.\n", str_ini_int
196
        jmp     .next
196
        jmp     .next
197
 
197
 
198
  .maintain_link:
198
  .maintain_link:
199
 
199
 
200
; Check for IP conflicts
200
; Check for IP conflicts
201
        mov     ebx, API_ARP
201
        mov     ebx, API_ARP
202
        mov     bh, byte[ebp + interface.number]
202
        mov     bh, byte[ebp + interface.number]
203
        mov     bl, 7
203
        mov     bl, 7
204
        mcall   76                      ; Number of IP conflicts
204
        mcall   76                      ; Number of IP conflicts
205
        cmp     eax, [ebp + interface.ip_conflicts]
205
        cmp     eax, [ebp + interface.ip_conflicts]
206
        je      @f
206
        je      @f
207
        mov     [ebp + interface.ip_conflicts], eax
207
        mov     [ebp + interface.ip_conflicts], eax
208
        DEBUGF  2, "IP address conflict on interface %u\n", [ebp + interface.number]
208
        DEBUGF  2, "IP address conflict on interface %u\n", [ebp + interface.number]
209
        ; Notify user of the IP address conflict
209
        ; Notify user of the IP address conflict
210
        mov     [notify_struct.msg], str_conflict
210
        mov     [notify_struct.msg], str_conflict
211
        mcall   70, notify_struct
211
        mcall   70, notify_struct
212
  @@:
212
  @@:
213
 
213
 
214
; Check if device is still there
214
; Check if device is still there
215
        mov     bh, byte[ebp + interface.number]
215
        mov     bh, byte[ebp + interface.number]
216
        mov     bl, 0                   ; Get device type
216
        mov     bl, 0                   ; Get device type
217
        mcall   74
217
        mcall   74
218
        test    eax, eax                ; No device
218
        test    eax, eax                ; No device
219
        jz      .link_down
219
        jz      .link_down
220
 
220
 
221
; Check if link is still there
221
; Check if link is still there
222
        mov     bl, 10                  ; Get Link status
222
        mov     bl, 10                  ; Get Link status
223
        mcall   74
223
        mcall   74
224
        test    eax, eax
224
        test    eax, eax
225
        jnz     .next
225
        jnz     .next
226
 
226
 
227
  .link_down:
227
  .link_down:
228
        mov     [ebp + interface.state], 0
228
        mov     [ebp + interface.state], 0
229
 
229
 
230
; Notify user that the link is down
230
; Notify user that the link is down
231
        mov     [notify_struct.msg], str_disconnected
231
        mov     [notify_struct.msg], str_disconnected
232
        mcall   70, notify_struct
232
        mcall   70, notify_struct
233
 
233
 
234
; CHECKME: should we do this in kernel instead? Should we even do this at all?
234
; CHECKME: should we do this in kernel instead? Should we even do this at all?
235
        xor     ecx, ecx
235
        xor     ecx, ecx
236
        mov     ebx, API_IPv4 + 3
236
        mov     ebx, API_IPv4 + 3
237
        mov     bh, byte[ebp + interface.number]
237
        mov     bh, byte[ebp + interface.number]
238
        mcall   76                      ; ip
238
        mcall   76                      ; ip
239
        mov     bl, 5
239
        mov     bl, 5
240
        mcall   76                      ; dns
240
        mcall   76                      ; dns
241
        mov     bl, 7
241
        mov     bl, 7
242
        mcall   76                      ; subnet
242
        mcall   76                      ; subnet
243
        mov     bl, 9
243
        mov     bl, 9
244
        mcall   76                      ; gateway
244
        mcall   76                      ; gateway
245
 
245
 
246
        jmp     .next
246
        jmp     .next
247
 
247
 
248
link_up:
248
link_up:
249
 
249
 
250
; Read number of previous IP conflicts
250
; Read number of previous IP conflicts
251
        mov     ebx, API_ARP
251
        mov     ebx, API_ARP
252
        mov     bh, byte[ebp + interface.number]
252
        mov     bh, byte[ebp + interface.number]
253
        mov     bl, 7
253
        mov     bl, 7
254
        mcall   76
254
        mcall   76
255
        mov     [ebp + interface.ip_conflicts], eax
255
        mov     [ebp + interface.ip_conflicts], eax
256
 
256
 
257
; Notify user that the link is up and running
257
; Notify user that the link is up and running
258
        mov     [notify_struct.msg], str_connected
258
        mov     [notify_struct.msg], str_connected
259
        mcall   70, notify_struct
259
        mcall   70, notify_struct
260
 
260
 
261
  .fail:
261
  .fail:
262
        mcall   40, EVM_STACK2
262
        mcall   40, EVM_STACK2
263
        jmp     mainloop.next
263
        jmp     mainloop.next
264
 
264
 
265
static:
265
static:
266
        DEBUGF  1, "Applying Static IP settings\n"
266
        DEBUGF  1, "Applying Static IP settings\n"
267
 
267
 
268
        invoke  ini.get_str, ini_path, str_ini_int, str_ip, inibuf, 16, str_null
268
        invoke  ini.get_str, ini_path, str_ini_int, str_ip, inibuf, 16, str_null
269
        mov     esi, inibuf
269
        mov     esi, inibuf
270
        call    ip_str_to_dword
270
        call    ip_str_to_dword
271
        mov     ebx, API_IPv4 + 3       ; set IP
271
        mov     ebx, API_IPv4 + 3       ; set IP
272
        mov     bh, byte[ebp + interface.number]
272
        mov     bh, byte[ebp + interface.number]
273
        mcall   76
273
        mcall   76
274
 
274
 
275
        invoke  ini.get_str, ini_path, str_ini_int, str_subnet, inibuf, 16, str_null
275
        invoke  ini.get_str, ini_path, str_ini_int, str_subnet, inibuf, 16, str_null
276
        mov     esi, inibuf
276
        mov     esi, inibuf
277
        call    ip_str_to_dword
277
        call    ip_str_to_dword
278
        mov     ebx, API_IPv4 + 7       ; set subnet
278
        mov     ebx, API_IPv4 + 7       ; set subnet
279
        mov     bh, byte[ebp + interface.number]
279
        mov     bh, byte[ebp + interface.number]
280
        mcall   76
280
        mcall   76
281
 
281
 
282
        invoke  ini.get_str, ini_path, str_ini_int, str_gateway, inibuf, 16, str_null
282
        invoke  ini.get_str, ini_path, str_ini_int, str_gateway, inibuf, 16, str_null
283
        mov     esi, inibuf
283
        mov     esi, inibuf
284
        call    ip_str_to_dword
284
        call    ip_str_to_dword
285
        mov     ebx, API_IPv4 + 9       ; set gateway
285
        mov     ebx, API_IPv4 + 9       ; set gateway
286
        mov     bh, byte[ebp + interface.number]
286
        mov     bh, byte[ebp + interface.number]
287
        mcall   76
287
        mcall   76
288
 
288
 
289
  .dns:
289
  .dns:
290
        invoke  ini.get_str, ini_path, str_ini_int, str_dns, inibuf, 16, str_null
290
        invoke  ini.get_str, ini_path, str_ini_int, str_dns, inibuf, 16, str_null
291
        mov     esi, inibuf
291
        mov     esi, inibuf
292
        call    ip_str_to_dword
292
        call    ip_str_to_dword
293
        mov     ebx, API_IPv4 + 5       ; set DNS
293
        mov     ebx, API_IPv4 + 5       ; set DNS
294
        mov     bh, byte[ebp + interface.number]
294
        mov     bh, byte[ebp + interface.number]
295
        mcall   76
295
        mcall   76
296
 
296
 
297
        jmp     link_up
297
        jmp     link_up
298
 
298
 
299
 
299
 
300
dhcp:
300
dhcp:
301
 
301
 
302
        DEBUGF  2, "Trying to contact DHCP server\n"
302
        DEBUGF  2, "Trying to contact DHCP server\n"
303
 
303
 
304
        mcall   40, EVM_STACK
304
        mcall   40, EVM_STACK
305
 
305
 
306
        mcall   75, 0, AF_INET4, SOCK_DGRAM, 0                          ; open socket (parameters: domain, type, reserved)
306
        mcall   75, 0, AF_INET4, SOCK_DGRAM, 0                          ; open socket (parameters: domain, type, reserved)
307
        cmp     eax, -1
307
        cmp     eax, -1
308
        je      dhcp_error
308
        je      dhcp_error
309
        mov     [ebp + interface.socketNum], eax
309
        mov     [ebp + interface.socketNum], eax
310
 
310
 
311
        DEBUGF  1, "Socket %x opened\n", eax
311
        DEBUGF  1, "Socket %x opened\n", eax
312
 
312
 
313
        mcall   75, 2, [ebp + interface.socketNum], sock_local, 18      ; bind socket to local port 68
313
        mcall   75, 2, [ebp + interface.socketNum], sock_local, 18      ; bind socket to local port 68
314
        cmp     eax, -1
314
        cmp     eax, -1
315
        je      socket_error
315
        je      socket_error
316
 
316
 
317
        DEBUGF  1, "Socket Bound to local port 68\n"
317
        DEBUGF  1, "Socket Bound to local port 68\n"
318
 
318
 
319
        pushd   [ebp + interface.number]
319
        pushd   [ebp + interface.number]
320
        pushd   4                       ; length of option
320
        pushd   4                       ; length of option
321
        pushd   SO_BINDTODEVICE
321
        pushd   SO_BINDTODEVICE
322
        pushd   SOL_SOCKET
322
        pushd   SOL_SOCKET
323
        mcall   75, 8, [ebp + interface.socketNum], esp
323
        mcall   75, 8, [ebp + interface.socketNum], esp
324
        add     esp, 16
324
        add     esp, 16
325
        cmp     eax, -1
325
        cmp     eax, -1
326
        je      socket_error
326
        je      socket_error
327
 
327
 
328
        DEBUGF  1, "Socket Bound to local interface %u\n", [ebp + interface.number]
328
        DEBUGF  1, "Socket Bound to local interface %u\n", [ebp + interface.number]
329
 
329
 
330
        mcall   75, 4, [ebp + interface.socketNum], sock_remote, 18     ; connect to 255.255.255.255 on port 67
330
        mcall   75, 4, [ebp + interface.socketNum], sock_remote, 18     ; connect to 255.255.255.255 on port 67
331
        cmp     eax, -1
331
        cmp     eax, -1
332
        je      socket_error
332
        je      socket_error
333
 
333
 
334
        DEBUGF  1, "Connected to 255.255.255.255 on port 67\n"
334
        DEBUGF  1, "Connected to 255.255.255.255 on port 67\n"
335
 
335
 
336
        ; Read preferred IP address from settings file
336
        ; Read preferred IP address from settings file
337
        invoke  ini.get_str, ini_path, str_ini_int, str_ip, inibuf, 16, str_null
337
        invoke  ini.get_str, ini_path, str_ini_int, str_ip, inibuf, 16, str_null
338
        mov     esi, inibuf
338
        mov     esi, inibuf
339
        call    ip_str_to_dword
339
        call    ip_str_to_dword
340
        mov     [ebp + interface.ip], ecx
340
        mov     [ebp + interface.ip], ecx
341
 
341
 
342
        call    random
342
        call    random
343
        mov     [tx_msg.xid], eax                                       ; randomize session ID
343
        mov     [tx_msg.xid], eax                                       ; randomize session ID
344
        mov     [tx_msg_type], 1                                        ; DHCP discover
344
        mov     [tx_msg_type], 1                                        ; DHCP discover
345
 
345
 
346
build_dhcp_packet:
346
build_dhcp_packet:
347
 
347
 
348
        DEBUGF  1, "Building DHCP packet\n"
348
        DEBUGF  1, "Building DHCP packet\n"
349
 
349
 
350
        mov     [ebp + interface.tries], DHCP_TRIES
350
        mov     [ebp + interface.tries], DHCP_TRIES
351
 
351
 
352
        ; Boot protocol legacy
352
        ; Boot protocol legacy
353
        mov     [tx_msg.op], 1                                          ; Boot request
353
        mov     [tx_msg.op], 1                                          ; Boot request
354
        mov     [tx_msg.htype], 1                                       ; Ethernet
354
        mov     [tx_msg.htype], 1                                       ; Ethernet
355
        mov     [tx_msg.hlen], 6                                        ; Ethernet address h/w len
355
        mov     [tx_msg.hlen], 6                                        ; Ethernet address h/w len
356
        mov     [tx_msg.hops], 0
356
        mov     [tx_msg.hops], 0
357
        mcall   26, 9                                                   ; Time since boot
357
        mcall   26, 9                                                   ; Time since boot
358
        xor     edx, edx
358
        xor     edx, edx
359
        mov     ebx, 100
359
        mov     ebx, 100
360
        div     ebx                                                     ; Divide by 100 to get number of seconds
360
        div     ebx                                                     ; Divide by 100 to get number of seconds
-
 
361
        xchg    al, ah                                                  ; Convert to big endian
361
        mov     [tx_msg.secs], ax
362
        mov     [tx_msg.secs], ax
362
        mov     [tx_msg.flags], 0
363
        mov     [tx_msg.flags], 0
363
 
364
 
364
        ; DHCP extension
365
        ; DHCP extension
365
        mov     [tx_msg.cookie], 0x63538263                             ; magic cookie
366
        mov     [tx_msg.cookie], 0x63538263                             ; magic cookie
366
 
367
 
367
        mov     word[tx_msg+240], 0x0135                                ; option DHCP msg type
368
        mov     word[tx_msg+240], 0x0135                                ; option DHCP msg type
368
        mov     al,[tx_msg_type]
369
        mov     al,[tx_msg_type]
369
        mov     [tx_msg+240+2], al
370
        mov     [tx_msg+240+2], al
370
 
371
 
371
        mov     word[tx_msg+240+3], 0x0433                              ; option Lease time
372
        mov     word[tx_msg+240+3], 0x0433                              ; option Lease time
372
        mov     dword[tx_msg+240+5], -1                                 ; infinite
373
        mov     dword[tx_msg+240+5], -1                                 ; infinite
373
 
374
 
374
        mov     word[tx_msg+240+9], 0x0432                              ; option requested IP address
375
        mov     word[tx_msg+240+9], 0x0432                              ; option requested IP address
375
        mov     eax,[ebp + interface.ip]
376
        mov     eax,[ebp + interface.ip]
376
        mov     [tx_msg+240+11], eax
377
        mov     [tx_msg+240+11], eax
377
 
378
 
378
        mov     word[tx_msg+240+15], 0x0437                             ; option request list
379
        mov     word[tx_msg+240+15], 0x0437                             ; option request list
379
        mov     dword[tx_msg+240+17], 0x0f060301
380
        mov     dword[tx_msg+240+17], 0x0f060301
380
 
381
 
381
        cmp     [tx_msg_type], 1                                        ; Check which msg we are sending
382
        cmp     [tx_msg_type], 1                                        ; Check which msg we are sending
382
        jne     .request
383
        jne     .request
383
 
384
 
384
        mov     byte[tx_msg+240+21], 0xff                               ; end of options marker
385
        mov     byte[tx_msg+240+21], 0xff                               ; end of options marker
385
 
386
 
386
        mov     [tx_msg_len], 262                                       ; length
387
        mov     [tx_msg_len], 262                                       ; length
387
        jmp     send_dhcp_packet
388
        jmp     send_dhcp_packet
388
 
389
 
389
  .request:
390
  .request:
390
        mov     word[tx_msg+240+21], 0x0436                             ; server IP
391
        mov     word[tx_msg+240+21], 0x0436                             ; server IP
391
        mov     eax,[ebp + interface.ServerIP]
392
        mov     eax,[ebp + interface.ServerIP]
392
        mov     [tx_msg+240+23], eax
393
        mov     [tx_msg+240+23], eax
393
 
394
 
394
        mov     byte[tx_msg+240+27], 0xff                               ; end of options marker
395
        mov     byte[tx_msg+240+27], 0xff                               ; end of options marker
395
 
396
 
396
        mov     [tx_msg_len], 268                                       ; length
397
        mov     [tx_msg_len], 268                                       ; length
397
 
398
 
398
 
399
 
399
send_dhcp_packet:
400
send_dhcp_packet:
400
        DEBUGF  1, "Sending DHCP packet\n"
401
        DEBUGF  1, "Sending DHCP packet\n"
401
        lea     edx, [tx_msg]
402
        lea     edx, [tx_msg]
402
        mcall   75, 6, [ebp + interface.socketNum], , [tx_msg_len]
403
        mcall   75, 6, [ebp + interface.socketNum], , [tx_msg_len]
403
 
404
 
404
; Wait for reply
405
; Wait for reply
405
        mcall   26, 9
406
        mcall   26, 9
406
        add     eax, TIMEOUT*100
407
        add     eax, TIMEOUT*100
407
        mov     [ebp + interface.timeout], eax
408
        mov     [ebp + interface.timeout], eax
408
        mov     ebx, TIMEOUT*100
409
        mov     ebx, TIMEOUT*100
409
  .wait:
410
  .wait:
410
        mcall   23                                                      ; Wait for event with timeout
411
        mcall   23                                                      ; Wait for event with timeout
411
read_packet:                                                            ; we have data - this will be the response
412
read_packet:                                                            ; we have data - this will be the response
412
        lea     edx, [rx_msg]
413
        lea     edx, [rx_msg]
413
        mcall   75, 7, [ebp + interface.socketNum], , BUFFER, MSG_DONTWAIT    ; read data from socket
414
        mcall   75, 7, [ebp + interface.socketNum], , BUFFER, MSG_DONTWAIT    ; read data from socket
414
        cmp     eax, -1
415
        cmp     eax, -1
415
        jne     .got_data
416
        jne     .got_data
416
 
417
 
417
        mcall   26, 9
418
        mcall   26, 9
418
        mov     ebx, eax
419
        mov     ebx, eax
419
        sub     ebx, [ebp + interface.timeout]
420
        sub     ebx, [ebp + interface.timeout]
420
        ja      send_dhcp_packet.wait
421
        ja      send_dhcp_packet.wait
421
 
422
 
422
        DEBUGF  1, "No answer from DHCP server\n"
423
        DEBUGF  1, "No answer from DHCP server\n"
423
        dec     [ebp + interface.tries]
424
        dec     [ebp + interface.tries]
424
        jnz     send_dhcp_packet
425
        jnz     send_dhcp_packet
425
        jmp     dhcp_fail
426
        jmp     dhcp_fail
426
 
427
 
427
  .got_data:
428
  .got_data:
428
        DEBUGF  1, "%d bytes received\n", eax
429
        DEBUGF  1, "%d bytes received\n", eax
429
        mov     [rx_msg_len], eax
430
        mov     [rx_msg_len], eax
430
 
431
 
431
; depending on which msg we sent, handle the response
432
; depending on which msg we sent, handle the response
432
; accordingly.
433
; accordingly.
433
; If the response is to a dhcp discover, then:
434
; If the response is to a dhcp discover, then:
434
;  1) If response is DHCP OFFER then
435
;  1) If response is DHCP OFFER then
435
;  1.1) record server IP, lease time & IP address.
436
;  1.1) record server IP, lease time & IP address.
436
;  1.2) send a request packet
437
;  1.2) send a request packet
437
; If the response is to a dhcp request, then:
438
; If the response is to a dhcp request, then:
438
;  1) If the response is DHCP ACK then
439
;  1) If the response is DHCP ACK then
439
;  1.1) extract the DNS & subnet fields. Set them in the stack
440
;  1.1) extract the DNS & subnet fields. Set them in the stack
440
 
441
 
441
        cmp     [tx_msg_type], 1                ; did we send a discover?
442
        cmp     [tx_msg_type], 1                ; did we send a discover?
442
        je      discover_sent
443
        je      discover_sent
443
        cmp     [tx_msg_type], 3                ; did we send a request?
444
        cmp     [tx_msg_type], 3                ; did we send a request?
444
        je      request_sent
445
        je      request_sent
445
        jmp     exit_immediately
446
        jmp     exit_immediately
446
 
447
 
447
discover_sent:
448
discover_sent:
448
        call    parse_dhcp_reply
449
        call    parse_dhcp_reply
449
        cmp     [rx_msg_type], 2                ; Was the response an offer?
450
        cmp     [rx_msg_type], 2                ; Was the response an offer?
450
        jne     read_packet
451
        jne     read_packet
451
 
452
 
452
        DEBUGF  1, "Got offer, making request\n"
453
        DEBUGF  1, "Got offer, making request\n"
453
        mov     [tx_msg_type], 3                ; make it a request
454
        mov     [tx_msg_type], 3                ; make it a request
454
        jmp     build_dhcp_packet
455
        jmp     build_dhcp_packet
455
 
456
 
456
request_sent:
457
request_sent:
457
        call    parse_dhcp_reply
458
        call    parse_dhcp_reply
458
        cmp     [rx_msg_type], 5                ; Was the response an ACK? It should be
459
        cmp     [rx_msg_type], 5                ; Was the response an ACK? It should be
459
        jne     read_packet                     ; NO - read next packets
460
        jne     read_packet                     ; NO - read next packets
460
 
461
 
461
        DEBUGF  2, "IP address %u.%u.%u.%u assigned to network interface %u by DHCP\n",\
462
        DEBUGF  2, "IP address %u.%u.%u.%u assigned to network interface %u by DHCP\n",\
462
        [ebp+interface.ip+0]:1, [ebp+interface.ip+1]:1, [ebp+interface.ip+2]:1, [ebp+interface.ip+3]:1, [ebp + interface.number]:1
463
        [ebp+interface.ip+0]:1, [ebp+interface.ip+1]:1, [ebp+interface.ip+2]:1, [ebp+interface.ip+3]:1, [ebp + interface.number]:1
463
 
464
 
464
        mcall   close, [ebp + interface.socketNum]
465
        mcall   close, [ebp + interface.socketNum]
465
 
466
 
466
        mov     ebx, API_IPv4 + 3
467
        mov     ebx, API_IPv4 + 3
467
        mov     bh, byte[ebp + interface.number]
468
        mov     bh, byte[ebp + interface.number]
468
        mcall   76, , [ebp + interface.ip]            ; ip
469
        mcall   76, , [ebp + interface.ip]            ; ip
469
        mov     bl, 7
470
        mov     bl, 7
470
        mcall   76, , [ebp + interface.subnet]        ; subnet
471
        mcall   76, , [ebp + interface.subnet]        ; subnet
471
        mov     bl, 9
472
        mov     bl, 9
472
        mcall   76, , [ebp + interface.gateway]       ; gateway
473
        mcall   76, , [ebp + interface.gateway]       ; gateway
473
 
474
 
474
        invoke  ini.get_str, ini_path, str_ini_int, str_dns_type, inibuf, 16, str_null
475
        invoke  ini.get_str, ini_path, str_ini_int, str_dns_type, inibuf, 16, str_null
475
        test    eax, eax
476
        test    eax, eax
476
        jnz     @f
477
        jnz     @f
477
        mov     eax, dword[inibuf]
478
        mov     eax, dword[inibuf]
478
        or      eax, 0x202020
479
        or      eax, 0x202020
479
        cmp     eax, 'stat'
480
        cmp     eax, 'stat'
480
        je      static.dns
481
        je      static.dns
481
  @@:
482
  @@:
482
        mov     ebx, API_IPv4 + 5
483
        mov     ebx, API_IPv4 + 5
483
        mov     bh, byte[ebp + interface.number]
484
        mov     bh, byte[ebp + interface.number]
484
        mcall   76, , [ebp + interface.dns]           ; dns
485
        mcall   76, , [ebp + interface.dns]           ; dns
485
 
486
 
486
        jmp     link_up
487
        jmp     link_up
487
 
488
 
488
 
489
 
489
parse_dhcp_reply:
490
parse_dhcp_reply:
490
 
491
 
491
        DEBUGF  1, "Parsing response\n"
492
        DEBUGF  1, "Parsing response\n"
492
        mov     [rx_msg_type], 0
493
        mov     [rx_msg_type], 0
493
 
494
 
494
; Verify if session ID matches
495
; Verify if session ID matches
495
        mov     eax, [tx_msg.xid]
496
        mov     eax, [tx_msg.xid]
496
        cmp     [rx_msg.xid], eax
497
        cmp     [rx_msg.xid], eax
497
        jne     .done
498
        jne     .done
498
 
499
 
499
        pushd   [rx_msg.yiaddr]
500
        pushd   [rx_msg.yiaddr]
500
        pop     [ebp + interface.ip]
501
        pop     [ebp + interface.ip]
501
        DEBUGF  1, "Client: %u.%u.%u.%u\n", \
502
        DEBUGF  1, "Client: %u.%u.%u.%u\n", \
502
        [rx_msg.yiaddr]:1, [rx_msg.yiaddr+1]:1, [rx_msg.yiaddr+2]:1, [rx_msg.yiaddr+3]:1
503
        [rx_msg.yiaddr]:1, [rx_msg.yiaddr+1]:1, [rx_msg.yiaddr+2]:1, [rx_msg.yiaddr+3]:1
503
 
504
 
504
; Verify magic cookie
505
; Verify magic cookie
505
        cmp     [rx_msg.cookie], 0x63538263
506
        cmp     [rx_msg.cookie], 0x63538263
506
        jne     .done
507
        jne     .done
507
 
508
 
508
; Parse the DHCP options
509
; Parse the DHCP options
509
        lea     esi, [rx_msg]
510
        lea     esi, [rx_msg]
510
        mov     ecx, 240                        ; point to the first option
511
        mov     ecx, 240                        ; point to the first option
511
  .next_option:
512
  .next_option:
512
; TODO: check if we still are inside the buffer!
513
; TODO: check if we still are inside the buffer!
513
        add     esi, ecx
514
        add     esi, ecx
514
 
515
 
515
        lodsb                                   ; get message identifier
516
        lodsb                                   ; get message identifier
516
        mov     bl, al
517
        mov     bl, al
517
        cmp     bl, 0xff                        ; End of options?
518
        cmp     bl, 0xff                        ; End of options?
518
        je      .done
519
        je      .done
519
        test    bl, bl
520
        test    bl, bl
520
        jz      .pad
521
        jz      .pad
521
 
522
 
522
        lodsb                                   ; load data length
523
        lodsb                                   ; load data length
523
        movzx   ecx, al
524
        movzx   ecx, al
524
        cmp     bl, dhcp_msg_type               ; Msg type is a single byte option
525
        cmp     bl, dhcp_msg_type               ; Msg type is a single byte option
525
        je      .msgtype
526
        je      .msgtype
526
        cmp     bl, dhcp_dhcp_server_id
527
        cmp     bl, dhcp_dhcp_server_id
527
        je      .server
528
        je      .server
528
        cmp     bl, dhcp_address_time
529
        cmp     bl, dhcp_address_time
529
        je      .lease
530
        je      .lease
530
        cmp     bl, dhcp_subnet_mask
531
        cmp     bl, dhcp_subnet_mask
531
        je      .subnet
532
        je      .subnet
532
        cmp     bl, dhcp_router
533
        cmp     bl, dhcp_router
533
        je      .router
534
        je      .router
534
        cmp     bl, dhcp_domain_server
535
        cmp     bl, dhcp_domain_server
535
        je      .dns
536
        je      .dns
536
 
537
 
537
        DEBUGF  1, "Unsupported DHCP option: %u\n", bl
538
        DEBUGF  1, "Unsupported DHCP option: %u\n", bl
538
        jmp     .next_option
539
        jmp     .next_option
539
 
540
 
540
  .pad:
541
  .pad:
541
        xor     ecx, ecx
542
        xor     ecx, ecx
542
        inc     ecx
543
        inc     ecx
543
        jmp     .next_option
544
        jmp     .next_option
544
 
545
 
545
  .msgtype:
546
  .msgtype:
546
        mov     al, [esi]
547
        mov     al, [esi]
547
        mov     [rx_msg_type], al
548
        mov     [rx_msg_type], al
548
 
549
 
549
        DEBUGF  1, "DHCP Msg type: %u\n", al
550
        DEBUGF  1, "DHCP Msg type: %u\n", al
550
        jmp     .next_option                    ; Get next option
551
        jmp     .next_option                    ; Get next option
551
 
552
 
552
  .server:
553
  .server:
553
        pushd   [esi]
554
        pushd   [esi]
554
        pop     [ebp + interface.ServerIP]
555
        pop     [ebp + interface.ServerIP]
555
        DEBUGF  1, "Server: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
556
        DEBUGF  1, "Server: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
556
        jmp     .next_option
557
        jmp     .next_option
557
 
558
 
558
  .lease:
559
  .lease:
559
        pusha
560
        pusha
560
        mov     eax,[esi]
561
        mov     eax,[esi]
561
        bswap   eax
562
        bswap   eax
562
        mov     [ebp + interface.lease], eax
563
        mov     [ebp + interface.lease], eax
563
        DEBUGF  1, "Lease: %d\n", eax
564
        DEBUGF  1, "Lease: %d\n", eax
564
        popa
565
        popa
565
        jmp     .next_option
566
        jmp     .next_option
566
 
567
 
567
  .subnet:
568
  .subnet:
568
        pushd   [esi]
569
        pushd   [esi]
569
        pop     [ebp + interface.subnet]
570
        pop     [ebp + interface.subnet]
570
        DEBUGF  1, "Subnet: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
571
        DEBUGF  1, "Subnet: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
571
        jmp     .next_option
572
        jmp     .next_option
572
 
573
 
573
  .router:
574
  .router:
574
        pushd   [esi]
575
        pushd   [esi]
575
        pop     [ebp + interface.gateway]
576
        pop     [ebp + interface.gateway]
576
        DEBUGF  1, "Gateway: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
577
        DEBUGF  1, "Gateway: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
577
        jmp     .next_option
578
        jmp     .next_option
578
 
579
 
579
  .dns:
580
  .dns:
580
        pushd   [esi]
581
        pushd   [esi]
581
        pop     [ebp + interface.dns]
582
        pop     [ebp + interface.dns]
582
        DEBUGF  1, "DNS: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
583
        DEBUGF  1, "DNS: %u.%u.%u.%u\n", [esi]:1, [esi+1]:1, [esi+2]:1, [esi+3]:1
583
        jmp     .next_option
584
        jmp     .next_option
584
 
585
 
585
  .done:
586
  .done:
586
        ret
587
        ret
587
 
588
 
588
exit_immediately:
589
exit_immediately:
589
        DEBUGF  2, "Zeroconf failed!\n"
590
        DEBUGF  2, "Zeroconf failed!\n"
590
        mcall   -1
591
        mcall   -1
591
 
592
 
592
socket_error:
593
socket_error:
593
        DEBUGF  2, "Socket error!\n"
594
        DEBUGF  2, "Socket error!\n"
594
 
595
 
595
dhcp_fail:
596
dhcp_fail:
596
        mcall   close, [ebp + interface.socketNum]
597
        mcall   close, [ebp + interface.socketNum]
597
 
598
 
598
dhcp_error:
599
dhcp_error:
599
        DEBUGF  2, "DHCP failed\n"
600
        DEBUGF  2, "DHCP failed\n"
600
        cmp     [ebp + interface.mode], 3               ; zero config mode?
601
        cmp     [ebp + interface.mode], 3               ; zero config mode?
601
        jne     link_up
602
        jne     link_up
602
 
603
 
603
link_local:
604
link_local:
604
 
605
 
605
; TODO: send ARP probes before setting the IP address in stack!
606
; TODO: send ARP probes before setting the IP address in stack!
606
 
607
 
607
        call    random
608
        call    random
608
        mov     cx, ax
609
        mov     cx, ax
609
        shl     ecx, 16
610
        shl     ecx, 16
610
        mov     cx, 0xfea9                              ; IP 169.254.0.0 link local net, see RFC3927
611
        mov     cx, 0xfea9                              ; IP 169.254.0.0 link local net, see RFC3927
611
        mov     ebx, API_IPv4 + 3
612
        mov     ebx, API_IPv4 + 3
612
        mov     bh, byte[ebp + interface.number]
613
        mov     bh, byte[ebp + interface.number]
613
        mcall   76, , ecx                               ; mask is 255.255.0.0
614
        mcall   76, , ecx                               ; mask is 255.255.0.0
614
        DEBUGF  2, "IP address 169.254.%u.%u assigned to network interface %u through Link-Local\n",\
615
        DEBUGF  2, "IP address 169.254.%u.%u assigned to network interface %u through Link-Local\n",\
615
        [generator+0]:1, [generator+1]:1, [ebp + interface.number]:1
616
        [generator+0]:1, [generator+1]:1, [ebp + interface.number]:1
616
        mov     bl, 7
617
        mov     bl, 7
617
        mcall   76, , 0xffff
618
        mcall   76, , 0xffff
618
        mov     bl, 9
619
        mov     bl, 9
619
        mcall   76, , 0x0
620
        mcall   76, , 0x0
620
        mov     bl, 5
621
        mov     bl, 5
621
        mcall   76, , 0x0
622
        mcall   76, , 0x0
622
 
623
 
623
        jmp     link_up
624
        jmp     link_up
624
 
625
 
625
 
626
 
626
random:  ; Pseudo random actually
627
random:  ; Pseudo random actually
627
 
628
 
628
        mov     eax,[generator]
629
        mov     eax,[generator]
629
        add     eax, -43ab45b5h
630
        add     eax, -43ab45b5h
630
        ror     eax, 1
631
        ror     eax, 1
631
        bswap   eax
632
        bswap   eax
632
        xor     eax, dword[tx_msg.chaddr]
633
        xor     eax, dword[tx_msg.chaddr]
633
        ror     eax, 1
634
        ror     eax, 1
634
        xor     eax, dword[tx_msg.chaddr+2]
635
        xor     eax, dword[tx_msg.chaddr+2]
635
        mov     [generator], eax
636
        mov     [generator], eax
636
 
637
 
637
        ret
638
        ret
638
 
639
 
639
 
640
 
640
 
641
 
641
create_str_ini_int:
642
create_str_ini_int:
642
        mov     eax, [ebp + interface.number]
643
        mov     eax, [ebp + interface.number]
643
        mov     ebx, 10
644
        mov     ebx, 10
644
        xor     edx, edx
645
        xor     edx, edx
645
        push    0
646
        push    0
646
  @@:
647
  @@:
647
        div     ebx
648
        div     ebx
648
        add     dl, '0'
649
        add     dl, '0'
649
        push    edx
650
        push    edx
650
        test    eax, eax
651
        test    eax, eax
651
        jnz     @r
652
        jnz     @r
652
  @@:
653
  @@:
653
        mov     edi, str_ini_int+2
654
        mov     edi, str_ini_int+2
654
  @@:
655
  @@:
655
        pop     eax
656
        pop     eax
656
        stosb
657
        stosb
657
        test    eax, eax
658
        test    eax, eax
658
        jnz     @r
659
        jnz     @r
659
 
660
 
660
        ret
661
        ret
661
 
662
 
662
 
663
 
663
 
664
 
664
; In: esi = ptr to ASCIIZ IP address
665
; In: esi = ptr to ASCIIZ IP address
665
; Out: ecx = IP (0 on error)
666
; Out: ecx = IP (0 on error)
666
 
667
 
667
ip_str_to_dword:
668
ip_str_to_dword:
668
 
669
 
669
        xor     ecx, ecx        ; end result
670
        xor     ecx, ecx        ; end result
670
  .charloop:
671
  .charloop:
671
        lodsb
672
        lodsb
672
        test    al, al
673
        test    al, al
673
        jz      .finish
674
        jz      .finish
674
        cmp     al, '.'
675
        cmp     al, '.'
675
        je      .dot
676
        je      .dot
676
        sub     al, '0'
677
        sub     al, '0'
677
        jb      .fail
678
        jb      .fail
678
        cmp     al, 9
679
        cmp     al, 9
679
        ja      .fail
680
        ja      .fail
680
        mov     dl, cl
681
        mov     dl, cl
681
        shl     cl, 2
682
        shl     cl, 2
682
        jc      .fail
683
        jc      .fail
683
        add     cl, dl
684
        add     cl, dl
684
        jc      .fail
685
        jc      .fail
685
        add     cl, cl
686
        add     cl, cl
686
        jc      .fail
687
        jc      .fail
687
        add     cl, al
688
        add     cl, al
688
        jc      .fail
689
        jc      .fail
689
        jmp     .charloop
690
        jmp     .charloop
690
  .dot:
691
  .dot:
691
        shl     ecx, 8
692
        shl     ecx, 8
692
        jc      .fail
693
        jc      .fail
693
        xor     cl, cl
694
        xor     cl, cl
694
        jmp     .charloop
695
        jmp     .charloop
695
  .finish:
696
  .finish:
696
        bswap   ecx             ; we want little endian order
697
        bswap   ecx             ; we want little endian order
697
        ret
698
        ret
698
 
699
 
699
  .fail:
700
  .fail:
700
        xor     ecx, ecx
701
        xor     ecx, ecx
701
        ret
702
        ret
702
 
703
 
703
; DATA AREA
704
; DATA AREA
704
 
705
 
705
align 16
706
align 16
706
@IMPORT:
707
@IMPORT:
707
 
708
 
708
library \
709
library \
709
        libini,         'libini.obj'
710
        libini,         'libini.obj'
710
 
711
 
711
import  libini, \
712
import  libini, \
712
        ini.get_str,    'ini_get_str',\
713
        ini.get_str,    'ini_get_str',\
713
        ini.set_str,    'ini_set_str'
714
        ini.set_str,    'ini_set_str'
714
 
715
 
715
include_debug_strings
716
include_debug_strings
716
 
717
 
717
str_ip          db 'ip', 0
718
str_ip          db 'ip', 0
718
str_subnet      db 'subnet', 0
719
str_subnet      db 'subnet', 0
719
str_gateway     db 'gateway', 0
720
str_gateway     db 'gateway', 0
720
str_dns         db 'dns', 0
721
str_dns         db 'dns', 0
721
 
722
 
722
str_ip_type     db 'ip_type', 0
723
str_ip_type     db 'ip_type', 0
723
str_dns_type    db 'dns_type', 0
724
str_dns_type    db 'dns_type', 0
724
 
725
 
725
str_ini_int     db 'ip1', 0
726
str_ini_int     db 'ip1', 0
726
                rb 10
727
                rb 10
727
 
728
 
728
str_null        db 0
729
str_null        db 0
729
 
730
 
730
sock_local:
731
sock_local:
731
        dw AF_INET4
732
        dw AF_INET4
732
        dw 68 shl 8     ; local port
733
        dw 68 shl 8     ; local port
733
        dd 0            ; local IP
734
        dd 0            ; local IP
734
        rb 10
735
        rb 10
735
 
736
 
736
 
737
 
737
sock_remote:
738
sock_remote:
738
        dw AF_INET4
739
        dw AF_INET4
739
        dw 67 shl 8     ; destination port
740
        dw 67 shl 8     ; destination port
740
        dd -1           ; destination IP
741
        dd -1           ; destination IP
741
        rb 10
742
        rb 10
742
 
743
 
743
notify_struct:
744
notify_struct:
744
        dd 7            ; run application
745
        dd 7            ; run application
745
        dd 0
746
        dd 0
746
 .msg   dd 0
747
 .msg   dd 0
747
        dd 0
748
        dd 0
748
        dd 0
749
        dd 0
749
        db '/sys/@notify', 0
750
        db '/sys/@notify', 0
750
 
751
 
751
str_connected           db '"You are now connected to the network." -N', 0
752
str_connected           db '"You are now connected to the network." -N', 0
752
str_disconnected        db '"You are now disconnected from the network." -N', 0
753
str_disconnected        db '"You are now disconnected from the network." -N', 0
753
str_conflict            db '"An IP address conflict has been detected on the network." -W', 0
754
str_conflict            db '"An IP address conflict has been detected on the network." -W', 0
754
 
755
 
755
ini_path                db '/sys/settings/network.ini',0
756
ini_path                db '/sys/settings/network.ini',0
756
 
757
 
757
IM_END:
758
IM_END:
758
 
759
 
759
generator       dd ?
760
generator       dd ?
760
 
761
 
761
inibuf          rb 16
762
inibuf          rb 16
762
 
763
 
763
tx_msg_len      dd ?
764
tx_msg_len      dd ?
764
rx_msg_len      dd ?
765
rx_msg_len      dd ?
765
tx_msg_type     db ?
766
tx_msg_type     db ?
766
rx_msg_type     db ?
767
rx_msg_type     db ?
767
tx_msg          dhcp_msg
768
tx_msg          dhcp_msg
768
rx_msg          dhcp_msg
769
rx_msg          dhcp_msg
769
 
770
 
770
device_list     rd MAX_INTERFACES*sizeof.interface
771
device_list     rd MAX_INTERFACES*sizeof.interface
771
 
772
 
772
I_END:
773
I_END: