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
00039
00040 #include "../../sr_module.h"
00041 #include "../../dprint.h"
00042 #include "../../error.h"
00043 #include "mf_funcs.h"
00044 #include "../../cfg/cfg.h"
00045
00046 MODULE_VERSION
00047
00048 #define MODULE_NAME "maxfwd"
00049
00050 struct cfg_group_maxfwd {
00051 int max_limit;
00052 };
00053
00054 static struct cfg_group_maxfwd default_maxfwd_cfg = {
00055 max_limit:16
00056 };
00057
00058 static void *maxfwd_cfg = &default_maxfwd_cfg;
00059
00060 static cfg_def_t maxfwd_cfg_def[] = {
00061 {"max_limit", CFG_VAR_INT, 0, 255, 0, 0, "Max. maxfwd limit"},
00062 {0, 0, 0, 0, 0, 0}
00063 };
00064
00065
00066 static int process_maxfwd_header(struct sip_msg* msg, char* str, char* str2);
00067 static int check_lowlimit(struct sip_msg* msg, char* str, char* str2);
00068 static int mod_init(void);
00069
00070 static cmd_export_t cmds[]={
00071 {MODULE_NAME"_process", process_maxfwd_header, 1, fixup_var_int_1, REQUEST_ROUTE},
00072 {MODULE_NAME"_at_least", check_lowlimit, 1, fixup_var_int_1, REQUEST_ROUTE},
00073
00074 {"mf_process_maxfwd_header", process_maxfwd_header, 1, fixup_var_int_1, REQUEST_ROUTE},
00075 {"process_maxfwd", process_maxfwd_header, 1,
00076 fixup_var_int_1, REQUEST_ROUTE},
00077 {"mf_lowlimit", check_lowlimit, 1, fixup_var_int_1, REQUEST_ROUTE},
00078 {0,0,0,0,0}
00079 };
00080
00081 static param_export_t params[]={
00082 {"max_limit", PARAM_INT, &default_maxfwd_cfg.max_limit},
00083 {0,0,0}
00084 };
00085
00086
00087 #ifdef STATIC_MAXFWD
00088 struct module_exports MODULE_NAME##_exports = {
00089 #else
00090 struct module_exports exports= {
00091 #endif
00092 MODULE_NAME,
00093 cmds,
00094 0,
00095 params,
00096 mod_init,
00097 (response_function) 0,
00098 (destroy_function) 0,
00099 0,
00100 0
00101 };
00102
00103
00104
00105 static int mod_init(void) {
00106 DBG(MODULE_NAME": initializing\n");
00107
00108 if (cfg_declare(MODULE_NAME, maxfwd_cfg_def, &default_maxfwd_cfg, cfg_sizeof(maxfwd), &maxfwd_cfg)) {
00109 ERR(MODULE_NAME": mod_init: failed to declare the configuration\n");
00110 return E_UNSPEC;
00111 }
00112 return E_OK;
00113 }
00114
00115 static int process_maxfwd_header(struct sip_msg* msg, char* str1, char* str2) {
00116 int val, tmp;
00117 str mf_value;
00118 int max_limit;
00119
00120 val = is_maxfwd_present(msg, &mf_value);
00121 switch (val) {
00122 case -1:
00123 if (get_int_fparam(&tmp, msg, (fparam_t*) str1) < 0) return -1;
00124 if (tmp < 0 || tmp > 255) {
00125 ERR(MODULE_NAME": number (%d) beyond range <0,255>\n", tmp);
00126 return -1;
00127 }
00128 if (tmp == 0) return 0;
00129 max_limit = cfg_get(maxfwd, maxfwd_cfg, max_limit);
00130 if ( max_limit && tmp > max_limit) {
00131 ERR(MODULE_NAME": default value (%d) greater than max.limit (%d)\n", tmp, max_limit);
00132 return -1;
00133 }
00134 add_maxfwd_header(msg, tmp);
00135 break;
00136 case -2:
00137 break;
00138 case 0:
00139 return -1;
00140 default:
00141 max_limit = cfg_get(maxfwd, maxfwd_cfg, max_limit);
00142 if (max_limit && val > max_limit){
00143 DBG(MODULE_NAME": process_maxfwd_header: "
00144 "value %d decreased to %d\n", val, max_limit);
00145 val = max_limit+1;
00146 }
00147 if ( decrement_maxfwd(msg, val, &mf_value)!=1 )
00148 ERR(MODULE_NAME": process_maxfwd_header: "
00149 "decrement failed\n");
00150 }
00151 return 1;
00152 }
00153
00154
00155 static int check_lowlimit(struct sip_msg* msg, char* str1, char* str2) {
00156 int val, lowlimit;
00157 str mf_value;
00158
00159 val = is_maxfwd_present(msg, &mf_value);
00160 switch (val) {
00161 case -2:
00162 return -1;
00163 case -1:
00164 return 1;
00165 default:
00166 if (get_int_fparam(&lowlimit, msg, (fparam_t*) str1) < 0) return -1;
00167 DBG(MODULE_NAME": check_low_limit(%d): current=%d\n", lowlimit, val);
00168 return ((val >= 0) && (val < lowlimit))?-1:1;
00169 }
00170 }