Browse code

core: unified function for returning string of a protocol

- returns variants for uppercase and lowecase, representation for uri or
bare proto: udp, tcp, tls, sctp, ws and wss
- in uri, PROTO_WS and PROTO_WSS are represented as transport=ws

Daniel-Constantin Mierla authored on 19/02/2015 08:09:14
Showing 4 changed files
... ...
@@ -307,7 +307,50 @@ int is_mcast(struct ip_addr* ip)
307 307
 
308 308
 #endif /* USE_MCAST */
309 309
 
310
-
310
+/** get string for known protocols.
311
+ * @param iproto - protocol number
312
+ * @param utype  - 1 if result is used for URI, or 0
313
+ * @param vtype  - 1 if result is wanted uppercase, or 0 for lowercase
314
+ * @param sproto - the string for the proto
315
+ * @return  0 if it is a valid and supported protocol, negative otherwise
316
+ */
317
+int get_valid_proto_string(unsigned int iproto, int utype, int vtype,
318
+		str *sproto)
319
+{
320
+	switch(iproto){
321
+		case PROTO_NONE:
322
+			return -1;
323
+		case PROTO_UDP:
324
+			sproto->len = 3;
325
+			sproto->s = (vtype)?"UDP":"udp";
326
+			return 0;
327
+		case PROTO_TCP:
328
+			sproto->len = 3;
329
+			sproto->s = (vtype)?"TCP":"tcp";
330
+			return 0;
331
+		case PROTO_TLS:
332
+			sproto->len = 3;
333
+			sproto->s = (vtype)?"TLS":"tls";
334
+			return 0;
335
+		case PROTO_SCTP:
336
+			sproto->len = 4;
337
+			sproto->s = (vtype)?"SCTP":"sctp";
338
+			return 0;
339
+		case PROTO_WS:
340
+		case PROTO_WSS:
341
+			if(iproto==PROTO_WS || utype) {
342
+				/* ws-only in SIP URI */
343
+				sproto->len = 2;
344
+				sproto->s = (vtype)?"WS":"ws";
345
+			} else {
346
+				sproto->len = 3;
347
+				sproto->s = (vtype)?"WSS":"wss";
348
+			}
349
+			return 0;
350
+		default:
351
+			return -2;
352
+	}
353
+}
311 354
 
312 355
 /** get protocol name (asciiz).
313 356
  * @param proto - protocol number
... ...
@@ -315,22 +358,14 @@ int is_mcast(struct ip_addr* ip)
315 315
  */
316 316
 char* get_proto_name(unsigned int proto)
317 317
 {
318
+	str sproto;
318 319
 	switch(proto){
319 320
 		case PROTO_NONE:
320 321
 			return "*";
321
-		case PROTO_UDP:
322
-			return "udp";
323
-		case PROTO_TCP:
324
-			return "tcp";
325
-		case PROTO_TLS:
326
-			return "tls";
327
-		case PROTO_SCTP:
328
-			return "sctp";
329
-		case PROTO_WS:
330
-		case PROTO_WSS:
331
-			return "ws";
332 322
 		default:
333
-			return "unknown";
323
+			if(get_valid_proto_string(proto, 1, 0, &sproto)<0)
324
+				return "unknown";
325
+			return sproto.s;
334 326
 	}
335 327
 }
336 328
 
... ...
@@ -245,7 +245,8 @@ void print_net(struct net* net);
245 245
 char* get_proto_name(unsigned int proto);
246 246
 #define proto2a get_proto_name
247 247
 
248
-
248
+int get_valid_proto_string(unsigned int iproto, int utype, int vtype,
249
+		str *sproto);
249 250
 
250 251
 #ifdef USE_MCAST
251 252
 /* Returns 1 if the given address is a multicast address */
... ...
@@ -1033,3 +1033,86 @@ int msg_set_time(sip_msg_t* const msg)
1033 1033
 		return 0;
1034 1034
 	return gettimeofday(&msg->tval, NULL);
1035 1035
 }
1036
+
1037
+/**
1038
+ * get source ip, port and protocol in SIP URI format
1039
+ * - tmode - 0: short format (transport=udp is not added, being default)
1040
+ */
1041
+int get_src_uri(sip_msg_t *m, int tmode, str *uri)
1042
+{
1043
+	static char buf[MAX_URI_SIZE];
1044
+	char* p;
1045
+	str ip, port;
1046
+	int len;
1047
+	str proto;
1048
+
1049
+	if (!uri || !m) {
1050
+		LM_ERR("invalid parameter value\n");
1051
+		return -1;
1052
+	}
1053
+
1054
+	if(tmode==0) {
1055
+		switch(m->rcv.proto) {
1056
+			case PROTO_NONE:
1057
+			case PROTO_UDP:
1058
+				proto.s = 0; /* Do not add transport parameter, UDP is default */
1059
+				proto.len = 0;
1060
+			break;
1061
+			default:
1062
+				if(get_valid_proto_string(m->rcv.proto, 1, 0, &proto)<0) {
1063
+					LM_ERR("unknown transport protocol\n");
1064
+					return -1;
1065
+				}
1066
+		}
1067
+	} else {
1068
+		if(get_valid_proto_string(m->rcv.proto, 1, 0, &proto)<0) {
1069
+			LM_ERR("unknown transport protocol\n");
1070
+			return -1;
1071
+		}
1072
+	}
1073
+
1074
+	ip.s = ip_addr2a(&m->rcv.src_ip);
1075
+	ip.len = strlen(ip.s);
1076
+
1077
+	port.s = int2str(m->rcv.src_port, &port.len);
1078
+
1079
+	len = 4 + ip.len + 2*(m->rcv.src_ip.af==AF_INET6)+ 1 + port.len;
1080
+	if (proto.s) {
1081
+		len += TRANSPORT_PARAM_LEN;
1082
+		len += proto.len;
1083
+	}
1084
+
1085
+	if (len > MAX_URI_SIZE) {
1086
+		LM_ERR("buffer too small\n");
1087
+		return -1;
1088
+	}
1089
+
1090
+	p = buf;
1091
+	memcpy(p, "sip:", 4);
1092
+	p += 4;
1093
+
1094
+	if (m->rcv.src_ip.af==AF_INET6)
1095
+		*p++ = '[';
1096
+	memcpy(p, ip.s, ip.len);
1097
+	p += ip.len;
1098
+	if (m->rcv.src_ip.af==AF_INET6)
1099
+		*p++ = ']';
1100
+
1101
+	*p++ = ':';
1102
+
1103
+	memcpy(p, port.s, port.len);
1104
+	p += port.len;
1105
+
1106
+	if (proto.s) {
1107
+		memcpy(p, TRANSPORT_PARAM, TRANSPORT_PARAM_LEN);
1108
+		p += TRANSPORT_PARAM_LEN;
1109
+
1110
+		memcpy(p, proto.s, proto.len);
1111
+		p += proto.len;
1112
+	}
1113
+
1114
+	uri->s = buf;
1115
+	uri->len = len;
1116
+
1117
+	return 0;
1118
+}
... ...
@@ -521,4 +521,9 @@ int msg_set_time(sip_msg_t* const msg);
521 521
  */
522 522
 void msg_ldata_reset(sip_msg_t*);
523 523
 
524
+/**
525
+ * get source ip, port and protocol in SIP URI format
526
+ */
527
+int get_src_uri(sip_msg_t *m, int tmode, str *uri);
528
+
524 529
 #endif