Rev 1011 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1011 | Rev 1102 | ||
---|---|---|---|
1 | ; Zero-config |
1 | ; Zero-config |
2 | ; v 1.4 |
2 | ; v 1.4 |
3 | ; |
3 | ; |
4 | ; DHCP code is based on that by Mike Hibbet (DHCP client for menuetos) |
4 | ; DHCP code is based on that by Mike Hibbet (DHCP client for menuetos) |
5 | ; |
5 | ; |
6 | ; Written by HidnPlayr & Derpenguin |
6 | ; Written by HidnPlayr & Derpenguin |
7 | 7 | ||
8 | use32 |
8 | use32 |
9 | org 0x0 |
9 | org 0x0 |
10 | 10 | ||
11 | db 'MENUET01' ; 8 byte id |
11 | db 'MENUET01' ; 8 byte id |
12 | dd 0x01 ; header version |
12 | dd 0x01 ; header version |
13 | dd START ; start of code |
13 | dd START ; start of code |
14 | dd IM_END ; size of image |
14 | dd IM_END ; size of image |
15 | dd I_END ; memory for app |
15 | dd I_END ; memory for app |
16 | dd I_END ; esp |
16 | dd I_END ; esp |
17 | dd 0x0 , path ; I_Param , I_Icon |
17 | dd 0x0 , path ; I_Param , I_Icon |
18 | 18 | ||
19 | ; CONFIGURATION |
19 | ; CONFIGURATION |
20 | 20 | ||
21 | 21 | ||
22 | TIMEOUT equ 60 ; in seconds |
22 | TIMEOUT equ 60 ; in seconds |
23 | BUFFER equ 1024 ; in bytes |
23 | BUFFER equ 1024 ; in bytes |
24 | __DEBUG__ equ 1 ; enable/disable |
24 | __DEBUG__ equ 1 ; enable/disable |
25 | __DEBUG_LEVEL__ equ 1 ; 1 = all, 2 = errors |
25 | __DEBUG_LEVEL__ equ 1 ; 1 = all, 2 = errors |
26 | 26 | ||
27 | ; CONFIGURATION FOR LINK-LOCAL |
27 | ; CONFIGURATION FOR LINK-LOCAL |
28 | 28 | ||
29 | PROBE_WAIT equ 1 ; second (initial random delay) |
29 | PROBE_WAIT equ 1 ; second (initial random delay) |
30 | PROBE_MIN equ 1 ; second (minimum delay till repeated probe) |
30 | PROBE_MIN equ 1 ; second (minimum delay till repeated probe) |
31 | PROBE_MAX equ 2 ; seconds (maximum delay till repeated probe) |
31 | PROBE_MAX equ 2 ; seconds (maximum delay till repeated probe) |
32 | PROBE_NUM equ 3 ; (number of probe packets) |
32 | PROBE_NUM equ 3 ; (number of probe packets) |
33 | 33 | ||
34 | ANNOUNCE_NUM equ 2 ; (number of announcement packets) |
34 | ANNOUNCE_NUM equ 2 ; (number of announcement packets) |
35 | ANNOUNCE_INTERVAL equ 2 ; seconds (time between announcement packets) |
35 | ANNOUNCE_INTERVAL equ 2 ; seconds (time between announcement packets) |
36 | ANNOUNCE_WAIT equ 2 ; seconds (delay before announcing) |
36 | ANNOUNCE_WAIT equ 2 ; seconds (delay before announcing) |
37 | 37 | ||
38 | MAX_CONFLICTS equ 10 ; (max conflicts before rate limiting) |
38 | MAX_CONFLICTS equ 10 ; (max conflicts before rate limiting) |
39 | 39 | ||
40 | RATE_LIMIT_INTERVAL equ 60 ; seconds (delay between successive attempts) |
40 | RATE_LIMIT_INTERVAL equ 60 ; seconds (delay between successive attempts) |
41 | 41 | ||
42 | DEFEND_INTERVAL equ 10 ; seconds (min. wait between defensive ARPs) |
42 | DEFEND_INTERVAL equ 10 ; seconds (min. wait between defensive ARPs) |
43 | 43 | ||
44 | include '../../../proc32.inc' |
44 | include '../../../proc32.inc' |
45 | include '../../../macros.inc' |
45 | include '../../../macros.inc' |
46 | include 'eth.inc' |
46 | include 'eth.inc' |
47 | include 'debug-fdo.inc' |
47 | include 'debug-fdo.inc' |
48 | include 'dhcp.inc' |
48 | include 'dhcp.inc' |
49 | include 'dll.inc' |
49 | include 'dll.inc' |
50 | 50 | ||
51 | START: ; start of execution |
51 | START: ; start of execution |
52 | 52 | ||
53 | mcall 40, 0 |
53 | mcall 40, 0 |
54 | 54 | ||
55 | eth.set_network_drv 0x00000383 |
55 | eth.set_network_drv 0x00000383 |
56 | 56 | ||
57 | DEBUGF 1,"Zero-config service:\n" |
57 | DEBUGF 1,"Zero-config service:\n" |
58 | 58 | ||
59 | eth.status eax ; Read the Stack status |
59 | eth.status eax ; Read the Stack status |
60 | test eax,eax ; if eax is zero, no driver was found |
60 | test eax,eax ; if eax is zero, no driver was found |
61 | jnz @f |
61 | jnz @f |
62 | DEBUGF 1,"No Card found!\n" |
62 | DEBUGF 1,"No Card found!\n" |
63 | jmp close |
63 | jmp close |
64 | 64 | ||
65 | @@: |
65 | @@: |
66 | DEBUGF 1,"Detected card: %x\n",eax |
66 | DEBUGF 1,"Detected card: %x\n",eax |
67 | @@: |
67 | @@: |
68 | eth.check_cable eax |
68 | eth.check_cable eax |
69 | test al,al |
69 | test al,al |
70 | jnz @f |
70 | jnz @f |
71 | DEBUGF 1,"Cable disconnected!\n" |
71 | DEBUGF 1,"Cable disconnected!\n" |
72 | mcall 5, 500 ; loop until cable is connected (check every 5 sec) |
72 | mcall 5, 500 ; loop until cable is connected (check every 5 sec) |
73 | jmp @r |
73 | jmp @r |
74 | 74 | ||
75 | @@: |
75 | @@: |
76 | eth.read_mac MAC |
76 | eth.read_mac MAC |
77 | 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 |
77 | 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 |
78 | 78 | ||
79 | cld |
79 | cld |
80 | mov edi, path ; Calculate the length of zero-terminated string |
80 | mov edi, path ; Calculate the length of zero-terminated string |
81 | xor al , al |
81 | xor al , al |
82 | mov ecx, 1024 |
82 | mov ecx, 1024 |
83 | repnz scas byte[es:edi] |
83 | repnz scas byte[es:edi] |
84 | dec edi |
84 | dec edi |
85 | 85 | ||
86 | mov esi, filename |
86 | mov esi, filename |
87 | mov ecx, 5 |
87 | mov ecx, 5 |
88 | rep movsb |
88 | rep movsb |
89 | 89 | ||
90 | mcall 68,11 |
90 | mcall 68,11 |
91 | 91 | ||
92 | stdcall dll.Load,@IMPORT |
92 | stdcall dll.Load,@IMPORT |
93 | or eax,eax |
93 | or eax,eax |
94 | jnz skip_ini |
94 | jnz skip_ini |
95 | 95 | ||
96 | 96 | ||
97 | invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0 |
97 | invoke ini.get_str, path, str_ipconfig, str_type, inibuf, 16, 0 |
98 | 98 | ||
99 | mov eax,dword[inibuf] |
99 | mov eax,dword[inibuf] |
100 | 100 | ||
101 | cmp eax,'stat' |
101 | cmp eax,'stat' |
102 | jne skip_ini |
102 | jne skip_ini |
103 | 103 | ||
104 | invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0 |
104 | invoke ini.get_str, path, str_ipconfig, str_ip, inibuf, 16, 0 |
105 | mov edx, inibuf |
105 | mov edx, inibuf |
106 | call Ip2dword |
106 | call Ip2dword |
107 | eth.set_IP edx |
107 | eth.set_IP edx |
108 | 108 | ||
109 | invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0 |
109 | invoke ini.get_str, path, str_ipconfig, str_gateway, inibuf, 16, 0 |
110 | mov edx, inibuf |
110 | mov edx, inibuf |
111 | call Ip2dword |
111 | call Ip2dword |
112 | eth.set_GATEWAY edx |
112 | eth.set_GATEWAY edx |
113 | 113 | ||
114 | invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0 |
114 | invoke ini.get_str, path, str_ipconfig, str_dns, inibuf, 16, 0 |
115 | mov edx, inibuf |
115 | mov edx, inibuf |
116 | call Ip2dword |
116 | call Ip2dword |
117 | eth.set_DNS edx |
117 | eth.set_DNS edx |
118 | 118 | ||
119 | invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0 |
119 | invoke ini.get_str, path, str_ipconfig, str_subnet, inibuf, 16, 0 |
120 | mov edx, inibuf |
120 | mov edx, inibuf |
121 | call Ip2dword |
121 | call Ip2dword |
122 | eth.set_SUBNET edx |
122 | eth.set_SUBNET edx |
123 | 123 | ||
124 | 124 | ||
125 | mcall -1 |
125 | mcall -1 |
126 | 126 | ||
127 | 127 | ||
128 | skip_ini: |
128 | skip_ini: |
129 | 129 | ||
130 | eth.check_port 68,eax ; Check if port 68 is available |
130 | eth.check_port 68,eax ; Check if port 68 is available |
131 | cmp eax,1 |
131 | cmp eax,1 |
132 | je @f |
132 | je @f |
133 | 133 | ||
134 | DEBUGF 1,"Port 68 is already in use!\n" |
134 | DEBUGF 1,"Port 68 is already in use!\n" |
135 | jmp close |
135 | jmp close |
136 | 136 | ||
137 | @@: |
137 | @@: |
138 | eth.open_udp 68,67,-1,[socketNum] ; open socket (local,remote,ip,socket) |
138 | eth.open_udp 68,67,-1,[socketNum] ; open socket (local,remote,ip,socket) |
139 | ; Setup the first msg we will send |
139 | ; Setup the first msg we will send |
140 | mov byte [dhcpMsgType], 0x01 ; DHCP discover |
140 | mov byte [dhcpMsgType], 0x01 ; DHCP discover |
141 | mov dword [dhcpLease], esi ; esi is still -1 (-1 = forever) |
141 | mov dword [dhcpLease], esi ; esi is still -1 (-1 = forever) |
142 | 142 | ||
143 | mcall 26, 9 |
143 | mcall 26, 9 |
144 | imul eax,100 |
144 | imul eax,100 |
145 | mov [currTime],eax |
145 | mov [currTime],eax |
146 | 146 | ||
147 | buildRequest: ; Creates a DHCP request packet. |
147 | buildRequest: ; Creates a DHCP request packet. |
148 | stdcall mem.Alloc, BUFFER |
148 | stdcall mem.Alloc, BUFFER |
149 | mov [dhcpMsg], eax |
149 | mov [dhcpMsg], eax |
150 | test eax,eax |
150 | test eax,eax |
151 | jz apipa |
151 | jz apipa |
152 | 152 | ||
153 | 153 | ||
154 | mov edi, eax |
154 | mov edi, eax |
155 | mov ecx,BUFFER |
155 | mov ecx,BUFFER |
156 | xor eax,eax |
156 | xor eax,eax |
157 | cld |
157 | cld |
158 | rep stosb |
158 | rep stosb |
159 | 159 | ||
160 | mov edx,[dhcpMsg] |
160 | mov edx,[dhcpMsg] |
161 | 161 | ||
162 | mov [edx], byte 0x01 ; Boot request |
162 | mov [edx], byte 0x01 ; Boot request |
163 | mov [edx+1], byte 0x01 ; Ethernet |
163 | mov [edx+1], byte 0x01 ; Ethernet |
164 | mov [edx+2], byte 0x06 ; Ethernet h/w len |
164 | mov [edx+2], byte 0x06 ; Ethernet h/w len |
165 | mov [edx+4], dword 0x11223344 ; xid |
165 | mov [edx+4], dword 0x11223344 ; xid |
166 | mov eax,[currTime] |
166 | mov eax,[currTime] |
167 | mov [edx+8], eax ; secs, our uptime |
167 | mov [edx+8], eax ; secs, our uptime |
168 | mov [edx+10], byte 0x80 ; broadcast flag set |
168 | mov [edx+10], byte 0x80 ; broadcast flag set |
169 | mov eax, dword [MAC] ; first 4 bytes of MAC |
169 | mov eax, dword [MAC] ; first 4 bytes of MAC |
170 | mov [edx+28],dword eax |
170 | mov [edx+28],dword eax |
171 | mov ax, word [MAC+4] ; last 2 bytes of MAC |
171 | mov ax, word [MAC+4] ; last 2 bytes of MAC |
172 | mov [edx+32],word ax |
172 | mov [edx+32],word ax |
173 | mov [edx+236], dword 0x63538263 ; magic number |
173 | mov [edx+236], dword 0x63538263 ; magic number |
174 | mov [edx+240], word 0x0135 ; option DHCP msg type |
174 | mov [edx+240], word 0x0135 ; option DHCP msg type |
175 | mov al, [dhcpMsgType] |
175 | mov al, [dhcpMsgType] |
176 | mov [edx+240+2], al |
176 | mov [edx+240+2], al |
177 | mov [edx+240+3], word 0x0433 ; option Lease time = infinity |
177 | mov [edx+240+3], word 0x0433 ; option Lease time = infinity |
178 | mov eax, [dhcpLease] |
178 | mov eax, [dhcpLease] |
179 | mov [edx+240+5], eax |
179 | mov [edx+240+5], eax |
180 | mov [edx+240+9], word 0x0432 ; option requested IP address |
180 | mov [edx+240+9], word 0x0432 ; option requested IP address |
181 | mov eax, [dhcpClientIP] |
181 | mov eax, [dhcpClientIP] |
182 | mov [edx+240+11], eax |
182 | mov [edx+240+11], eax |
183 | mov [edx+240+15], word 0x0437 ; option request list |
183 | mov [edx+240+15], word 0x0437 ; option request list |
184 | mov [edx+240+17], dword 0x0f060301 |
184 | mov [edx+240+17], dword 0x0f060301 |
185 | 185 | ||
186 | cmp [dhcpMsgType], byte 0x01 ; Check which msg we are sending |
186 | cmp [dhcpMsgType], byte 0x01 ; Check which msg we are sending |
187 | jne request_options |
187 | jne request_options |
188 | 188 | ||
189 | mov [edx+240+21], byte 0xff ; "Discover" options |
189 | mov [edx+240+21], byte 0xff ; "Discover" options |
190 | 190 | ||
191 | mov [dhcpMsgLen], dword 262 ; end of options marker |
191 | mov [dhcpMsgLen], dword 262 ; end of options marker |
192 | jmp send_request |
192 | jmp send_request |
193 | 193 | ||
194 | request_options: |
194 | request_options: |
195 | mov [edx+240+21], word 0x0436 ; server IP |
195 | mov [edx+240+21], word 0x0436 ; server IP |
196 | mov eax, [dhcpServerIP] |
196 | mov eax, [dhcpServerIP] |
197 | mov [edx+240+23], eax |
197 | mov [edx+240+23], eax |
198 | 198 | ||
199 | mov [edx+240+27], byte 0xff ; end of options marker |
199 | mov [edx+240+27], byte 0xff ; end of options marker |
200 | 200 | ||
201 | mov [dhcpMsgLen], dword 268 |
201 | mov [dhcpMsgLen], dword 268 |
202 | 202 | ||
203 | send_request: |
203 | send_request: |
204 | eth.write_udp [socketNum],[dhcpMsgLen],[dhcpMsg] ; write to socket ( send broadcast request ) |
204 | eth.write_udp [socketNum],[dhcpMsgLen],[dhcpMsg] ; write to socket ( send broadcast request ) |
205 | 205 | ||
206 | mov eax, [dhcpMsg] ; Setup the DHCP buffer to receive response |
206 | mov eax, [dhcpMsg] ; Setup the DHCP buffer to receive response |
207 | mov [dhcpMsgLen], eax ; Used as a pointer to the data |
207 | mov [dhcpMsgLen], eax ; Used as a pointer to the data |
208 | 208 | ||
209 | mov eax,23 ; wait here for event (data from remote) |
209 | mov eax,23 ; wait here for event (data from remote) |
210 | mov ebx,TIMEOUT*10 |
210 | mov ebx,TIMEOUT*10 |
211 | mcall |
211 | mcall |
212 | 212 | ||
213 | eth.poll [socketNum] |
213 | eth.poll [socketNum] |
214 | 214 | ||
215 | test eax,eax |
215 | test eax,eax |
216 | jnz read_data |
216 | jnz read_data |
217 | 217 | ||
218 | DEBUGF 2,"Timeout!\n" |
218 | DEBUGF 2,"Timeout!\n" |
219 | eth.close_udp [socketNum] |
219 | eth.close_udp [socketNum] |
220 | jmp apipa ; no server found, lets try zeroconf |
220 | jmp apipa ; no server found, lets try zeroconf |
221 | 221 | ||
222 | 222 | ||
223 | read_data: ; we have data - this will be the response |
223 | read_data: ; we have data - this will be the response |
224 | eth.read_packet [socketNum], [dhcpMsg], BUFFER |
224 | eth.read_packet [socketNum], [dhcpMsg], BUFFER |
225 | mov [dhcpMsgLen], eax |
225 | mov [dhcpMsgLen], eax |
226 | eth.close_udp [socketNum] |
226 | eth.close_udp [socketNum] |
227 | 227 | ||
228 | ; depending on which msg we sent, handle the response |
228 | ; depending on which msg we sent, handle the response |
229 | ; accordingly. |
229 | ; accordingly. |
230 | ; If the response is to a dhcp discover, then: |
230 | ; If the response is to a dhcp discover, then: |
231 | ; 1) If response is DHCP OFFER then |
231 | ; 1) If response is DHCP OFFER then |
232 | ; 1.1) record server IP, lease time & IP address. |
232 | ; 1.1) record server IP, lease time & IP address. |
233 | ; 1.2) send a request packet |
233 | ; 1.2) send a request packet |
234 | ; If the response is to a dhcp request, then: |
234 | ; If the response is to a dhcp request, then: |
235 | ; 1) If the response is DHCP ACK then |
235 | ; 1) If the response is DHCP ACK then |
236 | ; 1.1) extract the DNS & subnet fields. Set them in the stack |
236 | ; 1.1) extract the DNS & subnet fields. Set them in the stack |
237 | 237 | ||
238 | cmp [dhcpMsgType], byte 0x01 ; did we send a discover? |
238 | cmp [dhcpMsgType], byte 0x01 ; did we send a discover? |
239 | je discover |
239 | je discover |
240 | cmp [dhcpMsgType], byte 0x03 ; did we send a request? |
240 | cmp [dhcpMsgType], byte 0x03 ; did we send a request? |
241 | je request |
241 | je request |
242 | 242 | ||
243 | jmp close ; really unknown, what we did |
243 | jmp close ; really unknown, what we did |
244 | 244 | ||
245 | discover: |
245 | discover: |
246 | call parseResponse |
246 | call parseResponse |
247 | 247 | ||
248 | cmp [dhcpMsgType], byte 0x02 ; Was the response an offer? |
248 | cmp [dhcpMsgType], byte 0x02 ; Was the response an offer? |
249 | jne apipa ; NO - so we do zeroconf |
249 | jne apipa ; NO - so we do zeroconf |
250 | mov [dhcpMsgType], byte 0x03 ; DHCP request |
250 | mov [dhcpMsgType], byte 0x03 ; DHCP request |
251 | jmp buildRequest |
251 | jmp buildRequest |
252 | 252 | ||
253 | request: |
253 | request: |
254 | call parseResponse |
254 | call parseResponse |
255 | 255 | ||
256 | cmp [dhcpMsgType], byte 0x05 ; Was the response an ACK? It should be |
256 | cmp [dhcpMsgType], byte 0x05 ; Was the response an ACK? It should be |
257 | jne apipa ; NO - so we do zeroconf |
257 | jne apipa ; NO - so we do zeroconf |
258 | 258 | ||
259 | jmp close |
259 | jmp close |
260 | 260 | ||
261 | ;*************************************************************************** |
261 | ;*************************************************************************** |
262 | ; Function |
262 | ; Function |
263 | ; parseResponse |
263 | ; parseResponse |
264 | ; |
264 | ; |
265 | ; Description |
265 | ; Description |
266 | ; extracts the fields ( client IP address and options ) from |
266 | ; extracts the fields ( client IP address and options ) from |
267 | ; a DHCP response |
267 | ; a DHCP response |
268 | ; The values go into |
268 | ; The values go into |
269 | ; dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP, |
269 | ; dhcpMsgType,dhcpLease,dhcpClientIP,dhcpServerIP, |
270 | ; dhcpDNSIP, dhcpSubnet |
270 | ; dhcpDNSIP, dhcpSubnet |
271 | ; The message is stored in dhcpMsg |
271 | ; The message is stored in dhcpMsg |
272 | ; |
272 | ; |
273 | ;*************************************************************************** |
273 | ;*************************************************************************** |
274 | parseResponse: |
274 | parseResponse: |
275 | DEBUGF 1,"Data received, parsing response\n" |
275 | DEBUGF 1,"Data received, parsing response\n" |
276 | mov edx, [dhcpMsg] |
276 | mov edx, [dhcpMsg] |
277 | 277 | ||
278 | pusha |
278 | pusha |
279 | eth.set_IP [edx+16] |
279 | eth.set_IP [edx+16] |
280 | mov eax,[edx] |
280 | mov eax,[edx] |
281 | mov [dhcpClientIP],eax |
281 | mov [dhcpClientIP],eax |
282 | DEBUGF 1,"Client: %u.%u.%u.%u\n",[edx+16]:1,[edx+17]:1,[edx+18]:1,[edx+19]:1 |
282 | DEBUGF 1,"Client: %u.%u.%u.%u\n",[edx+16]:1,[edx+17]:1,[edx+18]:1,[edx+19]:1 |
283 | popa |
283 | popa |
284 | 284 | ||
285 | add edx, 240 ; Point to first option |
285 | add edx, 240 ; Point to first option |
286 | xor ecx, ecx |
286 | xor ecx, ecx |
287 | 287 | ||
288 | next_option: |
288 | next_option: |
289 | add edx, ecx |
289 | add edx, ecx |
290 | pr001: |
290 | pr001: |
291 | mov al, [edx] |
291 | mov al, [edx] |
292 | cmp al, 0xff ; End of options? |
292 | cmp al, 0xff ; End of options? |
293 | je pr_exit |
293 | je pr_exit |
294 | 294 | ||
295 | cmp al, dhcp_msg_type ; Msg type is a single byte option |
295 | cmp al, dhcp_msg_type ; Msg type is a single byte option |
296 | jne @f |
296 | jne @f |
297 | 297 | ||
298 | mov al, [edx+2] |
298 | mov al, [edx+2] |
299 | mov [dhcpMsgType], al |
299 | mov [dhcpMsgType], al |
300 | add edx, 3 |
300 | add edx, 3 |
301 | jmp pr001 ; Get next option |
301 | jmp pr001 ; Get next option |
302 | 302 | ||
303 | @@: |
303 | @@: |
304 | inc edx |
304 | inc edx |
305 | movzx ecx, byte [edx] |
305 | movzx ecx, byte [edx] |
306 | inc edx ; point to data |
306 | inc edx ; point to data |
307 | 307 | ||
308 | cmp al, dhcp_dhcp_server_id ; server ip |
308 | cmp al, dhcp_dhcp_server_id ; server ip |
309 | jne @f |
309 | jne @f |
310 | mov eax, [edx] |
310 | mov eax, [edx] |
311 | mov [dhcpServerIP], eax |
311 | mov [dhcpServerIP], eax |
312 | DEBUGF 1,"Server: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1 |
312 | DEBUGF 1,"Server: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1 |
313 | jmp next_option |
313 | jmp next_option |
314 | 314 | ||
315 | @@: |
315 | @@: |
316 | cmp al, dhcp_address_time |
316 | cmp al, dhcp_address_time |
317 | jne @f |
317 | jne @f |
318 | 318 | ||
319 | pusha |
319 | pusha |
320 | mov eax,[edx] |
320 | mov eax,[edx] |
321 | bswap eax |
321 | bswap eax |
322 | mov [dhcpLease],eax |
322 | mov [dhcpLease],eax |
323 | DEBUGF 1,"lease: %d\n",eax |
323 | DEBUGF 1,"lease: %d\n",eax |
324 | popa |
324 | popa |
325 | 325 | ||
326 | jmp next_option |
326 | jmp next_option |
327 | 327 | ||
328 | @@: |
328 | @@: |
329 | cmp al, dhcp_subnet_mask |
329 | cmp al, dhcp_subnet_mask |
330 | jne @f |
330 | jne @f |
331 | 331 | ||
332 | pusha |
332 | pusha |
333 | eth.set_SUBNET [edx] |
333 | eth.set_SUBNET [edx] |
334 | DEBUGF 1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1 |
334 | DEBUGF 1,"Subnet: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1 |
335 | popa |
335 | popa |
336 | 336 | ||
337 | jmp next_option |
337 | jmp next_option |
338 | 338 | ||
339 | @@: |
339 | @@: |
340 | cmp al, dhcp_router |
340 | cmp al, dhcp_router |
341 | jne @f |
341 | jne @f |
342 | 342 | ||
343 | pusha |
343 | pusha |
344 | eth.set_GATEWAY [edx] |
344 | eth.set_GATEWAY [edx] |
345 | DEBUGF 1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1 |
345 | DEBUGF 1,"Gateway: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1 |
346 | popa |
346 | popa |
347 | 347 | ||
348 | jmp next_option |
348 | jmp next_option |
349 | 349 | ||
350 | 350 | ||
351 | @@: |
351 | @@: |
352 | cmp al, dhcp_domain_server |
352 | cmp al, dhcp_domain_server |
353 | jne next_option |
353 | jne next_option |
354 | 354 | ||
355 | pusha |
355 | pusha |
356 | eth.set_DNS [edx] |
356 | eth.set_DNS [edx] |
357 | DEBUGF 1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1 |
357 | DEBUGF 1,"DNS: %u.%u.%u.%u\n",[edx]:1,[edx+1]:1,[edx+2]:1,[edx+3]:1 |
358 | popa |
358 | popa |
359 | 359 | ||
360 | jmp next_option |
360 | jmp next_option |
361 | 361 | ||
362 | pr_exit: |
362 | pr_exit: |
363 | 363 | ||
364 | ; DEBUGF 1,"Sending ARP announce\n" |
364 | ; DEBUGF 1,"Sending ARP announce\n" |
365 | ; eth.ARP_ANNOUNCE [dhcpClientIP] ; send an ARP announce packet |
365 | ; eth.ARP_ANNOUNCE [dhcpClientIP] ; send an ARP announce packet |
366 | 366 | ||
367 | jmp close |
367 | jmp close |
368 | 368 | ||
369 | apipa: |
369 | apipa: |
370 | stdcall mem.Free, [dhcpMsg] |
370 | stdcall mem.Free, [dhcpMsg] |
371 | 371 | ||
372 | link_local: |
372 | link_local: |
373 | call random |
373 | call random |
374 | mov ecx,0xfea9 ; IP 169.254.0.0 link local net, see RFC3927 |
374 | mov ecx,0xfea9 ; IP 169.254.0.0 link local net, see RFC3927 |
375 | mov cx,ax |
375 | mov cx,ax |
376 | eth.set_IP ecx ; mask is 255.255.0.0 |
376 | eth.set_IP ecx ; mask is 255.255.0.0 |
377 | DEBUGF 1,"Link Local IP assinged: 169.254.%u.%u\n",[generator+2]:1,[generator+3]:1 |
377 | DEBUGF 1,"Link Local IP assinged: 169.254.%u.%u\n",[generator+2]:1,[generator+3]:1 |
378 | eth.set_SUBNET 0xffff |
378 | eth.set_SUBNET 0xffff |
379 | eth.set_GATEWAY 0x0 |
379 | eth.set_GATEWAY 0x0 |
380 | eth.set_DNS 0x0 |
380 | eth.set_DNS 0x0 |
381 | 381 | ||
382 | mcall 5, PROBE_WAIT*100 |
382 | mcall 5, PROBE_WAIT*100 |
383 | 383 | ||
384 | xor esi,esi |
384 | xor esi,esi |
385 | probe_loop: |
385 | probe_loop: |
386 | call random ; create a pseudo random number in eax (seeded by MAC) |
386 | call random ; create a pseudo random number in eax (seeded by MAC) |
387 | 387 | ||
388 | cmp al,PROBE_MIN*100 ; check if al is bigger then PROBE_MIN |
388 | cmp al,PROBE_MIN*100 ; check if al is bigger then PROBE_MIN |
389 | jge @f ; all ok |
389 | jge @f ; all ok |
390 | add al,(PROBE_MAX-PROBE_MIN)*100 ; al is too small |
390 | add al,(PROBE_MAX-PROBE_MIN)*100 ; al is too small |
391 | @@: |
391 | @@: |
392 | 392 | ||
393 | cmp al,PROBE_MAX*100 |
393 | cmp al,PROBE_MAX*100 |
394 | jle @f |
394 | jle @f |
395 | sub al,(PROBE_MAX-PROBE_MIN)*100 |
395 | sub al,(PROBE_MAX-PROBE_MIN)*100 |
396 | @@: |
396 | @@: |
397 | 397 | ||
398 | movzx ebx,al |
398 | movzx ebx,al |
399 | DEBUGF 1,"Waiting %u0ms\n",ebx |
399 | DEBUGF 1,"Waiting %u0ms\n",ebx |
400 | mcall 5 |
400 | mcall 5 |
401 | 401 | ||
402 | DEBUGF 1,"Sending Probe\n" |
402 | DEBUGF 1,"Sending Probe\n" |
403 | ; eth.ARP_PROBE MAC |
403 | ; eth.ARP_PROBE MAC |
404 | inc esi |
404 | inc esi |
405 | 405 | ||
406 | cmp esi,PROBE_NUM |
406 | cmp esi,PROBE_NUM |
407 | jl probe_loop |
407 | jl probe_loop |
408 | 408 | ||
409 | ; now we wait further ANNOUNCE_WAIT seconds and send ANNOUNCE_NUM ARP announces. If any other host has assingned |
409 | ; now we wait further ANNOUNCE_WAIT seconds and send ANNOUNCE_NUM ARP announces. If any other host has assingned |
410 | ; IP within this time, we should create another adress, that have to be done later |
410 | ; IP within this time, we should create another adress, that have to be done later |
411 | 411 | ||
412 | DEBUGF 1,"Waiting %us\n",ANNOUNCE_WAIT |
412 | DEBUGF 1,"Waiting %us\n",ANNOUNCE_WAIT |
413 | mcall 5, ANNOUNCE_WAIT*100 |
413 | mcall 5, ANNOUNCE_WAIT*100 |
414 | xor esi,esi |
414 | xor esi,esi |
415 | announce_loop: |
415 | announce_loop: |
416 | 416 | ||
417 | DEBUGF 1,"Sending Announce\n" |
417 | DEBUGF 1,"Sending Announce\n" |
418 | ; eth.ARP_ANNOUNCE MAC |
418 | ; eth.ARP_ANNOUNCE MAC |
419 | 419 | ||
420 | inc esi |
420 | inc esi |
421 | cmp esi,ANNOUNCE_NUM |
421 | cmp esi,ANNOUNCE_NUM |
422 | je @f |
422 | je @f |
423 | 423 | ||
424 | DEBUGF 1,"Waiting %us\n",ANNOUNCE_INTERVAL |
424 | DEBUGF 1,"Waiting %us\n",ANNOUNCE_INTERVAL |
425 | mcall 5, ANNOUNCE_INTERVAL*100 |
425 | mcall 5, ANNOUNCE_INTERVAL*100 |
426 | jmp announce_loop |
426 | jmp announce_loop |
427 | @@: |
427 | @@: |
428 | ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;) |
428 | ; we should, instead of closing, detect ARP conflicts and detect if cable keeps connected ;) |
429 | 429 | ||
430 | close: |
430 | close: |
431 | mcall -1 |
431 | mcall -1 |
432 | 432 | ||
433 | 433 | ||
434 | random: ; Pseudo random actually |
434 | random: ; Pseudo random actually |
435 | 435 | ||
436 | mov eax,[generator] |
436 | mov eax,[generator] |
437 | add eax,-43ab45b5h |
437 | add eax,-43ab45b5h |
438 | ror eax,1 |
438 | ror eax,1 |
439 | bswap eax |
439 | bswap eax |
440 | xor eax,dword[MAC] |
440 | xor eax,dword[MAC] |
441 | ror eax,1 |
441 | ror eax,1 |
442 | xor eax,dword[MAC+2] |
442 | xor eax,dword[MAC+2] |
443 | mov [generator],eax |
443 | mov [generator],eax |
444 | 444 | ||
445 | ret |
445 | ret |
446 | 446 | ||
447 | ; DATA AREA |
447 | ; DATA AREA |
448 | 448 | ||
449 | align 16 |
449 | align 16 |
450 | @IMPORT: |
450 | @IMPORT: |
451 | 451 | ||
452 | library \ |
452 | library \ |
453 | libini,'libini.obj' |
453 | libini,'libini.obj' |
454 | 454 | ||
455 | import libini, \ |
455 | import libini, \ |
456 | ini.get_str,'ini.get_str' |
456 | ini.get_str,'ini_get_str' |
457 | 457 | ||
458 | include_debug_strings |
458 | include_debug_strings |
459 | 459 | ||
460 | filename db '.ini',0 |
460 | filename db '.ini',0 |
461 | str_ip db 'ip',0 |
461 | str_ip db 'ip',0 |
462 | str_subnet db 'subnet',0 |
462 | str_subnet db 'subnet',0 |
463 | str_gateway db 'gateway',0 |
463 | str_gateway db 'gateway',0 |
464 | str_dns db 'dns',0 |
464 | str_dns db 'dns',0 |
465 | str_ipconfig db 'ipconfig',0 |
465 | str_ipconfig db 'ipconfig',0 |
466 | str_type db 'type',0 |
466 | str_type db 'type',0 |
467 | 467 | ||
468 | 468 | ||
469 | IM_END: |
469 | IM_END: |
470 | 470 | ||
471 | inibuf rb 16 |
471 | inibuf rb 16 |
472 | 472 | ||
473 | dhcpClientIP dd ? |
473 | dhcpClientIP dd ? |
474 | dhcpMsgType db ? |
474 | dhcpMsgType db ? |
475 | dhcpLease dd ? |
475 | dhcpLease dd ? |
476 | dhcpServerIP dd ? |
476 | dhcpServerIP dd ? |
477 | 477 | ||
478 | dhcpMsgLen dd ? |
478 | dhcpMsgLen dd ? |
479 | socketNum dd ? |
479 | socketNum dd ? |
480 | 480 | ||
481 | MAC dp ? |
481 | MAC dp ? |
482 | currTime dd ? |
482 | currTime dd ? |
483 | renewTime dd ? |
483 | renewTime dd ? |
484 | generator dd ? |
484 | generator dd ? |
485 | 485 | ||
486 | dhcpMsg dd ? |
486 | dhcpMsg dd ? |
487 | 487 | ||
488 | I_END_2: |
488 | I_END_2: |
489 | 489 | ||
490 | path rb 1024+5 |
490 | path rb 1024+5 |
491 | 491 | ||
492 | I_END: |
492 | I_END: |