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
00034
00035
00036
00037
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include <stdlib.h>
00041
00042 #include "../../sr_module.h"
00043 #include "../../dprint.h"
00044 #include "../../error.h"
00045 #include "../../ut.h"
00046 #include "../../mem/mem.h"
00047 #include "mf_funcs.h"
00048 #include "api.h"
00049
00050 MODULE_VERSION
00051
00052 #define MAXFWD_UPPER_LIMIT 256
00053
00054 static int max_limit = MAXFWD_UPPER_LIMIT;
00055
00056 static int fixup_maxfwd_header(void** param, int param_no);
00057 static int w_process_maxfwd_header(struct sip_msg* msg,char* str,char* str2);
00058 static int is_maxfwd_lt(struct sip_msg *msg, char *slimit, char *foo);
00059 static int mod_init(void);
00060
00061 int bind_maxfwd(maxfwd_api_t *api);
00062
00063 static cmd_export_t cmds[]={
00064 {"mf_process_maxfwd_header", (cmd_function)w_process_maxfwd_header, 1,
00065 fixup_maxfwd_header, 0, REQUEST_ROUTE},
00066 {"is_maxfwd_lt", (cmd_function)is_maxfwd_lt, 1,
00067 fixup_maxfwd_header, 0, REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
00068 {"bind_maxfwd", (cmd_function)bind_maxfwd, 0,
00069 0, 0, 0},
00070 {0,0,0,0,0,0}
00071 };
00072
00073 static param_export_t params[]={
00074 {"max_limit", INT_PARAM, &max_limit},
00075 {0,0,0}
00076 };
00077
00078
00079
00080 struct module_exports exports= {
00081 "maxfwd",
00082 DEFAULT_DLFLAGS,
00083 cmds,
00084 params,
00085 0,
00086 0,
00087 0,
00088 0,
00089 mod_init,
00090 0,
00091 0,
00092 0
00093 };
00094
00095
00096
00097 static int mod_init(void)
00098 {
00099 if ( max_limit<1 || max_limit>MAXFWD_UPPER_LIMIT ) {
00100 LM_ERR("invalid max limit (%d) [1,%d]\n",
00101 max_limit,MAXFWD_UPPER_LIMIT);
00102 return E_CFG;
00103 }
00104 return 0;
00105 }
00106
00107
00108
00109 static int fixup_maxfwd_header(void** param, int param_no)
00110 {
00111 unsigned long code;
00112 int err;
00113
00114 if (param_no==1){
00115 code=str2s(*param, strlen(*param), &err);
00116 if (err==0){
00117 if (code<1 || code>MAXFWD_UPPER_LIMIT){
00118 LM_ERR("invalid MAXFWD number <%ld> [1,%d]\n",
00119 code,MAXFWD_UPPER_LIMIT);
00120 return E_UNSPEC;
00121 }
00122 if (code>max_limit) {
00123 LM_ERR("default value <%ld> bigger than max limit(%d)\n",
00124 code, max_limit);
00125 return E_UNSPEC;
00126 }
00127 pkg_free(*param);
00128 *param=(void*)code;
00129 return 0;
00130 }else{
00131 LM_ERR("bad number <%s>\n",(char*)(*param));
00132 return E_UNSPEC;
00133 }
00134 }
00135 return 0;
00136 }
00137
00138
00142 int process_maxfwd_header(struct sip_msg *msg, int limit)
00143 {
00144 int val;
00145 str mf_value;
00146
00147 val=is_maxfwd_present(msg, &mf_value);
00148 switch (val) {
00149
00150 case -1:
00151 if (add_maxfwd_header(msg, (unsigned int)limit)!=0)
00152 goto error;
00153 return 2;
00154
00155 case -2:
00156 goto error;
00157
00158 case 0:
00159 return -1;
00160 default:
00161 if (val>max_limit){
00162 LM_DBG("value %d decreased to %d\n", val, max_limit);
00163 val = max_limit+1;
00164 }
00165 if ( decrement_maxfwd(msg, val, &mf_value)!=0 ) {
00166 LM_ERR("decrement failed!\n");
00167 goto error;
00168 }
00169 }
00170
00171 return 1;
00172 error:
00173 return -2;
00174 }
00175
00179 static int w_process_maxfwd_header(struct sip_msg* msg, char* str1, char* str2)
00180 {
00181 return process_maxfwd_header(msg, (int)(unsigned long)str1);
00182 }
00183
00184
00188 static int is_maxfwd_lt(struct sip_msg *msg, char *slimit, char *foo)
00189 {
00190 str mf_value;
00191 int limit;
00192 int val;
00193
00194 limit = (int)(long)slimit;
00195 val = is_maxfwd_present( msg, &mf_value);
00196 LM_DBG("value = %d \n",val);
00197
00198 if ( val<0 ) {
00199
00200 return val-1;
00201 } else if ( val>=limit ) {
00202
00203 return -1;
00204 }
00205
00206 return 1;
00207 }
00208
00212 int bind_maxfwd(maxfwd_api_t *api)
00213 {
00214 if (!api) {
00215 ERR("Invalid parameter value\n");
00216 return -1;
00217 }
00218 api->process_maxfwd = process_maxfwd_header;
00219
00220 return 0;
00221 }