pethsock.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:5k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * pethsock.cxx
  3.  *
  4.  * Direct Ethernet socket I/O channel class.
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: pethsock.cxx,v $
  30.  * Revision 1.4  1998/11/30 04:58:52  robertj
  31.  * New directory structure
  32.  *
  33.  * Revision 1.3  1998/09/23 06:22:29  robertj
  34.  * Added open source copyright license.
  35.  *
  36.  * Revision 1.2  1998/09/14 12:37:51  robertj
  37.  * Added function to parse type and payload address out of ethernet/802.2 packet.
  38.  *
  39.  * Revision 1.1  1998/08/31 12:59:55  robertj
  40.  * Initial revision
  41.  *
  42.  */
  43. #include <ptlib.h>
  44. #include <ptlib/sockets.h>
  45. PEthSocket::Address::Address()
  46. {
  47.   memset(b, 0xff, sizeof(b));
  48. }
  49. PEthSocket::Address::Address(const BYTE * addr)
  50. {
  51.   memcpy(b, PAssertNULL(addr), sizeof(b));
  52. }
  53. PEthSocket::Address::Address(const Address & addr)
  54. {
  55.   ls.l = addr.ls.l;
  56.   ls.s = addr.ls.s;
  57. }
  58. PEthSocket::Address::Address(const PString & str)
  59. {
  60.   operator=(str);
  61. }
  62. PEthSocket::Address & PEthSocket::Address::operator=(const Address & addr)
  63. {
  64.   ls.l = addr.ls.l;
  65.   ls.s = addr.ls.s;
  66.   return *this;
  67. }
  68. PEthSocket::Address & PEthSocket::Address::operator=(const PString & str)
  69. {
  70.   memset(b, 0, sizeof(b));
  71.   int shift = 0;
  72.   PINDEX byte = 5;
  73.   PINDEX pos = str.GetLength();
  74.   while (pos-- > 0) {
  75.     int c = str[pos];
  76.     if (c != '-') {
  77.       if (isdigit(c))
  78.         b[byte] |= (c - '0') << shift;
  79.       else if (isxdigit(c))
  80.         b[byte] |= (toupper(c) - 'A' + 10) << shift;
  81.       else {
  82.         memset(this, 0, sizeof(*this));
  83.         return *this;
  84.       }
  85.       if (shift == 0)
  86.         shift = 4;
  87.       else {
  88.         shift = 0;
  89.         byte--;
  90.       }
  91.     }
  92.   }
  93.   return *this;
  94. }
  95. PEthSocket::Address::operator PString() const
  96. {
  97.   return psprintf("%02X-%02X-%02X-%02X-%02X-%02X", b[0], b[1], b[2], b[3], b[4], b[5]);
  98. }
  99. void PEthSocket::Frame::Parse(WORD & type, BYTE * & payload, PINDEX & length)
  100. {
  101.   WORD len_or_type = ntohs(snap.length);
  102.   if (len_or_type > sizeof(*this)) {
  103.     type = len_or_type;
  104.     payload = ether.payload;
  105.     // Subtract off the Ethernet II header
  106.     length -= sizeof(dst_addr)+sizeof(src_addr)+sizeof(snap.length);
  107.     return;
  108.   }
  109.   if (snap.dsap == 0xaa && snap.ssap == 0xaa) {
  110.     type = ntohs(snap.type);   // SNAP header
  111.     payload = snap.payload;
  112.     // Subtract off the 802.2 header and SNAP data
  113.     length = len_or_type - (sizeof(snap)-sizeof(snap.payload));
  114.     return;
  115.   }
  116.   
  117.   if (snap.dsap == 0xff && snap.ssap == 0xff) {
  118.     type = TypeIPX;   // Special case for Novell netware's stuffed up 802.3
  119.     payload = &snap.dsap;
  120.     length = len_or_type;  // Whole thing is IPX payload
  121.     return;
  122.   }
  123.   if (snap.dsap == 0xe0 && snap.ssap == 0xe0)
  124.     type = TypeIPX;   // Special case for Novell netware's 802.2
  125.   else
  126.     type = snap.dsap;    // A pure 802.2 protocol id
  127.   payload = snap.oui;
  128.   // Subtract off the 802.2 header
  129.   length = len_or_type - (sizeof(snap.dsap)+sizeof(snap.ssap)+sizeof(snap.ctrl));
  130. }
  131. const char * PEthSocket::GetProtocolName() const
  132. {
  133.   return "eth";
  134. }
  135. BOOL PEthSocket::Listen(unsigned, WORD, Reusability)
  136. {
  137.   PAssertAlways(PUnimplementedFunction);
  138.   return FALSE;
  139. }
  140. BOOL PEthSocket::GetIpAddress(PIPSocket::Address & addr)
  141. {
  142.   PIPSocket::Address net_mask;
  143.   return EnumIpAddress(0, addr, net_mask);
  144. }
  145. BOOL PEthSocket::GetIpAddress(PIPSocket::Address & addr, PIPSocket::Address & net_mask)
  146. {
  147.   return EnumIpAddress(0, addr, net_mask);
  148. }
  149. BOOL PEthSocket::ReadPacket(PBYTEArray & buffer,
  150.                             Address & dest,
  151.                             Address & src,
  152.                             WORD & type,
  153.                             PINDEX & length,
  154.                             BYTE * & payload)
  155. {
  156.   Frame * frame = (Frame *)buffer.GetPointer(sizeof(Frame));
  157.   const PINDEX MinFrameSize = sizeof(frame->dst_addr)+sizeof(frame->src_addr)+sizeof(frame->snap.length);
  158.   do {
  159.     if (!Read(frame, sizeof(*frame)))
  160.       return FALSE;
  161.   } while (lastReadCount < MinFrameSize);
  162.   dest = frame->dst_addr;
  163.   src = frame->src_addr;
  164.   length = lastReadCount;
  165.   frame->Parse(type, payload, length);
  166.   return TRUE;
  167. }
  168. // End Of File ///////////////////////////////////////////////////////////////