Browse code

sipdump: insert P-KSR-SIPDump header if SIPDUMP_MODE_WPCAPEX flag is set

- inserted header contains sip message specific meta data (transport,
pid, proc no)

Daniel-Constantin Mierla authored on 16/07/2020 12:00:09
Showing 1 changed files
... ...
@@ -28,6 +28,8 @@
28 28
 
29 29
 #include "sipdump_write.h"
30 30
 
31
+extern int sipdump_mode;
32
+
31 33
 /* structures related to PCAP headers imported from open source Asterisk project
32 34
  * fuction to write to PCAP file adapted for internal structures
33 35
  * source: res_pjsip_logger.c - License GPLv2 -  Copyright (C) Digium, Inc.*/
... ...
@@ -113,8 +115,15 @@ void sipdump_init_pcap(FILE *fs)
113 115
 	}
114 116
 }
115 117
 
118
+static char *_sipdump_pcap_data_buf = NULL;
119
+
116 120
 void sipdump_write_pcap(FILE *fs, sipdump_data_t *spd)
117 121
 {
122
+	str data = str_init("");
123
+	str mval = str_init("");
124
+	str sproto = str_init("none");
125
+	char *p = NULL;
126
+
118 127
 	struct pcap_record_header v_pcap_record_header = {
119 128
 		.ts_sec = spd->tv.tv_sec,
120 129
 		.ts_usec = spd->tv.tv_usec,
... ...
@@ -139,10 +148,40 @@ void sipdump_write_pcap(FILE *fs, sipdump_data_t *spd)
139 148
 		return;
140 149
 	}
141 150
 
151
+	data = spd->data;
152
+	if((sipdump_mode & SIPDUMP_MODE_WPCAPEX) && (spd->data.len < BUF_SIZE - 256)) {
153
+		if(_sipdump_pcap_data_buf == NULL) {
154
+			_sipdump_pcap_data_buf = (char*)malloc(BUF_SIZE);
155
+		}
156
+		if(_sipdump_pcap_data_buf != NULL) {
157
+			data.s = _sipdump_pcap_data_buf;
158
+			data.len = 0;
159
+			mval.s = q_memchr(spd->data.s, '\n', spd->data.len);
160
+			p = data.s;
161
+			if(mval.s != NULL) {
162
+				data.len = mval.s - spd->data.s + 1;
163
+				memcpy(p, spd->data.s, data.len);
164
+				p += data.len;
165
+				get_valid_proto_string(spd->protoid, 0, 0, &sproto);
166
+				mval.len = snprintf(p, BUF_SIZE - (data.len + 1),
167
+						"P-KSR-SIPDump: %.*s pid=%d pno=%d\r\n",
168
+						sproto.len, sproto.s, spd->pid, spd->procno);
169
+				if(mval.len < 0 || mval.len >= BUF_SIZE - (data.len + 1)) {
170
+					data = spd->data;
171
+				} else {
172
+					data.len += mval.len;
173
+					p += mval.len;
174
+					mval.s += 1;
175
+					memcpy(p, mval.s, spd->data.s + spd->data.len - mval.s);
176
+					data.len += spd->data.s + spd->data.len - mval.s;
177
+				}
178
+			}
179
+		}
180
+	}
142 181
 	/* always store UDP */
143 182
 	v_pcap_udp_header.src = ntohs(spd->src_port);
144 183
 	v_pcap_udp_header.dst = ntohs(spd->dst_port);
145
-	v_pcap_udp_header.length = ntohs(sizeof(struct pcap_udp_header) + spd->data.len);
184
+	v_pcap_udp_header.length = ntohs(sizeof(struct pcap_udp_header) + data.len);
146 185
 
147 186
 	/* IP header */
148 187
 	if (spd->afid == AF_INET6) {
... ...
@@ -161,7 +200,7 @@ void sipdump_write_pcap(FILE *fs, sipdump_data_t *spd)
161 200
 		}
162 201
 		memcpy(&v_pcap_ipv6_header.ip6_dst, &ip6addr, sizeof(struct in6_addr));
163 202
 		v_pcap_ipv6_header.ip6_ctlun.ip6_un1.ip6_un1_plen = htons(sizeof(struct pcap_udp_header)
164
-					+ spd->data.len);
203
+					+ data.len);
165 204
 		v_pcap_ipv6_header.ip6_ctlun.ip6_un1.ip6_un1_nxt = IPPROTO_UDP;
166 205
 	} else {
167 206
 		LM_DBG("ipv4 = %s -> %s\n", spd->src_ip.s, spd->dst_ip.s);
... ...
@@ -179,13 +218,13 @@ void sipdump_write_pcap(FILE *fs, sipdump_data_t *spd)
179 218
 		}
180 219
 		memcpy(&v_pcap_ipv4_header.ip_dst, &ip4addr, sizeof(uint32_t));
181 220
 		v_pcap_ipv4_header.ip_len = htons(sizeof(struct pcap_udp_header)
182
-					+ sizeof(struct pcap_ipv4_header) + spd->data.len);
221
+					+ sizeof(struct pcap_ipv4_header) + data.len);
183 222
 		v_pcap_ipv4_header.ip_protocol = IPPROTO_UDP; /* UDP */
184 223
 	}
185 224
 
186 225
 	/* add up all the sizes for this record */
187 226
 	v_pcap_record_header.orig_len = sizeof(struct pcap_ethernet_header) + pcap_ip_header_len
188
-			+ sizeof(struct pcap_udp_header) + spd->data.len;
227
+			+ sizeof(struct pcap_udp_header) + data.len;
189 228
 	v_pcap_record_header.incl_len = v_pcap_record_header.orig_len;
190 229
 
191 230
 	if (fwrite(&v_pcap_record_header, sizeof(struct pcap_record_header), 1, fs) != 1) {
... ...
@@ -200,7 +239,7 @@ void sipdump_write_pcap(FILE *fs, sipdump_data_t *spd)
200 239
 	if (fwrite(&v_pcap_udp_header, sizeof(struct pcap_udp_header), 1, fs) != 1) {
201 240
 		LM_ERR("writing UDP header to pcap failed: %s\n", strerror(errno));
202 241
 	}
203
-	if (fwrite(spd->data.s, spd->data.len, 1, fs) != 1) {
242
+	if (fwrite(data.s, data.len, 1, fs) != 1) {
204 243
 		LM_ERR("writing UDP payload to pcap failed: %s\n", strerror(errno));
205 244
 	}
206 245
 	fflush(fs);