Rev 1171 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1171 | Rev 1185 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2008. 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 | ;; Address Resolution Protocol ;; |
8 | ;; Address Resolution Protocol ;; |
9 | ;; ;; |
9 | ;; ;; |
10 | ;; This file contains the following: ;; |
10 | ;; This file contains the following: ;; |
11 | ;; arp_table_manager - Manages an ARPTable ;; |
11 | ;; arp_table_manager - Manages an ARPTable ;; |
12 | ;; arp_request - Sends an ARP request on the ethernet ;; |
12 | ;; arp_request - Sends an ARP request on the ethernet ;; |
13 | ;; arp_handler - Called when an ARP packet is received ;; |
13 | ;; arp_handler - Called when an ARP packet is received ;; |
14 | ;; ;; |
14 | ;; ;; |
15 | ;; Changes history: ;; |
15 | ;; Changes history: ;; |
16 | ;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
16 | ;; 22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net ;; |
17 | ;; 11.11.2006 - [Johnny_B] and [smb] ;; |
17 | ;; 11.11.2006 - [Johnny_B] and [smb] ;; |
18 | ;; ;; |
18 | ;; ;; |
19 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
19 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
20 | 20 | ||
21 | $Revision: 983 $ |
21 | $Revision: 983 $ |
22 | 22 | ||
23 | 23 | ||
24 | ARP_NO_ENTRY equ 0 |
24 | ARP_NO_ENTRY equ 0 |
25 | ARP_VALID_MAPPING equ 1 |
25 | ARP_VALID_MAPPING equ 1 |
26 | ARP_AWAITING_RESPONSE equ 2 |
26 | ARP_AWAITING_RESPONSE equ 2 |
27 | ARP_RESPONSE_TIMEOUT equ 3 |
27 | ARP_RESPONSE_TIMEOUT equ 3 |
28 | 28 | ||
29 | ETHER_ARP equ 0x0608 |
29 | ETHER_ARP equ 0x0608 |
30 | 30 | ||
31 | ARP_REQ_OPCODE equ 0x0100 ; request |
31 | ARP_REQ_OPCODE equ 0x0100 ; request |
32 | ARP_REP_OPCODE equ 0x0200 ; reply |
32 | ARP_REP_OPCODE equ 0x0200 ; reply |
33 | 33 | ||
34 | ARP_TABLE_SIZE equ 20 ; Size of table |
34 | ARP_TABLE_SIZE equ 20 ; Size of table |
35 | 35 | ||
36 | struct ARP_ENTRY |
36 | struct ARP_ENTRY |
37 | .IP dd ? |
37 | .IP dd ? |
38 | .MAC dp ? |
38 | .MAC dp ? |
39 | .Status dw ? |
39 | .Status dw ? |
40 | .TTL dw ? ; in seconds |
40 | .TTL dw ? ; in seconds |
41 | .size: |
41 | .size: |
42 | ends |
42 | ends |
43 | 43 | ||
44 | struct ARP_Packet |
44 | struct ARP_Packet |
45 | .HardwareType dw ? |
45 | .HardwareType dw ? |
46 | .ProtocolType dw ? |
46 | .ProtocolType dw ? |
47 | .HardwareSize db ? |
47 | .HardwareSize db ? |
48 | .ProtocolSize db ? |
48 | .ProtocolSize db ? |
49 | .Opcode dw ? |
49 | .Opcode dw ? |
50 | .SenderMAC dp ? |
50 | .SenderMAC dp ? |
51 | .SenderIP dd ? |
51 | .SenderIP dd ? |
52 | .TargetMAC dp ? |
52 | .TargetMAC dp ? |
53 | .TargetIP dd ? |
53 | .TargetIP dd ? |
54 | ends |
54 | ends |
55 | 55 | ||
56 | 56 | ||
57 | ; The TTL field is decremented every second, and is deleted when it |
57 | ; The TTL field is decremented every second, and is deleted when it |
58 | ; reaches 0. It is refreshed every time a packet is received |
58 | ; reaches 0. It is refreshed every time a packet is received |
59 | ; If the TTL field is 0xFFFF it is a static entry and is never deleted |
59 | ; If the TTL field is 0xFFFF it is a static entry and is never deleted |
60 | ; The status field can be the following values: |
60 | ; The status field can be the following values: |
61 | ; 0x0000 entry not used |
61 | ; 0x0000 entry not used |
62 | ; 0x0001 entry holds a valid mapping |
62 | ; 0x0001 entry holds a valid mapping |
63 | ; 0x0002 entry contains an IP address, awaiting ARP response |
63 | ; 0x0002 entry contains an IP address, awaiting ARP response |
64 | ; 0x0003 No response received to ARP request. |
64 | ; 0x0003 No response received to ARP request. |
65 | ; The last status value is provided to allow the network layer to delete |
65 | ; The last status value is provided to allow the network layer to delete |
66 | ; a packet that is queued awaiting an ARP response |
66 | ; a packet that is queued awaiting an ARP response |
67 | 67 | ||
68 | align 4 |
68 | align 4 |
69 | uglobal |
69 | uglobal |
70 | 70 | ||
71 | NumARP dd ? |
71 | NumARP dd ? |
72 | ARPTable rb ARP_ENTRY.size * ARP_TABLE_SIZE |
72 | ARPTable rb ARP_ENTRY.size * ARP_TABLE_SIZE |
73 | 73 | ||
74 | ARP_PACKETS_TX rd MAX_NET_DEVICES |
74 | ARP_PACKETS_TX rd MAX_NET_DEVICES |
75 | ARP_PACKETS_RX rd MAX_NET_DEVICES |
75 | ARP_PACKETS_RX rd MAX_NET_DEVICES |
76 | 76 | ||
77 | 77 | ||
78 | endg |
78 | endg |
79 | 79 | ||
80 | 80 | ||
81 | 81 | ||
82 | 82 | ||
83 | ARP_init: |
83 | ARP_init: |
84 | 84 | ||
85 | xor eax, eax |
85 | xor eax, eax |
86 | 86 | ||
87 | mov [NumARP], eax |
87 | mov [NumARP], eax |
88 | 88 | ||
89 | mov edi, ARP_PACKETS_TX |
89 | mov edi, ARP_PACKETS_TX |
90 | mov ecx, 2*MAX_NET_DEVICES |
90 | mov ecx, 2*MAX_NET_DEVICES |
91 | rep stosd |
91 | rep stosd |
92 | 92 | ||
93 | ret |
93 | ret |
94 | 94 | ||
95 | 95 | ||
96 | 96 | ||
97 | 97 | ||
98 | ;*************************************************************************** |
98 | ;*************************************************************************** |
99 | ; Function |
99 | ; Function |
100 | ; arp_table_manager [by Johnny_B] |
100 | ; arp_table_manager [by Johnny_B] |
101 | ; |
101 | ; |
102 | ; Description |
102 | ; Description |
103 | ; Does a most required operations with ARP-table |
103 | ; Does a most required operations with ARP-table |
104 | ; IN: |
104 | ; IN: |
105 | ; Operation: see Opcode's constants below |
105 | ; Operation: see Opcode's constants below |
106 | ; Index: Index of entry in the ARP-table |
106 | ; Index: Index of entry in the ARP-table |
107 | ; Extra: Extra parameter for some Opcodes |
107 | ; Extra: Extra parameter for some Opcodes |
108 | ; OUT: |
108 | ; OUT: |
109 | ; EAX = Returned value depends on opcodes, more detailed see below |
109 | ; EAX = Returned value depends on opcodes, more detailed see below |
110 | ; |
110 | ; |
111 | ;*************************************************************************** |
111 | ;*************************************************************************** |
112 | ;Opcode's constants |
112 | ;Opcode's constants |
113 | ARP_TABLE_ADD equ 1 |
113 | ARP_TABLE_ADD equ 1 |
114 | ARP_TABLE_DEL equ 2 |
114 | ARP_TABLE_DEL equ 2 |
115 | ARP_TABLE_GET equ 3 |
115 | ARP_TABLE_GET equ 3 |
116 | ARP_TABLE_GET_ENTRIES_NUMBER equ 4 |
116 | ARP_TABLE_GET_ENTRIES_NUMBER equ 4 |
117 | ARP_TABLE_IP_TO_MAC equ 5 |
117 | ARP_TABLE_IP_TO_MAC equ 5 |
118 | ARP_TABLE_TIMER equ 6 |
118 | ARP_TABLE_TIMER equ 6 |
119 | 119 | ||
120 | ;Index's constants |
120 | ;Index's constants |
121 | EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_Packet |
121 | EXTRA_IS_ARP_PACKET_PTR equ 0 ;if Extra contain pointer to ARP_Packet |
122 | EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY |
122 | EXTRA_IS_ARP_ENTRY_PTR equ -1 ;if Extra contain pointer to ARP_ENTRY |
123 | 123 | ||
124 | align 4 |
124 | align 4 |
125 | proc arp_table_manager stdcall uses ebx esi edi ecx edx, Opcode:DWORD,Index:DWORD,Extra:DWORD |
125 | proc arp_table_manager stdcall uses ebx esi edi ecx edx, Opcode:DWORD,Index:DWORD,Extra:DWORD |
126 | 126 | ||
127 | mov ebx, ARPTable ;ARPTable base |
127 | mov ebx, ARPTable ;ARPTable base |
128 | mov ecx, dword[NumARP] ;ARP-entries counter |
128 | mov ecx, dword[NumARP] ;ARP-entries counter |
129 | 129 | ||
130 | mov eax, dword[Opcode] |
130 | mov eax, dword[Opcode] |
131 | 131 | ||
132 | cmp eax, ARP_TABLE_TIMER |
132 | cmp eax, ARP_TABLE_TIMER |
133 | je .timer |
133 | je .timer |
134 | 134 | ||
135 | DEBUGF 1,"ARP table manager opcode:%u numARP:%u\n",eax,ecx |
135 | DEBUGF 1,"ARP table manager opcode:%u numARP:%u\n",eax,ecx |
136 | 136 | ||
137 | cmp eax, ARP_TABLE_ADD |
137 | cmp eax, ARP_TABLE_ADD |
138 | je .add |
138 | je .add |
139 | cmp eax, ARP_TABLE_DEL |
139 | cmp eax, ARP_TABLE_DEL |
140 | je .del |
140 | je .del |
141 | cmp eax, ARP_TABLE_GET |
141 | cmp eax, ARP_TABLE_GET |
142 | je .get |
142 | je .get |
143 | cmp eax, ARP_TABLE_IP_TO_MAC |
143 | cmp eax, ARP_TABLE_IP_TO_MAC |
144 | je .ip_to_mac |
144 | je .ip_to_mac |
145 | cmp eax, ARP_TABLE_GET_ENTRIES_NUMBER |
145 | cmp eax, ARP_TABLE_GET_ENTRIES_NUMBER |
146 | je .get_entries_number |
146 | je .get_entries_number |
147 | jmp .exit ;if unknown opcode |
147 | jmp .exit ;if unknown opcode |
148 | 148 | ||
149 | 149 | ||
150 | ;;BEGIN TIMER |
150 | ;;BEGIN TIMER |
151 | ;;Description: it must be callback every second. It is responsible for removing expired routes. |
151 | ;;Description: it must be callback every second. It is responsible for removing expired routes. |
152 | ;;IN: Operation: ARP_TABLE_TIMER |
152 | ;;IN: Operation: ARP_TABLE_TIMER |
153 | ;; Index: must be zero |
153 | ;; Index: must be zero |
154 | ;; Extra: must be zero |
154 | ;; Extra: must be zero |
155 | ;;OUT: |
155 | ;;OUT: |
156 | ;; EAX=not defined |
156 | ;; EAX=not defined |
157 | ;; |
157 | ;; |
158 | .timer: |
158 | .timer: |
159 | test ecx, ecx |
159 | test ecx, ecx |
160 | jz .exit ;if NumARP=0 nothing to do |
160 | jz .exit ;if NumARP=0 nothing to do |
161 | ; sub ecx, ARP_TABLE_ENTRIES ;ecx=dynamic entries number |
161 | ; sub ecx, ARP_TABLE_ENTRIES ;ecx=dynamic entries number |
162 | ; jz .exit ;if NumARP=number of static entries then exit |
162 | ; jz .exit ;if NumARP=number of static entries then exit |
163 | 163 | ||
164 | ; add ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE ;ebx=dynamic entries base |
164 | ; add ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE ;ebx=dynamic entries base |
165 | 165 | ||
166 | .timer_loop: |
166 | .timer_loop: |
167 | movsx esi, word [ebx + ARP_ENTRY.TTL] |
167 | movsx esi, word [ebx + ARP_ENTRY.TTL] |
168 | cmp esi, 0xFFFFFFFF |
168 | cmp esi, 0xFFFFFFFF |
169 | je .timer_loop_end ;if TTL==0xFFFF then it's static entry |
169 | je .timer_loop_end ;if TTL==0xFFFF then it's static entry |
170 | 170 | ||
171 | test esi, esi |
171 | test esi, esi |
172 | jnz .timer_loop_end_with_dec ;if TTL!=0 |
172 | jnz .timer_loop_end_with_dec ;if TTL!=0 |
173 | 173 | ||
174 | ; Ok, TTL is 0 |
174 | ; Ok, TTL is 0 |
175 | ;if Status==AWAITING_RESPONSE and TTL==0 |
175 | ;if Status==AWAITING_RESPONSE and TTL==0 |
176 | ;then we have to change it to ARP_RESPONSE_TIMEOUT |
176 | ;then we have to change it to ARP_RESPONSE_TIMEOUT |
177 | cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
177 | cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
178 | jne @f |
178 | jne @f |
179 | 179 | ||
180 | mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
180 | mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
181 | mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec |
181 | mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec |
182 | jmp .timer_loop_end |
182 | jmp .timer_loop_end |
183 | 183 | ||
184 | @@: |
184 | @@: |
185 | ;if TTL==0 and Status==VALID_MAPPING, we have to delete it |
185 | ;if TTL==0 and Status==VALID_MAPPING, we have to delete it |
186 | ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too |
186 | ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too |
187 | mov esi, dword[NumARP] |
187 | mov esi, dword[NumARP] |
188 | sub esi, ecx ;esi=index of entry, will be deleted |
188 | sub esi, ecx ;esi=index of entry, will be deleted |
189 | stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra |
189 | stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra |
190 | jmp .timer_loop_end |
190 | jmp .timer_loop_end |
191 | 191 | ||
192 | 192 | ||
193 | .timer_loop_end_with_dec: |
193 | .timer_loop_end_with_dec: |
194 | dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL |
194 | dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL |
195 | .timer_loop_end: |
195 | .timer_loop_end: |
196 | add ebx, ARP_ENTRY.size |
196 | add ebx, ARP_ENTRY.size |
197 | loop .timer_loop |
197 | loop .timer_loop |
198 | 198 | ||
199 | jmp .exit |
199 | jmp .exit |
200 | ;;END TIMER |
200 | ;;END TIMER |
201 | 201 | ||
202 | ;;BEGIN ADD |
202 | ;;BEGIN ADD |
203 | ;;Description: it adds an entry in the table. If ARP-table already |
203 | ;;Description: it adds an entry in the table. If ARP-table already |
204 | ;; contains same IP, it will be updated. |
204 | ;; contains same IP, it will be updated. |
205 | ;;IN: Operation: ARP_TABLE_ADD |
205 | ;;IN: Operation: ARP_TABLE_ADD |
206 | ;; Index: specifies what contains Extra-parameter |
206 | ;; Index: specifies what contains Extra-parameter |
207 | ;; Extra: if Index==EXTRA_IS_ARP_Packet_PTR, |
207 | ;; Extra: if Index==EXTRA_IS_ARP_Packet_PTR, |
208 | ;; then Extra contains pointer to ARP_Packet, |
208 | ;; then Extra contains pointer to ARP_Packet, |
209 | ;; otherwise Extra contains pointer to ARP_ENTRY |
209 | ;; otherwise Extra contains pointer to ARP_ENTRY |
210 | ;;OUT: |
210 | ;;OUT: |
211 | ;; EAX=index of entry, that has been added |
211 | ;; EAX=index of entry, that has been added |
212 | ;; |
212 | ;; |
213 | .add: |
213 | .add: |
214 | 214 | ||
215 | DEBUGF 1,"1" |
215 | DEBUGF 1,"1" |
216 | 216 | ||
217 | sub esp, ARP_ENTRY.size ;Allocate ARP_ENTRY_SIZE byte in stack |
217 | sub esp, ARP_ENTRY.size ;Allocate ARP_ENTRY_SIZE byte in stack |
218 | 218 | ||
219 | mov esi, [Extra] ;pointer |
219 | mov esi, [Extra] ;pointer |
220 | mov edi, [Index] ;opcode |
220 | mov edi, [Index] ;opcode |
221 | 221 | ||
222 | cmp edi, EXTRA_IS_ARP_PACKET_PTR |
222 | cmp edi, EXTRA_IS_ARP_PACKET_PTR |
223 | je .ARP_Packet_to_entry ;if Extra contain ptr to ARP_Packet and we have to form arp-entry |
223 | je .ARP_Packet_to_entry ;if Extra contain ptr to ARP_Packet and we have to form arp-entry |
224 | ;else it contain ptr to arp-entry |
224 | ;else it contain ptr to arp-entry |
225 | 225 | ||
226 | DEBUGF 1,"2" |
226 | DEBUGF 1,"2" |
227 | 227 | ||
228 | cld |
228 | cld |
229 | ; esi already has been loaded |
229 | ; esi already has been loaded |
230 | mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) |
230 | mov edi, esp ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) |
231 | mov ecx,ARP_ENTRY.size/2 ;ARP_ENTRY_SIZE must be even number!!! |
231 | mov ecx,ARP_ENTRY.size/2 ;ARP_ENTRY_SIZE must be even number!!! |
232 | rep movsw ;copy |
232 | rep movsw ;copy |
233 | jmp .search |
233 | jmp .search |
234 | 234 | ||
235 | .ARP_Packet_to_entry: |
235 | .ARP_Packet_to_entry: |
236 | 236 | ||
237 | DEBUGF 1,"3" |
237 | DEBUGF 1,"3" |
238 | mov edx, dword[esi + ARP_Packet.SenderIP] ;esi=base of ARP_Packet |
238 | mov edx, dword[esi + ARP_Packet.SenderIP] ;esi=base of ARP_Packet |
239 | mov [esp + ARP_ENTRY.IP], edx |
239 | mov [esp + ARP_ENTRY.IP], edx |
240 | 240 | ||
241 | cld |
241 | cld |
242 | lea esi, [esi + ARP_Packet.SenderMAC] |
242 | lea esi, [esi + ARP_Packet.SenderMAC] |
243 | lea edi, [esp + ARP_ENTRY.MAC] |
243 | lea edi, [esp + ARP_ENTRY.MAC] |
244 | movsd |
244 | movsd |
245 | movsw |
245 | movsw |
246 | mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING ; specify the type - a valid entry |
246 | mov word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING ; specify the type - a valid entry |
247 | mov word[esp + ARP_ENTRY.TTL], 0x0E10 ; = 1 hour |
247 | mov word[esp + ARP_ENTRY.TTL], 0x0E10 ; = 1 hour |
248 | 248 | ||
249 | .search: |
249 | .search: |
250 | 250 | ||
251 | DEBUGF 1,"4" |
251 | DEBUGF 1,"4" |
252 | mov edx, dword[esp + ARP_ENTRY.IP] ;edx=IP-address, which we'll search |
252 | mov edx, dword[esp + ARP_ENTRY.IP] ;edx=IP-address, which we'll search |
253 | mov ecx, dword[NumARP] ;ecx=ARP-entries counter |
253 | mov ecx, dword[NumARP] ;ecx=ARP-entries counter |
254 | jecxz .add_to_end ;if ARP-entries number == 0 |
254 | jecxz .add_to_end ;if ARP-entries number == 0 |
255 | imul eax, ecx, ARP_ENTRY.size ;eax=current table size(in bytes) |
255 | imul eax, ecx, ARP_ENTRY.size ;eax=current table size(in bytes) |
256 | @@: |
256 | @@: |
257 | sub eax, ARP_ENTRY.size |
257 | sub eax, ARP_ENTRY.size |
258 | cmp dword[ebx + eax + ARP_ENTRY.IP], edx |
258 | cmp dword[ebx + eax + ARP_ENTRY.IP], edx |
259 | loopnz @b |
259 | loopnz @b |
260 | ; jz .replace ; found, replace existing entry, ptr to it is in eax |
260 | ; jz .replace ; found, replace existing entry, ptr to it is in eax |
261 | 261 | ||
262 | .add_to_end: |
262 | .add_to_end: |
263 | ; |
263 | ; |
264 | ; DEBUGF 1,"5\n" |
264 | ; DEBUGF 1,"5\n" |
265 | ; ;else add to end |
265 | ; ;else add to end |
266 | ; or eax,-1 ;set eax=0xFFFFFFFF if adding is impossible |
266 | ; or eax,-1 ;set eax=0xFFFFFFFF if adding is impossible |
267 | ; mov ecx, dword[NumARP] |
267 | ; mov ecx, dword[NumARP] |
268 | ; cmp ecx, ARP_TABLE_SIZE |
268 | ; cmp ecx, ARP_TABLE_SIZE |
269 | ; je .add_exit ;if arp-entries number is equal to arp-table maxsize |
269 | ; je .add_exit ;if arp-entries number is equal to arp-table maxsize |
270 | 270 | ||
271 | ; imul eax, dword[NumARP], ARP_ENTRY.size ;eax=ptr to end of ARPTable |
271 | ; imul eax, dword[NumARP], ARP_ENTRY.size ;eax=ptr to end of ARPTable |
272 | ; inc dword [NumARP] ;increase ARP-entries counter |
272 | ; inc dword [NumARP] ;increase ARP-entries counter |
273 | 273 | ||
274 | ; .replace: |
274 | ; .replace: |
275 | DEBUGF 1,"Updating ARP entry: %x-%x-%x-%x-%x-%x = %u.%u.%u.%u to slot:%u\n",\ |
275 | DEBUGF 1,"Updating ARP entry: %x-%x-%x-%x-%x-%x = %u.%u.%u.%u to slot:%u\n",\ |
276 | [esp + ARP_ENTRY.MAC]:2,[esp + ARP_ENTRY.MAC+1]:2,[esp + ARP_ENTRY.MAC+2]:2,[esp + ARP_ENTRY.MAC+3]:2,[esp + ARP_ENTRY.MAC+4]:2,[esp + ARP_ENTRY.MAC+5]:2,\ |
276 | [esp + ARP_ENTRY.MAC]:2,[esp + ARP_ENTRY.MAC+1]:2,[esp + ARP_ENTRY.MAC+2]:2,[esp + ARP_ENTRY.MAC+3]:2,[esp + ARP_ENTRY.MAC+4]:2,[esp + ARP_ENTRY.MAC+5]:2,\ |
277 | [esp + ARP_ENTRY.IP]:1,[esp + ARP_ENTRY.IP+1]:1,[esp + ARP_ENTRY.IP+2]:1,[esp + ARP_ENTRY.IP+3]:1,eax |
277 | [esp + ARP_ENTRY.IP]:1,[esp + ARP_ENTRY.IP+1]:1,[esp + ARP_ENTRY.IP+2]:1,[esp + ARP_ENTRY.IP+3]:1,eax |
278 | 278 | ||
279 | cld |
279 | cld |
280 | mov esi, esp ;esp=base of ARP-entry, that will be added |
280 | mov esi, esp ;esp=base of ARP-entry, that will be added |
281 | lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) |
281 | lea edi, [ebx + eax] ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add) |
282 | mov ecx,ARP_ENTRY.size/2 ;ARP_ENTRY_SIZE must be even number!!! |
282 | mov ecx,ARP_ENTRY.size/2 ;ARP_ENTRY_SIZE must be even number!!! |
283 | rep movsw |
283 | rep movsw |
284 | 284 | ||
285 | mov ecx, ARP_ENTRY.size |
285 | mov ecx, ARP_ENTRY.size |
286 | xor edx, edx ;"div" takes operand from EDX:EAX |
286 | xor edx, edx ;"div" takes operand from EDX:EAX |
287 | div ecx ;eax=index of entry, which has been added |
287 | div ecx ;eax=index of entry, which has been added |
288 | 288 | ||
289 | 289 | ||
290 | 290 | ||
291 | .add_exit: |
291 | .add_exit: |
292 | 292 | ||
293 | add esp, ARP_ENTRY.size ;free stack |
293 | add esp, ARP_ENTRY.size ;free stack |
294 | jmp .exit |
294 | jmp .exit |
295 | ;;END ADD |
295 | ;;END ADD |
296 | 296 | ||
297 | ;;BEGIN DEL |
297 | ;;BEGIN DEL |
298 | ;;Description: it deletes an entry in the table. |
298 | ;;Description: it deletes an entry in the table. |
299 | ;;IN: Operation: ARP_TABLE_DEL |
299 | ;;IN: Operation: ARP_TABLE_DEL |
300 | ;; Index: index of entry, that should be deleted |
300 | ;; Index: index of entry, that should be deleted |
301 | ;; Extra: must be zero |
301 | ;; Extra: must be zero |
302 | ;;OUT: |
302 | ;;OUT: |
303 | ;; EAX=not defined |
303 | ;; EAX=not defined |
304 | ;; |
304 | ;; |
305 | .del: |
305 | .del: |
306 | mov esi, [Index] |
306 | mov esi, [Index] |
307 | imul esi, ARP_ENTRY.size |
307 | imul esi, ARP_ENTRY.size |
308 | 308 | ||
309 | mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size |
309 | mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size |
310 | sub ecx, esi |
310 | sub ecx, esi |
311 | 311 | ||
312 | lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted |
312 | lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted |
313 | lea esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry |
313 | lea esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry |
314 | 314 | ||
315 | shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER! |
315 | shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER! |
316 | cld |
316 | cld |
317 | rep movsw |
317 | rep movsw |
318 | 318 | ||
319 | dec dword[NumARP] ;decrease arp-entries counter |
319 | dec dword[NumARP] ;decrease arp-entries counter |
320 | jmp .exit |
320 | jmp .exit |
321 | ;;END DEL |
321 | ;;END DEL |
322 | 322 | ||
323 | ;;BEGIN GET |
323 | ;;BEGIN GET |
324 | ;;Description: it reads an entry of table into buffer. |
324 | ;;Description: it reads an entry of table into buffer. |
325 | ;;IN: Operation: ARP_TABLE_GET |
325 | ;;IN: Operation: ARP_TABLE_GET |
326 | ;; Index: index of entry, that should be read |
326 | ;; Index: index of entry, that should be read |
327 | ;; Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE) |
327 | ;; Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE) |
328 | ;;OUT: |
328 | ;;OUT: |
329 | ;; EAX=not defined |
329 | ;; EAX=not defined |
330 | ;; |
330 | ;; |
331 | .get: |
331 | .get: |
332 | mov esi, [Index] |
332 | mov esi, [Index] |
333 | imul esi, ARP_ENTRY.size ;esi=ptr to required ARP_ENTRY |
333 | imul esi, ARP_ENTRY.size ;esi=ptr to required ARP_ENTRY |
334 | mov edi, [Extra] ;edi=buffer for reading |
334 | mov edi, [Extra] ;edi=buffer for reading |
335 | mov ecx, ARP_ENTRY.size/2 ; must be even number!!! |
335 | mov ecx, ARP_ENTRY.size/2 ; must be even number!!! |
336 | cld |
336 | cld |
337 | rep movsw |
337 | rep movsw |
338 | jmp .exit |
338 | jmp .exit |
339 | ;;END GET |
339 | ;;END GET |
340 | 340 | ||
341 | ;;BEGIN IP_TO_MAC |
341 | ;;BEGIN IP_TO_MAC |
342 | ;;Description: it gets an IP from Index, scans each entry in the table and writes |
342 | ;;Description: it gets an IP from Index, scans each entry in the table and writes |
343 | ;; MAC, that relates to specified IP, into buffer specified in Extra. |
343 | ;; MAC, that relates to specified IP, into buffer specified in Extra. |
344 | ;; And if it cannot find an IP-address in the table, it does an ARP-request of that. |
344 | ;; And if it cannot find an IP-address in the table, it does an ARP-request of that. |
345 | ;;IN: Operation: ARP_TABLE_IP_TO_MAC |
345 | ;;IN: Operation: ARP_TABLE_IP_TO_MAC |
346 | ;; Index: IP that should be transformed into MAC |
346 | ;; Index: IP that should be transformed into MAC |
347 | ;; Extra: pointer to buffer where will be written the MAC-address. |
347 | ;; Extra: pointer to buffer where will be written the MAC-address. |
348 | ;;OUT: |
348 | ;;OUT: |
349 | ;; EAX=ARP table entry status code. |
349 | ;; EAX=ARP table entry status code. |
350 | ;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request. |
350 | ;; If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request. |
351 | ;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system. |
351 | ;; If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system. |
352 | ;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long. |
352 | ;; If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long. |
353 | ;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC. |
353 | ;; If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC. |
354 | ;; |
354 | ;; |
355 | ;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet |
355 | ;; If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet |
356 | ;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this |
356 | ;; resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this |
357 | ;; function with 1sec delay. sure, only if it not return a valid MAC after a first call. |
357 | ;; function with 1sec delay. sure, only if it not return a valid MAC after a first call. |
358 | ;; |
358 | ;; |
359 | .ip_to_mac: |
359 | .ip_to_mac: |
360 | 360 | ||
361 | DEBUGF 1,"Trying to find MAC for %u.%u.%u.%u\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1 |
361 | DEBUGF 1,"Trying to find MAC for %u.%u.%u.%u\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1 |
362 | 362 | ||
363 | xor eax, eax |
363 | xor eax, eax |
364 | mov edi, dword[Extra] |
364 | mov edi, dword[Extra] |
365 | cld |
365 | cld |
366 | stosd |
366 | stosd |
367 | stosw |
367 | stosw |
368 | 368 | ||
369 | 369 | ||
370 | ; first, check destination IP to see if it is on 'this' network. |
370 | ; first, check destination IP to see if it is on 'this' network. |
371 | ; The test is: |
371 | ; The test is: |
372 | ; if ( destIP & subnet_mask == stack_ip & subnet_mask ) |
372 | ; if ( destIP & subnet_mask == stack_ip & subnet_mask ) |
373 | ; destination is local |
373 | ; destination is local |
374 | ; else |
374 | ; else |
375 | ; destination is remote, so pass to gateway |
375 | ; destination is remote, so pass to gateway |
376 | 376 | ||
377 | 377 | ||
378 | ;;; TODO: get device number ! (in edx) |
378 | ;;; TODO: get device number ! (in edx) |
379 | xor edx, edx |
379 | xor edx, edx |
380 | 380 | ||
381 | mov eax, [Index] ;eax=required IP |
381 | mov eax, [Index] ;eax=required IP |
382 | mov esi, eax |
382 | mov esi, eax |
383 | and esi, [SUBNET_LIST+edx] |
383 | and esi, [SUBNET_LIST+edx] |
384 | mov ecx, [IP_LIST+edx] |
384 | mov ecx, [IP_LIST+edx] |
385 | and ecx, [SUBNET_LIST+edx] |
385 | and ecx, [SUBNET_LIST+edx] |
386 | cmp esi, ecx |
386 | cmp esi, ecx |
387 | je @f ;if we and target IP are located in the same network |
387 | je @f ;if we and target IP are located in the same network |
388 | mov eax, [GATEWAY_LIST+edx] |
388 | mov eax, [GATEWAY_LIST+edx] |
389 | mov [Index], eax |
389 | mov [Index], eax |
390 | DEBUGF 1,"IP is not on subnet, using %u.%u.%u.%u instead\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1 |
390 | DEBUGF 1,"IP is not on subnet, using %u.%u.%u.%u instead\n",[Index]:1,[Index+1]:1,[Index+2]:1,[Index+3]:1 |
391 | @@: |
391 | @@: |
392 | 392 | ||
393 | cmp dword[NumARP], 0 |
393 | cmp dword[NumARP], 0 |
394 | je .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP. |
394 | je .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP. |
395 | ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY |
395 | ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY |
396 | 396 | ||
397 | mov ecx, dword[NumARP] |
397 | mov ecx, dword[NumARP] |
398 | imul esi, ecx, ARP_ENTRY.size ;esi=current ARP-table size |
398 | imul esi, ecx, ARP_ENTRY.size ;esi=current ARP-table size |
399 | 399 | ||
400 | @@: |
400 | @@: |
401 | sub esi, ARP_ENTRY.size |
401 | sub esi, ARP_ENTRY.size |
402 | cmp [ebx + esi + ARP_ENTRY.IP], eax ; ebx=ARPTable base |
402 | cmp [ebx + esi + ARP_ENTRY.IP], eax ; ebx=ARPTable base |
403 | loopnz @b ; Return back if non match |
403 | loopnz @b ; Return back if non match |
404 | jnz .ip_to_mac_send_request ; and request IP->MAC if none found in the table |
404 | jnz .ip_to_mac_send_request ; and request IP->MAC if none found in the table |
405 | 405 | ||
406 | ; Return the entry status in eax |
406 | ; Return the entry status in eax |
407 | movzx eax, word[ebx + esi + ARP_ENTRY.Status] |
407 | movzx eax, word[ebx + esi + ARP_ENTRY.Status] |
408 | 408 | ||
409 | DEBUGF 1,"MAC found: %x-%x-%x-%x-%x-%x status:%x in slot:%u\n",\ |
409 | DEBUGF 1,"MAC found: %x-%x-%x-%x-%x-%x status:%x in slot:%u\n",\ |
410 | [ebx + esi + ARP_ENTRY.MAC]:2,[ebx + esi + ARP_ENTRY.MAC+1]:2,[ebx + esi + ARP_ENTRY.MAC+2]:2,[ebx + esi + ARP_ENTRY.MAC+3]:2,[ebx + esi + ARP_ENTRY.MAC+4]:2,[ebx + esi + ARP_ENTRY.MAC+5]:2, ax, esi |
410 | [ebx + esi + ARP_ENTRY.MAC]:2,[ebx + esi + ARP_ENTRY.MAC+1]:2,[ebx + esi + ARP_ENTRY.MAC+2]:2,[ebx + esi + ARP_ENTRY.MAC+3]:2,[ebx + esi + ARP_ENTRY.MAC+4]:2,[ebx + esi + ARP_ENTRY.MAC+5]:2, ax, esi |
411 | 411 | ||
412 | ; esi holds index |
412 | ; esi holds index |
413 | cld |
413 | cld |
414 | lea esi, [ebx + esi + ARP_ENTRY.MAC] |
414 | lea esi, [ebx + esi + ARP_ENTRY.MAC] |
415 | mov edi, [Extra] ;edi=ptr to buffer for write MAC |
415 | mov edi, [Extra] ;edi=ptr to buffer for write MAC |
416 | movsd |
416 | movsd |
417 | movsw |
417 | movsw |
418 | jmp .exit |
418 | jmp .exit |
419 | 419 | ||
420 | .ip_to_mac_send_request: |
420 | .ip_to_mac_send_request: |
421 | ;;; TODO: get device number ! (in edx) |
421 | ;;; TODO: get device number ! (in edx) |
422 | xor edx, edx |
422 | xor edx, edx |
423 | mov edx, [ETH_DRV_LIST + 4*edx] |
423 | mov edx, [ETH_DRV_LIST + 4*edx] |
424 | lea ecx, [edx + ETH_DEVICE.mac] |
424 | lea ecx, [edx + ETH_DEVICE.mac] |
425 | 425 | ||
426 | stdcall arp_request,[Index],[IP_LIST+edx],ecx ;TargetIP,SenderIP_ptr,SenderMAC_ptr |
426 | stdcall arp_request,[Index],[IP_LIST+edx],ecx ;TargetIP,SenderIP_ptr,SenderMAC_ptr |
427 | mov eax, ARP_NO_ENTRY |
427 | mov eax, ARP_NO_ENTRY |
428 | jmp .exit |
428 | jmp .exit |
429 | 429 | ||
430 | ;;END IP_TO_MAC |
430 | ;;END IP_TO_MAC |
431 | 431 | ||
432 | ;;BEGIN GET_ENTRIES_NUMBER |
432 | ;;BEGIN GET_ENTRIES_NUMBER |
433 | ;;Description: returns an ARP-entries number in the ARPTable |
433 | ;;Description: returns an ARP-entries number in the ARPTable |
434 | ;;IN: Operation: ARP_TABLE_GET_ENTRIES_NUMBER |
434 | ;;IN: Operation: ARP_TABLE_GET_ENTRIES_NUMBER |
435 | ;; Index: must be zero |
435 | ;; Index: must be zero |
436 | ;; Extra: must be zero |
436 | ;; Extra: must be zero |
437 | ;;OUT: |
437 | ;;OUT: |
438 | ;; EAX=ARP-entries number in the ARPTable |
438 | ;; EAX=ARP-entries number in the ARPTable |
439 | .get_entries_number: |
439 | .get_entries_number: |
440 | mov eax, dword[NumARP] |
440 | mov eax, dword[NumARP] |
441 | jmp .exit |
441 | jmp .exit |
442 | ;;END GET_ENTRIES_NUMBER |
442 | ;;END GET_ENTRIES_NUMBER |
443 | 443 | ||
444 | .exit: |
444 | .exit: |
445 | ret |
445 | ret |
446 | endp |
446 | endp |
447 | 447 | ||
448 | 448 | ||
449 | ;*************************************************************************** |
449 | ;*************************************************************************** |
450 | ; Function |
450 | ; Function |
451 | ; arp_request [by Johnny_B] |
451 | ; arp_request [by Johnny_B] |
452 | ; |
452 | ; |
453 | ; Description |
453 | ; Description |
454 | ; Sends an ARP request on the ethernet |
454 | ; Sends an ARP request on the ethernet |
455 | ; IN: |
455 | ; IN: |
456 | ; TargetIP : requested IP address |
456 | ; TargetIP : requested IP address |
457 | ; SenderIP_ptr : POINTER to sender's IP address(our system's address) |
457 | ; SenderIP_ptr : POINTER to sender's IP address(our system's address) |
458 | ; SenderMAC_ptr : POINTER to sender's MAC address(our system's address) |
458 | ; SenderMAC_ptr : POINTER to sender's MAC address(our system's address) |
459 | ; OUT: |
459 | ; OUT: |
460 | ; EAX=0 (if all is ok), otherwise EAX is not defined |
460 | ; EAX=0 (if all is ok), otherwise EAX is not defined |
461 | ; |
461 | ; |
462 | ; EBX,ESI,EDI will be saved |
462 | ; EBX,ESI,EDI will be saved |
463 | ; |
463 | ; |
464 | ;*************************************************************************** |
464 | ;*************************************************************************** |
465 | proc arp_request stdcall uses ebx esi edi,\ |
465 | proc arp_request stdcall uses ebx esi edi,\ |
466 | TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD |
466 | TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD |
467 | 467 | ||
468 | DEBUGF 1,"Create ARP request\n" |
468 | DEBUGF 1,"Create ARP request\n" |
469 | 469 | ||
470 | 470 | ||
471 | stdcall kernel_alloc, 60 ; minimum eth packet size |
471 | stdcall kernel_alloc, 60 ; minimum eth packet size |
472 | test eax, eax |
472 | test eax, eax |
473 | jz .exit |
473 | jz .exit |
474 | 474 | ||
475 | mov ebx, eax |
475 | mov ebx, eax |
476 | 476 | ||
477 | mov word [ebx + ETH_FRAME.Data + ARP_Packet.HardwareType], 0x0100 ;Ethernet |
477 | mov word [ebx + ETH_FRAME.Data + ARP_Packet.HardwareType], 0x0100 ;Ethernet |
478 | mov word [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolType], 0x0008 ;IP |
478 | mov word [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolType], 0x0008 ;IP |
479 | mov byte [ebx + ETH_FRAME.Data + ARP_Packet.HardwareSize], 0x06 ;MAC-addr length |
479 | mov byte [ebx + ETH_FRAME.Data + ARP_Packet.HardwareSize], 0x06 ;MAC-addr length |
480 | mov byte [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolSize], 0x04 ;IP-addr length |
480 | mov byte [ebx + ETH_FRAME.Data + ARP_Packet.ProtocolSize], 0x04 ;IP-addr length |
481 | mov word [ebx + ETH_FRAME.Data + ARP_Packet.Opcode], 0x0100 ;Request |
481 | mov word [ebx + ETH_FRAME.Data + ARP_Packet.Opcode], 0x0100 ;Request |
482 | 482 | ||
483 | DEBUGF 1,"1" |
483 | DEBUGF 1,"1" |
484 | 484 | ||
485 | cld |
485 | cld |
486 | mov esi, [SenderMAC_ptr] |
486 | mov esi, [SenderMAC_ptr] |
487 | lea edi, [ebx + ETH_FRAME.Data + ARP_Packet.SenderMAC] ;Our MAC-addr |
487 | lea edi, [ebx + ETH_FRAME.Data + ARP_Packet.SenderMAC] ;Our MAC-addr |
488 | movsd |
488 | movsd |
489 | movsw |
489 | movsw |
490 | 490 | ||
491 | DEBUGF 1,"2" |
491 | DEBUGF 1,"2" |
492 | 492 | ||
493 | mov esi, [SenderIP_ptr] |
493 | mov esi, [SenderIP_ptr] |
494 | mov [ebx + ETH_FRAME.Data + ARP_Packet.SenderIP], esi ;Our IP-addr |
494 | mov [ebx + ETH_FRAME.Data + ARP_Packet.SenderIP], esi ;Our IP-addr |
495 | ; movsd |
495 | ; movsd |
496 | 496 | ||
497 | DEBUGF 1,"3" |
497 | DEBUGF 1,"3" |
498 | 498 | ||
499 | lea edi, [ebx + ETH_FRAME.Data + ARP_Packet.TargetMAC] ; Required MAC-addr |
499 | lea edi, [ebx + ETH_FRAME.Data + ARP_Packet.TargetMAC] ; Required MAC-addr |
500 | xor eax, eax |
500 | xor eax, eax |
501 | stosd |
501 | stosd |
502 | stosw |
502 | stosw |
503 | 503 | ||
504 | DEBUGF 1,"4" |
504 | DEBUGF 1,"4" |
505 | 505 | ||
506 | lea edi, [ebx + ETH_FRAME.DstMAC] |
506 | lea edi, [ebx + ETH_FRAME.DstMAC] |
507 | stosd |
507 | stosd |
508 | stosw |
508 | stosw |
509 | 509 | ||
510 | DEBUGF 1,"5" |
510 | DEBUGF 1,"5" |
511 | 511 | ||
512 | mov esi, [TargetIP] |
512 | mov esi, [TargetIP] |
513 | mov dword [ebx + ETH_FRAME.Data + ARP_Packet.TargetIP], esi ;Required IP-addr(we get it as function parameter) |
513 | mov dword [ebx + ETH_FRAME.Data + ARP_Packet.TargetIP], esi ;Required IP-addr(we get it as function parameter) |
514 | 514 | ||
515 | 515 | ||
516 | DEBUGF 1,"6" |
516 | DEBUGF 1,"6" |
517 | 517 | ||
518 | mov esi, [SenderMAC_ptr] |
518 | mov esi, [SenderMAC_ptr] |
519 | lea edi, [ebx + ETH_FRAME.SrcMAC] |
519 | lea edi, [ebx + ETH_FRAME.SrcMAC] |
520 | movsd |
520 | movsd |
521 | movsw |
521 | movsw |
522 | 522 | ||
523 | DEBUGF 1,"7" |
523 | DEBUGF 1,"7" |
524 | 524 | ||
525 | mov ax , ETHER_ARP |
525 | mov ax , ETHER_ARP |
526 | stosw |
526 | stosw |
527 | 527 | ||
528 | DEBUGF 1,"8" |
528 | DEBUGF 1,"8" |
529 | 529 | ||
530 | ;;; TODO: get device number in edx !! |
530 | ;;; TODO: get device number in edx !! |
531 | xor edx, edx |
531 | xor edx, edx |
532 | shl edx, 2 |
532 | shl edx, 2 |
533 | 533 | ||
534 | inc [ARP_PACKETS_TX+edx] |
534 | inc [ARP_PACKETS_TX+edx] |
535 | 535 | ||
536 | push dword .returnaddr |
536 | push dword .returnaddr |
537 | push dword 60 |
537 | push dword 60 |
538 | push ebx |
538 | push ebx |
539 | mov ebx, [ETH_DRV_LIST + edx] |
539 | mov ebx, [ETH_DRV_LIST + edx] |
540 | jmp [ebx + ETH_DEVICE.transmit] |
540 | jmp [ebx + ETH_DEVICE.transmit] |
541 | .returnaddr: |
541 | .returnaddr: |
542 | 542 | ||
543 | ; Add an entry in the ARP table, awaiting response |
543 | ; Add an entry in the ARP table, awaiting response |
544 | sub esp, ARP_ENTRY.size ;allocate memory for ARP-entry |
544 | sub esp, ARP_ENTRY.size ;allocate memory for ARP-entry |
545 | 545 | ||
546 | mov esi, dword[TargetIP] |
546 | mov esi, dword[TargetIP] |
547 | mov dword[esp + ARP_ENTRY.IP],esi |
547 | mov dword[esp + ARP_ENTRY.IP],esi |
548 | 548 | ||
549 | lea edi, [esp + ARP_ENTRY.MAC] |
549 | lea edi, [esp + ARP_ENTRY.MAC] |
550 | xor eax, eax |
550 | xor eax, eax |
551 | stosd |
551 | stosd |
552 | stosw |
552 | stosw |
553 | 553 | ||
554 | mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
554 | mov word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
555 | mov word[esp + ARP_ENTRY.TTL], 10 ; 10 seconds |
555 | mov word[esp + ARP_ENTRY.TTL], 10 ; 10 seconds |
556 | 556 | ||
557 | stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp |
557 | stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp |
558 | add esp, ARP_ENTRY.size ; free memory |
558 | add esp, ARP_ENTRY.size ; free memory |
559 | 559 | ||
560 | .exit: |
560 | .exit: |
561 | 561 | ||
562 | DEBUGF 1,"ARP request - end\n" |
562 | DEBUGF 1,"ARP request - end\n" |
563 | ret |
563 | ret |
564 | endp |
564 | endp |
565 | 565 | ||
566 | 566 | ||
567 | 567 | ||
568 | 568 | ||
- | 569 | ||
- | 570 | ;--------------------------------------------------------------------------- |
|
- | 571 | ; |
|
- | 572 | ; ARP_decrease_entry_ttls |
|
- | 573 | ; |
|
- | 574 | ; IN: / |
|
- | 575 | ; OUT: / |
|
- | 576 | ; |
|
- | 577 | ;--------------------------------------------------------------------------- |
|
- | 578 | ||
- | 579 | align 4 |
|
- | 580 | ARP_decrease_entry_ttls: |
|
- | 581 | ||
- | 582 | mov ecx, [NumARP] |
|
- | 583 | test ecx, ecx |
|
- | 584 | jz .exit |
|
- | 585 | ||
- | 586 | mov ebx, ARPTable |
|
- | 587 | ||
- | 588 | .timer_loop: |
|
- | 589 | ||
- | 590 | movsx esi, word [ebx + ARP_ENTRY.TTL] |
|
- | 591 | cmp esi, 0xFFFFFFFF |
|
- | 592 | je .timer_loop_end ;if TTL==0xFFFF then it's static entry |
|
- | 593 | ||
- | 594 | test esi, esi |
|
- | 595 | jnz .timer_loop_end_with_dec ;if TTL!=0 |
|
- | 596 | ||
- | 597 | ; Ok, TTL is 0 |
|
- | 598 | ;if Status==AWAITING_RESPONSE and TTL==0 |
|
- | 599 | ;then we have to change it to ARP_RESPONSE_TIMEOUT |
|
- | 600 | cmp word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE |
|
- | 601 | jne @f |
|
- | 602 | ||
- | 603 | mov word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT |
|
- | 604 | mov word [ebx + ARP_ENTRY.TTL], word 0x000A ;10 sec |
|
- | 605 | jmp .timer_loop_end |
|
- | 606 | ||
- | 607 | @@: |
|
- | 608 | ;if TTL==0 and Status==VALID_MAPPING, we have to delete it |
|
- | 609 | ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too |
|
- | 610 | mov esi, dword[NumARP] |
|
- | 611 | sub esi, ecx ;esi=index of entry, will be deleted |
|
- | 612 | ||
- | 613 | call ARP_del_entry |
|
- | 614 | ||
- | 615 | jmp .timer_loop_end |
|
- | 616 | ||
- | 617 | ||
- | 618 | .timer_loop_end_with_dec: |
|
- | 619 | ||
- | 620 | dec word [ebx + ARP_ENTRY.TTL] ;decrease TTL |
|
- | 621 | ||
- | 622 | .timer_loop_end: |
|
- | 623 | ||
- | 624 | add ebx, ARP_ENTRY.size |
|
- | 625 | loop .timer_loop |
|
- | 626 | ||
- | 627 | .exit: |
|
- | 628 | ||
- | 629 | ret |
|
- | 630 | ||
- | 631 | ||
- | 632 | ;--------------------------------------------------------------------------- |
|
- | 633 | ; |
|
- | 634 | ; ARP_del_entry |
|
- | 635 | ; |
|
- | 636 | ; IN: entry # in esi |
|
- | 637 | ; OUT: / |
|
- | 638 | ; |
|
- | 639 | ;--------------------------------------------------------------------------- |
|
- | 640 | ||
- | 641 | align 4 |
|
- | 642 | ARP_del_entry: |
|
- | 643 | ||
- | 644 | imul esi, ARP_ENTRY.size |
|
- | 645 | ||
- | 646 | mov ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY.size |
|
- | 647 | sub ecx, esi |
|
- | 648 | ||
- | 649 | lea edi, [ebx + esi] ;edi=ptr to entry that should be deleted |
|
- | 650 | lea esi, [edi + ARP_ENTRY.size] ;esi=ptr to next entry |
|
- | 651 | ||
- | 652 | shr ecx,1 ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER! |
|
- | 653 | cld |
|
- | 654 | rep movsw |
|
- | 655 | ||
- | 656 | dec dword[NumARP] ;decrease arp-entries counter |
|
- | 657 | ret |
|
- | 658 | ||
- | 659 | ||
- | 660 | ||
- | 661 | ||
569 | 662 | ||
570 | ;----------------------------------------------------- |
663 | ;----------------------------------------------------- |
571 | ; |
664 | ; |
572 | ; ARP_Handler: |
665 | ; ARP_Handler: |
573 | ; |
666 | ; |
574 | ; This function handles ARP protocol over ethernet |
667 | ; This function handles ARP protocol over ethernet |
575 | ; (other protocols may follow in the future) |
668 | ; (other protocols may follow in the future) |
576 | ; |
669 | ; |
577 | ; IN: Pointer to buffer in [esp] |
670 | ; IN: Pointer to buffer in [esp] |
578 | ; size of buffer in [esp+4] |
671 | ; size of buffer in [esp+4] |
579 | ; packet size (without ethernet header) in ecx |
672 | ; packet size (without ethernet header) in ecx |
580 | ; OUT: / |
673 | ; OUT: / |
581 | ; |
674 | ; |
582 | ;----------------------------------------------------- |
675 | ;----------------------------------------------------- |
583 | align 4 |
676 | align 4 |
584 | ARP_Handler: |
677 | ARP_Handler: |
585 | 678 | ||
586 | DEBUGF 1,"ARP_Handler - start\n" |
679 | DEBUGF 1,"ARP_Handler - start\n" |
587 | cmp ecx, 28 |
680 | cmp ecx, 28 |
588 | jl .exit |
681 | jl .exit |
589 | 682 | ||
590 | ; Is this a REQUEST? |
683 | ; Is this a REQUEST? |
591 | ; Is this a request for My Host IP |
684 | ; Is this a request for My Host IP |
592 | ; Yes - So construct a response message. |
685 | ; Yes - So construct a response message. |
593 | ; Send this message to the ethernet card for transmission |
686 | ; Send this message to the ethernet card for transmission |
594 | 687 | ||
595 | ; push ebx edx |
688 | ; push ebx edx |
596 | stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_PACKET_PTR, edx |
689 | stdcall arp_table_manager, ARP_TABLE_ADD, EXTRA_IS_ARP_PACKET_PTR, edx |
597 | ; pop edx ebx |
690 | ; pop edx ebx |
598 | 691 | ||
599 | cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Is this a request packet? |
692 | cmp word [edx + ARP_Packet.Opcode], ARP_REQ_OPCODE ; Is this a request packet? |
600 | jne .exit |
693 | jne .exit |
601 | 694 | ||
602 | call ETH_struc2dev |
695 | call ETH_struc2dev |
603 | DEBUGF 1,"ARP Packet came from device: %u\n", edi |
696 | DEBUGF 1,"ARP Packet came from device: %u\n", edi |
604 | inc [ARP_PACKETS_RX+4*edi] |
697 | inc [ARP_PACKETS_RX+4*edi] |
605 | cmp edi, -1 |
698 | cmp edi, -1 |
606 | jz .exit |
699 | jz .exit |
607 | 700 | ||
608 | mov eax, edi |
701 | mov eax, edi |
609 | shl eax, 2 |
702 | shl eax, 2 |
610 | add eax, IP_LIST |
703 | add eax, IP_LIST |
611 | mov eax, [eax] |
704 | mov eax, [eax] |
612 | cmp eax, [edx + ARP_Packet.TargetIP] ; Is it looking for my IP address? |
705 | cmp eax, [edx + ARP_Packet.TargetIP] ; Is it looking for my IP address? |
613 | jnz .exit |
706 | jnz .exit |
614 | push eax |
707 | push eax |
615 | push edi |
708 | push edi |
616 | 709 | ||
617 | ; DEBUGF 1,"ETH_ARP_Handler - request for %u.%u.%u.%u\n",[edi+0]:1,[edi+1]:1,[edi+2]:1,[edi+3]:1 |
710 | ; DEBUGF 1,"ETH_ARP_Handler - request for %u.%u.%u.%u\n",[edi+0]:1,[edi+1]:1,[edi+2]:1,[edi+3]:1 |
618 | 711 | ||
619 | ; OK, it is a request for one of our MAC addresses. Build the frame and send it |
712 | ; OK, it is a request for one of our MAC addresses. Build the frame and send it |
620 | ; We can reuse the buffer. |
713 | ; We can reuse the buffer. |
621 | 714 | ||
622 | cld |
715 | cld |
623 | lea esi, [edx + ARP_Packet.SenderMAC] |
716 | lea esi, [edx + ARP_Packet.SenderMAC] |
624 | lea edi, [edx + ARP_Packet.TargetMAC] |
717 | lea edi, [edx + ARP_Packet.TargetMAC] |
625 | movsd ; Move Sender Mac to Dest MAC |
718 | movsd ; Move Sender Mac to Dest MAC |
626 | movsw ; |
719 | movsw ; |
627 | movsd ; Move sender IP to Dest IP |
720 | movsd ; Move sender IP to Dest IP |
628 | 721 | ||
629 | pop esi |
722 | pop esi |
630 | mov esi, [ETH_DRV_LIST + 4*esi] |
723 | mov esi, [ETH_DRV_LIST + 4*esi] |
631 | lea esi, [esi + ETH_DEVICE.mac] |
724 | lea esi, [esi + ETH_DEVICE.mac] |
632 | lea edi, [edx + ARP_Packet.SenderMAC] |
725 | lea edi, [edx + ARP_Packet.SenderMAC] |
633 | movsd ; Copy MAC address from in MAC_LIST |
726 | movsd ; Copy MAC address from in MAC_LIST |
634 | movsw ; |
727 | movsw ; |
635 | pop eax |
728 | pop eax |
636 | stosd ; Write our IP |
729 | stosd ; Write our IP |
637 | 730 | ||
638 | mov word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE |
731 | mov word [edx + ARP_Packet.Opcode], ARP_REP_OPCODE |
639 | 732 | ||
640 | ; Now, Fill in ETHERNET header |
733 | ; Now, Fill in ETHERNET header |
641 | 734 | ||
642 | mov edi, [esp] |
735 | mov edi, [esp] |
643 | lea esi, [edx + ARP_Packet.TargetMAC] |
736 | lea esi, [edx + ARP_Packet.TargetMAC] |
644 | movsd |
737 | movsd |
645 | movsw |
738 | movsw |
646 | lea esi, [edx + ARP_Packet.SenderMAC] |
739 | lea esi, [edx + ARP_Packet.SenderMAC] |
647 | movsd |
740 | movsd |
648 | movsw |
741 | movsw |
649 | mov ax , ETHER_ARP |
742 | mov ax , ETHER_ARP |
650 | stosw |
743 | stosw |
651 | 744 | ||
652 | jmp ETH_Sender ; And send it! |
745 | jmp ETH_Sender ; And send it! |
653 | 746 | ||
654 | .exit: |
747 | .exit: |
655 | call kernel_free |
748 | call kernel_free |
656 | add esp, 4 ; pop (balance stack) |
749 | add esp, 4 ; pop (balance stack) |
657 | 750 | ||
658 | DEBUGF 1,"ARP_Handler - fail\n" |
751 | DEBUGF 1,"ARP_Handler - fail\n" |
659 | ret |
752 | ret |
660 | 753 | ||
661 | 754 | ||
662 | 755 | ||
663 | 756 | ||
664 | ;--------------------------------------------------------------------------- |
757 | ;--------------------------------------------------------------------------- |
665 | ; |
758 | ; |
666 | ; ARP_API |
759 | ; ARP_API |
667 | ; |
760 | ; |
668 | ; This function is called by system function 75 |
761 | ; This function is called by system function 75 |
669 | ; |
762 | ; |
670 | ; IN: subfunction number in bl |
763 | ; IN: subfunction number in bl |
671 | ; device number in bh |
764 | ; device number in bh |
672 | ; ecx, edx, .. depends on subfunction |
765 | ; ecx, edx, .. depends on subfunction |
673 | ; |
766 | ; |
674 | ; OUT: |
767 | ; OUT: |
675 | ; |
768 | ; |
676 | ;--------------------------------------------------------------------------- |
769 | ;--------------------------------------------------------------------------- |
677 | 770 | ||
678 | align 4 |
771 | align 4 |
679 | ARP_API: |
772 | ARP_API: |
680 | 773 | ||
681 | movzx eax, bh |
774 | movzx eax, bh |
682 | shl eax, 2 |
775 | shl eax, 2 |
683 | 776 | ||
684 | test bl, bl |
777 | test bl, bl |
685 | jz .packets_tx ; 0 |
778 | jz .packets_tx ; 0 |
686 | dec bl |
779 | dec bl |
687 | jz .packets_rx ; 1 |
780 | jz .packets_rx ; 1 |
688 | dec bl |
781 | dec bl |
689 | jz .entries ; 2 |
782 | jz .entries ; 2 |
690 | dec bl |
783 | dec bl |
691 | jz .read ; 3 |
784 | jz .read ; 3 |
692 | dec bl |
785 | dec bl |
693 | jz .write ; 4 |
786 | jz .write ; 4 |
694 | dec bl |
787 | dec bl |
695 | jz .remove ; 5 |
788 | jz .remove ; 5 |
696 | dec bl |
789 | dec bl |
697 | 790 | ||
698 | 791 | ||
699 | .error: |
792 | .error: |
700 | mov eax, -1 |
793 | mov eax, -1 |
701 | ret |
794 | ret |
702 | 795 | ||
703 | .packets_tx: |
796 | .packets_tx: |
704 | add eax, ARP_PACKETS_TX |
797 | add eax, ARP_PACKETS_TX |
705 | mov eax, [eax] |
798 | mov eax, [eax] |
706 | ret |
799 | ret |
707 | 800 | ||
708 | .packets_rx: |
801 | .packets_rx: |
709 | add eax, ARP_PACKETS_RX |
802 | add eax, ARP_PACKETS_RX |
710 | mov eax, [eax] |
803 | mov eax, [eax] |
711 | ret |
804 | ret |
712 | 805 | ||
713 | .entries: |
806 | .entries: |
714 | mov eax, [NumARP] |
807 | mov eax, [NumARP] |
715 | ret |
808 | ret |
716 | 809 | ||
717 | .read: |
810 | .read: |
718 | ; TODO: write code |
811 | ; TODO: write code |
719 | ret |
812 | ret |
720 | 813 | ||
721 | .write: |
814 | .write: |
722 | ; TODO: write code |
815 | ; TODO: write code |
723 | ret |
816 | ret |
724 | 817 | ||
725 | .remove: |
818 | .remove: |
726 | ; TODO: write code |
819 | ; TODO: write code |
727 | ret |
820 | ret |