00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __PJNATH_STUN_MSG_H__
00021 #define __PJNATH_STUN_MSG_H__
00022
00028 #include <pjnath/types.h>
00029 #include <pj/sock.h>
00030
00031
00032 PJ_BEGIN_DECL
00033
00034
00035
00047 #define PJ_STUN_MAGIC 0x2112A442
00048
00049
00053 enum pj_stun_method_e
00054 {
00058 PJ_STUN_BINDING_METHOD = 1,
00059
00063 PJ_STUN_SHARED_SECRET_METHOD = 2,
00064
00068 PJ_STUN_ALLOCATE_METHOD = 3,
00069
00073 PJ_STUN_REFRESH_METHOD = 4,
00074
00078 PJ_STUN_SEND_METHOD = 6,
00079
00083 PJ_STUN_DATA_METHOD = 7,
00084
00088 PJ_STUN_CREATE_PERM_METHOD = 8,
00089
00093 PJ_STUN_CHANNEL_BIND_METHOD = 9,
00094
00098 PJ_STUN_METHOD_MAX
00099 };
00100
00101
00106 #define PJ_STUN_GET_METHOD(msg_type) ((msg_type) & 0xFEEF)
00107
00108
00112 enum pj_stun_msg_class_e
00113 {
00117 PJ_STUN_REQUEST_CLASS = 0,
00118
00122 PJ_STUN_INDICATION_CLASS = 1,
00123
00127 PJ_STUN_SUCCESS_CLASS = 2,
00128
00132 PJ_STUN_ERROR_CLASS = 3
00133 };
00134
00135
00139 #define PJ_STUN_IS_REQUEST(msg_type) (((msg_type) & 0x0110) == 0x0000)
00140
00141
00145 #define PJ_STUN_IS_SUCCESS_RESPONSE(msg_type) (((msg_type) & 0x0110) == 0x0100)
00146
00150 #define PJ_STUN_SUCCESS_RESPONSE_BIT (0x0100)
00151
00152
00156 #define PJ_STUN_IS_ERROR_RESPONSE(msg_type) (((msg_type) & 0x0110) == 0x0110)
00157
00161 #define PJ_STUN_ERROR_RESPONSE_BIT (0x0110)
00162
00166 #define PJ_STUN_IS_RESPONSE(msg_type) (((msg_type) & 0x0100) == 0x0100)
00167
00168
00172 #define PJ_STUN_IS_INDICATION(msg_type) (((msg_type) & 0x0110) == 0x0010)
00173
00177 #define PJ_STUN_INDICATION_BIT (0x0010)
00178
00179
00183 typedef enum pj_stun_msg_type
00184 {
00188 PJ_STUN_BINDING_REQUEST = 0x0001,
00189
00193 PJ_STUN_BINDING_RESPONSE = 0x0101,
00194
00198 PJ_STUN_BINDING_ERROR_RESPONSE = 0x0111,
00199
00203 PJ_STUN_BINDING_INDICATION = 0x0011,
00204
00208 PJ_STUN_SHARED_SECRET_REQUEST = 0x0002,
00209
00213 PJ_STUN_SHARED_SECRET_RESPONSE = 0x0102,
00214
00218 PJ_STUN_SHARED_SECRET_ERROR_RESPONSE = 0x0112,
00219
00220
00224 PJ_STUN_ALLOCATE_REQUEST = 0x0003,
00225
00229 PJ_STUN_ALLOCATE_RESPONSE = 0x0103,
00230
00234 PJ_STUN_ALLOCATE_ERROR_RESPONSE = 0x0113,
00235
00236
00240 PJ_STUN_REFRESH_REQUEST = 0x0004,
00241
00245 PJ_STUN_REFRESH_RESPONSE = 0x0104,
00246
00250 PJ_STUN_REFRESH_ERROR_RESPONSE = 0x0114,
00251
00252
00256 PJ_STUN_SEND_INDICATION = 0x0016,
00257
00258
00262 PJ_STUN_DATA_INDICATION = 0x0017,
00263
00264
00268 PJ_STUN_CREATE_PERM_REQUEST = 0x0008,
00269
00273 PJ_STUN_CREATE_PERM_RESPONSE = 0x0108,
00274
00278 PJ_STUN_CREATE_PERM_ERROR_RESPONSE = 0x0118,
00279
00280
00284 PJ_STUN_CHANNEL_BIND_REQUEST = 0x0009,
00285
00289 PJ_STUN_CHANNEL_BIND_RESPONSE = 0x0109,
00290
00294 PJ_STUN_CHANNEL_BIND_ERROR_RESPONSE = 0x0119
00295
00296 } pj_stun_msg_type;
00297
00298
00299
00303 typedef enum pj_stun_attr_type
00304 {
00305 PJ_STUN_ATTR_MAPPED_ADDR = 0x0001,
00306 PJ_STUN_ATTR_RESPONSE_ADDR = 0x0002,
00307 PJ_STUN_ATTR_CHANGE_REQUEST = 0x0003,
00308 PJ_STUN_ATTR_SOURCE_ADDR = 0x0004,
00309 PJ_STUN_ATTR_CHANGED_ADDR = 0x0005,
00310 PJ_STUN_ATTR_USERNAME = 0x0006,
00311 PJ_STUN_ATTR_PASSWORD = 0x0007,
00312 PJ_STUN_ATTR_MESSAGE_INTEGRITY = 0x0008,
00313 PJ_STUN_ATTR_ERROR_CODE = 0x0009,
00314 PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES = 0x000A,
00315 PJ_STUN_ATTR_REFLECTED_FROM = 0x000B,
00316 PJ_STUN_ATTR_CHANNEL_NUMBER = 0x000C,
00317 PJ_STUN_ATTR_LIFETIME = 0x000D,
00318 PJ_STUN_ATTR_MAGIC_COOKIE = 0x000F,
00319 PJ_STUN_ATTR_BANDWIDTH = 0x0010,
00320 PJ_STUN_ATTR_XOR_PEER_ADDR = 0x0012,
00321 PJ_STUN_ATTR_DATA = 0x0013,
00322 PJ_STUN_ATTR_REALM = 0x0014,
00323 PJ_STUN_ATTR_NONCE = 0x0015,
00324 PJ_STUN_ATTR_XOR_RELAYED_ADDR = 0x0016,
00325 PJ_STUN_ATTR_REQ_ADDR_TYPE = 0x0017,
00326 PJ_STUN_ATTR_EVEN_PORT = 0x0018,
00327 PJ_STUN_ATTR_REQ_TRANSPORT = 0x0019,
00328 PJ_STUN_ATTR_DONT_FRAGMENT = 0x001A,
00329 PJ_STUN_ATTR_XOR_MAPPED_ADDR = 0x0020,
00330 PJ_STUN_ATTR_TIMER_VAL = 0x0021,
00331 PJ_STUN_ATTR_RESERVATION_TOKEN = 0x0022,
00332 PJ_STUN_ATTR_XOR_REFLECTED_FROM = 0x0023,
00333 PJ_STUN_ATTR_PRIORITY = 0x0024,
00334 PJ_STUN_ATTR_USE_CANDIDATE = 0x0025,
00335 PJ_STUN_ATTR_ICMP = 0x0030,
00337 PJ_STUN_ATTR_END_MANDATORY_ATTR,
00338
00339 PJ_STUN_ATTR_START_EXTENDED_ATTR= 0x8021,
00340
00341 PJ_STUN_ATTR_SOFTWARE = 0x8022,
00342 PJ_STUN_ATTR_ALTERNATE_SERVER = 0x8023,
00343 PJ_STUN_ATTR_REFRESH_INTERVAL = 0x8024,
00344 PJ_STUN_ATTR_FINGERPRINT = 0x8028,
00345 PJ_STUN_ATTR_ICE_CONTROLLED = 0x8029,
00346 PJ_STUN_ATTR_ICE_CONTROLLING = 0x802a,
00348 PJ_STUN_ATTR_END_EXTENDED_ATTR
00349
00350 } pj_stun_attr_type;
00351
00352
00356 typedef enum pj_stun_status
00357 {
00358 PJ_STUN_SC_TRY_ALTERNATE = 300,
00359 PJ_STUN_SC_BAD_REQUEST = 400,
00360 PJ_STUN_SC_UNAUTHORIZED = 401,
00361 PJ_STUN_SC_FORBIDDEN = 403,
00362 PJ_STUN_SC_UNKNOWN_ATTRIBUTE = 420,
00363 #if 0
00364
00365
00366
00367
00368
00369
00370
00371
00372 #endif
00373 PJ_STUN_SC_ALLOCATION_MISMATCH = 437,
00374 PJ_STUN_SC_STALE_NONCE = 438,
00375 PJ_STUN_SC_TRANSITIONING = 439,
00376 PJ_STUN_SC_WRONG_CREDENTIALS = 441,
00377 PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO = 442,
00379 PJ_STUN_SC_OPER_TCP_ONLY = 445,
00380 PJ_STUN_SC_CONNECTION_FAILURE = 446,
00381 PJ_STUN_SC_CONNECTION_TIMEOUT = 447,
00382 PJ_STUN_SC_ALLOCATION_QUOTA_REACHED = 486,
00384 PJ_STUN_SC_ROLE_CONFLICT = 487,
00385 PJ_STUN_SC_SERVER_ERROR = 500,
00386 PJ_STUN_SC_INSUFFICIENT_CAPACITY = 508,
00388 PJ_STUN_SC_GLOBAL_FAILURE = 600
00389 } pj_stun_status;
00390
00391
00414 typedef struct pj_stun_msg_hdr
00415 {
00419 pj_uint16_t type;
00420
00425 pj_uint16_t length;
00426
00432 pj_uint32_t magic;
00433
00442 pj_uint8_t tsx_id[12];
00443
00444 } pj_stun_msg_hdr;
00445
00446
00462 typedef struct pj_stun_attr_hdr
00463 {
00467 pj_uint16_t type;
00468
00475 pj_uint16_t length;
00476
00477 } pj_stun_attr_hdr;
00478
00479
00505 typedef struct pj_stun_sockaddr_attr
00506 {
00510 pj_stun_attr_hdr hdr;
00511
00516 pj_bool_t xor_ed;
00517
00521 pj_sockaddr sockaddr;
00522
00523 } pj_stun_sockaddr_attr;
00524
00525
00530 typedef struct pj_stun_empty_attr
00531 {
00535 pj_stun_attr_hdr hdr;
00536
00537 } pj_stun_empty_attr;
00538
00539
00544 typedef struct pj_stun_string_attr
00545 {
00549 pj_stun_attr_hdr hdr;
00550
00554 pj_str_t value;
00555
00556 } pj_stun_string_attr;
00557
00558
00563 typedef struct pj_stun_uint_attr
00564 {
00568 pj_stun_attr_hdr hdr;
00569
00573 pj_uint32_t value;
00574
00575 } pj_stun_uint_attr;
00576
00577
00582 typedef struct pj_stun_uint64_attr
00583 {
00587 pj_stun_attr_hdr hdr;
00588
00592 pj_timestamp value;
00593
00594 } pj_stun_uint64_attr;
00595
00596
00601 typedef struct pj_stun_binary_attr
00602 {
00606 pj_stun_attr_hdr hdr;
00607
00612 pj_uint32_t magic;
00613
00617 unsigned length;
00618
00622 pj_uint8_t *data;
00623
00624 } pj_stun_binary_attr;
00625
00626
00634 typedef struct pj_stun_msgint_attr
00635 {
00639 pj_stun_attr_hdr hdr;
00640
00644 pj_uint8_t hmac[20];
00645
00646 } pj_stun_msgint_attr;
00647
00648
00655 typedef struct pj_stun_uint_attr pj_stun_fingerprint_attr;
00656
00657
00676 typedef struct pj_stun_errcode_attr
00677 {
00681 pj_stun_attr_hdr hdr;
00682
00686 int err_code;
00687
00691 pj_str_t reason;
00692
00693 } pj_stun_errcode_attr;
00694
00695
00703 typedef struct pj_stun_string_attr pj_stun_realm_attr;
00704
00705
00713 typedef struct pj_stun_string_attr pj_stun_nonce_attr;
00714
00715
00726 typedef struct pj_stun_unknown_attr
00727 {
00731 pj_stun_attr_hdr hdr;
00732
00736 unsigned attr_count;
00737
00741 pj_uint16_t attrs[PJ_STUN_MAX_ATTR];
00742
00743 } pj_stun_unknown_attr;
00744
00745
00750 typedef struct pj_stun_sockaddr_attr pj_stun_mapped_addr_attr;
00751
00752
00762 typedef struct pj_stun_sockaddr_attr pj_stun_xor_mapped_addr_attr;
00763
00764
00771 typedef struct pj_stun_string_attr pj_stun_software_attr;
00772
00773
00780 typedef struct pj_stun_sockaddr_attr pj_stun_alt_server_attr;
00781
00782
00789 typedef struct pj_stun_uint_attr pj_stun_refresh_interval_attr;
00790
00791
00801 typedef struct pj_stun_sockaddr_attr pj_stun_response_addr_attr;
00802
00803
00816 typedef struct pj_stun_sockaddr_attr pj_stun_changed_addr_attr;
00817
00818
00836 typedef struct pj_stun_uint_attr pj_stun_change_request_attr;
00837
00848 typedef struct pj_stun_sockaddr_attr pj_stun_src_addr_attr;
00849
00850
00860 typedef struct pj_stun_sockaddr_attr pj_stun_reflected_from_attr;
00861
00862
00870 typedef struct pj_stun_string_attr pj_stun_username_attr;
00871
00872
00878 typedef struct pj_stun_string_attr pj_stun_password_attr;
00879
00880
00899 typedef struct pj_stun_uint_attr pj_stun_channel_number_attr;
00900
00907 #define PJ_STUN_GET_CH_NB(u32) ((pj_uint16_t)(u32>>16))
00908
00915 #define PJ_STUN_SET_CH_NB(chnum) (((pj_uint32_t)chnum) << 16)
00916
00917
00925 typedef struct pj_stun_uint_attr pj_stun_lifetime_attr;
00926
00927
00934 typedef struct pj_stun_uint_attr pj_stun_bandwidth_attr;
00935
00936
00943 typedef struct pj_stun_sockaddr_attr pj_stun_xor_peer_addr_attr;
00944
00945
00953 typedef struct pj_stun_binary_attr pj_stun_data_attr;
00954
00955
00962 typedef struct pj_stun_sockaddr_attr pj_stun_xor_relayed_addr_attr;
00963
00964
00981 typedef struct pj_stun_uint_attr pj_stun_req_addr_type_attr;
00982
00983
01011 typedef struct pj_stun_uint_attr pj_stun_even_port_attr;
01012
01013
01042 typedef struct pj_stun_uint_attr pj_stun_req_transport_attr;
01043
01047 #define PJ_STUN_GET_RT_PROTO(u32) (u32 >> 24)
01048
01053 #define PJ_STUN_SET_RT_PROTO(proto) (((pj_uint32_t)(proto)) << 24)
01054
01055
01064 typedef struct pj_stun_empty_attr pj_stun_dont_fragment_attr;
01065
01066
01079 typedef struct pj_stun_uint64_attr pj_stun_res_token_attr;
01080
01091 typedef struct pj_stun_sockaddr_attr pj_stun_xor_reflected_from_attr;
01092
01100 typedef struct pj_stun_uint_attr pj_stun_priority_attr;
01101
01109 typedef struct pj_stun_empty_attr pj_stun_use_candidate_attr;
01110
01117 typedef struct pj_stun_uint_attr pj_stun_timer_val_attr;
01118
01122 typedef struct pj_stun_uint64_attr pj_stun_ice_controlling_attr;
01123
01127 typedef struct pj_stun_uint64_attr pj_stun_ice_controlled_attr;
01128
01132 typedef struct pj_stun_uint_attr pj_stun_icmp_attr;
01133
01139 typedef struct pj_stun_msg
01140 {
01144 pj_stun_msg_hdr hdr;
01145
01149 unsigned attr_count;
01150
01154 pj_stun_attr_hdr *attr[PJ_STUN_MAX_ATTR];
01155
01156 } pj_stun_msg;
01157
01158
01160 enum pj_stun_decode_options
01161 {
01166 PJ_STUN_IS_DATAGRAM = 1,
01167
01173 PJ_STUN_CHECK_PACKET = 2,
01174
01180 PJ_STUN_NO_AUTHENTICATE = 4,
01181
01188 PJ_STUN_NO_FINGERPRINT_CHECK = 8
01189 };
01190
01191
01199 PJ_DECL(const char*) pj_stun_get_method_name(unsigned msg_type);
01200
01201
01209 PJ_DECL(const char*) pj_stun_get_class_name(unsigned msg_type);
01210
01211
01219 PJ_DECL(const char*) pj_stun_get_attr_name(unsigned attr_type);
01220
01221
01229 PJ_DECL(pj_str_t) pj_stun_get_err_reason(int err_code);
01230
01231
01238 PJ_DECL(int) pj_stun_set_padding_char(int chr);
01239
01240
01254 PJ_DECL(pj_status_t) pj_stun_msg_init(pj_stun_msg *msg,
01255 unsigned msg_type,
01256 pj_uint32_t magic,
01257 const pj_uint8_t tsx_id[12]);
01258
01272 PJ_DECL(pj_status_t) pj_stun_msg_create(pj_pool_t *pool,
01273 unsigned msg_type,
01274 pj_uint32_t magic,
01275 const pj_uint8_t tsx_id[12],
01276 pj_stun_msg **p_msg);
01277
01286 PJ_DECL(pj_stun_msg*) pj_stun_msg_clone(pj_pool_t *pool,
01287 const pj_stun_msg *msg);
01288
01305 PJ_DECL(pj_status_t) pj_stun_msg_create_response(pj_pool_t *pool,
01306 const pj_stun_msg *req_msg,
01307 unsigned err_code,
01308 const pj_str_t *err_msg,
01309 pj_stun_msg **p_response);
01310
01311
01321 PJ_DECL(pj_status_t) pj_stun_msg_add_attr(pj_stun_msg *msg,
01322 pj_stun_attr_hdr *attr);
01323
01324
01358 PJ_DECL(pj_status_t) pj_stun_msg_encode(pj_stun_msg *msg,
01359 pj_uint8_t *pkt_buf,
01360 pj_size_t buf_size,
01361 unsigned options,
01362 const pj_str_t *key,
01363 pj_size_t *p_msg_len);
01364
01384 PJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu,
01385 pj_size_t pdu_len, unsigned options);
01386
01387
01409 PJ_DECL(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
01410 const pj_uint8_t *pdu,
01411 pj_size_t pdu_len,
01412 unsigned options,
01413 pj_stun_msg **p_msg,
01414 pj_size_t *p_parsed_len,
01415 pj_stun_msg **p_response);
01416
01429 #if PJ_LOG_MAX_LEVEL > 0
01430 PJ_DECL(char*) pj_stun_msg_dump(const pj_stun_msg *msg,
01431 char *buffer,
01432 unsigned length,
01433 unsigned *printed_len);
01434 #else
01435 # define pj_stun_msg_dump(msg, buf, length, printed_len) ""
01436 #endif
01437
01438
01452 PJ_DECL(pj_stun_attr_hdr*) pj_stun_msg_find_attr(const pj_stun_msg *msg,
01453 int attr_type,
01454 unsigned start_index);
01455
01456
01465 PJ_DECL(pj_stun_attr_hdr*) pj_stun_attr_clone(pj_pool_t *pool,
01466 const pj_stun_attr_hdr *attr);
01467
01468
01483 PJ_DECL(pj_status_t) pj_stun_sockaddr_attr_init(pj_stun_sockaddr_attr *attr,
01484 int attr_type,
01485 pj_bool_t xor_ed,
01486 const pj_sockaddr_t *addr,
01487 unsigned addr_len);
01488
01504 PJ_DECL(pj_status_t) pj_stun_sockaddr_attr_create(pj_pool_t *pool,
01505 int attr_type,
01506 pj_bool_t xor_ed,
01507 const pj_sockaddr_t *addr,
01508 unsigned addr_len,
01509 pj_stun_sockaddr_attr **p_attr);
01510
01511
01527 PJ_DECL(pj_status_t) pj_stun_msg_add_sockaddr_attr(pj_pool_t *pool,
01528 pj_stun_msg *msg,
01529 int attr_type,
01530 pj_bool_t xor_ed,
01531 const pj_sockaddr_t *addr,
01532 unsigned addr_len);
01533
01545 PJ_DECL(pj_status_t) pj_stun_string_attr_init(pj_stun_string_attr *attr,
01546 pj_pool_t *pool,
01547 int attr_type,
01548 const pj_str_t *value);
01549
01560 PJ_DECL(pj_status_t) pj_stun_string_attr_create(pj_pool_t *pool,
01561 int attr_type,
01562 const pj_str_t *value,
01563 pj_stun_string_attr **p_attr);
01564
01575 PJ_DECL(pj_status_t) pj_stun_msg_add_string_attr(pj_pool_t *pool,
01576 pj_stun_msg *msg,
01577 int attr_type,
01578 const pj_str_t *value);
01579
01590 PJ_DECL(pj_status_t) pj_stun_uint_attr_create(pj_pool_t *pool,
01591 int attr_type,
01592 pj_uint32_t value,
01593 pj_stun_uint_attr **p_attr);
01594
01605 PJ_DECL(pj_status_t) pj_stun_msg_add_uint_attr(pj_pool_t *pool,
01606 pj_stun_msg *msg,
01607 int attr_type,
01608 pj_uint32_t value);
01609
01610
01621 PJ_DECL(pj_status_t) pj_stun_uint64_attr_create(pj_pool_t *pool,
01622 int attr_type,
01623 const pj_timestamp *value,
01624 pj_stun_uint64_attr **p_attr);
01625
01626
01637 PJ_DECL(pj_status_t) pj_stun_msg_add_uint64_attr(pj_pool_t *pool,
01638 pj_stun_msg *msg,
01639 int attr_type,
01640 const pj_timestamp *value);
01641
01650 PJ_DECL(pj_status_t) pj_stun_msgint_attr_create(pj_pool_t *pool,
01651 pj_stun_msgint_attr **p_attr);
01652
01661 PJ_DECL(pj_status_t) pj_stun_msg_add_msgint_attr(pj_pool_t *pool,
01662 pj_stun_msg *msg);
01663
01675 PJ_DECL(pj_status_t) pj_stun_errcode_attr_create(pj_pool_t *pool,
01676 int err_code,
01677 const pj_str_t *err_reason,
01678 pj_stun_errcode_attr **p_attr);
01679
01680
01692 PJ_DECL(pj_status_t) pj_stun_msg_add_errcode_attr(pj_pool_t *pool,
01693 pj_stun_msg *msg,
01694 int err_code,
01695 const pj_str_t *err_reason);
01696
01708 PJ_DECL(pj_status_t) pj_stun_unknown_attr_create(pj_pool_t *pool,
01709 unsigned attr_cnt,
01710 const pj_uint16_t attr[],
01711 pj_stun_unknown_attr **p_attr);
01712
01723 PJ_DECL(pj_status_t) pj_stun_msg_add_unknown_attr(pj_pool_t *pool,
01724 pj_stun_msg *msg,
01725 unsigned attr_cnt,
01726 const pj_uint16_t attr[]);
01727
01741 PJ_DECL(pj_status_t) pj_stun_binary_attr_init(pj_stun_binary_attr *attr,
01742 pj_pool_t *pool,
01743 int attr_type,
01744 const pj_uint8_t *data,
01745 unsigned length);
01746
01760 PJ_DECL(pj_status_t) pj_stun_binary_attr_create(pj_pool_t *pool,
01761 int attr_type,
01762 const pj_uint8_t *data,
01763 unsigned length,
01764 pj_stun_binary_attr **p_attr);
01765
01779 PJ_DECL(pj_status_t) pj_stun_msg_add_binary_attr(pj_pool_t *pool,
01780 pj_stun_msg *msg,
01781 int attr_type,
01782 const pj_uint8_t *data,
01783 unsigned length);
01784
01794 PJ_DECL(pj_status_t) pj_stun_empty_attr_create(pj_pool_t *pool,
01795 int attr_type,
01796 pj_stun_empty_attr **p_attr);
01797
01807 PJ_DECL(pj_status_t) pj_stun_msg_add_empty_attr(pj_pool_t *pool,
01808 pj_stun_msg *msg,
01809 int attr_type);
01810
01816 PJ_END_DECL
01817
01818
01819 #endif
01820