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: |
||