Subversion Repositories Kolibri OS

Rev

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