📄 stun.c
字号:
msg->hasXorMappedAddress = TRUE; if ( stunParseAtrAddress( body, attrLen, &msg->xorMappedAddress ) == FALSE ) { ortp_error("stun: problem parsing XorMappedAddress"); return FALSE; } else { if (verbose) ortp_message("stun: XorMappedAddress = %s\n", ipaddr(&msg->mappedAddress.ipv4) ); } } else if (atrType == XorOnly) { msg->xorOnly = TRUE; } else if (atrType == ServerName) { msg->hasServerName = TRUE; if (stunParseAtrString( body, attrLen, &msg->serverName) == FALSE) { ortp_error("stun: problem parsing ServerName"); return FALSE; } else { if (verbose) ortp_message("stun: ServerName = %s\n", msg->serverName.value ); } } else if (atrType == SecondaryAddress) { msg->hasSecondaryAddress = TRUE; if ( stunParseAtrAddress( body, attrLen, &msg->secondaryAddress ) == FALSE ) { ortp_error("stun: problem parsing secondaryAddress"); return FALSE; } else { if (verbose) ortp_message("stun: SecondaryAddress = %s\n", ipaddr(&msg->secondaryAddress.ipv4) ); } } else { if (verbose) ortp_message("stun: Unknown attribute: %i\n", atrType ); 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)); */ memcpy(buf, &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));*/ memcpy(buf, &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); ptr = encode16(ptr, 6 + atr->sizeReason); ptr = encode16(ptr, atr->pad); *ptr++ = atr->errorClass; *ptr++ = atr->number; ptr = encode(ptr, atr->reason, atr->sizeReason); return ptr;}static char* encodeAtrUnknown(char* ptr, const StunAtrUnknown *atr){ int i; ptr = encode16(ptr, UnknownAttribute); ptr = encode16(ptr, 2+2*atr->numAttributes); for (i=0; i<atr->numAttributes; i++) { ptr = encode16(ptr, atr->attrType[i]); } return ptr;}static char* encodeXorOnly(char* ptr){ ptr = encode16(ptr, XorOnly ); return ptr;}static char* encodeAtrString(char* ptr, UInt16 type, const StunAtrString *atr){ /*assert(atr->sizeValue % 4 == 0);*/ ptr = encode16(ptr, type); ptr = encode16(ptr, atr->sizeValue); ptr = encode(ptr, atr->value, atr->sizeValue); return ptr;}static char* encodeAtrIntegrity(char* ptr, const StunAtrIntegrity *atr){ ptr = encode16(ptr, MessageIntegrity); ptr = encode16(ptr, 20); ptr = encode(ptr, atr->hash, sizeof(atr->hash)); return ptr;}unsigned intstunEncodeMessage( const StunMessage *msg, char* buf, unsigned int bufLen, const StunAtrString *password, bool_t verbose){ /*assert(bufLen >= sizeof(StunMsgHdr));*/ char* ptr = buf; char* lengthp; ptr = encode16(ptr, msg->msgHdr.msgType); lengthp = ptr; ptr = encode16(ptr, 0); /*ptr = encode(ptr, reinterpret_cast<const char*>(msg->msgHdr.id.octet), sizeof(msg->msgHdr.id));*/ ptr = encode(ptr, (const char*)msg->msgHdr.id.octet, sizeof(msg->msgHdr.id)); if (verbose) ortp_message("stun: Encoding stun message: "); if (msg->hasMappedAddress) { if (verbose) ortp_message("stun: Encoding MappedAddress: %s\n", ipaddr(&msg->mappedAddress.ipv4) ); ptr = encodeAtrAddress4 (ptr, MappedAddress, &msg->mappedAddress); } if (msg->hasResponseAddress) { if (verbose) ortp_message("stun: Encoding ResponseAddress: %s\n", ipaddr(&msg->responseAddress.ipv4) ); ptr = encodeAtrAddress4(ptr, ResponseAddress, &msg->responseAddress); } if (msg->hasChangeRequest) { if (verbose) ortp_message("stun: Encoding ChangeRequest: %i\n", msg->changeRequest.value ); ptr = encodeAtrChangeRequest(ptr, &msg->changeRequest); } if (msg->hasSourceAddress) { if (verbose) ortp_message("stun: Encoding SourceAddress: %s\n", ipaddr(&msg->sourceAddress.ipv4) ); ptr = encodeAtrAddress4(ptr, SourceAddress, &msg->sourceAddress); } if (msg->hasChangedAddress) { if (verbose) ortp_message("stun: Encoding ChangedAddress: %s\n", ipaddr(&msg->changedAddress.ipv4) ); ptr = encodeAtrAddress4(ptr, ChangedAddress, &msg->changedAddress); } if (msg->hasUsername) { if (verbose) ortp_message("stun: Encoding Username: %s\n", msg->username.value ); ptr = encodeAtrString(ptr, STUNUsername, &msg->username); } if (msg->hasPassword) { if (verbose) ortp_message("stun: Encoding Password: %s\n", msg->password.value ); ptr = encodeAtrString(ptr, STUNPassword, &msg->password); } if (msg->hasErrorCode) { if (verbose) ortp_message("stun: Encoding ErrorCode: class=%i number=%i reason=%s\n" , msg->errorCode.errorClass , msg->errorCode.number , msg->errorCode.reason ); ptr = encodeAtrError(ptr, &msg->errorCode); } if (msg->hasUnknownAttributes) { if (verbose) ortp_message("stun: Encoding UnknownAttribute: ???"); ptr = encodeAtrUnknown(ptr, &msg->unknownAttributes); } if (msg->hasReflectedFrom) { if (verbose) ortp_message("stun: Encoding ReflectedFrom: %s\n", ipaddr(&msg->reflectedFrom.ipv4) ); ptr = encodeAtrAddress4(ptr, ReflectedFrom, &msg->reflectedFrom); } if (msg->hasXorMappedAddress) { if (verbose) ortp_message("stun: Encoding XorMappedAddress: %s\n", ipaddr(&msg->xorMappedAddress.ipv4) ); ptr = encodeAtrAddress4 (ptr, XorMappedAddress, &msg->xorMappedAddress); } if (msg->xorOnly) { if (verbose) ortp_message("stun: Encoding xorOnly: "); ptr = encodeXorOnly( ptr ); } if (msg->hasServerName) { if (verbose) ortp_message("stun: Encoding ServerName: %s\n", msg->serverName.value ); ptr = encodeAtrString(ptr, ServerName, &msg->serverName); } if (msg->hasSecondaryAddress) { if (verbose) ortp_message("stun: Encoding SecondaryAddress: %s\n", ipaddr(&msg->secondaryAddress.ipv4) ); ptr = encodeAtrAddress4 (ptr, SecondaryAddress, &msg->secondaryAddress); } if (password->sizeValue > 0) { StunAtrIntegrity integrity; if (verbose) ortp_message("stun: HMAC with password: %s\n", password->value ); computeHmac(integrity.hash, buf, (int)(ptr-buf) , password->value, password->sizeValue); ptr = encodeAtrIntegrity(ptr, &integrity); } encode16(lengthp, (UInt16)(ptr - buf - sizeof(StunMsgHdr))); return (int)(ptr - buf);}int stunRand(void){ /* return 32 bits of random stuff */ /* assert( sizeof(int) == 4 ); */ static bool_t init=FALSE; if ( !init ) { UInt64 tick; int seed; init = TRUE;#if defined(_WIN32_WCE) tick = GetTickCount ();#elif defined(_MSC_VER) { volatile unsigned int lowtick=0,hightick=0; __asm { rdtsc mov lowtick, eax mov hightick, edx } tick = hightick; tick <<= 32; tick |= lowtick; }#elif defined(__GNUC__) && ( defined(__i686__) || defined(__i386__) ) asm("rdtsc" : "=A" (tick));#elif defined(__GNUC__) && defined(__amd64__) asm("rdtsc" : "=A" (tick));#elif defined (__SUNPRO_CC) && defined( __sparc__ ) tick = gethrtime();#elif defined(__MACH__) { int fd=open("/dev/random",O_RDONLY); read(fd,&tick,sizeof(tick)); closesocket(fd); }#elif defined(__linux) { fd_set fdSet; int maxFd=0; struct timeval tv; int e; int fd=open("/dev/random",O_RDONLY); if (fd<0) { ortp_message("stun: Failed to open random device\n"); return random(); } FD_ZERO(&fdSet); FD_SET(fd,&fdSet); maxFd=fd+1; tv.tv_sec = 0; tv.tv_usec = 500; e = select( maxFd, &fdSet, NULL,NULL, &tv ); if (e <= 0) { ortp_error("stun: Failed to get data from random device\n"); closesocket(fd); return random(); } read(fd,&tick,sizeof(tick)); closesocket(fd); }#else# error Need some way to seed the random number generator #endif seed = (int)(tick);#if defined(_WIN32) || defined(_WIN32_WCE) srand(seed);#else srandom(seed);#endif } #if defined(_WIN32) || defined(_WIN32_WCE) /* assert( RAND_MAX == 0x7fff ); */ { int r1 = rand(); int r2 = rand(); int ret = (r1<<16) + r2; return ret; }#else return random(); #endif}/* return a random number to use as a port */static intrandomPort(){ int min=0x4000; int max=0x7FFF; int ret = stunRand(); ret = ret|min; ret = ret&max; return ret;}#ifdef NOSSLstatic voidcomputeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey){ strncpy(hmac,"hmac-not-implemented",20);}#else#include <openssl/hmac.h>static voidcomputeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey){ unsigned int resultSize=0; HMAC(EVP_sha1(), key, sizeKey, (const unsigned char*) input, length, (unsigned char*)hmac, &resultSize); /* HMAC(EVP_sha1(), key, sizeKey, reinterpret_cast<const unsigned char*>(input), length, reinterpret_cast<unsigned char*>(hmac), &resultSize); //assert(resultSize == 20); */}#endifstatic voidtoHex(const char* buffer, int bufferSize, char* output) { int i; static char hexmap[] = "0123456789abcdef"; const char* p = buffer; char* r = output; for (i=0; i < bufferSize; i++) { unsigned char temp = *p++; int hi = (temp & 0xf0)>>4; int low = (temp & 0xf); *r++ = hexmap[hi]; *r++ = hexmap[low]; } *r = 0;}voidstunCreateUserName(const StunAddress4* source, StunAtrString* username){ UInt64 time = stunGetSystemTimeSecs(); UInt64 lotime; char buffer[1024]; char hmac[20]; char key[] = "Jason"; char hmacHex[41]; int l; time -= (time % 20*60); /* UInt64 hitime = time >> 32; */ lotime = time & 0xFFFFFFFF; sprintf(buffer, "%08x:%08x:%08x:", (UInt32)(source->addr), (UInt32)(stunRand()), (UInt32)(lotime)); /*assert( strlen(buffer) < 1024 ); */ /*assert(strlen(buffer) + 41 < STUN_MAX_STRING); */ computeHmac(hmac, buffer, strlen(buffer), key, strlen(key) ); toHex(hmac, 20, hmacHex ); hmacHex[40] =0; strcat(buffer,hmacHex); l = strlen(buffer); /* assert( l+1 < STUN_MAX_STRING );*/ /* assert( l%4 == 0 ); */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -