core, lib, modules: restructured source code tree
[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 "../../sr_module.h"
25 #include "../../dprint.h"
26 #include "../../events.h"
27 #include "../../ut.h"
28 #include "../../ip_addr.h"
29 #include "../../mem/mem.h"
30 #include "../../mem/shm_mem.h"
31 #include "../../lib/srdb1/db.h"
32 #include "../../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(void *data)
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**)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                                         hg->time_sec->data = ntohl(hg->time_sec->data);
376                                         heptime->tv_sec = hg->time_sec->data;
377                                         i+=chunk_length;
378                                         totelem++;
379                                         break;                                                     
380                                                      
381                                 case 10:
382                                         hg->time_usec  = (hep_chunk_uint32_t *) (tmp);
383                                         hg->time_usec->data = ntohl(hg->time_usec->data);
384                                         heptime->tv_usec = hg->time_usec->data;
385                                         i+=chunk_length;
386                                         totelem++;
387                                         break;      
388
389                                 case 11:
390                                         hg->proto_t  = (hep_chunk_uint8_t *) (tmp);
391                                         i+=chunk_length;
392                                         totelem++;
393                                         break;                                                                                                                                                         
394
395                                 case 12:
396                                         hg->capt_id  = (hep_chunk_uint32_t *) (tmp);
397                                         i+=chunk_length;
398                                         heptime->captid = ntohl(hg->capt_id->data);
399                                         totelem++;
400                                         break;
401
402                                 case 13:
403                                         hg->keep_tm  = (hep_chunk_uint16_t *) (tmp);
404                                         i+=chunk_length;
405                                         break;                                                     
406
407                                 case 14:
408                                         authkey = (char *) tmp + sizeof(hep_chunk_t);
409                                         i+=chunk_length;                                                                             
410                                         break;
411                                                      
412                                 case 15:
413                                         hg->payload_chunk  = (hep_chunk_t *) (tmp);
414                                         payload = (char *) tmp+sizeof(hep_chunk_t);
415                                         payload_len = chunk_length - sizeof(hep_chunk_t);
416                                         i+=chunk_length;
417                                         totelem++;
418                                         break;
419                                 case 17:
420                                 
421                                         correlation_id = (char *) tmp + sizeof(hep_chunk_t);
422                                         i+=chunk_length;                                                                            
423                                         break;
424
425                                                      
426                                 default:
427                                         i+=chunk_length;
428                                         break;
429                         }                                        
430                 }
431         }                                                                                                                 
432                         
433         /* CHECK how much elements */
434         if(totelem < 9) {                        
435                 LM_ERR("Not all elements [%d]\n", totelem);                        
436                 goto done;
437         }                 
438
439         if ( dst_ip.af == 0 || src_ip.af == 0)  {
440                 LM_ERR("NO IP's set\n");
441                 goto done;
442         }
443
444                         
445         ip_addr2su(&to, &dst_ip, ri.dst_port);
446         ip_addr2su(&from, &src_ip, ri.src_port);
447                         
448         ri.src_su=from;
449         su2ip_addr(&ri.src_ip, &from);
450         su2ip_addr(&ri.dst_ip, &to);
451
452         if(hg->ip_proto->data == IPPROTO_TCP) ri.proto=PROTO_TCP;
453         else if(hg->ip_proto->data == IPPROTO_UDP) ri.proto=PROTO_UDP;
454
455         /* a little bit memory */
456         si=(struct socket_info*) pkg_malloc(sizeof(struct socket_info));
457         if (si==0) {
458                 LOG(L_ERR, "ERROR: new_sock_info: memory allocation error\n");
459                 goto error;
460         }
461
462         memset(si, 0, sizeof(struct socket_info));
463         si->address = ri.dst_ip;
464         si->socket=-1;
465
466         /* set port & proto */
467         si->port_no = ri.dst_port;
468
469         if(hg->ip_proto->data == IPPROTO_TCP) si->proto=PROTO_TCP;
470         else if(hg->ip_proto->data == IPPROTO_UDP) si->proto=PROTO_UDP;
471
472         si->flags=0;
473         si->addr_info_lst=0;
474
475         si->address_str.s = ip_addr2a(&si->address);;
476         si->address_str.len = strlen(si->address_str.s);                                                
477
478         si->port_no_str.s = int2str(si->port_no, &tmp_len);
479         si->port_no_str.len = tmp_len;
480         si->address_str.len = strlen(si->address_str.s);
481
482         si->name.len = si->address_str.len;
483         si->name.s = si->address_str.s;
484         ri.bind_address=si;
485
486
487         /*TIME*/ 
488         heptime->tv_sec = hg->time_sec->data;
489         heptime->tv_usec = hg->time_usec->data;
490         heptime->captid = ntohl(hg->capt_id->data);
491           
492
493         if(payload != NULL ) {
494                 /* and now recieve message */
495                 if (hg->proto_t->data == 5) receive_logging_json_msg(payload, payload_len, hg, "rtcp_capture");
496                 else if (hg->proto_t->data == 32) receive_logging_json_msg(payload, payload_len, hg, "report_capture");
497                 else if (hg->proto_t->data == 99) receive_logging_json_msg(payload, payload_len, hg, "report_capture");
498                 else if (hg->proto_t->data == 100) receive_logging_json_msg(payload, payload_len, hg, "logs_capture");
499                 else receive_msg(payload, payload_len, &ri);
500         }
501
502 done:
503         if(si) pkg_free(si);
504         if(hg) pkg_free(hg);                     
505
506         return 1;
507         
508 error:
509
510         if(si) pkg_free(si);
511         if(hg) pkg_free(hg);
512                 
513         return -1;           
514         
515 }
516
517
518 int hepv3_message_parse(char *buf, unsigned int len, sip_msg_t* msg) {
519
520         union sockaddr_union from;
521         union sockaddr_union to;
522         char *tmp;
523         struct ip_addr dst_ip, src_ip;
524         struct socket_info* si = 0;
525         int i;
526         char *payload = NULL;
527         unsigned int payload_len = 0;
528         struct hep_chunk *chunk;        
529         struct hep_generic_recv *hg;
530         int totelem = 0;
531         int chunk_vendor=0, chunk_type=0, chunk_length=0;
532         int total_length = 0;
533         int ret = 0;
534         
535         hg = (struct hep_generic_recv*)pkg_malloc(sizeof(struct hep_generic_recv));
536         if(hg==NULL) {
537                 LM_ERR("no more pkg memory left for hg\n");
538                 return -1;
539         }
540                                                                         
541         memset(hg, 0, sizeof(struct hep_generic_recv));
542
543         
544         memset(heptime, 0, sizeof(struct hep_timeinfo));        
545                 
546
547         /* HEADER */
548         hg->header  = (hep_ctrl_t *) (buf);
549
550         /*Packet size */
551         total_length = ntohs(hg->header->length);
552
553         dst_ip.af = 0;
554         src_ip.af = 0;
555                                 
556         payload = NULL;
557         correlation_id = NULL;
558         authkey = NULL;
559
560         i = sizeof(hep_ctrl_t);         
561                 
562         while(i < total_length) {
563                 
564                 /*OUR TMP DATA */                                  
565                 tmp = buf+i;
566
567                 chunk = (struct hep_chunk*) tmp;
568                              
569                 chunk_vendor = ntohs(chunk->vendor_id);                             
570                 chunk_type = ntohs(chunk->type_id);
571                 chunk_length = ntohs(chunk->length);
572                        
573                 /* if chunk_length */
574                 if(chunk_length == 0) {
575                         /* BAD LEN we drop this packet */
576                         goto error;
577                 }
578
579                 /* SKIP not general Chunks */
580                 if(chunk_vendor != 0) {
581                         i+=chunk_length;
582                 }
583                 else {                                                                                                                               
584                         switch(chunk_type) {
585                                      
586                                 case 0:
587                                         goto error;
588                                         break;
589                                      
590                                 case 1:                                                                          
591                                         hg->ip_family  = (hep_chunk_uint8_t *) (tmp);
592                                         i+=chunk_length;
593                                         totelem++;
594                                         break;
595                                 case 2:
596                                         hg->ip_proto  = (hep_chunk_uint8_t *) (tmp);
597                                         i+=chunk_length;
598                                         totelem++;
599                                         break;                                                     
600                                 case 3:
601                                         hg->hep_src_ip4  = (hep_chunk_ip4_t *) (tmp);
602                                         i+=chunk_length;
603                                         src_ip.af=AF_INET;
604                                         src_ip.len=4;
605                                         src_ip.u.addr32[0] = hg->hep_src_ip4->data.s_addr;
606                                         totelem++;
607                                         break;
608                                 case 4:
609                                         hg->hep_dst_ip4  = (hep_chunk_ip4_t *) (tmp);
610                                         i+=chunk_length;                                                     
611                                         dst_ip.af=AF_INET;
612                                         dst_ip.len=4;
613                                         dst_ip.u.addr32[0] = hg->hep_dst_ip4->data.s_addr;
614                                         totelem++;
615
616                                         break;
617                                 case 5:
618                                         hg->hep_src_ip6  = (hep_chunk_ip6_t *) (tmp);
619                                         i+=chunk_length;
620                                         src_ip.af=AF_INET6;
621                                         src_ip.len=16;
622                                         memcpy(src_ip.u.addr, &hg->hep_src_ip6->data, 16);
623                                         totelem++;
624                                         break;
625                                 case 6:
626                                         hg->hep_dst_ip6  = (hep_chunk_ip6_t *) (tmp);
627                                         i+=chunk_length;                                                     
628                                         dst_ip.af=AF_INET6;
629                                         dst_ip.len=16;
630                                         memcpy(dst_ip.u.addr, &hg->hep_dst_ip6->data, 16);
631                                         totelem++;
632                                         break;
633         
634                                 case 7:
635                                         hg->src_port  = (hep_chunk_uint16_t *) (tmp);
636                                         msg->rcv.src_port = ntohs(hg->src_port->data);
637                                         i+=chunk_length;                      
638                                         totelem++;
639                                         break;
640
641                                 case 8:
642                                         hg->dst_port  = (hep_chunk_uint16_t *) (tmp);
643                                         msg->rcv.dst_port = ntohs(hg->dst_port->data);
644                                         i+=chunk_length;
645                                         totelem++;
646                                         break;
647                                 case 9:
648                                         hg->time_sec  = (hep_chunk_uint32_t *) (tmp);
649                                         hg->time_sec->data = ntohl(hg->time_sec->data);
650                                         heptime->tv_sec = hg->time_sec->data;
651                                         i+=chunk_length;
652                                         totelem++;
653                                         break;                                                     
654                                                      
655                                 case 10:
656                                         hg->time_usec  = (hep_chunk_uint32_t *) (tmp);
657                                         hg->time_usec->data = ntohl(hg->time_usec->data);
658                                         heptime->tv_usec = hg->time_usec->data;
659                                         i+=chunk_length;
660                                         totelem++;
661                                         break;      
662
663                                 case 11:
664                                         hg->proto_t  = (hep_chunk_uint8_t *) (tmp);
665                                         i+=chunk_length;
666                                         totelem++;
667                                         break;                                                                                                                                                         
668
669                                 case 12:
670                                         hg->capt_id  = (hep_chunk_uint32_t *) (tmp);
671                                         i+=chunk_length;
672                                         heptime->captid = ntohl(hg->capt_id->data);
673                                         totelem++;
674                                         break;
675
676                                 case 13:
677                                         hg->keep_tm  = (hep_chunk_uint16_t *) (tmp);
678                                         i+=chunk_length;
679                                         break;                                                     
680
681                                 case 14:
682                                         authkey = (char *) tmp + sizeof(hep_chunk_t);
683                                         i+=chunk_length;                                                                             
684                                         break;
685                                                      
686                                 case 15:
687                                         hg->payload_chunk  = (hep_chunk_t *) (tmp);
688                                         payload = (char *) tmp+sizeof(hep_chunk_t);
689                                         payload_len = chunk_length - sizeof(hep_chunk_t);
690                                         i+=chunk_length;
691                                         totelem++;
692                                         break;
693                                 case 17:
694                                 
695                                         correlation_id = (char *) tmp + sizeof(hep_chunk_t);
696                                         i+=chunk_length;                                                                            
697                                         break;
698
699                                                      
700                                 default:
701                                         i+=chunk_length;
702                                         break;
703                         }                                        
704                 }
705         }                                                                                                                 
706                         
707         /* CHECK how much elements */
708         if(totelem < 9) {                        
709                 LM_ERR("Not all elements [%d]\n", totelem);                        
710                 goto done;
711         }                 
712
713         if ( dst_ip.af == 0 || src_ip.af == 0)  {
714                 LM_ERR("NO IP's set\n");
715                 goto done;
716         }
717
718                         
719         ip_addr2su(&to, &dst_ip, msg->rcv.dst_port);
720         ip_addr2su(&from, &src_ip, msg->rcv.src_port);
721                         
722         msg->rcv.src_su=from;
723         su2ip_addr(&msg->rcv.src_ip, &from);
724         su2ip_addr(&msg->rcv.dst_ip, &to);
725
726         if(hg->ip_proto->data == IPPROTO_TCP) msg->rcv.proto=PROTO_TCP;
727         else if(hg->ip_proto->data == IPPROTO_UDP) msg->rcv.proto=PROTO_UDP;
728
729         if(payload != NULL) ret = len - payload_len;
730
731         /*TIME*/ 
732         heptime->tv_sec = hg->time_sec->data;
733         heptime->tv_usec = hg->time_usec->data;
734         heptime->captid = ntohl(hg->capt_id->data);
735
736 done:
737           
738         //if(si) pkg_free(si);
739         if(hg) pkg_free(hg);                     
740
741         return ret;
742         
743 error:
744
745         if(si) pkg_free(si);
746         if(hg) pkg_free(hg);
747                 
748         return -1;           
749         
750 }
751
752 int hepv2_message_parse(char *buf, unsigned int len, sip_msg_t* msg) {
753
754         int hl;
755         struct hep_hdr *heph;
756         struct ip_addr dst_ip, src_ip;
757         char *hep_payload, *end, *hep_ip;
758         struct hep_iphdr *hepiph = NULL;
759
760         struct hep_timehdr* heptime_tmp = NULL;
761         memset(heptime, 0, sizeof(struct hep_timeinfo));
762
763         struct hep_ip6hdr *hepip6h = NULL;
764                         
765         correlation_id = NULL;
766         authkey = NULL;
767
768         hep_offset = 0; 
769         
770         hl = hep_offset = sizeof(struct hep_hdr);
771         end = buf + len;
772         if (unlikely(len<hep_offset)) {
773                 LOG(L_ERR, "ERROR: sipcapture:hep_msg_received len less than offset [%i] vs [%i]\n", len, hep_offset);
774                 return -1;
775         }
776
777         /* hep_hdr */
778         heph = (struct hep_hdr*) buf;
779
780         switch(heph->hp_f){
781                 case AF_INET:
782                         hl += sizeof(struct hep_iphdr);
783                         break;
784                 case AF_INET6:
785                         hl += sizeof(struct hep_ip6hdr);
786                         break;
787                 default:
788                         LOG(L_ERR, "ERROR: sipcapture:hep_msg_received:  unsupported family [%d]\n", heph->hp_f);
789                         return -1;
790         }
791
792         /* PROTO */
793         if(heph->hp_p == IPPROTO_UDP) msg->rcv.proto=PROTO_UDP;
794         else if(heph->hp_p == IPPROTO_TCP) msg->rcv.proto=PROTO_TCP;
795         else if(heph->hp_p == IPPROTO_IDP) msg->rcv.proto=PROTO_TLS; /* fake protocol */
796 #ifdef USE_SCTP
797         else if(heph->hp_p == IPPROTO_SCTP) msg->rcv.proto=PROTO_SCTP;
798 #endif
799         else {
800                 LOG(L_ERR, "ERROR: sipcapture:hep_msg_received: unknown protocol [%d]\n",heph->hp_p);
801                 msg->rcv.proto = PROTO_NONE;
802         }
803
804         hep_ip = buf + sizeof(struct hep_hdr);
805
806         if (unlikely(hep_ip>end)){
807                 LOG(L_ERR,"hep_ip is over buf+len\n");
808                 return -1;
809         }
810
811         switch(heph->hp_f){
812                 case AF_INET:
813                         hep_offset+=sizeof(struct hep_iphdr);
814                         hepiph = (struct hep_iphdr*) hep_ip;
815                         break;
816
817                 case AF_INET6:
818                         hep_offset+=sizeof(struct hep_ip6hdr);
819                         hepip6h = (struct hep_ip6hdr*) hep_ip;
820                         break;
821
822         }
823
824         /* VOIP payload */
825         hep_payload = buf + hep_offset;
826
827         if (unlikely(hep_payload>end)){
828                 LOG(L_ERR,"hep_payload is over buf+len\n");
829                 return -1;
830         }
831
832         /* timming */
833         if(heph->hp_v == 2) {
834                 hep_offset+=sizeof(struct hep_timehdr);
835                 heptime_tmp = (struct hep_timehdr*) hep_payload;
836
837                 heptime->tv_sec = to_le(heptime_tmp->tv_sec);
838                 heptime->tv_usec = to_le(heptime_tmp->tv_usec);
839                 heptime->captid = heptime_tmp->captid;
840         }
841
842
843         /* fill ip from the packet to dst_ip && to */
844         switch(heph->hp_f){
845
846                 case AF_INET:
847                         dst_ip.af = src_ip.af = AF_INET;
848                         dst_ip.len = src_ip.len = 4 ;
849                         memcpy(&dst_ip.u.addr, &hepiph->hp_dst, 4);
850                         memcpy(&src_ip.u.addr, &hepiph->hp_src, 4);
851                         break;
852
853                 case AF_INET6:
854                         dst_ip.af = src_ip.af = AF_INET6;
855                         dst_ip.len = src_ip.len = 16 ;
856                         memcpy(&dst_ip.u.addr, &hepip6h->hp6_dst, 16);
857                         memcpy(&src_ip.u.addr, &hepip6h->hp6_src, 16);
858                         break;
859
860         }
861
862         msg->rcv.src_ip = src_ip;
863         msg->rcv.src_port = ntohs(heph->hp_sport);
864
865         msg->rcv.dst_ip = dst_ip;
866         msg->rcv.dst_port = ntohs(heph->hp_dport);
867
868         return hep_offset;
869 }
870
871
872 int hepv3_get_chunk(struct sip_msg *msg, char *buf, unsigned int len, int req_chunk, pv_param_t *param, pv_value_t *res) {
873
874         str tmpstr;
875         char *tmp;
876         int i;
877         struct hep_chunk *chunk;        
878         struct hep_generic_recv *hg;
879         int chunk_vendor=0, chunk_type=0, chunk_length=0;
880         int total_length = 0;
881         int ret = 0;
882         char ipstr[INET6_ADDRSTRLEN];        
883
884         if(memcmp(buf, "\x48\x45\x50\x33",4) && !memcmp(buf, "\x45\x45\x50\x31",4)) {
885         
886                 LM_ERR("not hep 3 protocol");
887                 pv_get_uintval(msg, param, res, -1);
888                 return -1;        
889         }
890         
891         hg = (struct hep_generic_recv*)pkg_malloc(sizeof(struct hep_generic_recv));
892         if(hg==NULL) {
893                 LM_ERR("no more pkg memory left for hg\n");
894                 return -1;
895         }
896                                                                         
897         memset(hg, 0, sizeof(struct hep_generic_recv));
898         
899         /* HEADER */
900         hg->header  = (hep_ctrl_t *) (buf);
901
902         /*Packet size */
903         total_length = ntohs(hg->header->length);
904
905         i = sizeof(hep_ctrl_t);         
906                 
907         while(i < total_length) {
908                 
909                 /*OUR TMP DATA */                                  
910                 tmp = buf+i;
911
912                 chunk = (struct hep_chunk*) tmp;
913                              
914                 chunk_vendor = ntohs(chunk->vendor_id);                             
915                 chunk_type = ntohs(chunk->type_id);
916                 chunk_length = ntohs(chunk->length);
917                        
918                 /* if chunk_length */
919                 if(chunk_length == 0) {
920                         /* BAD LEN we drop this packet */
921                         goto error;
922                 }
923
924                 /* SKIP not general Chunks */
925                 if(chunk_vendor != 0) {
926                         i+=chunk_length;
927                 }
928                 else {                 
929                         if(chunk_type != req_chunk)
930                         {
931                                 i+=chunk_length;
932                                 continue;                        
933                         }              
934                                                                                                                               
935                         switch(chunk_type) {
936                                      
937                                 case 0:
938                                         goto error;
939                                         break;
940                                      
941                                 case 1:                                                                          
942                                         hg->ip_family  = (hep_chunk_uint8_t *) (tmp);
943                                         ret = pv_get_uintval(msg, param, res, hg->ip_family->data);
944                                         goto done;
945                                 case 2:
946                                         hg->ip_proto  = (hep_chunk_uint8_t *) (tmp);
947                                         ret = pv_get_uintval(msg, param, res, hg->ip_proto->data);
948                                         goto done;
949                                 case 3:
950                                         hg->hep_src_ip4  = (hep_chunk_ip4_t *) (tmp);
951                                         inet_ntop(AF_INET, &(hg->hep_src_ip4->data), ipstr, INET_ADDRSTRLEN);
952                                         tmpstr.s = ipstr;
953                                         tmpstr.len = strlen(ipstr);
954                                         ret = pv_get_strval(msg, param, res, &tmpstr);
955                                         goto done;
956                                 case 4:
957                                         hg->hep_dst_ip4  = (hep_chunk_ip4_t *) (tmp);
958                                         inet_ntop(AF_INET, &(hg->hep_dst_ip4->data), ipstr, INET_ADDRSTRLEN);
959                                         tmpstr.s = ipstr;
960                                         tmpstr.len = strlen(ipstr);
961                                         ret = pv_get_strval(msg, param, res, &tmpstr);
962                                         goto done;
963                                 case 5:
964                                         hg->hep_src_ip6  = (hep_chunk_ip6_t *) (tmp);
965                                         inet_ntop(AF_INET6, &(hg->hep_src_ip6->data), ipstr, INET6_ADDRSTRLEN);                                                        
966                                         tmpstr.s = ipstr;
967                                         tmpstr.len = strlen(ipstr);
968                                         ret = pv_get_strval(msg, param, res, &tmpstr);
969                                         goto done;                                                                                
970                                 case 6:
971                                         hg->hep_dst_ip6  = (hep_chunk_ip6_t *) (tmp);
972                                         inet_ntop(AF_INET6, &(hg->hep_dst_ip6->data), ipstr, INET6_ADDRSTRLEN);                                                        
973                                         tmpstr.s = ipstr;
974                                         tmpstr.len = strlen(ipstr);
975                                         ret = pv_get_strval(msg, param, res, &tmpstr);
976                                         goto done;
977                                 case 7:
978                                         hg->src_port  = (hep_chunk_uint16_t *) (tmp);
979                                         ret = pv_get_uintval(msg, param, res, ntohs(hg->src_port->data));
980                                         break;
981                                 case 8:
982                                         hg->dst_port  = (hep_chunk_uint16_t *) (tmp);
983                                         ret = pv_get_uintval(msg, param, res, ntohs(hg->dst_port->data));
984                                         break;
985                                 case 9:
986                                         hg->time_sec  = (hep_chunk_uint32_t *) (tmp);
987                                         hg->time_sec->data = ntohl(hg->time_sec->data);
988                                         ret = pv_get_uintval(msg, param, res, hg->time_sec->data);
989                                         goto done;
990                                                      
991                                 case 10:
992                                         hg->time_usec  = (hep_chunk_uint32_t *) (tmp);
993                                         hg->time_usec->data = ntohl(hg->time_usec->data);
994                                         ret = pv_get_uintval(msg, param, res, hg->time_usec->data);
995                                         goto done;
996
997                                 case 11:
998                                         hg->proto_t  = (hep_chunk_uint8_t *) (tmp);
999                                         ret = pv_get_uintval(msg, param, res, hg->proto_t->data);
1000                                         goto done;
1001
1002                                 case 12:
1003                                         hg->capt_id  = (hep_chunk_uint32_t *) (tmp);
1004                                         ret = pv_get_uintval(msg, param, res, ntohs(hg->capt_id->data));
1005                                         goto done;
1006
1007                                 case 13:
1008                                         hg->keep_tm  = (hep_chunk_uint16_t *) (tmp);
1009                                         ret = pv_get_uintval(msg, param, res, hg->keep_tm->data);                                                                                
1010                                         goto done;
1011                                 case 14:
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                                                      
1017                                 case 15:
1018                                         hg->payload_chunk  = (hep_chunk_t *) (tmp);
1019                                         tmpstr.s = (char *) tmp+sizeof(hep_chunk_t);
1020                                         tmpstr.len = chunk_length - sizeof(hep_chunk_t);
1021                                         ret = pv_get_strval(msg, param, res, &tmpstr);
1022                                         goto done;
1023                                 case 17:                                        
1024                                         tmpstr.s = (char *) tmp + sizeof(hep_chunk_t);
1025                                         tmpstr.len = chunk_length - sizeof(hep_chunk_t); 
1026                                         ret = pv_get_strval(msg, param, res, &tmpstr);                                                                                 
1027                                         goto done;
1028                                 default:
1029                                         ret = pv_get_uintval(msg, param, res, -1);
1030                                         goto done;                                        
1031                         }                                        
1032                 }
1033         }                                                                                                                 
1034
1035 done:
1036           
1037         //if(si) pkg_free(si);
1038         if(hg) pkg_free(hg);                             
1039         return ret;
1040         
1041 error:
1042
1043         if(hg) pkg_free(hg);
1044         ret = pv_get_uintval(msg, param, res, -1);                
1045         return -1;                   
1046 }
1047