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 #include "../../onsend.h"
00030 #include "../../parser/parse_fline.h"
00031 #include "../../ut.h"
00032 #include "permissions.h"
00033 #include "im_hash.h"
00034 #include "im_db.h"
00035 #include "im_locks.h"
00036 #include "ipmatch.h"
00037
00038
00039 int init_ipmatch(void)
00040 {
00041 if (db_mode != ENABLE_CACHE) {
00042
00043 LOG(L_WARN, "WARNING: ipmatch_init(): Database cache is disabled, thus ipmatch functions cannot be used\n");
00044 return 0;
00045 }
00046
00047 if (init_im_hash()) {
00048 LOG(L_ERR, "ERROR: ipmatch_init(): cannot init ipmatch hash table\n");
00049 return -1;
00050 }
00051
00052 if (reload_im_cache()) {
00053 LOG(L_ERR, "ERROR: ipmatch_init(): error occured while caching ipmatch table\n");
00054 return -1;
00055 }
00056 return 0;
00057 }
00058
00059
00060 void clean_ipmatch(void) {
00061 LOG(L_DBG, "DEBUG: clean_ipmatch(): free shared memory required by ipmatch table\n");
00062 destroy_im_hash();
00063 }
00064
00065
00066 static unsigned int IM_FILTER = ~0;
00067
00068
00069
00070
00071
00072
00073
00074 static int ipmatch(struct ip_addr *ip, unsigned short port,
00075 avp_ident_t *avp)
00076 {
00077 im_entry_t *entry;
00078 int ret;
00079 avp_value_t avp_val;
00080
00081 ret = 0;
00082
00083 if (!IM_HASH) {
00084 LOG(L_CRIT, "ERROR: ipmatch(): ipmatch hash table is not initialied. "
00085 "Have you set the database url?\n");
00086 return 0;
00087 }
00088
00089
00090 reader_lock_imhash();
00091
00092 LOG(L_DBG, "DEBUG: ipmatch(): start searching... (ip=%s, port=%u, filter=%u)\n",
00093 ip_addr2a(ip), port, IM_FILTER);
00094
00095 if (!IM_HASH->entries) {
00096 LOG(L_DBG, "DEBUG: ipmatch(): cache is empty\n");
00097 goto done;
00098 }
00099
00100 entry = IM_HASH->entries[im_hash(ip)];
00101 while (entry) {
00102 if ((entry->mark & IM_FILTER)
00103 && ((entry->port == 0) || (port == 0) || (entry->port == port))
00104 && (ip_addr_cmp(&entry->ip, ip))) {
00105
00106 LOG(L_DBG, "DEBUG: ipmatch(): entry found\n");
00107
00108
00109 if (avp) {
00110
00111 delete_avp(avp->flags, avp->name);
00112
00113 avp_val.s.s = entry->avp_val.s;
00114 avp_val.s.len = entry->avp_val.len;
00115 if (add_avp(avp->flags | AVP_VAL_STR, avp->name, avp_val)) {
00116 LOG(L_ERR, "ERROR: ipmatch(): failed to add AVP\n");
00117 ret = -1;
00118 break;
00119 }
00120 }
00121
00122 ret = 1;
00123 break;
00124 }
00125
00126 entry = entry->next;
00127 }
00128
00129 if (!entry) LOG(L_DBG, "DEBUG: ipmatch(): entry not found\n");
00130
00131 done:
00132
00133 reader_release_imhash();
00134
00135
00136 IM_FILTER = ~0;
00137
00138 return ret;
00139 }
00140
00141
00142 int ipmatch_2(struct sip_msg *msg, char *str1, char *str2)
00143 {
00144 int ret;
00145 fparam_t *param1;
00146 str s;
00147 struct ip_addr *ip, ip_buf;
00148 unsigned short port;
00149 unsigned int iport;
00150
00151 param1 = (fparam_t *)str1;
00152
00153 switch(param1->type) {
00154 case FPARAM_AVP:
00155 case FPARAM_SELECT:
00156 if (get_str_fparam(&s, msg, param1)) {
00157 LOG(L_ERR, "ERROR: w_ipmatch_2(): could not get first parameter\n");
00158 return -1;
00159 }
00160 if (parse_ip(&s, &ip_buf, &port)) {
00161 LOG(L_ERR, "ERROR: w_ipmatch_2(): could not parse ip address\n");
00162 return -1;
00163 }
00164 ip = &ip_buf;
00165 break;
00166
00167 case FPARAM_STR:
00168 if (param1->v.str.s[0] == 's') {
00169
00170 ip = &msg->rcv.src_ip;
00171 port = msg->rcv.src_port;
00172
00173 } else {
00174
00175 if (!msg->via2 &&
00176 ((parse_headers(msg, HDR_VIA2_F, 0) == -1) || !msg->via2)) {
00177
00178 LOG(L_ERR, "ERROR: w_ipmatch_2(): could not get 2nd VIA HF\n");
00179 return -1;
00180 }
00181 if (!msg->via2->received || !msg->via2->received->value.s) {
00182 LOG(L_ERR, "ERROR: w_ipmatch_2(): there is no received param in the 2nd VIA HF\n");
00183 return -1;
00184 }
00185 if (parse_ip(&msg->via2->received->value, &ip_buf, &port)) {
00186 LOG(L_ERR, "ERROR: w_ipmatch_2(): could not parse ip address\n");
00187 return -1;
00188 }
00189 ip = &ip_buf;
00190 if (!msg->via2->rport || !msg->via2->rport->value.s) {
00191 LOG(L_WARN, "WARNING: w_ipmatch_2(): there is no rport param in the 2nd VIA HF\n");
00192 port = 0;
00193 } else {
00194 if (str2int(&msg->via2->rport->value, &iport)) {
00195 LOG(L_ERR, "ERROR: w_ipmatch_2(): invalid port number %.*s\n",
00196 msg->via2->rport->value.len, msg->via2->rport->value.s);
00197 return -1;
00198 }
00199 port = iport;
00200 }
00201 }
00202 break;
00203
00204 default:
00205 LOG(L_ERR, "ERROR: w_ipmatch_2(): unknown parameter type\n");
00206 return -1;
00207 }
00208
00209 ret = ipmatch(
00210 ip,
00211 port,
00212 (str2) ? &((fparam_t *)str2)->v.avp : 0
00213 );
00214
00215
00216 return (ret == 0) ? -1 : 1;
00217 }
00218
00219
00220 int ipmatch_1(struct sip_msg *msg, char *str1, char *str2)
00221 {
00222 return ipmatch_2(msg, str1, 0);
00223 }
00224
00225
00226 int ipmatch_onsend(struct sip_msg *msg, char *str1, char *str2)
00227 {
00228 int ret;
00229 struct ip_addr ip;
00230 unsigned short port;
00231 char *buf, *ch1, *ch2;
00232 struct msg_start fl;
00233 str *uri, s;
00234
00235 if (str1[0] == 'd') {
00236
00237 port = su_getport(get_onsend_info()->to);
00238 su2ip_addr(&ip, get_onsend_info()->to);
00239
00240 } else {
00241
00242
00243
00244
00245
00246 buf = get_onsend_info()->buf;
00247 parse_first_line(buf, get_onsend_info()->len, &fl);
00248 if (fl.type != SIP_REQUEST) {
00249 LOG(L_ERR, "ERROR: w_ipmatch_onsend(): message type is not request\n");
00250 return -1;
00251 }
00252 uri = &(fl.u.request.uri);
00253
00254
00255 if ((!(ch1 = memchr(uri->s, '@', uri->len))) && (!(ch1 = memchr(uri->s, ':', uri->len)))) {
00256 LOG(L_ERR, "ERROR: w_ipmatch_onsend(): unable to get host:port part of uri: %.*s\n",
00257 uri->len, uri->s);
00258 return -1;
00259 }
00260
00261 if ((ch2 = memchr(uri->s, ';', uri->len))) {
00262 s.s = ch1 + 1;
00263 s.len = ch2 - ch1 - 1;
00264 } else {
00265 s.s = ch1 + 1;
00266 s.len = uri->len - (ch1 - uri->s) - 1;
00267 }
00268 if (parse_ip(&s, &ip, &port)) {
00269 LOG(L_ERR, "ERROR: w_ipmatch_onsend(): could not parse ip address\n");
00270 return -1;
00271 }
00272 }
00273
00274 ret = ipmatch(
00275 &ip,
00276 port,
00277 0
00278 );
00279
00280 return (ret == 0) ? -1 : 1;
00281 }
00282
00283
00284 int ipmatch_filter(struct sip_msg *msg, char *str1, char *str2)
00285 {
00286 int i;
00287
00288 if (get_int_fparam(&i, msg, (fparam_t *)str1)) return -1;
00289 IM_FILTER = (unsigned int)i;
00290 return 1;
00291 }