Преглед изворни кода

modules:sipcapture: fixed mirroring capture mode. Currently it works only on Linux.

Alexandr Dubovikov пре 14 година
родитељ
комит
b7ed9c1e4f

+ 8 - 6
modules/sipcapture/README

@@ -231,7 +231,8 @@ modparam("sipcapture", "raw_ipip_capture_on", 1)
 3.8. raw_moni_capture_on (integer)
 3.8. raw_moni_capture_on (integer)
 
 
    Parameter to enable/disable monitoring/mirroring port capturing
    Parameter to enable/disable monitoring/mirroring port capturing
-   (on(1)/off(0)) Only one mode on raw socket can be enabled!
+   (on(1)/off(0)) Only one mode on raw socket can be enabled! Monitoring
+   port capturing currently supported only on Linux.
 
 
    Default value is "0".
    Default value is "0".
 
 
@@ -292,9 +293,10 @@ modparam("sipcapture", "promiscuous_on", 1)
 
 
 3.13. raw_moni_bpf_on (integer)
 3.13. raw_moni_bpf_on (integer)
 
 
-   Activate BPF on the mirroring interface. The structure is defined in
-   sipcapture.h. The default BPF accept a portrange from the
-   raw_socket_listen param.
+   Activate Linux Socket Filter (LSF based on BPF) on the mirroring
+   interface. The structure is defined in linux/filter.h. The default LSF
+   accept a portrange from the raw_socket_listen param. Currently LSF
+   supported only on Linux.
 
 
    Default value is "0".
    Default value is "0".
 
 
@@ -353,5 +355,5 @@ modparam("sipcapture", "capture_node", "homer03")
    monitoring/mirroring port. Don't activate both at the same time. 2. By
    monitoring/mirroring port. Don't activate both at the same time. 2. By
    default MySQL doesn't support INSERT DELAYED for partitioning table.
    default MySQL doesn't support INSERT DELAYED for partitioning table.
    You can patch MySQL (http://bugs.mysql.com/bug.php?id=50393) or use
    You can patch MySQL (http://bugs.mysql.com/bug.php?id=50393) or use
-   separate tables (pseudo partitioning) 3. Promiscuous mode works only on
-   Linux.
+   separate tables (pseudo partitioning) 3. Mirroring port capturing works
+   only on Linux.

+ 6 - 5
modules/sipcapture/doc/sipcapture_admin.xml

@@ -218,7 +218,8 @@ modparam("sipcapture", "raw_ipip_capture_on", 1)
                 <title><varname>raw_moni_capture_on</varname> (integer)</title>
                 <title><varname>raw_moni_capture_on</varname> (integer)</title>
                 <para>
                 <para>
                 Parameter to enable/disable monitoring/mirroring port capturing (on(1)/off(0))
                 Parameter to enable/disable monitoring/mirroring port capturing (on(1)/off(0))
-		Only one mode on raw socket can be enabled!
+		Only one mode on raw socket can be enabled! Monitoring port capturing currently 
+		supported only on Linux.
                 </para>
                 </para>
                 <para>
                 <para>
                 <emphasis>
                 <emphasis>
@@ -318,9 +319,9 @@ modparam("sipcapture", "promiscuous_on", 1)
         <section>
         <section>
                 <title><varname>raw_moni_bpf_on</varname> (integer)</title>
                 <title><varname>raw_moni_bpf_on</varname> (integer)</title>
                 <para>
                 <para>
-                Activate BPF on the mirroring interface. The structure is
-                defined in sipcapture.h. The default BPF accept a portrange
-                from the raw_socket_listen param.
+                Activate Linux Socket Filter (LSF based on BPF) on the mirroring interface. 
+                The structure is defined in linux/filter.h. The default LSF accept a portrange
+                from the raw_socket_listen param. Currently LSF supported only on Linux.
                 </para>
                 </para>
                 <para>
                 <para>
                 <emphasis>
                 <emphasis>
@@ -415,7 +416,7 @@ modparam("sipcapture", "capture_node", "homer03")
 		   Don't activate both at the same time.
 		   Don't activate both at the same time.
 		2. By default MySQL doesn't support INSERT DELAYED for partitioning table. You can patch MySQL 
 		2. By default MySQL doesn't support INSERT DELAYED for partitioning table. You can patch MySQL 
 		  (http://bugs.mysql.com/bug.php?id=50393) or use separate tables (pseudo partitioning)
 		  (http://bugs.mysql.com/bug.php?id=50393) or use separate tables (pseudo partitioning)
-		3. Promiscuous mode works only on Linux.
+		3. Mirroring port capturing works only on Linux.
 	
 	
         </para>
         </para>
         </section>
         </section>

+ 3 - 4
modules/sipcapture/examples/kamailio.cfg

@@ -40,20 +40,19 @@ modparam("sipcapture", "hep_capture_on", 1)
 modparam("sipcapture", "raw_interface", "eth0")
 modparam("sipcapture", "raw_interface", "eth0")
 /* activate IPIP capturing */
 /* activate IPIP capturing */
 modparam("sipcapture", "raw_ipip_capture_on", 1)
 modparam("sipcapture", "raw_ipip_capture_on", 1)
-/* activate monitoring/mirroring port capturing */
-modparam("sipcapture", "raw_moni_capture_on", 0)
 /* My table name*/
 /* My table name*/
 modparam("sipcapture", "table_name", "sip_capture")
 modparam("sipcapture", "table_name", "sip_capture")
 /* children for raw socket */
 /* children for raw socket */
 modparam("sipcapture", "raw_sock_children", 4)
 modparam("sipcapture", "raw_sock_children", 4)
 /* insert delayed */
 /* insert delayed */
 #modparam("sipcapture", "db_insert_mode", 1)
 #modparam("sipcapture", "db_insert_mode", 1)
+/* activate monitoring/mirroring port capturing. Linux only */
+modparam("sipcapture", "raw_moni_capture_on", 0)
 /* Promiscious mode RAW socket. Mirroring port. Linux only */
 /* Promiscious mode RAW socket. Mirroring port. Linux only */
 #modparam("sipcapture", "promiscious_on", 1)
 #modparam("sipcapture", "promiscious_on", 1)
-/* activate BPF on mirroring interface */
+/* activate Linux Socket Filter (LSF/BPF) on mirroring interface. Linux only */
 #modparam("sipcapture", "raw_moni_bpf_on", 1)
 #modparam("sipcapture", "raw_moni_bpf_on", 1)
 
 
-
 # Main SIP request routing logic
 # Main SIP request routing logic
 # - processing of any incoming SIP request starts with this route
 # - processing of any incoming SIP request starts with this route
 route {
 route {

+ 49 - 22
modules/sipcapture/sipcapture.c

@@ -40,6 +40,11 @@
 #include <net/if.h> 
 #include <net/if.h> 
 #include <netdb.h>
 #include <netdb.h>
 
 
+/* BPF structure */
+#ifdef __OS_linux
+#include <linux/filter.h>
+#endif
+
 #ifndef __USE_BSD
 #ifndef __USE_BSD
 #define __USE_BSD  /* on linux use bsd version of iphdr (more portable) */
 #define __USE_BSD  /* on linux use bsd version of iphdr (more portable) */
 #endif /* __USE_BSD */
 #endif /* __USE_BSD */
@@ -205,6 +210,19 @@ str raw_interface = { 0, 0 };
 
 
 struct ifreq ifr; 	/* interface structure */
 struct ifreq ifr; 	/* interface structure */
 
 
+#ifdef __OS_linux
+/* Linux socket filter */
+/* tcpdump -s 0 udp and portrange 5060-5090 -dd */
+static struct sock_filter BPF_code[] = { { 0x28, 0, 0, 0x0000000c }, { 0x15, 0, 7, 0x000086dd },
+        { 0x30, 0, 0, 0x00000014 },   { 0x15, 0, 18, 0x00000011 }, { 0x28, 0, 0, 0x00000036 },
+        { 0x35, 0, 1, 0x000013c4 },   { 0x25, 0, 14, 0x000013e2 }, { 0x28, 0, 0, 0x00000038 },
+        { 0x35, 11, 13, 0x000013c4 }, { 0x15, 0, 12, 0x00000800 }, { 0x30, 0, 0, 0x00000017 },
+        { 0x15, 0, 10, 0x00000011 },  { 0x28, 0, 0, 0x00000014 },  { 0x45, 8, 0, 0x00001fff },
+        { 0xb1, 0, 0, 0x0000000e },   { 0x48, 0, 0, 0x0000000e },  { 0x35, 0, 1, 0x000013c4 },
+        { 0x25, 0, 3, 0x000013e2 },   { 0x48, 0, 0, 0x00000010 },  { 0x35, 0, 2, 0x000013c4 },
+        { 0x25, 1, 0, 0x000013e2 },   { 0x6, 0, 0, 0x0000ffff },   { 0x6, 0, 0, 0x00000000 },
+};
+#endif
 
 
 db1_con_t *db_con = NULL; 		/*!< database connection */
 db1_con_t *db_con = NULL; 		/*!< database connection */
 db_func_t db_funcs;      		/*!< Database functions */
 db_func_t db_funcs;      		/*!< Database functions */
@@ -1301,13 +1319,14 @@ static struct mi_root* sip_capture_mi(struct mi_root* cmd_tree, void* param )
 
 
 int raw_moni_socket(str* iface, int port_start, int port_end)
 int raw_moni_socket(str* iface, int port_start, int port_end)
 {
 {
-	int sock;
+
+	int sock;	
 	
 	
-#if defined (SO_BINDTODEVICE)
+#ifdef __OS_linux
+	struct sock_fprog pf;
 	char short_ifname[sizeof(int)];
 	char short_ifname[sizeof(int)];
 	int ifname_len;
 	int ifname_len;
 	char* ifname;
 	char* ifname;
-#endif /* SO_BINDTODEVICE */
  
  
  	//0x0003 - all packets
  	//0x0003 - all packets
 	sock = socket(PF_PACKET, SOCK_RAW, htons(0x0800));
 	sock = socket(PF_PACKET, SOCK_RAW, htons(0x0800));
@@ -1317,7 +1336,7 @@ int raw_moni_socket(str* iface, int port_start, int port_end)
 
 
 	/* set socket options */
 	/* set socket options */
 	if (iface && iface->s){
 	if (iface && iface->s){
-#if defined (SO_BINDTODEVICE)
+
 		/* workaround for linux bug: arg to setsockopt must have at least
 		/* workaround for linux bug: arg to setsockopt must have at least
 		 * sizeof(int) size or EINVAL would be returned */
 		 * sizeof(int) size or EINVAL would be returned */
 		if (iface->len<sizeof(int)){
 		if (iface->len<sizeof(int)){
@@ -1329,45 +1348,53 @@ int raw_moni_socket(str* iface, int port_start, int port_end)
 			ifname_len=iface->len;
 			ifname_len=iface->len;
 			ifname=iface->s;
 			ifname=iface->s;
 		}
 		}
-		if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifname, ifname_len)
-						<0){
+		if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifname, ifname_len) <0){
 				ERR("raw_socket: could not bind to %.*s: %s [%d]\n",
 				ERR("raw_socket: could not bind to %.*s: %s [%d]\n",
 							iface->len, ZSW(iface->s), strerror(errno), errno);
 							iface->len, ZSW(iface->s), strerror(errno), errno);
 				goto error;
 				goto error;
 		}
 		}
-#else /* !SO_BINDTODEVICE */
-		/* SO_BINDTODEVICE is linux specific => cannot bind to a device */
-		ERR("raw_socket: bind to device supported only on linux\n");
-		goto error;
-#endif /* SO_BINDTODEVICE */
 	}
 	}
 
 
 	if(bpf_on) {
 	if(bpf_on) {
-	
+
+		memset(&pf, 0, sizeof(pf));
+	        pf.len = sizeof(BPF_code) / sizeof(BPF_code[0]);
+        	pf.filter = (struct sock_filter *) BPF_code;
+
         	/* Start PORT */
         	/* Start PORT */
-        	BPF_code[5]  = (struct my_sock_filter)BPF_JUMP(0x35, port_start, 0, 1);
-        	BPF_code[8] = (struct my_sock_filter)BPF_JUMP(0x35, port_start, 11, 13);
-        	BPF_code[16] = (struct my_sock_filter)BPF_JUMP(0x35, port_start, 0, 1);
-        	BPF_code[19] = (struct my_sock_filter)BPF_JUMP(0x35, port_start, 0, 2);
+        	BPF_code[5]  = (struct sock_filter)BPF_JUMP(0x35, port_start, 0, 1);
+        	BPF_code[8] = (struct  sock_filter)BPF_JUMP(0x35, port_start, 11, 13);
+        	BPF_code[16] = (struct sock_filter)BPF_JUMP(0x35, port_start, 0, 1);
+        	BPF_code[19] = (struct sock_filter)BPF_JUMP(0x35, port_start, 0, 2);
         	/* Stop PORT */
         	/* Stop PORT */
-        	BPF_code[6]  = (struct my_sock_filter)BPF_JUMP(0x25, port_end, 0, 14);
-        	BPF_code[17] = (struct my_sock_filter)BPF_JUMP(0x25, port_end, 0, 3);	
-        	BPF_code[20] = (struct my_sock_filter)BPF_JUMP(0x25, port_end, 1, 0);			                                                
+        	BPF_code[6]  = (struct sock_filter)BPF_JUMP(0x25, port_end, 0, 14);
+        	BPF_code[17] = (struct sock_filter)BPF_JUMP(0x25, port_end, 0, 3);	
+        	BPF_code[20] = (struct sock_filter)BPF_JUMP(0x25, port_end, 1, 0);			                                                
 	
 	
         	/* Attach the filter to the socket */
         	/* Attach the filter to the socket */
-        	if(setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &Filter, sizeof(Filter)) < 0 ) {
+        	if(setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &pf, sizeof(pf)) < 0 ) {
                         ERR(" setsockopt filter: [%s] [%d]\n", strerror(errno), errno);
                         ERR(" setsockopt filter: [%s] [%d]\n", strerror(errno), errno);
                 }		
                 }		
+
+
         }
         }
-	
+
+#else
+        ERR("raw_moni_socket: currently suppoted only on linux\n");
+        goto error;
+#endif
+
 	return sock;
 	return sock;
+	
 error:
 error:
 	if (sock!=-1) close(sock);
 	if (sock!=-1) close(sock);
-	return -1;
+	return -1;		
+               		
 }
 }
 
 
 int raw_moni_rcv_loop(int rsock, int port1, int port2) {
 int raw_moni_rcv_loop(int rsock, int port1, int port2) {
 
 
+
 	static char buf [BUF_SIZE+1];
 	static char buf [BUF_SIZE+1];
 	union sockaddr_union from;
 	union sockaddr_union from;
 	union sockaddr_union to;
 	union sockaddr_union to;

+ 0 - 53
modules/sipcapture/sipcapture.h

@@ -44,56 +44,3 @@ struct hep_ip6hdr {
         struct in6_addr hp6_dst;        /* destination address */
         struct in6_addr hp6_dst;        /* destination address */
 };
 };
 #endif
 #endif
-
-/* Make it independed */
-/* Copied from linux/filter.h */
-struct my_sock_filter      /* Filter block */
-{
-        __u16   code;   /* Actual filter code */
-        __u8    jt;     /* Jump true */
-        __u8    jf;     /* Jump false */
-        __u32   k;      /* Generic multiuse field */
-};
-
-struct my_sock_fprog       /* Required for SO_ATTACH_FILTER. */
-{
-        unsigned short          len;    /* Number of filter blocks */
-        struct my_sock_filter __user *filter;
-};
-
-#ifndef BPF_JUMP
-#define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k }
-#endif
-
-/* tcpdump -s 0 udp and portrange 5060-5090 -dd */
-static struct my_sock_filter BPF_code[] = {
-		{ 0x28, 0, 0, 0x0000000c },
-		{ 0x15, 0, 7, 0x000086dd },
-		{ 0x30, 0, 0, 0x00000014 },
-		{ 0x15, 0, 18, 0x00000011 },
-		{ 0x28, 0, 0, 0x00000036 },
-		{ 0x35, 0, 1, 0x000013c4 },
-		{ 0x25, 0, 14, 0x000013e2 },
-		{ 0x28, 0, 0, 0x00000038 },
-		{ 0x35, 11, 13, 0x000013c4 },
-		{ 0x15, 0, 12, 0x00000800 },
-		{ 0x30, 0, 0, 0x00000017 },
-		{ 0x15, 0, 10, 0x00000011 },
-		{ 0x28, 0, 0, 0x00000014 },
-		{ 0x45, 8, 0, 0x00001fff },
-		{ 0xb1, 0, 0, 0x0000000e },
-		{ 0x48, 0, 0, 0x0000000e },
-		{ 0x35, 0, 1, 0x000013c4 },
-		{ 0x25, 0, 3, 0x000013e2 },
-		{ 0x48, 0, 0, 0x00000010 },
-		{ 0x35, 0, 2, 0x000013c4 },
-		{ 0x25, 1, 0, 0x000013e2 },
-		{ 0x6, 0, 0, 0x0000ffff },
-		{ 0x6, 0, 0, 0x00000000 },
-};
-
-
-static struct my_sock_fprog Filter = {
-           .len = sizeof(BPF_code) / sizeof(BPF_code[0]),
-           .filter = (struct my_sock_filter *) BPF_code,
-};