Subversion Repositories Kolibri OS

Rev

Rev 1196 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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