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