Rev 1519 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1519 | Rev 1529 | ||
---|---|---|---|
Line 14... | Line 14... | ||
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
14 | ;; GNU GENERAL PUBLIC LICENSE ;; |
15 | ;; Version 2, June- 1991 ;; |
15 | ;; Version 2, June- 1991 ;; |
16 | ;; ;; |
16 | ;; ;; |
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
17 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 18... | Line -... | ||
18 | - | ||
19 | 18 | ||
20 | $Revision: 1519 $ |
- | |
Line 21... | Line 19... | ||
21 | 19 | $Revision: 1529 $ |
|
22 | 20 | ||
23 | ARP_NO_ENTRY equ 0 |
21 | ARP_NO_ENTRY equ 0 |
24 | ARP_VALID_MAPPING equ 1 |
22 | ARP_VALID_MAPPING equ 1 |
Line 25... | Line 23... | ||
25 | ARP_AWAITING_RESPONSE equ 2 |
23 | ARP_AWAITING_RESPONSE equ 2 |
26 | ARP_RESPONSE_TIMEOUT equ 3 |
24 | ARP_RESPONSE_TIMEOUT equ 3 |
27 | - | ||
28 | ARP_REQUEST_TTL = 20 ; in seconds |
- | |
Line 29... | Line 25... | ||
29 | ARP_ENTRY_TTL = 600 ; in seconds |
25 | |
30 | 26 | ARP_REQUEST_TTL equ 31 ; 20 s |
|
Line 31... | Line 27... | ||
31 | ETHER_ARP equ 0x0608 |
27 | ARP_ENTRY_TTL equ 937 ; 600 s |
Line 32... | Line 28... | ||
32 | 28 | ||
33 | ARP_REQ_OPCODE equ 0x0100 ; request |
29 | ARP_REQ_OPCODE equ 0x0100 ; request |
34 | ARP_REP_OPCODE equ 0x0200 ; reply |
30 | ARP_REP_OPCODE equ 0x0200 ; reply |
35 | 31 | ||
36 | ARP_TABLE_SIZE equ 20 ; Size of table |
32 | ARP_TABLE_SIZE equ 20 ; Size of table |
37 | 33 | ||
38 | struct ARP_ENTRY |
34 | struct ARP_ENTRY |
Line 39... | Line 35... | ||
39 | .IP dd ? |
35 | .IP dd ? |
40 | .MAC dp ? |
36 | .MAC dp ? |
Line 51... | Line 47... | ||
51 | .Opcode dw ? |
47 | .Opcode dw ? |
52 | .SenderMAC dp ? |
48 | .SenderMAC dp ? |
53 | .SenderIP dd ? |
49 | .SenderIP dd ? |
54 | .TargetMAC dp ? |
50 | .TargetMAC dp ? |
55 | .TargetIP dd ? |
51 | .TargetIP dd ? |
- | 52 | .size: |
|
56 | ends |
53 | ends |
Line 57... | Line -... | ||
57 | - | ||
58 | - | ||
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 |
- | |
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: |
- | |
63 | ; 0x0000 entry not used |
- | |
64 | ; 0x0001 entry holds a valid mapping |
- | |
65 | ; 0x0002 entry contains an IP address, awaiting ARP response |
- | |
66 | ; 0x0003 No response received to ARP request. |
- | |
67 | ; The last status value is provided to allow the network layer to delete |
- | |
68 | ; a packet that is queued awaiting an ARP response |
54 | |
69 | 55 | ||
Line 70... | Line 56... | ||
70 | align 4 |
56 | align 4 |
Line 71... | Line 57... | ||
71 | uglobal |
57 | uglobal |
Line 72... | Line 58... | ||
72 | 58 | ||
73 | NumARP dd ? |
59 | NumARP dd ? |
Line 86... | Line 72... | ||
86 | ; |
72 | ; |
87 | ; ARP_init |
73 | ; ARP_init |
88 | ; |
74 | ; |
89 | ; This function resets all ARP variables |
75 | ; This function resets all ARP variables |
90 | ; |
76 | ; |
91 | ; IN: / |
- | |
92 | ; OUT: / |
- | |
93 | ; |
- | |
94 | ;----------------------------------------------------------------- |
77 | ;----------------------------------------------------------------- |
95 | align 4 |
- | |
96 | ARP_init: |
78 | macro ARP_init { |
Line 97... | Line 79... | ||
97 | 79 | ||
98 | xor eax, eax |
- | |
99 | 80 | xor eax, eax |
|
Line 100... | Line 81... | ||
100 | mov [NumARP], eax |
81 | mov [NumARP], eax |
101 | 82 | ||
102 | mov edi, ARP_PACKETS_TX |
83 | mov edi, ARP_PACKETS_TX |
Line -... | Line 84... | ||
- | 84 | mov ecx, 2*MAX_NET_DEVICES |
|
- | 85 | rep stosd |
|
- | 86 | ||
- | 87 | } |
|
- | 88 | ||
- | 89 | ;--------------------------------------------------------------------------- |
|
- | 90 | ; |
|
- | 91 | ; ARP_decrease_entry_ttls |
|
- | 92 | ; |
|
- | 93 | ;--------------------------------------------------------------------------- |
|
- | 94 | ||
- | 95 | macro ARP_decrease_entry_ttls { |
|
- | 96 | ||
- | 97 | local .loop |
|
- | 98 | local .exit |
|
- | 99 | ||
- | 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 |
|
103 | mov ecx, 2*MAX_NET_DEVICES |
110 | |
- | 111 | mov ecx, [NumARP] |
|
- | 112 | test ecx, ecx |
|
- | 113 | jz .exit |
|
- | 114 | ||
- | 115 | mov esi, ARP_table |
|
- | 116 | .loop: |
|
- | 117 | cmp [esi + ARP_ENTRY.TTL], 0xffff ; 0xffff = static entry |
|
- | 118 | je .next |
|
- | 119 | ||
- | 120 | dec [esi + ARP_ENTRY.TTL] |
|
- | 121 | jz .time_out |
|
- | 122 | ||
- | 123 | .next: |
|
- | 124 | add esi, ARP_ENTRY.size |
|
- | 125 | loop .loop |
|
- | 126 | jmp .exit |
|
- | 127 | ||
- | 128 | .time_out: |
|
- | 129 | cmp [esi + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
|
- | 130 | jz .response_timeout |
|
- | 131 | ||
- | 132 | push esi ecx |
|
- | 133 | call ARP_del_entry |
|
- | 134 | pop ecx esi |
|
- | 135 | ||
- | 136 | jmp .next |
|
- | 137 | ||
- | 138 | .response_timeout: |
|
- | 139 | mov [esi + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
|
- | 140 | mov [esi + ARP_ENTRY.TTL], 10 |
|
- | 141 | ||
- | 142 | jmp .next |
|
- | 143 | ||
Line 104... | Line 144... | ||
104 | rep stosd |
144 | .exit: |
105 | 145 | ||
106 | ret |
146 | } |
107 | - | ||
108 | - | ||
109 | ;----------------------------------------------------------------- |
147 | |
110 | ; |
148 | |
111 | ; ARP_IP_to_MAC |
149 | ;----------------------------------------------------------------- |
112 | ; |
150 | ; |
113 | ; This function resets all ARP variables |
- | |
- | 151 | ; ARP_input |
|
114 | ; |
152 | ; |
115 | ; IN: eax = IPv4 address |
153 | ; IN: Pointer to buffer in [esp] |
116 | ; OUT: eax = -1 on error, else eax = first two bytes of mac |
154 | ; size of buffer in [esp+4] |
117 | ; ( high 16 bits are zero) |
155 | ; packet size (without ethernet header) in ecx |
118 | ; ebx = last four bytes of mac ; TODO: special eax value for 'request send' |
- | |
119 | ; |
- | |
120 | ;----------------------------------------------------------------- |
- | |
121 | align 4 |
- | |
122 | ARP_IP_to_MAC: |
- | |
123 | - | ||
124 | DEBUGF 1,"ARP_IP_to_MAC\n" |
- | |
125 | - | ||
126 | ; first, check destination IP to see if it is on 'this' network. |
- | |
127 | ; The test is: |
- | |
128 | ; if ( destIP & subnet_mask == stack_ip & subnet_mask ) |
- | |
Line 129... | Line 156... | ||
129 | ; destination is local |
156 | ; OUT: / |
130 | ; else |
157 | ; |
- | 158 | ;----------------------------------------------------------------- |
|
Line 131... | Line 159... | ||
131 | ; destination is remote, so pass to gateway |
159 | align 4 |
132 | 160 | ARP_input: |
|
Line 133... | Line 161... | ||
133 | xor edx, edx ;;; TODO: find device num in edx |
161 | |
134 | 162 | DEBUGF 1,"ARP_Handler - start\n" |
|
Line 135... | Line -... | ||
135 | mov ebx, [IP_LIST + edx] |
- | |
136 | and ebx, [SUBNET_LIST + edx] |
163 | cmp ecx, 28 |
- | 164 | jl .exit |
|
Line 137... | Line -... | ||
137 | - | ||
138 | mov ecx, eax |
- | |
139 | and ecx, [SUBNET_LIST + edx] |
165 | |
140 | 166 | ;--------------------- |
|
141 | cmp ecx, ebx |
167 | ; Handle Reply packets |
- | 168 | ||
- | 169 | cmp word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE |
|
142 | je .local |
170 | jne .maybe_request |
- | 171 | ||
143 | 172 | DEBUGF 1,"ARP_Handler - it's a reply packet from %u.%u.%u.%u\n",\ |
|
144 | mov eax, [GATEWAY_LIST + edx] |
173 | [edx + ARP_Packet.SenderIP]:1,[edx + ARP_Packet.SenderIP+1]:1,[edx + ARP_Packet.SenderIP+2]:1,[edx + ARP_Packet.SenderIP+3]:1, |
145 | DEBUGF 1,"requested IP is not on subnet, using gateway\n" |
174 | |
146 | 175 | mov ecx, [NumARP] |
|
147 | .local: |
176 | test ecx, ecx |
148 | ; try to find it on the list |
- | |
Line 149... | Line 177... | ||
149 | mov ecx, [NumARP] |
177 | jz .exit |
Line -... | Line 178... | ||
- | 178 | ||
150 | test ecx, ecx |
179 | mov eax, [edx + ARP_Packet.SenderIP] |
Line -... | Line 180... | ||
- | 180 | mov esi, ARP_table |
|
151 | jz .not_in_list |
181 | |
Line -... | Line 182... | ||
- | 182 | .loop: |
|
- | 183 | cmp [esi + ARP_ENTRY.IP], eax |
|
- | 184 | je .gotit |
|
152 | mov esi, ARPTable + ARP_ENTRY.IP |
185 | add esi, ARP_ENTRY.size |
- | 186 | loop .loop |
|
- | 187 | ||
- | 188 | jmp .exit |
|
- | 189 | ||
153 | .scan_loop: |
190 | .gotit: |
- | 191 | DEBUGF 1,"ARP_Handler - found matching entry\n" |
|
154 | cmp [esi], eax |
192 | |
- | 193 | cmp [esi+ARP_ENTRY.TTL], 0xffff ; if it is a static entry, dont touch it |
|
- | 194 | je .exit |
|
- | 195 | ||
- | 196 | DEBUGF 1,"ARP_Handler - updating entry\n" |
|
- | 197 | ||
155 | je .found_it |
198 | mov [esi+ARP_ENTRY.Status], ARP_VALID_MAPPING |
- | 199 | mov [esi+ARP_ENTRY.TTL], ARP_ENTRY_TTL |
|
156 | add esi, ARP_ENTRY.size |
200 | |
- | 201 | mov eax, dword [edx + ARP_Packet.SenderMAC] |
|
157 | loop .scan_loop |
202 | mov dword [esi+ARP_ENTRY.MAC], eax |
158 | .not_in_list: |
203 | mov ax , word [edx + ARP_Packet.SenderMAC + 4] |
159 | 204 | mov word [esi+ARP_ENTRY.MAC+4], ax |
|
- | 205 | ||
- | 206 | jmp .exit |
|
Line 160... | Line 207... | ||
160 | DEBUGF 1,"IP not found on list, preparing for ARP request\n" |
207 | |
- | 208 | ||
- | 209 | ;----------------------- |
|
Line -... | Line 210... | ||
- | 210 | ; Handle Request packets |
|
- | 211 | ||
- | 212 | .maybe_request: |
|
161 | 213 | cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE |
|
- | 214 | jne .exit |
|
- | 215 | ||
- | 216 | call NET_ptr_to_num |
|
- | 217 | cmp edi, -1 |
|
- | 218 | jz .exit |
|
- | 219 | DEBUGF 1,"ARP Request packet through device: %u\n", edi |
|
- | 220 | inc [ARP_PACKETS_RX+4*edi] |
|
Line -... | Line 221... | ||
- | 221 | ||
- | 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 ? |
|
- | 225 | ||
162 | ; if not, reserve an entry in list and send an ARP request packet |
226 | push eax |
163 | 227 | push edi |
|
164 | push eax |
- | |
165 | 228 | ||
Line 166... | Line -... | ||
166 | pushw ARP_REQUEST_TTL |
- | |
167 | pushw ARP_AWAITING_RESPONSE |
- | |
168 | pushd 0 |
- | |
169 | pushw 0 |
- | |
170 | pushd eax |
- | |
171 | call ARP_add_entry |
- | |
172 | cmp eax, -1 |
- | |
173 | je .full |
- | |
174 | - | ||
175 | ; |
- | |
176 | 229 | ; OK, it is a request for one of our MAC addresses. |
|
177 | ; This piece of code waits for an ARP reply |
- | |
178 | - | ||
179 | mov ebx, eax |
- | |
180 | pop eax |
- | |
181 | push ebx |
- | |
182 | call ARP_create_request |
- | |
183 | - | ||
184 | push [timer_ticks] |
- | |
185 | add dword[esp], 100*ARP_REQUEST_TTL |
- | |
186 | DEBUGF 1,"Waiting for ARP reply, time: %x, entry:%u\n",[timer_ticks], [esp + 4] |
- | |
Line 187... | Line -... | ||
187 | .dirty_loop: |
- | |
188 | 230 | ; Build the frame and send it. We can reuse the buffer. (faster then using ARP_create_packet) |
|
189 | call change_task ; The ARP reply hasnt been received yet, tell the processor to do some other stuff first |
- | |
190 | - | ||
191 | mov eax, [esp + 4] |
- | |
Line -... | Line 231... | ||
- | 231 | ||
- | 232 | lea esi, [edx + ARP_Packet.SenderMAC] |
|
192 | imul eax, ARP_ENTRY.size |
233 | lea edi, [edx + ARP_Packet.TargetMAC] |
193 | add eax, ARPTable |
234 | movsd ; Move Sender Mac to Dest MAC |
- | 235 | movsw ; |
|
- | 236 | movsd ; Move sender IP to Dest IP |
|
194 | cmp [eax + ARP_ENTRY.Status], ARP_VALID_MAPPING |
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 ; |
|
195 | je .gogogo |
244 | pop eax |
Line 196... | Line 245... | ||
196 | 245 | stosd ; Write our IP |
|
197 | mov eax, [esp] ; Check if the reply hasnt timed-out yet |
246 | |
198 | cmp [timer_ticks], eax |
247 | mov word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE |
- | 248 | ||
199 | jl .dirty_loop |
249 | ; Now, Fill in ETHERNET header |
200 | - | ||
201 | ; |
250 | |
Line 202... | Line 251... | ||
202 | or eax, -1 |
251 | mov edi, [esp] |
203 | add esp, 8 |
252 | lea esi, [edx + ARP_Packet.TargetMAC] |
204 | ret |
253 | movsd |
205 | 254 | movsw |
|
206 | .found_it: |
255 | lea esi, [edx + ARP_Packet.SenderMAC] |
207 | DEBUGF 1,"found MAC in ARPTable\n" |
- | |
208 | movzx eax, word [esi+ARP_ENTRY.MAC] |
256 | movsd |
209 | mov ebx, dword[esi+ARP_ENTRY.MAC+2] |
257 | movsw |
210 | ret |
258 | ; mov ax , ETHER_ARP |
211 | 259 | ; stosw |
|
212 | .full: |
260 | |
Line 213... | Line 261... | ||
213 | add esp, 4 |
261 | DEBUGF 1,"ARP_Handler - Sending reply \n" |
Line 214... | Line 262... | ||
214 | mov eax, -1 |
262 | |
215 | ret |
- | |
216 | 263 | call [ebx + NET_DEVICE.transmit] |
|
217 | .gogogo: |
264 | ret |
218 | DEBUGF 1,"got ARP reply, time: %x\n",[timer_ticks] |
265 | |
- | 266 | .exit: |
|
Line 219... | Line -... | ||
219 | mov ebx, dword[eax+ARP_ENTRY.MAC+2] |
- | |
220 | movzx eax, word [eax+ARP_ENTRY.MAC] |
267 | call kernel_free |
221 | add esp, 8 |
268 | add esp, 4 ; pop (balance stack) |
222 | ret |
269 | |
223 | - | ||
224 | 270 | DEBUGF 1,"ARP_Handler - exiting\n" |
|
225 | ;--------------------------------------------------------------------------- |
271 | ret |
226 | ; |
272 | |
Line 227... | Line 273... | ||
227 | ; ARP_create_request |
273 | |
Line 228... | Line 274... | ||
228 | ; |
274 | ;--------------------------------------------------------------------------- |
229 | ; IN: ip in eax |
275 | ; |
230 | ; |
276 | ; ARP_output_request |
231 | ; OUT: / |
277 | ; |
232 | ; |
278 | ; IN: ip in eax |
Line 233... | Line 279... | ||
233 | ;--------------------------------------------------------------------------- |
279 | ; OUT: / |
- | 280 | ; |
|
234 | align 4 |
281 | ;--------------------------------------------------------------------------- |
235 | ARP_create_request: |
282 | align 4 |
236 | 283 | ARP_output_request: |
|
237 | DEBUGF 1,"Create ARP Packet\n" |
284 | |
238 | 285 | DEBUGF 1,"Create ARP Packet\n" |
|
- | 286 | ||
239 | call IPv4_dest_to_dev |
287 | call IPv4_dest_to_dev |
240 | 288 | push eax ; DestIP |
|
241 | push eax ; DestIP |
289 | pushd [IP_LIST+edi] ; SenderIP |
242 | mov eax, [IP_LIST+4*edi] ; senderIP |
290 | |
243 | push eax |
291 | mov ebx, [NET_DRV_LIST+edi] ; device ptr |
Line 244... | Line 292... | ||
244 | 292 | ||
Line 245... | Line 293... | ||
245 | mov edi, [NET_DRV_LIST + 4*edi] |
293 | lea eax, [ebx + ETH_DEVICE.mac] ; local device mac |
246 | lea eax, [edi + ETH_DEVICE.mac] |
294 | mov edx, ETH_BROADCAST ; broadcast mac |
247 | mov ebx, ETH_BROADCAST |
295 | mov ecx, ARP_Packet.size |
Line 248... | Line 296... | ||
248 | mov ecx, 60 ; minimum packet size |
296 | mov di, ETHER_ARP |
249 | mov edx, edi ;;; |
297 | call ETH_output |
250 | mov di , ETHER_ARP |
298 | jz .exit |
251 | call ETH_create_packet |
299 | |
252 | jz .exit |
300 | mov ecx, eax |
Line 253... | Line -... | ||
253 | - | ||
254 | mov ecx, eax |
- | |
255 | - | ||
256 | mov [edi + ARP_Packet.HardwareType], 0x0100 ;Ethernet |
- | |
257 | mov [edi + ARP_Packet.ProtocolType], 0x0008 ;IP |
- | |
258 | mov [edi + ARP_Packet.HardwareSize], 6 ;MAC-addr length |
- | |
259 | mov [edi + ARP_Packet.ProtocolSize], 4 ;IP-addr length |
- | |
260 | mov [edi + ARP_Packet.Opcode], ARP_REQ_OPCODE ;Request |
- | |
261 | - | ||
262 | add edi, ARP_Packet.SenderMAC ; sendermac |
- | |
263 | lea esi, [ebx + ETH_DEVICE.mac] ; |
- | |
264 | movsw ; |
- | |
265 | movsd ; |
- | |
266 | pop eax ; |
- | |
267 | stosd ; |
- | |
268 | mov eax, -1 ; destmac |
- | |
269 | stosd ; |
- | |
270 | stosw ; |
- | |
271 | pop eax |
- | |
272 | stosd ; |
- | |
273 | - | ||
274 | DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx |
- | |
275 | - | ||
276 | push edx ecx |
- | |
277 | call [ebx + NET_DEVICE.transmit] |
- | |
278 | ret |
- | |
279 | - | ||
280 | .exit: |
- | |
281 | add esp, 8 |
- | |
282 | DEBUGF 1,"Create ARP Packet - failed\n" |
- | |
283 | mov eax, -1 |
- | |
284 | ret |
- | |
285 | - | ||
286 | - | ||
287 | - | ||
288 | ;--------------------------------------------------------------------------- |
- | |
289 | ; |
- | |
290 | ; ARP_decrease_entry_ttls |
- | |
291 | ; |
- | |
292 | ; IN: / |
- | |
293 | ; OUT: / |
- | |
294 | ; |
- | |
295 | ;--------------------------------------------------------------------------- |
- | |
296 | align 4 |
- | |
297 | ARP_decrease_entry_ttls: |
- | |
298 | - | ||
299 | mov ecx, [NumARP] |
- | |
300 | test ecx, ecx |
- | |
301 | jz .exit |
- | |
302 | - | ||
303 | mov ebx, ARPTable |
- | |
304 | - | ||
305 | .timer_loop: |
- | |
306 | - | ||
307 | cmp [ebx + ARP_ENTRY.TTL], 0xFFFF |
- | |
308 | je .timer_loop_end ;if TTL==0xFFFF then it's static entry |
- | |
309 | - | ||
310 | cmp [ebx + ARP_ENTRY.TTL], 0 |
- | |
311 | jnz .timer_loop_end_with_dec ;if TTL!=0 |
- | |
312 | - | ||
313 | ; Ok, TTL is 0 |
- | |
314 | ;if Status==AWAITING_RESPONSE and TTL==0 |
- | |
315 | ;then we have to change it to ARP_RESPONSE_TIMEOUT |
301 | |
316 | cmp [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
302 | mov [edi + ARP_Packet.HardwareType], 0x0100 ; Ethernet |
317 | jne @f |
303 | mov [edi + ARP_Packet.ProtocolType], 0x0008 ; IP |
318 | 304 | mov [edi + ARP_Packet.HardwareSize], 6 ; MAC-addr length |
|
319 | mov [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
305 | mov [edi + ARP_Packet.ProtocolSize], 4 ; IP-addr length |
320 | mov [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec |
- | |
321 | jmp .timer_loop_end |
- | |
322 | - | ||
323 | @@: |
- | |
324 | ;if TTL==0 and Status==VALID_MAPPING, we have to delete it |
- | |
325 | ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too |
306 | mov [edi + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Request |
326 | mov esi, [NumARP] |
307 | |
327 | sub esi, ecx ;esi=index of entry, will be deleted |
308 | add edi, ARP_Packet.SenderMAC |
328 | 309 | ||
329 | push ebx ecx |
310 | lea esi, [ebx + ETH_DEVICE.mac] ; SenderMac |
Line 330... | Line 311... | ||
330 | call ARP_del_entry |
311 | movsw ; |
Line 331... | Line 312... | ||
331 | pop ecx ebx |
312 | movsd ; |
332 | 313 | pop eax ; SenderIP |
|
333 | jmp .timer_loop_end |
314 | stosd ; |
- | 315 | ||
- | 316 | mov eax, -1 ; DestMac |
|
Line 334... | Line 317... | ||
334 | 317 | stosd ; |
|
335 | 318 | stosw ; |
|
336 | .timer_loop_end_with_dec: |
319 | pop eax ; DestIP |
Line 337... | Line 320... | ||
337 | 320 | stosd ; |
|
338 | dec [ebx + ARP_ENTRY.TTL] ;decrease TTL |
321 | |
339 | 322 | DEBUGF 1,"ARP Packet for device %x created successfully\n", ebx |
|
340 | .timer_loop_end: |
323 | |
341 | 324 | push edx ecx |
|
Line 342... | Line 325... | ||
342 | add ebx, ARP_ENTRY.size |
325 | call [ebx + NET_DEVICE.transmit] |
343 | loop .timer_loop |
326 | ret |
344 | 327 | ||
345 | .exit: |
328 | .exit: |
346 | 329 | add esp, 4+4 |
|
Line 347... | Line -... | ||
347 | ret |
- | |
348 | 330 | DEBUGF 1,"Create ARP Packet - failed\n" |
|
349 | ;----------------------------------------------------------------- |
331 | sub eax, eax |
350 | ; |
332 | ret |
Line 351... | Line 333... | ||
351 | ; ARP_add_entry (or update) |
333 | |
352 | ; |
334 | |
353 | ; IN: arp entry in stack: esp .IP |
335 | ;----------------------------------------------------------------- |
Line 354... | Line 336... | ||
354 | ; esp+4 .MAC |
336 | ; |
355 | ; esp+10 .Status |
- | |
356 | ; esp+12 .TTL |
- | |
357 | ; esp+14 |
- | |
358 | ; |
337 | ; ARP_add_entry (or update) |
359 | ; OUT: eax = entry #, -1 on error |
338 | ; |
360 | ; |
339 | ; IN: esi = ptr to entry (can easily be made on the stack) |
361 | ;----------------------------------------------------------------- ; TODO: use a mutex |
340 | ; OUT: eax = entry #, -1 on error |
362 | align 4 |
- | |
363 | ARP_add_entry: |
341 | ; |
364 | 342 | ;----------------------------------------------------------------- ; TODO: use a mutex |
|
Line -... | Line 343... | ||
- | 343 | align 4 |
|
365 | DEBUGF 1,"ARP add entry: " |
344 | ARP_add_entry: |
366 | 345 | ||
367 | mov ecx, [NumARP] |
346 | DEBUGF 1,"ARP add entry: " |
- | 347 | ||
368 | test ecx, ecx |
348 | mov ecx, [NumARP] |
369 | jz .add |
349 | test ecx, ecx ; first entry? |
370 | 350 | jz .add |
|
Line 371... | Line 351... | ||
371 | mov eax, dword[esp + 4 + ARP_ENTRY.MAC] |
351 | cmp ecx, ARP_TABLE_SIZE ; list full ? |
372 | mov bx , word[esp + 4 + ARP_ENTRY.MAC + 4] |
- | |
373 | mov esi, ARPTable |
352 | jge .error |
374 | - | ||
375 | .loop: |
353 | |
376 | cmp dword [esi + ARP_ENTRY.MAC], eax |
354 | mov eax, dword[esi + ARP_ENTRY.MAC] |
Line 377... | Line 355... | ||
377 | jne .maybe_next |
355 | mov bx , word[esi + ARP_ENTRY.MAC + 4] |
378 | cmp word [esi + ARP_ENTRY.MAC + 4], bx |
356 | mov edi, ARP_table |
379 | jne .maybe_next |
357 | |
380 | 358 | .loop: |
|
381 | cmp dword[esi + ARP_ENTRY.TTL], 0xFFFF ; static entry |
359 | cmp dword [edi + ARP_ENTRY.MAC], eax ; Check for duplicate MAC's |
382 | jne .notstatic |
360 | jne .maybe_next ; |
383 | cmp dword[esp + 4 + ARP_ENTRY.TTL], 0xFFFF |
361 | cmp word [edi + ARP_ENTRY.MAC + 4], bx ; |
384 | jne .error |
362 | jne .maybe_next ; |
385 | .notstatic: |
363 | |
386 | 364 | cmp dword[edi + ARP_ENTRY.TTL], 0xFFFF ; static entry |
|
Line 387... | Line 365... | ||
387 | mov ebx, [NumARP] |
365 | jne .notstatic |
388 | xchg ebx, ecx |
- | |
389 | sub ecx, ebx |
- | |
390 | jmp .add |
- | |
391 | - | ||
392 | .maybe_next: |
- | |
Line 393... | Line 366... | ||
393 | add esi, ARP_ENTRY.size |
366 | cmp dword[esi + ARP_ENTRY.TTL], 0xFFFF |
394 | loop .loop |
367 | jne .error |
- | 368 | .notstatic: |
|
Line 395... | Line 369... | ||
395 | 369 | ||
396 | mov ecx, [NumARP] |
370 | neg ecx |
397 | cmp ecx, ARP_TABLE_SIZE |
- | |
398 | jge .error |
- | |
399 | 371 | add ecx, [NumARP] |
|
Line 400... | Line 372... | ||
400 | .add: |
372 | jmp .add |
401 | push ecx |
373 | |
402 | imul ecx, ARP_ENTRY.size |
374 | .maybe_next: |
403 | lea edi, [ecx + ARPTable] |
375 | add esi, ARP_ENTRY.size |
Line -... | Line 376... | ||
- | 376 | loop .loop |
|
404 | lea esi, [esp + 8] |
377 | |
405 | mov ecx, ARP_ENTRY.size/2 |
378 | mov ecx, [NumARP] |
406 | repz movsw |
379 | .add: |
407 | 380 | push ecx |
|
408 | inc [NumARP] |
381 | imul ecx, ARP_ENTRY.size |
409 | pop eax |
- | |
410 | DEBUGF 1,"New entry created: %u\n", eax |
382 | lea edi, [ecx + ARP_table] |
411 | .exit: |
383 | mov ecx, ARP_ENTRY.size/2 |
412 | DEBUGF 1,"Exiting\n" |
384 | rep movsw |
413 | ret ARP_ENTRY.size |
385 | |
414 | 386 | lea esi, [edi - ARP_ENTRY.size] |
|
415 | .error: |
387 | inc [NumARP] |
416 | 388 | pop eax |
|
417 | DEBUGF 1,"error! \n" |
389 | DEBUGF 1,"New entry created: %u\n", eax |
418 | 390 | ||
419 | mov eax, -1 |
- | |
420 | jmp .exit |
- | |
421 | - | ||
422 | - | ||
423 | ;----------------------------------------------------------------- |
- | |
424 | ; |
- | |
425 | ; ARP_del_entry |
- | |
426 | ; |
- | |
427 | ; IN: entry # in esi |
- | |
428 | ; OUT: / |
- | |
429 | ; |
- | |
430 | ;----------------------------------------------------------------- |
- | |
431 | align 4 |
- | |
432 | ARP_del_entry: |
- | |
433 | - | ||
434 | DEBUGF 1,"ARP del entry %u, total entrys: %u\n", esi, [NumARP] |
- | |
435 | - | ||
436 | cmp esi, [NumARP] |
- | |
437 | jge .error |
- | |
438 | - | ||
439 | imul esi, ARP_ENTRY.size |
- | |
440 | - | ||
441 | mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size |
- | |
442 | sub ecx, esi |
- | |
443 | - | ||
444 | lea edi, [ARPTable + esi] ;edi=ptr to entry that should be deleted |
- | |
445 | lea esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry |
- | |
Line 446... | Line 391... | ||
446 | 391 | .exit: |
|
Line 447... | Line 392... | ||
447 | shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER! |
392 | DEBUGF 1,"Exiting\n" |
448 | rep movsw |
393 | ret |
Line -... | Line 394... | ||
- | 394 | ||
- | 395 | .error: |
|
449 | 396 | DEBUGF 1,"error! \n" |
|
Line -... | Line 397... | ||
- | 397 | mov eax, -1 |
|
450 | dec [NumARP] ;decrease arp-entries counter |
398 | ret |
451 | DEBUGF 1,"ARP entry deleted\n" |
399 | |
Line 452... | Line -... | ||
452 | .error: |
- | |
453 | ret |
400 | |
454 | - | ||
455 | 401 | ;----------------------------------------------------------------- |
|
Line -... | Line 402... | ||
- | 402 | ; |
|
456 | 403 | ; ARP_del_entry |
|
Line -... | Line 404... | ||
- | 404 | ; |
|
- | 405 | ; IN: esi = ptr to arp entry |
|
Line 457... | Line 406... | ||
457 | 406 | ; OUT: / |
|
- | 407 | ; |
|
Line -... | Line 408... | ||
- | 408 | ;----------------------------------------------------------------- |
|
- | 409 | align 4 |
|
- | 410 | ARP_del_entry: |
|
- | 411 | ||
- | 412 | DEBUGF 1,"ARP del entry %x, total entrys: %u\n", esi, [NumARP] |
|
- | 413 | ||
- | 414 | mov ecx, ARP_table + (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size |
|
- | 415 | sub ecx, esi |
|
- | 416 | shr ecx, 1 |
|
- | 417 | ||
Line 458... | Line 418... | ||
458 | ;----------------------------------------------------------------- |
418 | mov edi, esi |
459 | ; |
419 | lea esi, [edi + ARP_ENTRY.size] |
460 | ; ARP_Handler: |
- | |
Line 461... | Line 420... | ||
461 | ; |
420 | rep movsw |
462 | ; This function handles ARP protocol over ethernet |
- | |
463 | ; (other protocols may follow in the future) |
421 | |
464 | ; |
- | |
465 | ; IN: Pointer to buffer in [esp] |
- | |
Line 466... | Line -... | ||
466 | ; size of buffer in [esp+4] |
- | |
467 | ; packet size (without ethernet header) in ecx |
- | |
468 | ; OUT: / |
- | |
469 | ; |
- | |
470 | ;----------------------------------------------------------------- |
- | |
471 | align 4 |
- | |
472 | ARP_handler: |
422 | dec [NumARP] |
473 | - | ||
Line -... | Line 423... | ||
- | 423 | DEBUGF 1,"ARP entry deleted\n" |
|
474 | DEBUGF 1,"ARP_Handler - start\n" |
424 | |
- | 425 | ret |
|
- | 426 | ||
- | 427 | ||
- | 428 | ||
- | 429 | ||
475 | cmp ecx, 28 |
430 | |
Line 476... | Line 431... | ||
476 | jl .exit |
431 | ;----------------------------------------------------------------- |
477 | - | ||
478 | cmp word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE ; Is this a reply packet? |
- | |
479 | jne .maybe_request |
- | |
480 | 432 | ; |
|
481 | DEBUGF 1,"ARP_Handler - it's a reply packet from %u.%u.%u.%u\n",\ |
- | |
Line 482... | Line -... | ||
482 | [edx + ARP_Packet.SenderIP]:1,[edx + ARP_Packet.SenderIP+1]:1,[edx + ARP_Packet.SenderIP+2]:1,[edx + ARP_Packet.SenderIP+3]:1, |
- | |
483 | - | ||
484 | mov ecx, [NumARP] |
- | |
485 | test ecx, ecx |
- | |
486 | jz .exit |
- | |
487 | - | ||
488 | mov eax, [edx + ARP_Packet.SenderIP] |
433 | ; ARP_IP_to_MAC |
489 | mov esi, ARPTable+ARP_ENTRY.IP |
- | |
490 | - | ||
491 | .loop: |
- | |
Line 492... | Line 434... | ||
492 | cmp [esi], eax |
434 | ; |
Line 493... | Line 435... | ||
493 | je .gotit |
435 | ; This function translates an IP address to a MAC address |
494 | add esi, ARP_ENTRY.size |
- | |
495 | loop .loop |
436 | ; |
496 | - | ||
497 | jmp .exit |
- | |
498 | - | ||
499 | .gotit: |
- | |
500 | - | ||
501 | DEBUGF 1,"ARP_Handler - found matching entry\n" |
- | |
Line -... | Line 437... | ||
- | 437 | ; IN: eax = IPv4 address |
|
502 | 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 |
|
Line -... | Line 441... | ||
- | 441 | ; |
|
503 | cmp [esi+ARP_ENTRY.Status], 0x0300 ;if it is a static entry, dont touch it |
442 | ;----------------------------------------------------------------- |
504 | je .exit |
443 | align 4 |
Line 505... | Line 444... | ||
505 | 444 | ARP_IP_to_MAC: |
|
506 | DEBUGF 1,"ARP_Handler - updating entry\n" |
445 | |
507 | 446 | DEBUGF 1,"ARP_IP_to_MAC\n" |
|
Line -... | Line 447... | ||
- | 447 | ||
508 | mov [esi+ARP_ENTRY.Status], ARP_VALID_MAPPING |
448 | cmp eax, 0xffffffff |
- | 449 | je .broadcast |
|
- | 450 | ||
509 | mov [esi+ARP_ENTRY.TTL], ARP_ENTRY_TTL |
451 | ; if ((Remote IP & subnet_mask) == (local IP & subnet_mask )) |
Line -... | Line 452... | ||
- | 452 | ; destination is on same subnet |
|
- | 453 | ; else, destination is remote and must use a gateway |
|
- | 454 | ||
- | 455 | call IPv4_dest_to_dev |
|
Line 510... | Line 456... | ||
510 | 456 | mov ebx, [IP_LIST + edi] |
|
511 | mov eax, dword [edx + ARP_Packet.SenderMAC] |
457 | and ebx, [SUBNET_LIST + edi] |
Line 641... | Line 587... | ||
641 | cmp ecx, [NumARP] |
587 | cmp ecx, [NumARP] |
642 | jge .error |
588 | jge .error |
643 | ; edi = pointer to buffer |
589 | ; edi = pointer to buffer |
644 | ; ecx = # entry |
590 | ; ecx = # entry |
645 | imul ecx, ARP_ENTRY.size |
591 | imul ecx, ARP_ENTRY.size |
646 | add ecx, ARPTable |
592 | add ecx, ARP_table |
647 | mov esi, ecx |
593 | mov esi, ecx |
648 | mov ecx, ARP_ENTRY.size/2 |
594 | mov ecx, ARP_ENTRY.size/2 |
649 | rep movsw |
595 | rep movsw |
Line 650... | Line 596... | ||
650 | 596 | ||
651 | xor eax, eax |
597 | xor eax, eax |
Line 652... | Line 598... | ||
652 | ret |
598 | ret |
653 | 599 | ||
654 | .write: |
- | |
655 | ; esi = pointer to buffer |
- | |
656 | sub esp, ARP_ENTRY.size |
- | |
657 | mov edi, esp |
- | |
658 | mov ecx, ARP_ENTRY.size/2 |
600 | .write: |
659 | rep movsw |
601 | ; esi = pointer to buffer |
Line 660... | Line 602... | ||
660 | call ARP_add_entry ;out: eax = entry number, -1 on error |
602 | call ARP_add_entry ;out: eax = entry number, -1 on error |
661 | ret |
603 | ret |
662 | 604 | ||
- | 605 | .remove: |
|
- | 606 | ; ecx = # entry |
|
- | 607 | cmp ecx, [NumARP] |
|
663 | .remove: |
608 | jge .error |
664 | ; ecx = # entry |
609 | imul ecx, ARP_ENTRY.size |