blob: 90dd36a8a2d084943dd731759f14d5d63eeb2048 [file] [log] [blame]
Benny Prijono4766ffe2005-11-01 17:56:59 +00001/* $Id$
Benny Prijonodd859a62005-11-01 16:42:51 +00002 */
3#include <pj/stun.h>
4#include <pj/pool.h>
5#include <pj/log.h>
6#include <pj/sock.h>
7#include <pj/os.h>
8
9#define THIS_FILE "stun"
10
11PJ_DEF(pj_status_t) pj_stun_create_bind_req( pj_pool_t *pool,
12 void **msg, pj_size_t *len,
13 pj_uint32_t id_hi,
14 pj_uint32_t id_lo)
15{
16 pj_stun_msg_hdr *hdr;
17
18 PJ_CHECK_STACK();
19
20 PJ_LOG(5,(THIS_FILE, "pj_stun_create_bind_req"));
21
22 hdr = pj_pool_calloc(pool, 1, sizeof(pj_stun_msg_hdr));
23 if (!hdr) {
24 PJ_LOG(5,(THIS_FILE, "Error allocating memory!"));
25 return -1;
26 }
27
28 hdr->type = pj_htons(PJ_STUN_BINDING_REQUEST);
29 hdr->tsx[2] = pj_htonl(id_hi);
30 hdr->tsx[3] = pj_htonl(id_lo);
31 *msg = hdr;
32 *len = sizeof(pj_stun_msg_hdr);
33
34 return 0;
35}
36
37PJ_DEF(pj_status_t) pj_stun_parse_msg( void *buf, pj_size_t len,
38 pj_stun_msg *msg)
39{
40 pj_uint16_t msg_type, msg_len;
41 char *p_attr;
42
43 PJ_CHECK_STACK();
44
45 PJ_LOG(5,(THIS_FILE, "pj_stun_parse_msg %p, len=%d", buf, len));
46
47 msg->hdr = (pj_stun_msg_hdr*)buf;
48 msg_type = pj_ntohs(msg->hdr->type);
49
50 switch (msg_type) {
51 case PJ_STUN_BINDING_REQUEST:
52 case PJ_STUN_BINDING_RESPONSE:
53 case PJ_STUN_BINDING_ERROR_RESPONSE:
54 case PJ_STUN_SHARED_SECRET_REQUEST:
55 case PJ_STUN_SHARED_SECRET_RESPONSE:
56 case PJ_STUN_SHARED_SECRET_ERROR_RESPONSE:
57 break;
58 default:
59 PJ_LOG(5,(THIS_FILE, "Error: unknown msg type %d", msg_type));
60 return -1;
61 }
62
63 msg_len = pj_ntohs(msg->hdr->length);
64 if (msg_len != len - sizeof(pj_stun_msg_hdr)) {
65 PJ_LOG(5,(THIS_FILE, "Error: invalid msg_len %d (expecting %d)",
66 msg_len, len - sizeof(pj_stun_msg_hdr)));
67 return -1;
68 }
69
70 msg->attr_count = 0;
71 p_attr = (char*)buf + sizeof(pj_stun_msg_hdr);
72
73 while (msg_len > 0) {
74 pj_stun_attr_hdr **attr = &msg->attr[msg->attr_count];
75 pj_uint32_t len;
76
77 *attr = (pj_stun_attr_hdr*)p_attr;
78 len = pj_ntohs((pj_uint16_t) ((*attr)->length)) + sizeof(pj_stun_attr_hdr);
79
80 if (msg_len < len) {
81 PJ_LOG(5,(THIS_FILE, "Error: length mismatch in attr %d",
82 msg->attr_count));
83 return -1;
84 }
85
86 if (pj_ntohs((*attr)->type) > PJ_STUN_ATTR_REFLECTED_FORM) {
87 PJ_LOG(5,(THIS_FILE, "Error: invalid attr type %d in attr %d",
88 pj_ntohs((*attr)->type), msg->attr_count));
89 return -1;
90 }
91
92 msg_len = (pj_uint16_t)(msg_len - len);
93 p_attr += len;
94 ++msg->attr_count;
95 }
96
97 return 0;
98}
99
100PJ_DEF(void*) pj_stun_msg_find_attr( pj_stun_msg *msg, pj_stun_attr_type t)
101{
102 int i;
103
104 PJ_CHECK_STACK();
105
106 for (i=0; i<msg->attr_count; ++i) {
107 pj_stun_attr_hdr *attr = msg->attr[i];
108 if (pj_ntohs(attr->type) == t)
109 return attr;
110 }
111
112 return 0;
113}