ipops_mod.c

Go to the documentation of this file.
00001 /*
00002  * ipops module - IPv4 and Ipv6 operations
00003  *
00004  * Copyright (C) 2011 IƱaki Baz Castillo
00005  *
00006  * This file is part of SIP Router, a free SIP server.
00007  *
00008  * SIP Router is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version
00012  *
00013  * SIP Router is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * History:
00023  * -------
00024  *  2011-07-29: Added a function to detect RFC1918 private IPv4 addresses (ibc)
00025  *  2011-04-27: Initial version (ibc)
00026  */
00040 #include <stdio.h>
00041 #include <stdlib.h>
00042 #include <string.h>
00043 #include <arpa/inet.h>
00044 #include "../../sr_module.h"
00045 #include "../../dprint.h"
00046 #include "../../str.h"
00047 #include "../../mod_fix.h"
00048 #include "../../pvar.h"
00049 #include "ip_parser.h"
00050 #include "rfc1918_parser.h"
00051 
00052 MODULE_VERSION
00053 
00054 
00055 /*
00056  * Module parameter variables
00057  */
00058 
00059 
00060 /*
00061  * Module core functions
00062  */
00063 
00064 
00065 /*
00066  * Module internal functions
00067  */
00068 static int _compare_ips(char*, size_t, enum enum_ip_type, char*, size_t, enum enum_ip_type);
00069 
00070 
00071 /*
00072  * Script functions
00073  */
00074 static int w_is_ip(struct sip_msg*, char*);
00075 static int w_is_pure_ip(struct sip_msg*, char*);
00076 static int w_is_ipv4(struct sip_msg*, char*);
00077 static int w_is_ipv6(struct sip_msg*, char*);
00078 static int w_is_ipv6_reference(struct sip_msg*, char*);
00079 static int w_ip_type(struct sip_msg*, char*);
00080 static int w_compare_ips(struct sip_msg*, char*, char*);
00081 static int w_compare_pure_ips(struct sip_msg*, char*, char*);
00082 static int w_is_ip_rfc1918(struct sip_msg*, char*);
00083 
00084 
00085 /*
00086  * Exported functions
00087  */
00088 static cmd_export_t cmds[] =
00089 {
00090   { "is_ip", (cmd_function)w_is_ip, 1, fixup_spve_null, 0,
00091   REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00092   { "is_pure_ip", (cmd_function)w_is_pure_ip, 1, fixup_spve_null, 0,
00093   REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00094   { "is_ipv4", (cmd_function)w_is_ipv4, 1, fixup_spve_null, 0,
00095   REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00096   { "is_ipv6", (cmd_function)w_is_ipv6, 1, fixup_spve_null, 0,
00097   REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00098   { "is_ipv6_reference", (cmd_function)w_is_ipv6_reference, 1, fixup_spve_null, 0,
00099   REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00100   { "ip_type", (cmd_function)w_ip_type, 1, fixup_spve_null, 0,
00101   REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00102   { "compare_ips", (cmd_function)w_compare_ips, 2, fixup_spve_spve, 0,
00103   REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00104   { "compare_pure_ips", (cmd_function)w_compare_pure_ips, 2, fixup_spve_spve, 0,
00105   REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00106   { "is_ip_rfc1918", (cmd_function)w_is_ip_rfc1918, 1, fixup_spve_null, 0,
00107   REQUEST_ROUTE|FAILURE_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE },
00108   { 0, 0, 0, 0, 0, 0 }
00109 };
00110 
00111 
00112 /*
00113  * Module interface
00114  */
00115 struct module_exports exports = {
00116   "ipops",                   
00117   DEFAULT_DLFLAGS,           
00118   cmds,                      
00119   0,                         
00120   0,                         
00121   0,                         
00122   0,                         
00123   0,                         
00124   0,                         
00125   (response_function) 0,     
00126   0,                         
00127   0                          
00128 };
00129 
00130 
00131 /*
00132  * Module internal functions
00133  */
00134 
00136 static int _compare_ips(char *ip1, size_t len1, enum enum_ip_type ip1_type, char *ip2, size_t len2, enum enum_ip_type ip2_type)
00137 {
00138   struct in_addr in_addr1, in_addr2;
00139   struct in6_addr in6_addr1, in6_addr2;
00140   char _ip1[INET6_ADDRSTRLEN], _ip2[INET6_ADDRSTRLEN];
00141   
00142   // Not same IP type, return false.
00143   if (ip1_type != ip2_type)
00144     return 0;
00145 
00146   memcpy(_ip1, ip1, len1);
00147   _ip1[len1] = '\0';
00148   memcpy(_ip2, ip2, len2);
00149   _ip2[len2] = '\0';
00150 
00151   switch(ip1_type) {
00152     // Comparing IPv4 with IPv4.
00153     case(ip_type_ipv4):
00154       if (inet_pton(AF_INET, _ip1, &in_addr1) == 0)  return 0;
00155       if (inet_pton(AF_INET, _ip2, &in_addr2) == 0)  return 0;
00156       if (in_addr1.s_addr == in_addr2.s_addr)
00157         return 1;
00158       else
00159         return 0;
00160       break;
00161     // Comparing IPv6 with IPv6.
00162     case(ip_type_ipv6):
00163       if (inet_pton(AF_INET6, _ip1, &in6_addr1) != 1)  return 0;
00164       if (inet_pton(AF_INET6, _ip2, &in6_addr2) != 1)  return 0;
00165       if (memcmp(in6_addr1.s6_addr, in6_addr2.s6_addr, sizeof(in6_addr1.s6_addr)) == 0)
00166         return 1;
00167       else
00168         return 0;
00169       break;
00170     default:
00171       return 0;
00172       break;
00173   }
00174 }
00175 
00176 
00177 
00178 /*
00179  * Script functions
00180  */
00181 
00183 static int w_is_ip(struct sip_msg* _msg, char* _s)
00184 {
00185   str string;
00186   
00187   if (_s == NULL) {
00188     LM_ERR("bad parameter\n");
00189     return -2;
00190   }
00191   
00192   if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
00193   {
00194     LM_ERR("cannot print the format for string\n");
00195     return -3;
00196   }
00197   
00198   if (ip_parser_execute(string.s, string.len) != ip_type_error)
00199     return 1;
00200   else
00201     return -1;
00202 }
00203 
00204 
00206 static int w_is_pure_ip(struct sip_msg* _msg, char* _s)
00207 {
00208   str string;
00209   
00210   if (_s == NULL) {
00211     LM_ERR("bad parameter\n");
00212     return -2;
00213   }
00214   
00215   if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
00216   {
00217     LM_ERR("cannot print the format for string\n");
00218     return -3;
00219   }
00220 
00221   switch(ip_parser_execute(string.s, string.len)) {
00222     case(ip_type_ipv4):
00223       return 1;
00224       break;
00225     case(ip_type_ipv6):
00226       return 1;
00227       break;
00228     default:
00229       return -1;
00230       break;
00231   }
00232 }
00233 
00234 
00236 static int w_is_ipv4(struct sip_msg* _msg, char* _s)
00237 {
00238   str string;
00239   
00240   if (_s == NULL) {
00241     LM_ERR("bad parameter\n");
00242     return -2;
00243   }
00244   
00245   if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
00246   {
00247     LM_ERR("cannot print the format for string\n");
00248     return -3;
00249   }
00250 
00251   if (ip_parser_execute(string.s, string.len) == ip_type_ipv4)
00252     return 1;
00253   else
00254     return -1;
00255 }
00256 
00257 
00259 static int w_is_ipv6(struct sip_msg* _msg, char* _s)
00260 {
00261   str string;
00262   
00263   if (_s == NULL) {
00264     LM_ERR("bad parameter\n");
00265     return -2;
00266   }
00267   
00268   if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
00269   {
00270     LM_ERR("cannot print the format for string\n");
00271     return -3;
00272   }
00273   
00274   if (ip_parser_execute(string.s, string.len) == ip_type_ipv6)
00275     return 1;
00276   else
00277     return -1;
00278 }
00279 
00280 
00282 static int w_is_ipv6_reference(struct sip_msg* _msg, char* _s)
00283 {
00284   str string;
00285   
00286   if (_s == NULL) {
00287     LM_ERR("bad parameter\n");
00288     return -2;
00289   }
00290   
00291   if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
00292   {
00293     LM_ERR("cannot print the format for string\n");
00294     return -3;
00295   }
00296   
00297   if (ip_parser_execute(string.s, string.len) == ip_type_ipv6_reference)
00298     return 1;
00299   else
00300     return -1;
00301 }
00302 
00303 
00305 static int w_ip_type(struct sip_msg* _msg, char* _s)
00306 {
00307   str string;
00308   
00309   if (_s == NULL) {
00310     LM_ERR("bad parameter\n");
00311     return -2;
00312   }
00313   
00314   if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
00315   {
00316     LM_ERR("cannot print the format for string\n");
00317     return -3;
00318   }
00319   
00320   switch (ip_parser_execute(string.s, string.len)) {
00321     case(ip_type_ipv4):
00322       return 1;
00323       break;
00324     case(ip_type_ipv6):
00325       return 2;
00326       break;
00327     case(ip_type_ipv6_reference):
00328       return 3;
00329       break;
00330     default:
00331       return -1;
00332       break;
00333   }
00334 }
00335 
00336 
00338 static int w_compare_ips(struct sip_msg* _msg, char* _s1, char* _s2)
00339 {
00340   str string1, string2;
00341   enum enum_ip_type ip1_type, ip2_type;
00342   
00343   if (_s1 == NULL || _s2 == NULL ) {
00344     LM_ERR("bad parameters\n");
00345     return -2;
00346   }
00347   
00348   if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
00349   {
00350     LM_ERR("cannot print the format for first string\n");
00351     return -3;
00352   }
00353 
00354   if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
00355   {
00356     LM_ERR("cannot print the format for second string\n");
00357     return -3;
00358   }
00359 
00360   switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
00361     case(ip_type_error):
00362       return -1;
00363       break;
00364     case(ip_type_ipv6_reference):
00365       string1.s += 1;
00366       string1.len -= 2;
00367       ip1_type = ip_type_ipv6;
00368       break;
00369     default:
00370       break;
00371   }
00372   switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
00373     case(ip_type_error):
00374       return -1;
00375       break;
00376     case(ip_type_ipv6_reference):
00377       string2.s += 1;
00378       string2.len -= 2;
00379       ip2_type = ip_type_ipv6;
00380       break;
00381     default:
00382       break;
00383   }
00384 
00385   if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
00386     return 1;
00387   else
00388     return -1;
00389 }
00390 
00391 
00393 static int w_compare_pure_ips(struct sip_msg* _msg, char* _s1, char* _s2)
00394 {
00395   str string1, string2;
00396   enum enum_ip_type ip1_type, ip2_type;
00397   
00398   if (_s1 == NULL || _s2 == NULL ) {
00399     LM_ERR("bad parameters\n");
00400     return -2;
00401   }
00402   
00403   if (fixup_get_svalue(_msg, (gparam_p)_s1, &string1))
00404   {
00405     LM_ERR("cannot print the format for first string\n");
00406     return -3;
00407   }
00408   
00409   if (fixup_get_svalue(_msg, (gparam_p)_s2, &string2))
00410   {
00411     LM_ERR("cannot print the format for second string\n");
00412     return -3;
00413   }
00414 
00415   switch(ip1_type = ip_parser_execute(string1.s, string1.len)) {
00416     case(ip_type_error):
00417       return -1;
00418       break;
00419     case(ip_type_ipv6_reference):
00420       return -1;
00421       break;
00422     default:
00423       break;
00424   }
00425   switch(ip2_type = ip_parser_execute(string2.s, string2.len)) {
00426     case(ip_type_error):
00427       return -1;
00428       break;
00429     case(ip_type_ipv6_reference):
00430       return -1;
00431       break;
00432     default:
00433       break;
00434   }
00435   
00436   if (_compare_ips(string1.s, string1.len, ip1_type, string2.s, string2.len, ip2_type))
00437     return 1;
00438   else
00439     return -1;
00440 }
00441 
00442 
00444 static int w_is_ip_rfc1918(struct sip_msg* _msg, char* _s)
00445 {
00446   str string;
00447   
00448   if (_s == NULL) {
00449     LM_ERR("bad parameter\n");
00450     return -2;
00451   }
00452   
00453   if (fixup_get_svalue(_msg, (gparam_p)_s, &string))
00454   {
00455     LM_ERR("cannot print the format for string\n");
00456     return -3;
00457   }
00458   
00459   if (rfc1918_parser_execute(string.s, string.len) == 1)
00460     return 1;
00461   else
00462     return -1;
00463 }