📄 arp.lst
字号:
155 // If destination IP is on my subnet then we want the eth
156 // address of destination, otherwise we want eth addr of gateway.
157 // Look in ARP cache first. If not found there, send ARP request.
158 // Return pointer to the hardware address or NULL if not found
159 // See "TCP/IP Illustrated, Volume 1" Sect 4.5
160 //------------------------------------------------------------------------
161 UCHAR xdata * arp_resolve(ULONG dest_ipaddr)
162 {
163 1 UCHAR i;
164 1
165 1 // If destination IP is not on my subnet then we really want eth addr
166 1 // of gateway, not destination IP
167 1 if ((dest_ipaddr ^ my_ipaddr) & my_subnet)
168 1 {
169 2 if (gateway_ipaddr == 0)
170 2 {
171 3 // if (debug) printf("ARP: Error, gateway addr not set\n");
172 3 return (NULL);
173 3 }
174 2 else dest_ipaddr = gateway_ipaddr;
175 2 }
176 1
177 1
178 1 // See if IP addr of interest is in ARP cache
179 1 for (i=0; i < CACHESIZE; i++)
C51 COMPILER V7.06 ARP 06/26/2004 13:41:25 PAGE 4
180 1 {
181 2 if (arp_cache[i].ipaddr == dest_ipaddr)
182 2 return (&arp_cache[i].hwaddr[0]);
183 2 }
184 1
185 1 // if (debug) printf("ARP: IP addr not found in cache\n");
186 1 // if (debug) printf("ARP: Sending an ARP broadcast\n");
187 1 // Not in cache so broadcast ARP request
188 1 arp_send(NULL, dest_ipaddr, ARP_REQUEST);
189 1
190 1 // Set a flag to indicate that an IP datagram is waiting
191 1 // to be sent
192 1 waiting_for_arp = TRUE;
193 1
194 1 // Null means that we have sent an ARP request
195 1 return (NULL);
196 1 }
197
198
199
200
201
202 //------------------------------------------------------------------------
203 // This handles incoming ARP messages
204 // See "TCP/IP Illustrated, Volume 1" Sect 4.4
205 // Todo: Resolve problem of trying to add to a full cache
206 //------------------------------------------------------------------------
207 void arp_rcve(UCHAR xdata * inbuf)
208 {
209 1 UCHAR idata i, cached, oldest;
210 1 UINT idata minimum;
211 1 ARP_HEADER xdata * arp;
212 1
213 1 arp = (ARP_HEADER xdata *)(inbuf + 14);
214 1 cached = FALSE;
215 1
216 1 // Print message
217 1
218 1 // Validate incoming frame
219 1 if ((arp->hardware_type != DIX_ETHERNET) ||
220 1 (arp->protocol_type != IP_PACKET)) return;
221 1
222 1 // Search ARP cache for senders IP address
223 1 // If found, update entry and restart timer
224 1 for (i=0; i < CACHESIZE; i++)
225 1 {
226 2 if (arp_cache[i].ipaddr == arp->source_ipaddr)
227 2 {
228 3 memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);
229 3 arp_cache[i].timer = CACHETIME;
230 3 cached = TRUE;
231 3 // if (debug) printf("ARP: Cache entry updated\n");
232 3
233 3 break;
234 3 }
235 2 }
236 1
237 1 if (arp->dest_ipaddr != my_ipaddr) return;
238 1
239 1 // At this point we know the the frame is addressed to me
240 1 // If not already in cache then add entry and start timer
241 1 if (cached == FALSE)
C51 COMPILER V7.06 ARP 06/26/2004 13:41:25 PAGE 5
242 1 {
243 2 // Find first blank space and add entry
244 2 // Blank entries are indicated by ip addr = 0
245 2 for (i=0; i < CACHESIZE; i++)
246 2 {
247 3 if (arp_cache[i].ipaddr == 0)
248 3 {
249 4 arp_cache[i].ipaddr = arp->source_ipaddr;
250 4 memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);
251 4 arp_cache[i].timer = CACHETIME;
252 4 // if (debug) printf("ARP: New cache entry added\n");
253 4 break;
254 4 }
255 3 }
256 2
257 2 // If no blank entries in arp cache then sort cache
258 2 // to find oldest entry and replace it
259 2 if (i == CACHESIZE)
260 2 {
261 3 // Oldest entry is the one with lowest timer value
262 3 minimum = 0xFFFF;
263 3 for (i=0; i < CACHESIZE; i++)
264 3 {
265 4 if (arp_cache[i].timer < minimum)
266 4 {
267 5 minimum = arp_cache[i].timer;
268 5 oldest = i;
269 5 }
270 4 }
271 3
272 3 // "oldest" is now index of oldest entry, so replace it
273 3 arp_cache[oldest].ipaddr = arp->source_ipaddr;
274 3 memcpy(&arp_cache[oldest].hwaddr[0], &arp->source_hwaddr[0], 6);
275 3 arp_cache[oldest].timer = CACHETIME;
276 3 // if (debug) printf("ARP: Cache full, so replaced oldest\n");
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 // if (debug) printf("ARP: Sending response\n");
296 2 arp_send(arp->source_hwaddr, arp->source_ipaddr, ARP_RESPONSE);
297 2 }
298 1 }
299
300
MODULE INFORMATION: STATIC OVERLAYABLE
C51 COMPILER V7.06 ARP 06/26/2004 13:41:25 PAGE 6
CODE SIZE = 1619 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 111 20
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
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 + -