[sr-dev] git:master: ipops: new pv to get hostname details:

Daniel-Constantin Mierla miconda at gmail.com
Sun Apr 13 22:22:44 CEST 2014


Module: sip-router
Branch: master
Commit: 997f13c89d16361799651cd77214ffdcf26d532c
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=997f13c89d16361799651cd77214ffdcf26d532c

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Sun Apr 13 16:22:38 2014 +0200

ipops: new pv to get hostname details:

- $HN(n) - hostname
- $HN(d) - domain
- $HN(f) - fullname
- $HN(i) - ip address
- based on gethsontname and resolving it

---

 modules/ipops/ipops_mod.c |    2 +
 modules/ipops/ipops_pv.c  |  166 +++++++++++++++++++++++++++++++++++++++++++++
 modules/ipops/ipops_pv.h  |    4 +
 3 files changed, 172 insertions(+), 0 deletions(-)

diff --git a/modules/ipops/ipops_mod.c b/modules/ipops/ipops_mod.c
index d90aaa3..4e174f5 100644
--- a/modules/ipops/ipops_mod.c
+++ b/modules/ipops/ipops_mod.c
@@ -96,6 +96,8 @@ static int w_dns_query(struct sip_msg* msg, char* str1, char* str2);
 static pv_export_t mod_pvs[] = {
 	{ {"dns", sizeof("dns")-1}, PVT_OTHER, pv_get_dns, 0,
 		pv_parse_dns_name, 0, 0, 0 },
+	{ {"HN", sizeof("HN")-1}, PVT_OTHER, pv_get_hn, 0,
+		pv_parse_hn_name, 0, 0, 0 },
 	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
 };
 
diff --git a/modules/ipops/ipops_pv.c b/modules/ipops/ipops_pv.c
index 08be1fe..d6edadd 100644
--- a/modules/ipops/ipops_pv.c
+++ b/modules/ipops/ipops_pv.c
@@ -33,6 +33,7 @@
 
 #include "../../dprint.h"
 #include "../../hashes.h"
+#include "../../resolve.h"
 #include "../../pvar.h"
 
 
@@ -428,3 +429,168 @@ int dns_update_pv(str *hostname, str *name)
 
 	return 1;
 }
+
+
+struct _hn_pv_data {
+	str data;
+	str fullname;
+	str hostname;
+	str domain;
+	str ipaddr;
+};
+
+static struct _hn_pv_data *_hn_data = NULL;
+
+/**
+ *
+ */
+int hn_pv_data_init(void)
+{
+	char hbuf[512];
+	int hlen;
+	char *d;
+	struct hostent *he;
+	int i;
+
+	if(_hn_data != NULL)
+		return 0;
+
+	if (gethostname(hbuf, 512)<0) {
+		LM_WARN("gethostname failed - host pvs will be null\n");
+		return -1;
+	}
+
+	hlen = strlen(hbuf);
+	if(hlen<=0) {
+		LM_WARN("empty hostname result - host pvs will be null\n");
+		return -1;
+	}
+
+	_hn_data = (struct _hn_pv_data*)pkg_malloc(sizeof(struct _hn_pv_data)+46+2*(hlen+1));
+	if(_hn_data==NULL) {
+		LM_ERR("no more pkg to init hostname data\n");
+		return -1;
+	}
+	memset(_hn_data, 0, sizeof(struct _hn_pv_data)+46+2*(hlen+1));
+
+	_hn_data->data.len = hlen;
+	_hn_data->data.s = (char*)_hn_data + sizeof(struct _hn_pv_data);
+	_hn_data->fullname.len = hlen;
+	_hn_data->fullname.s = _hn_data->data.s + hlen + 1;
+
+	strcpy(_hn_data->data.s, hbuf);
+	strcpy(_hn_data->fullname.s, hbuf);
+
+	d=strchr(_hn_data->data.s, '.');
+	if (d) {
+		_hn_data->hostname.len   = d - _hn_data->data.s;
+		_hn_data->hostname.s     = _hn_data->data.s;
+		_hn_data->domain.len     = _hn_data->fullname.len
+										- _hn_data->hostname.len-1;
+		_hn_data->domain.s       = d+1;
+	} else {
+		_hn_data->hostname       = _hn_data->fullname;
+	}
+
+	he=resolvehost(_hn_data->fullname.s);
+	if (he) {
+		if ((strlen(he->h_name)!=_hn_data->fullname.len)
+				|| strncmp(he->h_name, _hn_data->fullname.s,
+									_hn_data->fullname.len)) {
+			LM_WARN("hostname '%.*s' different than gethostbyname '%s'\n",
+					_hn_data->fullname.len, _hn_data->fullname.s, he->h_name);
+		}
+
+		if (he->h_addr_list) {
+			for (i=0; he->h_addr_list[i]; i++) {
+				if (inet_ntop(he->h_addrtype, he->h_addr_list[i], hbuf, 46)) {
+					if (_hn_data->ipaddr.len==0) {
+						_hn_data->ipaddr.len = strlen(hbuf);
+						_hn_data->ipaddr.s = _hn_data->fullname.s + hlen + 1;
+						strcpy(_hn_data->ipaddr.s, hbuf);
+					} else if (strncmp(_hn_data->ipaddr.s, hbuf,
+								_hn_data->ipaddr.len)!=0) {
+						LM_WARN("many IPs to hostname: %s not used\n", hbuf);
+					}
+				}
+			}
+		} else {
+			LM_WARN(" can't resolve hostname's address: %s\n",
+					_hn_data->fullname.s);
+		}
+	}
+
+	DBG("Hostname: %.*s\n", _hn_data->hostname.len, ZSW(_hn_data->hostname.s));
+	DBG("Domain:   %.*s\n", _hn_data->domain.len, ZSW(_hn_data->domain.s));
+	DBG("Fullname: %.*s\n", _hn_data->fullname.len, ZSW(_hn_data->fullname.s));
+	DBG("IPaddr:   %.*s\n", _hn_data->ipaddr.len, ZSW(_hn_data->ipaddr.s));
+
+	return 0;
+}
+
+/**
+ *
+ */
+int pv_parse_hn_name(pv_spec_p sp, str *in)
+{
+	if(sp==NULL || in==NULL || in->len<=0)
+		return -1;
+
+	switch(in->len)
+	{
+		case 1: 
+			if(strncmp(in->s, "n", 1)==0)
+				sp->pvp.pvn.u.isname.name.n = 0;
+			else if(strncmp(in->s, "f", 1)==0)
+				sp->pvp.pvn.u.isname.name.n = 1;
+			else if(strncmp(in->s, "d", 1)==0)
+				sp->pvp.pvn.u.isname.name.n = 2;
+			else if(strncmp(in->s, "i", 1)==0)
+				sp->pvp.pvn.u.isname.name.n = 3;
+			else goto error;
+		break;
+		default:
+			goto error;
+	}
+	sp->pvp.pvn.type = PV_NAME_INTSTR;
+	sp->pvp.pvn.u.isname.type = 0;
+
+	hn_pv_data_init();
+
+	return 0;
+
+error:
+	LM_ERR("unknown host PV name %.*s\n", in->len, in->s);
+	return -1;
+}
+
+/**
+ *
+ */
+int pv_get_hn(struct sip_msg *msg, pv_param_t *param,
+		pv_value_t *res)
+{
+	if(param==NULL)
+		return -1;
+	if(_hn_data==NULL)
+		return pv_get_null(msg, param, res);;
+	switch(param->pvn.u.isname.name.n)
+	{
+		case 1:
+			if(_hn_data->fullname.len==0)
+				return pv_get_null(msg, param, res);;
+			return pv_get_strval(msg, param, res, &_hn_data->fullname);
+		case 2:
+			if(_hn_data->domain.len==0)
+				return pv_get_null(msg, param, res);;
+			return pv_get_strval(msg, param, res, &_hn_data->domain);
+		case 3:
+			if(_hn_data->ipaddr.len==0)
+				return pv_get_null(msg, param, res);;
+			return pv_get_strval(msg, param, res, &_hn_data->ipaddr);
+		default:
+			if(_hn_data->hostname.len==0)
+				return pv_get_null(msg, param, res);;
+			return pv_get_strval(msg, param, res, &_hn_data->hostname);
+	}
+}
diff --git a/modules/ipops/ipops_pv.h b/modules/ipops/ipops_pv.h
index 043d891..16c8ac8 100644
--- a/modules/ipops/ipops_pv.h
+++ b/modules/ipops/ipops_pv.h
@@ -35,5 +35,9 @@ int dns_init_pv(char *path);
 void dns_destroy_pv(void);
 int dns_update_pv(str *tomatch, str *name);
 
+int pv_parse_hn_name(pv_spec_p sp, str *in);
+int pv_get_hn(struct sip_msg *msg, pv_param_t *param,
+		pv_value_t *res);
+
 #endif
 




More information about the sr-dev mailing list