Subversion Repositories Kolibri OS

Rev

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

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