?? arp.lst
字號:
153 2 }
154 1 }
155
156
157
158
159 //------------------------------------------------------------------------
160 // Find the ethernet hardware address for the given ip address
161 // If destination IP is on my subnet then we want the eth
162 // address of destination, otherwise we want eth addr of gateway.
163 // Look in ARP cache first. If not found there, send ARP request.
164 // Return pointer to the hardware address or NULL if not found
165 // See "TCP/IP Illustrated, Volume 1" Sect 4.5
166 //------------------------------------------------------------------------
167 UCHAR xdata * arp_resolve(ULONG dest_ipaddr)
168 {
169 1 UCHAR i;
170 1
171 1 // If destination IP is not on my subnet then we really want eth addr
172 1 // of gateway, not destination IP
173 1 if ((dest_ipaddr ^ my_ipaddr) & my_subnet)
174 1 {
175 2 if (gateway_ipaddr == 0)
176 2 {
C51 COMPILER V8.08 ARP 11/04/2008 18:45:33 PAGE 4
177 3 return (NULL);
178 3 }
179 2 else dest_ipaddr = gateway_ipaddr;
180 2 }
181 1
182 1
183 1 // See if IP addr of interest is in ARP cache
184 1 for (i=0; i < CACHESIZE; i++)
185 1 {
186 2 if (arp_cache[i].ipaddr == dest_ipaddr)
187 2 return (&arp_cache[i].hwaddr[0]);
188 2 }
189 1
190 1 // Not in cache so broadcast ARP request
191 1 arp_send(NULL, dest_ipaddr, ARP_REQUEST);
192 1
193 1 // Set a flag to indicate that an IP datagram is waiting
194 1 // to be sent
195 1 waiting_for_arp = TRUE;
196 1
197 1 // Null means that we have sent an ARP request
198 1 return (NULL);
199 1 }
200
201
202
203
204
205 //------------------------------------------------------------------------
206 // This handles incoming ARP messages
207 // See "TCP/IP Illustrated, Volume 1" Sect 4.4
208 // Todo: Resolve problem of trying to add to a full cache
209 //------------------------------------------------------------------------
210 void arp_rcve(UCHAR xdata * inbuf)
211 {
212 1 UCHAR idata i, cached, oldest;
213 1 UINT idata minimum;
214 1 ARP_HEADER xdata * arp;
215 1
216 1 arp = (ARP_HEADER xdata *)(inbuf + 14);
217 1 cached = FALSE;
218 1
219 1 // Print message
220 1
221 1 // Validate incoming frame
222 1 if ((arp->hardware_type != DIX_ETHERNET) ||
223 1 (arp->protocol_type != IP_PACKET)) return;
224 1
225 1 // Search ARP cache for senders IP address
226 1 // If found, update entry and restart timer
227 1 for (i=0; i < CACHESIZE; i++)
228 1 {
229 2 if (arp_cache[i].ipaddr == arp->source_ipaddr)
230 2 {
231 3 memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);
232 3 arp_cache[i].timer = CACHETIME;
233 3 cached = TRUE;
234 3
235 3 break;
236 3 }
237 2 }
238 1
C51 COMPILER V8.08 ARP 11/04/2008 18:45:33 PAGE 5
239 1 if (arp->dest_ipaddr != my_ipaddr) return;
240 1
241 1 // At this point we know the the frame is addressed to me
242 1 // If not already in cache then add entry and start timer
243 1 if (cached == FALSE)
244 1 {
245 2 // Find first blank space and add entry
246 2 // Blank entries are indicated by ip addr = 0
247 2 for (i=0; i < CACHESIZE; i++)
248 2 {
249 3 if (arp_cache[i].ipaddr == 0)
250 3 {
251 4 arp_cache[i].ipaddr = arp->source_ipaddr;
252 4 memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);
253 4 arp_cache[i].timer = CACHETIME;
254 4 break;
255 4 }
256 3 }
257 2
258 2 // If no blank entries in arp cache then sort cache
259 2 // to find oldest entry and replace it
260 2 if (i == CACHESIZE)
261 2 {
262 3 // Oldest entry is the one with lowest timer value
263 3 minimum = 0xFFFF;
264 3 for (i=0; i < CACHESIZE; i++)
265 3 {
266 4 if (arp_cache[i].timer < minimum)
267 4 {
268 5 minimum = arp_cache[i].timer;
269 5 oldest = i;
270 5 }
271 4 }
272 3
273 3 // "oldest" is now index of oldest entry, so replace it
274 3 arp_cache[oldest].ipaddr = arp->source_ipaddr;
275 3 memcpy(&arp_cache[oldest].hwaddr[0], &arp->source_hwaddr[0], 6);
276 3 arp_cache[oldest].timer = CACHETIME;
277 3 }
278 2 }
279 1
280 1
281 1 // If we are waiting for an arp response and the arp response
282 1 // that just came in is addressed to me and is from the host
283 1 // we are waiting for, then send the message-in-waiting
284 1 if (arp->message_type == ARP_RESPONSE)
285 1 {
286 2 if ((waiting_for_arp) && (wait.ipaddr == arp->source_ipaddr))
287 2 {
288 3 waiting_for_arp = FALSE;
289 3 ip_send(wait.buf, wait.ipaddr, wait.proto_id, wait.len);
290 3 }
291 2 }
292 1 else if (arp->message_type == ARP_REQUEST)
293 1 {
294 2 // Send ARP response
295 2 arp_send(arp->source_hwaddr, arp->source_ipaddr, ARP_RESPONSE);
296 2 }
297 1 }
298
299
C51 COMPILER V8.08 ARP 11/04/2008 18:45:33 PAGE 6
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1449 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 110 ----
PDATA SIZE = ---- ----
DATA SIZE = 1 20
IDATA SIZE = 1 5
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 2 WARNING(S), 0 ERROR(S)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -