Subversion Repositories Kolibri OS

Rev

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

Rev 837 Rev 2971
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2007. 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
;;  Last revision: 10.11.2006                                   ;;
-
 
11
;;                                                              ;;
-
 
12
;;  This file contains the following:                           ;;
10
;;  This file contains the following:                           ;;
13
;;   arp_table_manager - Manages an ARPTable                    ;;
11
;;   arp_table_manager - Manages an ARPTable                    ;;
14
;;   arp_request - Sends an ARP request on the ethernet         ;;
12
;;   arp_request - Sends an ARP request on the ethernet         ;;
15
;;   arp_handler - Called when an ARP packet is received        ;;
13
;;   arp_handler - Called when an ARP packet is received        ;;
16
;;                                                              ;;
14
;;                                                              ;;
17
;;  Changes history:                                            ;;
15
;;  Changes history:                                            ;;
18
;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net          ;;
16
;;   22.09.2003 - [Mike Hibbett] : mikeh@oceanfree.net          ;;
19
;;   11.11.2006 - [Johnny_B] and [smb]                          ;;
17
;;   11.11.2006 - [Johnny_B] and [smb]                          ;;
20
;;                                                              ;;
18
;;                                                              ;;
21
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
22
 
20
 
23
$Revision: 739 $
21
$Revision: 2971 $
24
 
22
 
25
 
23
 
26
ARP_NO_ENTRY                equ  0
24
ARP_NO_ENTRY                equ  0
27
ARP_VALID_MAPPING           equ  1
25
ARP_VALID_MAPPING           equ  1
28
ARP_AWAITING_RESPONSE       equ  2
26
ARP_AWAITING_RESPONSE       equ  2
29
ARP_RESPONSE_TIMEOUT        equ  3
27
ARP_RESPONSE_TIMEOUT        equ  3
30
 
28
 
31
struc ARP_ENTRY     ;=14 bytes
29
struc ARP_ENTRY     ;=14 bytes
32
{  .IP       dd  ?  ;+00
30
{  .IP       dd  ?  ;+00
33
   .MAC      dp  ?  ;+04
31
   .MAC      dp  ?  ;+04
34
   .Status   dw  ?  ;+10
32
   .Status   dw  ?  ;+10
35
   .TTL      dw  ?  ;+12 : ( in seconds )
33
   .TTL      dw  ?  ;+12 : ( in seconds )
36
}
34
}
37
 
35
 
38
virtual at 0
36
virtual at 0
39
  ARP_ENTRY ARP_ENTRY
37
  ARP_ENTRY ARP_ENTRY
40
end virtual
38
end virtual
41
 
39
 
42
; The TTL field is decremented every second, and is deleted when it
40
; The TTL field is decremented every second, and is deleted when it
43
; reaches 0. It is refreshed every time a packet is received
41
; reaches 0. It is refreshed every time a packet is received
44
; If the TTL field is 0xFFFF it is a static entry and is never deleted
42
; If the TTL field is 0xFFFF it is a static entry and is never deleted
45
; The status field can be the following values:
43
; The status field can be the following values:
46
; 0x0000  entry not used
44
; 0x0000  entry not used
47
; 0x0001  entry holds a valid mapping
45
; 0x0001  entry holds a valid mapping
48
; 0x0002  entry contains an IP address, awaiting ARP response
46
; 0x0002  entry contains an IP address, awaiting ARP response
49
; 0x0003  No response received to ARP request.
47
; 0x0003  No response received to ARP request.
50
; The last status value is provided to allow the network layer to delete
48
; The last status value is provided to allow the network layer to delete
51
; a packet that is queued awaiting an ARP response
49
; a packet that is queued awaiting an ARP response
52
 
50
 
53
 
51
 
54
; The follow is the ARP Table.
52
; The follow is the ARP Table.
55
; This table must be manually updated and the kernel recompilied if
53
; This table must be manually updated and the kernel recompilied if
56
; changes are made to it.
54
; changes are made to it.
57
; Empty entries are filled with zeros
55
; Empty entries are filled with zeros
58
 
56
 
59
ARP_ENTRY_SIZE              equ     14          ; Number of bytes per entry
57
ARP_ENTRY_SIZE              equ     14          ; Number of bytes per entry
60
ARP_TABLE_SIZE              equ     20          ; Size of table
58
ARP_TABLE_SIZE              equ     20          ; Size of table
61
ARP_TABLE_ENTRIES           equ     0           ; Number of static entries in the table
59
ARP_TABLE_ENTRIES           equ     0           ; Number of static entries in the table
62
 
60
 
63
;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!!
61
;TO ADD A STATIC ENTRY, DONT FORGET, PUT "ARPTable" from "uglobal" to "iglobal"!!!
64
;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!!
62
;AND ALSO - IP and MAC have net byte-order, BUT STATUS AND TTL HAVE A MIRROR BYTE-ORDER!!!
65
uglobal
63
uglobal
66
  ARPTable:
64
  ARPTable:
67
;example, static entry ->  db  11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF
65
;example, static entry ->  db  11,22,33,44, 0x11,0x22,0x33,0x44,0x55,0x66, 0x01,0x00, 0xFF,0xFF
68
  times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE  db 0
66
  times ( ARP_TABLE_SIZE - ARP_TABLE_ENTRIES ) * ARP_ENTRY_SIZE  db 0
69
endg
67
endg
70
 
68
 
71
iglobal
69
iglobal
72
  NumARP:        dd    ARP_TABLE_ENTRIES
70
  NumARP:        dd    ARP_TABLE_ENTRIES
73
  ARPTable_ptr   dd    ARPTable   ;pointer to ARPTable
71
  ARPTable_ptr   dd    ARPTable   ;pointer to ARPTable
74
endg
72
endg
75
 
73
 
76
ARP_REQ_OPCODE              equ     0x0100  ;request
74
ARP_REQ_OPCODE              equ     0x0100  ;request
77
ARP_REP_OPCODE              equ     0x0200  ;reply
75
ARP_REP_OPCODE              equ     0x0200  ;reply
78
 
76
 
79
struc ARP_PACKET
77
struc ARP_PACKET
80
{  .HardwareType dw   ?  ;+00
78
{  .HardwareType dw   ?  ;+00
81
   .ProtocolType dw   ?  ;+02
79
   .ProtocolType dw   ?  ;+02
82
   .HardwareSize db   ?  ;+04
80
   .HardwareSize db   ?  ;+04
83
   .ProtocolSize db   ?  ;+05
81
   .ProtocolSize db   ?  ;+05
84
   .Opcode       dw   ?  ;+06
82
   .Opcode       dw   ?  ;+06
85
   .SenderMAC    dp   ?  ;+08
83
   .SenderMAC    dp   ?  ;+08
86
   .SenderIP     dd   ?  ;+14
84
   .SenderIP     dd   ?  ;+14
87
   .TargetMAC    dp   ?  ;+18
85
   .TargetMAC    dp   ?  ;+18
88
   .TargetIP     dd   ?  ;+24
86
   .TargetIP     dd   ?  ;+24
89
}
87
}
90
 
88
 
91
virtual at 0
89
virtual at 0
92
  ARP_PACKET ARP_PACKET
90
  ARP_PACKET ARP_PACKET
93
end virtual
91
end virtual
94
 
92
 
95
 
93
 
96
 
94
 
97
;***************************************************************************
95
;***************************************************************************
98
;   Function
96
;   Function
99
;      arp_table_manager  [by Johnny_B]
97
;      arp_table_manager  [by Johnny_B]
100
;
98
;
101
;   Description
99
;   Description
102
;     Does a most required operations with ARP-table
100
;     Does a most required operations with ARP-table
103
;  IN:
101
;  IN:
104
;   Operation: see Opcode's constants below
102
;   Operation: see Opcode's constants below
105
;       Index: Index of entry in the ARP-table
103
;       Index: Index of entry in the ARP-table
106
;       Extra: Extra parameter for some Opcodes
104
;       Extra: Extra parameter for some Opcodes
107
;  OUT:
105
;  OUT:
108
;   EAX = Returned value depends on opcodes, more detailed see below
106
;   EAX = Returned value depends on opcodes, more detailed see below
109
;
107
;
110
;***************************************************************************
108
;***************************************************************************
111
;Opcode's constants
109
;Opcode's constants
112
ARP_TABLE_ADD                 equ  1
110
ARP_TABLE_ADD                 equ  1
113
ARP_TABLE_DEL                 equ  2
111
ARP_TABLE_DEL                 equ  2
114
ARP_TABLE_GET                 equ  3
112
ARP_TABLE_GET                 equ  3
115
ARP_TABLE_GET_ENTRIES_NUMBER  equ  4
113
ARP_TABLE_GET_ENTRIES_NUMBER  equ  4
116
ARP_TABLE_IP_TO_MAC           equ  5
114
ARP_TABLE_IP_TO_MAC           equ  5
117
ARP_TABLE_TIMER               equ  6
115
ARP_TABLE_TIMER               equ  6
118
 
116
 
119
;Index's constants
117
;Index's constants
120
EXTRA_IS_ARP_PACKET_PTR  equ  0   ;if Extra contain pointer to ARP_PACKET
118
EXTRA_IS_ARP_PACKET_PTR  equ  0   ;if Extra contain pointer to ARP_PACKET
121
EXTRA_IS_ARP_ENTRY_PTR   equ  -1  ;if Extra contain pointer to ARP_ENTRY
119
EXTRA_IS_ARP_ENTRY_PTR   equ  -1  ;if Extra contain pointer to ARP_ENTRY
122
 
120
 
123
align 4
121
align 4
124
proc arp_table_manager stdcall uses ebx esi edi ecx edx,\
122
proc arp_table_manager stdcall uses ebx esi edi ecx edx,\
125
    Opcode:DWORD,Index:DWORD,Extra:DWORD
123
    Opcode:DWORD,Index:DWORD,Extra:DWORD
126
 
124
 
127
    mov     ebx, dword[ARPTable_ptr]   ;ARPTable base
125
    mov     ebx, dword[ARPTable_ptr]   ;ARPTable base
128
    mov     ecx, dword[NumARP]         ;ARP-entries counter
126
    mov     ecx, dword[NumARP]         ;ARP-entries counter
129
 
127
 
130
    mov     eax, dword[Opcode]
128
    mov     eax, dword[Opcode]
131
    cmp     eax, ARP_TABLE_TIMER
129
    cmp     eax, ARP_TABLE_TIMER
132
    je      .timer
130
    je      .timer
133
    cmp     eax, ARP_TABLE_ADD
131
    cmp     eax, ARP_TABLE_ADD
134
    je      .add
132
    je      .add
135
    cmp     eax, ARP_TABLE_DEL
133
    cmp     eax, ARP_TABLE_DEL
136
    je      .del
134
    je      .del
137
    cmp     eax, ARP_TABLE_GET
135
    cmp     eax, ARP_TABLE_GET
138
    je      .get
136
    je      .get
139
    cmp     eax, ARP_TABLE_IP_TO_MAC
137
    cmp     eax, ARP_TABLE_IP_TO_MAC
140
    je      .ip_to_mac
138
    je      .ip_to_mac
141
    cmp     eax, ARP_TABLE_GET_ENTRIES_NUMBER
139
    cmp     eax, ARP_TABLE_GET_ENTRIES_NUMBER
142
    je      .get_entries_number
140
    je      .get_entries_number
143
    jmp     .exit     ;if unknown opcode
141
    jmp     .exit     ;if unknown opcode
144
 
142
 
145
 
143
 
146
;;BEGIN TIMER
144
;;BEGIN TIMER
147
;;Description: it must be callback every second. It is responsible for removing expired routes.
145
;;Description: it must be callback every second. It is responsible for removing expired routes.
148
;;IN:   Operation: ARP_TABLE_TIMER
146
;;IN:   Operation: ARP_TABLE_TIMER
149
;;      Index: must be zero
147
;;      Index: must be zero
150
;;      Extra: must be zero
148
;;      Extra: must be zero
151
;;OUT:
149
;;OUT:
152
;;  EAX=not defined
150
;;  EAX=not defined
153
;;
151
;;
154
.timer:
152
.timer:
155
    test    ecx, ecx
153
    test    ecx, ecx
156
    jz      .exit    ;if NumARP=0 nothing to do
154
    jz      .exit    ;if NumARP=0 nothing to do
157
    sub     ecx, ARP_TABLE_ENTRIES  ;ecx=dynamic entries number
155
    sub     ecx, ARP_TABLE_ENTRIES  ;ecx=dynamic entries number
158
    jz      .exit    ;if NumARP=number of static entries then exit
156
    jz      .exit    ;if NumARP=number of static entries then exit
159
 
157
 
160
    add     ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE  ;ebx=dynamic entries base
158
    add     ebx, ARP_TABLE_ENTRIES*ARP_ENTRY_SIZE  ;ebx=dynamic entries base
161
 
159
 
162
  .timer_loop:
160
  .timer_loop:
163
    movsx   esi, word [ebx + ARP_ENTRY.TTL]
161
    movsx   esi, word [ebx + ARP_ENTRY.TTL]
164
    cmp     esi, 0xFFFFFFFF
162
    cmp     esi, 0xFFFFFFFF
165
    je      .timer_loop_end  ;if TTL==0xFFFF then it's static entry
163
    je      .timer_loop_end  ;if TTL==0xFFFF then it's static entry
166
 
164
 
167
    test    esi, esi
165
    test    esi, esi
168
    jnz     .timer_loop_end_with_dec  ;if TTL!=0
166
    jnz     .timer_loop_end_with_dec  ;if TTL!=0
169
 
167
 
170
    ; Ok, TTL is 0
168
    ; Ok, TTL is 0
171
    ;if Status==AWAITING_RESPONSE and TTL==0
169
    ;if Status==AWAITING_RESPONSE and TTL==0
172
    ;then we have to change it to ARP_RESPONSE_TIMEOUT
170
    ;then we have to change it to ARP_RESPONSE_TIMEOUT
173
    cmp     word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
171
    cmp     word [ebx + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
174
    jne     @f
172
    jne     @f
175
 
173
 
176
    mov     word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
174
    mov     word [ebx + ARP_ENTRY.Status], ARP_RESPONSE_TIMEOUT
177
    mov     word [ebx + ARP_ENTRY.TTL], word 0x000A   ;10 sec
175
    mov     word [ebx + ARP_ENTRY.TTL], word 0x000A   ;10 sec
178
    jmp     .timer_loop_end
176
    jmp     .timer_loop_end
179
 
177
 
180
  @@:
178
  @@:
181
    ;if TTL==0 and Status==VALID_MAPPING, we have to delete it
179
    ;if TTL==0 and Status==VALID_MAPPING, we have to delete it
182
    ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
180
    ;if TTL==0 and Status==RESPONSE_TIMEOUT, delete too
183
    mov     esi, dword[NumARP]
181
    mov     esi, dword[NumARP]
184
    sub     esi, ecx          ;esi=index of entry, will be deleted
182
    sub     esi, ecx          ;esi=index of entry, will be deleted
185
    stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra
183
    stdcall arp_table_manager,ARP_TABLE_DEL,esi,0 ;opcode,index,extra
186
    jmp     .timer_loop_end
184
    jmp     .timer_loop_end
187
 
185
 
188
 
186
 
189
  .timer_loop_end_with_dec:
187
  .timer_loop_end_with_dec:
190
    dec     word [ebx + ARP_ENTRY.TTL]  ;decrease TTL
188
    dec     word [ebx + ARP_ENTRY.TTL]  ;decrease TTL
191
  .timer_loop_end:
189
  .timer_loop_end:
192
    add     ebx, ARP_ENTRY_SIZE
190
    add     ebx, ARP_ENTRY_SIZE
193
    loop    .timer_loop
191
    loop    .timer_loop
194
 
192
 
195
    jmp     .exit
193
    jmp     .exit
196
;;END TIMER
194
;;END TIMER
197
 
195
 
198
;;BEGIN ADD
196
;;BEGIN ADD
199
;;Description: it adds an entry in the table. If ARP-table already
197
;;Description: it adds an entry in the table. If ARP-table already
200
;;             contains same IP, it will be updated.
198
;;             contains same IP, it will be updated.
201
;;IN:   Operation: ARP_TABLE_ADD
199
;;IN:   Operation: ARP_TABLE_ADD
202
;;      Index: specifies what contains Extra-parameter
200
;;      Index: specifies what contains Extra-parameter
203
;;      Extra: if Index==EXTRA_IS_ARP_PACKET_PTR,
201
;;      Extra: if Index==EXTRA_IS_ARP_PACKET_PTR,
204
;;             then Extra contains pointer to ARP_PACKET,
202
;;             then Extra contains pointer to ARP_PACKET,
205
;;             otherwise Extra contains pointer to ARP_ENTRY
203
;;             otherwise Extra contains pointer to ARP_ENTRY
206
;;OUT:
204
;;OUT:
207
;;  EAX=index of entry, that has been added
205
;;  EAX=index of entry, that has been added
208
;;
206
;;
209
.add:
207
.add:
210
 
208
 
211
    sub     esp, ARP_ENTRY_SIZE   ;Allocate ARP_ENTRY_SIZE byte in stack
209
    sub     esp, ARP_ENTRY_SIZE   ;Allocate ARP_ENTRY_SIZE byte in stack
212
 
210
 
213
    mov     esi, [Extra]   ;pointer
211
    mov     esi, [Extra]   ;pointer
214
    mov     edi, [Index]   ;opcode
212
    mov     edi, [Index]   ;opcode
215
 
213
 
216
    cmp     edi, EXTRA_IS_ARP_PACKET_PTR
214
    cmp     edi, EXTRA_IS_ARP_PACKET_PTR
217
    je      .arp_packet_to_entry ;if Extra contain ptr to ARP_PACKET and we have to form arp-entry
215
    je      .arp_packet_to_entry ;if Extra contain ptr to ARP_PACKET and we have to form arp-entry
218
                                 ;else it contain ptr to arp-entry
216
                                 ;else it contain ptr to arp-entry
219
 
217
 
220
    cld
218
    cld
221
          ; esi already has been loaded
219
          ; esi already has been loaded
222
    mov     edi, esp      ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
220
    mov     edi, esp      ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
223
    mov     ecx,ARP_ENTRY_SIZE/2  ;ARP_ENTRY_SIZE must be even number!!!
221
    mov     ecx,ARP_ENTRY_SIZE/2  ;ARP_ENTRY_SIZE must be even number!!!
224
    rep     movsw    ;copy
222
    rep     movsw    ;copy
225
    jmp     .search
223
    jmp     .search
226
 
224
 
227
  .arp_packet_to_entry:
225
  .arp_packet_to_entry:
228
    mov     edx, dword[esi + ARP_PACKET.SenderIP] ;esi=base of ARP_PACKET
226
    mov     edx, dword[esi + ARP_PACKET.SenderIP] ;esi=base of ARP_PACKET
229
    mov     [esp + ARP_ENTRY.IP], edx
227
    mov     [esp + ARP_ENTRY.IP], edx
230
 
228
 
231
    cld
229
    cld
232
    lea     esi, [esi + ARP_PACKET.SenderMAC]
230
    lea     esi, [esi + ARP_PACKET.SenderMAC]
233
    lea     edi, [esp + ARP_ENTRY.MAC]
231
    lea     edi, [esp + ARP_ENTRY.MAC]
234
    movsd
232
    movsd
235
    movsw
233
    movsw
236
    mov     word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING  ; specify the type - a valid entry
234
    mov     word[esp + ARP_ENTRY.Status], ARP_VALID_MAPPING  ; specify the type - a valid entry
237
    mov     word[esp + ARP_ENTRY.TTL], 0x0E10    ; = 1 hour
235
    mov     word[esp + ARP_ENTRY.TTL], 0x0E10    ; = 1 hour
238
 
236
 
239
  .search:
237
  .search:
240
    mov     edx, dword[esp + ARP_ENTRY.IP]  ;edx=IP-address, which we'll search
238
    mov     edx, dword[esp + ARP_ENTRY.IP]  ;edx=IP-address, which we'll search
241
    mov     ecx, dword[NumARP]              ;ecx=ARP-entries counter
239
    mov     ecx, dword[NumARP]              ;ecx=ARP-entries counter
242
    jecxz   .add_to_end                     ;if ARP-entries number == 0
240
    jecxz   .add_to_end                     ;if ARP-entries number == 0
243
    imul    eax, ecx, ARP_ENTRY_SIZE        ;eax=current table size(in bytes)
241
    imul    eax, ecx, ARP_ENTRY_SIZE        ;eax=current table size(in bytes)
244
  @@:
242
  @@:
245
    sub     eax, ARP_ENTRY_SIZE
243
    sub     eax, ARP_ENTRY_SIZE
246
    cmp     dword[ebx + eax + ARP_ENTRY.IP], edx
244
    cmp     dword[ebx + eax + ARP_ENTRY.IP], edx
247
    loopnz  @b
245
    loopnz  @b
248
    jz      .replace       ; found, replace existing entry, ptr to it is in eax
246
    jz      .replace       ; found, replace existing entry, ptr to it is in eax
249
 
247
 
250
  .add_to_end:
248
  .add_to_end:
251
    ;else add to end
249
    ;else add to end
252
    or      eax,-1    ;set eax=0xFFFFFFFF if adding is impossible
250
    or      eax,-1    ;set eax=0xFFFFFFFF if adding is impossible
253
    mov     ecx, dword[NumARP]
251
    mov     ecx, dword[NumARP]
254
    cmp     ecx, ARP_TABLE_SIZE
252
    cmp     ecx, ARP_TABLE_SIZE
255
    je      .add_exit   ;if arp-entries number is equal to arp-table maxsize
253
    je      .add_exit   ;if arp-entries number is equal to arp-table maxsize
256
 
254
 
257
    imul    eax, dword[NumARP], ARP_ENTRY_SIZE ;eax=ptr to end of ARPTable
255
    imul    eax, dword[NumARP], ARP_ENTRY_SIZE ;eax=ptr to end of ARPTable
258
    inc     dword [NumARP]    ;increase ARP-entries counter
256
    inc     dword [NumARP]    ;increase ARP-entries counter
259
 
257
 
260
  .replace:
258
  .replace:
261
    cld
259
    cld
262
    mov     esi, esp              ;esp=base of ARP-entry, that will be added
260
    mov     esi, esp              ;esp=base of ARP-entry, that will be added
263
    lea     edi, [ebx + eax]      ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
261
    lea     edi, [ebx + eax]      ;ebx + eax=ARPTable_base + ARP-entry_base(where we will add)
264
    mov     ecx,ARP_ENTRY_SIZE/2  ;ARP_ENTRY_SIZE must be even number!!!
262
    mov     ecx,ARP_ENTRY_SIZE/2  ;ARP_ENTRY_SIZE must be even number!!!
265
    rep     movsw
263
    rep     movsw
266
 
264
 
267
    mov     ecx, ARP_ENTRY_SIZE
265
    mov     ecx, ARP_ENTRY_SIZE
268
    xor     edx, edx  ;"div" takes operand from EDX:EAX
266
    xor     edx, edx  ;"div" takes operand from EDX:EAX
269
    div     ecx       ;eax=index of entry, which has been added
267
    div     ecx       ;eax=index of entry, which has been added
270
 
268
 
271
.add_exit:
269
.add_exit:
272
    add     esp, ARP_ENTRY_SIZE   ;free stack
270
    add     esp, ARP_ENTRY_SIZE   ;free stack
273
    jmp     .exit
271
    jmp     .exit
274
;;END ADD
272
;;END ADD
275
 
273
 
276
;;BEGIN DEL
274
;;BEGIN DEL
277
;;Description: it deletes an entry in the table.
275
;;Description: it deletes an entry in the table.
278
;;IN:   Operation: ARP_TABLE_DEL
276
;;IN:   Operation: ARP_TABLE_DEL
279
;;      Index: index of entry, that should be deleted
277
;;      Index: index of entry, that should be deleted
280
;;      Extra: must be zero
278
;;      Extra: must be zero
281
;;OUT:
279
;;OUT:
282
;;  EAX=not defined
280
;;  EAX=not defined
283
;;
281
;;
284
.del:
282
.del:
285
    mov     esi, [Index]
283
    mov     esi, [Index]
286
    imul    esi, ARP_ENTRY_SIZE
284
    imul    esi, ARP_ENTRY_SIZE
287
 
285
 
288
    mov     ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
286
    mov     ecx, (ARP_TABLE_SIZE - 1) * ARP_ENTRY_SIZE
289
    sub     ecx, esi
287
    sub     ecx, esi
290
 
288
 
291
    lea     edi, [ebx + esi]            ;edi=ptr to entry that should be deleted
289
    lea     edi, [ebx + esi]            ;edi=ptr to entry that should be deleted
292
    lea     esi, [edi + ARP_ENTRY_SIZE] ;esi=ptr to next entry
290
    lea     esi, [edi + ARP_ENTRY_SIZE] ;esi=ptr to next entry
293
 
291
 
294
    shr     ecx,1      ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
292
    shr     ecx,1      ;ecx/2 => ARP_ENTRY_SIZE MUST BE EVEN NUMBER!
295
    cld
293
    cld
296
    rep     movsw
294
    rep     movsw
297
 
295
 
298
    dec     dword[NumARP] ;decrease arp-entries counter
296
    dec     dword[NumARP] ;decrease arp-entries counter
299
    jmp     .exit
297
    jmp     .exit
300
;;END DEL
298
;;END DEL
301
 
299
 
302
;;BEGIN GET
300
;;BEGIN GET
303
;;Description: it reads an entry of table into buffer.
301
;;Description: it reads an entry of table into buffer.
304
;;IN:   Operation: ARP_TABLE_GET
302
;;IN:   Operation: ARP_TABLE_GET
305
;;      Index: index of entry, that should be read
303
;;      Index: index of entry, that should be read
306
;;      Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE)
304
;;      Extra: pointer to buffer for reading(size must be equal to ARP_ENTRY_SIZE)
307
;;OUT:
305
;;OUT:
308
;;  EAX=not defined
306
;;  EAX=not defined
309
;;
307
;;
310
.get:
308
.get:
311
    mov     esi, [Index]
309
    mov     esi, [Index]
312
    imul    esi, ARP_ENTRY_SIZE   ;esi=ptr to required ARP_ENTRY
310
    imul    esi, ARP_ENTRY_SIZE   ;esi=ptr to required ARP_ENTRY
313
    mov     edi, [Extra]          ;edi=buffer for reading
311
    mov     edi, [Extra]          ;edi=buffer for reading
314
    mov     ecx, ARP_ENTRY_SIZE/2 ; must be even number!!!
312
    mov     ecx, ARP_ENTRY_SIZE/2 ; must be even number!!!
315
    cld
313
    cld
316
    rep     movsw
314
    rep     movsw
317
    jmp     .exit
315
    jmp     .exit
318
;;END GET
316
;;END GET
319
 
317
 
320
;;BEGIN IP_TO_MAC
318
;;BEGIN IP_TO_MAC
321
;;Description: it gets an IP from Index, scans each entry in the table and writes
319
;;Description: it gets an IP from Index, scans each entry in the table and writes
322
;;             MAC, that relates to specified IP, into buffer specified in Extra.
320
;;             MAC, that relates to specified IP, into buffer specified in Extra.
323
;;             And if it cannot find an IP-address in the table, it does an ARP-request of that.
321
;;             And if it cannot find an IP-address in the table, it does an ARP-request of that.
324
;;IN:   Operation: ARP_TABLE_IP_TO_MAC
322
;;IN:   Operation: ARP_TABLE_IP_TO_MAC
325
;;      Index: IP that should be transformed into MAC
323
;;      Index: IP that should be transformed into MAC
326
;;      Extra: pointer to buffer where will be written the MAC-address.
324
;;      Extra: pointer to buffer where will be written the MAC-address.
327
;;OUT:
325
;;OUT:
328
;;  EAX=ARP table entry status code.
326
;;  EAX=ARP table entry status code.
329
;;      If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
327
;;      If EAX==ARP_NO_ENTRY, IP isn't found in the table and we have sent the request.
330
;;      If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
328
;;      If EAX==ARP_AWAITING_RESPONSE, we wait the response from remote system.
331
;;      If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
329
;;      If EAX==ARP_RESPONSE_TIMEOUT, remote system not responds too long.
332
;;      If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
330
;;      If EAX==ARP_VALID_MAPPING, all is ok, we've got a true MAC.
333
;;
331
;;
334
;;  If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
332
;;  If MAC will equal to a zero, in the buffer. It means, that IP-address was not yet
335
;;  resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
333
;;  resolved, or that doesn't exist. I recommend you, to do at most 3-5 calls of this
336
;;  function with 1sec delay. sure, only if it not return a valid MAC after a first call.
334
;;  function with 1sec delay. sure, only if it not return a valid MAC after a first call.
337
;;  
335
;;  
338
.ip_to_mac:
336
.ip_to_mac:
339
 
337
 
340
    xor     eax, eax
338
    xor     eax, eax
341
    mov     edi, dword[Extra]
339
    mov     edi, dword[Extra]
342
    cld
340
    cld
343
    stosd
341
    stosd
344
    stosw
342
    stosw
345
 
343
 
346
 
344
 
347
    ; first, check destination IP to see if it is on 'this' network.
345
    ; first, check destination IP to see if it is on 'this' network.
348
    ; The test is:
346
    ; The test is:
349
    ; if ( destIP & subnet_mask == stack_ip & subnet_mask )
347
    ; if ( destIP & subnet_mask == stack_ip & subnet_mask )
350
    ;   destination is local
348
    ;   destination is local
351
    ; else
349
    ; else
352
    ;  destination is remote, so pass to gateway
350
    ;  destination is remote, so pass to gateway
353
 
351
 
354
    mov     eax, [Index]       ;eax=required IP
352
    mov     eax, [Index]       ;eax=required IP
355
    mov     esi, eax
353
    mov     esi, eax
356
    and     esi, [subnet_mask]
354
    and     esi, [subnet_mask]
357
    mov     ecx, [stack_ip]
355
    mov     ecx, [stack_ip]
358
    and     ecx, [subnet_mask]
356
    and     ecx, [subnet_mask]
359
    cmp     esi, ecx
357
    cmp     esi, ecx
360
    je      @f        ;if we and target IP are located in the same network
358
    je      @f        ;if we and target IP are located in the same network
361
    mov     eax, [gateway_ip]
359
    mov     eax, [gateway_ip]
362
    mov     [Index], eax
360
    mov     [Index], eax
363
  @@:
361
  @@:
364
 
362
 
365
    cmp     dword[NumARP], 0
363
    cmp     dword[NumARP], 0
366
    je      .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
364
    je      .ip_to_mac_send_request ;if ARP-table not contain an entries, we have to request IP.
367
                                    ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
365
                                    ;EAX will be containing a zero, it's equal to ARP_NO_ENTRY
368
 
366
 
369
    mov     ecx, dword[NumARP]
367
    mov     ecx, dword[NumARP]
370
    imul    esi, ecx, ARP_ENTRY_SIZE  ;esi=current ARP-table size
368
    imul    esi, ecx, ARP_ENTRY_SIZE  ;esi=current ARP-table size
371
 
369
 
372
  @@:
370
  @@:
373
    sub     esi, ARP_ENTRY_SIZE
371
    sub     esi, ARP_ENTRY_SIZE
374
    cmp     [ebx + esi], eax         ; ebx=ARPTable base
372
    cmp     [ebx + esi], eax         ; ebx=ARPTable base
375
    loopnz  @b                       ; Return back if non match
373
    loopnz  @b                       ; Return back if non match
376
    jnz     .ip_to_mac_send_request  ; and request IP->MAC if none found in the table
374
    jnz     .ip_to_mac_send_request  ; and request IP->MAC if none found in the table
377
 
375
 
378
    ; Return the entry status in eax
376
    ; Return the entry status in eax
379
    movzx   eax, word[ebx + esi + ARP_ENTRY.Status]
377
    movzx   eax, word[ebx + esi + ARP_ENTRY.Status]
380
 
378
 
381
    ; esi holds index
379
    ; esi holds index
382
    cld
380
    cld
383
    lea     esi, [ebx + esi + ARP_ENTRY.MAC]
381
    lea     esi, [ebx + esi + ARP_ENTRY.MAC]
384
    mov     edi, [Extra]   ;edi=ptr to buffer for write MAC
382
    mov     edi, [Extra]   ;edi=ptr to buffer for write MAC
385
    movsd
383
    movsd
386
    movsw
384
    movsw
387
    jmp     .exit
385
    jmp     .exit
388
 
386
 
389
  .ip_to_mac_send_request:
387
  .ip_to_mac_send_request:
390
    stdcall arp_request,[Index],stack_ip,node_addr  ;TargetIP,SenderIP_ptr,SenderMAC_ptr
388
    stdcall arp_request,[Index],stack_ip,node_addr  ;TargetIP,SenderIP_ptr,SenderMAC_ptr
391
    mov     eax, ARP_NO_ENTRY
389
    mov     eax, ARP_NO_ENTRY
392
    jmp     .exit
390
    jmp     .exit
393
 
391
 
394
;;END IP_TO_MAC
392
;;END IP_TO_MAC
395
 
393
 
396
;;BEGIN GET_ENTRIES_NUMBER
394
;;BEGIN GET_ENTRIES_NUMBER
397
;;Description: returns an ARP-entries number in the ARPTable
395
;;Description: returns an ARP-entries number in the ARPTable
398
;;IN:   Operation: ARP_TABLE_GET_ENTRIES_NUMBER
396
;;IN:   Operation: ARP_TABLE_GET_ENTRIES_NUMBER
399
;;      Index: must be zero
397
;;      Index: must be zero
400
;;      Extra: must be zero
398
;;      Extra: must be zero
401
;;OUT:
399
;;OUT:
402
;;  EAX=ARP-entries number in the ARPTable
400
;;  EAX=ARP-entries number in the ARPTable
403
  .get_entries_number:
401
  .get_entries_number:
404
    mov     eax, dword[NumARP]
402
    mov     eax, dword[NumARP]
405
    jmp     .exit
403
    jmp     .exit
406
;;END GET_ENTRIES_NUMBER
404
;;END GET_ENTRIES_NUMBER
407
 
405
 
408
.exit:
406
.exit:
409
    ret
407
    ret
410
endp
408
endp
411
 
409
 
412
 
410
 
413
;***************************************************************************
411
;***************************************************************************
414
;   Function
412
;   Function
415
;      arp_handler
413
;      arp_handler
416
;
414
;
417
;   Description
415
;   Description
418
;      Called when an ARP packet is received on the ethernet
416
;      Called when an ARP packet is received on the ethernet
419
;      Header + Data is in Ether_buffer[]
417
;      Header + Data is in Ether_buffer[]
420
;       It looks to see if the packet is a request to resolve this Hosts
418
;       It looks to see if the packet is a request to resolve this Hosts
421
;       IP address. If it is, send the ARP reply packet.
419
;       IP address. If it is, send the ARP reply packet.
422
;      This Hosts IP address is in dword [stack_ip]  ( in network format )
420
;      This Hosts IP address is in dword [stack_ip]  ( in network format )
423
;       This Hosts MAC address is in node_addr[6]
421
;       This Hosts MAC address is in node_addr[6]
424
;      All registers may be destroyed
422
;      All registers may be destroyed
425
;
423
;
426
;***************************************************************************
424
;***************************************************************************
427
arp_handler:
425
arp_handler:
428
    ; Is this a REQUEST?
426
    ; Is this a REQUEST?
429
    ; Is this a request for My Host IP
427
    ; Is this a request for My Host IP
430
    ; Yes - So construct a response message.
428
    ; Yes - So construct a response message.
431
    ; Send this message to the ethernet card for transmission
429
    ; Send this message to the ethernet card for transmission
432
 
430
 
433
    stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET
431
    stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_PACKET_PTR,ETH_FRAME.Data + ARP_PACKET
434
 
432
 
435
    inc     dword[arp_rx_count] ;increase ARP-packets counter
433
    inc     dword[arp_rx_count] ;increase ARP-packets counter
436
 
434
 
437
    cmp     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE  ; Is this a request packet?
435
    cmp     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REQ_OPCODE  ; Is this a request packet?
438
    jne     .exit            ; No - so exit
436
    jne     .exit            ; No - so exit
439
 
437
 
440
    mov     eax, [stack_ip] 
438
    mov     eax, [stack_ip] 
441
    cmp     eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP]         ; Is it looking for my IP address?
439
    cmp     eax, dword[ETH_FRAME.Data + ARP_PACKET.TargetIP]         ; Is it looking for my IP address?
442
    jne     .exit            ; No - so quit now
440
    jne     .exit            ; No - so quit now
443
 
441
 
444
    ; OK, it is a request for my MAC address. Build the frame and send it
442
    ; OK, it is a request for my MAC address. Build the frame and send it
445
    ; We can reuse the packet.
443
    ; We can reuse the packet.
446
 
444
 
447
    mov     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE
445
    mov     word[ETH_FRAME.Data + ARP_PACKET.Opcode], ARP_REP_OPCODE
448
 
446
 
449
    cld
447
    cld
450
    mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
448
    mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
451
    mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC
449
    mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC
452
    movsd
450
    movsd
453
    movsw
451
    movsw
454
 
452
 
455
    mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderIP
453
    mov     esi, ETH_FRAME.Data + ARP_PACKET.SenderIP
456
    mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetIP
454
    mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetIP
457
    movsd
455
    movsd
458
 
456
 
459
    mov     esi, node_addr
457
    mov     esi, node_addr
460
    mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
458
    mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderMAC
461
    movsd
459
    movsd
462
    movsw
460
    movsw
463
 
461
 
464
    mov     esi, stack_ip
462
    mov     esi, stack_ip
465
    mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderIP
463
    mov     edi, ETH_FRAME.Data + ARP_PACKET.SenderIP
466
    movsd
464
    movsd
467
 
465
 
468
    ; Now, send it!
466
    ; Now, send it!
469
    mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC   ;ptr to destination MAC address
467
    mov     edi, ETH_FRAME.Data + ARP_PACKET.TargetMAC   ;ptr to destination MAC address
470
    mov     bx, ETHER_ARP               ;type of protocol
468
    mov     bx, ETHER_ARP               ;type of protocol
471
    mov     ecx, 28                     ;data size
469
    mov     ecx, 28                     ;data size
472
    mov     esi, ETH_FRAME.Data + ARP_PACKET             ;ptr to data
470
    mov     esi, ETH_FRAME.Data + ARP_PACKET             ;ptr to data
473
    push    ebp
471
    push    ebp
474
    call    dword [drvr_transmit]       ;transmit packet
472
    call    dword [drvr_transmit]       ;transmit packet
475
    pop     ebp
473
    pop     ebp
476
 
474
 
477
  .exit:
475
  .exit:
478
    ret
476
    ret
479
 
477
 
480
 
478
 
481
;***************************************************************************
479
;***************************************************************************
482
;   Function
480
;   Function
483
;      arp_request  [by Johnny_B]
481
;      arp_request  [by Johnny_B]
484
;
482
;
485
;   Description
483
;   Description
486
;      Sends an ARP request on the ethernet
484
;      Sends an ARP request on the ethernet
487
;   IN:
485
;   IN:
488
;     TargetIP      : requested IP address
486
;     TargetIP      : requested IP address
489
;     SenderIP_ptr  : POINTER to sender's IP address(our system's address)
487
;     SenderIP_ptr  : POINTER to sender's IP address(our system's address)
490
;     SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
488
;     SenderMAC_ptr : POINTER to sender's MAC address(our system's address)
491
;   OUT:
489
;   OUT:
492
;     EAX=0 (if all is ok), otherwise EAX is not defined
490
;     EAX=0 (if all is ok), otherwise EAX is not defined
493
;
491
;
494
;      EBX,ESI,EDI will be saved
492
;      EBX,ESI,EDI will be saved
495
;
493
;
496
;***************************************************************************
494
;***************************************************************************
497
proc arp_request stdcall uses ebx esi edi,\
495
proc arp_request stdcall uses ebx esi edi,\
498
    TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
496
    TargetIP:DWORD, SenderIP_ptr:DWORD, SenderMAC_ptr:DWORD
499
 
497
 
500
    inc     dword[arp_tx_count]  ; increase counter
498
    inc     dword[arp_tx_count]  ; increase counter
501
 
499
 
502
    sub     esp, 28  ; allocate memory for ARP_PACKET
500
    sub     esp, 28  ; allocate memory for ARP_PACKET
503
 
501
 
504
    mov     word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet
502
    mov     word[esp + ARP_PACKET.HardwareType],0x0100 ;Ethernet
505
    mov     word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP
503
    mov     word[esp + ARP_PACKET.ProtocolType],0x0008 ;IP
506
    mov     byte[esp + ARP_PACKET.HardwareSize],0x06   ;MAC-addr length
504
    mov     byte[esp + ARP_PACKET.HardwareSize],0x06   ;MAC-addr length
507
    mov     byte[esp + ARP_PACKET.ProtocolSize],0x04   ;IP-addr length
505
    mov     byte[esp + ARP_PACKET.ProtocolSize],0x04   ;IP-addr length
508
    mov     word[esp + ARP_PACKET.Opcode],0x0100       ;Request
506
    mov     word[esp + ARP_PACKET.Opcode],0x0100       ;Request
509
 
507
 
510
    cld
508
    cld
511
    mov     esi,[SenderMAC_ptr]
509
    mov     esi,[SenderMAC_ptr]
512
    lea     edi,[esp + ARP_PACKET.SenderMAC]       ;Our MAC-addr
510
    lea     edi,[esp + ARP_PACKET.SenderMAC]       ;Our MAC-addr
513
    movsd
511
    movsd
514
    movsw
512
    movsw
515
 
513
 
516
    mov     esi,[SenderIP_ptr]
514
    mov     esi,[SenderIP_ptr]
517
    lea     edi,[esp + ARP_PACKET.SenderIP]        ;Our IP-addr
515
    lea     edi,[esp + ARP_PACKET.SenderIP]        ;Our IP-addr
518
    movsd
516
    movsd
519
 
517
 
520
    xor     eax, eax
518
    xor     eax, eax
521
    lea     edi, [esp + ARP_PACKET.TargetMAC]      ;Required MAC-addr(zeroed)
519
    lea     edi, [esp + ARP_PACKET.TargetMAC]      ;Required MAC-addr(zeroed)
522
    stosd
520
    stosd
523
    stosw
521
    stosw
524
 
522
 
525
    mov     esi, dword[TargetIP]
523
    mov     esi, dword[TargetIP]
526
    mov     dword[esp + ARP_PACKET.TargetIP],esi   ;Required IP-addr(we get it as function parameter)
524
    mov     dword[esp + ARP_PACKET.TargetIP],esi   ;Required IP-addr(we get it as function parameter)
527
 
525
 
528
    ; Now, send it!
526
    ; Now, send it!
529
    mov     edi, broadcast_add     ; Pointer to 48 bit destination address
527
    mov     edi, broadcast_add     ; Pointer to 48 bit destination address
530
    mov     bx, ETHER_ARP          ; Type of packet
528
    mov     bx, ETHER_ARP          ; Type of packet
531
    mov     ecx, 28                ; size of packet
529
    mov     ecx, 28                ; size of packet
532
    lea     esi, [esp + ARP_PACKET]; pointer to packet data
530
    lea     esi, [esp + ARP_PACKET]; pointer to packet data
533
    push    ebp
531
    push    ebp
534
    call    dword [drvr_transmit]  ; Call the drivers transmit function
532
    call    dword [drvr_transmit]  ; Call the drivers transmit function
535
    pop     ebp
533
    pop     ebp
536
 
534
 
537
    add     esp, 28  ; free memory, allocated before for ARP_PACKET
535
    add     esp, 28  ; free memory, allocated before for ARP_PACKET
538
 
536
 
539
    ; Add an entry in the ARP table, awaiting response
537
    ; Add an entry in the ARP table, awaiting response
540
    sub     esp, ARP_ENTRY_SIZE    ;allocate memory for ARP-entry
538
    sub     esp, ARP_ENTRY_SIZE    ;allocate memory for ARP-entry
541
 
539
 
542
    mov     esi, dword[TargetIP]
540
    mov     esi, dword[TargetIP]
543
    mov     dword[esp + ARP_ENTRY.IP],esi
541
    mov     dword[esp + ARP_ENTRY.IP],esi
544
 
542
 
545
    lea     edi, [esp + ARP_ENTRY.MAC]
543
    lea     edi, [esp + ARP_ENTRY.MAC]
546
    xor     eax, eax
544
    xor     eax, eax
547
    stosd
545
    stosd
548
    stosw
546
    stosw
549
 
547
 
550
    mov     word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
548
    mov     word[esp + ARP_ENTRY.Status], ARP_AWAITING_RESPONSE
551
    mov     word[esp + ARP_ENTRY.TTL], 0x000A  ; 10 seconds
549
    mov     word[esp + ARP_ENTRY.TTL], 0x000A  ; 10 seconds
552
 
550
 
553
    stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
551
    stdcall arp_table_manager,ARP_TABLE_ADD,EXTRA_IS_ARP_ENTRY_PTR,esp
554
    add     esp, ARP_ENTRY_SIZE  ; free memory
552
    add     esp, ARP_ENTRY_SIZE  ; free memory
555
 
553
 
556
.exit:
554
.exit:
557
    ret
555
    ret
558
endp
556
endp