Browse Source

new select functions:

Source ip/port based on message's src ip_addr struct:
- src.(ip | port | ip_port)

Destination ip/port based on message's dst ip_addr struct:
- dst.(ip | port | ip_port)

Received info (based on socket used while received this message):
- received.(proto | ip | port | ip_port | proto_ip_port)
Michal Matyska 19 years ago
parent
commit
c51c5eb64c
2 changed files with 126 additions and 0 deletions
  1. 96 0
      select_core.c
  2. 30 0
      select_core.h

+ 96 - 0
select_core.c

@@ -51,6 +51,7 @@
 #include "parser/digest/digest.h"
 #include "mem/mem.h"
 #include "parser/parse_hname2.h"
+#include "ip_addr.h"
 
 #define RETURN0_res(x) {*res=x;return 0;}
 #define TRIM_RET0_res(x) {*res=x;trim(res);return 0;} 
@@ -1019,3 +1020,98 @@ int select_nameaddr_params(str* res, select_t* s, struct sip_msg* msg)
 	return select_any_params(res, s, msg);
 }
 
+ABSTRACT_F(select_src)
+ABSTRACT_F(select_dst)
+ABSTRACT_F(select_rcv)
+int select_ip_port(str* res, select_t* s, struct sip_msg* msg)
+{
+	str ip_str=STR_NULL, port_str=STR_NULL, proto_str=STR_NULL;
+	int param, pos;
+	
+
+	if ((s->n != 2) || (s->params[1].type != SEL_PARAM_DIV)) return -1;
+	param=s->params[1].v.i;
+
+	if (param & SEL_SRC) {
+		if (param & SEL_IP) {
+			ip_str.s = ip_addr2a(&msg->rcv.src_ip);
+			ip_str.len = strlen(ip_str.s);
+		}
+		if (param & SEL_PORT) {
+			port_str.s = int2str(msg->rcv.src_port, &port_str.len);
+		}
+	} else if (param & SEL_DST) {
+		if (param & SEL_IP) {
+			ip_str.s = ip_addr2a(&msg->rcv.dst_ip);
+			ip_str.len = strlen(ip_str.s);
+		}
+		if (param & SEL_PORT) {
+			port_str.s = int2str(msg->rcv.dst_port, &port_str.len);
+		}
+	} else if (param & SEL_RCV) {
+		if (param & SEL_IP) {
+			ip_str = msg->rcv.bind_address->address_str;
+		}
+		if (param & SEL_PORT) {
+			port_str = msg->rcv.bind_address->port_no_str;
+		}
+		if (param & SEL_PROTO) {
+			switch (msg->rcv.proto) {
+			case PROTO_NONE:
+				proto_str.s = 0;
+				proto_str.len = 0;
+				break;
+
+			case PROTO_UDP:
+				proto_str.s = "udp";
+				proto_str.len = 3;
+				break;
+
+			case PROTO_TCP:
+				proto_str.s = "tcp";
+				proto_str.len = 3;
+				break;
+
+			case PROTO_TLS:
+				proto_str.s = "tls";
+				proto_str.len = 3;
+				break;
+
+			case PROTO_SCTP:
+				proto_str.s = "sctp";
+				proto_str.len = 4;
+				break;
+
+			default:
+				ERR("BUG: select_ip_port: Unknown transport protocol\n");
+				return -1;
+			}
+		}
+	} else {
+		return -1;
+	}
+
+	res->s = get_static_buffer(ip_str.len+port_str.len+proto_str.len+3);
+	if (!res->s) return -1;
+
+	pos=0;
+	if (param & SEL_PROTO) {
+		memcpy(res->s, proto_str.s, proto_str.len);
+		pos += proto_str.len;
+	}
+	if (param & SEL_IP) {
+		if (pos) res->s[pos++] = ':';
+		memcpy(res->s+pos, ip_str.s, ip_str.len);
+		pos += ip_str.len;
+	}
+	if (param & SEL_PORT) {
+		if (pos) res->s[pos++] = ':';
+		memcpy(res->s+pos, port_str.s, port_str.len);
+		pos += port_str.len;
+	}
+	res->s[pos] = 0;
+	res->len = pos;
+	return (pos==0 ? 1 : 0);
+
+}
+

+ 30 - 0
select_core.h

@@ -61,6 +61,16 @@ enum {
 	SEL_AUTH_QOP
 };
 
+enum {
+	SEL_SRC  = 1<<0,
+	SEL_DST  = 1<<1,
+	SEL_RCV  = 1<<2,
+	SEL_PROTO= 1<<5,
+	SEL_IP   = 1<<6,
+	SEL_PORT = 1<<7,
+	SEL_IP_PORT = SEL_IP | SEL_PORT,
+};
+
 SELECT_F(select_method)
 SELECT_F(select_ruri)
 SELECT_F(select_from)
@@ -123,6 +133,11 @@ SELECT_F(select_auth_param)
 SELECT_F(select_auth_username)
 SELECT_F(select_auth_username_comp)
 
+SELECT_F(select_src)
+SELECT_F(select_dst)
+SELECT_F(select_rcv)
+SELECT_F(select_ip_port)
+
 static select_row_t select_core[] = {
 	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("method"), select_method, 0},
 	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("ruri"), select_ruri, 0},
@@ -214,6 +229,21 @@ static select_row_t select_core[] = {
 	{ select_auth_username, SEL_PARAM_STR, STR_STATIC_INIT("user"), select_auth_username_comp, DIVERSION | SEL_AUTH_USER},
 	{ select_auth_username, SEL_PARAM_STR, STR_STATIC_INIT("domain"), select_auth_username_comp, DIVERSION | SEL_AUTH_DOMAIN},
 
+	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("src"), select_src, SEL_PARAM_EXPECTED},
+	{ select_src, SEL_PARAM_STR, STR_STATIC_INIT("ip"), select_ip_port, DIVERSION | SEL_SRC | SEL_IP},
+	{ select_src, SEL_PARAM_STR, STR_STATIC_INIT("port"), select_ip_port, DIVERSION | SEL_SRC | SEL_PORT},
+	{ select_src, SEL_PARAM_STR, STR_STATIC_INIT("ip_port"), select_ip_port, DIVERSION | SEL_SRC | SEL_IP_PORT},
+	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("dst"), select_dst, SEL_PARAM_EXPECTED},
+	{ select_dst, SEL_PARAM_STR, STR_STATIC_INIT("ip"), select_ip_port, DIVERSION | SEL_DST | SEL_IP},
+	{ select_dst, SEL_PARAM_STR, STR_STATIC_INIT("port"), select_ip_port, DIVERSION | SEL_DST | SEL_PORT},
+	{ select_dst, SEL_PARAM_STR, STR_STATIC_INIT("ip_port"), select_ip_port, DIVERSION | SEL_DST | SEL_IP_PORT},
+	{ NULL, SEL_PARAM_STR, STR_STATIC_INIT("received"), select_rcv, SEL_PARAM_EXPECTED},
+	{ select_rcv, SEL_PARAM_STR, STR_STATIC_INIT("proto"), select_ip_port, DIVERSION | SEL_RCV | SEL_PROTO},
+	{ select_rcv, SEL_PARAM_STR, STR_STATIC_INIT("ip"), select_ip_port, DIVERSION | SEL_RCV | SEL_IP},
+	{ select_rcv, SEL_PARAM_STR, STR_STATIC_INIT("port"), select_ip_port, DIVERSION | SEL_RCV | SEL_PORT},
+	{ select_rcv, SEL_PARAM_STR, STR_STATIC_INIT("ip_port"), select_ip_port, DIVERSION | SEL_RCV | SEL_IP_PORT},
+	{ select_rcv, SEL_PARAM_STR, STR_STATIC_INIT("proto_ip_port"), select_ip_port, DIVERSION | SEL_RCV | SEL_PROTO | SEL_IP_PORT},
+
 	{ NULL, SEL_PARAM_INT, STR_NULL, NULL, 0}
 };