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 *encodeAtrIntegrity(char *ptr, const StunAtrIntegrity *atr) { ptr = encode16(ptr, MessageIntegrity); ptr = encode16(ptr, 20); ptr = encode(ptr, atr->hash, sizeof(atr->hash)); return ptr; }
static char *encodeAtrString(char *ptr, uint16_t 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 *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 *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 *encodeAtrAddress4(char *ptr, uint16_t 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; }
char *base16encode(const char *inBuffer, int count) { char *outBuffer = (char *) malloc(count*2+1); char *outBufferPtr = outBuffer; BYTE *inBufferPtr = (BYTE *) inBuffer; while(count){ *outBufferPtr++ = encode16(((*inBufferPtr)>>4)&0x0F); *outBufferPtr++ = encode16((*inBufferPtr++)&0x0F); count--; } *outBufferPtr = '\0'; return outBuffer; }
static unsigned int stunEncodeMessage(const StunMessage *msg, char *buf, unsigned int bufLen, const StunAtrString *password) { assert(bufLen >= sizeof(StunMsgHdr)); char *ptr = buf; ptr = encode16(ptr, msg->msgHdr.msgType); char *lengthp = ptr; ptr = encode16(ptr, 0); ptr = encode(ptr, (const char *)(msg->msgHdr.id.octet), sizeof(msg->msgHdr.id)); if (msg->hasMappedAddress) { ptr = encodeAtrAddress4(ptr, MappedAddress, &msg->mappedAddress); } if (msg->hasResponseAddress) { ptr = encodeAtrAddress4(ptr, ResponseAddress, &msg->responseAddress); } if (msg->hasChangeRequest) { ptr = encodeAtrChangeRequest(ptr, &msg->changeRequest); } if (msg->hasSourceAddress) { ptr = encodeAtrAddress4(ptr, SourceAddress, &msg->sourceAddress); } if (msg->hasChangedAddress) { ptr = encodeAtrAddress4(ptr, ChangedAddress, &msg->changedAddress); } if (msg->hasUsername) { ptr = encodeAtrString(ptr, Username, &msg->username); } if (msg->hasPassword) { ptr = encodeAtrString(ptr, Password, &msg->password); } if (msg->hasErrorCode) { ptr = encodeAtrError(ptr, &msg->errorCode); } if (msg->hasUnknownAttributes) { ptr = encodeAtrUnknown(ptr, &msg->unknownAttributes); } if (msg->hasReflectedFrom) { ptr = encodeAtrAddress4(ptr, ReflectedFrom, &msg->reflectedFrom); } if (msg->hasXorMappedAddress) { ptr = encodeAtrAddress4(ptr, XorMappedAddress, &msg->xorMappedAddress); } if (msg->xorOnly) { ptr = encodeXorOnly(ptr); } if (msg->hasServerName) { ptr = encodeAtrString(ptr, ServerName, &msg->serverName); } if (msg->hasSecondaryAddress) { ptr = encodeAtrAddress4(ptr, SecondaryAddress, &msg->secondaryAddress); } if (password->sizeValue > 0) { StunAtrIntegrity integrity; computeHmac(integrity.hash, buf, (int)(ptr - buf), password->value, password->sizeValue); ptr = encodeAtrIntegrity(ptr, &integrity); } encode16(lengthp, (uint16_t)(ptr - buf - sizeof(StunMsgHdr))); return (int)(ptr - buf); }
static char *encodeXorOnly(char *ptr) { ptr = encode16(ptr, XorOnly); return ptr; }