|
|
| 515 |
} |
515 |
} |
| 516 |
} |
516 |
} |
| 517 |
NS_ASSERT (m_mainAddress != Ipv4Address () && m_broadcast != Ipv4Address ()); |
517 |
NS_ASSERT (m_mainAddress != Ipv4Address () && m_broadcast != Ipv4Address ()); |
| 518 |
ConnectCallbacks (); |
|
|
| 519 |
} |
| 520 |
} |
| 521 |
|
| 522 |
void DsrRouting::ConnectCallbacks () |
| 523 |
{ |
| 524 |
// Connect the callbacks |
| 525 |
Config::Connect ("NodeList/*/DeviceList/*/$ns3::WifiNetDevice/Phy/PhyRxEnd", |
| 526 |
MakeCallback (&DsrRouting::NotifyDataReceipt, this)); |
| 527 |
} |
| 528 |
|
| 529 |
void DsrRouting::NotifyDataReceipt (std::string context, Ptr<const Packet> p) |
| 530 |
{ |
| 531 |
Ptr<NetDevice> ndev = GetNetDeviceFromContext (context); |
| 532 |
NS_ASSERT (ndev); |
| 533 |
Ptr<Node> n = ndev->GetNode (); |
| 534 |
Ptr<Ipv4> ipv4 = n->GetObject<Ipv4> (); |
| 535 |
NS_ASSERT (n); |
| 536 |
|
| 537 |
Ptr<WifiNetDevice> netDevice = DynamicCast<WifiNetDevice> (ndev); |
| 538 |
Mac48Address nodeAddr = netDevice->GetMac()->GetAddress(); |
| 539 |
std::ostringstream oss; |
| 540 |
oss << nodeAddr; |
| 541 |
|
| 542 |
Ptr<Packet> newP = p->Copy(); |
| 543 |
WifiMacHeader hdr; |
| 544 |
newP->RemoveHeader(hdr); |
| 545 |
/// \todo this is a hard-coded check, need to find a better way to work on this |
| 546 |
if (newP->GetSize () == 4) |
| 547 |
{ |
| 548 |
// NS_LOG_WARN ("WifiMacTrailer left, skip this packet"); |
| 549 |
return; |
| 550 |
} |
| 551 |
|
| 552 |
LlcSnapHeader llc; |
| 553 |
if(!newP->PeekHeader (llc)) |
| 554 |
{ |
| 555 |
// NS_LOG_WARN ("llc snap header not present"); |
| 556 |
NS_ASSERT (newP->GetSize() < 64); |
| 557 |
return; |
| 558 |
} |
| 559 |
newP->RemoveHeader(llc); |
| 560 |
/** \internal |
| 561 |
* Tried to use peekheader here, but for ipv4 header here, |
| 562 |
* dsr removes the Ipv4Header and then pass the packet and the header |
| 563 |
* separately to Ipv4L3Protocol. Ipv4L3Protocol then re-adds them |
| 564 |
* together, which causes the problem. Check \bugid{1479} |
| 565 |
*/ |
| 566 |
ArpHeader arp; |
| 567 |
if(newP->PeekHeader (arp)) |
| 568 |
{ |
| 569 |
// NS_LOG_WARN ("arp header present, skip this packet"); |
| 570 |
NS_ASSERT (newP->GetSize() < 64); |
| 571 |
return; |
| 572 |
} |
| 573 |
/// Remove the ipv4 header here |
| 574 |
Ipv4Header ip; |
| 575 |
newP->RemoveHeader(ip); |
| 576 |
/// Remove the dsr routing header here |
| 577 |
DsrRoutingHeader dsrRouting; |
| 578 |
newP->RemoveHeader(dsrRouting); |
| 579 |
/* |
| 580 |
* Message type 2 means the data packet, we will further process the data |
| 581 |
* packet for delivery notification, safely ignore control packet |
| 582 |
* Another check here is our own address, if this is the data destinated for us, |
| 583 |
* process it further, otherwise, just ignore it |
| 584 |
*/ |
| 585 |
Ipv4Address ourAddress = ipv4->GetAddress (1, 0).GetLocal (); |
| 586 |
// check if the message type is 2 and if the ipv4 address matches |
| 587 |
if (dsrRouting.GetMessageType () == 2 && ourAddress == m_mainAddress) |
| 588 |
{ |
| 589 |
NS_LOG_DEBUG ("data packet receives " << p->GetUid()); |
| 590 |
Ipv4Address sourceIp = GetIPfromID (dsrRouting.GetSourceId()); |
| 591 |
Ipv4Address destinationIp = GetIPfromID ( dsrRouting.GetDestId()); |
| 592 |
/// This is the ip address we just received data packet from |
| 593 |
Ipv4Address previousHop = GetIPfromMAC (hdr.GetAddr2 ()); |
| 594 |
|
| 595 |
Ptr<Packet> p = Create<Packet> (); |
| 596 |
// Here the segments left value need to plus one to check the earlier hop maintain buffer entry |
| 597 |
DsrMaintainBuffEntry newEntry; |
| 598 |
newEntry.SetPacket (p); |
| 599 |
newEntry.SetSrc (sourceIp); |
| 600 |
newEntry.SetDst (destinationIp); |
| 601 |
/// Remember this is the entry for previous node |
| 602 |
newEntry.SetOurAdd (previousHop); |
| 603 |
newEntry.SetNextHop (ourAddress); |
| 604 |
/// Get the previous node's maintenance buffer and passive ack |
| 605 |
Ptr<Node> node = GetNodeWithAddress (previousHop); |
| 606 |
NS_LOG_DEBUG ("The previous node " << previousHop); |
| 607 |
|
| 608 |
Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> (); |
| 609 |
dsr->CancelLinkPacketTimer (newEntry); |
| 610 |
} |
518 |
} |
| 611 |
} |
519 |
} |
| 612 |
|
520 |
|
|
|
| 1136 |
bool DsrRouting::PromiscReceive (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address &from, |
1044 |
bool DsrRouting::PromiscReceive (Ptr<NetDevice> device, Ptr<const Packet> packet, uint16_t protocol, const Address &from, |
| 1137 |
const Address &to, NetDevice::PacketType packetType) |
1045 |
const Address &to, NetDevice::PacketType packetType) |
| 1138 |
{ |
1046 |
{ |
| 1139 |
// Receive only IP packets and packets destined for other hosts |
1047 |
|
| 1140 |
if (protocol == Ipv4L3Protocol::PROT_NUMBER && packetType == NetDevice::PACKET_OTHERHOST) |
1048 |
if (protocol != Ipv4L3Protocol::PROT_NUMBER) |
| 1141 |
{ |
1049 |
{ |
| 1142 |
Ptr<Packet> p = packet->Copy (); |
1050 |
return false; |
| 1143 |
//pull off IP header |
1051 |
} |
| 1144 |
Ipv4Header ipv4Header; |
1052 |
// Remove the ipv4 header here |
| 1145 |
p->RemoveHeader (ipv4Header); |
1053 |
Ptr<Packet> pktMinusIpHdr = packet->Copy (); |
| 1146 |
|
1054 |
Ipv4Header ipv4Header; |
| 1147 |
// Process only data packets with DSR header |
1055 |
pktMinusIpHdr->RemoveHeader(ipv4Header); |
| 1148 |
if (ipv4Header.GetProtocol () == DsrRouting::PROT_NUMBER) |
1056 |
|
|
|
1057 |
if (ipv4Header.GetProtocol () != DsrRouting::PROT_NUMBER) |
| 1058 |
{ |
| 1059 |
return false; |
| 1060 |
} |
| 1061 |
// Remove the dsr routing header here |
| 1062 |
Ptr<Packet> pktMinusDsrHdr = pktMinusIpHdr->Copy (); |
| 1063 |
DsrRoutingHeader dsrRouting; |
| 1064 |
pktMinusDsrHdr->RemoveHeader (dsrRouting); |
| 1065 |
|
| 1066 |
/* |
| 1067 |
* Message type 2 means the data packet, we will further process the data |
| 1068 |
* packet for delivery notification, safely ignore control packet |
| 1069 |
* Another check here is our own address, if this is the data destinated for us, |
| 1070 |
* process it further, otherwise, just ignore it |
| 1071 |
*/ |
| 1072 |
Ipv4Address ourAddress = m_ipv4->GetAddress (1, 0).GetLocal (); |
| 1073 |
// check if the message type is 2 and if the ipv4 address matches |
| 1074 |
if (dsrRouting.GetMessageType () == 2 && ourAddress == m_mainAddress) |
| 1075 |
{ |
| 1076 |
NS_LOG_DEBUG ("data packet receives " << packet->GetUid ()); |
| 1077 |
Ipv4Address sourceIp = GetIPfromID (dsrRouting.GetSourceId ()); |
| 1078 |
Ipv4Address destinationIp = GetIPfromID ( dsrRouting.GetDestId ()); |
| 1079 |
/// This is the ip address we just received data packet from |
| 1080 |
Ipv4Address previousHop = GetIPfromMAC (Mac48Address::ConvertFrom (from)); |
| 1081 |
|
| 1082 |
Ptr<Packet> p = Create<Packet> (); |
| 1083 |
// Here the segments left value need to plus one to check the earlier hop maintain buffer entry |
| 1084 |
DsrMaintainBuffEntry newEntry; |
| 1085 |
newEntry.SetPacket (p); |
| 1086 |
newEntry.SetSrc (sourceIp); |
| 1087 |
newEntry.SetDst (destinationIp); |
| 1088 |
/// Remember this is the entry for previous node |
| 1089 |
newEntry.SetOurAdd (previousHop); |
| 1090 |
newEntry.SetNextHop (ourAddress); |
| 1091 |
/// Get the previous node's maintenance buffer and passive ack |
| 1092 |
Ptr<Node> node = GetNodeWithAddress (previousHop); |
| 1093 |
NS_LOG_DEBUG ("The previous node " << previousHop); |
| 1094 |
|
| 1095 |
Ptr<dsr::DsrRouting> dsr = node->GetObject<dsr::DsrRouting> (); |
| 1096 |
dsr->CancelLinkPacketTimer (newEntry); |
| 1097 |
} |
| 1098 |
|
| 1099 |
// Receive only IP packets and packets destined for other hosts |
| 1100 |
if (packetType == NetDevice::PACKET_OTHERHOST) |
| 1101 |
{ |
| 1102 |
//just to minimize debug output |
| 1103 |
NS_LOG_INFO (this << from << to << packetType << *pktMinusIpHdr); |
| 1104 |
|
| 1105 |
uint8_t offset = dsrRouting.GetDsrOptionsOffset (); // Get the offset for option header, 4 bytes in this case |
| 1106 |
uint8_t nextHeader = dsrRouting.GetNextHeader (); |
| 1107 |
uint32_t sourceId = dsrRouting.GetSourceId (); |
| 1108 |
Ipv4Address source = GetIPfromID (sourceId); |
| 1109 |
|
| 1110 |
// This packet is used to peek option type |
| 1111 |
pktMinusIpHdr->RemoveAtStart (offset); |
| 1112 |
/* |
| 1113 |
* Peek data to get the option type as well as length and segmentsLeft field |
| 1114 |
*/ |
| 1115 |
uint32_t size = pktMinusIpHdr->GetSize (); |
| 1116 |
uint8_t *data = new uint8_t[size]; |
| 1117 |
pktMinusIpHdr->CopyData (data, size); |
| 1118 |
uint8_t optionType = 0; |
| 1119 |
optionType = *(data); |
| 1120 |
|
| 1121 |
Ptr<dsr::DsrOptions> dsrOption; |
| 1122 |
|
| 1123 |
if (optionType == 96) // This is the source route option |
| 1149 |
{ |
1124 |
{ |
| 1150 |
//just to minimize debug output |
1125 |
Ipv4Address promiscSource = GetIPfromMAC (Mac48Address::ConvertFrom (from)); |
| 1151 |
NS_LOG_INFO (this << from << to << packetType << *p); |
1126 |
dsrOption = GetOption (optionType); // Get the relative DSR option and demux to the process function |
| 1152 |
DsrRoutingHeader dsrRoutingHeader; |
1127 |
NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << |
| 1153 |
//pull of DSR header to check option type |
1128 |
" DSR node " << m_mainAddress << |
| 1154 |
Ptr<Packet> dsrPacket = p->Copy (); |
1129 |
" overhearing packet PID: " << pktMinusIpHdr->GetUid () << |
| 1155 |
dsrPacket->RemoveHeader (dsrRoutingHeader); |
1130 |
" from " << promiscSource << |
| 1156 |
uint8_t offset = dsrRoutingHeader.GetDsrOptionsOffset (); // Get the offset for option header, 4 bytes in this case |
1131 |
" to " << GetIPfromMAC (Mac48Address::ConvertFrom (to)) << |
| 1157 |
uint8_t nextHeader = dsrRoutingHeader.GetNextHeader (); |
1132 |
" with source IP " << ipv4Header.GetSource () << |
| 1158 |
uint32_t sourceId = dsrRoutingHeader.GetSourceId (); |
1133 |
" and destination IP " << ipv4Header.GetDestination () << |
| 1159 |
Ipv4Address source = GetIPfromID (sourceId); |
1134 |
" and packet : " << *pktMinusDsrHdr); |
| 1160 |
|
1135 |
|
| 1161 |
// This packet is used to peek option type |
1136 |
bool isPromisc = true; // Set the boolean value isPromisc as true |
| 1162 |
p->RemoveAtStart (offset); |
1137 |
dsrOption->Process (pktMinusIpHdr, pktMinusDsrHdr, m_mainAddress, source, ipv4Header, nextHeader, isPromisc, promiscSource); |
| 1163 |
/* |
1138 |
return true; |
| 1164 |
* Peek data to get the option type as well as length and segmentsLeft field |
1139 |
|
| 1165 |
*/ |
|
|
| 1166 |
uint32_t size = p->GetSize (); |
| 1167 |
uint8_t *data = new uint8_t[size]; |
| 1168 |
p->CopyData (data, size); |
| 1169 |
uint8_t optionType = 0; |
| 1170 |
optionType = *(data); |
| 1171 |
|
| 1172 |
Ptr<dsr::DsrOptions> dsrOption; |
| 1173 |
|
| 1174 |
if (optionType == 96) // This is the source route option |
| 1175 |
{ |
| 1176 |
Ipv4Address promiscSource = GetIPfromMAC (Mac48Address::ConvertFrom (from)); |
| 1177 |
dsrOption = GetOption (optionType); // Get the relative DSR option and demux to the process function |
| 1178 |
NS_LOG_DEBUG (Simulator::Now ().GetSeconds () << |
| 1179 |
" DSR node " << m_mainAddress << |
| 1180 |
" overhearing packet PID: " << p->GetUid () << |
| 1181 |
" from " << promiscSource << |
| 1182 |
" to " << GetIPfromMAC (Mac48Address::ConvertFrom (to)) << |
| 1183 |
" with source IP " << ipv4Header.GetSource () << |
| 1184 |
" and destination IP " << ipv4Header.GetDestination () << |
| 1185 |
" and packet : " << *dsrPacket); |
| 1186 |
|
| 1187 |
bool isPromisc = true; // Set the boolean value isPromisc as true |
| 1188 |
dsrOption->Process (p, dsrPacket, m_mainAddress, source, ipv4Header, nextHeader, isPromisc, promiscSource); |
| 1189 |
return true; |
| 1190 |
} |
| 1191 |
} |
1140 |
} |
| 1192 |
} |
1141 |
} |
| 1193 |
return false; |
1142 |
return false; |