modules: readme files regenerated - uac ... [skip ci]
[sip-router] / src / modules / sipcapture / hep.c
1 /*
2  * hep related functions
3  *
4  * Copyright (C) 2011-2014 Alexandr Dubovikov <alexandr.dubovikov@gmail.com>
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 "../../core/sr_module.h"
25 #include "../../core/dprint.h"
26 #include "../../core/events.h"
27 #include "../../core/ut.h"
28 #include "../../core/ip_addr.h"
29 #include "../../core/mem/mem.h"
30 #include "../../core/mem/shm_mem.h"
31 #include "../../lib/srdb1/db.h"
32 #include "../../core/receive.h"
33
34 #include "hep.h"
35 #include "sipcapture.h"
36
37
38 static int count = 0;
39
40 extern struct hep_timeinfo *heptime;
41
42 /* HEPv2 HEPv3 */
43 int hepv2_received(char *buf, unsigned int len, struct receive_info *ri);
44 int hepv3_received(char *buf, unsigned int len, struct receive_info *ri);
45 int parsing_hepv3_message(char *buf, unsigned int len);
46
47 /**
48  * HEP message
49  */
50 /* int hep_msg_received(char * buf, unsigned int len, struct receive_info * ri) */
51 int hep_msg_received(sr_event_param_t *evp)
52 {
53         void **srevp;
54         char *buf;
55         unsigned *len;
56         struct receive_info *ri;
57
58         if(!hep_capture_on) {
59                 LOG(L_ERR, "sipcapture:hep_msg_received HEP is not enabled\n");
60                 return -1;
61         }
62
63         srevp = (void **)evp->data;
64
65         buf = (char *)srevp[0];
66         len = (unsigned *)srevp[1];
67         ri = (struct receive_info *)srevp[2];
68
69         correlation_id = NULL;
70         authkey = NULL;
71
72         count++;
73         struct hep_hdr *heph;
74         /* hep_hdr */
75         heph = (struct hep_hdr *)buf;
76
77         /* Check version */
78         if(heph->hp_v == 1 || heph->hp_v == 2) {
79
80                 return hepv2_received(buf, *len, ri);
81         } else if(!memcmp(buf, "\x48\x45\x50\x33", 4)) {
82
83                 return hepv3_received(buf, *len, ri);
84         } else {
85
86                 LOG(L_ERR, "ERROR: sipcapture:hep_msg_received: not supported version "
87                                    "or bad length: v:[%d] l:[%d]\n",
88                                 heph->hp_v, heph->hp_l);
89                 return -1;
90         }
91 }
92
93 int hepv2_received(char *buf, unsigned int len, struct receive_info *ri)
94 {
95
96         int hl;
97         struct hep_hdr *heph;
98         struct ip_addr dst_ip, src_ip;
99         char *hep_payload, *end, *hep_ip;
100         struct hep_iphdr *hepiph = NULL;
101
102         struct hep_timehdr *heptime_tmp = NULL;
103         memset(heptime, 0, sizeof(struct hep_timeinfo));
104
105         struct hep_ip6hdr *hepip6h = NULL;
106
107         correlation_id = NULL;
108         authkey = NULL;
109
110         hep_offset = 0;
111
112         hl = hep_offset = sizeof(struct hep_hdr);
113         end = buf + len;
114         if(unlikely(len < hep_offset)) {
115                 LOG(L_ERR, "ERROR: sipcapture:hep_msg_received len less than offset "
116                                    "[%i] vs [%i]\n",
117                                 len, hep_offset);
118                 return -1;
119         }
120
121         /* hep_hdr */
122         heph = (struct hep_hdr *)buf;
123
124         switch(heph->hp_f) {
125                 case AF_INET:
126                         hl += sizeof(struct hep_iphdr);
127                         break;
128                 case AF_INET6:
129                         hl += sizeof(struct hep_ip6hdr);
130                         break;
131                 default:
132                         LOG(L_ERR, "ERROR: sipcapture:hep_msg_received:  unsupported "
133                                            "family [%d]\n",
134                                         heph->hp_f);
135                         return -1;
136         }
137
138         /* PROTO */
139         if(heph->hp_p == IPPROTO_UDP)
140                 ri->proto = PROTO_UDP;
141         else if(heph->hp_p == IPPROTO_TCP)
142                 ri->proto = PROTO_TCP;
143         else if(heph->hp_p == IPPROTO_IDP)
144                 ri->proto = PROTO_TLS; /* fake protocol */
145 #ifdef USE_SCTP
146         else if(heph->hp_p == IPPROTO_SCTP)
147                 ri->proto = PROTO_SCTP;
148 #endif
149         else {
150                 LOG(L_ERR,
151                                 "ERROR: sipcapture:hep_msg_received: unknown protocol [%d]\n",
152                                 heph->hp_p);
153                 ri->proto = PROTO_NONE;
154         }
155
156         hep_ip = buf + sizeof(struct hep_hdr);
157
158         if(unlikely(hep_ip > end)) {
159                 LOG(L_ERR, "hep_ip is over buf+len\n");
160                 return -1;
161         }
162
163         switch(heph->hp_f) {
164                 case AF_INET:
165                         hep_offset += sizeof(struct hep_iphdr);
166                         hepiph = (struct hep_iphdr *)hep_ip;
167                         break;
168
169                 case AF_INET6:
170                         hep_offset += sizeof(struct hep_ip6hdr);
171                         hepip6h = (struct hep_ip6hdr *)hep_ip;
172                         break;
173         }
174
175         /* VOIP payload */
176         hep_payload = buf + hep_offset;
177
178         if(unlikely(hep_payload > end)) {
179                 LOG(L_ERR, "hep_payload is over buf+len\n");
180                 return -1;
181         }
182
183         /* timming */
184         if(heph->hp_v == 2) {
185                 hep_offset += sizeof(struct hep_timehdr);
186                 heptime_tmp = (struct hep_timehdr *)hep_payload;
187
188                 heptime->tv_sec = to_le(heptime_tmp->tv_sec);
189                 heptime->tv_usec = to_le(heptime_tmp->tv_usec);
190                 heptime->captid = heptime_tmp->captid;
191         }
192
193
194         /* fill ip from the packet to dst_ip && to */
195         switch(heph->hp_f) {
196
197                 case AF_INET:
198                         dst_ip.af = src_ip.af = AF_INET;
199                         dst_ip.len = src_ip.len = 4;
200                         memcpy(&dst_ip.u.addr, &hepiph->hp_dst, 4);
201                         memcpy(&src_ip.u.addr, &hepiph->hp_src, 4);
202                         break;
203
204                 case AF_INET6:
205                         dst_ip.af = src_ip.af = AF_INET6;
206                         dst_ip.len = src_ip.len = 16;
207                         memcpy(&dst_ip.u.addr, &hepip6h->hp6_dst, 16);
208                         memcpy(&src_ip.u.addr, &hepip6h->hp6_src, 16);
209                         break;
210         }
211
212         ri->src_ip = src_ip;
213         ri->src_port = ntohs(heph->hp_sport);
214
215         ri->dst_ip = dst_ip;
216         ri->dst_port = ntohs(heph->hp_dport);
217
218         /* cut off the offset */
219         /* 
220          *  len -= offset;
221          *  p = buf + offset;
222          *  memmove(buf, p, BUF_SIZE+1); 
223         */
224
225         hep_payload = buf + hep_offset;
226
227         receive_msg(hep_payload, (unsigned int)(len - hep_offset), ri);
228
229         return -1;
230 }
231
232
233 /**
234  * HEP message
235  */
236 int hepv3_received(char *buf, unsigned int len, struct receive_info *ri)
237 {
238         if(!parsing_hepv3_message(buf, len)) {
239                 LM_ERR("couldn't parse hepv3 message\n");
240                 return -2;
241         }
242
243         return -1;
244 }
245
246 int parsing_hepv3_message(char *buf, unsigned int len)
247 {
248
249         union sockaddr_union from;
250         union sockaddr_union to;
251         struct receive_info ri;
252         char *tmp;
253         struct ip_addr dst_ip, src_ip;
254         struct socket_info *si = 0;
255         int tmp_len, i;
256         char *payload = NULL;
257         unsigned int payload_len = 0;
258         struct hep_chunk *chunk;
259         struct hep_generic_recv *hg;
260         int totelem = 0;
261         int chunk_vendor = 0, chunk_type = 0, chunk_length = 0;
262         int total_length = 0;
263
264
265         hg = (struct hep_generic_recv *)pkg_malloc(sizeof(struct hep_generic_recv));
266         if(hg == NULL) {
267                 LM_ERR("no more pkg memory left for hg\n");
268                 return -1;
269         }
270
271         memset(hg, 0, sizeof(struct hep_generic_recv));
272
273
274         memset(heptime, 0, sizeof(struct hep_timeinfo));
275
276
277         /* HEADER */
278         hg->header = (hep_ctrl_t *)(buf);
279
280         /*Packet size */
281         total_length = ntohs(hg->header->length);
282
283         ri.src_port = 0;
284         ri.dst_port = 0;
285         dst_ip.af = 0;
286         src_ip.af = 0;
287
288         payload = NULL;
289         correlation_id = NULL;
290         authkey = NULL;
291
292         i = sizeof(hep_ctrl_t);
293
294         while(i < total_length) {
295
296                 /*OUR TMP DATA */
297                 tmp = buf + i;
298
299                 chunk = (struct hep_chunk *)tmp;
300
301                 chunk_vendor = ntohs(chunk->vendor_id);
302                 chunk_type = ntohs(chunk->type_id);
303                 chunk_length = ntohs(chunk->length);
304
305
306                 /* if chunk_length */
307                 if(chunk_length == 0) {
308                         /* BAD LEN we drop this packet */
309                         goto error;
310                 }
311
312                 /* SKIP not general Chunks */
313                 if(chunk_vendor != 0) {
314                         i += chunk_length;
315                 } else {
316                         switch(chunk_type) {
317
318                                 case 0:
319                                         goto error;
320                                         break;
321
322                                 case 1:
323                                         hg->ip_family = (hep_chunk_uint8_t *)(tmp);
324                                         i += chunk_length;
325                                         totelem++;
326                                         break;
327                                 case 2:
328                                         hg->ip_proto = (hep_chunk_uint8_t *)(tmp);
329                                         i += chunk_length;
330                                         totelem++;
331                                         break;
332                                 case 3:
333                                         hg->hep_src_ip4 = (hep_chunk_ip4_t *)(tmp);
334                                         i += chunk_length;
335                                         src_ip.af = AF_INET;
336                                         src_ip.len = 4;
337                                         src_ip.u.addr32[0] = hg->hep_src_ip4->data.s_addr;
338                                         totelem++;
339                                         break;
340                                 case 4:
341                                         hg->hep_dst_ip4 = (hep_chunk_ip4_t *)(tmp);
342                                         i += chunk_length;
343                                         dst_ip.af = AF_INET;
344                                         dst_ip.len = 4;
345                                         dst_ip.u.addr32[0] = hg->hep_dst_ip4->data.s_addr;
346                                         totelem++;
347
348                                         break;
349                                 case 5:
350                                         hg->hep_src_ip6 = (hep_chunk_ip6_t *)(tmp);
351                                         i += chunk_length;
352                                         src_ip.af = AF_INET6;
353                                         src_ip.len = 16;
354                                         memcpy(src_ip.u.addr, &hg->hep_src_ip6->data, 16);
355                                         totelem++;
356                                         break;
357                                 case 6:
358                                         hg->hep_dst_ip6 = (hep_chunk_ip6_t *)(tmp);
359                                         i += chunk_length;
360                                         dst_ip.af = AF_INET6;
361                                         dst_ip.len = 16;
362                                         memcpy(dst_ip.u.addr, &hg->hep_dst_ip6->data, 16);
363                                         totelem++;
364                                         break;
365
366                                 case 7:
367                                         hg->src_port = (hep_chunk_uint16_t *)(tmp);
368                                         ri.src_port = ntohs(hg->src_port->data);
369                                         i += chunk_length;
370                                         totelem++;
371                                         break;
372
373                                 case 8:
374                                         hg->dst_port = (hep_chunk_uint16_t *)(tmp);
375                                         ri.dst_port = ntohs(hg->dst_port->data);
376                                         i += chunk_length;
377                                         totelem++;
378                                         break;
379                                 case 9:
380                                         hg->time_sec = (hep_chunk_uint32_t *)(tmp);
381                                         heptime->tv_sec = ntohl(hg->time_sec->data);
382                                         i += chunk_length;
383                                         totelem++;
384                                         break;
385
386                                 case 10:
387                                         hg->time_usec = (hep_chunk_uint32_t *)(tmp);
388                                         heptime->tv_usec = ntohl(hg->time_usec->data);
389                                         i += chunk_length;
390                                         totelem++;
391                                         break;
392
393                                 case 11:
394                                         hg->proto_t = (hep_chunk_uint8_t *)(tmp);
395                                         i += chunk_length;
396                                         totelem++;
397                                         break;
398
399                                 case 12:
400                                         hg->capt_id = (hep_chunk_uint32_t *)(tmp);
401                                         heptime->captid = ntohl(hg->capt_id->data);
402                                         i += chunk_length;
403                                         totelem++;
404                                         break;
405
406                                 case 13:
407                                         hg->keep_tm = (hep_chunk_uint16_t *)(tmp);
408                                         i += chunk_length;
409                                         break;
410
411                                 case 14:
412                                         authkey = (char *)tmp + sizeof(hep_chunk_t);
413                                         i += chunk_length;
414                                         break;
415
416                                 case 15:
417                                         hg->payload_chunk = (hep_chunk_t *)(tmp);
418                                         payload = (char *)tmp + sizeof(hep_chunk_t);
419                                         payload_len = chunk_length - sizeof(hep_chunk_t);
420                                         i += chunk_length;
421                                         totelem++;
422                                         break;
423                                 case 17:
424
425                                         correlation_id = (char *)tmp + sizeof(hep_chunk_t);
426                                         i += chunk_length;
427                                         break;
428
429
430                                 default:
431                                         i += chunk_length;
432                                         break;
433                         }
434                 }
435         }
436
437         /* CHECK how much elements */
438         if(totelem < 9) {
439                 LM_ERR("Not all elements [%d]\n", totelem);
440                 goto done;
441         }
442
443         if(dst_ip.af == 0 || src_ip.af == 0) {
444                 LM_ERR("NO IP's set\n");
445                 goto done;
446         }
447
448
449         ip_addr2su(&to, &dst_ip, ri.dst_port);
450         ip_addr2su(&from, &src_ip, ri.src_port);
451
452         ri.src_su = from;
453         su2ip_addr(&ri.src_ip, &from);
454         su2ip_addr(&ri.dst_ip, &to);
455
456         if(hg->ip_proto->data == IPPROTO_TCP)
457                 ri.proto = PROTO_TCP;
458         else if(hg->ip_proto->data == IPPROTO_UDP)
459                 ri.proto = PROTO_UDP;
460
461         /* a little bit memory */
462         si = (struct socket_info *)pkg_malloc(sizeof(struct socket_info));
463         if(si == 0) {
464                 LOG(L_ERR, "ERROR: new_sock_info: memory allocation error\n");
465                 goto error;
466         }
467
468         memset(si, 0, sizeof(struct socket_info));
469         si->address = ri.dst_ip;
470         si->socket = -1;
471
472         /* set port & proto */
473         si->port_no = ri.dst_port;
474
475         if(hg->ip_proto->data == IPPROTO_TCP)
476                 si->proto = PROTO_TCP;
477         else if(hg->ip_proto->data == IPPROTO_UDP)
478                 si->proto = PROTO_UDP;
479
480         si->flags = 0;
481         si->addr_info_lst = 0;
482
483         si->address_str.s = ip_addr2a(&si->address);
484
485         si->address_str.len = strlen(si->address_str.s);
486
487         si->port_no_str.s = int2str(si->port_no, &tmp_len);
488         si->port_no_str.len = tmp_len;
489         si->address_str.len = strlen(si->address_str.s);
490
491         si->name.len = si->address_str.len;
492         si->name.s = si->address_str.s;
493         ri.bind_address = si;
494
495         if(payload != NULL) {
496                 /* and now receive message */
497                 if(hg->proto_t->data == 5)
498                         receive_logging_json_msg(payload, payload_len, hg, "rtcp_capture");
499                 else if(hg->proto_t->data == 32)
500                         receive_logging_json_msg(
501                                         payload, payload_len, hg, "report_capture");
502                 else if(hg->proto_t->data == 99)
503                         receive_logging_json_msg(
504                                         payload, payload_len, hg, "report_capture");
505                 else if(hg->proto_t->data == 100)
506                         receive_logging_json_msg(payload, payload_len, hg, "logs_capture");
507                 else
508                         receive_msg(payload, payload_len, &ri);
509         }
510
511 done:
512         if(si)
513                 pkg_free(si);
514         if(hg)
515                 pkg_free(hg);
516
517         return 1;
518
519 error:
520
521         if(si)
522                 pkg_free(si);
523         if(hg)
524                 pkg_free(hg);
525
526         return -1;
527 }
528
529
530 int hepv3_message_parse(char *buf, unsigned int len, sip_msg_t *msg)
531 {
532
533         union sockaddr_union from;
534         union sockaddr_union to;
535         char *tmp;
536         struct ip_addr dst_ip, src_ip;
537         struct socket_info *si = 0;
538         int i;
539         char *payload = NULL;
540         unsigned int payload_len = 0;
541         struct hep_chunk *chunk;
542         struct hep_generic_recv *hg;
543         int totelem = 0;
544         int chunk_vendor = 0, chunk_type = 0, chunk_length = 0;
545         int total_length = 0;
546         int ret = 0;
547
548         hg = (struct hep_generic_recv *)pkg_malloc(sizeof(struct hep_generic_recv));
549         if(hg == NULL) {
550                 LM_ERR("no more pkg memory left for hg\n");
551                 return -1;
552         }
553
554         memset(hg, 0, sizeof(struct hep_generic_recv));
555
556
557         memset(heptime, 0, sizeof(struct hep_timeinfo));
558
559
560         /* HEADER */
561         hg->header = (hep_ctrl_t *)(buf);
562
563         /*Packet size */
564         total_length = ntohs(hg->header->length);
565
566         dst_ip.af = 0;
567         src_ip.af = 0;
568
569         payload = NULL;
570         correlation_id = NULL;
571         authkey = NULL;
572
573         i = sizeof(hep_ctrl_t);
574
575         while(i < total_length) {
576
577                 /*OUR TMP DATA */
578                 tmp = buf + i;
579
580                 chunk = (struct hep_chunk *)tmp;
581
582                 chunk_vendor = ntohs(chunk->vendor_id);
583                 chunk_type = ntohs(chunk->type_id);
584                 chunk_length = ntohs(chunk->length);
585
586                 /* if chunk_length */
587                 if(chunk_length == 0) {
588                         /* BAD LEN we drop this packet */
589                         goto error;
590                 }
591
592                 /* SKIP not general Chunks */
593                 if(chunk_vendor != 0) {
594                         i += chunk_length;
595                 } else {
596                         switch(chunk_type) {
597
598                                 case 0:
599                                         goto error;
600                                         break;
601
602                                 case 1:
603                                         hg->ip_family = (hep_chunk_uint8_t *)(tmp);
604                                         i += chunk_length;
605                                         totelem++;
606                                         break;
607                                 case 2:
608                                         hg->ip_proto = (hep_chunk_uint8_t *)(tmp);
609                                         i += chunk_length;
610                                         totelem++;
611                                         break;
612                                 case 3:
613                                         hg->hep_src_ip4 = (hep_chunk_ip4_t *)(tmp);
614                                         i += chunk_length;
615                                         src_ip.af = AF_INET;
616                                         src_ip.len = 4;
617                                         src_ip.u.addr32[0] = hg->hep_src_ip4->data.s_addr;
618                                         totelem++;
619                                         break;
620                                 case 4:
621                                         hg->hep_dst_ip4 = (hep_chunk_ip4_t *)(tmp);
622                                         i += chunk_length;
623                                         dst_ip.af = AF_INET;
624                                         dst_ip.len = 4;
625                                         dst_ip.u.addr32[0] = hg->hep_dst_ip4->data.s_addr;
626                                         totelem++;
627
628                                         break;
629                                 case 5:
630                                         hg->hep_src_ip6 = (hep_chunk_ip6_t *)(tmp);
631                                         i += chunk_length;
632                                         src_ip.af = AF_INET6;
633                                         src_ip.len = 16;
634                                         memcpy(src_ip.u.addr, &hg->hep_src_ip6->data, 16);
635                                         totelem++;
636                                         break;
637                                 case 6:
638                                         hg->hep_dst_ip6 = (hep_chunk_ip6_t *)(tmp);
639                                         i += chunk_length;
640                                         dst_ip.af = AF_INET6;
641                                         dst_ip.len = 16;
642                                         memcpy(dst_ip.u.addr, &hg->hep_dst_ip6->data, 16);
643                                         totelem++;
644                                         break;
645
646                                 case 7:
647                                         hg->src_port = (hep_chunk_uint16_t *)(tmp);
648                                         msg->rcv.src_port = ntohs(hg->src_port->data);
649                                         i += chunk_length;
650                                         totelem++;
651                                         break;
652
653                                 case 8:
654                                         hg->dst_port = (hep_chunk_uint16_t *)(tmp);
655                                         msg->rcv.dst_port = ntohs(hg->dst_port->data);
656                                         i += chunk_length;
657                                         totelem++;
658                                         break;
659                                 case 9:
660                                         hg->time_sec = (hep_chunk_uint32_t *)(tmp);
661                                         heptime->tv_sec = ntohl(hg->time_sec->data);
662                                         i += chunk_length;
663                                         totelem++;
664                                         break;
665
666                                 case 10:
667                                         hg->time_usec = (hep_chunk_uint32_t *)(tmp);
668                                         heptime->tv_usec = ntohl(hg->time_usec->data);
669                                         i += chunk_length;
670                                         totelem++;
671                                         break;
672
673                                 case 11:
674                                         hg->proto_t = (hep_chunk_uint8_t *)(tmp);
675                                         i += chunk_length;
676                                         totelem++;
677                                         break;
678
679                                 case 12:
680                                         hg->capt_id = (hep_chunk_uint32_t *)(tmp);
681                                         i += chunk_length;
682                                         heptime->captid = ntohl(hg->capt_id->data);
683                                         totelem++;
684                                         break;
685
686                                 case 13:
687                                         hg->keep_tm = (hep_chunk_uint16_t *)(tmp);
688                                         i += chunk_length;
689                                         break;
690
691                                 case 14:
692                                         authkey = (char *)tmp + sizeof(hep_chunk_t);
693                                         i += chunk_length;
694                                         break;
695
696                                 case 15:
697                                         hg->payload_chunk = (hep_chunk_t *)(tmp);
698                                         payload = (char *)tmp + sizeof(hep_chunk_t);
699                                         payload_len = chunk_length - sizeof(hep_chunk_t);
700                                         i += chunk_length;
701                                         totelem++;
702                                         break;
703                                 case 17:
704
705                                         correlation_id = (char *)tmp + sizeof(hep_chunk_t);
706                                         i += chunk_length;
707                                         break;
708
709
710                                 default:
711                                         i += chunk_length;
712                                         break;
713                         }
714                 }
715         }
716
717         /* CHECK how much elements */
718         if(totelem < 9) {
719                 LM_ERR("Not all elements [%d]\n", totelem);
720                 goto done;
721         }
722
723         if(dst_ip.af == 0 || src_ip.af == 0) {
724                 LM_ERR("NO IP's set\n");
725                 goto done;
726         }
727
728
729         ip_addr2su(&to, &dst_ip, msg->rcv.dst_port);
730         ip_addr2su(&from, &src_ip, msg->rcv.src_port);
731
732         msg->rcv.src_su = from;
733         su2ip_addr(&msg->rcv.src_ip, &from);
734         su2ip_addr(&msg->rcv.dst_ip, &to);
735
736         if(hg->ip_proto->data == IPPROTO_TCP)
737                 msg->rcv.proto = PROTO_TCP;
738         else if(hg->ip_proto->data == IPPROTO_UDP)
739                 msg->rcv.proto = PROTO_UDP;
740
741         if(payload != NULL)
742         {
743                 ret = len - payload_len;
744                 msg->buf = payload;
745                 msg->len = payload_len;
746         }
747
748
749 done:
750
751         //if(si) pkg_free(si);
752         if(hg)
753                 pkg_free(hg);
754
755         return ret;
756
757 error:
758
759         if(si)
760                 pkg_free(si);
761         if(hg)
762                 pkg_free(hg);
763
764         return -1;
765 }
766
767 int hepv2_message_parse(char *buf, unsigned int len, sip_msg_t *msg)
768 {
769
770         int hl;
771         struct hep_hdr *heph;
772         struct ip_addr dst_ip, src_ip;
773         char *hep_payload, *end, *hep_ip;
774         struct hep_iphdr *hepiph = NULL;
775
776         struct hep_timehdr *heptime_tmp = NULL;
777         memset(heptime, 0, sizeof(struct hep_timeinfo));
778
779         struct hep_ip6hdr *hepip6h = NULL;
780
781         correlation_id = NULL;
782         authkey = NULL;
783
784         hep_offset = 0;
785
786         hl = hep_offset = sizeof(struct hep_hdr);
787         end = buf + len;
788         if(unlikely(len < hep_offset)) {
789                 LOG(L_ERR, "ERROR: sipcapture:hep_msg_received len less than offset "
790                                    "[%i] vs [%i]\n",
791                                 len, hep_offset);
792                 return -1;
793         }
794
795         /* hep_hdr */
796         heph = (struct hep_hdr *)buf;
797
798         switch(heph->hp_f) {
799                 case AF_INET:
800                         hl += sizeof(struct hep_iphdr);
801                         break;
802                 case AF_INET6:
803                         hl += sizeof(struct hep_ip6hdr);
804                         break;
805                 default:
806                         LOG(L_ERR, "ERROR: sipcapture:hep_msg_received:  unsupported "
807                                            "family [%d]\n",
808                                         heph->hp_f);
809                         return -1;
810         }
811
812         /* PROTO */
813         if(heph->hp_p == IPPROTO_UDP)
814                 msg->rcv.proto = PROTO_UDP;
815         else if(heph->hp_p == IPPROTO_TCP)
816                 msg->rcv.proto = PROTO_TCP;
817         else if(heph->hp_p == IPPROTO_IDP)
818                 msg->rcv.proto = PROTO_TLS; /* fake protocol */
819 #ifdef USE_SCTP
820         else if(heph->hp_p == IPPROTO_SCTP)
821                 msg->rcv.proto = PROTO_SCTP;
822 #endif
823         else {
824                 LOG(L_ERR,
825                                 "ERROR: sipcapture:hep_msg_received: unknown protocol [%d]\n",
826                                 heph->hp_p);
827                 msg->rcv.proto = PROTO_NONE;
828         }
829
830         hep_ip = buf + sizeof(struct hep_hdr);
831
832         if(unlikely(hep_ip > end)) {
833                 LOG(L_ERR, "hep_ip is over buf+len\n");
834                 return -1;
835         }
836
837         switch(heph->hp_f) {
838                 case AF_INET:
839                         hep_offset += sizeof(struct hep_iphdr);
840                         hepiph = (struct hep_iphdr *)hep_ip;
841                         break;
842
843                 case AF_INET6:
844                         hep_offset += sizeof(struct hep_ip6hdr);
845                         hepip6h = (struct hep_ip6hdr *)hep_ip;
846                         break;
847         }
848
849         /* VOIP payload */
850         hep_payload = buf + hep_offset;
851
852         if(unlikely(hep_payload > end)) {
853                 LOG(L_ERR, "hep_payload is over buf+len\n");
854                 return -1;
855         }
856
857         /* timming */
858         if(heph->hp_v == 2) {
859                 hep_offset += sizeof(struct hep_timehdr);
860                 heptime_tmp = (struct hep_timehdr *)hep_payload;
861
862                 heptime->tv_sec = to_le(heptime_tmp->tv_sec);
863                 heptime->tv_usec = to_le(heptime_tmp->tv_usec);
864                 heptime->captid = heptime_tmp->captid;
865         }
866
867
868         /* fill ip from the packet to dst_ip && to */
869         switch(heph->hp_f) {
870
871                 case AF_INET:
872                         dst_ip.af = src_ip.af = AF_INET;
873                         dst_ip.len = src_ip.len = 4;
874                         memcpy(&dst_ip.u.addr, &hepiph->hp_dst, 4);
875                         memcpy(&src_ip.u.addr, &hepiph->hp_src, 4);
876                         break;
877
878                 case AF_INET6:
879                         dst_ip.af = src_ip.af = AF_INET6;
880                         dst_ip.len = src_ip.len = 16;
881                         memcpy(&dst_ip.u.addr, &hepip6h->hp6_dst, 16);
882                         memcpy(&src_ip.u.addr, &hepip6h->hp6_src, 16);
883                         break;
884         }
885
886         msg->rcv.src_ip = src_ip;
887         msg->rcv.src_port = ntohs(heph->hp_sport);
888
889         msg->rcv.dst_ip = dst_ip;
890         msg->rcv.dst_port = ntohs(heph->hp_dport);
891
892         return hep_offset;
893 }
894
895
896 int hepv3_get_chunk(struct sip_msg *msg, char *buf, unsigned int len,
897                 int req_chunk, pv_param_t *param, pv_value_t *res)
898 {
899
900         str tmpstr;
901         char *tmp;
902         int i;
903         struct hep_chunk *chunk;
904         struct hep_generic_recv *hg;
905         int chunk_vendor = 0, chunk_type = 0, chunk_length = 0;
906         int total_length = 0;
907         int ret = 0;
908         static char ipstr[INET6_ADDRSTRLEN];
909
910         if(memcmp(buf, "\x48\x45\x50\x33", 4)
911                         && !memcmp(buf, "\x45\x45\x50\x31", 4)) {
912
913                 LM_ERR("not hep 3 protocol");
914                 pv_get_uintval(msg, param, res, -1);
915                 return -1;
916         }
917
918         hg = (struct hep_generic_recv *)pkg_malloc(sizeof(struct hep_generic_recv));
919         if(hg == NULL) {
920                 LM_ERR("no more pkg memory left for hg\n");
921                 return -1;
922         }
923
924         memset(hg, 0, sizeof(struct hep_generic_recv));
925
926         /* HEADER */
927         hg->header = (hep_ctrl_t *)(buf);
928
929         /*Packet size */
930         total_length = ntohs(hg->header->length);
931
932         i = sizeof(hep_ctrl_t);
933
934         while(i < total_length) {
935
936                 /*OUR TMP DATA */
937                 tmp = buf + i;
938
939                 chunk = (struct hep_chunk *)tmp;
940
941                 chunk_vendor = ntohs(chunk->vendor_id);
942                 chunk_type = ntohs(chunk->type_id);
943                 chunk_length = ntohs(chunk->length);
944
945                 /* if chunk_length */
946                 if(chunk_length == 0) {
947                         /* BAD LEN we drop this packet */
948                         goto error;
949                 }
950
951                 /* SKIP not general Chunks */
952                 if(chunk_vendor != 0) {
953                         i += chunk_length;
954                 } else {
955                         if(chunk_type != req_chunk) {
956                                 i += chunk_length;
957                                 continue;
958                         }
959
960                         switch(chunk_type) {
961
962                                 case 0:
963                                         goto error;
964                                         break;
965
966                                 case 1:
967                                         hg->ip_family = (hep_chunk_uint8_t *)(tmp);
968                                         ret = pv_get_uintval(msg, param, res, hg->ip_family->data);
969                                         goto done;
970                                 case 2:
971                                         hg->ip_proto = (hep_chunk_uint8_t *)(tmp);
972                                         ret = pv_get_uintval(msg, param, res, hg->ip_proto->data);
973                                         goto done;
974                                 case 3:
975                                         hg->hep_src_ip4 = (hep_chunk_ip4_t *)(tmp);
976                                         inet_ntop(AF_INET, &(hg->hep_src_ip4->data), ipstr,
977                                                         INET_ADDRSTRLEN);
978                                         tmpstr.s = ipstr;
979                                         tmpstr.len = strlen(ipstr);
980                                         ret = pv_get_strval(msg, param, res, &tmpstr);
981                                         goto done;
982                                 case 4:
983                                         hg->hep_dst_ip4 = (hep_chunk_ip4_t *)(tmp);
984                                         inet_ntop(AF_INET, &(hg->hep_dst_ip4->data), ipstr,
985                                                         INET_ADDRSTRLEN);
986                                         tmpstr.s = ipstr;
987                                         tmpstr.len = strlen(ipstr);
988                                         ret = pv_get_strval(msg, param, res, &tmpstr);
989                                         goto done;
990                                 case 5:
991                                         hg->hep_src_ip6 = (hep_chunk_ip6_t *)(tmp);
992                                         inet_ntop(AF_INET6, &(hg->hep_src_ip6->data), ipstr,
993                                                         INET6_ADDRSTRLEN);
994                                         tmpstr.s = ipstr;
995                                         tmpstr.len = strlen(ipstr);
996                                         ret = pv_get_strval(msg, param, res, &tmpstr);
997                                         goto done;
998                                 case 6:
999                                         hg->hep_dst_ip6 = (hep_chunk_ip6_t *)(tmp);
1000                                         inet_ntop(AF_INET6, &(hg->hep_dst_ip6->data), ipstr,
1001                                                         INET6_ADDRSTRLEN);
1002                                         tmpstr.s = ipstr;
1003                                         tmpstr.len = strlen(ipstr);
1004                                         ret = pv_get_strval(msg, param, res, &tmpstr);
1005                                         goto done;
1006                                 case 7:
1007                                         hg->src_port = (hep_chunk_uint16_t *)(tmp);
1008                                         ret = pv_get_uintval(
1009                                                         msg, param, res, ntohs(hg->src_port->data));
1010                                         goto done;
1011                                 case 8:
1012                                         hg->dst_port = (hep_chunk_uint16_t *)(tmp);
1013                                         ret = pv_get_uintval(
1014                                                         msg, param, res, ntohs(hg->dst_port->data));
1015                                         goto done;
1016                                 case 9:
1017                                         hg->time_sec = (hep_chunk_uint32_t *)(tmp);
1018                                         ret = pv_get_uintval(
1019                                                         msg, param, res, ntohl(hg->time_sec->data));
1020                                         goto done;
1021
1022                                 case 10:
1023                                         hg->time_usec = (hep_chunk_uint32_t *)(tmp);
1024                                         ret = pv_get_uintval(
1025                                                         msg, param, res, ntohl(hg->time_usec->data));
1026                                         goto done;
1027
1028                                 case 11:
1029                                         hg->proto_t = (hep_chunk_uint8_t *)(tmp);
1030                                         ret = pv_get_uintval(msg, param, res, hg->proto_t->data);
1031                                         goto done;
1032
1033                                 case 12:
1034                                         hg->capt_id = (hep_chunk_uint32_t *)(tmp);
1035                                         ret = pv_get_uintval(
1036                                                         msg, param, res, ntohl(hg->capt_id->data));
1037                                         goto done;
1038
1039                                 case 13:
1040                                         hg->keep_tm = (hep_chunk_uint16_t *)(tmp);
1041                                         ret = pv_get_uintval(
1042                                                         msg, param, res, ntohs(hg->keep_tm->data));
1043                                         goto done;
1044
1045                                 case 14:
1046                                         tmpstr.s = (char *)tmp + sizeof(hep_chunk_t);
1047                                         tmpstr.len = chunk_length - sizeof(hep_chunk_t);
1048                                         ret = pv_get_strval(msg, param, res, &tmpstr);
1049                                         goto done;
1050
1051                                 case 15:
1052                                         hg->payload_chunk = (hep_chunk_t *)(tmp);
1053                                         tmpstr.s = (char *)tmp + sizeof(hep_chunk_t);
1054                                         tmpstr.len = chunk_length - sizeof(hep_chunk_t);
1055                                         ret = pv_get_strval(msg, param, res, &tmpstr);
1056                                         goto done;
1057                                 case 17:
1058                                         tmpstr.s = (char *)tmp + sizeof(hep_chunk_t);
1059                                         tmpstr.len = chunk_length - sizeof(hep_chunk_t);
1060                                         ret = pv_get_strval(msg, param, res, &tmpstr);
1061                                         goto done;
1062                                 default:
1063                                         ret = pv_get_uintval(msg, param, res, -1);
1064                                         goto done;
1065                         }
1066                 }
1067         }
1068
1069 done:
1070
1071         //if(si) pkg_free(si);
1072         if(hg)
1073                 pkg_free(hg);
1074         return ret;
1075
1076 error:
1077
1078         if(hg)
1079                 pkg_free(hg);
1080         ret = pv_get_uintval(msg, param, res, -1);
1081         return -1;
1082 }