Collaboration diagram for STUN code:
| #define SWITCH_STUN_ATTRIBUTE_MIN_LEN 8 |
| #define switch_stun_attribute_padded_length | ( | attribute | ) | ((uint16_t)(attribute->length + (sizeof(uint32_t)-1)) & ~sizeof(uint32_t)) |
Obtain the padded length of an attribute's value.
| attribute | the attribute |
Definition at line 218 of file switch_stun.h.
Referenced by switch_stun_packet_parse().
| #define SWITCH_STUN_DEFAULT_PORT 3478 |
Definition at line 41 of file switch_stun.h.
| #define switch_stun_packet_first_attribute | ( | packet, | |||
| attribute | ) | attribute = (switch_stun_packet_attribute_t *)(&packet->first_attribute); |
set a switch_stun_packet_attribute_t pointer to point at the first attribute in a packet
| packet | the packet in question | |
| attribute | the pointer to set up |
Definition at line 225 of file switch_stun.h.
Referenced by handle_ice(), switch_stun_lookup(), and switch_stun_packet_parse().
| #define switch_stun_packet_length | ( | packet | ) | ntohs(packet->header.length) + (sizeof(switch_stun_packet_header_t)) |
Obtain the correct length in bytes of a stun packet.
| packet | the packet in question |
Definition at line 240 of file switch_stun.h.
Referenced by do_stun_ping(), handle_ice(), ice_out(), and switch_stun_lookup().
| #define SWITCH_STUN_PACKET_MIN_LEN 20 |
| #define switch_stun_packet_next_attribute | ( | attribute, | |||
| end | ) | (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length(attribute))) && ((void *)attribute < end) && attribute->length && ((void *)(attribute + switch_stun_attribute_padded_length(attribute)) < end)) |
Increment an attribute pointer to the next attribute in it's packet.
| attribute | the pointer to increment | |
| end | pointer to the end of the buffer |
Definition at line 233 of file switch_stun.h.
Referenced by handle_ice(), switch_stun_lookup(), and switch_stun_packet_parse().
Definition at line 60 of file switch_stun.h.
00060 { 00061 SWITCH_STUN_ATTR_MAPPED_ADDRESS = 0x0001, /* Address */ 00062 SWITCH_STUN_ATTR_RESPONSE_ADDRESS = 0x0002, /* Address */ 00063 SWITCH_STUN_ATTR_CHANGE_REQUEST = 0x0003, /* UInt32 */ 00064 SWITCH_STUN_ATTR_SOURCE_ADDRESS = 0x0004, /* Address */ 00065 SWITCH_STUN_ATTR_CHANGED_ADDRESS = 0x0005, /* Address */ 00066 SWITCH_STUN_ATTR_USERNAME = 0x0006, /* ByteString, multiple of 4 bytes */ 00067 SWITCH_STUN_ATTR_PASSWORD = 0x0007, /* ByteString, multiple of 4 bytes */ 00068 SWITCH_STUN_ATTR_MESSAGE_INTEGRITY = 0x0008, /* ByteString, 20 bytes */ 00069 SWITCH_STUN_ATTR_ERROR_CODE = 0x0009, /* ErrorCode */ 00070 SWITCH_STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000a, /* UInt16List */ 00071 SWITCH_STUN_ATTR_REFLECTED_FROM = 0x000b, /* Address */ 00072 SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES = 0x000c, /* TransportPrefs */ 00073 SWITCH_STUN_ATTR_LIFETIME = 0x000d, /* UInt32 */ 00074 SWITCH_STUN_ATTR_ALTERNATE_SERVER = 0x000e, /* Address */ 00075 SWITCH_STUN_ATTR_MAGIC_COOKIE = 0x000f, /* ByteString, 4 bytes */ 00076 SWITCH_STUN_ATTR_BANDWIDTH = 0x0010, /* UInt32 */ 00077 SWITCH_STUN_ATTR_DESTINATION_ADDRESS = 0x0011, /* Address */ 00078 SWITCH_STUN_ATTR_SOURCE_ADDRESS2 = 0x0012, /* Address */ 00079 SWITCH_STUN_ATTR_DATA = 0x0013, /* ByteString */ 00080 SWITCH_STUN_ATTR_OPTIONS = 0x8001 /* UInt32 */ 00081 } switch_stun_attribute_t;
| enum switch_stun_error_t |
Definition at line 83 of file switch_stun.h.
00083 { 00084 SWITCH_STUN_ERROR_BAD_REQUEST = 400, 00085 SWITCH_STUN_ERROR_UNAUTHORIZED = 401, 00086 SWITCH_STUN_ERROR_UNKNOWN_ATTRIBUTE = 420, 00087 SWITCH_STUN_ERROR_STALE_CREDENTIALS = 430, 00088 SWITCH_STUN_ERROR_INTEGRITY_CHECK_FAILURE = 431, 00089 SWITCH_STUN_ERROR_MISSING_USERNAME = 432, 00090 SWITCH_STUN_ERROR_USE_TLS = 433, 00091 SWITCH_STUN_ERROR_SERVER_ERROR = 500, 00092 SWITCH_STUN_ERROR_GLOBAL_FAILURE = 600 00093 } switch_stun_error_t;
Definition at line 44 of file switch_stun.h.
00044 { 00045 SWITCH_STUN_BINDING_REQUEST = 0x0001, 00046 SWITCH_STUN_BINDING_RESPONSE = 0x0101, 00047 SWITCH_STUN_BINDING_ERROR_RESPONSE = 0x0111, 00048 SWITCH_STUN_SHARED_SECRET_REQUEST = 0x0002, 00049 SWITCH_STUN_SHARED_SECRET_RESPONSE = 0x0102, 00050 SWITCH_STUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112, 00051 SWITCH_STUN_ALLOCATE_REQUEST = 0x0003, 00052 SWITCH_STUN_ALLOCATE_RESPONSE = 0x0103, 00053 SWITCH_STUN_ALLOCATE_ERROR_RESPONSE = 0x0113, 00054 SWITCH_STUN_SEND_REQUEST = 0x0004, 00055 SWITCH_STUN_SEND_RESPONSE = 0x0104, 00056 SWITCH_STUN_SEND_ERROR_RESPONSE = 0x0114, 00057 SWITCH_STUN_DATA_INDICATION = 0x0115 00058 } switch_stun_message_t;
| enum switch_stun_type_t |
Definition at line 95 of file switch_stun.h.
00095 { 00096 SWITCH_STUN_TYPE_PACKET_TYPE, 00097 SWITCH_STUN_TYPE_ATTRIBUTE, 00098 SWITCH_STUN_TYPE_ERROR 00099 } switch_stun_type_t;
| char* switch_stun_host_lookup | ( | const char * | host, | |
| switch_memory_pool_t * | pool | |||
| ) |
Definition at line 429 of file switch_stun.c.
References buf, switch_core_strdup, switch_get_addr(), switch_sockaddr_info_get(), switch_str_nil, and SWITCH_UNSPEC.
00430 { 00431 switch_sockaddr_t *addr = NULL; 00432 char buf[30]; 00433 00434 switch_sockaddr_info_get(&addr, host, SWITCH_UNSPEC, 0, 0, pool); 00435 return switch_core_strdup(pool, switch_str_nil(switch_get_addr(buf, sizeof(buf), addr))); 00436 00437 }
| switch_status_t switch_stun_lookup | ( | char ** | ip, | |
| switch_port_t * | port, | |||
| char * | stunip, | |||
| switch_port_t | stunport, | |||
| char ** | err, | |||
| switch_memory_pool_t * | pool | |||
| ) |
Perform a stun lookup.
| ip | the local ip to use (replaced with stun results) | |
| port | the local port to use (replaced with stun results) | |
| stunip | the ip of the stun server | |
| stunport | the port of the stun server | |
| err | a pointer to describe errors | |
| pool | the memory pool to use |
Definition at line 439 of file switch_stun.c.
References switch_stun_ip_t::address, buf, switch_assert, switch_cond_next(), switch_core_strdup, switch_micro_time_now(), SWITCH_SHUTDOWN_READWRITE, SWITCH_SO_NONBLOCK, switch_sockaddr_info_get(), switch_socket_bind(), switch_socket_close(), switch_socket_create(), switch_socket_opt_set(), switch_socket_recvfrom(), switch_socket_sendto(), switch_socket_shutdown(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, SWITCH_STUN_ATTR_MAPPED_ADDRESS, SWITCH_STUN_ATTR_USERNAME, SWITCH_STUN_BINDING_REQUEST, SWITCH_STUN_BINDING_RESPONSE, switch_stun_packet_attribute_add_username(), switch_stun_packet_attribute_get_mapped_address(), switch_stun_packet_attribute_get_username(), switch_stun_packet_build_header(), switch_stun_packet_first_attribute, switch_stun_packet_length, switch_stun_packet_next_attribute, switch_stun_packet_parse(), switch_stun_random_string(), SWITCH_UNSPEC, TRUE, switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.
00441 { 00442 switch_sockaddr_t *local_addr = NULL, *remote_addr = NULL, *from_addr = NULL; 00443 switch_socket_t *sock = NULL; 00444 uint8_t buf[260] = { 0 }; 00445 uint8_t *start = buf; 00446 void *end_buf; 00447 switch_stun_packet_t *packet; 00448 switch_stun_packet_attribute_t *attr; 00449 switch_size_t bytes = 0; 00450 char username[33] = { 0 }; 00451 char rip[16] = { 0 }; 00452 uint16_t rport = 0; 00453 switch_time_t started = 0; 00454 unsigned int elapsed = 0; 00455 int funny = 0; 00456 int size = sizeof(buf); 00457 00458 switch_assert(err); 00459 00460 if (*err && !strcmp(*err, "funny")) { 00461 funny = 1; 00462 } 00463 00464 *err = "Success"; 00465 00466 switch_sockaddr_info_get(&from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool); 00467 00468 if (switch_sockaddr_info_get(&local_addr, *ip, SWITCH_UNSPEC, *port, 0, pool) != SWITCH_STATUS_SUCCESS) { 00469 *err = "Local Address Error!"; 00470 return SWITCH_STATUS_FALSE; 00471 } 00472 00473 if (switch_sockaddr_info_get(&remote_addr, stunip, SWITCH_UNSPEC, stunport, 0, pool) != SWITCH_STATUS_SUCCESS) { 00474 *err = "Remote Address Error!"; 00475 return SWITCH_STATUS_FALSE; 00476 } 00477 00478 if (switch_socket_create(&sock, AF_INET, SOCK_DGRAM, 0, pool) != SWITCH_STATUS_SUCCESS) { 00479 *err = "Socket Error!"; 00480 return SWITCH_STATUS_FALSE; 00481 } 00482 00483 if (switch_socket_bind(sock, local_addr) != SWITCH_STATUS_SUCCESS) { 00484 *err = "Bind Error!"; 00485 return SWITCH_STATUS_FALSE; 00486 } 00487 00488 if (funny) { 00489 *start++ = 0; 00490 *start++ = 0; 00491 *start++ = 0x22; 00492 *start++ = 0x22; 00493 } 00494 00495 switch_socket_opt_set(sock, SWITCH_SO_NONBLOCK, TRUE); 00496 packet = switch_stun_packet_build_header(SWITCH_STUN_BINDING_REQUEST, NULL, start); 00497 switch_stun_random_string(username, 32, NULL); 00498 switch_stun_packet_attribute_add_username(packet, username, 32); 00499 bytes = switch_stun_packet_length(packet); 00500 00501 if (funny) { 00502 packet = (switch_stun_packet_t *) buf; 00503 bytes += 4; 00504 buf[bytes++] = 0; 00505 buf[bytes++] = 0; 00506 buf[bytes++] = 0; 00507 buf[bytes++] = 0; 00508 } 00509 00510 switch_socket_sendto(sock, remote_addr, 0, (void *) packet, &bytes); 00511 started = switch_micro_time_now(); 00512 00513 *ip = NULL; 00514 *port = 0; 00515 00516 00517 for (;;) { 00518 bytes = sizeof(buf); 00519 if (switch_socket_recvfrom(from_addr, sock, 0, (char *) &buf, &bytes) == SWITCH_STATUS_SUCCESS && bytes > 0) { 00520 break; 00521 } 00522 00523 if ((elapsed = (unsigned int) ((switch_micro_time_now() - started) / 1000)) > 5000) { 00524 *err = "Timeout"; 00525 switch_socket_shutdown(sock, SWITCH_SHUTDOWN_READWRITE); 00526 switch_socket_close(sock); 00527 return SWITCH_STATUS_TIMEOUT; 00528 } 00529 switch_cond_next(); 00530 } 00531 switch_socket_close(sock); 00532 00533 if (funny) { 00534 size -= 4; 00535 } 00536 00537 packet = switch_stun_packet_parse(start, size); 00538 if (!packet) { 00539 *err = "Invalid STUN/ICE packet"; 00540 return SWITCH_STATUS_FALSE; 00541 } 00542 end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf)); 00543 00544 switch_stun_packet_first_attribute(packet, attr); 00545 do { 00546 switch (attr->type) { 00547 case SWITCH_STUN_ATTR_MAPPED_ADDRESS: 00548 if (attr->type) { 00549 if (funny) { 00550 switch_stun_ip_t *tmp = (switch_stun_ip_t *) attr->value; 00551 tmp->address ^= ntohl(0xabcdabcd); 00552 } 00553 switch_stun_packet_attribute_get_mapped_address(attr, rip, &rport); 00554 } 00555 break; 00556 case SWITCH_STUN_ATTR_USERNAME: 00557 if (attr->type) { 00558 switch_stun_packet_attribute_get_username(attr, username, 32); 00559 } 00560 break; 00561 } 00562 } while (switch_stun_packet_next_attribute(attr, end_buf)); 00563 00564 if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) { 00565 *ip = switch_core_strdup(pool, rip); 00566 *port = rport; 00567 return SWITCH_STATUS_SUCCESS; 00568 } else { 00569 *err = "Invalid Reply"; 00570 } 00571 00572 return SWITCH_STATUS_FALSE; 00573 }
| uint8_t switch_stun_packet_attribute_add_binded_address | ( | switch_stun_packet_t * | packet, | |
| char * | ipstr, | |||
| uint16_t | port | |||
| ) |
Add a binded address packet attribute.
| packet | the packet to add the attribute to | |
| ipstr | the string representation of the ip | |
| port | the port of the mapped address |
Definition at line 380 of file switch_stun.c.
References switch_stun_ip_t::address, switch_stun_ip_t::family, switch_stun_packet_attribute_t::length, switch_stun_ip_t::port, SWITCH_STUN_ATTR_MAPPED_ADDRESS, switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.
Referenced by handle_ice().
00381 { 00382 switch_stun_packet_attribute_t *attribute; 00383 switch_stun_ip_t *ip; 00384 uint8_t *i, x; 00385 char *p = ipstr; 00386 00387 attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length)); 00388 attribute->type = htons(SWITCH_STUN_ATTR_MAPPED_ADDRESS); 00389 attribute->length = htons(8); 00390 ip = (switch_stun_ip_t *) attribute->value; 00391 00392 ip->port = htons(port); 00393 ip->family = 1; 00394 i = (uint8_t *) & ip->address; 00395 00396 for (x = 0; x < 4; x++) { 00397 i[x] = (uint8_t) atoi(p); 00398 if ((p = strchr(p, '.'))) { 00399 p++; 00400 } else { 00401 break; 00402 } 00403 } 00404 00405 packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length; 00406 return 1; 00407 }
| uint8_t switch_stun_packet_attribute_add_username | ( | switch_stun_packet_t * | packet, | |
| char * | username, | |||
| uint16_t | ulen | |||
| ) |
Add a username packet attribute.
| packet | the packet to add the attribute to | |
| username | the string representation of the username | |
| ulen | the length of the username |
Definition at line 409 of file switch_stun.c.
References switch_stun_packet_attribute_t::length, SWITCH_STUN_ATTR_USERNAME, switch_stun_random_string(), switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.
Referenced by handle_ice(), ice_out(), and switch_stun_lookup().
00410 { 00411 switch_stun_packet_attribute_t *attribute; 00412 00413 if (ulen % 4 != 0) { 00414 return 0; 00415 } 00416 attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length)); 00417 attribute->type = htons(SWITCH_STUN_ATTR_USERNAME); 00418 attribute->length = htons(ulen); 00419 if (username) { 00420 memcpy(attribute->value, username, ulen); 00421 } else { 00422 switch_stun_random_string(attribute->value, ulen, NULL); 00423 } 00424 00425 packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length; 00426 return 1; 00427 }
| uint8_t switch_stun_packet_attribute_get_mapped_address | ( | switch_stun_packet_attribute_t * | attribute, | |
| char * | ipstr, | |||
| uint16_t * | port | |||
| ) |
Extract a mapped address (IP:PORT) from a packet attribute.
| attribute | the attribute from which to extract | |
| ipstr | a buffer to write the string representation of the ip | |
| port | the port |
Definition at line 337 of file switch_stun.c.
References switch_stun_ip_t::address, and switch_stun_ip_t::port.
Referenced by handle_ice(), and switch_stun_lookup().
00338 { 00339 switch_stun_ip_t *ip; 00340 uint8_t x, *i; 00341 char *p = ipstr; 00342 00343 ip = (switch_stun_ip_t *) attribute->value; 00344 i = (uint8_t *) & ip->address; 00345 *ipstr = 0; 00346 for (x = 0; x < 4; x++) { 00347 sprintf(p, "%u%s", i[x], x == 3 ? "" : "."); 00348 p = ipstr + strlen(ipstr); 00349 } 00350 *port = ip->port; 00351 return 1; 00352 }
| char* switch_stun_packet_attribute_get_username | ( | switch_stun_packet_attribute_t * | attribute, | |
| char * | username, | |||
| uint16_t | len | |||
| ) |
Extract a username from a packet attribute.
| attribute | the attribute from which to extract | |
| username | a buffer to write the string representation of the username | |
| len | the maximum size of the username buffer |
Definition at line 354 of file switch_stun.c.
Referenced by handle_ice(), and switch_stun_lookup().
00355 { 00356 uint16_t cpylen; 00357 00358 cpylen = attribute->length < len ? attribute->length : len; 00359 return memcpy(username, attribute->value, cpylen); 00360 }
| switch_stun_packet_t* switch_stun_packet_build_header | ( | switch_stun_message_t | type, | |
| char * | id, | |||
| uint8_t * | buf | |||
| ) |
Prepare a new outbound packet of a certian type and id.
| id | id to use (NULL for an auto generated id) | |
| type | the stun packet type | |
| buf | a pointer to data to use for the packet |
Definition at line 362 of file switch_stun.c.
References switch_stun_packet_header_t::id, switch_stun_packet_header_t::length, switch_stun_random_string(), and switch_stun_packet_header_t::type.
Referenced by do_stun_ping(), handle_ice(), ice_out(), and switch_stun_lookup().
00363 { 00364 switch_stun_packet_header_t *header; 00365 00366 00367 header = (switch_stun_packet_header_t *) buf; 00368 header->type = htons(type); 00369 header->length = 0; 00370 00371 if (id) { 00372 memcpy(header->id, id, 16); 00373 } else { 00374 switch_stun_random_string(header->id, 16, NULL); 00375 } 00376 00377 return (switch_stun_packet_t *) buf; 00378 }
| switch_stun_packet_t* switch_stun_packet_parse | ( | uint8_t * | buf, | |
| uint32_t | len | |||
| ) |
Prepare a raw packet for parsing.
| buf | the raw data | |
| len | the length of the data |
Definition at line 115 of file switch_stun.c.
References switch_stun_ip_t::family, switch_stun_packet_t::header, switch_stun_packet_header_t::length, switch_stun_packet_attribute_t::length, switch_stun_ip_t::port, SWITCH_STUN_ALLOCATE_ERROR_RESPONSE, SWITCH_STUN_ALLOCATE_REQUEST, SWITCH_STUN_ALLOCATE_RESPONSE, SWITCH_STUN_ATTR_ALTERNATE_SERVER, SWITCH_STUN_ATTR_BANDWIDTH, SWITCH_STUN_ATTR_CHANGE_REQUEST, SWITCH_STUN_ATTR_CHANGED_ADDRESS, SWITCH_STUN_ATTR_DATA, SWITCH_STUN_ATTR_DESTINATION_ADDRESS, SWITCH_STUN_ATTR_ERROR_CODE, SWITCH_STUN_ATTR_LIFETIME, SWITCH_STUN_ATTR_MAGIC_COOKIE, SWITCH_STUN_ATTR_MAPPED_ADDRESS, SWITCH_STUN_ATTR_MESSAGE_INTEGRITY, SWITCH_STUN_ATTR_OPTIONS, SWITCH_STUN_ATTR_PASSWORD, SWITCH_STUN_ATTR_REFLECTED_FROM, SWITCH_STUN_ATTR_RESPONSE_ADDRESS, SWITCH_STUN_ATTR_SOURCE_ADDRESS, SWITCH_STUN_ATTR_SOURCE_ADDRESS2, SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES, SWITCH_STUN_ATTR_UNKNOWN_ATTRIBUTES, SWITCH_STUN_ATTR_USERNAME, SWITCH_STUN_ATTRIBUTE_MIN_LEN, switch_stun_attribute_padded_length, SWITCH_STUN_BINDING_ERROR_RESPONSE, SWITCH_STUN_BINDING_REQUEST, SWITCH_STUN_BINDING_RESPONSE, SWITCH_STUN_DATA_INDICATION, switch_stun_packet_first_attribute, SWITCH_STUN_PACKET_MIN_LEN, switch_stun_packet_next_attribute, SWITCH_STUN_SEND_ERROR_RESPONSE, SWITCH_STUN_SEND_REQUEST, SWITCH_STUN_SEND_RESPONSE, SWITCH_STUN_SHARED_SECRET_ERROR_RESPONSE, SWITCH_STUN_SHARED_SECRET_REQUEST, SWITCH_STUN_SHARED_SECRET_RESPONSE, switch_stun_packet_header_t::type, switch_stun_packet_attribute_t::type, and switch_stun_packet_attribute_t::value.
Referenced by handle_ice(), and switch_stun_lookup().
00116 { 00117 switch_stun_packet_t *packet; 00118 switch_stun_packet_attribute_t *attr; 00119 uint32_t bytes_left = len; 00120 void *end_buf = buf + len; 00121 00122 if (len < SWITCH_STUN_PACKET_MIN_LEN) { 00123 return NULL; 00124 } 00125 00126 packet = (switch_stun_packet_t *) buf; 00127 packet->header.type = ntohs(packet->header.type); 00128 packet->header.length = ntohs(packet->header.length); 00129 bytes_left -= packet->header.length + 20; 00130 00131 /* 00132 * Check packet type (RFC3489(bis?) values) 00133 */ 00134 switch (packet->header.type) { 00135 case SWITCH_STUN_BINDING_REQUEST: 00136 case SWITCH_STUN_BINDING_RESPONSE: 00137 case SWITCH_STUN_BINDING_ERROR_RESPONSE: 00138 case SWITCH_STUN_SHARED_SECRET_REQUEST: 00139 case SWITCH_STUN_SHARED_SECRET_RESPONSE: 00140 case SWITCH_STUN_SHARED_SECRET_ERROR_RESPONSE: 00141 case SWITCH_STUN_ALLOCATE_REQUEST: 00142 case SWITCH_STUN_ALLOCATE_RESPONSE: 00143 case SWITCH_STUN_ALLOCATE_ERROR_RESPONSE: 00144 case SWITCH_STUN_SEND_REQUEST: 00145 case SWITCH_STUN_SEND_RESPONSE: 00146 case SWITCH_STUN_SEND_ERROR_RESPONSE: 00147 case SWITCH_STUN_DATA_INDICATION: 00148 /* Valid */ 00149 break; 00150 00151 default: 00152 /* Invalid value */ 00153 return NULL; 00154 } 00155 00156 /* 00157 * Check for length overflow 00158 */ 00159 if (bytes_left <= 0) { 00160 /* Invalid */ 00161 return NULL; 00162 } 00163 00164 /* 00165 * No payload? 00166 */ 00167 if (packet->header.length == 0) { 00168 /* Invalid?! */ 00169 return NULL; 00170 } 00171 00172 /* check if we have enough bytes left for an attribute */ 00173 if (bytes_left < SWITCH_STUN_ATTRIBUTE_MIN_LEN) { 00174 return NULL; 00175 } 00176 00177 switch_stun_packet_first_attribute(packet, attr); 00178 do { 00179 attr->length = ntohs(attr->length); 00180 attr->type = ntohs(attr->type); 00181 bytes_left -= 4; /* attribute header consumed */ 00182 00183 if (!attr->length || switch_stun_attribute_padded_length(attr) > bytes_left) { 00184 /* 00185 * Note we simply don't "break" here out of the loop anymore because 00186 * we don't want the upper layers to have to deal with attributes without a value 00187 * (or worse: invalid length) 00188 */ 00189 return NULL; 00190 } 00191 00192 /* 00193 * Handle STUN attributes 00194 */ 00195 switch (attr->type) { 00196 case SWITCH_STUN_ATTR_MAPPED_ADDRESS: /* Address, we only care about this one, but parse the others too */ 00197 case SWITCH_STUN_ATTR_RESPONSE_ADDRESS: 00198 case SWITCH_STUN_ATTR_SOURCE_ADDRESS: 00199 case SWITCH_STUN_ATTR_CHANGED_ADDRESS: 00200 case SWITCH_STUN_ATTR_REFLECTED_FROM: 00201 case SWITCH_STUN_ATTR_ALTERNATE_SERVER: 00202 case SWITCH_STUN_ATTR_DESTINATION_ADDRESS: 00203 case SWITCH_STUN_ATTR_SOURCE_ADDRESS2: 00204 { 00205 switch_stun_ip_t *ip; 00206 uint32_t addr_length = 0; 00207 ip = (switch_stun_ip_t *) attr->value; 00208 00209 switch (ip->family) { 00210 case 0x01: /* IPv4 */ 00211 addr_length = 4; 00212 break; 00213 00214 case 0x02: /* IPv6 */ 00215 addr_length = 16; 00216 break; 00217 00218 default: /* Invalid */ 00219 return NULL; 00220 } 00221 00222 /* attribute payload length must be == address length + size of other payload fields (family...) */ 00223 if (attr->length != addr_length + 4) { 00224 /* Invalid */ 00225 return NULL; 00226 } 00227 00228 ip->port = ntohs(ip->port); 00229 } 00230 break; 00231 00232 case SWITCH_STUN_ATTR_CHANGE_REQUEST: /* UInt32 */ 00233 case SWITCH_STUN_ATTR_LIFETIME: 00234 case SWITCH_STUN_ATTR_BANDWIDTH: 00235 case SWITCH_STUN_ATTR_OPTIONS: 00236 { 00237 uint32_t *val = (uint32_t *) attr->value; 00238 00239 if (attr->length != sizeof(uint32_t)) { 00240 /* Invalid */ 00241 return NULL; 00242 } 00243 00244 *val = ntohl(*val); /* should we do this here? */ 00245 } 00246 break; 00247 00248 case SWITCH_STUN_ATTR_USERNAME: /* ByteString, multiple of 4 bytes */ 00249 case SWITCH_STUN_ATTR_PASSWORD: /* ByteString, multiple of 4 bytes */ 00250 if (attr->length % 4 != 0) { 00251 /* Invalid */ 00252 return NULL; 00253 } 00254 break; 00255 00256 case SWITCH_STUN_ATTR_DATA: /* ByteString */ 00257 case SWITCH_STUN_ATTR_ERROR_CODE: /* ErrorCode */ 00258 case SWITCH_STUN_ATTR_TRANSPORT_PREFERENCES: /* TransportPrefs */ 00259 /* 00260 * No length checking here, since we already checked against the padded length 00261 * before 00262 */ 00263 break; 00264 00265 case SWITCH_STUN_ATTR_MESSAGE_INTEGRITY: /* ByteString, 20 bytes */ 00266 if (attr->length != 20) { 00267 /* Invalid */ 00268 return NULL; 00269 } 00270 break; 00271 00272 case SWITCH_STUN_ATTR_MAGIC_COOKIE: /* ByteString, 4 bytes */ 00273 if (attr->length != 4) { 00274 /* Invalid */ 00275 return NULL; 00276 } 00277 break; 00278 00279 case SWITCH_STUN_ATTR_UNKNOWN_ATTRIBUTES: /* UInt16List (= multiple of 2 bytes) */ 00280 if (attr->length % 2 != 0) { 00281 return NULL; 00282 } 00283 break; 00284 00285 default: 00286 /* Mandatory attribute range? => invalid */ 00287 if (attr->type <= 0x7FFF) { 00288 return NULL; 00289 } 00290 break; 00291 } 00292 bytes_left -= switch_stun_attribute_padded_length(attr); /* attribute value consumed, substract padded length */ 00293 00294 } while (bytes_left >= SWITCH_STUN_ATTRIBUTE_MIN_LEN && switch_stun_packet_next_attribute(attr, end_buf)); 00295 00296 if ((uint32_t) (packet->header.length + 20) > (uint32_t) (len - bytes_left)) { 00297 /* 00298 * the packet length is longer than the length of all attributes? 00299 * for now simply decrease the packet size 00300 */ 00301 packet->header.length = (uint16_t) ((len - bytes_left) - 20); 00302 } 00303 00304 return packet; 00305 }
| void switch_stun_random_string | ( | char * | buf, | |
| uint16_t | len, | |||
| char * | set | |||
| ) |
Writes random characters into a buffer.
| buf | the buffer | |
| len | the length of the data | |
| set | the set of chars to use (NULL for auto) |
Definition at line 96 of file switch_stun.c.
Referenced by switch_core_set_serial(), switch_rtp_get_random(), switch_stun_lookup(), switch_stun_packet_attribute_add_username(), and switch_stun_packet_build_header().
00097 { 00098 char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 00099 int max; 00100 uint16_t x; 00101 00102 if (!set) { 00103 set = chars; 00104 } 00105 00106 max = (int) strlen(set); 00107 00108 for (x = 0; x < len; x++) { 00109 int j = (int) (max * 1.0 * rand() / (RAND_MAX + 1.0)); 00110 buf[x] = set[j]; 00111 } 00112 }
| const char* switch_stun_value_to_name | ( | int32_t | type, | |
| uint32_t | value | |||
| ) |
Obtain a printable string form of a given value.
| type | the type of message | |
| value | the value to look up |
Definition at line 307 of file switch_stun.c.
References ATTR_TYPES, ERROR_TYPES, value_mapping::name, PACKET_TYPES, SWITCH_STUN_TYPE_ATTRIBUTE, SWITCH_STUN_TYPE_ERROR, SWITCH_STUN_TYPE_PACKET_TYPE, and value_mapping::value.
00308 { 00309 uint32_t x = 0; 00310 const struct value_mapping *map = NULL; 00311 switch (type) { 00312 case SWITCH_STUN_TYPE_PACKET_TYPE: 00313 map = PACKET_TYPES; 00314 break; 00315 case SWITCH_STUN_TYPE_ATTRIBUTE: 00316 map = ATTR_TYPES; 00317 break; 00318 case SWITCH_STUN_TYPE_ERROR: 00319 map = ERROR_TYPES; 00320 break; 00321 default: 00322 map = NULL; 00323 break; 00324 } 00325 00326 if (map) { 00327 for (x = 0; map[x].value; x++) { 00328 if (map[x].value == value) { 00329 return map[x].name; 00330 } 00331 } 00332 } 00333 00334 return "INVALID"; 00335 }
1.4.7