diff --git a/modules/path/path.c b/modules/path/path.c
index 122d7fa..6cf7f8f 100644
--- a/modules/path/path.c
+++ b/modules/path/path.c
@@ -49,83 +49,72 @@ typedef enum {
 #define PATH_PREFIX		"Path: <sip:"
 #define PATH_PREFIX_LEN		(sizeof(PATH_PREFIX)-1)
 
-#define PATH_LR_PARAM		";lr"
-#define PATH_LR_PARAM_LEN	(sizeof(PATH_LR_PARAM)-1)
-
-#define PATH_RC_PARAM		";received="
-#define PATH_RC_PARAM_LEN	(sizeof(PATH_RC_PARAM)-1)
-
-#define PATH_OB_PARAM		";ob"
-#define PATH_OB_PARAM_LEN	(sizeof(PATH_OB_PARAM)-1)
-
-#define	PATH_CRLF		">\r\n"
-#define PATH_CRLF_LEN		(sizeof(PATH_CRLF)-1)
-
-#define ALLOC_AND_COPY_PATH_HDR() \
-	if ((suffix = pkg_malloc(suffix_len)) == NULL) { \
-		LM_ERR("no pkg memory left for suffix\n"); \
-		goto out1; \
-	} \
-	memcpy(suffix, PATH_LR_PARAM, PATH_LR_PARAM_LEN);
-
-static int prepend_path(struct sip_msg* _m, str *user, path_param_t param)
+const static char *proto_strings[] = {
+	[PROTO_TCP] = "%3Btransport%3Dtcp",
+	[PROTO_TLS] = "%3Btransport%3Dtls",
+	[PROTO_SCTP] = "%3Btransport%3Dsctp",
+	[PROTO_WS] = "%3Btransport%3Dws",
+	[PROTO_WSS] = "%3Btransport%3Dws",
+};
+
+static int prepend_path(struct sip_msg* _m, str *user, path_param_t param, str *add_params)
 {
 	struct lump *l;
-	char *prefix, *suffix, *crlf;
+	char *prefix, *suffix, *cp;
+	const char *proto_str;
 	int prefix_len, suffix_len;
 	struct hdr_field *hf;
-	str rcv_addr = {0, 0};
-	char *src_ip;
-		
-	prefix = suffix = crlf = 0;
 
-	prefix_len = PATH_PREFIX_LEN + (user->len ? (user->len+1) : 0);
-	prefix = pkg_malloc(prefix_len);
-	if (!prefix) {
-		LM_ERR("no pkg memory left for prefix\n");
+	/* maximum possible length of suffix */
+	suffix_len = strlen(";lr;received=sip::12345%3Btransport%3Dsctp;ob;>\r\n")
+			+ IP_ADDR_MAX_STR_SIZE + (add_params ? add_params->len : 0) + 1;
+
+	cp = suffix = pkg_malloc(suffix_len);
+	if (!suffix) {
+		LM_ERR("no pkg memory left for suffix\n");
 		goto out1;
 	}
-	memcpy(prefix, PATH_PREFIX, PATH_PREFIX_LEN);
-	if (user->len) {
-		memcpy(prefix + PATH_PREFIX_LEN, user->s, user->len);
-		memcpy(prefix + prefix_len - 1, "@", 1);
-	}
+
+	cp += sprintf(cp, ";lr");
 
 	switch(param) {
 	default:
-		suffix_len = PATH_LR_PARAM_LEN;
-		ALLOC_AND_COPY_PATH_HDR();
 		break;
 	case PATH_PARAM_RECEIVED:
-		suffix_len = PATH_LR_PARAM_LEN + PATH_RC_PARAM_LEN;
-		ALLOC_AND_COPY_PATH_HDR();
-		memcpy(suffix + PATH_LR_PARAM_LEN, PATH_RC_PARAM,	
-			PATH_RC_PARAM_LEN);
+		if (_m->rcv.proto < (sizeof(proto_strings) / sizeof(*proto_strings)))
+			proto_str = proto_strings[(unsigned int) _m->rcv.proto];
+		else
+			proto_str = NULL;
+
+		cp += sprintf(cp, ";received=sip:%s:%hu%s", ip_addr2a(&_m->rcv.src_ip),
+				_m->rcv.src_port, proto_str ? : "");
 		break;
 	case PATH_PARAM_OB:
-		suffix_len = PATH_LR_PARAM_LEN + PATH_OB_PARAM_LEN;
-		ALLOC_AND_COPY_PATH_HDR();
-		memcpy(suffix + PATH_LR_PARAM_LEN, PATH_OB_PARAM,
-			PATH_OB_PARAM_LEN);
+		cp += sprintf(cp, ";ob");
 		break;
 	}
 
-	crlf = pkg_malloc(PATH_CRLF_LEN);
-	if (!crlf) {
-		LM_ERR("no pkg memory left for crlf\n");
-		goto out1;
+	if (add_params && add_params->len)
+		cp += sprintf(cp, ";%.*s", add_params->len, add_params->s);
+
+	cp += sprintf(cp, ">\r\n");
+
+	prefix_len = PATH_PREFIX_LEN + (user ? user->len : 0) + 2;
+	prefix = pkg_malloc(prefix_len);
+	if (!prefix) {
+		LM_ERR("no pkg memory left for prefix\n");
+		goto out2;
 	}
-	memcpy(crlf, PATH_CRLF, PATH_CRLF_LEN);
+	if (user && user->len)
+		prefix_len = sprintf(prefix, PATH_PREFIX "%.*s@", user->len, user->s);
+	else
+		prefix_len = sprintf(prefix, PATH_PREFIX);
 
 	if (parse_headers(_m, HDR_PATH_F, 0) < 0) {
 		LM_ERR("failed to parse message for Path header\n");
-		goto out1;
-	}
-	for (hf = _m->headers; hf; hf = hf->next) {
-		if (hf->type == HDR_PATH_T) {
-			break;
-		} 
+		goto out3;
 	}
+	hf = get_hdr(_m, HDR_PATH_T);
 	if (hf)
 		/* path found, add ours in front of that */
 		l = anchor_lump(_m, hf->name.s - _m->buf, 0, 0);
@@ -134,60 +123,24 @@ static int prepend_path(struct sip_msg* _m, str *user, path_param_t param)
 		l = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
 	if (!l) {
 		LM_ERR("failed to get anchor\n");
-		goto out1;
+		goto out3;
 	}
 
 	l = insert_new_lump_before(l, prefix, prefix_len, 0);
-	if (!l) goto out1;
+	if (!l) goto out3;
 	l = insert_subst_lump_before(l, SUBST_SND_ALL, 0);
 	if (!l) goto out2;
-	l = insert_new_lump_before(l, suffix, suffix_len, 0);
+	l = insert_new_lump_before(l, suffix, cp - suffix, 0);
 	if (!l) goto out2;
-	if (param == PATH_PARAM_RECEIVED) {
-		/* TODO: agranig: optimize this one! */
-		src_ip = ip_addr2a(&_m->rcv.src_ip);
-		rcv_addr.s = pkg_malloc(6 + IP_ADDR_MAX_STR_SIZE + 24); /* sip:<ip>:<port>%3Btransport%3Dsctp\0 */
-		if(!rcv_addr.s) {
-			LM_ERR("no pkg memory left for receive-address\n");
-			goto out3;
-		}
-		switch (_m->rcv.proto) {
-			case PROTO_UDP:
-				rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 4, "sip:%s:%u", src_ip, _m->rcv.src_port);
-				break;
-			case PROTO_TCP:
-				rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 22, "sip:%s:%u%%3Btransport%%3Dtcp", src_ip, _m->rcv.src_port);
-				break;
-			case PROTO_TLS:
-				rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 22, "sip:%s:%u%%3Btransport%%3Dtls", src_ip, _m->rcv.src_port);
-				break;
-			case PROTO_SCTP:
-				rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 23, "sip:%s:%u%%3Btransport%%3Dsctp", src_ip, _m->rcv.src_port);
-				break;
-			case PROTO_WS:
-			case PROTO_WSS:
-				rcv_addr.len = snprintf(rcv_addr.s, 6 + IP_ADDR_MAX_STR_SIZE + 21, "sip:%s:%u%%3Btransport%%3Dws", src_ip, _m->rcv.src_port);
-				break;
-	    }
-
-		l = insert_new_lump_before(l, rcv_addr.s, rcv_addr.len, 0);
-		if (!l) goto out3;
-	}
-	l = insert_new_lump_before(l, crlf, CRLF_LEN+1, 0);
-	if (!l) goto out4;
-	
+
 	return 1;
-	
-out1:
-	if (prefix) pkg_free(prefix);
-out2:
-	if (suffix) pkg_free(suffix);
-out3:
-	if (rcv_addr.s) pkg_free(rcv_addr.s);
-out4:
-	if (crlf) pkg_free(crlf);
 
-	LM_ERR("failed to insert prefix lump\n");
+out3:
+	pkg_free(prefix);
+out2:
+	pkg_free(suffix);
+out1:
+	LM_ERR("failed to insert Path header\n");
 
 	return -1;
 }
@@ -215,7 +168,7 @@ int add_path(struct sip_msg* _msg, char* _a, char* _b)
 			param = PATH_PARAM_OB;
 	}
 
-	ret = prepend_path(_msg, &user, param);
+	ret = prepend_path(_msg, &user, param, NULL);
 
 	if (user.s != NULL)
 		pkg_free(user.s);
@@ -227,9 +180,17 @@ int add_path(struct sip_msg* _msg, char* _a, char* _b)
  * Prepend own uri to Path header and take care of given
  * user.
  */
-int add_path_usr(struct sip_msg* _msg, char* _usr, char* _b)
+int add_path_usr(struct sip_msg* _msg, char* _usr, char* _parms)
 {
-	return prepend_path(_msg, (str*)_usr, PATH_PARAM_NONE);
+	str user = {0,0};
+	str parms = {0,0};
+
+	if (_usr)
+		get_str_fparam(&user, _msg, (fparam_t *) _usr);
+	if (_parms)
+		get_str_fparam(&parms, _msg, (fparam_t *) _parms);
+
+	return prepend_path(_msg, &user, PATH_PARAM_NONE, &parms);
 }
 
 /*! \brief
@@ -238,17 +199,24 @@ int add_path_usr(struct sip_msg* _msg, char* _usr, char* _b)
  */
 int add_path_received(struct sip_msg* _msg, char* _a, char* _b)
 {
-	str user = {0,0};
-	return prepend_path(_msg, &user, PATH_PARAM_RECEIVED);
+	return prepend_path(_msg, NULL, PATH_PARAM_RECEIVED, NULL);
 }
 
 /*! \brief
  * Prepend own uri to Path header and append received address as
  * "received"-param to that uri and take care of given user.
  */
-int add_path_received_usr(struct sip_msg* _msg, char* _usr, char* _b)
+int add_path_received_usr(struct sip_msg* _msg, char* _usr, char* _parms)
 {
-	return prepend_path(_msg, (str*)_usr, PATH_PARAM_RECEIVED);
+	str user = {0,0};
+	str parms = {0,0};
+
+	if (_usr)
+		get_str_fparam(&user, _msg, (fparam_t *) _usr);
+	if (_parms)
+		get_str_fparam(&parms, _msg, (fparam_t *) _parms);
+
+	return prepend_path(_msg, &user, PATH_PARAM_RECEIVED, &parms);
 }
 
 /*! \brief
diff --git a/modules/path/path_mod.c b/modules/path/path_mod.c
index 15fbc4d..0da11ae 100644
--- a/modules/path/path_mod.c
+++ b/modules/path/path_mod.c
@@ -87,11 +87,15 @@ static cmd_export_t cmds[] = {
 	{ "add_path",          (cmd_function)add_path,              0,
 			0,              0,  REQUEST_ROUTE },
 	{ "add_path",          (cmd_function)add_path_usr,          1,
-			fixup_str_null, 0, REQUEST_ROUTE },
+			fixup_spve_null, 0, REQUEST_ROUTE },
+	{ "add_path",          (cmd_function)add_path_usr,          2,
+			fixup_spve_spve, 0, REQUEST_ROUTE },
 	{ "add_path_received", (cmd_function)add_path_received,     0,
 			0,              0, REQUEST_ROUTE },
 	{ "add_path_received", (cmd_function)add_path_received_usr, 1,
-			fixup_str_null, 0, REQUEST_ROUTE },
+			fixup_spve_null, 0, REQUEST_ROUTE },
+	{ "add_path_received", (cmd_function)add_path_received_usr, 2,
+			fixup_spve_spve, 0, REQUEST_ROUTE },
 	{ 0, 0, 0, 0, 0, 0 }
 };
 
