Subversion Repositories Kolibri OS

Rev

Rev 5596 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5596 Rev 6078
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
2
;;                                                                 ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved.    ;;
3
;; Copyright (C) KolibriOS team 2004-2015. 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
$Revision: 5522 $
19
$Revision: 5522 $
20
 
20
 
21
ARP_NO_ENTRY            = 0
21
ARP_NO_ENTRY            = 0
22
ARP_VALID_MAPPING       = 1
22
ARP_VALID_MAPPING       = 1
23
ARP_AWAITING_RESPONSE   = 2
23
ARP_AWAITING_RESPONSE   = 2
24
ARP_RESPONSE_TIMEOUT    = 3
24
ARP_RESPONSE_TIMEOUT    = 3
25
 
25
 
26
ARP_REQUEST_TTL         = 31          ; 20 s
26
ARP_REQUEST_TTL         = 31          ; 20 s
27
ARP_ENTRY_TTL           = 937         ; 600 s
27
ARP_ENTRY_TTL           = 937         ; 600 s
28
ARP_STATIC_ENTRY        = -1
28
ARP_STATIC_ENTRY        = -1
29
 
29
 
30
ARP_REQ_OPCODE          = 0x0100      ; request
30
ARP_REQ_OPCODE          = 0x0100      ; request
31
ARP_REP_OPCODE          = 0x0200      ; reply
31
ARP_REP_OPCODE          = 0x0200      ; reply
32
 
32
 
33
ARP_TABLE_SIZE          = 20          ; Size of table
33
ARP_TABLE_SIZE          = 20          ; Size of table
34
 
34
 
35
struct  ARP_entry
35
struct  ARP_entry
36
 
36
 
37
        IP              dd ?
37
        IP              dd ?
38
        MAC             dp ?
38
        MAC             dp ?
39
        Status          dw ?
39
        Status          dw ?
40
        TTL             dw ?
40
        TTL             dw ?
41
 
41
 
42
ends
42
ends
43
 
43
 
44
struct  ARP_header
44
struct  ARP_header
45
 
45
 
46
        HardwareType    dw ?
46
        HardwareType    dw ?
47
        ProtocolType    dw ?
47
        ProtocolType    dw ?
48
        HardwareSize    db ?
48
        HardwareSize    db ?
49
        ProtocolSize    db ?
49
        ProtocolSize    db ?
50
        Opcode          dw ?
50
        Opcode          dw ?
51
        SenderMAC       dp ?
51
        SenderMAC       dp ?
52
        SenderIP        dd ?
52
        SenderIP        dd ?
53
        TargetMAC       dp ?
53
        TargetMAC       dp ?
54
        TargetIP        dd ?
54
        TargetIP        dd ?
55
 
55
 
56
ends
56
ends
57
 
57
 
58
uglobal
58
uglobal
59
align 4
59
align 4
60
 
60
 
61
        ARP_table       rb NET_DEVICES_MAX*(ARP_TABLE_SIZE * sizeof.ARP_entry)
61
        ARP_table       rb NET_DEVICES_MAX*(ARP_TABLE_SIZE * sizeof.ARP_entry)
62
 
62
 
63
        ARP_entries_num rd NET_DEVICES_MAX
63
        ARP_entries_num rd NET_DEVICES_MAX
64
        ARP_PACKETS_TX  rd NET_DEVICES_MAX
64
        ARP_PACKETS_TX  rd NET_DEVICES_MAX
65
        ARP_PACKETS_RX  rd NET_DEVICES_MAX
65
        ARP_PACKETS_RX  rd NET_DEVICES_MAX
66
        ARP_CONFLICTS   rd NET_DEVICES_MAX
66
        ARP_CONFLICTS   rd NET_DEVICES_MAX
67
 
67
 
68
 
68
 
69
endg
69
endg
70
 
70
 
71
 
71
 
72
 
72
 
73
;-----------------------------------------------------------------
-
 
74
;
-
 
75
; ARP_init
-
 
-
 
73
;-----------------------------------------------------------------;
76
;
74
;                                                                 ;
77
;  This function resets all ARP variables
-
 
-
 
75
; arp_init: Resets all ARP variables.                             ;
78
;
76
;                                                                 ;
79
;-----------------------------------------------------------------
77
;-----------------------------------------------------------------;
80
macro ARP_init {
78
macro arp_init {
81
 
79
 
82
        xor     eax, eax
80
        xor     eax, eax
83
        mov     edi, ARP_entries_num
81
        mov     edi, ARP_entries_num
84
        mov     ecx, 4*NET_DEVICES_MAX
82
        mov     ecx, 4*NET_DEVICES_MAX
85
        rep stosd
83
        rep stosd
86
 
84
 
87
}
85
}
88
 
86
 
89
;---------------------------------------------------------------------------
-
 
-
 
87
;-----------------------------------------------------------------;
90
;
88
;                                                                 ;
91
; ARP_decrease_entry_ttls
-
 
-
 
89
; arp_decrease_entry_ttls                                         ;
92
;
90
;                                                                 ;
93
;---------------------------------------------------------------------------
-
 
94
 
91
;-----------------------------------------------------------------;
95
macro ARP_decrease_entry_ttls {
92
macro arp_decrease_entry_ttls {
96
 
93
 
97
local   .loop
94
local   .loop
98
local   .exit
95
local   .exit
99
 
96
 
100
; The TTL field is decremented every second, and is deleted when it reaches 0.
97
; The TTL field is decremented every second, and is deleted when it reaches 0.
101
; It is refreshed every time a packet is received.
98
; 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.
99
; If the TTL field is 0xFFFF it is a static entry and is never deleted.
103
; The status field can be the following values:
100
; The status field can be the following values:
104
; 0x0000  entry not used
101
; 0x0000  entry not used
105
; 0x0001  entry holds a valid mapping
102
; 0x0001  entry holds a valid mapping
106
; 0x0002  entry contains an IP address, awaiting ARP response
103
; 0x0002  entry contains an IP address, awaiting ARP response
107
; 0x0003  No response received to ARP request.
104
; 0x0003  No response received to ARP request.
108
; The last status value is provided to allow the network layer to delete
105
; The last status value is provided to allow the network layer to delete
109
; a packet that is queued awaiting an ARP response
106
; a packet that is queued awaiting an ARP response
110
 
107
 
111
        xor     edi, edi
108
        xor     edi, edi
112
  .loop_outer:
109
  .loop_outer:
113
        mov     ecx, [ARP_entries_num + 4*edi]
110
        mov     ecx, [ARP_entries_num + 4*edi]
114
        test    ecx, ecx
111
        test    ecx, ecx
115
        jz      .exit
112
        jz      .exit
116
 
113
 
117
        mov     esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)
114
        mov     esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)
118
        imul    esi, edi
115
        imul    esi, edi
119
        add     esi, ARP_table
116
        add     esi, ARP_table
120
  .loop:
117
  .loop:
121
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
118
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
122
        je      .next
119
        je      .next
123
 
120
 
124
        dec     [esi + ARP_entry.TTL]
121
        dec     [esi + ARP_entry.TTL]
125
        jz      .time_out
122
        jz      .time_out
126
 
123
 
127
  .next:
124
  .next:
128
        add     esi, sizeof.ARP_entry
125
        add     esi, sizeof.ARP_entry
129
        dec     ecx
126
        dec     ecx
130
        jnz     .loop
127
        jnz     .loop
131
        jmp     .exit
128
        jmp     .exit
132
 
129
 
133
  .time_out:
130
  .time_out:
134
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE
131
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE
135
        je      .response_timeout
132
        je      .response_timeout
136
 
133
 
137
        push    esi edi ecx
134
        push    esi edi ecx
138
        call    ARP_del_entry
135
        call    arp_del_entry
139
        pop     ecx edi esi
136
        pop     ecx edi esi
140
 
137
 
141
        jmp     .next
138
        jmp     .next
142
 
139
 
143
  .response_timeout:
140
  .response_timeout:
144
        mov     [esi + ARP_entry.Status], ARP_RESPONSE_TIMEOUT
141
        mov     [esi + ARP_entry.Status], ARP_RESPONSE_TIMEOUT
145
        mov     [esi + ARP_entry.TTL], 10
142
        mov     [esi + ARP_entry.TTL], 10
146
 
143
 
147
        jmp     .next
144
        jmp     .next
148
 
145
 
149
  .exit:
146
  .exit:
150
        inc     edi
147
        inc     edi
151
        cmp     edi, NET_DEVICES_MAX
148
        cmp     edi, NET_DEVICES_MAX
152
        jb      .loop_outer
149
        jb      .loop_outer
153
 
150
 
154
}
151
}
155
 
152
 
156
 
153
 
157
;-----------------------------------------------------------------
-
 
-
 
154
;-----------------------------------------------------------------;
158
;
155
;                                                                 ;
159
; ARP_input
-
 
-
 
156
; arp_input                                                       ;
160
;
157
;                                                                 ;
161
;  IN:  Pointer to buffer in [esp]
158
;  IN:  [esp] = Pointer to buffer                                 ;
162
;       size of buffer in [esp+4]
159
;       [esp+4] = size of buffer                                  ;
163
;       packet size (without ethernet header) in ecx
160
;       ecx = packet size (without ethernet header)               ;
164
;       packet ptr in edx
161
;       edx = packet ptr                                          ;
-
 
162
;       ebx = device ptr                                          ;
165
;       device ptr in ebx
163
;                                                                 ;
166
;  OUT: /
-
 
-
 
164
;  OUT: /                                                         ;
167
;
165
;                                                                 ;
168
;-----------------------------------------------------------------
166
;-----------------------------------------------------------------;
169
align 4
167
align 4
170
ARP_input:
168
arp_input:
171
 
169
 
172
;-----------------------------------------
170
;-----------------------------------------
173
; Check validity and print some debug info
171
; Check validity and print some debug info
174
 
172
 
175
        cmp     ecx, sizeof.ARP_header
173
        cmp     ecx, sizeof.ARP_header
176
        jb      .exit
174
        jb      .exit
177
 
175
 
178
        call    NET_ptr_to_num4
176
        call    net_ptr_to_num4
179
        cmp     edi, -1
177
        cmp     edi, -1
180
        jz      .exit
178
        jz      .exit
181
 
179
 
182
        inc     [ARP_PACKETS_RX + edi]          ; update stats
180
        inc     [ARP_PACKETS_RX + edi]          ; update stats
183
 
181
 
184
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: got packet from %u.%u.%u.%u (device*4=%u)\n",\
182
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: got packet from %u.%u.%u.%u (device*4=%u)\n",\
185
        [edx + ARP_header.SenderIP]:1, [edx + ARP_header.SenderIP + 1]:1,\
183
        [edx + ARP_header.SenderIP]:1, [edx + ARP_header.SenderIP + 1]:1,\
186
        [edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1, edi
184
        [edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1, edi
187
 
185
 
188
;------------------------------
186
;------------------------------
189
; First, check for IP collision
187
; First, check for IP collision
190
 
188
 
191
        mov     eax, [edx + ARP_header.SenderIP]
189
        mov     eax, [edx + ARP_header.SenderIP]
192
        cmp     eax, [IP_LIST + edi]
190
        cmp     eax, [IP_LIST + edi]
193
        je      .collision
191
        je      .collision
194
 
192
 
195
;---------------------
193
;---------------------
196
; Handle reply packets
194
; Handle reply packets
197
 
195
 
198
        cmp     [edx + ARP_header.Opcode], ARP_REP_OPCODE
196
        cmp     [edx + ARP_header.Opcode], ARP_REP_OPCODE
199
        jne     .maybe_request
197
        jne     .maybe_request
200
 
198
 
201
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n"
199
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n"
202
 
200
 
203
        mov     ecx, [ARP_entries_num + edi]
201
        mov     ecx, [ARP_entries_num + edi]
204
        test    ecx, ecx
202
        test    ecx, ecx
205
        jz      .exit
203
        jz      .exit
206
 
204
 
207
        mov     esi, edi
205
        mov     esi, edi
208
        imul    esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)/4
206
        imul    esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)/4
209
        add     esi, ARP_table
207
        add     esi, ARP_table
210
  .loop:
208
  .loop:
211
        cmp     [esi + ARP_entry.IP], eax
209
        cmp     [esi + ARP_entry.IP], eax
212
        je      .gotit
210
        je      .gotit
213
        add     esi, sizeof.ARP_entry
211
        add     esi, sizeof.ARP_entry
214
        dec     ecx
212
        dec     ecx
215
        jnz     .loop
213
        jnz     .loop
216
 
214
 
217
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: no matching entry found\n"
215
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: no matching entry found\n"
218
        jmp     .exit
216
        jmp     .exit
219
 
217
 
220
  .gotit:
218
  .gotit:
221
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: found matching entry\n"
219
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: found matching entry\n"
222
 
220
 
223
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY         ; if it is a static entry, dont touch it
221
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY         ; if it is a static entry, dont touch it
224
        je      .exit
222
        je      .exit
225
 
223
 
226
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: updating entry\n"
224
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: updating entry\n"
227
 
225
 
228
        mov     [esi + ARP_entry.Status], ARP_VALID_MAPPING
226
        mov     [esi + ARP_entry.Status], ARP_VALID_MAPPING
229
        mov     [esi + ARP_entry.TTL], ARP_ENTRY_TTL
227
        mov     [esi + ARP_entry.TTL], ARP_ENTRY_TTL
230
 
228
 
231
        mov     eax, dword [edx + ARP_header.SenderMAC]
229
        mov     eax, dword [edx + ARP_header.SenderMAC]
232
        mov     dword [esi + ARP_entry.MAC], eax
230
        mov     dword [esi + ARP_entry.MAC], eax
233
        mov     cx, word [edx + ARP_header.SenderMAC + 4]
231
        mov     cx, word [edx + ARP_header.SenderMAC + 4]
234
        mov     word [esi + ARP_entry.MAC + 4], cx
232
        mov     word [esi + ARP_entry.MAC + 4], cx
235
 
233
 
236
        jmp     .exit
234
        jmp     .exit
237
 
235
 
238
;-----------------------
236
;-----------------------
239
; Handle request packets
237
; Handle request packets
240
 
238
 
241
  .maybe_request:
239
  .maybe_request:
242
        cmp     [edx + ARP_header.Opcode], ARP_REQ_OPCODE
240
        cmp     [edx + ARP_header.Opcode], ARP_REQ_OPCODE
243
        jne     .exit
241
        jne     .exit
244
 
242
 
245
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: its a request\n"
243
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: its a request\n"
246
 
244
 
247
        mov     eax, [IP_LIST + edi]
245
        mov     eax, [IP_LIST + edi]
248
        cmp     eax, [edx + ARP_header.TargetIP]                ; Is it looking for my IP address?
246
        cmp     eax, [edx + ARP_header.TargetIP]                ; Is it looking for my IP address?
249
        jne     .exit
247
        jne     .exit
250
 
248
 
251
        push    eax
249
        push    eax
252
        push    edi
250
        push    edi
253
 
251
 
254
; OK, it is a request for one of our MAC addresses.
252
; OK, it is a request for one of our MAC addresses.
255
; Build the frame and send it. We can reuse the buffer.  (faster then using ARP_create_packet)
253
; Build the frame and send it. We can reuse the buffer.  (faster then using ARP_create_packet)
256
 
254
 
257
        lea     esi, [edx + ARP_header.SenderMAC]
255
        lea     esi, [edx + ARP_header.SenderMAC]
258
        lea     edi, [edx + ARP_header.TargetMAC]
256
        lea     edi, [edx + ARP_header.TargetMAC]
259
        movsd                                                   ; Move Sender Mac to Dest MAC
257
        movsd                                                   ; Move Sender Mac to Dest MAC
260
        movsw                                                   ;
258
        movsw                                                   ;
261
        movsd                                                   ; Move sender IP to Dest IP
259
        movsd                                                   ; Move sender IP to Dest IP
262
 
260
 
263
        pop     esi
261
        pop     esi
264
        mov     esi, [NET_DRV_LIST + esi]
262
        mov     esi, [NET_DRV_LIST + esi]
265
        lea     esi, [esi + ETH_DEVICE.mac]
263
        lea     esi, [esi + ETH_DEVICE.mac]
266
        lea     edi, [edx + ARP_header.SenderMAC]
264
        lea     edi, [edx + ARP_header.SenderMAC]
267
        movsd                                                   ; Copy MAC address from in MAC_LIST
265
        movsd                                                   ; Copy MAC address from in MAC_LIST
268
        movsw                                                   ;
266
        movsw                                                   ;
269
        pop     eax
267
        pop     eax
270
        stosd                                                   ; Write our IP
268
        stosd                                                   ; Write our IP
271
 
269
 
272
        mov     [edx + ARP_header.Opcode], ARP_REP_OPCODE
270
        mov     [edx + ARP_header.Opcode], ARP_REP_OPCODE
273
 
271
 
274
; Now, Fill in ETHERNET header
272
; Now, Fill in ETHERNET header
275
 
273
 
276
        mov     edi, [esp]
274
        mov     edi, [esp]
277
        lea     esi, [edx + ARP_header.TargetMAC]
275
        lea     esi, [edx + ARP_header.TargetMAC]
278
        movsd
276
        movsd
279
        movsw
277
        movsw
280
        lea     esi, [edx + ARP_header.SenderMAC]
278
        lea     esi, [edx + ARP_header.SenderMAC]
281
        movsd
279
        movsd
282
        movsw
280
        movsw
283
;        mov     ax , ETHER_ARP                                 ; It's already there, I'm sure of it!
281
;        mov     ax , ETHER_ARP                                 ; It's already there, I'm sure of it!
284
;        stosw
282
;        stosw
285
 
283
 
286
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: Sending reply\n"
284
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: Sending reply\n"
287
 
285
 
288
        call    [ebx + NET_DEVICE.transmit]
286
        call    [ebx + NET_DEVICE.transmit]
289
        ret
287
        ret
290
 
288
 
291
  .collision:
289
  .collision:
292
        inc     [ARP_CONFLICTS + edi]
290
        inc     [ARP_CONFLICTS + edi]
293
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n"
291
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: IP address conflict detected!\n"
294
 
292
 
295
  .exit:
293
  .exit:
296
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: exiting\n"
294
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: exiting\n"
297
        call    NET_BUFF_free
295
        call    net_buff_free
298
        ret
296
        ret
299
 
297
 
300
;---------------------------------------------------------------------------
-
 
-
 
298
;-----------------------------------------------------------------;
301
;
299
;                                                                 ;
302
; ARP_output_request
-
 
-
 
300
; arp_output_request                                              ;
303
;
301
;                                                                 ;
304
; IN:   ebx = device ptr
302
;  IN:  ebx = device ptr                                          ;
305
;       eax = IP
-
 
-
 
303
;       eax = IP                                                  ;
306
; OUT: /
304
;                                                                 ;
307
;       scratched: probably everything
-
 
-
 
305
; OUT:  scratched: probably everything                            ;
308
;
306
;                                                                 ;
309
;---------------------------------------------------------------------------
307
;-----------------------------------------------------------------;
310
align 4
308
align 4
311
ARP_output_request:
309
arp_output_request:
312
 
310
 
313
        push    eax
311
        push    eax
314
 
312
 
315
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u device=0x%x\n",\
313
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_output_request: ip=%u.%u.%u.%u device=0x%x\n",\
316
        [esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx
314
        [esp]:1, [esp + 1]:1, [esp + 2]:1, [esp + 3]:1, ebx
317
 
315
 
318
        mov     ax, ETHER_PROTO_ARP
316
        mov     ax, ETHER_PROTO_ARP
319
        mov     ecx, sizeof.ARP_header
317
        mov     ecx, sizeof.ARP_header
320
        mov     edx, ETH_BROADCAST              ; broadcast mac
318
        mov     edx, ETH_BROADCAST              ; broadcast mac
321
        call    ETH_output
319
        call    eth_output
322
        jz      .exit
320
        jz      .exit
323
 
321
 
324
        mov     [edi + ARP_header.HardwareType], 0x0100         ; Ethernet
322
        mov     [edi + ARP_header.HardwareType], 0x0100         ; Ethernet
325
        mov     [edi + ARP_header.ProtocolType], 0x0008         ; IP
323
        mov     [edi + ARP_header.ProtocolType], 0x0008         ; IP
326
        mov     [edi + ARP_header.HardwareSize], 6              ; MAC-addr length
324
        mov     [edi + ARP_header.HardwareSize], 6              ; MAC-addr length
327
        mov     [edi + ARP_header.ProtocolSize], 4              ; IP-addr length
325
        mov     [edi + ARP_header.ProtocolSize], 4              ; IP-addr length
328
        mov     [edi + ARP_header.Opcode], ARP_REQ_OPCODE       ; Request
326
        mov     [edi + ARP_header.Opcode], ARP_REQ_OPCODE       ; Request
329
 
327
 
330
        add     edi, ARP_header.SenderMAC
328
        add     edi, ARP_header.SenderMAC
331
        lea     esi, [ebx + ETH_DEVICE.mac]     ; SenderMac
329
        lea     esi, [ebx + ETH_DEVICE.mac]     ; SenderMac
332
        movsw                                   ;
330
        movsw                                   ;
333
        movsd                                   ;
331
        movsd                                   ;
334
 
332
 
335
        push    edi
333
        push    edi
336
        call    NET_ptr_to_num4
334
        call    net_ptr_to_num4
337
        inc     [ARP_PACKETS_TX + edi]          ; assume we will succeed
335
        inc     [ARP_PACKETS_TX + edi]          ; assume we will succeed
338
        lea     esi, [IP_LIST + edi]            ; SenderIP
336
        lea     esi, [IP_LIST + edi]            ; SenderIP
339
        pop     edi
337
        pop     edi
340
        movsd
338
        movsd
341
 
339
 
342
        mov     esi, ETH_BROADCAST              ; DestMac
340
        mov     esi, ETH_BROADCAST              ; DestMac
343
        movsw                                   ;
341
        movsw                                   ;
344
        movsd                                   ;
342
        movsd                                   ;
345
        popd    [edi]                           ; DestIP
343
        popd    [edi]                           ; DestIP
346
 
344
 
347
        push    eax
345
        push    eax
348
        call    [ebx + NET_DEVICE.transmit]
346
        call    [ebx + NET_DEVICE.transmit]
349
        ret
347
        ret
350
 
348
 
351
  .exit:
349
  .exit:
352
        add     esp, 4
350
        add     esp, 4
353
        DEBUGF  DEBUG_NETWORK_ERROR, "ARP_output_request: send failed\n"
351
        DEBUGF  DEBUG_NETWORK_ERROR, "ARP_output_request: send failed\n"
354
        ret
352
        ret
355
 
353
 
356
 
354
 
357
;-----------------------------------------------------------------
-
 
-
 
355
;-----------------------------------------------------------------;
358
;
356
;                                                                 ;
359
; ARP_add_entry (or update)
-
 
-
 
357
; arp_add_entry: Add or update an entry in the ARP table.         ;
360
;
358
;                                                                 ;
361
; IN:  esi = ptr to entry (can easily be made on the stack)
359
;  IN:  esi = ptr to entry (can easily be made on the stack)      ;
-
 
360
;       edi = device num*4                                        ;
362
;      edi = device num*4
361
;                                                                 ;
-
 
362
; OUT:  eax = entry number on success                             ;
363
; OUT: eax = entry #, -1 on error
363
;       eax = -1 on error                                         ;
364
;      esi = ptr to newly created entry
-
 
-
 
364
;       esi = ptr to newly created entry                          ;
365
;
365
;                                                                 ;
366
;-----------------------------------------------------------------      ; TODO: use a mutex
366
;-----------------------------------------------------------------;
367
align 4
367
align 4
-
 
368
arp_add_entry:
-
 
369
 
368
ARP_add_entry:
370
; TODO: use a mutex to lock ARP table
369
 
371
 
370
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_add_entry: device=%u\n", edi
372
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_add_entry: device=%u\n", edi
371
 
373
 
372
        mov     ecx, [ARP_entries_num + edi]
374
        mov     ecx, [ARP_entries_num + edi]
373
        cmp     ecx, ARP_TABLE_SIZE                                     ; list full ?
375
        cmp     ecx, ARP_TABLE_SIZE                                     ; list full ?
374
        jae     .full
376
        jae     .full
375
 
377
 
376
; From this point on, we can only fail if IP has a static entry, or if table is corrupt.
378
; From this point on, we can only fail if IP has a static entry, or if table is corrupt.
377
 
379
 
378
        inc     [ARP_entries_num + edi]                                 ; assume we will succeed
380
        inc     [ARP_entries_num + edi]                                 ; assume we will succeed
379
 
381
 
380
        push    edi
382
        push    edi
381
        xor     ecx, ecx
383
        xor     ecx, ecx
382
        imul    edi, ARP_TABLE_SIZE*sizeof.ARP_entry/4
384
        imul    edi, ARP_TABLE_SIZE*sizeof.ARP_entry/4
383
        add     edi, ARP_table
385
        add     edi, ARP_table
384
        mov     eax, [esi + ARP_entry.IP]
386
        mov     eax, [esi + ARP_entry.IP]
385
  .loop:
387
  .loop:
386
        cmp     [edi + ARP_entry.Status], ARP_NO_ENTRY                  ; is this slot empty?
388
        cmp     [edi + ARP_entry.Status], ARP_NO_ENTRY                  ; is this slot empty?
387
        je      .add
389
        je      .add
388
 
390
 
389
        cmp     [edi + ARP_entry.IP], eax                               ; if not, check if it doesnt collide
391
        cmp     [edi + ARP_entry.IP], eax                               ; if not, check if it doesnt collide
390
        jne     .maybe_next
392
        jne     .maybe_next
391
 
393
 
392
        cmp     [edi + ARP_entry.TTL], ARP_STATIC_ENTRY                 ; ok, its the same IP, update it if not static
394
        cmp     [edi + ARP_entry.TTL], ARP_STATIC_ENTRY                 ; ok, its the same IP, update it if not static
393
        jne     .add
395
        jne     .add
394
 
396
 
395
        DEBUGF  DEBUG_NETWORK_ERROR, "ARP_add_entry: failed, IP already has a static entry\n"
397
        DEBUGF  DEBUG_NETWORK_ERROR, "ARP_add_entry: failed, IP already has a static entry\n"
396
        jmp     .error
398
        jmp     .error
397
 
399
 
398
  .maybe_next:                                                          ; try the next slot
400
  .maybe_next:                                                          ; try the next slot
399
        add     edi, sizeof.ARP_entry
401
        add     edi, sizeof.ARP_entry
400
        inc     ecx
402
        inc     ecx
401
        cmp     ecx, ARP_TABLE_SIZE
403
        cmp     ecx, ARP_TABLE_SIZE
402
        jb      .loop
404
        jb      .loop
403
 
405
 
404
  .add:
406
  .add:
405
        push    ecx
407
        push    ecx
406
        mov     ecx, sizeof.ARP_entry/2
408
        mov     ecx, sizeof.ARP_entry/2
407
        rep movsw
409
        rep movsw
408
        pop     ecx
410
        pop     ecx
409
        lea     esi, [edi - sizeof.ARP_entry]
411
        lea     esi, [edi - sizeof.ARP_entry]
410
        pop     edi
412
        pop     edi
411
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_add_entry: entry=%u\n", ecx
413
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_add_entry: entry=%u\n", ecx
412
 
414
 
413
        ret
415
        ret
414
 
416
 
415
  .error:
417
  .error:
416
        pop     edi
418
        pop     edi
417
        dec     [ARP_entries_num + edi]
419
        dec     [ARP_entries_num + edi]
418
        DEBUGF  DEBUG_NETWORK_ERROR, "ARP_add_entry_failed\n"
420
        DEBUGF  DEBUG_NETWORK_ERROR, "ARP_add_entry_failed\n"
419
  .full:
421
  .full:
420
        mov     eax, -1
422
        mov     eax, -1
421
        ret
423
        ret
422
 
424
 
423
 
425
 
424
;-----------------------------------------------------------------
-
 
-
 
426
;-----------------------------------------------------------------;
425
;
427
;                                                                 ;
426
; ARP_del_entry
-
 
-
 
428
; arp_del_entry: Remove an entry from the ARP table.              ;
427
;
429
;                                                                 ;
428
; IN:   esi = ptr to arp entry
430
; IN:   esi = ptr to arp entry                                    ;
-
 
431
;       edi = device number                                       ;
429
;       edi = device number
432
;                                                                 ;
430
; OUT:  /
-
 
-
 
433
; OUT:  /                                                         ;
431
;
434
;                                                                 ;
432
;-----------------------------------------------------------------
435
;-----------------------------------------------------------------;
433
align 4
436
align 4
-
 
437
arp_del_entry:
-
 
438
 
434
ARP_del_entry:
439
; TODO: use a mutex to lock ARP table
435
 
440
 
436
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_del_entry: entry=%x entrys=%u\n", esi, [ARP_entries_num + 4*edi]
441
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_del_entry: entry=0x%x entrys=%u\n", esi, [ARP_entries_num + 4*edi]
437
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_del_entry: IP=%u.%u.%u.%u\n", \
442
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_del_entry: IP=%u.%u.%u.%u\n", \
438
        [esi + ARP_entry.IP]:1, [esi + ARP_entry.IP + 1]:1, [esi + ARP_entry.IP + 2]:1, [esi + ARP_entry.IP + 3]:1
443
        [esi + ARP_entry.IP]:1, [esi + ARP_entry.IP + 1]:1, [esi + ARP_entry.IP + 2]:1, [esi + ARP_entry.IP + 3]:1
439
 
444
 
440
        push    edi
445
        push    edi
441
        imul    edi, (ARP_TABLE_SIZE) * sizeof.ARP_entry
446
        imul    edi, (ARP_TABLE_SIZE) * sizeof.ARP_entry
442
        lea     ecx, [ARP_table + (ARP_TABLE_SIZE - 1) * sizeof.ARP_entry + edi]
447
        lea     ecx, [ARP_table + (ARP_TABLE_SIZE - 1) * sizeof.ARP_entry + edi]
443
        sub     ecx, esi
448
        sub     ecx, esi
444
        shr     ecx, 1
449
        shr     ecx, 1
445
 
450
 
446
; move all trailing entries, sizeof.ARP_entry bytes to left.
451
; move all trailing entries, sizeof.ARP_entry bytes to left.
447
        mov     edi, esi
452
        mov     edi, esi
448
        add     esi, sizeof.ARP_entry
453
        add     esi, sizeof.ARP_entry
449
        rep movsw
454
        rep movsw
450
 
455
 
451
; now add an empty entry to the end (erasing previous one)
456
; now add an empty entry to the end (erasing previous one)
452
        xor     eax, eax
457
        xor     eax, eax
453
        mov     ecx, sizeof.ARP_entry/2
458
        mov     ecx, sizeof.ARP_entry/2
454
        rep stosw
459
        rep stosw
455
 
460
 
456
        pop     edi
461
        pop     edi
457
        dec     [ARP_entries_num + 4*edi]
462
        dec     [ARP_entries_num + 4*edi]
458
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_del_entry: success\n"
463
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_del_entry: success\n"
459
 
464
 
460
        ret
465
        ret
461
 
466
 
462
 
467
 
463
 
468
 
464
 
469
 
465
 
470
 
466
;-----------------------------------------------------------------
-
 
467
;
471
;-----------------------------------------------------------------;
468
; ARP_IP_to_MAC
-
 
469
;
472
;                                                                 ;
470
;  This function translates an IP address to a MAC address
-
 
-
 
473
; arp_ip_to_mac: Translate an IP address to a MAC address.        ;
471
;
474
;                                                                 ;
472
;  IN:  eax = IPv4 address
475
;  IN:  eax = IPv4 address                                        ;
-
 
476
;       edi = device number * 4                                   ;
473
;       edi = device number * 4
477
;                                                                 ;
-
 
478
;  OUT: eax = -1 on error                                         ;
474
;  OUT: eax = -1 on error, -2 means request send
479
;       eax = -2 when request send                                ;
475
;      else, ax = first two bytes of mac (high 16 bits of eax will be 0)
480
;       eax = first two bytes of mac on success                   ;
476
;       ebx = last four bytes of mac
481
;       ebx = last four bytes of mac on success                   ;
477
;       edi = unchanged
-
 
-
 
482
;       edi = unchanged                                           ;
478
;
483
;                                                                 ;
479
;-----------------------------------------------------------------
484
;-----------------------------------------------------------------;
480
align 4
485
align 4
481
ARP_IP_to_MAC:
486
arp_ip_to_mac:
482
 
487
 
483
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah
488
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: %u.%u", al, ah
484
        rol     eax, 16
489
        rol     eax, 16
485
        DEBUGF  DEBUG_NETWORK_VERBOSE, ".%u.%u device*4: %u\n", al, ah, edi
490
        DEBUGF  DEBUG_NETWORK_VERBOSE, ".%u.%u device*4: %u\n", al, ah, edi
486
        rol     eax, 16
491
        rol     eax, 16
487
 
492
 
488
        cmp     eax, 0xffffffff
493
        cmp     eax, 0xffffffff
489
        je      .broadcast
494
        je      .broadcast
490
 
495
 
491
;--------------------------------
496
;--------------------------------
492
; Try to find the IP in ARP_table
497
; Try to find the IP in ARP_table
493
 
498
 
494
        mov     ecx, [ARP_entries_num + edi]
499
        mov     ecx, [ARP_entries_num + edi]
495
        test    ecx, ecx
500
        test    ecx, ecx
496
        jz      .not_in_list
501
        jz      .not_in_list
497
        mov     esi, edi
502
        mov     esi, edi
498
        imul    esi, (sizeof.ARP_entry * ARP_TABLE_SIZE)/4
503
        imul    esi, (sizeof.ARP_entry * ARP_TABLE_SIZE)/4
499
        add     esi, ARP_table + ARP_entry.IP
504
        add     esi, ARP_table + ARP_entry.IP
500
  .scan_loop:
505
  .scan_loop:
501
        cmp     [esi], eax
506
        cmp     [esi], eax
502
        je      .found_it
507
        je      .found_it
503
        add     esi, sizeof.ARP_entry
508
        add     esi, sizeof.ARP_entry
504
        dec     ecx
509
        dec     ecx
505
        jnz     .scan_loop
510
        jnz     .scan_loop
506
 
511
 
507
  .not_in_list:
512
  .not_in_list:
508
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: preparing for ARP request\n"
513
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: preparing for ARP request\n"
509
 
514
 
510
        push    eax edi                 ; save IP for ARP_output_request
515
        push    eax edi                 ; save IP for ARP_output_request
511
; Now craft the ARP entry on the stack
516
; Now craft the ARP entry on the stack
512
        pushw   ARP_REQUEST_TTL         ; TTL
517
        pushw   ARP_REQUEST_TTL         ; TTL
513
        pushw   ARP_AWAITING_RESPONSE   ; status
518
        pushw   ARP_AWAITING_RESPONSE   ; status
514
        pushd   0                       ; mac
519
        pushd   0                       ; mac
515
        pushw   0
520
        pushw   0
516
        pushd   eax                     ; ip
521
        pushd   eax                     ; IP
517
        mov     esi, esp
522
        mov     esi, esp
518
 
523
 
519
; Add it to the list
524
; Add it to the list
520
        call    ARP_add_entry
525
        call    arp_add_entry
521
 
526
 
522
; Delete the temporary entry
527
; Delete the temporary entry
523
        add     esp, sizeof.ARP_entry   ; clear the entry from stack
528
        add     esp, sizeof.ARP_entry   ; clear the entry from stack
524
 
529
 
525
; If we could not add it to the list, give up
530
; If we could not add it to the list, give up
526
        cmp     eax, -1                 ; did ARP_add_entry fail?
531
        cmp     eax, -1                 ; did ARP_add_entry fail?
527
        je      .full
532
        je      .full
528
 
533
 
529
;-----------------------------------------------
534
;-----------------------------------------------
530
; At this point, we got an ARP entry in the list
535
; At this point, we got an ARP entry in the list
531
 
536
 
532
; Now send a request packet on the network
537
; Now send a request packet on the network
533
        pop     edi eax                 ; IP in eax, device number in ebx, for ARP_output_request
538
        pop     edi eax                 ; IP in eax, device number in ebx, for ARP_output_request
534
 
539
 
535
        push    esi edi
540
        push    esi edi
536
        mov     ebx, [NET_DRV_LIST + edi]
541
        mov     ebx, [NET_DRV_LIST + edi]
537
        call    ARP_output_request
542
        call    arp_output_request
538
        pop     edi esi
543
        pop     edi esi
539
  .found_it:
544
  .found_it:
540
        cmp     [esi + ARP_entry.Status], ARP_VALID_MAPPING             ; Does it have a MAC assigned?
545
        cmp     [esi + ARP_entry.Status], ARP_VALID_MAPPING             ; Does it have a MAC assigned?
541
        je      .valid
546
        je      .valid
542
 
547
 
543
if ARP_BLOCK
548
if ARP_BLOCK
544
 
549
 
545
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE         ; Are we waiting for reply from remote end?
550
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE         ; Are we waiting for reply from remote end?
546
        jne     .give_up
551
        jne     .give_up
547
        push    esi
552
        push    esi
548
        mov     esi, 10                 ; wait 10 ms
553
        mov     esi, 10                 ; wait 10 ms
549
        call    delay_ms
554
        call    delay_ms
550
        pop     esi
555
        pop     esi
551
        jmp     .found_it               ; now check again
556
        jmp     .found_it               ; now check again
552
 
557
 
553
else
558
else
554
 
559
 
555
        jmp     .give_up
560
        jmp     .give_up
556
 
561
 
557
end if
562
end if
558
 
563
 
559
  .valid:
564
  .valid:
560
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: found MAC\n"
565
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: found MAC\n"
561
        movzx   eax, word[esi + ARP_entry.MAC]
566
        movzx   eax, word[esi + ARP_entry.MAC]
562
        mov     ebx, dword[esi + ARP_entry.MAC + 2]
567
        mov     ebx, dword[esi + ARP_entry.MAC + 2]
563
        ret
568
        ret
564
 
569
 
565
  .full:
570
  .full:
566
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: table is full!\n"
571
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: table is full!\n"
567
        add     esp, 8
572
        add     esp, 8
568
  .give_up:
573
  .give_up:
569
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: entry has no valid mapping!\n"
574
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_IP_to_MAC: entry has no valid mapping!\n"
570
        mov     eax, -1
575
        mov     eax, -1
571
        ret
576
        ret
572
 
577
 
573
  .broadcast:
578
  .broadcast:
574
        mov     eax, 0x0000ffff
579
        mov     eax, 0x0000ffff
575
        mov     ebx, 0xffffffff
580
        mov     ebx, 0xffffffff
576
        ret
581
        ret
577
 
582
 
578
 
583
 
579
;-----------------------------------------------------------------
-
 
580
;
-
 
581
; ARP_API
-
 
-
 
584
;-----------------------------------------------------------------;
582
;
585
;                                                                 ;
583
; This function is called by system function 76
-
 
-
 
586
; arp_api: Part of system function 76.                            ;
584
;
587
;                                                                 ;
585
; IN:  subfunction number in bl
588
;  IN:  bl = subfunction number                                   ;
586
;      device number in bh
589
;       bh = device number                                        ;
587
;      ecx, edx, .. depends on subfunction
-
 
-
 
590
;       ecx, edx, .. depends on subfunction                       ;
588
;
591
;                                                                 ;
589
; OUT:  ?
-
 
-
 
592
; OUT:  depends on subfunction                                    ;
590
;
593
;                                                                 ;
591
;-----------------------------------------------------------------
594
;-----------------------------------------------------------------;
592
align 4
595
align 4
593
ARP_api:
596
arp_api:
594
 
597
 
595
        movzx   eax, bh
598
        movzx   eax, bh
596
        shl     eax, 2
599
        shl     eax, 2
597
 
600
 
598
        and     ebx, 0xff
601
        and     ebx, 0xff
599
        cmp     ebx, .number
602
        cmp     ebx, .number
600
        ja      .error
603
        ja      .error
601
        jmp     dword [.table + 4*ebx]
604
        jmp     dword [.table + 4*ebx]
602
 
605
 
603
  .table:
606
  .table:
604
        dd      .packets_tx     ; 0
607
        dd      .packets_tx     ; 0
605
        dd      .packets_rx     ; 1
608
        dd      .packets_rx     ; 1
606
        dd      .entries        ; 2
609
        dd      .entries        ; 2
607
        dd      .read           ; 3
610
        dd      .read           ; 3
608
        dd      .write          ; 4
611
        dd      .write          ; 4
609
        dd      .remove         ; 5
612
        dd      .remove         ; 5
610
        dd      .send_announce  ; 6
613
        dd      .send_announce  ; 6
611
        dd      .conflicts      ; 7
614
        dd      .conflicts      ; 7
612
  .number = ($ - .table) / 4 - 1
615
  .number = ($ - .table) / 4 - 1
613
 
616
 
614
  .error:
617
  .error:
615
        mov     eax, -1
618
        mov     eax, -1
616
        ret
619
        ret
617
 
620
 
618
  .packets_tx:
621
  .packets_tx:
619
        mov     eax, [ARP_PACKETS_TX + eax]
622
        mov     eax, [ARP_PACKETS_TX + eax]
620
        ret
623
        ret
621
 
624
 
622
  .packets_rx:
625
  .packets_rx:
623
        mov     eax, [ARP_PACKETS_RX + eax]
626
        mov     eax, [ARP_PACKETS_RX + eax]
624
        ret
627
        ret
625
 
628
 
626
  .conflicts:
629
  .conflicts:
627
        mov     eax, [ARP_CONFLICTS + eax]
630
        mov     eax, [ARP_CONFLICTS + eax]
628
        ret
631
        ret
629
 
632
 
630
  .entries:
633
  .entries:
631
        mov     eax, [ARP_entries_num + eax]
634
        mov     eax, [ARP_entries_num + eax]
632
        ret
635
        ret
633
 
636
 
634
  .read:
637
  .read:
635
        cmp     ecx, [ARP_entries_num + eax]
638
        cmp     ecx, [ARP_entries_num + eax]
636
        jae     .error
639
        jae     .error
637
        shr     eax, 2
640
        shr     eax, 2
638
        imul    eax, sizeof.ARP_entry*ARP_TABLE_SIZE
641
        imul    eax, sizeof.ARP_entry*ARP_TABLE_SIZE
639
        add     eax, ARP_table
642
        add     eax, ARP_table
640
        ; edi = pointer to buffer
643
        ; edi = pointer to buffer
641
        ; ecx = # entry
644
        ; ecx = # entry
642
        imul    ecx, sizeof.ARP_entry
645
        imul    ecx, sizeof.ARP_entry
643
        lea     esi, [eax + ecx]
646
        lea     esi, [eax + ecx]
644
        mov     ecx, sizeof.ARP_entry/2
647
        mov     ecx, sizeof.ARP_entry/2
645
        rep movsw
648
        rep movsw
646
 
649
 
647
        xor     eax, eax
650
        xor     eax, eax
648
        ret
651
        ret
649
 
652
 
650
  .write:
653
  .write:
651
        ; esi = pointer to buffer
654
        ; esi = pointer to buffer
652
        mov     edi, eax
655
        mov     edi, eax
653
        call    ARP_add_entry           ; out: eax = entry number, -1 on error
656
        call    arp_add_entry           ; out: eax = entry number, -1 on error
654
        ret
657
        ret
655
 
658
 
656
  .remove:
659
  .remove:
657
        ; ecx = # entry
660
        ; ecx = # entry
658
        cmp     ecx, [ARP_entries_num + eax]
661
        cmp     ecx, [ARP_entries_num + eax]
659
        jae     .error
662
        jae     .error
660
        imul    ecx, sizeof.ARP_entry
663
        imul    ecx, sizeof.ARP_entry
661
        lea     esi, [ARP_table + ecx]
664
        lea     esi, [ARP_table + ecx]
662
        mov     edi, eax
665
        mov     edi, eax
663
        shr     edi, 2
666
        shr     edi, 2
664
        call    ARP_del_entry
667
        call    arp_del_entry
665
        ret
668
        ret
666
 
669
 
667
  .send_announce:
670
  .send_announce:
668
        mov     ebx, [NET_DRV_LIST + eax]
671
        mov     ebx, [NET_DRV_LIST + eax]
669
        mov     eax, [IP_LIST + eax]
672
        mov     eax, [IP_LIST + eax]
670
        call    ARP_output_request      ; now send a gratuitous ARP
673
        call    arp_output_request      ; now send a gratuitous ARP
671
        ret
674
        ret