Example #1
0
        /// <summary>
        /// Removes a queued frame from the output FIFO and transmits it.
        /// </summary>
        void EmptySendFifo()
        {
            var frame = sendFifo.Dequeue();

            WriteMac("Outputting an Ethernet frame for " + frame.Destination + ".");
            emptyingFifo = true;
            // Serialize the Ethernet frame object into a sequence of bytes.
            var frameBytes = frame.Serialize();

            // Call into the physical layer to put the bytes "on the wire".
            Transmit(frameBytes);
        }
Example #2
0
 /// <summary>
 /// Processes the queue of incoming IP packets.
 /// </summary>
 void ProcessPackets()
 {
     try {
         var tuple  = inputQueue.Dequeue();
         var packet = tuple.Item1;
         var ifc    = tuple.Item2;
         packet.TimeToLive--;
         // Drop packet and send "TTL Expired"-ICMP back to packet originator.
         if (packet.TimeToLive == 0)
         {
             if (packet.Protocol != IpProtocol.Icmp)
             {
                 SendIcmp(ifc, packet.Source, IcmpPacket.TimeExceeded(packet));
             }
             return;
         }
         // Incrementally update the checksum.
         var sum = (uint)(packet.Checksum + 0x01);
         packet.Checksum = (ushort)(sum + (sum >> 16));
         if (IsPacketForUs(packet))
         {
             // See if we have all parts and can reassemble the original packet.
             if (IsFragment(packet))
             {
                 ReassemblePacket(packet);
             }
             else
             {
                 // If it's not a fragment, hand the data up to the transport layer.
                 HandUp(packet.Data, packet.Protocol);
             }
         }
         else
         {
             // If it's not for us, see if we can forward it to its destination.
             RoutePacket(packet, ifc);
         }
     } finally {
         // Nodal processing delay is the time it takes on average to process
         // a single IP packet.
         if (inputQueue.Count > 0)
         {
             Simulation.Callback(nodalProcessingDelay, ProcessPackets);
         }
     }
 }