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