Ethernet.cpp

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007-2008 by the ES40 Emulator Project
00003  *
00004  * WWW    : http://sourceforge.net/projects/es40
00005  * E-mail : camiel@camicom.com
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  * 
00021  * Although this is not required, the author would appreciate being notified of, 
00022  * and receiving any modifications you may make to the source code that might serve
00023  * the general public.
00024  *
00025  * Parts of this file based upon GXemul, which is Copyright (C) 2004-2007  
00026  * Anders Gavare.  All rights reserved.
00027  */
00028 
00044 #include "StdAfx.h"
00045 #include "Ethernet.h"
00046 #include "telnet.h"
00047 
00051 CPacketQueue::CPacketQueue(const char* name, int max)
00052 {
00053   this->name = name;
00054   this->max = max;
00055   head = 0;
00056   tail = -1;
00057   cnt = 0;
00058   highwater = 0;
00059   dropped = 0;
00060   packets = new eth_packet[max];
00061 }
00062 
00063 CPacketQueue::~CPacketQueue()
00064 {
00065   delete[] packets;
00066   printf("CPacketQueue(%s): highwater=%d, lost=%d\n", name, highwater, dropped);
00067 }
00068 
00069 void CPacketQueue::flush()
00070 {
00071   cnt = 0;
00072   head = 0;
00073   tail = -1;
00074 }
00075 
00076 static const u32  crcTable[256] = {
00077   0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
00078   0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
00079   0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
00080   0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
00081   0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
00082   0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
00083   0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
00084   0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
00085   0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
00086   0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
00087   0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
00088   0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
00089   0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
00090   0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
00091   0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
00092   0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
00093   0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
00094   0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
00095   0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
00096   0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
00097   0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
00098   0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
00099   0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
00100   0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
00101   0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
00102   0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
00103   0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
00104   0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
00105   0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
00106   0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
00107   0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
00108   0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
00109   0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
00110   0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
00111   0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
00112   0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
00113   0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
00114   0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
00115   0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
00116   0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
00117   0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
00118   0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
00119   0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
00120 };
00121 
00122 static u32 eth_crc32(u32 crc, const void* vbuf, int len)
00123 {
00124   const u32             mask = 0xFFFFFFFF;
00125   const unsigned char*  buf = (const unsigned char*) vbuf;
00126 
00127   crc ^= mask;
00128   while(0 != len--)
00129     crc = (crc >> 8) ^ crcTable[(crc ^ (*buf++)) & 0xFF];
00130   return(crc ^ mask);
00131 }
00132 
00133 bool CPacketQueue::add_tail(const u8*  packet_data, int packet_len,
00134                             bool calc_crc, bool need_crc)
00135 {
00136   if((cnt >= max) || (packet_len < 1) || (packet_len > 1514))
00137   {
00138     dropped += 1;
00139     printf("CPacketQueue(%s):add() packet lost! Size = %d", name, packet_len);
00140     printf(".. dst: %02x-%02x-%02x-%02x-%02x-%02x ", packet_data[0],
00141            packet_data[1], packet_data[2], packet_data[3], packet_data[4],
00142            packet_data[5]);
00143     printf(".. src: %02x-%02x-%02x-%02x-%02x-%02x \n", packet_data[6],
00144            packet_data[7], packet_data[8], packet_data[9], packet_data[10],
00145            packet_data[11]);
00146     return false;
00147   }
00148 
00149   tail += 1;
00150   if(tail >= max)
00151   {
00152     tail = 0;
00153   }
00154 
00155   eth_packet*   next = &packets[tail];
00156   next->len = packet_len;
00157   next->used = 0;
00158   memcpy(next->frame, packet_data, packet_len); // copy packet data
00159   if(need_crc)
00160   { // If packet needs CRC
00161     u32 crc = calc_crc ? eth_crc32(0, packet_data, packet_len) : 0; // recalculate crc if needed
00162     u32 ncrc = htonl(crc);  // put crc in network order
00163     memcpy(&next->frame[packet_len], &ncrc, 4); // append CRC to packet
00164     next->len += 4; // increase packet length
00165   }
00166 
00167   cnt += 1;
00168   if(cnt > highwater)
00169   {
00170     highwater = cnt;
00171   }
00172 
00173   return true;
00174 }
00175 
00176 bool CPacketQueue::get_head(eth_packet& packet)
00177 {
00178   if(cnt <= 0)
00179   {
00180     return false;
00181   }
00182 
00183   eth_packet*   headp = &packets[head];
00184   packet.len = headp->len;
00185   packet.used = headp->used;
00186   memcpy(packet.frame, headp->frame, sizeof(packet.frame));
00187   head += 1;
00188   if(head >= max)
00189   {
00190     head = 0;
00191   }
00192 
00193   cnt -= 1;
00194   return true;
00195 }

SourceForge.net Logo
Project space on SourceForge.net