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