Subversion Repositories Kolibri OS

Rev

Rev 7678 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3545 hidnplayr 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                                 ;;
7678 hidnplayr 3
;; Copyright (C) KolibriOS team 2004-2019. All rights reserved.    ;;
3545 hidnplayr 4
;; Distributed under terms of the GNU General Public License       ;;
5
;;                                                                 ;;
6
;;  ARP.INC                                                        ;;
7
;;                                                                 ;;
8
;;  Part of the tcp/ip network stack for KolibriOS                 ;;
9
;;                                                                 ;;
10
;;  Based on the work of [Johnny_B] and [smb]                      ;;
11
;;                                                                 ;;
12
;;    Written by hidnplayr@kolibrios.org                           ;;
13
;;                                                                 ;;
14
;;          GNU GENERAL PUBLIC LICENSE                             ;;
15
;;             Version 2, June- 1991                               ;;
16
;;                                                                 ;;
17
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18
 
4850 mario79 19
$Revision: 7679 $
3545 hidnplayr 20
 
21
ARP_NO_ENTRY            = 0
22
ARP_VALID_MAPPING       = 1
23
ARP_AWAITING_RESPONSE   = 2
24
ARP_RESPONSE_TIMEOUT    = 3
25
 
26
ARP_REQUEST_TTL         = 31          ; 20 s
27
ARP_ENTRY_TTL           = 937         ; 600 s
28
ARP_STATIC_ENTRY        = -1
29
 
30
ARP_REQ_OPCODE          = 0x0100      ; request
31
ARP_REP_OPCODE          = 0x0200      ; reply
32
 
33
ARP_TABLE_SIZE          = 20          ; Size of table
34
 
3601 hidnplayr 35
struct  ARP_entry
3545 hidnplayr 36
 
3601 hidnplayr 37
        IP              dd ?
38
        MAC             dp ?
39
        Status          dw ?
40
        TTL             dw ?
3545 hidnplayr 41
 
42
ends
43
 
3601 hidnplayr 44
struct  ARP_header
3545 hidnplayr 45
 
3601 hidnplayr 46
        HardwareType    dw ?
47
        ProtocolType    dw ?
48
        HardwareSize    db ?
49
        ProtocolSize    db ?
50
        Opcode          dw ?
51
        SenderMAC       dp ?
52
        SenderIP        dd ?
53
        TargetMAC       dp ?
54
        TargetIP        dd ?
3545 hidnplayr 55
 
56
ends
57
 
3698 hidnplayr 58
uglobal
3545 hidnplayr 59
align 4
60
 
3601 hidnplayr 61
        ARP_table       rb NET_DEVICES_MAX*(ARP_TABLE_SIZE * sizeof.ARP_entry)
3545 hidnplayr 62
 
7678 hidnplayr 63
        ARP_entries     rd NET_DEVICES_MAX
64
        ARP_packets_tx  rd NET_DEVICES_MAX
65
        ARP_packets_rx  rd NET_DEVICES_MAX
66
        ARP_conflicts   rd NET_DEVICES_MAX
3545 hidnplayr 67
 
68
 
69
endg
70
 
71
 
72
 
6011 hidnplayr 73
;-----------------------------------------------------------------;
74
;                                                                 ;
75
; arp_init: Resets all ARP variables.                             ;
76
;                                                                 ;
77
;-----------------------------------------------------------------;
78
macro arp_init {
3545 hidnplayr 79
 
80
        xor     eax, eax
7678 hidnplayr 81
        mov     edi, ARP_entries
3601 hidnplayr 82
        mov     ecx, 4*NET_DEVICES_MAX
3711 clevermous 83
        rep stosd
3545 hidnplayr 84
 
85
}
86
 
6011 hidnplayr 87
;-----------------------------------------------------------------;
88
;                                                                 ;
89
; arp_decrease_entry_ttls                                         ;
90
;                                                                 ;
91
;-----------------------------------------------------------------;
92
macro arp_decrease_entry_ttls {
3545 hidnplayr 93
 
94
local   .loop
95
local   .exit
96
 
97
; The TTL field is decremented every second, and is deleted when it reaches 0.
98
; It is refreshed every time a packet is received.
99
; If the TTL field is 0xFFFF it is a static entry and is never deleted.
100
; The status field can be the following values:
101
; 0x0000  entry not used
102
; 0x0001  entry holds a valid mapping
103
; 0x0002  entry contains an IP address, awaiting ARP response
104
; 0x0003  No response received to ARP request.
105
; The last status value is provided to allow the network layer to delete
106
; a packet that is queued awaiting an ARP response
107
 
3601 hidnplayr 108
        xor     edi, edi
109
  .loop_outer:
7678 hidnplayr 110
        mov     ecx, [ARP_entries + 4*edi]
3545 hidnplayr 111
        test    ecx, ecx
112
        jz      .exit
113
 
3601 hidnplayr 114
        mov     esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)
115
        imul    esi, edi
116
        add     esi, ARP_table
3545 hidnplayr 117
  .loop:
118
        cmp     [esi + ARP_entry.TTL], ARP_STATIC_ENTRY
119
        je      .next
120
 
121
        dec     [esi + ARP_entry.TTL]
122
        jz      .time_out
123
 
124
  .next:
125
        add     esi, sizeof.ARP_entry
126
        dec     ecx
127
        jnz     .loop
128
        jmp     .exit
129
 
130
  .time_out:
131
        cmp     [esi + ARP_entry.Status], ARP_AWAITING_RESPONSE
132
        je      .response_timeout
133
 
3601 hidnplayr 134
        push    esi edi ecx
6011 hidnplayr 135
        call    arp_del_entry
3601 hidnplayr 136
        pop     ecx edi esi
3545 hidnplayr 137
 
138
        jmp     .next
139
 
140
  .response_timeout:
141
        mov     [esi + ARP_entry.Status], ARP_RESPONSE_TIMEOUT
142
        mov     [esi + ARP_entry.TTL], 10
143
 
144
        jmp     .next
145
 
146
  .exit:
3601 hidnplayr 147
        inc     edi
148
        cmp     edi, NET_DEVICES_MAX
149
        jb      .loop_outer
3545 hidnplayr 150
 
151
}
152
 
153
 
6011 hidnplayr 154
;-----------------------------------------------------------------;
155
;                                                                 ;
156
; arp_input                                                       ;
157
;                                                                 ;
158
;  IN:  [esp] = Pointer to buffer                                 ;
159
;       [esp+4] = size of buffer                                  ;
160
;       ecx = packet size (without ethernet header)               ;
161
;       edx = packet ptr                                          ;
162
;       ebx = device ptr                                          ;
163
;                                                                 ;
164
;  OUT: /                                                         ;
165
;                                                                 ;
166
;-----------------------------------------------------------------;
3545 hidnplayr 167
align 4
6011 hidnplayr 168
arp_input:
3545 hidnplayr 169
 
170
;-----------------------------------------
171
; Check validity and print some debug info
172
 
173
        cmp     ecx, sizeof.ARP_header
174
        jb      .exit
175
 
6011 hidnplayr 176
        call    net_ptr_to_num4
3545 hidnplayr 177
        cmp     edi, -1
178
        jz      .exit
179
 
7678 hidnplayr 180
        inc     [ARP_packets_rx + edi]          ; update stats
3545 hidnplayr 181
 
3643 hidnplayr 182
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: got packet from %u.%u.%u.%u (device*4=%u)\n",\
3545 hidnplayr 183
        [edx + ARP_header.SenderIP]:1, [edx + ARP_header.SenderIP + 1]:1,\
184
        [edx + ARP_header.SenderIP + 2]:1, [edx + ARP_header.SenderIP + 3]:1, edi
185
 
186
;------------------------------
187
; First, check for IP collision
188
 
189
        mov     eax, [edx + ARP_header.SenderIP]
7678 hidnplayr 190
        cmp     eax, [IPv4_address + edi]
3545 hidnplayr 191
        je      .collision
192
 
193
;---------------------
194
; Handle reply packets
195
 
196
        cmp     [edx + ARP_header.Opcode], ARP_REP_OPCODE
197
        jne     .maybe_request
198
 
3556 hidnplayr 199
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: It's a reply\n"
3545 hidnplayr 200
 
7678 hidnplayr 201
        mov     ecx, [ARP_entries + edi]
3545 hidnplayr 202
        test    ecx, ecx
203
        jz      .exit
204
 
3643 hidnplayr 205
        mov     esi, edi
206
        imul    esi, (ARP_TABLE_SIZE * sizeof.ARP_entry)/4
3601 hidnplayr 207
        add     esi, ARP_table
3545 hidnplayr 208
  .loop:
209
        cmp     [esi + ARP_entry.IP], eax
210
        je      .gotit
211
        add     esi, sizeof.ARP_entry
212
        dec     ecx
213
        jnz     .loop
214
 
3556 hidnplayr 215
        DEBUGF  DEBUG_NETWORK_VERBOSE, "ARP_input: no matching entry found\n"
3545 hidnplayr 216
        jmp     .exit
217
 
218
  .gotit: