1 /*
2 * siptrace module - helper module to trace sip messages
3 *
4 * Copyright (C) 2017 kamailio.org
5 *
6 * This file is part of Kamailio, a free SIP server.
7 *
8 * Kamailio is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version
12 *
13 * Kamailio is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include "../../core/dprint.h"
29 #include "../../core/pvar.h"
30 #include "../../core/proxy.h"
31 #include "../../core/forward.h"
32 #include "../../core/resolve.h"
33 #include "../../core/socket_info.h"
34 #include "../../core/parser/parse_uri.h"
35
36 #include "../../modules/sipcapture/hep.h"
37
38 #include "siptrace_hep.h"
39
40 extern int hep_version;
41 extern int hep_capture_id;
42 extern int hep_vendor_id;
43 extern str hep_auth_key_str;
44 extern str trace_send_sock_str;
45 extern sip_uri_t *trace_send_sock_uri;
46 extern str trace_send_sock_name_str;
47 extern socket_info_t *trace_send_sock_info;
48 extern str trace_dup_uri_str;
49 extern sip_uri_t *trace_dup_uri;
50
51 /**
52 *
53 */
trace_send_hep_duplicate(str * body,str * from,str * to,struct dest_info * dst2,str * correlation_id_str)54 int trace_send_hep_duplicate(str *body, str *from, str *to,
55 struct dest_info *dst2, str *correlation_id_str)
56 {
57 switch(hep_version) {
58 case 1:
59 case 2:
60 return trace_send_hep2_duplicate(body, from, to, dst2);
61 case 3:
62 return trace_send_hep3_duplicate(
63 body, from, to, dst2, correlation_id_str);
64 default:
65 LM_ERR("Unsupported HEP version\n");
66 return -1;
67 }
68 }
69
70 /**
71 *
72 */
trace_send_hep3_duplicate(str * body,str * from,str * to,struct dest_info * dst2,str * correlation_id_str)73 int trace_send_hep3_duplicate(str *body, str *from, str *to,
74 struct dest_info *dst2, str *correlation_id_str)
75 {
76 struct socket_info *si;
77 void *buffer = NULL;
78 unsigned int len, proto;
79 struct dest_info dst;
80 struct dest_info *dst_fin = NULL;
81 struct proxy_l *p = NULL;
82 union sockaddr_union from_su;
83 union sockaddr_union to_su;
84 struct timeval tvb;
85 struct timezone tz;
86
87 gettimeofday(&tvb, &tz);
88
89 if(pipport2su(from->s, &from_su, &proto) == -1
90 || (pipport2su(to->s, &to_su, &proto) == -1))
91 goto error;
92
93 if(from_su.s.sa_family != to_su.s.sa_family) {
94 LM_ERR("interworking detected ?\n");
95 goto error;
96 }
97
98 len = sizeof(struct hep_ctrl); // header
99 len += sizeof(struct hep_chunk_uint8); // proto_family
100 len += sizeof(struct hep_chunk_uint8); // proto_id
101 if(from_su.s.sa_family == AF_INET6) {
102 len += sizeof(struct hep_chunk_ip6); // src IPv6 address
103 len += sizeof(struct hep_chunk_ip6); // dst IPv6 address
104 } else {
105 len += sizeof(struct hep_chunk_ip4); // src IPv4 address
106 len += sizeof(struct hep_chunk_ip4); // dst IPv4 address
107 }
108 len += sizeof(struct hep_chunk_uint16); // source port
109 len += sizeof(struct hep_chunk_uint16); // destination port
110 len += sizeof(struct hep_chunk_uint32); // timestamp
111 len += sizeof(struct hep_chunk_uint32); // timestamp us
112 len += sizeof(struct hep_chunk_uint8); // proto_type (SIP)
113 len += sizeof(struct hep_chunk_uint32); // capture ID
114 len += sizeof(struct hep_chunk); // payload
115
116 if(hep_auth_key_str.s && hep_auth_key_str.len > 0) {
117 len += sizeof(struct hep_chunk) + hep_auth_key_str.len;
118 }
119
120 if(correlation_id_str) {
121 if(correlation_id_str->len > 0) {
122 len += sizeof(struct hep_chunk) + correlation_id_str->len;
123 }
124 }
125
126 len += body->len;
127
128 if(unlikely(len > BUF_SIZE)) {
129 goto error;
130 }
131
132 buffer = (void *)pkg_malloc(len);
133 if(!buffer) {
134 LM_ERR("out of memory\n");
135 goto error;
136 }
137
138 HEP3_PACK_INIT(buffer);
139 HEP3_PACK_CHUNK_UINT8(0, 0x0001, from_su.s.sa_family);
140 HEP3_PACK_CHUNK_UINT8(0, 0x0002, proto);
141 if(from_su.s.sa_family == AF_INET) {
142 HEP3_PACK_CHUNK_UINT32_NBO(0, 0x0003, from_su.sin.sin_addr.s_addr);
143 HEP3_PACK_CHUNK_UINT32_NBO(0, 0x0004, to_su.sin.sin_addr.s_addr);
144 HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0007, htons(from_su.sin.sin_port));
145 HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0008, htons(to_su.sin.sin_port));
146 } else if(from_su.s.sa_family == AF_INET6) {
147 HEP3_PACK_CHUNK_IP6(0, 0x0005, &from_su.sin6.sin6_addr);
148 HEP3_PACK_CHUNK_IP6(0, 0x0006, &to_su.sin6.sin6_addr);
149 HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0007, htons(from_su.sin6.sin6_port));
150 HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0008, htons(to_su.sin6.sin6_port));
151 } else {
152 LM_ERR("unknown address family [%u]\n", from_su.s.sa_family);
153 goto error;
154 }
155
156 HEP3_PACK_CHUNK_UINT32(0, 0x0009, tvb.tv_sec);
157 HEP3_PACK_CHUNK_UINT32(0, 0x000a, tvb.tv_usec);
158 HEP3_PACK_CHUNK_UINT8(0, 0x000b, 0x01); /* protocol type: SIP */
159 HEP3_PACK_CHUNK_UINT32(0, 0x000c, hep_capture_id);
160
161 if(correlation_id_str) {
162 if(correlation_id_str->len > 0) {
163 HEP3_PACK_CHUNK_DATA(
164 0, 0x0011, correlation_id_str->s, correlation_id_str->len);
165 }
166 }
167 if(hep_auth_key_str.s && hep_auth_key_str.len > 0) {
168 HEP3_PACK_CHUNK_DATA(0, 0x000e, hep_auth_key_str.s, hep_auth_key_str.len);
169 }
170 HEP3_PACK_CHUNK_DATA(0, 0x000f, body->s, body->len);
171 HEP3_PACK_FINALIZE(buffer, &len);
172
173 if(!dst2) {
174 init_dest_info(&dst);
175 dst.proto = trace_dup_uri->proto;
176 p = mk_proxy(&trace_dup_uri->host, trace_dup_uri->port_no, dst.proto);
177 if(p == 0) {
178 LM_ERR("bad host name in uri\n");
179 goto error;
180 }
181
182 hostent2su(
183 &dst.to, &p->host, p->addr_idx, (p->port) ? p->port : SIP_PORT);
184 LM_DBG("setting up the socket_info\n");
185 dst_fin = &dst;
186 } else {
187 dst_fin = dst2;
188 }
189
190 if(trace_send_sock_str.s) {
191 LM_DBG("send sock activated, grep for the sock_info\n");
192 si = grep_sock_info(&trace_send_sock_uri->host,
193 trace_send_sock_uri->port_no,
194 trace_send_sock_uri->proto);
195 if(!si) {
196 LM_WARN("cannot grep socket info\n");
197 } else {
198 LM_DBG("found socket while grep: [%.*s] [%.*s]\n", si->name.len,
199 si->name.s, si->address_str.len, si->address_str.s);
200 dst_fin->send_sock = si;
201 }
202 }
203
204 if(dst_fin->send_sock == 0) {
205 dst_fin->send_sock = get_send_socket(0, &dst_fin->to, dst_fin->proto);
206 if(dst_fin->send_sock == 0) {
207 LM_ERR("can't forward to af %d, proto %d no corresponding"
208 " listening socket\n",
209 dst_fin->to.s.sa_family, dst_fin->proto);
210 goto error;
211 }
212 }
213
214 if(msg_send_buffer(dst_fin, buffer, len, 1) < 0) {
215 LM_ERR("cannot send hep duplicate message\n");
216 goto error;
217 }
218
219 if(p) {
220 free_proxy(p); /* frees only p content, not p itself */
221 pkg_free(p);
222 }
223 pkg_free(buffer);
224 return 0;
225 error:
226 if(p) {
227 free_proxy(p); /* frees only p content, not p itself */
228 pkg_free(p);
229 }
230 if(buffer)
231 pkg_free(buffer);
232 return -1;
233 }
234
235 /**
236 *
237 */
trace_send_hep2_duplicate(str * body,str * from,str * to,struct dest_info * dst2)238 int trace_send_hep2_duplicate(
239 str *body, str *from, str *to, struct dest_info *dst2)
240 {
241 struct dest_info dst;
242 struct socket_info *si;
243 struct dest_info *dst_fin = NULL;
244 struct proxy_l *p = NULL /* make gcc happy */;
245 void *buffer = NULL;
246 union sockaddr_union from_su;
247 union sockaddr_union to_su;
248 unsigned int len, buflen, proto;
249 struct hep_hdr hdr;
250 struct hep_iphdr hep_ipheader;
251 struct hep_timehdr hep_time;
252 struct timeval tvb;
253 struct timezone tz;
254
255 struct hep_ip6hdr hep_ip6header;
256
257 if(body->s == NULL || body->len <= 0)
258 return -1;
259
260 if(trace_dup_uri_str.s == 0 || trace_dup_uri == NULL)
261 return 0;
262
263
264 gettimeofday(&tvb, &tz);
265
266
267 /* message length */
268 len = body->len + sizeof(struct hep_ip6hdr) + sizeof(struct hep_hdr)
269 + sizeof(struct hep_timehdr);
270 ;
271
272
273 /* The packet is too big for us */
274 if(unlikely(len > BUF_SIZE)) {
275 goto error;
276 }
277
278 /* Convert proto:ip:port to sockaddress union SRC IP */
279 if(pipport2su(from->s, &from_su, &proto) == -1
280 || (pipport2su(to->s, &to_su, &proto) == -1))
281 goto error;
282
283 /* check if from and to are in the same family*/
284 if(from_su.s.sa_family != to_su.s.sa_family) {
285 LM_ERR("interworking detected ?\n");
286 goto error;
287 }
288
289 if(!dst2) {
290 init_dest_info(&dst);
291 /* create a temporary proxy*/
292 dst.proto = trace_dup_uri->proto;
293 p = mk_proxy(&trace_dup_uri->host, trace_dup_uri->port_no, dst.proto);
294 if(p == 0) {
295 LM_ERR("bad host name in uri\n");
296 goto error;
297 }
298
299 hostent2su(
300 &dst.to, &p->host, p->addr_idx, (p->port) ? p->port : SIP_PORT);
301 LM_DBG("setting up the socket_info\n");
302 dst_fin = &dst;
303 } else {
304 dst_fin = dst2;
305 }
306
307 if(trace_send_sock_str.s) {
308 LM_DBG("send sock activated, grep for the sock_info\n");
309 si = grep_sock_info(&trace_send_sock_uri->host,
310 trace_send_sock_uri->port_no,
311 trace_send_sock_uri->proto);
312 if(!si) {
313 LM_WARN("cannot grep socket info\n");
314 } else {
315 LM_DBG("found socket while grep: [%.*s] [%.*s]\n", si->name.len,
316 si->name.s, si->address_str.len, si->address_str.s);
317 dst_fin->send_sock = si;
318 }
319 }
320
321 if(dst_fin->send_sock == 0) {
322 dst_fin->send_sock = get_send_socket(0, &dst_fin->to, dst_fin->proto);
323 if(dst_fin->send_sock == 0) {
324 LM_ERR("can't forward to af %d, proto %d no corresponding"
325 " listening socket\n",
326 dst_fin->to.s.sa_family, dst_fin->proto);
327 goto error;
328 }
329 }
330
331 /* Version && proto && length */
332 hdr.hp_l = sizeof(struct hep_hdr);
333 hdr.hp_v = hep_version;
334 hdr.hp_p = proto;
335
336 /* AND the last */
337 if(from_su.s.sa_family == AF_INET) {
338 /* prepare the hep headers */
339
340 hdr.hp_f = AF_INET;
341 hdr.hp_sport = htons(from_su.sin.sin_port);
342 hdr.hp_dport = htons(to_su.sin.sin_port);
343
344 hep_ipheader.hp_src = from_su.sin.sin_addr;
345 hep_ipheader.hp_dst = to_su.sin.sin_addr;
346
347 len = sizeof(struct hep_iphdr);
348 } else if(from_su.s.sa_family == AF_INET6) {
349 /* prepare the hep6 headers */
350
351 hdr.hp_f = AF_INET6;
352
353 hdr.hp_sport = htons(from_su.sin6.sin6_port);
354 hdr.hp_dport = htons(to_su.sin6.sin6_port);
355
356 hep_ip6header.hp6_src = from_su.sin6.sin6_addr;
357 hep_ip6header.hp6_dst = to_su.sin6.sin6_addr;
358
359 len = sizeof(struct hep_ip6hdr);
360 } else {
361 LM_ERR("Unsupported protocol family\n");
362 goto error;
363 ;
364 }
365
366 hdr.hp_l += len;
367 if(hep_version == 2) {
368 len += sizeof(struct hep_timehdr);
369 }
370 len += sizeof(struct hep_hdr) + body->len;
371 buffer = (void *)pkg_malloc(len + 1);
372 if(buffer == 0) {
373 LM_ERR("out of memory\n");
374 goto error;
375 }
376
377 /* Copy job */
378 memset(buffer, '\0', len + 1);
379
380 /* copy hep_hdr */
381 memcpy((void *)buffer, &hdr, sizeof(struct hep_hdr));
382 buflen = sizeof(struct hep_hdr);
383
384 /* hep_ip_hdr */
385 if(from_su.s.sa_family == AF_INET) {
386 memcpy((void *)buffer + buflen, &hep_ipheader,
387 sizeof(struct hep_iphdr));
388 buflen += sizeof(struct hep_iphdr);
389 } else {
390 memcpy((void *)buffer + buflen, &hep_ip6header,
391 sizeof(struct hep_ip6hdr));
392 buflen += sizeof(struct hep_ip6hdr);
393 }
394
395 if(hep_version == 2) {
396
397 hep_time.tv_sec = to_le(tvb.tv_sec);
398 hep_time.tv_usec = to_le(tvb.tv_usec);
399 hep_time.captid = hep_capture_id;
400
401 memcpy((void *)buffer + buflen, &hep_time, sizeof(struct hep_timehdr));
402 buflen += sizeof(struct hep_timehdr);
403 }
404
405 /* PAYLOAD */
406 memcpy((void *)(buffer + buflen), (void *)body->s, body->len);
407 buflen += body->len;
408
409 if(msg_send_buffer(dst_fin, buffer, buflen, 1) < 0) {
410 LM_ERR("cannot send hep duplicate message\n");
411 goto error;
412 }
413
414 if(p) {
415 free_proxy(p); /* frees only p content, not p itself */
416 pkg_free(p);
417 }
418 pkg_free(buffer);
419 return 0;
420 error:
421 if(p) {
422 free_proxy(p); /* frees only p content, not p itself */
423 pkg_free(p);
424 }
425 if(buffer)
426 pkg_free(buffer);
427 return -1;
428 }
429
430 /*!
431 * \brief Convert a STR [proto:]ip[:port] into socket address.
432 * [proto:]ip[:port]
433 * \param pipport (udp:127.0.0.1:5060 or tcp:2001:0DB8:AC10:FE01:5060)
434 * \param tmp_su target structure
435 * \param proto uint protocol type
436 * \return success / unsuccess
437 */
pipport2su(char * pipport,union sockaddr_union * tmp_su,unsigned int * proto)438 int pipport2su(char *pipport, union sockaddr_union *tmp_su, unsigned int *proto)
439 {
440 unsigned int port_no, cutlen = 4;
441 struct ip_addr *ip;
442 char *p, *host_s;
443 str port_str, host_uri;
444 unsigned len = 0;
445 char tmp_piport[256];
446
447 /*parse protocol */
448 if(strncmp(pipport, "udp:", 4) == 0)
449 *proto = IPPROTO_UDP;
450 else if(strncmp(pipport, "tcp:", 4) == 0)
451 *proto = IPPROTO_TCP;
452 else if(strncmp(pipport, "tls:", 4) == 0)
453 *proto = IPPROTO_IDP; /* fake proto type */
454 else if(strncmp(pipport, "ws:", 3) == 0)
455 cutlen = 3, *proto = IPPROTO_IDP; /* fake proto type */
456 else if(strncmp(pipport, "wss:", 4) == 0)
457 *proto = IPPROTO_IDP; /* fake proto type */
458 #ifdef USE_SCTP
459 else if(strncmp(pipport, "sctp:", 5) == 0)
460 cutlen = 5, *proto = IPPROTO_SCTP;
461 #endif
462 else if(strncmp(pipport, "any:", 4) == 0)
463 *proto = IPPROTO_UDP;
464 else {
465 LM_ERR("bad protocol %s\n", pipport);
466 return -1;
467 }
468
469 if((len = strlen(pipport)) >= 256) {
470 LM_ERR("too big pipport\n");
471 goto error;
472 }
473
474 /* our tmp string */
475 strncpy(tmp_piport, pipport, len + 1);
476
477 len = 0;
478
479 /*separate proto and host */
480 p = tmp_piport + cutlen;
481 if((*(p)) == '\0') {
482 LM_ERR("malformed ip address\n");
483 goto error;
484 }
485 host_s = p;
486
487 if((p = strrchr(p + 1, ':')) == 0) {
488 LM_DBG("no port specified\n");
489 port_no = 0;
490 } else {
491 /*the address contains a port number*/
492 *p = '\0';
493 p++;
494 port_str.s = p;
495 port_str.len = strlen(p);
496 LM_DBG("the port string is %s\n", p);
497 if(str2int(&port_str, &port_no) != 0) {
498 LM_ERR("there is not a valid number port\n");
499 goto error;
500 }
501 *p = '\0';
502 }
503
504 /* now IPv6 address has no brakets. It should be fixed! */
505 if(host_s[0] == '[') {
506 len = strlen(host_s + 1) - 1;
507 if(host_s[len + 1] != ']') {
508 LM_ERR("bracket not closed\n");
509 goto error;
510 }
511 memmove(host_s, host_s + 1, len);
512 host_s[len] = '\0';
513 }
514
515 host_uri.s = host_s;
516 host_uri.len = strlen(host_s);
517
518 /* check if it's an ip address */
519 if(((ip = str2ip(&host_uri)) != 0) || ((ip = str2ip6(&host_uri)) != 0)) {
520 ip_addr2su(tmp_su, ip, ntohs(port_no));
521 return 0;
522 }
523
524 error:
525 return -1;
526 }
527
528 /**
529 *
530 */
hlog(struct sip_msg * msg,str * correlationid,str * message)531 int hlog(struct sip_msg *msg, str *correlationid, str *message)
532 {
533 char *buf;
534 size_t len;
535 struct timeval tvb;
536 struct timezone tz;
537 struct dest_info dst;
538 struct proxy_l *p = NULL;
539
540 if(!correlationid) {
541 if(msg->callid == NULL && ((parse_headers(msg, HDR_CALLID_F, 0) == -1)
542 || (msg->callid == NULL))) {
543 LM_ERR("cannot parse Call-Id header\n");
544 return -1;
545 }
546 correlationid = &(msg->callid->body);
547 }
548
549 len = sizeof(hep_ctrl_t)
550 + sizeof(hep_chunk_uint8_t) /* ip protocol family */
551 + sizeof(hep_chunk_uint8_t) /* ip protocol id */
552 + sizeof(hep_chunk_t) + 16 /* src address (enough space for ipv6) */
553 + sizeof(hep_chunk_t) + 16 /* dst address (ditto) */
554 + sizeof(hep_chunk_uint16_t) /* src port */
555 + sizeof(hep_chunk_uint16_t) /* dst port */
556 + sizeof(hep_chunk_uint32_t) /* timestamp */
557 + sizeof(hep_chunk_uint32_t) /* timestamp micro */
558 + sizeof(hep_chunk_uint32_t) /* capture id */
559 + sizeof(hep_chunk_uint8_t) /* protocol type */
560 + sizeof(hep_chunk_t) + correlationid->len + sizeof(hep_chunk_t)
561 + message->len;
562
563 if(hep_auth_key_str.len) {
564 len += sizeof(hep_chunk_t) + hep_auth_key_str.len;
565 }
566
567 buf = pkg_malloc(len);
568
569 if(!buf) {
570 LM_ERR("no more pkg memory\n");
571 return -1;
572 }
573
574 gettimeofday(&tvb, &tz);
575
576 init_dest_info(&dst);
577 dst.proto = trace_dup_uri->proto;
578 p = mk_proxy(&trace_dup_uri->host, trace_dup_uri->port_no, dst.proto);
579 if(p == 0) {
580 LM_ERR("bad host name in uri\n");
581 goto error;
582 }
583
584 hostent2su(&dst.to, &p->host, p->addr_idx, (p->port) ? p->port : SIP_PORT);
585 LM_DBG("setting up the socket_info\n");
586
587 free_proxy(p); /* frees only p content, not p itself */
588 pkg_free(p);
589
590 if(trace_send_sock_name_str.s) {
591 dst.send_sock = trace_send_sock_info;
592 } else if(trace_send_sock_str.s) {
593 LM_DBG("send sock activated - find the sock info\n");
594 if(trace_send_sock_info) {
595 dst.send_sock = trace_send_sock_info;
596 } else {
597 dst.send_sock = grep_sock_info(&trace_send_sock_uri->host,
598 trace_send_sock_uri->port_no,
599 trace_send_sock_uri->proto);
600 }
601 if(!dst.send_sock) {
602 LM_WARN("local socket not found for: [%.*s]\n",
603 trace_send_sock_str.len, trace_send_sock_str.s);
604 } else {
605 LM_DBG("using local send socket: [%.*s] [%.*s]\n",
606 dst.send_sock->name.len, dst.send_sock->name.s,
607 dst.send_sock->address_str.len, dst.send_sock->address_str.s);
608 }
609 }
610
611 if(dst.send_sock == 0) {
612 dst.send_sock = get_send_socket(0, &dst.to, dst.proto);
613 if(dst.send_sock == 0) {
614 LM_ERR("can't forward to af %d, proto %d no corresponding"
615 " listening socket\n",
616 dst.to.s.sa_family, dst.proto);
617 goto error;
618 }
619 }
620
621 HEP3_PACK_INIT(buf);
622 HEP3_PACK_CHUNK_UINT8(0, 0x0001, dst.send_sock->address.af);
623 HEP3_PACK_CHUNK_UINT8(0, 0x0002, 0x11);
624 if(dst.send_sock->address.af == AF_INET) {
625 HEP3_PACK_CHUNK_UINT32_NBO(
626 0, 0x0003, dst.send_sock->address.u.addr32[0]);
627 HEP3_PACK_CHUNK_UINT32_NBO(0, 0x0004, dst.to.sin.sin_addr.s_addr);
628 HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0008, dst.to.sin.sin_port);
629 } else if(dst.send_sock->address.af == AF_INET6) {
630 HEP3_PACK_CHUNK_IP6(0, 0x0005, dst.send_sock->address.u.addr);
631 HEP3_PACK_CHUNK_IP6(0, 0x0006, &dst.to.sin6.sin6_addr);
632 HEP3_PACK_CHUNK_UINT16_NBO(0, 0x0008, dst.to.sin6.sin6_port);
633 } else {
634 LM_ERR("unknown address family [%u]\n", dst.send_sock->address.af);
635 goto error;
636 }
637 HEP3_PACK_CHUNK_UINT16(0, 0x0007, dst.send_sock->port_no);
638
639 HEP3_PACK_CHUNK_UINT32(0, 0x0009, tvb.tv_sec);
640 HEP3_PACK_CHUNK_UINT32(0, 0x000a, tvb.tv_usec);
641 HEP3_PACK_CHUNK_UINT8(0, 0x000b, 0x64); /* protocol type: log */
642 HEP3_PACK_CHUNK_UINT32(0, 0x000c, hep_capture_id);
643 HEP3_PACK_CHUNK_DATA(0, 0x0011, correlationid->s, correlationid->len);
644 if(hep_auth_key_str.s && hep_auth_key_str.len > 0) {
645 HEP3_PACK_CHUNK_DATA(0, 0x000e, hep_auth_key_str.s, hep_auth_key_str.len);
646 }
647 HEP3_PACK_CHUNK_DATA(0, 0x000f, message->s, message->len);
648 HEP3_PACK_FINALIZE(buf, &len);
649
650 if(msg_send_buffer(&dst, buf, len, 1) < 0) {
651 LM_ERR("cannot send hep log\n");
652 goto error;
653 }
654
655 pkg_free(buf);
656 return 1;
657
658 error:
659 pkg_free(buf);
660 return -1;
661 }
662