00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <string.h>
00034 #include <stdio.h>
00035
00036 #include "../../mem/mem.h"
00037 #include "../../data_lump.h"
00038 #include "../../parser/parse_param.h"
00039
00040 #include "path.h"
00041 #include "path_mod.h"
00042
00043 #define PATH_PREFIX "Path: <sip:"
00044 #define PATH_PREFIX_LEN (sizeof(PATH_PREFIX)-1)
00045
00046 #define PATH_LR_PARAM ";lr"
00047 #define PATH_LR_PARAM_LEN (sizeof(PATH_LR_PARAM)-1)
00048
00049 #define PATH_RC_PARAM ";received="
00050 #define PATH_RC_PARAM_LEN (sizeof(PATH_RC_PARAM)-1)
00051
00052 #define PATH_CRLF ">\r\n"
00053 #define PATH_CRLF_LEN (sizeof(PATH_CRLF)-1)
00054
00055 static int prepend_path(struct sip_msg* _m, str *user, int recv)
00056 {
00057 struct lump *l;
00058 char *prefix, *suffix, *crlf;
00059 int prefix_len, suffix_len;
00060 struct hdr_field *hf;
00061 str rcv_addr = {0, 0};
00062 char *src_ip;
00063
00064 prefix = suffix = crlf = 0;
00065
00066 prefix_len = PATH_PREFIX_LEN + (user->len ? (user->len+1) : 0);
00067 prefix = pkg_malloc(prefix_len);
00068 if (!prefix) {
00069 LM_ERR("no pkg memory left for prefix\n");
00070 goto out1;
00071 }
00072 memcpy(prefix, PATH_PREFIX, PATH_PREFIX_LEN);
00073 if (user->len) {
00074 memcpy(prefix + PATH_PREFIX_LEN, user->s, user->len);
00075 memcpy(prefix + prefix_len - 1, "@", 1);
00076 }
00077
00078 suffix_len = PATH_LR_PARAM_LEN + (recv ? PATH_RC_PARAM_LEN : 0);
00079 suffix = pkg_malloc(suffix_len);
00080 if (!suffix) {
00081 LM_ERR("no pkg memory left for suffix\n");
00082 goto out1;
00083 }
00084 memcpy(suffix, PATH_LR_PARAM, PATH_LR_PARAM_LEN);
00085 if(recv)
00086 memcpy(suffix+PATH_LR_PARAM_LEN, PATH_RC_PARAM, PATH_RC_PARAM_LEN);
00087
00088 crlf = pkg_malloc(PATH_CRLF_LEN);
00089 if (!crlf) {
00090 LM_ERR("no pkg memory left for crlf\n");
00091 goto out1;
00092 }
00093 memcpy(crlf, PATH_CRLF, PATH_CRLF_LEN);
00094
00095 if (parse_headers(_m, HDR_PATH_F, 0) < 0) {
00096 LM_ERR("failed to parse message for Path header\n");
00097 goto out1;
00098 }
00099 for (hf = _m->headers; hf; hf = hf->next) {
00100 if (hf->type == HDR_PATH_T) {
00101 break;
00102 }
00103 }
00104 if (hf)
00105
00106 l = anchor_lump(_m, hf->name.s - _m->buf, 0, 0);
00107 else
00108
00109 l = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
00110 if (!l) {
00111 LM_ERR("failed to get anchor\n");
00112 goto out1;
00113 }
00114
00115 l = insert_new_lump_before(l, prefix, prefix_len, 0);
00116 if (!l) goto out1;
00117 l = insert_subst_lump_before(l, SUBST_SND_ALL, 0);
00118 if (!l) goto out2;
00119 l = insert_new_lump_before(l, suffix, suffix_len, 0);
00120 if (!l) goto out2;
00121 if (recv) {
00122
00123 src_ip = ip_addr2a(&_m->rcv.src_ip);
00124 rcv_addr.s = pkg_malloc(6 + IP_ADDR_MAX_STR_SIZE + 22);
00125 if(!rcv_addr.s) {
00126 LM_ERR("no pkg memory left for receive-address\n");
00127 goto out3;
00128 }
00129 switch (_m->rcv.proto) {
00130 case PROTO_UDP:
00131 rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 6, "\"sip:%s:%u\"", src_ip, _m->rcv.src_port);
00132 break;
00133 case PROTO_TCP:
00134 rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 20, "\"sip:%s:%u;transport=tcp\"", src_ip, _m->rcv.src_port);
00135 break;
00136 case PROTO_TLS:
00137 rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 20, "\"sip:%s:%u;transport=tls\"", src_ip, _m->rcv.src_port);
00138 break;
00139 case PROTO_SCTP:
00140 rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 21, "\"sip:%s:%u;transport=sctp\"", src_ip, _m->rcv.src_port);
00141 break;
00142 }
00143
00144 l = insert_new_lump_before(l, rcv_addr.s, rcv_addr.len, 0);
00145 if (!l) goto out3;
00146 }
00147 l = insert_new_lump_before(l, crlf, CRLF_LEN+1, 0);
00148 if (!l) goto out4;
00149
00150 return 1;
00151
00152 out1:
00153 if (prefix) pkg_free(prefix);
00154 out2:
00155 if (suffix) pkg_free(suffix);
00156 out3:
00157 if (rcv_addr.s) pkg_free(rcv_addr.s);
00158 out4:
00159 if (crlf) pkg_free(crlf);
00160
00161 LM_ERR("failed to insert prefix lump\n");
00162
00163 return -1;
00164 }
00165
00166
00167
00168
00169 int add_path(struct sip_msg* _msg, char* _a, char* _b)
00170 {
00171 str user = {0,0};
00172 return prepend_path(_msg, &user, 0);
00173 }
00174
00175
00176
00177
00178
00179 int add_path_usr(struct sip_msg* _msg, char* _usr, char* _b)
00180 {
00181 return prepend_path(_msg, (str*)_usr, 0);
00182 }
00183
00184
00185
00186
00187
00188 int add_path_received(struct sip_msg* _msg, char* _a, char* _b)
00189 {
00190 str user = {0,0};
00191 return prepend_path(_msg, &user, 1);
00192 }
00193
00194
00195
00196
00197
00198 int add_path_received_usr(struct sip_msg* _msg, char* _usr, char* _b)
00199 {
00200 return prepend_path(_msg, (str*)_usr, 1);
00201 }
00202
00203
00204
00205
00206 void path_rr_callback(struct sip_msg *_m, str *r_param, void *cb_param)
00207 {
00208 param_hooks_t hooks;
00209 param_t *params;
00210
00211 if (parse_params(r_param, CLASS_CONTACT, &hooks, ¶ms) != 0) {
00212 LM_ERR("failed to parse route parametes\n");
00213 return;
00214 }
00215
00216 if (hooks.contact.received) {
00217 if (set_dst_uri(_m, &hooks.contact.received->body) != 0) {
00218 LM_ERR("failed to set dst-uri\n");
00219 free_params(params);
00220 return;
00221 }
00222 }
00223 free_params(params);
00224 }