Rev 1530 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1196 | hidnplayr | 1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
||
1514 | hidnplayr | 3 | ;; Copyright (C) KolibriOS team 2004-2010. All rights reserved. ;; |
1196 | hidnplayr | 4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
||
6 | ;; ARP.INC ;; |
||
7 | ;; ;; |
||
8 | ;; Part of the tcp/ip network stack for KolibriOS ;; |
||
9 | ;; ;; |
||
10 | ;; Based on the work of [Johnny_B] and [smb] ;; |
||
11 | ;; ;; |
||
12 | ;; Written by hidnplayr@kolibrios.org ;; |
||
13 | ;; ;; |
||
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
||
1529 | hidnplayr | 15 | ;; Version 2, June- 1991 ;; |
1196 | hidnplayr | 16 | ;; ;; |
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
||
1159 | hidnplayr | 18 | |
1206 | hidnplayr | 19 | $Revision: 1533 $ |
1159 | hidnplayr | 20 | |
1529 | hidnplayr | 21 | ARP_NO_ENTRY equ 0 |
22 | ARP_VALID_MAPPING equ 1 |
||
23 | ARP_AWAITING_RESPONSE equ 2 |
||
24 | ARP_RESPONSE_TIMEOUT equ 3 |
||
1159 | hidnplayr | 25 | |
1529 | hidnplayr | 26 | ARP_REQUEST_TTL equ 31 ; 20 s |
27 | ARP_ENTRY_TTL equ 937 ; 600 s |
||
1159 | hidnplayr | 28 | |
1529 | hidnplayr | 29 | ARP_REQ_OPCODE equ 0x0100 ; request |
30 | ARP_REP_OPCODE equ 0x0200 ; reply |
||
1196 | hidnplayr | 31 | |
1529 | hidnplayr | 32 | ARP_TABLE_SIZE equ 20 ; Size of table |
1159 | hidnplayr | 33 | |
34 | struct ARP_ENTRY |
||
35 | .IP dd ? |
||
36 | .MAC dp ? |
||
37 | .Status dw ? |
||
1529 | hidnplayr | 38 | .TTL dw ? |
1159 | hidnplayr | 39 | .size: |
40 | ends |
||
41 | |||
42 | struct ARP_Packet |
||
43 | .HardwareType dw ? |
||
44 | .ProtocolType dw ? |
||
45 | .HardwareSize db ? |
||
46 | .ProtocolSize db ? |
||
47 | .Opcode dw ? |
||
48 | .SenderMAC dp ? |
||
49 | .SenderIP dd ? |
||
50 | .TargetMAC dp ? |
||
51 | .TargetIP dd ? |
||
1529 | hidnplayr | 52 | .size: |
1159 | hidnplayr | 53 | ends |
54 | |||
55 | |||
56 | align 4 |
||
57 | uglobal |
||
58 | |||
59 | NumARP dd ? |
||
1258 | hidnplayr | 60 | |
1529 | hidnplayr | 61 | ARP_table rb ARP_ENTRY.size * ARP_TABLE_SIZE |
1159 | hidnplayr | 62 | |
1529 | hidnplayr | 63 | ARP_PACKETS_TX rd MAX_NET_DEVICES |
64 | ARP_PACKETS_RX rd MAX_NET_DEVICES |
||
1159 | hidnplayr | 65 | |
66 | |||
67 | endg |
||
68 | |||
69 | |||
70 | |||
1196 | hidnplayr | 71 | ;----------------------------------------------------------------- |
72 | ; |
||
73 | ; ARP_init |
||
74 | ; |
||
75 | ; This function resets all ARP variables |
||
76 | ; |
||
77 | ;----------------------------------------------------------------- |
||
1529 | hidnplayr | 78 | macro ARP_init { |
1159 | hidnplayr | 79 | |
80 | xor eax, eax |
||
81 | mov [NumARP], eax |
||
82 | |||
83 | mov edi, ARP_PACKETS_TX |
||
84 | mov ecx, 2*MAX_NET_DEVICES |
||
85 | rep stosd |
||
86 | |||
1529 | hidnplayr | 87 | } |
1159 | hidnplayr | 88 | |
1529 | hidnplayr | 89 | ;--------------------------------------------------------------------------- |
1159 | hidnplayr | 90 | ; |
1529 | hidnplayr | 91 | ; ARP_decrease_entry_ttls |
1159 | hidnplayr | 92 | ; |
1529 | hidnplayr | 93 | ;--------------------------------------------------------------------------- |
1159 | hidnplayr | 94 | |
1529 | hidnplayr | 95 | macro ARP_decrease_entry_ttls { |
1159 | hidnplayr | 96 | |
1529 | hidnplayr | 97 | local .loop |
98 | local .exit |
||
1159 | hidnplayr | 99 | |
1529 | hidnplayr | 100 | ; The TTL field is decremented every second, and is deleted when it reaches 0. |
101 | ; It is refreshed every time a packet is received. |
||
102 | ; If the TTL field is 0xFFFF it is a static entry and is never deleted. |
||
103 | ; The status field can be the following values: |
||
104 | ; 0x0000 entry not used |
||
105 | ; 0x0001 entry holds a valid mapping |
||
106 | ; 0x0002 entry contains an IP address, awaiting ARP response |
||
107 | ; 0x0003 No response received to ARP request. |
||
108 | ; The last status value is provided to allow the network layer to delete |
||
109 | ; a packet that is queued awaiting an ARP response |
||
1159 | hidnplayr | 110 | |
1529 | hidnplayr | 111 | mov ecx, [NumARP] |
112 | test ecx, ecx |
||
113 | jz .exit |
||
1206 | hidnplayr | 114 | |
1529 | hidnplayr | 115 | mov esi, ARP_table |
116 | .loop: |
||
117 | cmp [esi + ARP_ENTRY.TTL], 0xffff ; 0xffff = static entry |
||
118 | je .next |
||
1206 | hidnplayr | 119 | |
1529 | hidnplayr | 120 | dec [esi + ARP_ENTRY.TTL] |
121 | jz .time_out |
||
1159 | hidnplayr | 122 | |
1529 | hidnplayr | 123 | .next: |
1206 | hidnplayr | 124 | add esi, ARP_ENTRY.size |
1529 | hidnplayr | 125 | loop .loop |
126 | jmp .exit |
||
1159 | hidnplayr | 127 | |
1529 | hidnplayr | 128 | .time_out: |
129 | cmp [esi + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
||
130 | jz .response_timeout |
||
1159 | hidnplayr | 131 | |
1529 | hidnplayr | 132 | push esi ecx |
133 | call ARP_del_entry |
||
134 | pop ecx esi |
||
1159 | hidnplayr | 135 | |
1529 | hidnplayr | 136 | jmp .next |
1159 | hidnplayr | 137 | |
1529 | hidnplayr | 138 | .response_timeout: |
139 | mov [esi + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
||
140 | mov [esi + ARP_ENTRY.TTL], 10 |
||
1159 | hidnplayr | 141 | |
1529 | hidnplayr | 142 | jmp .next |
1258 | hidnplayr | 143 | |
1529 | hidnplayr | 144 | .exit: |
1258 | hidnplayr | 145 | |
1529 | hidnplayr | 146 | } |
1159 | hidnplayr | 147 | |
1258 | hidnplayr | 148 | |
1529 | hidnplayr | 149 | ;----------------------------------------------------------------- |
150 | ; |
||
151 | ; ARP_input |
||
152 | ; |
||
153 | ; IN: Pointer to buffer in [esp] |
||
154 | ; size of buffer in [esp+4] |
||
155 | ; packet size (without ethernet header) in ecx |
||
156 | ; OUT: / |
||
157 | ; |
||
158 | ;----------------------------------------------------------------- |
||
159 | align 4 |
||
160 | ARP_input: |
||
1258 | hidnplayr | 161 | |
1529 | hidnplayr | 162 | DEBUGF 1,"ARP_Handler - start\n" |
163 | cmp ecx, 28 |
||
164 | jl .exit |
||
1258 | hidnplayr | 165 | |
1529 | hidnplayr | 166 | ;--------------------- |
167 | ; Handle Reply packets |
||
1258 | hidnplayr | 168 | |
1529 | hidnplayr | 169 | cmp word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE |
170 | jne .maybe_request |
||
1159 | hidnplayr | 171 | |
1529 | hidnplayr | 172 | DEBUGF 1,"ARP_Handler - it's a reply packet from %u.%u.%u.%u\n",\ |
173 | [edx + ARP_Packet.SenderIP]:1,[edx + ARP_Packet.SenderIP+1]:1,[edx + ARP_Packet.SenderIP+2]:1,[edx + ARP_Packet.SenderIP+3]:1, |
||
1159 | hidnplayr | 174 | |
1529 | hidnplayr | 175 | mov ecx, [NumARP] |
176 | test ecx, ecx |
||
177 | jz .exit |
||
1159 | hidnplayr | 178 | |
1529 | hidnplayr | 179 | mov eax, [edx + ARP_Packet.SenderIP] |
180 | mov esi, ARP_table |
||
1196 | hidnplayr | 181 | |
1529 | hidnplayr | 182 | .loop: |
183 | cmp [esi + ARP_ENTRY.IP], eax |
||
184 | je .gotit |
||
185 | add esi, ARP_ENTRY.size |
||
186 | loop .loop |
||
1258 | hidnplayr | 187 | |
1529 | hidnplayr | 188 | jmp .exit |
1159 | hidnplayr | 189 | |
1529 | hidnplayr | 190 | .gotit: |
191 | DEBUGF 1,"ARP_Handler - found matching entry\n" |
||
1159 | hidnplayr | 192 | |
1529 | hidnplayr | 193 | cmp [esi+ARP_ENTRY.TTL], 0xffff ; if it is a static entry, dont touch it |
194 | je .exit |
||
1159 | hidnplayr | 195 | |
1529 | hidnplayr | 196 | DEBUGF 1,"ARP_Handler - updating entry\n" |
1159 | hidnplayr | 197 | |
1529 | hidnplayr | 198 | mov [esi+ARP_ENTRY.Status], ARP_VALID_MAPPING |
199 | mov [esi+ARP_ENTRY.TTL], ARP_ENTRY_TTL |
||
200 | |||
201 | mov eax, dword [edx + ARP_Packet.SenderMAC] |
||
202 | mov dword [esi+ARP_ENTRY.MAC], eax |
||
203 | mov ax , word [edx + ARP_Packet.SenderMAC + 4] |
||
204 | mov word [esi+ARP_ENTRY.MAC+4], ax |
||
205 | |||
206 | jmp .exit |
||
207 | |||
208 | |||
209 | ;----------------------- |
||
210 | ; Handle Request packets |
||
211 | |||
212 | .maybe_request: |
||
213 | cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE |
||
214 | jne .exit |
||
215 | |||
216 | call NET_ptr_to_num |
||
217 | cmp edi, -1 |
||
1514 | hidnplayr | 218 | jz .exit |
1529 | hidnplayr | 219 | DEBUGF 1,"ARP Request packet through device: %u\n", edi |
220 | inc [ARP_PACKETS_RX+4*edi] |
||
1159 | hidnplayr | 221 | |
1529 | hidnplayr | 222 | mov eax, [IP_LIST+4*edi] |
223 | cmp eax, [edx + ARP_Packet.TargetIP] ; Is it looking for my IP address? |
||
224 | jne .exit ; TODO: instead of quitting, update local entrys with matching IP's ? |
||
1159 | hidnplayr | 225 | |
1529 | hidnplayr | 226 | push eax |
227 | push edi |
||
1206 | hidnplayr | 228 | |
1529 | hidnplayr | 229 | ; OK, it is a request for one of our MAC addresses. |
230 | ; Build the frame and send it. We can reuse the buffer. (faster then using ARP_create_packet) |
||
231 | |||
232 | lea esi, [edx + ARP_Packet.SenderMAC] |
||
233 | lea edi, [edx + ARP_Packet.TargetMAC] |
||
234 | movsd ; Move Sender Mac to Dest MAC |
||
1196 | hidnplayr | 235 | movsw ; |
1529 | hidnplayr | 236 | movsd ; Move sender IP to Dest IP |
237 | |||
238 | pop esi |
||
239 | mov esi, [NET_DRV_LIST + 4*esi] |
||
240 | lea esi, [esi + ETH_DEVICE.mac] |
||
241 | lea edi, [edx + ARP_Packet.SenderMAC] |
||
242 | movsd ; Copy MAC address from in MAC_LIST |
||
243 | movsw ; |
||
1196 | hidnplayr | 244 | pop eax |
1529 | hidnplayr | 245 | stosd ; Write our IP |
1159 | hidnplayr | 246 | |
1529 | hidnplayr | 247 | mov word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE |
1159 | hidnplayr | 248 | |
1529 | hidnplayr | 249 | ; Now, Fill in ETHERNET header |
250 | |||
251 | mov edi, [esp] |
||
252 | lea esi, [edx + ARP_Packet.TargetMAC] |
||
253 | movsd |
||
254 | movsw |
||
255 | lea esi, [edx + ARP_Packet.SenderMAC] |
||
256 | movsd |
||
257 | movsw |
||
258 | ; mov ax , ETHER_ARP |
||
259 | ; stosw |
||
260 | |||
261 | DEBUGF 1,"ARP_Handler - Sending reply \n" |
||
262 | |||
1519 | hidnplayr | 263 | call [ebx + NET_DEVICE.transmit] |
264 | ret |
||
1159 | hidnplayr | 265 | |
1529 | hidnplayr | 266 | .exit: |
267 | call kernel_free |
||
268 | add esp, 4 ; pop (balance stack) |
||
269 | |||
270 | DEBUGF 1,"ARP_Handler - exiting\n" |
||
1196 | hidnplayr | 271 | ret |
1159 | hidnplayr | 272 | |
273 | |||
1185 | hidnplayr | 274 | ;--------------------------------------------------------------------------- |
275 | ; |
||
1529 | hidnplayr | 276 | ; ARP_output_request |
1185 | hidnplayr | 277 | ; |
1529 | hidnplayr | 278 | ; IN: ip in eax |
1185 | hidnplayr | 279 | ; OUT: / |
280 | ; |
||
281 | ;--------------------------------------------------------------------------- |
||
282 | align 4 |
||
1529 | hidnplayr | 283 | ARP_output_request: |
1185 | hidnplayr | 284 | |
1529 | hidnplayr | 285 | DEBUGF 1,"Create ARP Packet\n" |
1185 | hidnplayr | 286 | |
1529 | hidnplayr | 287 | call IPv4_dest_to_dev |
288 | push eax ; DestIP |
||
289 | pushd [IP_LIST+edi] ; SenderIP |
||
1185 | hidnplayr | 290 | |
1529 | hidnplayr | 291 | mov ebx, [NET_DRV_LIST+edi] ; device ptr |
1185 | hidnplayr | 292 | |
1529 | hidnplayr | 293 | lea eax, [ebx + ETH_DEVICE.mac] ; local device mac |
294 | mov edx, ETH_BROADCAST ; broadcast mac |
||
295 | mov ecx, ARP_Packet.size |
||
296 | mov di, ETHER_ARP |
||
297 | call ETH_output |
||
298 | jz .exit |
||
1185 | hidnplayr | 299 | |
1529 | hidnplayr | 300 | mov ecx, eax |
1185 | hidnplayr | 301 | |
1529 | hidnplayr | 302 | mov [edi + ARP_Packet.HardwareType], 0x0100 ; Ethernet |
303 | mov [edi + ARP_Packet.ProtocolType], 0x0008 ; IP |
||
304 | mov [edi + ARP_Packet.HardwareSize], 6 ; MAC-addr length |
||
305 | mov [edi + ARP_Packet.ProtocolSize], 4 ; IP-addr length |
||
306 | mov [edi + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Request |
||
1185 | hidnplayr | 307 | |
1529 | hidnplayr | 308 | add edi, ARP_Packet.SenderMAC |
1185 | hidnplayr | 309 | |
1529 | hidnplayr | 310 | lea esi, [ebx + ETH_DEVICE.mac] ; SenderMac |
311 | movsw ; |
||
312 | movsd ; |
||
313 | pop eax ; SenderIP |
||
314 | stosd ; |
||
1185 | hidnplayr | 315 | |
1529 | hidnplayr | 316 | mov eax, -1 ; DestMac |
317 | stosd ; |
||
318 | stosw ; |
||
319 | pop eax ; DestIP |
||
320 | stosd ; |
||
1185 | hidnplayr | 321 | |
1529 | hidnplayr | 322 | DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx |
1185 | hidnplayr | 323 | |
1529 | hidnplayr | 324 | push edx ecx |
325 | call [ebx + NET_DEVICE.transmit] |
||
326 | ret |
||
1185 | hidnplayr | 327 | |
1529 | hidnplayr | 328 | .exit: |
329 | add esp, 4+4 |
||
330 | DEBUGF 1,"Create ARP Packet - failed\n" |
||
331 | sub eax, eax |
||
332 | ret |
||
1185 | hidnplayr | 333 | |
334 | |||
1257 | hidnplayr | 335 | ;----------------------------------------------------------------- |
1196 | hidnplayr | 336 | ; |
337 | ; ARP_add_entry (or update) |
||
338 | ; |
||
1529 | hidnplayr | 339 | ; IN: esi = ptr to entry (can easily be made on the stack) |
1196 | hidnplayr | 340 | ; OUT: eax = entry #, -1 on error |
341 | ; |
||
1257 | hidnplayr | 342 | ;----------------------------------------------------------------- ; TODO: use a mutex |
1196 | hidnplayr | 343 | align 4 |
344 | ARP_add_entry: |
||
345 | |||
1206 | hidnplayr | 346 | DEBUGF 1,"ARP add entry: " |
347 | |||
1196 | hidnplayr | 348 | mov ecx, [NumARP] |
1529 | hidnplayr | 349 | test ecx, ecx ; first entry? |
1196 | hidnplayr | 350 | jz .add |
1529 | hidnplayr | 351 | cmp ecx, ARP_TABLE_SIZE ; list full ? |
352 | jge .error |
||
1196 | hidnplayr | 353 | |
1529 | hidnplayr | 354 | mov eax, dword[esi + ARP_ENTRY.MAC] |
355 | mov bx , word[esi + ARP_ENTRY.MAC + 4] |
||
356 | mov edi, ARP_table |
||
1196 | hidnplayr | 357 | |
1529 | hidnplayr | 358 | .loop: |
359 | cmp dword [edi + ARP_ENTRY.MAC], eax ; Check for duplicate MAC's |
||
360 | jne .maybe_next ; |
||
361 | cmp word [edi + ARP_ENTRY.MAC + 4], bx ; |
||
362 | jne .maybe_next ; |
||
1196 | hidnplayr | 363 | |
1529 | hidnplayr | 364 | cmp dword[edi + ARP_ENTRY.TTL], 0xFFFF ; static entry |
1196 | hidnplayr | 365 | jne .notstatic |
1529 | hidnplayr | 366 | cmp dword[esi + ARP_ENTRY.TTL], 0xFFFF |
1206 | hidnplayr | 367 | jne .error |
1529 | hidnplayr | 368 | .notstatic: |
1196 | hidnplayr | 369 | |
1529 | hidnplayr | 370 | neg ecx |
371 | add ecx, [NumARP] |
||
1196 | hidnplayr | 372 | jmp .add |
373 | |||
1529 | hidnplayr | 374 | .maybe_next: |
1196 | hidnplayr | 375 | add esi, ARP_ENTRY.size |
376 | loop .loop |
||
377 | |||
378 | mov ecx, [NumARP] |
||
1529 | hidnplayr | 379 | .add: |
1196 | hidnplayr | 380 | push ecx |
381 | imul ecx, ARP_ENTRY.size |
||
1529 | hidnplayr | 382 | lea edi, [ecx + ARP_table] |
1196 | hidnplayr | 383 | mov ecx, ARP_ENTRY.size/2 |
1529 | hidnplayr | 384 | rep movsw |
1196 | hidnplayr | 385 | |
1529 | hidnplayr | 386 | lea esi, [edi - ARP_ENTRY.size] |
1196 | hidnplayr | 387 | inc [NumARP] |
388 | pop eax |
||
1258 | hidnplayr | 389 | DEBUGF 1,"New entry created: %u\n", eax |
1529 | hidnplayr | 390 | |
391 | .exit: |
||
1206 | hidnplayr | 392 | DEBUGF 1,"Exiting\n" |
1529 | hidnplayr | 393 | ret |
1196 | hidnplayr | 394 | |
1529 | hidnplayr | 395 | .error: |
1206 | hidnplayr | 396 | DEBUGF 1,"error! \n" |
1196 | hidnplayr | 397 | mov eax, -1 |
1529 | hidnplayr | 398 | ret |
1196 | hidnplayr | 399 | |
400 | |||
1257 | hidnplayr | 401 | ;----------------------------------------------------------------- |
1185 | hidnplayr | 402 | ; |
403 | ; ARP_del_entry |
||
404 | ; |
||
1529 | hidnplayr | 405 | ; IN: esi = ptr to arp entry |
1185 | hidnplayr | 406 | ; OUT: / |
407 | ; |
||
1257 | hidnplayr | 408 | ;----------------------------------------------------------------- |
1185 | hidnplayr | 409 | align 4 |
410 | ARP_del_entry: |
||
411 | |||
1529 | hidnplayr | 412 | DEBUGF 1,"ARP del entry %x, total entrys: %u\n", esi, [NumARP] |
1206 | hidnplayr | 413 | |
1529 | hidnplayr | 414 | mov ecx, ARP_table + (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size |
1185 | hidnplayr | 415 | sub ecx, esi |
1529 | hidnplayr | 416 | shr ecx, 1 |
1185 | hidnplayr | 417 | |
1529 | hidnplayr | 418 | mov edi, esi |
419 | lea esi, [edi + ARP_ENTRY.size] |
||
1185 | hidnplayr | 420 | rep movsw |
421 | |||
1529 | hidnplayr | 422 | dec [NumARP] |
1485 | hidnplayr | 423 | DEBUGF 1,"ARP entry deleted\n" |
1529 | hidnplayr | 424 | |
1185 | hidnplayr | 425 | ret |
426 | |||
427 | |||
428 | |||
429 | |||
1529 | hidnplayr | 430 | |
1257 | hidnplayr | 431 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 432 | ; |
1529 | hidnplayr | 433 | ; ARP_IP_to_MAC |
1159 | hidnplayr | 434 | ; |
1529 | hidnplayr | 435 | ; This function translates an IP address to a MAC address |
1159 | hidnplayr | 436 | ; |
1529 | hidnplayr | 437 | ; IN: eax = IPv4 address |
438 | ; OUT: eax = -1 on error, -2 means request send |
||
439 | ; else, ax = first two bytes of mac (high 16 bits of eax will be 0) |
||
440 | ; ebx = last four bytes of mac |
||
1159 | hidnplayr | 441 | ; |
1257 | hidnplayr | 442 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 443 | align 4 |
1529 | hidnplayr | 444 | ARP_IP_to_MAC: |
1159 | hidnplayr | 445 | |
1529 | hidnplayr | 446 | DEBUGF 1,"ARP_IP_to_MAC\n" |
1159 | hidnplayr | 447 | |
1529 | hidnplayr | 448 | cmp eax, 0xffffffff |
449 | je .broadcast |
||
1159 | hidnplayr | 450 | |
1529 | hidnplayr | 451 | ; if ((Remote IP & subnet_mask) == (local IP & subnet_mask )) |
452 | ; destination is on same subnet |
||
453 | ; else, destination is remote and must use a gateway |
||
1206 | hidnplayr | 454 | |
1529 | hidnplayr | 455 | call IPv4_dest_to_dev |
456 | mov ebx, [IP_LIST + edi] |
||
457 | and ebx, [SUBNET_LIST + edi] |
||
1159 | hidnplayr | 458 | |
1529 | hidnplayr | 459 | mov ecx, eax |
460 | and ecx, [SUBNET_LIST + edi] |
||
1196 | hidnplayr | 461 | |
1529 | hidnplayr | 462 | cmp ecx, ebx |
463 | je .local |
||
1196 | hidnplayr | 464 | |
1529 | hidnplayr | 465 | mov eax, [GATEWAY_LIST + edi] |
466 | DEBUGF 1,"requested IP is not on subnet, using default gateway\n" |
||
1196 | hidnplayr | 467 | |
1529 | hidnplayr | 468 | ;-------------------------------- |
469 | ; Try to find the IP in ARP_table |
||
1206 | hidnplayr | 470 | |
1529 | hidnplayr | 471 | .local: |
472 | mov ecx, [NumARP] |
||
473 | test ecx, ecx |
||
474 | jz .not_in_list |
||
475 | mov esi, ARP_table + ARP_ENTRY.IP |
||
476 | .scan_loop: |
||
477 | cmp [esi], eax |
||
478 | je .found_it |
||
479 | add esi, ARP_ENTRY.size |
||
480 | loop .scan_loop |
||
1206 | hidnplayr | 481 | |
1529 | hidnplayr | 482 | .not_in_list: |
483 | DEBUGF 1,"IP not found on list, preparing for ARP request\n" |
||
1196 | hidnplayr | 484 | |
1529 | hidnplayr | 485 | ;-------------------- |
486 | ; Send an ARP request |
||
1196 | hidnplayr | 487 | |
1159 | hidnplayr | 488 | push eax |
489 | |||
1529 | hidnplayr | 490 | pushw ARP_REQUEST_TTL |
491 | pushw ARP_AWAITING_RESPONSE |
||
492 | pushd 0 |
||
493 | pushw 0 |
||
494 | pushd eax |
||
495 | mov esi, esp |
||
496 | call ARP_add_entry |
||
497 | add esp, ARP_ENTRY.size |
||
1159 | hidnplayr | 498 | |
1529 | hidnplayr | 499 | cmp eax, -1 |
500 | je .full |
||
1159 | hidnplayr | 501 | |
1530 | hidnplayr | 502 | mov ecx, eax |
1159 | hidnplayr | 503 | pop eax |
1530 | hidnplayr | 504 | push ecx |
1529 | hidnplayr | 505 | call ARP_output_request |
1159 | hidnplayr | 506 | |
1530 | hidnplayr | 507 | ;; TODO: check if driver could transmit packet |
508 | |||
1533 | hidnplayr | 509 | pop esi |
510 | imul esi, ARP_ENTRY.size |
||
511 | add esi, ARP_table |
||
1530 | hidnplayr | 512 | |
513 | mov ecx, 25 |
||
514 | .wait_loop: |
||
1533 | hidnplayr | 515 | cmp [esi + ARP_ENTRY.Status], 1 |
1530 | hidnplayr | 516 | je .got_it |
1533 | hidnplayr | 517 | push esi |
1530 | hidnplayr | 518 | mov esi, 10 |
519 | call delay_ms |
||
1533 | hidnplayr | 520 | pop esi |
1530 | hidnplayr | 521 | loop .wait_loop |
522 | |||
1529 | hidnplayr | 523 | mov eax, -2 ; request send |
524 | ret |
||
1159 | hidnplayr | 525 | |
1529 | hidnplayr | 526 | .found_it: |
527 | DEBUGF 1,"found IP in ARPTable\n" |
||
528 | cmp [esi + ARP_ENTRY.Status], 1 |
||
529 | jne .invalid |
||
1159 | hidnplayr | 530 | |
1530 | hidnplayr | 531 | .got_it: |
1529 | hidnplayr | 532 | movzx eax, word [esi+ARP_ENTRY.MAC] |
533 | mov ebx, dword[esi+ARP_ENTRY.MAC+2] |
||
534 | ret |
||
1206 | hidnplayr | 535 | |
1529 | hidnplayr | 536 | .invalid: |
537 | mov eax, -1 |
||
1519 | hidnplayr | 538 | ret |
1159 | hidnplayr | 539 | |
1529 | hidnplayr | 540 | .full: |
541 | DEBUGF 1,"ARP table is full!\n" |
||
542 | pop eax |
||
543 | mov eax, -1 |
||
544 | ret |
||
1159 | hidnplayr | 545 | |
1529 | hidnplayr | 546 | .broadcast: |
547 | mov eax, 0x0000ffff |
||
548 | mov ebx, 0xffffffff |
||
1159 | hidnplayr | 549 | ret |
550 | |||
551 | |||
1257 | hidnplayr | 552 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 553 | ; |
554 | ; ARP_API |
||
555 | ; |
||
556 | ; This function is called by system function 75 |
||
557 | ; |
||
558 | ; IN: subfunction number in bl |
||
559 | ; device number in bh |
||
560 | ; ecx, edx, .. depends on subfunction |
||
561 | ; |
||
1257 | hidnplayr | 562 | ; OUT: ? |
1159 | hidnplayr | 563 | ; |
1257 | hidnplayr | 564 | ;----------------------------------------------------------------- |
1159 | hidnplayr | 565 | align 4 |
566 | ARP_API: |
||
567 | |||
568 | movzx eax, bh |
||
569 | shl eax, 2 |
||
570 | |||
571 | test bl, bl |
||
572 | jz .packets_tx ; 0 |
||
573 | dec bl |
||
574 | jz .packets_rx ; 1 |
||
575 | dec bl |
||
576 | jz .entries ; 2 |
||
577 | dec bl |
||
578 | jz .read ; 3 |
||
579 | dec bl |
||
580 | jz .write ; 4 |
||
581 | dec bl |
||
582 | jz .remove ; 5 |
||
583 | dec bl |
||
584 | |||
585 | .error: |
||
586 | mov eax, -1 |
||
587 | ret |
||
588 | |||
589 | .packets_tx: |
||
590 | add eax, ARP_PACKETS_TX |
||
591 | mov eax, [eax] |
||
592 | ret |
||
593 | |||
594 | .packets_rx: |
||
595 | add eax, ARP_PACKETS_RX |
||
596 | mov eax, [eax] |
||
597 | ret |
||
598 | |||
599 | .entries: |
||
600 | mov eax, [NumARP] |
||
601 | ret |
||
602 | |||
603 | .read: |
||
1200 | hidnplayr | 604 | cmp ecx, [NumARP] |
605 | jge .error |
||
606 | ; edi = pointer to buffer |
||
607 | ; ecx = # entry |
||
608 | imul ecx, ARP_ENTRY.size |
||
1529 | hidnplayr | 609 | add ecx, ARP_table |
1200 | hidnplayr | 610 | mov esi, ecx |
611 | mov ecx, ARP_ENTRY.size/2 |
||
612 | rep movsw |
||
613 | |||
614 | xor eax, eax |
||
1159 | hidnplayr | 615 | ret |
616 | |||
617 | .write: |
||
1200 | hidnplayr | 618 | ; esi = pointer to buffer |
1251 | clevermous | 619 | call ARP_add_entry ;out: eax = entry number, -1 on error |
620 | ret |
||
1159 | hidnplayr | 621 | |
622 | .remove: |
||
1200 | hidnplayr | 623 | ; ecx = # entry |
1529 | hidnplayr | 624 | cmp ecx, [NumARP] |
625 | jge .error |
||
626 | imul ecx, ARP_ENTRY.size |
||
627 | lea esi, [ARP_table + ecx] |
||
1196 | hidnplayr | 628 | call ARP_del_entry |
1159 | hidnplayr | 629 | ret |
630 |