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 #include <stdio.h>
00032 #include <string.h>
00033 #include "../../sr_module.h"
00034 #include "../../error.h"
00035 #include "../../dprint.h"
00036 #include "../../mem/mem.h"
00037 #include "../../data_lump.h"
00038
00039
00040 MODULE_VERSION
00041
00042 #define DIVERSION_HF "Diversion"
00043 #define DIVERSION_HF_LEN (sizeof(DIVERSION_HF) - 1)
00044
00045 #define DIVERSION_PREFIX DIVERSION_HF ": <"
00046 #define DIVERSION_PREFIX_LEN (sizeof(DIVERSION_PREFIX) - 1)
00047
00048 #define DIVERSION_SUFFIX ">;reason="
00049 #define DIVERSION_SUFFIX_LEN (sizeof(DIVERSION_SUFFIX) - 1)
00050
00051
00052
00053 str suffix = STR_STATIC_INIT("");
00054
00055 int add_diversion(struct sip_msg* msg, char* r, char* s);
00056
00057
00058
00059
00060
00061 static int mod_init(void);
00062
00063
00064
00065
00066
00067 static cmd_export_t cmds[] = {
00068 {"add_diversion", add_diversion, 1, fixup_var_str_1, REQUEST_ROUTE | FAILURE_ROUTE},
00069 {0, 0, 0, 0, 0}
00070 };
00071
00072
00073
00074
00075
00076 static param_export_t params[] = {
00077 {"suffix", PARAM_STR, &suffix},
00078 {0, 0, 0}
00079 };
00080
00081
00082
00083
00084
00085 struct module_exports exports = {
00086 "diversion",
00087 cmds,
00088 0,
00089 params,
00090 mod_init,
00091 0,
00092 0,
00093 0,
00094 0
00095 };
00096
00097
00098 static int mod_init(void)
00099 {
00100 return 0;
00101 }
00102
00103
00104 static inline int add_diversion_helper(struct sip_msg* msg, str* s)
00105 {
00106 char *ptr;
00107
00108 static struct lump* anchor = 0;
00109 static int msg_id = 0;
00110
00111 if (msg_id != msg->id) {
00112 msg_id = msg->id;
00113 anchor = 0;
00114 }
00115
00116 if (!msg->diversion && parse_headers(msg, HDR_DIVERSION_F, 0) == -1) {
00117 LOG(L_ERR, "add_diversion_helper: Header parsing failed\n");
00118 return -1;
00119 }
00120
00121 if (msg->diversion) {
00122
00123 ptr = msg->diversion->name.s;
00124 } else {
00125
00126 ptr = msg->unparsed;
00127 }
00128
00129 if (!anchor) {
00130 anchor = anchor_lump(msg, ptr - msg->buf, 0, 0);
00131 if (!anchor) {
00132 LOG(L_ERR, "add_diversion_helper: Can't get anchor\n");
00133 return -2;
00134 }
00135 }
00136
00137 if (!insert_new_lump_before(anchor, s->s, s->len, 0)) {
00138 LOG(L_ERR, "add_diversion_helper: Can't insert lump\n");
00139 return -3;
00140 }
00141
00142 return 0;
00143 }
00144
00145
00146 int add_diversion(struct sip_msg* msg, char* r, char* s)
00147 {
00148 str div_hf;
00149 char *at;
00150 str* uri;
00151 str reason;
00152
00153 if (get_str_fparam(&reason, msg, (fparam_t*)r) < 0) return -1;
00154
00155 uri = &msg->first_line.u.request.uri;
00156
00157 div_hf.len = DIVERSION_PREFIX_LEN + uri->len + DIVERSION_SUFFIX_LEN + reason.len + CRLF_LEN;
00158 div_hf.s = pkg_malloc(div_hf.len);
00159 if (!div_hf.s) {
00160 LOG(L_ERR, "add_diversion: No memory left\n");
00161 return -1;
00162 }
00163
00164 at = div_hf.s;
00165 memcpy(at, DIVERSION_PREFIX, DIVERSION_PREFIX_LEN);
00166 at += DIVERSION_PREFIX_LEN;
00167
00168 memcpy(at, uri->s, uri->len);
00169 at += uri->len;
00170
00171 memcpy(at, DIVERSION_SUFFIX, DIVERSION_SUFFIX_LEN);
00172 at += DIVERSION_SUFFIX_LEN;
00173
00174 memcpy(at, reason.s, reason.len);
00175 at += reason.len;
00176
00177 memcpy(at, CRLF, CRLF_LEN);
00178
00179 if (add_diversion_helper(msg, &div_hf) < 0) {
00180 pkg_free(div_hf.s);
00181 return -1;
00182 }
00183
00184 return 1;
00185 }