//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); } }
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 }
//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); } }
//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; }
//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 } }
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 }
//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); } }
//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); }