Пример #1
0
        public EthernetFrame(NetPacket pkt)
        {
            _pkt = pkt;
            int offset = 0;
            NetLib.ReadByteArray(pkt.buffer, ref offset, 6, out DestinationMAC);
            //WriteLine("eth dst MAC :" + DestinationMAC[0] + ":" + DestinationMAC[1] + ":" + DestinationMAC[2] + ":" + DestinationMAC[3] + ":" + DestinationMAC[4] + ":" + DestinationMAC[5]);
            NetLib.ReadByteArray(pkt.buffer, ref offset, 6, out SourceMAC);
            //WriteLine("src MAC :" + SourceMAC[0] + ":" + SourceMAC[1] + ":" + SourceMAC[2] + ":" + SourceMAC[3] + ":" + SourceMAC[4] + ":" + SourceMAC[5]);

            hlen = 14; //(6+6+2)

            //NOTE: we don't have to worry about the Ethernet Frame CRC as it is not included in the packet

            DataLib.ReadUInt16(pkt.buffer, ref offset, out proto);
            switch (proto) //Note, Diffrent Edian
            {
                case (UInt16)EtherFrameType.NULL:
                    break;
                case (UInt16)EtherFrameType.IPv4:
                    _pl = new IP.IPPacket(this);
                    break;
                case (UInt16)EtherFrameType.ARP:
                    _pl = new ARP.ARPPacket(this);
                    break;
                case (UInt16)EtherFrameType.VLAN_TAGGED_FRAME:
                    //Error.WriteLine("VLAN-tagged frame (IEEE 802.1Q)");
                    throw new NotImplementedException();
                //break;
                default:
                    PSE.CLR_PSE_PluginLog.WriteLine(TraceEventType.Error, (int)DEV9LogSources.ETHFrame, "Unkown Ethernet Protocol " + proto.ToString("X4"));
                    break;
            }
        }
Пример #2
0
 public override bool Send(NetPacket pkt)
 {
     if (dhcpActive)
     {
         EthernetFrame eth = new EthernetFrame(pkt);
         if (eth.Protocol == (UInt16)EtherFrameType.IPv4)
         {
             IPPacket ipp = (IPPacket)eth.Payload;
             if (ipp.Protocol == (byte)IPType.UDP)
             {
                 UDP udppkt = (UDP)ipp.Payload;
                 if (udppkt.DestinationPort == 67)
                 {
                     dhcp.Send(udppkt);
                     return true;
                 }
             }
         }
     }
     return false;
 }
Пример #3
0
        public override bool Recv(ref NetPacket pkt)
        {
            if (dhcpActive)
            {
                IPPayload retDHCP = dhcp.Recv();
                if (retDHCP != null)
                {
                    IPPacket retIP = new IPPacket(retDHCP);
                    retIP.DestinationIP = new byte[] { 255, 255, 255, 255 };
                    retIP.SourceIP = DefaultDHCPConfig.DHCP_IP;

                    EthernetFrame ef = new EthernetFrame(retIP);
                    ef.SourceMAC = virturalDHCPMAC;
                    ef.DestinationMAC = ps2MAC;
                    ef.Protocol = (UInt16)EtherFrameType.IPv4;
                    pkt = ef.CreatePacket();
                    return true;
                }
            }
            return false;
        }
Пример #4
0
        public override bool Send(NetPacket pkt)
        {
            if (base.Send(pkt)) { return true; }
            //get_eth_protocol_hi(pkt.buffer);
            //get_eth_protocol_lo(pkt.buffer);
            //get_dest_eth_mac(pkt.buffer);
            //get_src_eth_mac(pkt.buffer);
            //get_dest_arp_mac(pkt.buffer,14);
            //get_src_arp_mac(pkt.buffer,14);
            //get_dest_arp_ip(pkt.buffer, 14);
            //get_dest_ip_ip(pkt.buffer, 14);

            EthernetFrame eth = null;

            if (!switched)
            {
                eth = new EthernetFrame(pkt);

                //If intercept DHCP, then get IP from DHCP process
                if (eth.Protocol == (UInt16)EtherFrameType.IPv4)
                {
                    ps2IP = ((IPPacket)eth.Payload).SourceIP;
                    //MAC
                }
                else if (eth.Protocol == (UInt16)EtherFrameType.ARP)
                {
                    ps2IP = ((ARPPacket)eth.Payload).SenderProtocolAddress;
                    //MAC
                    //Need to also set Host MAC (SenderProtocolAddress)
                    //Utils.memcpy(ref pkt.buffer, 14 + 8, host_mac, 0, 6); //ARP
                    SetSrcMAC_ARP(pkt.buffer, 14, hostMAC);
                }
                //Set Sorce mac to host_mac
                SetSrcMAC_Eth(pkt.buffer, hostMAC);
            }
            else //Switched
            {
                byte[] host_mac_pkt = new byte[pkt.size];
                Array.Copy(pkt.buffer, host_mac_pkt, pkt.size);
                //here we send a boadcast with both host_mac and ps2_mac
                //is destination address broadcast?
                if (Utils.memcmp(GetDestMAC_Eth(host_mac_pkt), 0, broadcastMAC, 0, 6))
                {
                    //Set Dest to host mac
                    SetDestMAC_Eth(host_mac_pkt, hostMAC);
                    PcapSendIO(host_mac_pkt, pkt.size);
                }
            }

            if (PcapSendIO(pkt.buffer, pkt.size))
            {
                return false;
            }
            else
            {
                return true;
            }
        }
Пример #5
0
        public override bool Recv(ref NetPacket pkt)
        {
            if (base.Recv(ref pkt)) { return true; }

            int size = PcapRecvIO(pkt.buffer, pkt.buffer.Length);

            if (size <= 0)
            {
                return false;
            }

            //Recive DHCP Intercept Packets

            if (!switched) //TEST
            {
                //Quick and dirty lightweight packet reader
                if (GetEthProtocolHI(pkt.buffer) == 0x08) //ARP or IP
                {
                    if (GetEthProtocolLO(pkt.buffer) == 0x00) //IP
                    {
                        //Compare DEST IP in IP with PS2_IP, if match, change DEST MAC to PS2_MAC
                        //if (Utils.memcmp(pkt.buffer, 14 + 16, ps2_ip, 0, 4))
                        //{
                        //    Utils.memcpy(ref pkt.buffer, 0, ps2_mac, 0, 6); //ETH
                        //}
                        if (Utils.memcmp(GetDestIP_IP(pkt.buffer, 14), 0, ps2IP, 0, 4))
                        {
                            SetDestMAC_Eth(pkt.buffer, ps2MAC); //ETH
                        }
                    }
                    else if (GetEthProtocolLO(pkt.buffer) == 0x06) //ARP
                    {
                        //Compare DEST IP in ARP with PS2_IP, if match, DEST MAC to PS2_MAC
                        //on both ARP and ETH Packet
                        if (Utils.memcmp(GetDestARP_IP(pkt.buffer, 14), 0, ps2IP, 0, 4))
                        {
                            //Utils.memcpy(ref pkt.buffer, 0, ps2_mac, 0, 6); //ETH
                            SetDestMAC_Eth(pkt.buffer, ps2MAC); //ETH
                            //Utils.memcpy(ref pkt.buffer, 14 + 18, ps2_mac, 0, 6); //ARP
                            SetDestMAC_ARP(pkt.buffer, 14, ps2MAC);
                        }
                    }
                }
            }

            if (!Verify(pkt, size))
            {
                return false;
            }

            pkt.size = size;
            return true;
        }
Пример #6
0
        public void RxProcess(ref NetPacket pk)
        {
            if (!RxFifoCanRx())
            {
                Log_Error("ERROR : !rx_fifo_can_rx at rx_process");
                return;
            }
            //smap_bd_t* pbd = ((smap_bd_t*)&dev9.dev9R[SMAP_BD_RX_BASE & 0xffff]) + dev9.rxbdi;
            int soff = (int)((DEV9Header.SMAP_BD_RX_BASE & 0xffff) + dev9.rxbdi * SMAP_bd.GetSize());
            SMAP_bd pbd = new SMAP_bd(dev9.dev9R, soff);

            int bytes = (pk.size + 3) & (~3);

            if (!((pbd.CtrlStat & DEV9Header.SMAP_BD_RX_EMPTY) != 0))
            {
                Log_Info("(!(pbd->ctrl_stat & SMAP_BD_RX_EMPTY))");
                Log_Info("Discarding " + bytes + " bytes (RX" + dev9.rxbdi + " not ready)");
                return;
            }

            int pstart = (dev9.rxFifoWrPtr) & 16383;
            int i = 0;
            while (i < bytes)
            {
                dev9.Dev9RxFifoWrite(pk.buffer[i++]);
                dev9.rxFifoWrPtr &= 16383;
            }
            lock (resetSentry)
            {
                //increase RXBD
                dev9.rxbdi++;
                dev9.rxbdi &= ((DEV9Header.SMAP_BD_SIZE / 8u) - 1u);

                //Fill the BD with info !
                pbd.Length = (ushort)pk.size;
                pbd.Pointer = (ushort)(0x4000 + pstart);
                unchecked //Allow -int to uint
                {
                    pbd.CtrlStat &= (ushort)~DEV9Header.SMAP_BD_RX_EMPTY;
                }

                //increase frame count
                lock (counterSentry)
                {
                    byte framecount = dev9.Dev9Ru8((int)DEV9Header.SMAP_R_RXFIFO_FRAME_CNT);
                    framecount++;
                    dev9.Dev9Wu8((int)DEV9Header.SMAP_R_RXFIFO_FRAME_CNT, framecount);
                }
            }
            //spams// emu_printf("Got packet, %d bytes (%d fifo)\n", pk->size,bytes);
            fireIntR = true;
            //DEV9._DEV9irq(DEV9Header.SMAP_INTR_RXEND, 0);//now ? or when the fifo is full ? i guess now atm
            //note that this _is_ wrong since the IOP interrupt system is not thread safe.. but nothing i can do about that
        }
Пример #7
0
        //tx_process
        private void TxProcess()
        {
            //Error.WriteLine("TX");
            //we loop based on count ? or just *use* it ?
            UInt32 cnt = dev9.Dev9Ru8((int)DEV9Header.SMAP_R_TXFIFO_FRAME_CNT);
            //spams// printf("tx_process : %d cnt frames !\n",cnt);

            NetPacket pk = new NetPacket();
            int fc = 0;
            for (fc = 0; fc < cnt; fc++)
            {
                //smap_bd_t *pbd= ((smap_bd_t *)&dev9.dev9R[SMAP_BD_TX_BASE & 0xffff])+dev9.txbdi;

                SMAP_bd pbd;
                pbd = new SMAP_bd(dev9.dev9R, (int)((DEV9Header.SMAP_BD_TX_BASE & 0xffff) + (SMAP_bd.GetSize() * dev9.txbdi)));

                if (!((pbd.CtrlStat & DEV9Header.SMAP_BD_TX_READY) != 0))
                {
                    Log_Error("ERROR : !pbd->ctrl_stat&SMAP_BD_TX_READY\n");
                    break;
                }
                if ((pbd.Length & 3) != 0)
                {
                    //spams// emu_printf("WARN : pbd->length not alligned %d\n",pbd->length);
                }

                if (pbd.Length > 1514)
                {
                    Log_Error("ERROR : Trying to send packet too big.\n");
                }
                else
                {
                    UInt32 _base = (UInt32)((pbd.Pointer - 0x1000) & 16383);
                    Log_Verb("Sending Packet from base " + _base.ToString("X") + ", size " + pbd.Length);
                    //The 1st packet we send should be base 0, size 1514
                    //spams// emu_printf("Sending Packet from base %x, size %d\n", base, pbd->length);

                    pk.size = pbd.Length;

                    if (!(pbd.Pointer >= 0x1000))
                    {
                        Log_Error("ERROR: odd , !pbd->pointer>0x1000 | 0x" + pbd.Pointer.ToString("X") + " " + pbd.Length.ToString());
                    }

                    if (_base + pbd.Length > 16384)
                    {
                        UInt32 was = 16384 - _base;
                        Utils.memcpy(ref pk.buffer, 0, dev9.txFifo, (int)_base, (int)was);
                        Utils.memcpy(ref pk.buffer, (int)was, dev9.txFifo, 0, (int)(pbd.Length - was)); //I thingk this was a bug in the original plugin
                        Log_Verb("Warped read, was=" + was + ", sz=" + pbd.Length + ", sz-was=" + (pbd.Length - was));
                    }
                    else
                    {
                        Utils.memcpy(ref pk.buffer, 0, dev9.txFifo, (int)_base, (int)pbd.Length);
                    }
                    adapter.net.TxPut(ref pk);
                }

                unchecked
                {
                    pbd.CtrlStat &= (UInt16)(~DEV9Header.SMAP_BD_TX_READY);
                }

                //increase TXBD
                dev9.txbdi++;
                dev9.txbdi &= (DEV9Header.SMAP_BD_SIZE / 8) - 1;

                //decrease frame count -- this is not thread safe
                //dev9Ru8(SMAP_R_TXFIFO_FRAME_CNT)--;
                dev9.Dev9Wu8((int)DEV9Header.SMAP_R_TXFIFO_FRAME_CNT, (byte)(dev9.Dev9Ru8((int)DEV9Header.SMAP_R_TXFIFO_FRAME_CNT) - 1));
            }

            //spams// emu_printf("processed %d frames, %d count, cnt = %d\n",fc,dev9Ru8(SMAP_R_TXFIFO_FRAME_CNT),cnt);
            //if some error/early exit signal TXDNV
            if (fc != cnt || cnt == 0)
            {
                Log_Error("WARN : (fc!=cnt || cnt==0) but packet send request was made oO..");
                dev9.DEV9irq(DEV9Header.SMAP_INTR_TXDNV, 0);
            }
            //if we actualy send something send TXEND
            if (fc != 0)
                dev9.DEV9irq(DEV9Header.SMAP_INTR_TXEND, 100);//now ? or when the fifo is empty ? i guess now atm
        }
Пример #8
0
        public NetPacket CreatePacket()
        {
            NetPacket nPK = new NetPacket();
            byte[] PLbytes = _pl.GetBytes;
            int counter = 0;

            //byte[] rawbytes = new byte[PLbytes.Length + hlen];
            nPK.size = PLbytes.Length + hlen;
            NetLib.WriteByteArray(ref nPK.buffer, ref counter, DestinationMAC);
            NetLib.WriteByteArray(ref nPK.buffer, ref counter, SourceMAC);
            //
            DataLib.WriteUInt16(ref nPK.buffer, ref counter, proto);
            //
            NetLib.WriteByteArray(ref nPK.buffer, ref counter, PLbytes);
            return nPK;
        }
Пример #9
0
        //sends the packet and deletes it when done (if successful).rv :true success
        public override bool Send(NetPacket pkt)
        {
            if (base.Send(pkt)) { return true; }

            int writen = 0;

            htapstream.Write(pkt.buffer, 0, pkt.size);
            htapstream.Flush();
            //return type is void, assume full write
            writen = pkt.size;

            if (writen != pkt.size)
            {
                Log_Error("incomplete Send");
                return false;
            }

            return true;
        }
Пример #10
0
        //gets a packet.rv :true success
        public override bool Recv(ref NetPacket pkt)
        {
            if (base.Recv(ref pkt)) { return true; }

            int readSize = 0;
            //bool result = false;
            try
            {
                readSize = htapstream.Read(pkt.buffer, 0, pkt.buffer.Length);
                //result = true;
            }
            catch (OperationCanceledException)
            {
                return false;
            }
            catch (Exception e)
            {
                Log_Error("Packet Recive Error :" + e.ToString());
                return false;
            }

            //Error.WriteLine(read_size);

            //Result would always be true, don't other checking it.

            //if (result)
            //{
            if (!Verify(pkt, readSize))
            {
                return false;
            }
            pkt.size = readSize;
            return true;
            //}
            //else
            //    return false;
        }