///////////////////////////////////////////////////////////////////////// // $Id$ ///////////////////////////////////////////////////////////////////////// // // Copyright (C) 2000-2011 The Bochs Project // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // Define BX_PLUGGABLE in files that can be compiled into plugins. For // platforms that require a special tag on exported symbols, BX_PLUGGABLE // is used to know when we are exporting symbols and when we are importing. #define BX_PLUGGABLE #include "iodev.h" #if BX_NETWORKING && BX_NETMOD_ARPBACK #include "eth_packetmaker.h" bx_bool sendable(const eth_packet& outpacket) { //FINISH ME! return 0; } Bit32u eth_IPmaker::datalen(const eth_packet& outpacket) { Bit32u out; out=((outpacket.buf[16]<<8)+outpacket.buf[17])-(4*(0xF & outpacket.buf[14])); return out; } const Bit8u *eth_IPmaker::datagram(const eth_packet& outpacket) { const Bit8u *out; out=outpacket.buf+14+(4*(0xF & outpacket.buf[14])); return out; } Bit32u eth_IPmaker::build_packet_header(Bit32u source, Bit32u dest, Bit8u protocol, Bit32u datalen) { Bit32u temp; Bit32u i; memcpy(pending.buf,internal_mac,6); memcpy(pending.buf+6,external_mac,6); memcpy(pending.buf+12,ethtype_ip,2); pending.buf[14]=0x45; pending.buf[15]=0; temp=datalen+20; pending.buf[16]=(temp>>8) & 0xFF; pending.buf[17]=temp & 0xFF; pending.buf[18]=0; pending.buf[19]=0; pending.buf[20]=0; pending.buf[21]=0; pending.buf[22]=30; pending.buf[23]=protocol; pending.buf[24]=0; pending.buf[25]=0; pending.buf[26]=(source>>24) & 0xFF; pending.buf[27]=(source>>16) & 0xFF; pending.buf[28]=(source>>8) & 0xFF; pending.buf[29]=(source) & 0xFF; pending.buf[30]=(dest>>24) & 0xFF; pending.buf[31]=(dest>>16) & 0xFF; pending.buf[32]=(dest>>8) & 0xFF; pending.buf[33]=(dest) & 0xFF; //Compute Checksum temp=0; for(i=14;i<34;i=i+2) { Bit32u addee=pending.buf[i]; addee=(addee<<8) & pending.buf[i+1]; temp=temp+addee; } temp=(temp>>16)+(temp&0xFFFF); temp=(temp>>16)+(temp&0xFFFF); pending.buf[24]=~(Bit8u)((temp>>8) & 0xFF); pending.buf[25]=~(Bit8u)(temp & 0xFF); return(34); } Bit8u eth_IPmaker::protocol(const eth_packet& outpacket) { return (*(outpacket.buf+23) & 0xff); } Bit32u eth_IPmaker::source(const eth_packet& outpacket) { Bit32u out=0xFF & *(outpacket.buf+26); out=(out<<8) | (0xFF & *(outpacket.buf+27)); out=(out<<8) | (0xFF & *(outpacket.buf+28)); out=(out<<8) | (0xFF & *(outpacket.buf+29)); return out; } Bit32u eth_IPmaker::destination(const eth_packet& outpacket) { Bit32u out=0xFF & *(outpacket.buf+30); out=(out<<8) | (0xFF & *(outpacket.buf+31)); out=(out<<8) | (0xFF & *(outpacket.buf+32)); out=(out<<8) | (0xFF & *(outpacket.buf+33)); return out; } void eth_IPmaker::init(void) { is_pending=0; } void eth_ETHmaker::init(void) { arper.init(); } bx_bool eth_ETHmaker::getpacket(eth_packet& inpacket) { return arper.getpacket(inpacket); } bx_bool eth_ETHmaker::ishandler(const eth_packet& outpacket) { if((outpacket.len>=60) && ( (!memcmp(outpacket.buf, external_mac, 6)) || (!memcmp(outpacket.buf, broadcast_macaddr, 6))) && ( (!memcmp(outpacket.buf+12, ethtype_arp, 2)) || (!memcmp(outpacket.buf+12, ethtype_ip, 2))) && (outpacket.len=60) && (!memcmp(outpacket.buf+12, ethtype_arp, 2)) && (outpacket.len