⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stun.cxx

📁 现在应用最广泛的一种私网穿透方式
💻 CXX
📖 第 1 页 / 共 5 页
字号:
#include <cassert>#include <cstring>#include <iostream>#include <cstdlib>   #include <errno.h>#ifdef WIN32#include <winsock2.h>#include <stdlib.h>#include <io.h>#include <time.h>#else#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/types.h> #include <arpa/inet.h>#include <fcntl.h>#include <netdb.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <resolv.h>#include <net/if.h>#endif#if defined(__sparc__) || defined(WIN32)#define NOSSL#endif#define NOSSL#include "udp.h"#include "stun.h"using namespace std;static voidcomputeHmac(char* hmac, const char* input, int length, const char* key, int keySize);static bool stunParseAtrAddress( char* body, unsigned int hdrLen,  StunAtrAddress4& result ){   if ( hdrLen != 8 )   {      clog << "hdrLen wrong for Address" <<endl;      return false;   }   result.pad = *body++;   result.family = *body++;   if (result.family == IPv4Family)   {      UInt16 nport;      memcpy(&nport, body, 2); body+=2;      result.ipv4.port = ntohs(nport);		      UInt32 naddr;      memcpy(&naddr, body, 4); body+=4;      result.ipv4.addr = ntohl(naddr);      return true;   }   else if (result.family == IPv6Family)   {      clog << "ipv6 not supported" << endl;   }   else   {      clog << "bad address family: " << result.family << endl;   }	   return false;}static bool stunParseAtrChangeRequest( char* body, unsigned int hdrLen,  StunAtrChangeRequest& result ){   if ( hdrLen != 4 )   {      clog << "hdr length = " << hdrLen << " expecting " << sizeof(result) << endl;		      clog << "Incorrect size for ChangeRequest" << endl;      return false;   }   else   {      memcpy(&result.value, body, 4);      result.value = ntohl(result.value);      return true;   }}static bool stunParseAtrError( char* body, unsigned int hdrLen,  StunAtrError& result ){   if ( hdrLen >= sizeof(result) )   {      clog << "head on Error too large" << endl;      return false;   }   else   {      memcpy(&result.pad, body, 2); body+=2;      result.pad = ntohs(result.pad);      result.errorClass = *body++;      result.number = *body++;		      result.sizeReason = hdrLen - 4;      memcpy(&result.reason, body, result.sizeReason);      result.reason[result.sizeReason] = 0;      return true;   }}static bool stunParseAtrUnknown( char* body, unsigned int hdrLen,  StunAtrUnknown& result ){   if ( hdrLen >= sizeof(result) )   {      return false;   }   else   {      if (hdrLen % 4 != 0) return false;      result.numAttributes = hdrLen / 4;      for (int i=0; i<result.numAttributes; i++)      {         memcpy(&result.attrType[i], body, 2); body+=2;         result.attrType[i] = ntohs(result.attrType[i]);      }      return true;   }}static bool stunParseAtrString( char* body, unsigned int hdrLen,  StunAtrString& result ){   if ( hdrLen >= STUN_MAX_STRING )   {      clog << "String is too large" << endl;      return false;   }   else   {      if (hdrLen % 4 != 0)      {         clog << "Bad length string " << hdrLen << endl;         return false;      }		      result.sizeValue = hdrLen;      memcpy(&result.value, body, hdrLen);      result.value[hdrLen] = 0;      return true;   }}static bool stunParseAtrIntegrity( char* body, unsigned int hdrLen,  StunAtrIntegrity& result ){   if ( hdrLen != 20)   {      clog << "MessageIntegrity must be 20 bytes" << endl;      return false;   }   else   {      memcpy(&result.hash, body, hdrLen);      return true;   }}boolstunParseMessage( char* buf, unsigned int bufLen, StunMessage& msg, bool verbose){   if (verbose) clog << "Received stun message: " << bufLen << " bytes" << endl;   memset(&msg, 0, sizeof(msg));	   if (sizeof(StunMsgHdr) > bufLen)   {      clog << "Bad message" << endl;      return false;   }	   memcpy(&msg.msgHdr, buf, sizeof(StunMsgHdr));   msg.msgHdr.msgType = ntohs(msg.msgHdr.msgType);   msg.msgHdr.msgLength = ntohs(msg.msgHdr.msgLength);	   if (msg.msgHdr.msgLength + sizeof(StunMsgHdr) != bufLen)   {      clog << "Message header length doesn't match message size: " << msg.msgHdr.msgLength << " - " << bufLen << endl;      return false;   }	   char* body = buf + sizeof(StunMsgHdr);   unsigned int size = msg.msgHdr.msgLength;	   //clog << "bytes after header = " << size << endl;	   while ( size > 0 )   {      // !jf! should check that there are enough bytes left in the buffer		      StunAtrHdr* attr = reinterpret_cast<StunAtrHdr*>(body);		      unsigned int attrLen = ntohs(attr->length);      int atrType = ntohs(attr->type);		      //if (verbose) clog << "Found attribute type=" << AttrNames[atrType] << " length=" << attrLen << endl;      if ( attrLen+4 > size )       {         clog << "claims attribute is larger than size of message " <<"(attribute type="<<atrType<<")"<< endl;         return false;      }		      body += 4; // skip the length and type in attribute header      size -= 4;		      switch ( atrType )      {         case MappedAddress:            msg.hasMappedAddress = true;            if ( stunParseAtrAddress(  body,  attrLen,  msg.mappedAddress )== false )            {               clog << "problem parsing MappedAddress" << endl;               return false;            }            else            {               if (verbose) clog << "MappedAddress = " << msg.mappedAddress.ipv4 << endl;            }					            break;           case ResponseAddress:            msg.hasResponseAddress = true;            if ( stunParseAtrAddress(  body,  attrLen,  msg.responseAddress )== false )            {               clog << "problem parsing ResponseAddress" << endl;               return false;            }            else            {               if (verbose) clog << "ResponseAddress = " << msg.responseAddress.ipv4 << endl;            }            break;  				         case ChangeRequest:            msg.hasChangeRequest = true;            if (stunParseAtrChangeRequest( body, attrLen, msg.changeRequest) == false)            {               clog << "problem parsing ChangeRequest" << endl;               return false;            }            else            {               if (verbose) clog << "ChangeRequest = " << msg.changeRequest.value << endl;            }            break;				         case SourceAddress:            msg.hasSourceAddress = true;            if ( stunParseAtrAddress(  body,  attrLen,  msg.sourceAddress )== false )            {               clog << "problem parsing SourceAddress" << endl;               return false;            }            else            {               if (verbose) clog << "SourceAddress = " << msg.sourceAddress.ipv4 << endl;            }            break;  				         case ChangedAddress:            msg.hasChangedAddress = true;            if ( stunParseAtrAddress(  body,  attrLen,  msg.changedAddress )== false )            {               clog << "problem parsing ChangedAddress" << endl;               return false;            }            else            {               if (verbose) clog << "ChangedAddress = " << msg.changedAddress.ipv4 << endl;            }            break;  				         case Username:             msg.hasUsername = true;            if (stunParseAtrString( body, attrLen, msg.username) == false)            {               clog << "problem parsing Username" << endl;               return false;            }            else            {               if (verbose) clog << "Username = " << msg.username.value << endl;            }					            break;				         case Password:             msg.hasPassword = true;            if (stunParseAtrString( body, attrLen, msg.password) == false)            {               clog << "problem parsing Password" << endl;               return false;            }            else            {               if (verbose) clog << "Password = " << msg.password.value << endl;            }            break;				         case MessageIntegrity:            msg.hasMessageIntegrity = true;            if (stunParseAtrIntegrity( body, attrLen, msg.messageIntegrity) == false)            {               clog << "problem parsing MessageIntegrity" << endl;               return false;            }            else            {               //if (verbose) clog << "MessageIntegrity = " << msg.messageIntegrity.hash << endl;            }					            // read the current HMAC            // look up the password given the user of given the transaction id             // compute the HMAC on the buffer            // decide if they match or not            break;				         case ErrorCode:            msg.hasErrorCode = true;            if (stunParseAtrError(body, attrLen, msg.errorCode) == false)            {               clog << "problem parsing ErrorCode" << endl;               return false;            }            else            {               if (verbose) clog << "ErrorCode = " << int(msg.errorCode.errorClass)                                  << " " << int(msg.errorCode.number)                                  << " " << msg.errorCode.reason << endl;            }					            break;				         case UnknownAttribute:            msg.hasUnknownAttributes = true;            if (stunParseAtrUnknown(body, attrLen, msg.unknownAttributes) == false)            {               clog << "problem parsing UnknownAttribute" << endl;               return false;            }            break;				         case ReflectedFrom:            msg.hasReflectedFrom = true;            if ( stunParseAtrAddress(  body,  attrLen,  msg.reflectedFrom ) == false )            {               clog << "problem parsing ReflectedFrom" << endl;               return false;            }            break;  				         case XorMappedAddress:            msg.hasXorMappedAddress = true;            if ( stunParseAtrAddress(  body,  attrLen,  msg.xorMappedAddress ) == false )            {               clog << "problem parsing XorMappedAddress" << endl;               return false;            }            else            {               if (verbose) clog << "XorMappedAddress = " << msg.mappedAddress.ipv4 << endl;            }            break;           case XorOnly:            msg.xorOnly = true;            if (verbose)             {               clog << "xorOnly = true" << endl;            }            break;  				         case ServerName:             msg.hasServerName = true;            if (stunParseAtrString( body, attrLen, msg.serverName) == false)            {               clog << "problem parsing ServerName" << endl;               return false;            }            else            {               if (verbose) clog << "ServerName = " << msg.serverName.value << endl;            }            break;				         case SecondaryAddress:            msg.hasSecondaryAddress = true;            if ( stunParseAtrAddress(  body,  attrLen,  msg.secondaryAddress ) == false )            {               clog << "problem parsing secondaryAddress" << endl;               return false;            }            else            {               if (verbose) clog << "SecondaryAddress = " << msg.secondaryAddress.ipv4 << endl;            }            break;  					         default:            if (verbose) clog << "Unknown attribute: " << atrType << endl;            if ( atrType <= 0x7FFF )             {               return false;            }      }		      body += attrLen;      size -= attrLen;   }       return true;}static char* encode16(char* buf, UInt16 data){   UInt16 ndata = htons(data);   memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt16));   return buf + sizeof(UInt16);}static char* encode32(char* buf, UInt32 data){   UInt32 ndata = htonl(data);   memcpy(buf, reinterpret_cast<void*>(&ndata), sizeof(UInt32));   return buf + sizeof(UInt32);}static char* encode(char* buf, const char* data, unsigned int length){   memcpy(buf, data, length);   return buf + length;}static char* encodeAtrAddress4(char* ptr, UInt16 type, const StunAtrAddress4& atr){   ptr = encode16(ptr, type);   ptr = encode16(ptr, 8);   *ptr++ = atr.pad;   *ptr++ = IPv4Family;   ptr = encode16(ptr, atr.ipv4.port);   ptr = encode32(ptr, atr.ipv4.addr);	   return ptr;}static char* encodeAtrChangeRequest(char* ptr, const StunAtrChangeRequest& atr){   ptr = encode16(ptr, ChangeRequest);   ptr = encode16(ptr, 4);   ptr = encode32(ptr, atr.value);   return ptr;}static char* encodeAtrError(char* ptr, const StunAtrError& atr){   ptr = encode16(ptr, ErrorCode);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -