|
175 |
// |
175 |
// |
176 |
// If we're connected to a real world network, then some of the fields sizes |
176 |
// If we're connected to a real world network, then some of the fields sizes |
177 |
// in an ARP packet can vary in ways not seen in simulations. We need to be |
177 |
// in an ARP packet can vary in ways not seen in simulations. We need to be |
178 |
// able to detect ARP packets with headers we don't recongnize and not process |
178 |
// able to detect ARP packets with headers we don't recognize and not process |
179 |
// them instead of crashing. The ArpHeader will return 0 if it can't deal |
179 |
// them instead of crashing. The ArpHeader will return 0 if it can't deal |
180 |
// with the received header. |
180 |
// with the received header. |
181 |
// |
181 |
// |
|
198 |
NS_LOG_LOGIC (cache->GetInterface ()->GetAddress (i).GetLocal () << ", "); |
198 |
NS_LOG_LOGIC (cache->GetInterface ()->GetAddress (i).GetLocal () << ", "); |
199 |
} |
199 |
} |
200 |
|
200 |
|
201 |
/** |
|
|
202 |
* \internal |
203 |
* Note: we do not update the ARP cache when we receive an ARP request |
204 |
* from an unknown node. See \bugid{107} |
205 |
*/ |
206 |
bool found = false; |
201 |
bool found = false; |
207 |
for (uint32_t i = 0; i < cache->GetInterface ()->GetNAddresses (); i++) |
202 |
for (uint32_t i = 0; i < cache->GetInterface ()->GetNAddresses (); i++) |
208 |
{ |
203 |
{ |
209 |
if (arp.IsRequest () && arp.GetDestinationIpv4Address () == |
204 |
if (arp.IsRequest () && arp.GetDestinationIpv4Address () == |
210 |
cache->GetInterface ()->GetAddress (i).GetLocal ()) |
205 |
cache->GetInterface ()->GetAddress (i).GetLocal ()) |
211 |
{ |
206 |
{ |
|
|
207 |
ArpCache::Entry *entry = cache->Lookup (arp.GetSourceIpv4Address ()); |
208 |
if (entry!=0) |
209 |
{ |
210 |
if (entry->IsWaitReply ()) |
211 |
{ |
212 |
NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got request from " << |
213 |
arp.GetSourceIpv4Address () << |
214 |
" for waiting entry -- flush and later send reply"); |
215 |
entry->MarkAlive (arp.GetSourceHardwareAddress ()); |
216 |
} |
217 |
else |
218 |
{ |
219 |
// Ignore-- already have an entry |
220 |
NS_LOG_LOGIC("node="<<m_node->GetId () << ", got request from " << |
221 |
arp.GetSourceIpv4Address () << " for non-waiting entry"); |
222 |
entry->UpdateSeen (); |
223 |
} |
224 |
} |
225 |
else |
226 |
{ |
227 |
// No entry for this source, but add one now (RFC 826) |
228 |
NS_LOG_LOGIC("node="<<m_node->GetId ()<<", got request from " << |
229 |
arp.GetSourceIpv4Address () << |
230 |
" for non-existent entry-- adding "); |
231 |
ArpCache::Entry *entry = cache->Add (arp.GetSourceIpv4Address ()); |
232 |
entry->MarkAlive (arp.GetSourceHardwareAddress ()); |
233 |
} |
234 |
|
212 |
found = true; |
235 |
found = true; |
213 |
NS_LOG_LOGIC ("node="<<m_node->GetId () <<", got request from " << |
236 |
NS_LOG_LOGIC ("node="<<m_node->GetId () <<", got request from " << |
214 |
arp.GetSourceIpv4Address () << " -- send reply"); |
237 |
arp.GetSourceIpv4Address () << " -- send reply"); |
215 |
SendArpReply (cache, arp.GetDestinationIpv4Address (), arp.GetSourceIpv4Address (), |
238 |
SendArpReply (cache, arp.GetDestinationIpv4Address (), arp.GetSourceIpv4Address (), |
216 |
arp.GetSourceHardwareAddress ()); |
239 |
arp.GetSourceHardwareAddress ()); |
217 |
break; |
240 |
break; |
218 |
} |
241 |
} |
219 |
else if (arp.IsReply () && |
242 |
else if (arp.IsReply () && |
220 |
arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress (i).GetLocal ()) && |
243 |
arp.GetDestinationIpv4Address ().IsEqual (cache->GetInterface ()->GetAddress (i).GetLocal ()) && |
221 |
arp.GetDestinationHardwareAddress () == device->GetAddress ()) |
244 |
arp.GetDestinationHardwareAddress () == device->GetAddress ()) |
222 |
{ |
245 |
{ |
|
228 |
if (entry->IsWaitReply ()) |
251 |
if (entry->IsWaitReply ()) |
229 |
{ |
252 |
{ |
230 |
NS_LOG_LOGIC ("node="<< m_node->GetId () << |
253 |
NS_LOG_LOGIC ("node="<< m_node->GetId () << |
231 |
", got reply from " << arp.GetSourceIpv4Address () |
254 |
", got reply from " << arp.GetSourceIpv4Address () << |
232 |
<< " for waiting entry -- flush"); |
255 |
" for waiting entry -- flush"); |
233 |
Address from_mac = arp.GetSourceHardwareAddress (); |
256 |
Address from_mac = arp.GetSourceHardwareAddress (); |
234 |
entry->MarkAlive (from_mac); |
257 |
entry->MarkAlive (from_mac); |
235 |
ArpCache::Ipv4PayloadHeaderPair pending = entry->DequeuePending (); |
258 |
ArpCache::Ipv4PayloadHeaderPair pending = entry->DequeuePending (); |
|
243 |
else |
266 |
else |
244 |
{ |
267 |
{ |
245 |
// ignore this reply which might well be an attempt |
268 |
// ignore this reply which might well be an attempt |
246 |
// at poisening my arp cache. |
269 |
// at poisoning my arp cache. |
247 |
NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got reply from " << |
270 |
NS_LOG_LOGIC ("node=" << m_node->GetId () << ", got reply from " << |
248 |
arp.GetSourceIpv4Address () << |
271 |
arp.GetSourceIpv4Address () << |
249 |
" for non-waiting entry -- drop"); |
272 |
" for non-waiting entry -- drop"); |
250 |
m_dropTrace (packet); |
273 |
m_dropTrace (packet); |
|
252 |
} |
275 |
} |
253 |
else |
276 |
else |
254 |
{ |
277 |
{ |
255 |
NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got reply for unknown entry -- drop"); |
278 |
NS_LOG_LOGIC ("node=" << m_node->GetId () << ", got reply for unknown entry -- drop"); |
256 |
m_dropTrace (packet); |
279 |
m_dropTrace (packet); |
257 |
} |
280 |
} |
258 |
break; |
281 |
break; |
|
260 |
} |
283 |
} |
261 |
if (found == false) |
284 |
if (found == false) |
262 |
{ |
285 |
{ |
263 |
NS_LOG_LOGIC ("node="<<m_node->GetId ()<<", got request from " << |
286 |
NS_LOG_LOGIC ("node=" << m_node->GetId () << ", got request from " << |
264 |
arp.GetSourceIpv4Address () << " for unknown address " << |
287 |
arp.GetSourceIpv4Address () << " for unknown address " << |
265 |
arp.GetDestinationIpv4Address () << " -- drop"); |
288 |
arp.GetDestinationIpv4Address () << " -- drop"); |
266 |
} |
289 |
} |