예제 #1
0
            //sends the packet and deletes it when done (if successful).rv :true success
            public override bool send(netHeader.NetPacket pkt)
            {
                int writen = 0;

                Console.Error.WriteLine("---------------------Sent Packet");
                PacketReader.EthernetFrame ef = new PacketReader.EthernetFrame(pkt);

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

                bool result = false;

                result = true;

                if (result)
                {
                    if (writen != pkt.size)
                    {
                        Console.Error.WriteLine("Incompleat Send " + Marshal.GetLastWin32Error());
                        return(false);
                    }

                    return(true);
                }
                else
                {
                    Console.Error.WriteLine("No Send Result" + Marshal.GetLastWin32Error());
                    return(false);
                }
            }
예제 #2
0
        public static void rx_process(ref netHeader.NetPacket pk)
        {
            if (!rx_fifo_can_rx())
            {
                Console.Error.WriteLine("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) + DEV9Header.dev9.rxbdi * DEV9Header.smap_bd.GetSize());

            DEV9Header.smap_bd pbd = new DEV9Header.smap_bd(DEV9Header.dev9.dev9R, soff);

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

            if (!((pbd.ctrl_stat & DEV9Header.SMAP_BD_RX_EMPTY) != 0))
            {
                Console.Error.WriteLine("ERROR (!(pbd->ctrl_stat & SMAP_BD_RX_EMPTY))");
                Console.Error.WriteLine("ERROR : Discarding " + bytes + " bytes (RX" + DEV9Header.dev9.rxbdi + " not ready)");
                return;
            }

            int pstart = (DEV9Header.dev9.rxfifo_wr_ptr) & 16383;
            int i      = 0;

            while (i < bytes)
            {
                DEV9Header.dev9_rxfifo_write(pk.buffer[i++]);
                DEV9Header.dev9.rxfifo_wr_ptr &= 16383;
            }
            lock (reset_sentry)
            {
                //increase RXBD
                DEV9Header.dev9.rxbdi++;
                DEV9Header.dev9.rxbdi &= (uint)((DEV9Header.SMAP_BD_SIZE / 8) - 1);

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

                //increase frame count
                lock (counter_sentry)
                {
                    byte framecount = DEV9Header.dev9Ru8((int)DEV9Header.SMAP_R_RXFIFO_FRAME_CNT);
                    framecount++;
                    DEV9Header.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
        }
예제 #3
0
            //gets a packet.rv :true success
            public override bool recv(ref netHeader.NetPacket pkt)
            {
                int  read_size = 0;
                bool result    = false;

                try {
                    read_size = htapstream.Read(pkt.buffer, 0, pkt.buffer.Length);
                    result    = true;
                }catch (Exception e)
                {
                    Console.WriteLine("Packet Recive Error :" + e.ToString());
                    return(false);
                }

                //Console.Error.WriteLine(read_size);

                if (result)
                {
                    //original memcmp returns 0 on perfect match
                    //the if statment check if !=0
                    byte[] eeprombytes = new byte[6];
                    for (int i = 0; i < 3; i++)
                    {
                        byte[] tmp = BitConverter.GetBytes(DEV9Header.dev9.eeprom[i]);
                        Utils.memcpy(ref eeprombytes, i * 2, tmp, 0, 2);
                    }
                    if ((Utils.memcmp(pkt.buffer, 0, eeprombytes, 0, 6) == false) & (Utils.memcmp(pkt.buffer, 0, broadcast_adddrrrr, 0, 6) == false))
                    {
                        //ignore strange packets
                        Console.Error.WriteLine("Dropping Strange Packet");
                        return(false);
                    }

                    if (Utils.memcmp(pkt.buffer, 6, eeprombytes, 0, 6) == true)
                    {
                        //avoid pcap looping packets
                        Console.Error.WriteLine("Dropping Looping Packet");
                        return(false);
                    }
                    pkt.size = read_size;
                    Console.Error.WriteLine("---------------------Recived Packet");
                    PacketReader.EthernetFrame ef = new PacketReader.EthernetFrame(pkt);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
예제 #4
0
        //rx thread
        static void NetRxThread()
        {
            netHeader.NetPacket tmp = new netHeader.NetPacket();
            while (RxRunning)
            {
                while (smap.rx_fifo_can_rx() && nif.recv(ref tmp))
                {
                    smap.rx_process(ref tmp);
                }

                System.Threading.Thread.Sleep(10);
            }

            //return 0;
        }
예제 #5
0
        //tx_process
        private static void tx_process()
        {
            //Console.Error.WriteLine("TX");
            //we loop based on count ? or just *use* it ?
            UInt32 cnt = DEV9Header.dev9Ru8((int)DEV9Header.SMAP_R_TXFIFO_FRAME_CNT);

            //spams// printf("tx_process : %d cnt frames !\n",cnt);

            netHeader.NetPacket pk = new netHeader.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;

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

                if (!((pbd.ctrl_stat & DEV9Header.SMAP_BD_TX_READY) != 0))
                {
                    Console.Error.WriteLine("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)
                {
                    Console.Error.WriteLine("ERROR : Trying to send packet too big.\n");
                }
                else
                {
                    UInt32 _base = (UInt32)((pbd.pointer - 0x1000) & 16383);
                    DEV9.DEV9_LOG("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))
                    {
                        DEV9.DEV9_LOG("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, DEV9Header.dev9.txfifo, (int)_base, (int)was);
                        Utils.memcpy(ref pk.buffer, (int)was, DEV9Header.dev9.txfifo, 0, (int)(pbd.length - was)); //I thingk this was a bug in the original plugin
                        Console.Error.WriteLine("Warped read, was=" + was + ", sz=" + pbd.length + ", sz-was=" + (pbd.length - was));
                    }
                    else
                    {
                        Utils.memcpy(ref pk.buffer, 0, DEV9Header.dev9.txfifo, (int)_base, (int)pbd.length);
                    }
                    net.tx_put(ref pk);
                }

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

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

                //decrease frame count -- this is not thread safe
                //dev9Ru8(SMAP_R_TXFIFO_FRAME_CNT)--;
                DEV9Header.dev9Wu8((int)DEV9Header.SMAP_R_TXFIFO_FRAME_CNT, (byte)(DEV9Header.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)
            {
                Console.Error.WriteLine("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
            }
        }
예제 #6
0
 public static void tx_put(ref netHeader.NetPacket pkt)
 {
     nif.send(pkt);
     //pkt must be copied if its not processed by here, since it can be allocated on the callers stack
 }
예제 #7
0
        //gets a packet.rv :true success
        public override bool recv(ref netHeader.NetPacket pkt)
        {
            //return false;
            bool result = false;


            if (ps2_mac == null)
            {
                ps2_mac = new byte[6];
                byte[] eeprombytes = new byte[6];
                for (int i = 0; i < 3; i++)
                {
                    byte[] tmp = BitConverter.GetBytes(DEV9Header.dev9.eeprom[i]);
                    Utils.memcpy(ref eeprombytes, i * 2, tmp, 0, 2);
                }
                Utils.memcpy(ref ps2_mac, 0, eeprombytes, 0, 6);
            }

            if (vRecBuffer.Count == 0)
            {
                List <string> DeadConnections = new List <string>();
                lock (sentry)
                {
                    foreach (string key in Connections.Keys) //ToDo better multi-connection stuff
                    {
                        IPPayload PL;
                        PL = Connections[key].recv();
                        if (!(PL == null))
                        {
                            IPPacket ippkt = new IPPacket(PL);
                            ippkt.DestinationIP = Connections[key].SourceIP;
                            ippkt.SourceIP      = Connections[key].DestIP;
                            EthernetFrame eF = new EthernetFrame(ippkt);
                            eF.SourceMAC      = gateway_mac;
                            eF.DestinationMAC = ps2_mac;
                            eF.Protocol       = (Int16)EtherFrameType.IPv4;
                            pkt    = eF.CreatePacket();
                            result = true;
                            break;
                        }
                        if (Connections[key].isOpen() == false)
                        {
                            Console.Error.WriteLine("Removing Closed Connection : " + key);
                            DeadConnections.Add(key);
                        }
                    }
                    foreach (string key in DeadConnections)
                    {
                        Connections.Remove(key);
                    }
                }
            }
            else
            {
                pkt = vRecBuffer[0];
                vRecBuffer.RemoveAt(0);
                result = true;
            }

            if (result)
            {
                byte[] eeprombytes = new byte[6];
                for (int i = 0; i < 3; i++)
                {
                    byte[] tmp = BitConverter.GetBytes(DEV9Header.dev9.eeprom[i]);
                    Utils.memcpy(ref eeprombytes, i * 2, tmp, 0, 2);
                }
                //original memcmp returns 0 on perfect match
                //the if statment check if !=0
                if ((Utils.memcmp(pkt.buffer, 0, eeprombytes, 0, 6) == false) & (Utils.memcmp(pkt.buffer, 0, broadcast_adddrrrr, 0, 6) == false))
                {
                    //ignore strange packets
                    Console.Error.WriteLine("Dropping Strange Packet");
                    return(false);
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #8
0
        //sends the packet and deletes it when done (if successful).rv :true success
        public override bool send(netHeader.NetPacket pkt)
        {
            bool result = false;

            PacketReader.EthernetFrame ef = new PacketReader.EthernetFrame(pkt);

            switch (ef.Protocol)
            {
            case (int)EtherFrameType.NULL:
                //Adapter Reset
                //TODO close all open connections
                break;

            case (int)EtherFrameType.IPv4:
                //Console.Error.WriteLine("IPv4");
                IPPacket ippkt = ((IPPacket)ef.Payload);
                if (ippkt.VerifyCheckSum() == false)
                {
                    Console.Error.WriteLine("IP packet with bad CSUM");
                }
                if (ippkt.Payload.VerifyCheckSum(ippkt.SourceIP, ippkt.DestinationIP) == false)
                {
                    Console.Error.WriteLine("IP packet with bad Payload CSUM");
                }

                string Key = (ippkt.DestinationIP[0]) + "." + (ippkt.DestinationIP[1]) + "." + (ippkt.DestinationIP[2]) + "." + ((UInt64)ippkt.DestinationIP[3])
                             + "-" + (ippkt.Protocol);

                switch (ippkt.Protocol)     //(Prase Payload)
                {
                case (byte)IPType.ICMP:
                    Console.Error.WriteLine("ICMP");
                    lock (sentry)
                    {
                        if (Connections.ContainsKey(Key))
                        {
                            if (Connections[Key].isOpen() == false)
                            {
                                throw new Exception("Attempt to send on Closed Connection");
                            }
                            Console.Error.WriteLine("Found Open Connection");
                            result = Connections[Key].send(ippkt.Payload);
                        }
                        else
                        {
                            Console.Error.WriteLine("Creating New Connection with key " + Key);
                            ICMPSession s = new ICMPSession();
                            s.DestIP   = ippkt.DestinationIP;
                            s.SourceIP = UDP_DHCPsession.PS2_IP;
                            result     = s.send(ippkt.Payload);
                            Connections.Add(Key, s);
                        }
                    }
                    break;

                case (byte)IPType.TCP:
                    //Console.Error.WriteLine("TCP");
                    TCP tcp = (TCP)ippkt.Payload;

                    Key += "-" + ((UInt64)tcp.SourcePort) + ":" + ((UInt64)tcp.DestinationPort);
                    lock (sentry)
                    {
                        if (Connections.ContainsKey(Key))
                        {
                            if (Connections[Key].isOpen() == false)
                            {
                                throw new Exception("Attempt to send on Closed TCP Connection of Key : " + Key + "");
                            }
                            //Console.Error.WriteLine("Found Open Connection");
                            result = Connections[Key].send(ippkt.Payload);
                        }
                        else
                        {
                            //Console.Error.WriteLine("Creating New Connection with key " + Key);
                            Console.Error.WriteLine("Creating New TCP Connection with Dest Port " + tcp.DestinationPort);
                            TCPSession s = new TCPSession();
                            s.DestIP   = ippkt.DestinationIP;
                            s.SourceIP = UDP_DHCPsession.PS2_IP;
                            result     = s.send(ippkt.Payload);
                            Connections.Add(Key, s);
                        }
                    }
                    break;

                case (byte)IPType.UDP:
                    //Console.Error.WriteLine("UDP");
                    UDP udp = (UDP)ippkt.Payload;

                    Key += "-" + ((UInt64)udp.SourcePort) + ":" + ((UInt64)udp.DestinationPort);
                    if (udp.DestinationPort == 67)
                    {         //DHCP
                        result = DCHP_server.send(ippkt.Payload);
                        break;
                    }
                    lock (sentry)
                    {
                        if (Connections.ContainsKey(Key))
                        {
                            if (Connections[Key].isOpen() == false)
                            {
                                throw new Exception("Attempt to send on Closed Connection");
                            }
                            //Console.Error.WriteLine("Found Open Connection");
                            result = Connections[Key].send(ippkt.Payload);
                        }
                        else
                        {
                            //Console.Error.WriteLine("Creating New Connection with key " + Key);
                            Console.Error.WriteLine("Creating New UDP Connection with Dest Port " + udp.DestinationPort);
                            UDPSession s = new UDPSession();
                            s.DestIP   = ippkt.DestinationIP;
                            s.SourceIP = UDP_DHCPsession.PS2_IP;
                            result     = s.send(ippkt.Payload);
                            Connections.Add(Key, s);
                        }
                    }
                    break;

                default:
                    Console.Error.WriteLine("Unkown Protocol");
                    //throw new NotImplementedException();
                    break;
                }
                //Console.Error.WriteLine("Key = " + Key);
                break;

                #region "ARP"
            case (int)EtherFrameType.ARP:
                Console.Error.WriteLine("ARP (Ignoring)");
                ARPPacket arppkt = ((ARPPacket)ef.Payload);

                ////Detect ARP Packet Types
                //if (Utils.memcmp(arppkt.SenderProtocolAddress, 0, new byte[] { 0, 0, 0, 0 }, 0, 4))
                //{
                //    Console.WriteLine("ARP Probe"); //(Who has my IP?)
                //    break;
                //}
                //if (Utils.memcmp(arppkt.SenderProtocolAddress, 0, arppkt.TargetProtocolAddress, 0, 4))
                //{
                //    if (Utils.memcmp(arppkt.TargetHardwareAddress, 0, new byte[] { 0, 0, 0, 0, 0, 0 }, 0, 6) & arppkt.OP == 1)
                //    {
                //        Console.WriteLine("ARP Announcement Type 1");
                //        break;
                //    }
                //    if (Utils.memcmp(arppkt.SenderHardwareAddress, 0, arppkt.TargetHardwareAddress, 0, 6) & arppkt.OP == 2)
                //    {
                //        Console.WriteLine("ARP Announcement Type 2");
                //        break;
                //    }
                //}

                ////if (arppkt.OP == 1) //ARP request
                ////{
                ////    //This didn't work for whatever reason.
                ////    if (Utils.memcmp(arppkt.TargetProtocolAddress,0,UDP_DHCPsession.GATEWAY_IP,0,4))
                ////    //it's trying to resolve the virtual gateway's mac addr
                ////    {
                ////        Console.Error.WriteLine("ARP Attempt to Resolve Gateway Mac");
                ////        arppkt.TargetHardwareAddress = arppkt.SenderHardwareAddress;
                ////        arppkt.SenderHardwareAddress = gateway_mac;
                ////        arppkt.TargetProtocolAddress = arppkt.SenderProtocolAddress;
                ////        arppkt.SenderProtocolAddress = UDP_DHCPsession.GATEWAY_IP;
                ////        arppkt.OP = 2;

                ////        EthernetFrame retARP = new EthernetFrame(arppkt);
                ////        retARP.DestinationMAC = ps2_mac;
                ////        retARP.SourceMAC = gateway_mac;
                ////        retARP.Protocol = (Int16)EtherFrameType.ARP;
                ////        vRecBuffer.Add(retARP.CreatePacket());
                ////        break;
                ////    }
                ////}
                //Console.Error.WriteLine("Unhandled ARP packet");

                result = true;
                break;

                #endregion
            case (int)0x0081:
                Console.Error.WriteLine("VLAN-tagged frame (IEEE 802.1Q)");
                throw new NotImplementedException();

            //break;
            default:
                Console.Error.WriteLine("Unkown EtherframeType " + ef.Protocol.ToString("X4"));
                break;
            }

            return(result);
        }