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