⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nwip.pc

📁 simulator for ad hoc
💻 PC
📖 第 1 页 / 共 5 页
字号:
staticvoid ExpandReassemblyBuffer(   GlomoNode* node,   IpReassemblyBufferType* reassemblyBuffer,    int minSize) {   int newSize;   Message* biggerBufferPacket = GLOMO_MsgAlloc(node, 0, 0, 0);      newSize= (reassemblyBuffer->sizeLimit *              REASSEMBLY_BUFFER_EXPANSION_MULTIPLIER);                if (newSize < minSize) {      assert(minSize <= IP_MAXPACKET);      newSize = minSize;   }//if//                if (newSize > IP_MAXPACKET) {      newSize = IP_MAXPACKET;   }//if//            GLOMO_MsgPacketAlloc(node, biggerBufferPacket, newSize);      memcpy(biggerBufferPacket->packet,           reassemblyBuffer->packetUnderConstruction->packet,          reassemblyBuffer->sizeLimit);   reassemblyBuffer->sizeLimit = newSize;   GLOMO_MsgFree(node, reassemblyBuffer->packetUnderConstruction);   reassemblyBuffer->packetUnderConstruction = biggerBufferPacket;}////  Simple Bit vector manipulation macros.//#define BitIsSet(BitVector, Index)  \   ((BitVector[(Index)/8] & (1 << ((Index) % 8))) != 0)   #define SetBit(BitVector, Index) \   BitVector[(Index)/8] |= (1 << ((Index) % 8));//// FUNCTION CheckForFragmentBufferCompletion() //// PURPOSE  Checks the reassembly buffer to if it is complete.//          The answer is passed back in the "packetIsComplete" //          boolean output variable.//staticvoid CheckForFragmentBufferCompletion(   IpReassemblyBufferType* reassemblyBuffer,   BOOL* packetIsComplete){   int I;   int lastIndex =       reassemblyBuffer->endFragmentOffset / reassemblyBuffer->fragmentationSize;      // Set the extra bits in the end char in the bit vector, if they   // have not already been set.      if (!BitIsSet(reassemblyBuffer->fragmentIsHereBitTable, lastIndex)) {      for(I = lastIndex; (I < ((lastIndex/8) + 1) * 8); I++) {         SetBit(reassemblyBuffer->fragmentIsHereBitTable, I);      }//for//   }//if//      // Super fast byte comparison.  All the bits of the bit vector must   // be 1.                                                for(I = 0; (I < ((lastIndex/8) + 1)); I++) {      if (reassemblyBuffer->fragmentIsHereBitTable[I] != 0xFF) {         *packetIsComplete = FALSE;         return;      }//if//   }//for//   *packetIsComplete = TRUE;}               //// FUNCTION  AddFragmentToReassemblyBuffer() //// PURPOSE   Adds the data in a packet fragment to the reassembly buffer.//           if that was the last fragment the routine sets a boolean//           ("packetIsComplete") and returns a pointer to the complete//           packet ("competedPacket").//      staticvoid AddFragmentToReassemblyBuffer(   GlomoNode* node,   IpReassemblyBufferType* reassemblyBuffer,   const Message* msg,   BOOL* packetIsComplete,   Message** completedPacket){   //    // Determine the length and where the fragment's data should go.   // Expand the reassembly buffer if the packet is too large.   //   Message* bufferPacket = NULL;   IpHeaderType* ipHeader = (IpHeaderType*)msg->packet;   int ipHeaderSize = IpHeaderSize(ipHeader);      int fragmentOffset = FragmentOffset(ipHeader);   int fragmentDataLength = ipHeader->ip_len - ipHeaderSize;   char* fragmentData = msg->packet + IpHeaderSize(ipHeader);   int packetLengthSoFar = ipHeaderSize + fragmentOffset + fragmentDataLength;      *packetIsComplete = FALSE;   reassemblyBuffer->expirationDate = simclock() + NETWORK_IP_REASS_BUFF_TIMER;      if (packetLengthSoFar > reassemblyBuffer->sizeLimit) {      ExpandReassemblyBuffer(node, reassemblyBuffer, packetLengthSoFar);   }//if//                                                              //   // Copy in the fragment's data into the reassembly buffer.  Then   // set the bit in the table to says that the fragment has arrived.   // Currently one bit for each equally sized fragment (except last).   // Its not totally general, but probably is good enough.   //                                                                                                                 bufferPacket = reassemblyBuffer->packetUnderConstruction;      memcpy(      &(bufferPacket->packet[ipHeaderSize + fragmentOffset]),      fragmentData,       fragmentDataLength);      if (ipHeader->ip_more_fragments == 0) {      reassemblyBuffer->endFragmentHasArrived = TRUE;      reassemblyBuffer->endFragmentOffset = fragmentOffset;   } else {      int fragmentIndex;      if (reassemblyBuffer->fragmentationSize == 0) {         reassemblyBuffer->fragmentationSize = fragmentDataLength;      }//if//            // Only simple same sized fragments implemented.            assert(fragmentDataLength == reassemblyBuffer->fragmentationSize);             fragmentIndex =          fragmentOffset / reassemblyBuffer->fragmentationSize;            assert(fragmentIndex < MAX_IP_FRAGMENTS_SIMPLE_CASE);            SetBit(reassemblyBuffer->fragmentIsHereBitTable, fragmentIndex);   }//if//         //   // Check to see if all fragments have arrived and the packet is complete.   //      if ((reassemblyBuffer->endFragmentHasArrived) &&        (reassemblyBuffer->fragmentationSize != 0))    {      CheckForFragmentBufferCompletion(reassemblyBuffer, packetIsComplete);      if (*packetIsComplete) {         *completedPacket = reassemblyBuffer->packetUnderConstruction;         reassemblyBuffer->packetUnderConstruction = NULL;      }//if//    }//if//}//AddFragmentToReassemblyBuffer////// FUNCTION InitializeReassemblyBuffer() //// PURPOSE  Initializes a new reassembly buffer with a packet fragment.//staticvoid InitializeReassemblyBuffer(   GlomoNode* node,   IpReassemblyBufferType* reassemblyBuffer,   const Message* msg){   int I;   BOOL NotUsed;   IpHeaderType* msgIpHeader = (IpHeaderType *) msg->packet;     int ipHeaderSize = IpHeaderSize(msgIpHeader);   IpHeaderType* bufferIpHeader = NULL;      //   // Allocate a message to act as a reassembly buffer.   //   reassemblyBuffer->sizeLimit = SMALL_REASSEMBLY_BUFFER_SIZE;      reassemblyBuffer->packetUnderConstruction = GLOMO_MsgAlloc(node, 0, 0, 0);   GLOMO_MsgPacketAlloc(node,       reassemblyBuffer->packetUnderConstruction,      reassemblyBuffer->sizeLimit);      //   // Copy over the IP packet header and set the fields in the    // reassembly buffer to initial values including setting the   // "fragment is here" bit table to all 0's.   //   memcpy(      reassemblyBuffer->packetUnderConstruction->packet,       msg->packet, ipHeaderSize);         bufferIpHeader =       (IpHeaderType*)reassemblyBuffer->packetUnderConstruction->packet;      bufferIpHeader->ip_len = 0;   SetFragmentOffset(bufferIpHeader, 0);   reassemblyBuffer->fragmentationSize = 0;   reassemblyBuffer->endFragmentHasArrived = FALSE;   reassemblyBuffer->endFragmentOffset = 0;                           for(I = 0; I < (MAX_IP_FRAGMENTS_SIMPLE_CASE/8); I++) {      reassemblyBuffer->fragmentIsHereBitTable[I] = 0;   }      // Add the fragment's data to the reassembly buffer.         AddFragmentToReassemblyBuffer(node, reassemblyBuffer, msg, &NotUsed, 0);}//// FUNCTION ProcessFragmentAndMaybeBuildCompletePacket() //// PURPOSE  Creates or finds an existing reassembly buffer and moves//          the data from the passed message fragment into the buffer.//          Then detects whether if all pieces of the packet has arrived//          and if it has it passes the completed packet out and//          deletes that reassembly buffer.  The routine also scans//          for expired reassembly buffers (only when creating a new//          buffer).//staticvoid ProcessFragmentAndMaybeBuildCompletePacket(   GlomoNode* node, const Message* msg,    BOOL* packetIsComplete, Message** completedPacket) {   GlomoNetworkIp* ipLayer = (GlomoNetworkIp *)node->networkData.networkVar;   IpReassemblyBufferType* reassemblyBuffer = NULL;   BOOL foundAnExistingBuffer;      *packetIsComplete = FALSE;      IpReassemblyBufferList_FindOrCreateNew(      &ipLayer->reassemblyBufferList, msg,      &reassemblyBuffer, &foundAnExistingBuffer);         if (!foundAnExistingBuffer) {      InitializeReassemblyBuffer(node, reassemblyBuffer, msg);      RemoveExpiredIpReassemblyBuffers(         node, &ipLayer->reassemblyBufferList, simclock());   } else {      if (!ReassemblyBufferHasExpired(reassemblyBuffer, simclock())) {         AddFragmentToReassemblyBuffer(node, reassemblyBuffer, msg,             packetIsComplete, completedPacket);         if (*packetIsComplete) {            IpReassemblyBufferList_Delete(               &ipLayer->reassemblyBufferList, &reassemblyBuffer);              }//if//      }//if//   }//if//}//ProcessFragmentAndMaybeBuildCompletePacket////-----------------------------------------------------------------------------//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------//     ROUTING FUNCTIONS////  Simple functions to look at and set the out of memory//  alignment addresses.//staticNODE_ADDR ConvertRawAddressBytesToNodeAddress(char RawAddressBytes[]) {   // Done because the address bytes may be out of alignment   // on certain processors.      NODE_ADDR nodeAddress;   memcpy(&nodeAddress, RawAddressBytes, sizeof(NODE_ADDR));   return nodeAddress;}staticvoid SetRawAddressBytes(NODE_ADDR nodeAddress, char RawAddressBytes[]) {   // Done because the address bytes may be out of alignment   // on certain processors.      memcpy(RawAddressBytes, &nodeAddress, sizeof(NODE_ADDR));}//// FUNCTION  SourceRouteThePacket()//// PURPOSE   Find the next hop in the source route and send the//           packet.  // staticvoid SourceRouteThePacket(GlomoNode *node, Message *msg) {   IpOptionsHeaderType* ipOptions =       IpHeaderSourceRouteOptionField((IpHeaderType*)msg->packet);     if (ipOptions->ptr < ipOptions->len) {           // Extract Next Address       // The definition of "ptr" seems to number 1 as the       // first byte of the the options field.              char* routeRawAddressBytes = (char*)ipOptions + ipOptions->ptr - 1;               NODE_ADDR nextHop =          ConvertRawAddressBytesToNodeAddress(routeRawAddressBytes);            // Record Route (Replace next address with this node's address).            ipOptions->ptr += sizeof(NODE_ADDR);      NetworkIpSendPacketToMacLayer(          node, msg, DEFAULT_INTERFACE, nextHop);   } else {      assert(FALSE); abort();            /* Drop it, strange */            GLOMO_MsgFree(node, msg);   }//if//}       //// FUNCTION  RouteThePacketUsingLookupTable()//// PURPOSE   Tries to route and send the packet using the "forwarding//           lookup table. // staticvoid RouteThePacketUsingLookupTable(GlomoNode *node, Message *msg) {   GlomoNetworkIp* ipLayer = (GlomoNetworkIp *)node->networkData.networkVar;   IpHeaderType *ipHeader = (IpHeaderType *) msg->packet;   InterfaceIdType interfaceId;   NODE_ADDR nextHop;   NetworkGetInterfaceAndNextHopFromForwardingTable(node, ipHeader->ip_dst,      &interfaceId, &nextHop);   if (nextHop == NETWORK_UNREACHABLE) {      ipLayer->stats.numNetworkUnreachableDrops++;      GLOMO_MsgFree(node, msg);      return;    }   NetworkIpSendPacketToMacLayer(node, msg, interfaceId, nextHop);}//// FUNCTION  RoutePacketAndSendToMac()//// PURPOSE   Figure out the next hop in the route and send the packet.//           First the "routing function" is checked and if that fails//           the default source route or lookup table route is used.// staticvoid RoutePacketAndSendToMac(GlomoNode *node, Message *msg) {   GlomoNetworkIp *ipLayer = (GlomoNetworkIp *)node->networkData.networkVar;   IpHeaderType *ipHeader = (IpHeaderType *) msg->packet;   //   // Check if its a broadcast.   //      if (ipHeader->ip_dst == ANY_DEST) {      NetworkIpSendPacketToMacLayer(node, msg, DEFAULT_INTERFACE, ANY_DEST);   } else {      // First Try to route with the routing protocol supplied routing      // function.  If the function doesn't exists or      // fails to find a route, then try standard lookup table      // or source routing.            BOOL PacketWasRouted = FALSE;         if (ipLayer->routerFunction != NULL) {         (ipLayer->routerFunction)(            node, msg, ipHeader->ip_dst, &PacketWasRouted);      }//if//            if (!PacketWasRouted) {         if (IpHeaderHasSourceRoute(ipHeader)) {            SourceRouteThePacket(node, msg);         } else {            RouteThePacketUsingLookupTable(node, msg);         }//if//      }//if//   }//if//}//RoutePacketAndSendToMac////-----------------------------------------------------------------------------//       FRAGMENTATION ROUTINES//// FUNCTION    NetworkIpSendPacketToMacLayer()//// PURPOSE     Sends a IP packet to the MAC layer. If the packet is too//             large it is fragmented.  The next hop's node address//             is specified in "nextHop".     void NetworkIpSendPacketToMacLayer(        GlomoNode* node,    Message* msg, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -