Subversion Repositories Kolibri OS

Rev

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