Beispiel #1
0
 public void ReceiveFrame(EthernetFrame frame)
 {
     if(deviceFile == null)
     {
         return;
     }
     var bytes = frame.Bytes;
     try
     {
         // since the file reader operations are buffered, we have to immediately flush writes
         deviceFile.Write(bytes, 0, bytes.Length);
         deviceFile.Flush();
     }
     catch(IOException)
     {
         if(networkInterface.OperationalStatus != OperationalStatus.Up)
         {
             this.DebugLog("Interface is not up during write, frame dropped.");
         }
         else
         {
             throw;
         }
     }
     this.NoisyLog("Frame of length {0} sent to host.", frame.Length);
 }
Beispiel #2
0
 /// <summary>
 /// Is invoked by the parent interface to transmit a frame to any connected endpoint.
 /// </summary>
 /// <param name='frame'>
 /// Network frame.
 /// </param>
 public void TransmitFrameFromInterface(EthernetFrame frame)
 {
     var transmit = TransmitFromParentInterface;
     if(transmit != null)
     {
         transmit(this, frame);
     }
 }
Beispiel #3
0
 private void SendFrameToInterface(EthernetFrame frame)
 {
     var receive = ReceiveOnParentInterface;
     if(receive != null)
     {
         receive(this, frame);
     }
     Parent.ReceiveFrame(frame);
 }
Beispiel #4
0
 void ReceiveFrameInner(EthernetFrame frame)
 {
     if(!frame.DestinationMAC.Value.IsBroadcast && frame.DestinationMAC.Value != MAC)
     {
         return;
     }
     lock(packetQueue)
     {
         packetQueue.Enqueue(frame);
         SignalInterrupt();
     }
 }
Beispiel #5
0
 public void ReceiveFrame(EthernetFrame frame)
 {
     // TODO: non blocking
     if(stream == null)
     {
         return;
     }
     var handle = GCHandle.Alloc(frame.Bytes, GCHandleType.Pinned);
     try
     {
         var result = LibC.WriteData(stream.Handle, handle.AddrOfPinnedObject(), frame.Length);
         if(result == 0)
         {
             this.Log(LogLevel.Error,
                 "Error while writing to TUN interface: {0}.", result);
         }
     }
     finally
     {
         handle.Free();
     }
 }
Beispiel #6
0
 private async Task ReadPacketAsync()
 {
     var buffer = new byte[Mtu];
     while(!cts.IsCancellationRequested)
     {
         try
         {
             if(await deviceFile.ReadAsync(buffer, 0, buffer.Length, cts.Token) > 0)
             {
                 var frame = new EthernetFrame(buffer, true);
                 Link.TransmitFrameFromInterface(frame);
                 this.NoisyLog("Frame of length {0} received from host.", frame.Length);
             }
         }
         catch(IOException)
         {
             if(networkInterface.OperationalStatus != OperationalStatus.Up)
             {
                 this.NoisyLog("I/O exception while interface is not up, waiting {0}s.", Misc.NormalizeDecimal(GracePeriod.TotalSeconds));
                 // probably the interface is not opened yet
                 await Task.Delay(GracePeriod);
             }
             else
             {
                 throw;
             }
         }
     }
 }
Beispiel #7
0
 private void ReceiveFrameInner(EthernetFrame frame)
 {
     lock(sync)
     {
         this.Log(LogLevel.Noisy, "Received packet len {0}", frame.Length);
         if((registers.Control & (1u << 2)) == 0)
         {
             this.Log(LogLevel.Debug, "Receiver not enabled, dropping frame.");
             return;
         }
         bool interrupt = false;
         rxBufferDescriptor rxBD = new rxBufferDescriptor(machine.SystemBus);
         rxBD.Fetch(registers.RxQueueBaseAddr);
         if(!rxBD.Ownership)//if we could write data to this BD
         {
             interrupt = false;
             rxBD.Ownership = true;
             rxBD.StartOfFrame = true;
             rxBD.EndOfFrame = true;
             rxBD.Length = (ushort)frame.Length;
             machine.SystemBus.WriteBytes(frame.Bytes, rxBD.BufferAddress);
             rxBD.WriteBack();
             if(rxBD.Wrap)
             {
                 registers.RxQueueBaseAddr = rxBufferBase;
             }
             else
             {
                 registers.RxQueueBaseAddr += 8;
             }
             registers.RxStatus |= 1u << 1;
             if((registers.InterruptMask & (1u << 1)) == 0)
             {
                 registers.InterruptStatus |= 1u << 1;
                 interrupt = true;
             }
             if(interrupt)
             {
                 IRQ.Set();
             }
         }
     }
 }
Beispiel #8
0
        private void SendFrames()
        {
            lock(sync)
            {
                txBufferDescriptor txBD = new txBufferDescriptor(machine.SystemBus);
                bool interrupt = false;
                List <byte> packet = new List<byte>();
            
            
                txBD.Fetch(registers.TxQueueBaseAddr);
                       
                while(!txBD.Used)
                {
                    while(!txBD.Last)
                    {
                        packet.AddRange(machine.SystemBus.ReadBytes(txBD.Word0, txBD.Length));
                        txBD.Used = true;
                        txBD.WriteBack();
                        if(txBD.Wrap)
                        {
                            registers.TxQueueBaseAddr = txBufferBase;
                        }
                        else
                        {
                            registers.TxQueueBaseAddr += 8;
                        }
                        txBD.Fetch(registers.TxQueueBaseAddr);
                    }
                    interrupt = false;
                    txBD.Used = true;
                
                    packet.AddRange(machine.SystemBus.ReadBytes(txBD.Word0, txBD.Length));
                
                    if((registers.DMAConfig & 1u << 11) != 0)//if checksum offload enable
                    {
                        if((packet[14] & 0xF0) == 0x40) //IP packet
                        {
                            ushort cksum;
                            IPHeaderLength = (ushort)((packet[14] & 0x0F) * 4);
                            if(packet[23] == 0x06) // TCP packet
                            {
                            
                                IPpacket tcpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.TCP);
                                tcpPacket.ReadFromBuffer(packet.ToArray());
                                cksum = tcpPacket.GetChecksum();
                                cksum -= 1;
                                packet[MACHeaderLegth + IPHeaderLength + 16] = (byte)((cksum >> 8) & 0xFF);
                                packet[MACHeaderLegth + IPHeaderLength + 17] = (byte)((cksum) & 0xFF);
                            }
                            else if(packet[23] == 0x11) // UDP packet
                            {
                                IPpacket udpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.UDP);
                                udpPacket.ReadFromBuffer(packet.ToArray());
                                cksum = udpPacket.GetChecksum();
                                cksum -= 1;
                                packet[MACHeaderLegth + IPHeaderLength + 6] = (byte)((cksum >> 8) & 0xFF);
                                packet[MACHeaderLegth + IPHeaderLength + 7] = (byte)((cksum) & 0xFF);
                            }
                        }
                    }

                    if(Link.IsConnected)
                    {
                        var frame = new EthernetFrame(packet.ToArray());
                        this.Log(LogLevel.Noisy, "Sending packet length {0}", packet.ToArray().Length);
                        Link.TransmitFrameFromInterface(frame);
                    }
                
                    txBD.WriteBack();
                
                    if(txBD.Wrap)
                    {
                        registers.TxQueueBaseAddr = txBufferBase;
                    }
                    else
                    {
                        registers.TxQueueBaseAddr += 8;
                    }
                
                    registers.TxStatus |= 1u << 5; //tx complete
                    txBD.Fetch(registers.TxQueueBaseAddr);
                
                    if(txBD.Used)
                    {
                        registers.TxStatus |= 0x01;
                        if((registers.InterruptMask & (1u << 3)) == 0)
                        {
                            registers.InterruptStatus |= 1u << 3;
                            interrupt = true;
                        }
                    }
                
                    if((registers.InterruptMask & (1u << 7)) == 0)
                    {
                        registers.InterruptStatus |= 1u << 7;
                        interrupt = true;
                    
                    }
                
                    if(interrupt)
                    {
                        IRQ.Set();
                    }
            
                }
            }
        }
Beispiel #9
0
 private void Finished()
 {
     if(mode == Mode.WaitingForPacket)
     {
         this.DebugLog("Packet received, LEN {7} {0:x} {1:x} {2:x} {3:x} (...) {4:x} {5:x} {6:x}", request[0], request[1], request[2], request[3], request[currentLength - 5], request[currentLength - 4], request[currentLength - 3], currentLength);
         var frame = new byte[currentLength];
         Array.Copy(request, 0, frame, 0, currentLength);
         var ethernetFrame = new EthernetFrame(frame);
         Link.TransmitFrameFromInterface(ethernetFrame);
         mode = Mode.Standard;
         currentLength = 4;
         transmissionEnded = true;
         if(interruptAfterTransmision)
         {
             SignalInterrupt();
         }
     }
     if(mode == Mode.SendingPacket)
     {
         mode = Mode.Standard;
         currentLength = 4;
         lock(packetQueue)
         {
             if(packetQueue.Count > 0)
             {
                 SignalInterrupt();
             }
         }
     }
     if(mode == Mode.Special)
     {
         currentLength = 4;
         mode = Mode.Standard;
         return;
     }
     switch(lastPacketType)
     {
     case 0xC0:
         mode = Mode.WaitingForPacket;
         var encodedLength = request[3] + (request[4] << 8);
         this.DebugLog("Encoded length is 0x{0:X}.", encodedLength);
         currentLength = Align(encodedLength + 1 + 1);
         transmissionEnded = false;
         break;
     case 0xF:
         lastPacketType = 0;
         break;
     }
 }
Beispiel #10
0
        //   private byte[] macAddress = new byte[] {0,0,0,0,0,0};
        #endregion
        #region USB descriptors

        private void ReceiveFrameInner(EthernetFrame frame)
        {
            lock(sync)
            {
                if(!frame.DestinationMAC.Value.IsBroadcast && frame.DestinationMAC.Value != MAC)
                {
                    return;
                }
                rxPacketQueue.Enqueue(frame);
            }
        }
Beispiel #11
0
 public void ReceiveFrame(EthernetFrame frame)//when data is send to us
 {
     machine.ReportForeignEvent(frame, ReceiveFrameInner);
 }
 public void ReceiveFrame (EthernetFrame frame)
 {
     throw new NotImplementedException ();
 }
Beispiel #13
0
 private void ReceiveFrameInner(EthernetFrame frame)
 {
     if((registers.Control & (1u << 1)) == 0)
     {
         //if receiving is disabled discard packet
         return;
     }
     var rd = new receiveDescriptor(machine.SystemBus);
     rd.Fetch(receiveDescriptorBase | receiveDescriptorOffset);
     if(!rd.Enable)
     {
         //if receive descritptor disabled discard packet
         return;
     }
     machine.SystemBus.WriteBytes(frame.Bytes, (long)rd.PacketAddress);
     registers.Status = 1u << 2;
     if(rd.Wrap)
     {
         receiveDescriptorOffset = 0;
     }
     else
     {
         if(receiveDescriptorOffset != 0x3f8)
         {
             receiveDescriptorOffset += 8;
         }
         else
         {
             receiveDescriptorOffset = 0;
         }
     }
     if(rd.InterruptEnable && ((registers.Control & (1u << 3)) != 0))
     {
         registers.Status |= 1u << 2;
         this.IRQ.Set();
         this.IRQ.Unset();
     }
     rd.Length = (uint)frame.Length;
     rd.Enable = false;
     rd.Wrap = false;
     rd.WriteBack();
 }
Beispiel #14
0
 private void ReceiveFrameInner(EthernetFrame frame)
 {
     /*if(machine.ElapsedTime < TimeSpan.FromSeconds(30))
     {
         return;
     }*/
     lock(receiveLock)
     {
         if((dmaStatus & ReceiveStatus) != 0)
         {
             queue.Enqueue(frame);
             return;
         }
         if(!packetSent)
         {
             this.Log(LogLevel.Error, "Dropping - no packets sent.");
             return;
         }
         if(frame.Length < 14)
         {
             this.Log(LogLevel.Error, "DROPPING - packet too short.");
             return;
         }
         if(this.machine.IsPaused)
         {
             this.Log(LogLevel.Debug, "DROPPING - cpu is halted.");
             return;
         }
         var destinationMac = frame.DestinationMAC.Value;
         if(!destinationMac.IsBroadcast && !destinationMac.Equals(MAC))
         {
             this.Log(LogLevel.Debug, "DROPPING - not for us.");
             return;
         }
         if((dmaInterruptEnable & (ReceiveStatus)) == 0)
         {
             this.Log(LogLevel.Debug, "DROPPING - rx irq is turned off.");
             return;
         }
         this.Log(LogLevel.Noisy, Misc.DumpPacket(frame, false, machine));
         if(dmaReceiveDescriptorListAddress < 0x20000000)
         {
             // TODO: not in ram
             this.Log(LogLevel.Error, "DROPPING - descriptor is not valid.");
             return;
         }
         var written = 0;
         var first = true;
         var receiveDescriptor = new RxDescriptor(machine.SystemBus);
         receiveDescriptor.Fetch(dmaReceiveDescriptorListAddress);
         if(receiveDescriptor.IsUsed)
         {
             this.Log(LogLevel.Error, "DROPPING  - descriptor is used.");
             return;
         }
         this.Log(LogLevel.Noisy, "DESCRIPTOR ADDR1={0:X}, ADDR2={1:X}", receiveDescriptor.Address1, receiveDescriptor.Address2);
         while(!receiveDescriptor.IsUsed)
         {
             if(receiveDescriptor.Address1 < 0x20000000)
             {
                 this.Log(LogLevel.Error, "Descriptor points outside of ram, aborting... This should not happen!");
                 break;
             }
             receiveDescriptor.IsUsed = true;
             receiveDescriptor.IsFirst = first;
             first = false;
             var howManyBytes = Math.Min(receiveDescriptor.Buffer1Length, frame.Length - written);
             var toWriteArray = new byte[howManyBytes];
             var bytes = frame.Bytes;
             Array.Copy(bytes, written, toWriteArray, 0, howManyBytes);
             machine.SystemBus.WriteBytes(toWriteArray, receiveDescriptor.Address1);
             written += howManyBytes;
             //write second buffer
             if(frame.Length - written > 0 && !receiveDescriptor.IsNextDescriptorChained)
             {
                 howManyBytes = Math.Min(receiveDescriptor.Buffer2Length, frame.Length - written);
                 toWriteArray = new byte[howManyBytes];
                 Array.Copy(bytes, written, toWriteArray, 0, howManyBytes);
                 machine.SystemBus.WriteBytes(toWriteArray, receiveDescriptor.Address2);
                 written += howManyBytes;
             }
             if(frame.Length - written <= 0)
             {
                 receiveDescriptor.IsLast = true;
                 this.NoisyLog("Setting descriptor length to {0}", (uint)frame.Length + 4);
                 receiveDescriptor.FrameLength = (uint)frame.Length + 4;
                 //with CRC
             }
             this.NoisyLog("Writing descriptor at 0x{6:X}, first={0}, last={1}, written {2} of {3}. next_chained={4}, endofring={5}", receiveDescriptor.IsFirst, receiveDescriptor.IsLast, written, frame.Length, receiveDescriptor.IsNextDescriptorChained, receiveDescriptor.IsEndOfRing, dmaReceiveDescriptorListAddress);
             receiveDescriptor.WriteBack();
             if(!receiveDescriptor.IsNextDescriptorChained)
             {
                 dmaReceiveDescriptorListAddress += 8;
             }
             else if(receiveDescriptor.IsEndOfRing)
             {
                 dmaReceiveDescriptorListAddress = dmaReceiveDescriptorListAddressBegin;
             }
             else
             {
                 dmaReceiveDescriptorListAddress = receiveDescriptor.Address2;
             }
             if(frame.Length - written <= 0)
             {
                 if((dmaInterruptEnable & (ReceiveStatus)) != 0)// receive interrupt
                 {
                     dmaStatus |= ReceiveStatus;
                     IRQ.Set();
                 }
                 else
                 {
                     this.DebugLog("Exiting but not scheduling an interrupt!");
                 }
                 break;
             }
             receiveDescriptor.Fetch(dmaReceiveDescriptorListAddress);
         }
         this.DebugLog("Packet of length {0} delivered.", frame.Length);
         if(written < frame.Length)
         {
             this.Log(LogLevel.Error, "Delivered only {0} from {1} bytes!", written, frame.Length);
         }
     }
 }
Beispiel #15
0
 /// <summary>
 /// Is invoked by a connected endpoint to transmit a frame to the parent interface.
 /// </summary>
 /// <param name="frame">
 /// Network frame.
 /// </param> 
 public void ReceiveFrameOnInterface(EthernetFrame frame)
 {
     SendFrameToInterface(frame);
 }
Beispiel #16
0
        private void TransmitLoop(CancellationToken token)
        {
            while(true)
            {
                byte[] buffer = null;
                if(stream == null)
                {
                    return;
                }
                try
                {
                    buffer = LibC.ReadDataWithTimeout(stream.Handle, MTU, 1000, () => token.IsCancellationRequested);
                }
                catch(ArgumentException)
                {
                    // stream was closed
                    return;
                }
                catch(ObjectDisposedException)
                {
                    return;
                }

                if(token.IsCancellationRequested)
                {
                    return;
                }
                if(buffer == null || buffer.Length == 0)
                {
                    continue;
                }
                var ethernetFrame = new EthernetFrame(buffer, true);
                Link.TransmitFrameFromInterface(ethernetFrame);
            }
        }
Beispiel #17
0
 private void ReceiveFrameInner(EthernetFrame frame)
 {
     lock(lockObj)
     {
         this.NoisyLog("Received frame on MAC {0}. Frame destination MAC is {1}", this.MAC.ToString(), frame.DestinationMAC);
         var size = frame.Length;
         var isEven = (size & 1) == 0;
         if((receiveControl & ReceiveEnabled) == 0 || (receiveControl & SoftwareReset) != 0)
         {
             //Drop if reset is on or receiving is not enabled.
             return;
         }
         var packetSize = Math.Max(64, size & ~1);
         //64 is the minimal length
         packetSize += 6;
         var withCRC = (receiveControl & StripCRC) == 0;
         if(withCRC)
         {
             packetSize += 4;
         }
         if(packetSize > MaxPacketSize)
         {
             //Maybe we should react to overruns. Now we just drop.
             return;
         }
         byte whichPacket;
         if(!TryAllocatePacket(out whichPacket))
         {
             return;
         }
         rxFifo.Enqueue(whichPacket);
         var status = 0;
         if(size > 1518)
         {
             status |= 0x0800;
         }
         if(!isEven)
         {
             status |= 0x1000;
         }
         var currentBuffer = memoryBuffer[whichPacket];
         currentBuffer.Data[0] = (byte)(status & 0xff);
         currentBuffer.Data[1] = (byte)(status >> 8);
         currentBuffer.Data[2] = (byte)(packetSize & 0xff);
         currentBuffer.Data[3] = (byte)(packetSize >> 8);
         var frameBytes = frame.Bytes;
         for(int i = 0; i < (size & ~1); i++)
         {
             currentBuffer.Data[4 + i] = frameBytes[i];
         }
         //Pad with 0s
         if(size < 64)
         {
             var pad = 64 - size;
             if(!isEven)
             {
                 for(int i = 0; i < pad; i++)
                 {
                     currentBuffer.Data[4 + i + size] = 0;
                 }
             }
             else
             {
                 for(int i = 0; i < pad; i++)
                 {
                     currentBuffer.Data[4 + i + size + 1] = 0;
                 }
             }
             size = 64;
         }
         if(withCRC)
         {
             this.Log(LogLevel.Warning, "CRC not implemented.");
         }
         if(!isEven)
         {
             //TODO: For a short, odd-length packet, will it work? Should it not be written before?
             currentBuffer.Data[packetSize - 2] = frameBytes[size - 1];
             currentBuffer.Data[packetSize - 1] = 0x60;
         }
         else
         {
             currentBuffer.Data[packetSize - 1] = 0x40;
         }
         interruptStatus |= RxInterrupt;
         Update();
     }
 }
Beispiel #18
0
        public byte Transmit()
        {
            lock(lockObj)
            {
                int len;
                byte whichPacket;

                if((transmitControl & TransmitEnabled) == 0)
                {
                    return 0;
                }
                if(txFifo.Count == 0)
                {
                    return 0;
                }
                while(txFifo.Count > 0)
                {
                    whichPacket = txFifo.Dequeue();
                    var currentBuffer = memoryBuffer[whichPacket];
                    len = currentBuffer.Data[2];
                    len |= currentBuffer.Data[3] << 8;
                    len -= 6;
              
                    byte [] indata = new byte[len];

                    for(int j=0; j<len; j++)
                    {
                        indata[j] = currentBuffer.Data[j + 4];
                    }

                    if((control & ControlAutorelease) != 0)
                    {
                        currentBuffer.IsAllocated = false;
                    }
                    else
                    {
                        sentFifo.Enqueue((byte)whichPacket);
                    }
                    var frame = new EthernetFrame(indata);
                    Link.TransmitFrameFromInterface(frame);
                }
                Update();
                return 0;
            }
        }
Beispiel #19
0
        private void SendFrames()
        {
            this.Log(LogLevel.Noisy, "Sending frame");
            var transmitDescriptor = new TxDescriptor(machine.SystemBus);
            var packetData = new List<byte>();

            transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            while(!transmitDescriptor.IsUsed)
            {
                transmitDescriptor.IsUsed = true;
                this.Log(LogLevel.Noisy, "GOING TO READ FROM {0:X}, len={1}", transmitDescriptor.Address1, transmitDescriptor.Buffer1Length);
                packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address1, transmitDescriptor.Buffer1Length));
                if(!transmitDescriptor.IsNextDescriptorChained)
                {
                    packetData.AddRange(machine.SystemBus.ReadBytes(transmitDescriptor.Address2, transmitDescriptor.Buffer2Length));
                }

                transmitDescriptor.WriteBack();

                if(transmitDescriptor.IsEndOfRing)
                {
                    dmaTransmitDescriptorListAddress = dmaTransmitDescriptorListAddressBegin;
                }
                else if(transmitDescriptor.IsNextDescriptorChained)
                {
                    dmaTransmitDescriptorListAddress = transmitDescriptor.Address2;
                }
                else
                {
                    dmaTransmitDescriptorListAddress += 8;
                }
                if(transmitDescriptor.IsLast)
                {
                    this.Log(LogLevel.Noisy, "Sending frame of {0} bytes.", packetData.Count);
                    if(Link.IsConnected)
                    {
                        var frame = new EthernetFrame(packetData.ToArray());

                        if(transmitDescriptor.ChecksumInstertionControl > 0)
                        {
                            this.Log(LogLevel.Noisy, "Calculating checksum (mode {0}).", transmitDescriptor.ChecksumInstertionControl);
                            if(transmitDescriptor.ChecksumInstertionControl == 1)
                            {
                                //IP only
                                frame.FillWithChecksums(supportedEtherChecksums, null);
                            }
                            else
                            {
                                //IP and payload
                                frame.FillWithChecksums(supportedEtherChecksums, supportedIPChecksums);
                            }
                        }
                        this.Log(LogLevel.Debug, Misc.DumpPacket(frame, true, machine));

                        packetSent = true;
                        Link.TransmitFrameFromInterface(frame);
                    }
                }
                transmitDescriptor.Fetch(dmaTransmitDescriptorListAddress);
            }

            //set TransmitBufferUnavailable
            dmaStatus |= TransmitBufferUnavailableStatus;
            if((dmaInterruptEnable & (StartStopTransmission)) == 0)
            {
                IRQ.Set();
            }
            this.Log(LogLevel.Noisy, "Frame sent.");
        }
Beispiel #20
0
 public void ReceiveFrame(EthernetFrame frame)
 {
     machine.ReportForeignEvent(frame, ReceiveFrameInner);
 }
Beispiel #21
0
        public void WriteDataBulk(USBPacket packet)
        {
            if(packet.data == null)
                return;

            byte[] packetToSend;
            if(packet.data[5] != 64)
            {
                packetToSend = new byte[packet.data.Length - 8];
                Array.Copy(packet.data, 8, packetToSend, 0, packetToSend.Length);
            }
            else
            {
                packetToSend = new byte[packet.data.Length - 12];
                Array.Copy(packet.data, 12, packetToSend, 0, packetToSend.Length);

                if((packetToSend[14] & 0xF0) == 0x40) //IP packet
                {
                    ushort cksum;
                    IPHeaderLength = (ushort)((packetToSend[14] & 0x0F) * 4);
                    if(packetToSend[23] == 0x06) // TCP packet
                    {

                        IPpacket tcpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.TCP);
                        tcpPacket.ReadFromBuffer(packetToSend);
                        cksum = tcpPacket.GetChecksum();
                        cksum -= 1;
                        packetToSend[MACHeaderLegth + IPHeaderLength + 16] = (byte)((cksum >> 8) & 0xFF);
                        packetToSend[MACHeaderLegth + IPHeaderLength + 17] = (byte)((cksum) & 0xFF);
                    }
                    else if(packetToSend[23] == 0x11) // UDP packet
                    {
                        IPpacket udpPacket = new IPpacket(IPHeaderLength, IPpacket.PacketType.UDP);
                        udpPacket.ReadFromBuffer(packetToSend);
                        cksum = udpPacket.GetChecksum();
                        cksum -= 1;
                        packetToSend[MACHeaderLegth + IPHeaderLength + 6] = (byte)((cksum >> 8) & 0xFF);
                        packetToSend[MACHeaderLegth + IPHeaderLength + 7] = (byte)((cksum) & 0xFF);
                    }
                }

            }

            var frame = new EthernetFrame(packetToSend);
            Link.TransmitFrameFromInterface(frame);
        }
Beispiel #22
0
        private void transmitFrame()
        {
            var td = new transmitDescriptor(machine.SystemBus);
            td.Fetch(transmitDescriptorBase | transmitDescriptorOffset);

            if(!td.Enable)
            {
                return; //if decriptor is disabled there is nothing to send (just return)
            }

            var packet = new EthernetFrame(machine.SystemBus.ReadBytes((long)td.PacketAddress, (int)td.Length));

            if(Link.IsConnected)
            {
                this.Log(LogLevel.Info, "Sending packet length {0}", packet.Length);
                this.Log(LogLevel.Info, "Packet address = 0x{0:X}", td.PacketAddress);
                Link.TransmitFrameFromInterface(packet);
            }

            registers.Status |= 1u << 3;

            if(td.Wrap)
            {
                transmitDescriptorOffset = 0;
            }
            else
            {
                if(transmitDescriptorOffset != 0x3f8)
                {
                    transmitDescriptorOffset += 8;
                }
                else
                {
                    transmitDescriptorOffset = 0;
                }
            }

            if(td.InterruptEnable && ((registers.Control & (1u << 2)) != 0))
            {
                //if interrupts enabled
                registers.Status |= 1u << 3; //transmitter interrupt bit 
                this.IRQ.Set();
                this.IRQ.Unset();
            }

            td.Enable = false;
            td.Wrap = false;
            td.InterruptEnable = false;
            td.Length = 0;
            td.UnderrunError = false;
            td.AttemptLimitError = false;
            td.WriteBack();
           
        }
 public void ReceiveFrame(EthernetFrame frame)//when data is send to us
 {
     throw new NotImplementedException();
 }