END_TEST START_TEST (keepalive_resp_encode) { StunMessage stunMsg; StunMsgId transId; StunIPAddress ipAddr; uint8_t ip6Addr[16] = {0x20, 0x1, 0x4, 0x70, 0xdc, 0x88, 0x0, 0x2, 0x2, 0x26, 0x18, 0xff, 0xfe, 0x92, 0x6d, 0x53}; uint32_t i; uint8_t encBuf[STUN_MAX_PACKET_SIZE]; int encLen; for (i=0; i < sizeof(transId.octet); i++) transId.octet[i] = i; /* ip4 test */ stunlib_setIP4Address(&ipAddr, 0xAABBCCDD, 0x1234); encLen = stunlib_encodeStunKeepAliveResp(&transId, &ipAddr, encBuf, sizeof(encBuf)); stunlib_DecodeMessage(encBuf, encLen, &stunMsg, 0, NULL); fail_unless( (encLen == 32) && (stunMsg.hasXorMappedAddress) && (stunMsg.xorMappedAddress.familyType == STUN_ADDR_IPv4Family) && (stunMsg.xorMappedAddress.addr.v4.port == 0x1234) && (stunMsg.xorMappedAddress.addr.v4.addr == 0xAABBCCDD)); /* ip4 test */ stunlib_setIP6Address(&ipAddr, ip6Addr, 0x4321); encLen = stunlib_encodeStunKeepAliveResp(&transId, &ipAddr, encBuf, sizeof(encBuf)); stunlib_DecodeMessage(encBuf, encLen, &stunMsg, 0, NULL); fail_unless( (encLen == 44) && (stunMsg.hasXorMappedAddress) && (stunMsg.xorMappedAddress.familyType == STUN_ADDR_IPv6Family) && (stunMsg.xorMappedAddress.addr.v6.port == 0x4321) && (memcmp(stunMsg.xorMappedAddress.addr.v6.addr, ip6Addr, sizeof(ip6Addr)) == 0)); }
END_TEST START_TEST (response_decode) { StunMessage stunMsg; fail_unless( stunlib_DecodeMessage( respv4, 80, &stunMsg, NULL, NULL )); fail_unless( stunlib_checkIntegrity(respv4, 80, &stunMsg, password, sizeof(password)) ); fail_unless ( 0 == memcmp(&stunMsg.msgHdr.id.octet,&idOctet,12)); fail_unless( stunMsg.msgHdr.msgType == STUN_MSG_BindResponseMsg ); fail_unless( stunMsg.hasXorMappedAddress ); fail_unless( stunMsg.xorMappedAddress.addr.v4.addr == xorMapped ); fail_unless( stunMsg.xorMappedAddress.addr.v4.port == port ); fail_unless( stunMsg.hasSoftware); fail_unless( strncmp( stunMsg.software.value, software_resp, max(stunMsg.software.sizeValue,sizeof(software)) )==0 ); }
CTEST(stunserver, Encode_decode) { StunMessage stunMsg; StunMessage stunResponse; StunMsgId stunId; uint8_t stunBuff[STUN_MAX_PACKET_SIZE]; stunlib_createId(&stunId); sockaddr_initFromString( (struct sockaddr*)&mappedAddr, "193.200.93.152:3478" ); CreateConnectivityBindingResp(&stunMsg, stunId, (struct sockaddr *)&mappedAddr, 1, 1, STUN_MSG_BindResponseMsg, 200, NULL); int len = stunlib_encodeMessage(&stunMsg, (uint8_t*)stunBuff, STUN_MAX_PACKET_SIZE, (unsigned char *) passwd, strlen(passwd), NULL); ASSERT_TRUE(len == 72); ASSERT_TRUE( stunlib_DecodeMessage(stunBuff, len, &stunResponse, NULL, NULL /*stdout for debug*/)); }
END_TEST START_TEST (print) { StunMessage stunMsg; fail_unless( stunlib_DecodeMessage( req, 108, &stunMsg, NULL, NULL)); }
END_TEST START_TEST (response_decode_IPv6) { StunMessage stunMsg; struct sockaddr_storage a; struct sockaddr_storage b; sockaddr_initFromString((struct sockaddr*)&b, "[2001:db8:1234:5678:11:2233:4455:6677]:32853"); fail_unless( stunlib_DecodeMessage( respv6, 96, &stunMsg, NULL, NULL )); fail_unless( stunlib_checkIntegrity(respv6, 96, &stunMsg, password, sizeof(password)) ); fail_unless ( 0 == memcmp(&stunMsg.msgHdr.id.octet,&idOctet,12)); fail_unless( stunMsg.msgHdr.msgType == STUN_MSG_BindResponseMsg ); fail_unless( stunMsg.hasXorMappedAddress ); sockaddr_initFromIPv6Int((struct sockaddr_in6 *)&a, stunMsg.xorMappedAddress.addr.v6.addr, htons(stunMsg.xorMappedAddress.addr.v6.port)); fail_unless( sockaddr_alike((struct sockaddr *)&a, (struct sockaddr *)&b) ); fail_unless( stunMsg.xorMappedAddress.addr.v6.port == port ); fail_unless( stunMsg.hasSoftware); fail_unless( strncmp( stunMsg.software.value, software_resp, max(stunMsg.software.sizeValue,sizeof(software_resp)) )==0 ); }
END_TEST START_TEST( error_encode_decode ) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; const char *testStr[MAX_STRING_TEST] = {"a", "ab", "acb", "abcd", "abcde" }; int i; for (i=0; i < MAX_STRING_TEST; i++) { int encLen; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunlib_addError(&stunMsg, testStr[i], 400+i, ' '); encLen = stunlib_encodeMessage(&stunMsg, stunBuf, STUN_MAX_PACKET_SIZE, (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, encLen, &stunMsg, NULL, NULL)); fail_unless( stunlib_checkIntegrity(stunBuf, encLen, &stunMsg, password, sizeof(password)) ); fail_unless( (stunMsg.errorCode.errorClass == 4) && (stunMsg.errorCode.number == i) && (stunMsg.errorCode.reserved == 0) && (strncmp(stunMsg.errorCode.reason, testStr[i], strlen(testStr[i])) == 0) ); } }
END_TEST START_TEST (string_realm_encode_decode) { uint8_t stunBuf[STUN_MAX_PACKET_SIZE]; const char *testStr[MAX_STRING_TEST] = {"a", "ab", "acb", "abcd", "abcde" }; StunMessage stunMsg; int i; for (i=0; i < MAX_STRING_TEST; i++) { int encLen; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; /*id*/ memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunlib_addRealm(&stunMsg, testStr[i], STUN_DFLT_PAD); encLen = stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, encLen, &stunMsg, NULL, NULL) ); fail_unless( stunlib_checkIntegrity(stunBuf, encLen, &stunMsg, password, sizeof(password)) ); fail_unless(stunMsg.realm.sizeValue == strlen(testStr[i])); fail_unless(strcmp(stunMsg.realm.value, testStr[i]) == 0); } }
END_TEST START_TEST( channel_encode_decode ) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; uint16_t chan; for (chan = STUN_MIN_CHANNEL_ID; chan <= STUN_MAX_CHANNEL_ID; chan += 0x100) { memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; /*id*/ memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunlib_addChannelNumber(&stunMsg, chan); stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, sizeof(stunBuf), &stunMsg, NULL, NULL) ); fail_unless( stunlib_checkIntegrity(stunBuf, sizeof(stunBuf), &stunMsg, password, sizeof(password)) ); fail_unless(( stunMsg.channelNumber.channelNumber == chan) && (stunMsg.channelNumber.rffu == 0)); } }
int recvStunMsg(int sockfd, struct sockaddr_storage *their_addr, StunMessage *stunResponse, unsigned char *buf, int buflen) { socklen_t addr_len = sizeof their_addr; int numbytes; if ((numbytes = recvfrom(sockfd, buf, buflen , 0, (struct sockaddr *)their_addr, &addr_len)) == -1) { perror("recvfrom"); exit(1); } //printf("Got a packet that is %d bytes long\n", numbytes); if (stunlib_isStunMsg(buf, numbytes)) { //printf(" Packet is STUN\n"); stunlib_DecodeMessage(buf, numbytes, stunResponse, NULL, NULL); return numbytes; } return -1; }
END_TEST START_TEST (transport_encode_decode) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunlib_addRequestedTransport(&stunMsg, STUN_REQ_TRANSPORT_UDP); stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, sizeof(stunBuf), &stunMsg, NULL, NULL)); fail_unless( stunlib_checkIntegrity(stunBuf, sizeof(stunBuf), &stunMsg, password, sizeof(password)) ); fail_unless(( stunMsg.requestedTransport.protocol == STUN_REQ_TRANSPORT_UDP) && (stunMsg.requestedTransport.rffu[0] == 0) && (stunMsg.requestedTransport.rffu[1] == 0) && (stunMsg.requestedTransport.rffu[2] == 0) ); }
void stunHandler(struct socketConfig* config, struct sockaddr* from_addr, void* cb, unsigned char* buf, int buflen) { StunMessage stunRequest; STUN_INCOMING_REQ_DATA pReq; STUN_CLIENT_DATA* clientData = (STUN_CLIENT_DATA*)cb; char realm[STUN_MSG_MAX_REALM_LENGTH]; printf("Got a STUN message... (%i)\n", buflen); stunlib_DecodeMessage(buf, buflen, &stunRequest, NULL, stdout); printf("Finished decoding..\n"); if (stunRequest.msgHdr.msgType == STUN_MSG_DataIndicationMsg) { if (stunRequest.hasData) { /* Decode and do something with the data? */ /* config->data_handler(config->socketConfig[i].sockfd, */ /* config->socketConfig[i].tInst, */ /* &buf[stunResponse.data.offset]); */ } } if (stunRequest.hasRealm) { memcpy(&realm, stunRequest.realm.value, STUN_MSG_MAX_REALM_LENGTH); } if (stunRequest.hasMessageIntegrity) { printf("Checking integrity..%s\n", config->pass); if ( stunlib_checkIntegrity( buf, buflen, &stunRequest, (uint8_t*)config->pass, strlen(config->pass) ) ) { printf(" - Integrity check OK\n"); } else { printf(" - Integrity check NOT OK\n"); } } StunServer_HandleStunIncomingBindReqMsg(clientData, &pReq, &stunRequest, false); StunServer_SendConnectivityBindingResp(clientData, config->sockfd, stunRequest.msgHdr.id, PASSWORD, from_addr, from_addr, NULL, sendPacket, SOCK_DGRAM, false, 200, NULL); }
END_TEST START_TEST (discuss_encode_decode) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; DiscussData discussData; discussData.streamType=0x004; discussData.interactivity=0x01; discussData.networkStatus_flags = 0; discussData.networkStatus_nodeCnt = 0; discussData.networkStatus_tbd = 0; discussData.networkStatus_upMaxBandwidth = 0; discussData.networkStatus_downMaxBandwidth = 0; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); stunMsg.hasStreamType = true; stunMsg.streamType.type = discussData.streamType; stunMsg.streamType.interactivity = discussData.interactivity; stunMsg.hasNetworkStatus = true; stunMsg.networkStatus.flags = 0; stunMsg.networkStatus.nodeCnt = 0; stunMsg.networkStatus.upMaxBandwidth = 0; stunMsg.networkStatus.downMaxBandwidth = 0; stunMsg.hasNetworkStatusResp = true; stunMsg.networkStatusResp.flags = discussData.networkStatusResp_flags; stunMsg.networkStatusResp.nodeCnt = discussData.networkStatusResp_nodeCnt; stunMsg.networkStatusResp.upMaxBandwidth = discussData.networkStatusResp_upMaxBandwidth; stunMsg.networkStatusResp.downMaxBandwidth = discussData.networkStatusResp_downMaxBandwidth; stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, sizeof(stunBuf), &stunMsg, NULL, NULL)); fail_unless( stunlib_checkIntegrity(stunBuf, sizeof(stunBuf), &stunMsg, password, sizeof(password)) ); fail_unless( stunMsg.streamType.type == discussData.streamType); fail_unless( stunMsg.streamType.interactivity == discussData.interactivity); fail_unless( stunMsg.networkStatusResp.flags == discussData.networkStatusResp_flags); fail_unless( stunMsg.networkStatusResp.nodeCnt == discussData.networkStatusResp_nodeCnt); fail_unless( stunMsg.networkStatusResp.upMaxBandwidth == discussData.networkStatusResp_upMaxBandwidth); fail_unless( stunMsg.networkStatusResp.downMaxBandwidth == discussData.networkStatusResp_downMaxBandwidth); }
END_TEST START_TEST( xor_encode_decode ) { StunMessage stunMsg; unsigned char stunBuf[STUN_MAX_PACKET_SIZE]; int encLen; uint8_t ip6Addr[] = {0x20, 0x1, 0x4, 0x70, 0xdc, 0x88, 0x0, 0x2, 0x2, 0x26, 0x18, 0xff, 0xfe, 0x92, 0x6d, 0x53}; memset(&stunMsg, 0, sizeof(StunMessage)); stunMsg.msgHdr.msgType = STUN_MSG_AllocateRequestMsg; memcpy(&stunMsg.msgHdr.id.octet,&idOctet,12); /* ip4 test */ stunlib_setIP4Address(&stunMsg.xorMappedAddress, 0x12345678, 4355); stunMsg.hasXorMappedAddress = true; encLen = stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, encLen, &stunMsg, NULL, NULL) ); fail_unless( stunlib_checkIntegrity(stunBuf, encLen, &stunMsg, password, sizeof(password)) ); fail_unless( (stunMsg.xorMappedAddress.familyType == STUN_ADDR_IPv4Family) && (stunMsg.xorMappedAddress.addr.v4.port == 4355) && (stunMsg.xorMappedAddress.addr.v4.addr == 0x12345678)); /* ip6 */ stunlib_setIP6Address(&stunMsg.xorMappedAddress, ip6Addr, 4685); memcpy(stunMsg.xorMappedAddress.addr.v6.addr, ip6Addr, sizeof(ip6Addr)); stunMsg.hasXorMappedAddress = true; encLen = stunlib_encodeMessage(&stunMsg, stunBuf, sizeof(stunBuf), (unsigned char*)password, strlen(password), NULL); fail_unless( stunlib_DecodeMessage(stunBuf, encLen, &stunMsg, NULL, NULL)); fail_unless( stunlib_checkIntegrity(stunBuf, encLen, &stunMsg, password, sizeof(password)) ); fail_unless( (stunMsg.xorMappedAddress.familyType == STUN_ADDR_IPv6Family) && (stunMsg.xorMappedAddress.addr.v6.port == 4685) && (memcmp(stunMsg.xorMappedAddress.addr.v6.addr, ip6Addr, sizeof(ip6Addr)) == 0)); }
void stunHandler(struct socketConfig* config, struct sockaddr* from_addr, void* cb, unsigned char* buf, int buflen) { StunMessage stunRequest; /* STUN_INCOMING_REQ_DATA pReq; */ STUN_CLIENT_DATA* clientData = (STUN_CLIENT_DATA*)cb; char realm[STUN_MSG_MAX_REALM_LENGTH]; uint8_t enf_flags = 0; uint8_t enf_nodeCnt = 0; uint16_t enf_upMaxBandwidth = 0; uint16_t enf_downMaxBandwidth = 0; stun_pkt_cnt++; byte_cnt += buflen; /* printf("Got a STUN message... (%i)\n", buflen); */ stunlib_DecodeMessage(buf, buflen, &stunRequest, NULL, NULL); /* printf("Finished decoding..\n"); */ if (stunRequest.msgHdr.msgType == STUN_MSG_DataIndicationMsg) { if (stunRequest.hasData) { /* Decode and do something with the data? */ /* config->data_handler(config->socketConfig[i].sockfd, */ /* config->socketConfig[i].tInst, */ /* &buf[stunResponse.data.offset]); */ } } if (stunRequest.hasRealm) { memcpy(&realm, stunRequest.realm.value, STUN_MSG_MAX_REALM_LENGTH); } if (stunRequest.hasEnfNetworkStatus) { enf_flags = stunRequest.enfNetworkStatusResp.flags; enf_nodeCnt = stunRequest.enfNetworkStatusResp.nodeCnt; enf_upMaxBandwidth = stunRequest.enfNetworkStatusResp.upMaxBandwidth; enf_downMaxBandwidth = stunRequest.enfNetworkStatusResp.downMaxBandwidth; } if (stunRequest.hasMessageIntegrity) { /* printf("Checking integrity..%s\n", config->pass); */ if ( !stunlib_checkIntegrity( buf, buflen, &stunRequest, (uint8_t*)config->pass, strlen(config->pass) ) ) { printf(" - Integrity check NOT OK\n"); return; } } uint32_t lastReqCnt = 0; if (stunRequest.hasTransCount) { lastReqCnt = stunRequest.transCount.reqCnt; /* lastRespCnt = stunRequest.transCount.respCnt; */ } if (lastReqCnt >= upstream_loss) { /* Store some stats.. */ int32_t num = insertTransId(&stunRequest.msgHdr.id); StunServer_SendConnectivityBindingResp(clientData, config->sockfd, stunRequest.msgHdr.id, PASSWORD, from_addr, from_addr, lastReqCnt, num, enf_flags, enf_nodeCnt + 1, enf_upMaxBandwidth, enf_downMaxBandwidth, NULL, sendPacket, SOCK_DGRAM, false, 200); } else { printf("Weird...\n"); } }