hep/
lib.rs

1/*!
2 # hep
3
4 use HEP3 Network Protocol Specification
5
6 HEP3 (Homer Encapsulation Protocol Version 3) transmits packets over UDP/TCP/SCTP connections.
7
8 Supprot HEPv1 HEPv2 HEP v3.
9
10 HEPv2 Just Support IPv4
11
12 author: MROJECT(ZhangLianJun z0413@outlook.com)
13
14## Examples
15
16```
17use hep::parse_packet;
18use std::net::UdpSocket;
19
20fn main() -> std::io::Result<()> {
21
22    let socket = UdpSocket::bind("169.254.165.11:9060").expect("couldn't bind to address");
23    loop {
24        let mut buffer = [0x0; 0xdbba0];
25        let (number_of_bytes, src_addr) =
26            socket.recv_from(&mut buffer).expect("Didn't receive data");
27        let filled_buf = &mut buffer[..number_of_bytes];
28        let data = parse_packet(&filled_buf);
29        
30        match data {
31            Ok(chunk) => {
32                println!("Message length:{}", &chunk.packet_payload.len());
33                if chunk.packet_payload.len() > 6 {
34                    println!(
35                        "Received Hep(sip) Message from IP:{}, CaptureId:{}\n{}",
36                        src_addr, 
37                        chunk.capture_agent_id, 
38                        chunk.packet_payload
39                    );
40                } else {
41                    println!(
42                        "Received Hep(Keepalive) Message from IP:{}, CaptureId:{}.\n",
43                        src_addr, 
44                        chunk.capture_agent_id
45                    );
46                }
47            }
48            Err(_) => {
49                println!(
50                    "Received Hep Message from IP:{}\n ignore data.\r\n\r\n",
51                    src_addr
52                );
53            }
54        }
55    }
56}
57
58```
59*/
60use byteorder::{ByteOrder, NetworkEndian};
61use log::{debug, error, trace};
62use std::net::{Ipv4Addr, Ipv6Addr};
63
64/// CHUNK_PAYLOAD_START with HEPv3
65/// 
66/// 0..4 HEP Version
67///
68/// 4..6 Packet Size
69const CHUNK_PAYLOAD_START: usize = 6;
70
71/// Hep Version enum
72#[derive(Debug, PartialEq)]
73pub enum HepVersion {
74    HepV1,
75    HepV2,
76    HepV3,
77    Unknown,
78}
79
80/// match hep packet 0..4
81/// 
82/// convert to Version
83/// 
84/// [1, _, _, _] -> HepV1
85/// 
86/// [2, _, _, _] -> HepV2
87/// 
88/// [72, 69, 80, 51] -> HepV3
89/// 
90impl std::convert::From<&[u8]> for HepVersion {
91    fn from(b: &[u8]) -> Self {
92        match b {
93            [1, _, _, _] => HepVersion::HepV1,
94            [2, _, _, _] => HepVersion::HepV2,
95            [72, 69, 80, 51] => HepVersion::HepV3,
96            _ => HepVersion::Unknown,
97        }
98    }
99}
100
101/// Vendor Id enum
102#[warn(clippy::upper_case_acronyms)]
103#[derive(Debug, PartialEq)]
104pub enum Vendor {
105    Generic,
106    FreeSwitch,
107    Kamailio,
108    OpenSips,
109    Asterisk,
110    Homer,
111    SipXecs,
112    YetiSwitch,
113    Genesys,
114}
115
116/// Vendor id defined
117impl std::convert::From<u16> for Vendor {
118    fn from(b: u16) -> Self {
119        match b {
120            0 => Vendor::Generic,
121            1 => Vendor::FreeSwitch,
122            2 => Vendor::Kamailio,
123            3 => Vendor::OpenSips,
124            4 => Vendor::Asterisk,
125            5 => Vendor::Homer,
126            6 => Vendor::SipXecs,
127            7 => Vendor::YetiSwitch,
128            8 => Vendor::Genesys,
129            _ => Vendor::Generic,
130        }
131    }
132}
133
134/// Hep Capture Protocol Type
135///
136/// Support list as below
137///
138/// but this project just suppport sip
139///
140#[derive(Debug, PartialEq, Clone, Copy)]
141pub enum CapProtoType {
142    Reserved,
143    Sip,
144    Xmpp,
145    Sdp,
146    Rtp,
147    Rtcp,
148    Mgcp,
149    Megaco,
150    Mtp2,
151    Mtp3,
152    Iax,
153    H3222,
154    H321,
155    M2Pa,
156    MosFull,
157    MosShort,
158    SipJson,
159    DnsJson,
160    M3UaJson,
161    Rtsp,
162    Diameter,
163    GsmMap,
164}
165
166/// Print Capture Protocol Type
167impl std::fmt::Display for CapProtoType {
168    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169        use CapProtoType::*;
170        match &self {
171            Reserved => write!(f, "Reserved"),
172            Sip => write!(f, "SIP"),
173            Xmpp => write!(f, "XMPP"),
174            Sdp => write!(f, "SDP"),
175            Rtp => write!(f, "RTP"),
176            Rtcp => write!(f, "RTCP"),
177            Mgcp => write!(f, "MGCP"),
178            Megaco => write!(f, "Megaco"),
179            Mtp2 => write!(f, "MTP2"),
180            Mtp3 => write!(f, "MTP3"),
181            Iax => write!(f, "IAX"),
182            H3222 => write!(f, "H322"),
183            H321 => write!(f, "H321"),
184            M2Pa => write!(f, "M2PA"),
185            MosFull => write!(f, "MOS Full"),
186            MosShort => write!(f, "MOS Short"),
187            SipJson => write!(f, "SIP JSON"),
188            DnsJson => write!(f, "DNS JSON"),
189            M3UaJson => write!(f, "M3UA JSON"),
190            Rtsp => write!(f, "RTSP"),
191            Diameter => write!(f, "Diameter"),
192            GsmMap => write!(f, "GSM map"),
193        }
194    }
195}
196
197/// match Capture id
198///
199/// Convert to Capture Protocol Type
200impl std::convert::From<u8> for CapProtoType {
201    fn from(b: u8) -> Self {
202        match b {
203            0 => CapProtoType::Reserved,
204            1 => CapProtoType::Sip,
205            2 => CapProtoType::Xmpp,
206            3 => CapProtoType::Sdp,
207            4 => CapProtoType::Rtp,
208            5 => CapProtoType::Rtcp,
209            6 => CapProtoType::Mgcp,
210            7 => CapProtoType::Megaco,
211            8 => CapProtoType::Mtp2,
212            9 => CapProtoType::Mtp3,
213            10 => CapProtoType::Iax,
214            11 => CapProtoType::H3222,
215            12 => CapProtoType::H321,
216            13 => CapProtoType::M2Pa,
217            34 => CapProtoType::MosFull,
218            35 => CapProtoType::MosShort,
219            50 => CapProtoType::SipJson,
220            51 => CapProtoType::Reserved,
221            52 => CapProtoType::Reserved,
222            53 => CapProtoType::DnsJson,
223            54 => CapProtoType::M3UaJson,
224            55 => CapProtoType::Rtsp,
225            56 => CapProtoType::Diameter,
226            57 => CapProtoType::GsmMap,
227            _ => CapProtoType::Reserved,
228        }
229    }
230}
231
232/// Chunk types with chunk vendor ID 0x0000 are called generic chunk types. The following
233///
234/// generic chunk types are defined:
235/// 1 uint8 IP protocol family
236///
237/// 2 uint8 IP protocol ID
238///
239/// 3 inet4-addr IPv4 source address
240///
241/// 4 inet4-addr IPv4 destination address
242///
243/// 5 inet6-addr IPv6 source address
244///
245/// 6 inet6-addr IPv6 destination address
246///
247/// 7 uint16 protocol source port (UDP, TCP, SCTP)
248///
249/// 8 uint16 protocol destination port (UDP, TCP, SCTP)
250///
251/// 9 uint32 timestamp, seconds since 01/01/1970 (epoch)
252///
253/// 10 uint32 timestamp microseconds offset (added to timestamp)
254///
255/// 11 uint8 protocol type (SIP/H323/RTP/MGCP/M2UA)
256///
257/// 12 uint32 capture agent ID (202, 1201, 2033...)
258///
259/// 13 uint16 keep alive timer (sec)Capture protocol types (0x00b)
260///
261/// 14 octet-string authenticate key (plain text / TLS connection)
262///
263/// 15 octet-string captured packet payload
264///
265/// 16 octet-string captured compressed payload (gzip/inflate)
266///
267/// 17 octet-string Internal correlation id
268///
269/// 18 uint16 Vlan ID
270///
271/// 19 octet-string Group ID
272///
273/// 20 uint64 Source MAC
274///
275/// 21 uint64 Destination MAC
276///
277/// 22 uint16 Ethernet Type
278///
279/// 23 uint8 TCP Flag [SYN.PUSH...]
280///
281/// 24 uint8 IP TOS
282/// ….. ….. …...
283/// 31 Reserved
284///
285/// 32 uint16 MOS value
286///
287/// 33 uint16 R-Factor
288///
289/// 34 octet-string GEO Location
290///
291/// 35 uint32 Jitter
292///
293/// 36 octet-string Transaction type [call, registration]
294///
295/// 37 octet-string Payload JSON Keys
296///
297/// 38 octet-string Tags’ values
298///
299/// 39 uint16 Type of tag
300#[derive(Debug, Clone, PartialEq)]
301pub struct Chunk {
302    pub ip_protocol_family: u8,              //1
303    pub ip_protocol_id: u8,                  //2
304    pub ipv4_src_address: Ipv4Addr,          //3
305    pub ipv4_dst_address: Ipv4Addr,          //4
306    pub ipv6_src_address: Ipv6Addr,          //5
307    pub ipv6_dst_address: Ipv6Addr,          //6
308    pub proto_src_port: u16,                 //7
309    pub proto_dst_port: u16,                 //8
310    pub timestamp_seconds: u32,              //9
311    pub timestamp_micro_seconds_offset: u32, //10
312    pub proto_type: CapProtoType,            //11
313    pub capture_agent_id: u32,               //12
314    pub keep_alive_timer: u16,               //13
315    pub authenticate_key: String,            //14
316    pub packet_payload: String,              //15
317    pub compressed_payload: String,          //16
318    pub internal_correlation_id: String,     //17
319    pub vlan_id: u16,                        //18
320    pub group_id: String,                    //19
321    pub src_mac: u64,                        //20
322    pub dst_mac: u64,                        //21
323    pub ethernet_type: u16,                  //22
324    pub tcp_flag: u8,                        //23
325    pub ip_tos: u8,                          //24
326    pub mos_value: u16,                      //32
327    pub rfactor: u16,                        //33
328    pub geo_location: String,                //34
329    pub jitter: u32,                         //35
330    pub translation_type: String,            //36
331    pub payload_json_keys: String,           //37
332    pub tags_values: String,                 //38
333    pub type_of_tag: String,                 //39
334}
335
336impl Chunk {
337    pub fn new() -> Chunk {
338        Chunk {
339            ip_protocol_family: 0,
340            ip_protocol_id: 0,
341            ipv4_src_address: Ipv4Addr::new(0, 0, 0, 0),
342            ipv4_dst_address: Ipv4Addr::new(0, 0, 0, 0),
343            ipv6_src_address: Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
344            ipv6_dst_address: Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0),
345            proto_src_port: 5060,
346            proto_dst_port: 9060,
347            timestamp_seconds: 0,
348            timestamp_micro_seconds_offset: 0,
349            proto_type: CapProtoType::Sip,
350            capture_agent_id: 0,
351            keep_alive_timer: 1500,
352            authenticate_key: String::new(),
353            packet_payload: String::new(),
354            compressed_payload: String::new(),
355            internal_correlation_id: String::new(),
356            vlan_id: 0,
357            group_id: String::new(),
358            src_mac: 0,
359            dst_mac: 0,
360            ethernet_type: 0,
361            tcp_flag: 0,
362            ip_tos: 0,
363            mos_value: 0,
364            rfactor: 0,
365            geo_location: String::new(),
366            jitter: 0,
367            translation_type: String::new(),
368            payload_json_keys: String::new(),
369            tags_values: String::new(),
370            type_of_tag: String::new(),
371        }
372    }
373}
374
375impl Chunk {
376    /// set Chunk types of IpProtocolFamily
377    /// ```
378    /// use hep::Chunk;
379    /// 
380    /// let mut chunks = Chunk::new();
381    /// chunks.set_ip_protocol_family(1);
382    ///
383    /// println!("{:?}",chunks);
384    /// ```
385    pub fn set_ip_protocol_family(&mut self, ip_protocol_family: u8) -> &mut Chunk {
386        self.ip_protocol_family = ip_protocol_family;
387        self
388    }
389
390    /// set Chunk types of IpProtocolId
391    pub fn set_ip_protocol_id(&mut self, ip_protocol_id: u8) -> &mut Chunk {
392        self.ip_protocol_id = ip_protocol_id;
393        self
394    }
395
396    /// set Chunk types of Ipv4SrcAddress
397    pub fn set_ipv4_src_address(&mut self, ipv4_src_address: Ipv4Addr) -> &mut Chunk {
398        self.ipv4_src_address = ipv4_src_address;
399        self
400    }
401
402    /// set Chunk types of Ipv4DstAddress
403    pub fn set_ipv4_dst_address(&mut self, ipv4_dst_address: Ipv4Addr) -> &mut Chunk {
404        self.ipv4_dst_address = ipv4_dst_address;
405        self
406    }
407
408    /// set Chunk types of Ipv6SrcAddress
409    pub fn set_ipv6_src_address(&mut self, ipv6_src_address: Ipv6Addr) -> &mut Chunk {
410        self.ipv6_src_address = ipv6_src_address;
411        self
412    }
413
414    /// set Chunk types of Ipv6DstAddress
415    pub fn set_ipv6_dst_address(&mut self, ipv6_dst_address: Ipv6Addr) -> &mut Chunk {
416        self.ipv6_dst_address = ipv6_dst_address;
417        self
418    }
419
420    /// set Chunk types of ProtoSrcPort
421    pub fn set_proto_src_port(&mut self, proto_src_port: u16) -> &mut Chunk {
422        self.proto_src_port = proto_src_port;
423        self
424    }
425
426    /// set Chunk types of ProtoDstPort
427    pub fn set_proto_dst_port(&mut self, proto_dst_port: u16) -> &mut Chunk {
428        self.proto_dst_port = proto_dst_port;
429        self
430    }
431
432    /// set Chunk types of Timestamp_Seconds
433    pub fn set_timestamp_seconds(&mut self, timestamp_seconds: u32) -> &mut Chunk {
434        self.timestamp_seconds = timestamp_seconds;
435        self
436    }
437
438    /// set Chunk types of TimestampMicroSecondsOffset
439    pub fn set_timestamp_micro_seconds_offset(
440        &mut self,
441        timestamp_micro_seconds_offset: u32,
442    ) -> &mut Chunk {
443        self.timestamp_micro_seconds_offset = timestamp_micro_seconds_offset;
444        self
445    }
446
447    /// set Chunk types of ProtoType
448    pub fn set_proto_type(&mut self, proto_type: CapProtoType) -> &mut Chunk {
449        self.proto_type = proto_type;
450        self
451    }
452
453    /// set Chunk types of CaptureAgentId
454    pub fn set_capture_agent_id(&mut self, capture_agent_id: u32) -> &mut Chunk {
455        self.capture_agent_id = capture_agent_id;
456        self
457    }
458
459    /// set Chunk types of KeepAliveTimer
460    pub fn set_keep_alive_timer(&mut self, keep_alive_timer: u16) -> &mut Chunk {
461        self.keep_alive_timer = keep_alive_timer;
462        self
463    }
464
465    /// set Chunk types of AuthenticateKey
466    pub fn set_authenticate_key(&mut self, authenticate_key: String) -> &mut Chunk {
467        self.authenticate_key = authenticate_key;
468        self
469    }
470
471    /// set Chunk types of PacketPayload
472    ///
473    /// Valid Data in PacketPayload
474    pub fn set_packet_payload(&mut self, packet_payload: String) -> &mut Chunk {
475        self.packet_payload = packet_payload;
476        self
477    }
478
479    /// set Chunk types of CompressedPayload
480    pub fn set_compressed_payload(&mut self, compressed_payload: String) -> &mut Chunk {
481        self.compressed_payload = compressed_payload;
482        self
483    }
484
485    /// set Chunk types of InternalCorrelationId
486    pub fn set_set_internal_correlation_id(&mut self, internal_correlation_id: String) -> &mut Chunk {
487        self.internal_correlation_id = internal_correlation_id;
488        self
489    }
490
491    /// set Chunk types of VlanId
492    pub fn set_vlan_id(&mut self, vlan_id: u16) -> &mut Chunk {
493        self.vlan_id = vlan_id;
494        self
495    }
496
497    /// set Chunk types of GroupId
498    pub fn set_group_id(&mut self, group_id: String) -> &mut Chunk {
499        self.group_id = group_id;
500        self
501    }
502
503    /// set Chunk types of SrcMac
504    pub fn set_src_mac(&mut self, src_mac: u64) -> &mut Chunk {
505        self.src_mac = src_mac;
506        self
507    }
508
509    /// set Chunk types of DstMac
510    pub fn set_dst_mac(&mut self, dst_mac: u64) -> &mut Chunk {
511        self.dst_mac = dst_mac;
512        self
513    }
514
515    /// set Chunk types of EthernetType
516    pub fn set_ethernet_type(&mut self, ethernet_type: u16) -> &mut Chunk {
517        self.ethernet_type = ethernet_type;
518        self
519    }
520
521    /// set Chunk types of TcpFlag
522    pub fn set_tcp_flag(&mut self, tcp_flag: u8) -> &mut Chunk {
523        self.tcp_flag = tcp_flag;
524        self
525    }
526
527    /// set Chunk types of IpTos
528    pub fn set_ip_tos(&mut self, ip_tos: u8) -> &mut Chunk {
529        self.ip_tos = ip_tos;
530        self
531    }
532
533    /// set Chunk types of MosValue
534    pub fn set_mos_value(&mut self, mos_value: u16) -> &mut Chunk {
535        self.mos_value = mos_value;
536        self
537    }
538
539    /// set Chunk types of RFactor
540    pub fn set_rfactor(&mut self, rfactor: u16) -> &mut Chunk {
541        self.rfactor = rfactor;
542        self
543    }
544
545    /// set Chunk types of GeoLocation
546    pub fn set_geo_location(&mut self, geo_location: String) -> &mut Chunk {
547        self.geo_location = geo_location;
548        self
549    }
550
551    /// set Chunk types of Jitter
552    pub fn set_jitter(&mut self, jitter: u32) -> &mut Chunk {
553        self.jitter = jitter;
554        self
555    }
556
557    /// set Chunk types of TranslationType
558    pub fn set_translation_type(&mut self, translation_type: String) -> &mut Chunk {
559        self.translation_type = translation_type;
560        self
561    }
562
563    /// set Chunk types of PlayloadJsonKeys
564    pub fn set_payload_json_keys(&mut self, payload_json_keys: String) -> &mut Chunk {
565        self.payload_json_keys = payload_json_keys;
566        self
567    }
568
569    /// set Chunk types of TagsValues
570    pub fn set_tags_values(&mut self, tags_values: String) -> &mut Chunk {
571        self.tags_values = tags_values;
572        self
573    }
574
575    /// set Chunk types of TypeOfTag
576    pub fn set_type_of_tag(&mut self, type_of_tag: String) -> &mut Chunk {
577        self.type_of_tag = type_of_tag;
578        self
579    }
580}
581
582/// Entry Function
583///
584/// input params: hep packet data
585///
586/// return data:
587///
588/// 1. ();
589///
590/// 2. Ok(Chunk);// Chunk defined see pub Struct Chunk
591///
592pub fn parse_packet(packet: &[u8]) -> Result<Chunk, ()> {
593    let version = HepVersion::from(&packet[..4]);
594
595    match version {
596        HepVersion::HepV1 => {
597            debug!("HEP Version 1");
598            parse_hep_v1(packet)
599        }
600        HepVersion::HepV2 => {
601            debug!("HEP Version 2");
602            parse_hep_v2(packet)
603        }
604        HepVersion::HepV3 => {
605            debug!("HEP version 3");
606            parse_hep_v3(packet)
607        }
608        _ => {
609            error!("Not matched HEP/EEP.");
610            parse_hep_v1(packet)
611        }
612    }
613}
614
615/// Hep v1
616/// 
617/// Hep v1 Header is exist
618/// 
619/// [0]: Hep Version, static value: 1
620/// 
621/// [1..]: Payload Data
622///
623/// return Ok([Chunk](./struct.Chunk.html)),
624///
625/// but PacketPayload is null
626fn parse_hep_v1(_packet: &[u8]) -> Result<Chunk, ()> {
627    trace!("Parse HEPV2/EEPV2 Start.");
628    let mut chunks = Chunk::new();
629
630    trace!("Ignore Chunk Data, hep v1 exist chunk.");
631
632    chunks.set_packet_payload(
633        String::from_utf8(_packet[1..].to_vec()).unwrap_or_else(|_| "".to_owned()),
634    );
635
636    trace!("Parse HEPV2/EEPV2 Completed.");
637    
638    if chunks.packet_payload.len() > 2 {
639        Ok(chunks)
640    } else {
641        Err(())
642    }
643}
644
645/// Hepv2 used
646///
647/// hep v2 header format:
648/// 
649/// [0]: hep 2, value is 2
650/// 
651/// [1]: header length, static value: 28
652/// 
653/// [2]: ip_protocol_family: static value: 2
654/// 
655/// [3]: transport type:17 is UDP, 06 is TCP, STCP Unknown
656/// 
657/// [4..6]: Src Port
658/// 
659/// [6..8]: Dst Port
660/// 
661/// [8..12]: Src IP
662/// 
663/// [12..16]: Dst IP
664/// 
665/// [16..20]: Unix Timestamp
666/// 
667/// [20..24]: Timestamp Micro Seconds Offset
668/// 
669/// [24..28]: Capture Agent Id
670/// 
671/// [28]: Meaningless
672/// 
673/// [28..]: Payload Data
674/// 
675fn parse_hep_v2(_packet: &[u8]) -> Result<Chunk, ()> {
676    trace!("Parse HEPV2/EEPV2 Start.");
677
678    let mut chunks = Chunk::new();
679    trace!("Match Chunk Data.");
680
681    let payload_start = _packet[1] as usize;
682
683    chunks.set_ip_protocol_family(_packet[2]);
684
685    chunks.set_translation_type(match _packet[3] {
686        17 => String::from("UDP"),
687        6 => String::from("TCP"),
688        _ => String::from("Unknown")
689
690    });
691
692    chunks.set_proto_src_port(NetworkEndian::read_u16(&_packet[4..6]));
693
694    chunks.set_proto_dst_port(NetworkEndian::read_u16(&_packet[6..8]));
695
696    let src_ip_chunk = &_packet[8..12];
697    chunks.set_ipv4_src_address(Ipv4Addr::new(
698        src_ip_chunk[0],
699        src_ip_chunk[1],
700        src_ip_chunk[2],
701        src_ip_chunk[3],
702    ));
703
704    let dst_ip_chunk = &_packet[12..16];
705    chunks.set_ipv4_dst_address(Ipv4Addr::new(
706        dst_ip_chunk[0],
707        dst_ip_chunk[1],
708        dst_ip_chunk[2],
709        dst_ip_chunk[3],
710    ));
711
712    let tmso = &_packet[16..20];
713    let tmso_clone = <&[u8]>::clone(&tmso);
714    let tmso_clone:Vec<u8> =  tmso_clone.iter().rev().copied().collect();
715    chunks.set_timestamp_seconds(NetworkEndian::read_u32(tmso_clone.as_slice()));
716
717    let tm = &_packet[20..24];
718    let tm_clone = <&[u8]>::clone(&tm);
719    let tm_clone:Vec<u8> =  tm_clone.iter().rev().copied().collect();
720    chunks.set_timestamp_micro_seconds_offset(NetworkEndian::read_u32(tm_clone.as_slice()));
721
722    let agent_id_byte = &_packet[24..28];
723    let agent_clone = <&[u8]>::clone(&agent_id_byte);
724    let agent_clone: Vec<u8> = agent_clone.iter().rev().copied().collect();
725    chunks.set_capture_agent_id(NetworkEndian::read_u32(agent_clone.as_slice()));
726
727    trace!("Read Payload Data.");
728
729    chunks.set_packet_payload(
730        String::from_utf8(_packet[payload_start..].to_vec()).unwrap_or_else(|_| "".to_owned()),
731    );
732
733    trace!("Parse HEPV2/EEPV2 Completed.");
734
735    if chunks.packet_payload.len() > 2 {
736        Ok(chunks)
737    } else {
738        Err(())
739    }
740}
741
742
743fn parse_hep_v3(packet: &[u8]) -> Result<Chunk, ()> {
744    trace!("Parse HEPV3/EEPV3 Start.");
745    let mut current_byte = CHUNK_PAYLOAD_START;
746    let total_len = NetworkEndian::read_u16(&packet[4..6]) as usize;
747    trace!("HEPV3/EEPV3 Packet Size: {}", &total_len);
748
749    let mut chunks = Chunk::new();
750
751    while current_byte < total_len {
752        let chunk = &packet[current_byte as usize..];
753
754        let vendor = Vendor::from(NetworkEndian::read_u16(&chunk[0..2]));
755        trace!("Vendor Chunk Id: {:?}", &vendor);
756
757        let chunk_type = NetworkEndian::read_u16(&chunk[2..4]);
758        trace!("Chunk Type: {}", &chunk_type);
759
760        let chunk_len = NetworkEndian::read_u16(&chunk[4..6]) as usize;
761        trace!("Chunk Length: {}", &chunk_len);
762
763        let chunk_payload = &chunk[CHUNK_PAYLOAD_START..chunk_len];
764
765        match chunk_type {
766            1 => chunks.set_ip_protocol_family(chunk_payload[0]),
767            2 => chunks.set_ip_protocol_id(chunk_payload[0]),
768            3 => chunks.set_ipv4_src_address(Ipv4Addr::new(
769                chunk_payload[0],
770                chunk_payload[1],
771                chunk_payload[2],
772                chunk_payload[3],
773            )),
774            4 => chunks.set_ipv4_dst_address(Ipv4Addr::new(
775                chunk_payload[0],
776                chunk_payload[1],
777                chunk_payload[2],
778                chunk_payload[3],
779            )),
780            5 => chunks
781                .set_ipv6_src_address(Ipv6Addr::from(NetworkEndian::read_u128(&chunk_payload))),
782            6 => chunks
783                .set_ipv6_dst_address(Ipv6Addr::from(NetworkEndian::read_u128(&chunk_payload))),
784            7 => chunks.set_proto_src_port(NetworkEndian::read_u16(&chunk_payload)),
785            8 => chunks.set_proto_dst_port(NetworkEndian::read_u16(&chunk_payload)),
786            9 => chunks.set_timestamp_seconds(NetworkEndian::read_u32(&chunk_payload)),
787            10 => {
788                chunks.set_timestamp_micro_seconds_offset(NetworkEndian::read_u32(&chunk_payload))
789            }
790
791            11 => chunks.set_proto_type(CapProtoType::from(chunk_payload[0])),
792            12 => chunks.set_capture_agent_id(NetworkEndian::read_u32(&chunk_payload)),
793            13 => chunks.set_keep_alive_timer(NetworkEndian::read_u16(&chunk_payload)),
794            14 => chunks.set_authenticate_key(
795                String::from_utf8(chunk_payload.to_vec()).unwrap_or_else(|_| "".to_owned()),
796            ),
797            15 => chunks.set_packet_payload(
798                String::from_utf8(chunk_payload.to_vec()).unwrap_or_else(|_| "".to_owned()),
799            ),
800            16 => chunks.set_compressed_payload(
801                String::from_utf8(chunk_payload.to_vec()).unwrap_or_else(|_| "".to_owned()),
802            ),
803            17 => chunks.set_set_internal_correlation_id(
804                String::from_utf8(chunk_payload.to_vec()).unwrap_or_else(|_| "".to_owned()),
805            ),
806            18 => chunks.set_vlan_id(NetworkEndian::read_u16(&chunk_payload)),
807            19 => {
808                chunks.set_group_id(String::from_utf8(chunk_payload.to_vec()).unwrap_or_default())
809            }
810            20 => chunks.set_src_mac(NetworkEndian::read_u64(&chunk_payload)),
811            21 => chunks.set_dst_mac(NetworkEndian::read_u64(&chunk_payload)),
812            22 => chunks.set_ethernet_type(NetworkEndian::read_u16(&chunk_payload)),
813            23 => chunks.set_tcp_flag(chunk_payload[0]),
814            24 => chunks.set_ip_tos(chunk_payload[0]),
815            32 => chunks.set_mos_value(NetworkEndian::read_u16(&chunk_payload)),
816            33 => chunks.set_rfactor(NetworkEndian::read_u16(&chunk_payload)),
817            34 => chunks
818                .set_geo_location(String::from_utf8(chunk_payload.to_vec()).unwrap_or_default()),
819            35 => chunks.set_jitter(NetworkEndian::read_u32(&chunk_payload)),
820            36 => chunks.set_translation_type(
821                String::from_utf8(chunk_payload.to_vec()).unwrap_or_default(),
822            ),
823            37 => chunks.set_payload_json_keys(
824                String::from_utf8(chunk_payload.to_vec()).unwrap_or_default(),
825            ),
826            38 => chunks
827                .set_tags_values(String::from_utf8(chunk_payload.to_vec()).unwrap_or_default()),
828            39 => chunks
829                .set_type_of_tag(String::from_utf8(chunk_payload.to_vec()).unwrap_or_default()),
830            _ => &mut chunks,
831        };
832
833        current_byte += chunk_len;
834        trace!("Chunk Data Length: {}", &current_byte);
835    }
836    trace!("Parse HEPV3/EEPV3 Completed.");
837
838    if chunks.packet_payload.len() > 2 {
839        Ok(chunks)
840    } else {
841        Err(())
842    }
843}
844
845
846#[cfg(test)]
847mod tests {
848
849    #[test]
850    fn hep() {
851        assert_eq!(true, true)
852    }
853
854    #[test]
855    fn parse_hep_version_1() {
856        let packet = &[
857            1, 82, 69, 71, 73, 83, 84, 69, 82, 32, 115, 105, 112,
858            58, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 48, 48, 32, 83, 73, 80, 47, 50,
859            46, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32,
860            49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49, 58, 53, 48, 54, 48, 59, 98,
861            114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 46, 51, 76, 106, 69, 126, 83,
862            97, 106, 70, 59, 114, 112, 111, 114, 116, 13, 10, 70, 114, 111, 109, 58, 32, 60, 115,
863            105, 112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49,
864            48, 48, 62, 59, 116, 97, 103, 61, 67, 88, 76, 112, 109, 106, 74, 120, 77, 13, 10, 84,
865            111, 58, 32, 115, 105, 112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49,
866            54, 53, 46, 49, 48, 48, 13, 10, 67, 83, 101, 113, 58, 32, 50, 48, 32, 82, 69, 71, 73,
867            83, 84, 69, 82, 13, 10, 67, 97, 108, 108, 45, 73, 68, 58, 32, 71, 119, 67, 103, 48, 85,
868            100, 88, 49, 98, 13, 10, 77, 97, 120, 45, 70, 111, 114, 119, 97, 114, 100, 115, 58, 32,
869            55, 48, 13, 10, 83, 117, 112, 112, 111, 114, 116, 101, 100, 58, 32, 111, 117, 116, 98,
870            111, 117, 110, 100, 13, 10, 65, 99, 99, 101, 112, 116, 58, 32, 97, 112, 112, 108, 105,
871            99, 97, 116, 105, 111, 110, 47, 115, 100, 112, 44, 32, 116, 101, 120, 116, 47, 112,
872            108, 97, 105, 110, 44, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 118,
873            110, 100, 46, 103, 115, 109, 97, 46, 114, 99, 115, 45, 102, 116, 45, 104, 116, 116,
874            112, 43, 120, 109, 108, 13, 10, 67, 111, 110, 116, 97, 99, 116, 58, 32, 60, 115, 105,
875            112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49,
876            62, 59, 43, 115, 105, 112, 46, 105, 110, 115, 116, 97, 110, 99, 101, 61, 34, 60, 117,
877            114, 110, 58, 117, 117, 105, 100, 58, 54, 102, 98, 98, 102, 101, 48, 51, 45, 54, 99,
878            54, 57, 45, 52, 101, 50, 99, 45, 57, 99, 51, 97, 45, 57, 52, 49, 54, 52, 57, 54, 56,
879            99, 54, 97, 48, 62, 34, 13, 10, 69, 120, 112, 105, 114, 101, 115, 58, 32, 51, 54, 48,
880            48, 13, 10, 85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 76, 105, 110, 112,
881            104, 111, 110, 101, 47, 51, 46, 56, 46, 49, 32, 40, 98, 101, 108, 108, 101, 45, 115,
882            105, 112, 47, 49, 46, 52, 46, 48, 41, 13, 10, 13, 10,
883        ];
884
885        use super::*;
886
887        let mut check = Chunk::new();
888        check.set_packet_payload("REGISTER sip:169.254.165.100 SIP/2.0\r\nVia: SIP/2.0/UDP 169.254.165.11:5060;branch=z9hG4bK.3LjE~SajF;rport\r\nFrom: <sip:1000@169.254.165.100>;tag=CXLpmjJxM\r\nTo: sip:1000@169.254.165.100\r\nCSeq: 20 REGISTER\r\nCall-ID: GwCg0UdX1b\r\nMax-Forwards: 70\r\nSupported: outbound\r\nAccept: application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml\r\nContact: <sip:1000@169.254.165.11>;+sip.instance=\"<urn:uuid:6fbbfe03-6c69-4e2c-9c3a-94164968c6a0>\"\r\nExpires: 3600\r\nUser-Agent: Linphone/3.8.1 (belle-sip/1.4.0)\r\n\r\n".parse().unwrap());
889
890        assert_eq!(parse_hep_v1(packet).unwrap(), check);
891    }
892
893    #[test]
894    fn parse_hep_version_2() {
895        let packet = &[
896            2, 28, 2, 17, 19, 196, 19, 196, 169, 254, 165, 11, 169, 254, 165, 100, 113, 223, 164,
897            96, 51, 111, 3, 0, 255, 255, 0, 0, 82, 69, 71, 73, 83, 84, 69, 82, 32, 115, 105, 112,
898            58, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 48, 48, 32, 83, 73, 80, 47, 50,
899            46, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32,
900            49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49, 58, 53, 48, 54, 48, 59, 98,
901            114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 46, 51, 76, 106, 69, 126, 83,
902            97, 106, 70, 59, 114, 112, 111, 114, 116, 13, 10, 70, 114, 111, 109, 58, 32, 60, 115,
903            105, 112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49,
904            48, 48, 62, 59, 116, 97, 103, 61, 67, 88, 76, 112, 109, 106, 74, 120, 77, 13, 10, 84,
905            111, 58, 32, 115, 105, 112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49,
906            54, 53, 46, 49, 48, 48, 13, 10, 67, 83, 101, 113, 58, 32, 50, 48, 32, 82, 69, 71, 73,
907            83, 84, 69, 82, 13, 10, 67, 97, 108, 108, 45, 73, 68, 58, 32, 71, 119, 67, 103, 48, 85,
908            100, 88, 49, 98, 13, 10, 77, 97, 120, 45, 70, 111, 114, 119, 97, 114, 100, 115, 58, 32,
909            55, 48, 13, 10, 83, 117, 112, 112, 111, 114, 116, 101, 100, 58, 32, 111, 117, 116, 98,
910            111, 117, 110, 100, 13, 10, 65, 99, 99, 101, 112, 116, 58, 32, 97, 112, 112, 108, 105,
911            99, 97, 116, 105, 111, 110, 47, 115, 100, 112, 44, 32, 116, 101, 120, 116, 47, 112,
912            108, 97, 105, 110, 44, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 118,
913            110, 100, 46, 103, 115, 109, 97, 46, 114, 99, 115, 45, 102, 116, 45, 104, 116, 116,
914            112, 43, 120, 109, 108, 13, 10, 67, 111, 110, 116, 97, 99, 116, 58, 32, 60, 115, 105,
915            112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49,
916            62, 59, 43, 115, 105, 112, 46, 105, 110, 115, 116, 97, 110, 99, 101, 61, 34, 60, 117,
917            114, 110, 58, 117, 117, 105, 100, 58, 54, 102, 98, 98, 102, 101, 48, 51, 45, 54, 99,
918            54, 57, 45, 52, 101, 50, 99, 45, 57, 99, 51, 97, 45, 57, 52, 49, 54, 52, 57, 54, 56,
919            99, 54, 97, 48, 62, 34, 13, 10, 69, 120, 112, 105, 114, 101, 115, 58, 32, 51, 54, 48,
920            48, 13, 10, 85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 76, 105, 110, 112,
921            104, 111, 110, 101, 47, 51, 46, 56, 46, 49, 32, 40, 98, 101, 108, 108, 101, 45, 115,
922            105, 112, 47, 49, 46, 52, 46, 48, 41, 13, 10, 13, 10,
923        ];
924
925        use super::*;
926
927        let mut check = Chunk::new();
928        check.set_ip_protocol_family(2)
929             .set_proto_src_port(5060)
930             .set_proto_dst_port(5060)
931             .set_ipv4_src_address("169.254.165.11".parse().unwrap())
932             .set_ipv4_dst_address("169.254.165.100".parse().unwrap())
933             .set_capture_agent_id(65535)
934             .set_timestamp_seconds("1621417841".parse().unwrap())
935             .set_timestamp_micro_seconds_offset("225075".parse().unwrap())
936             .set_translation_type(String::from("UDP"))
937             .set_packet_payload("REGISTER sip:169.254.165.100 SIP/2.0\r\nVia: SIP/2.0/UDP 169.254.165.11:5060;branch=z9hG4bK.3LjE~SajF;rport\r\nFrom: <sip:1000@169.254.165.100>;tag=CXLpmjJxM\r\nTo: sip:1000@169.254.165.100\r\nCSeq: 20 REGISTER\r\nCall-ID: GwCg0UdX1b\r\nMax-Forwards: 70\r\nSupported: outbound\r\nAccept: application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml\r\nContact: <sip:1000@169.254.165.11>;+sip.instance=\"<urn:uuid:6fbbfe03-6c69-4e2c-9c3a-94164968c6a0>\"\r\nExpires: 3600\r\nUser-Agent: Linphone/3.8.1 (belle-sip/1.4.0)\r\n\r\n".parse().unwrap());
938
939        assert_eq!(parse_hep_v2(packet).unwrap(), check);
940    }
941
942    #[test]
943    fn parse_hep_version_3() {
944        let packet = &[
945            72, 69, 80, 51, 2, 89, 0, 0, 0, 1, 0, 7, 2, 0, 0, 0, 2, 0, 7, 17, 0, 0, 0, 7, 0, 8, 19,
946            196, 0, 0, 0, 8, 0, 8, 19, 196, 0, 0, 0, 9, 0, 10, 96, 163, 125, 225, 0, 0, 0, 10, 0,
947            10, 0, 12, 37, 96, 0, 0, 0, 11, 0, 7, 1, 0, 0, 0, 12, 0, 10, 0, 0, 0, 100, 0, 0, 0, 3,
948            0, 10, 169, 254, 165, 11, 0, 0, 0, 4, 0, 10, 169, 254, 165, 100, 0, 0, 0, 15, 1, 252,
949            82, 69, 71, 73, 83, 84, 69, 82, 32, 115, 105, 112, 58, 49, 54, 57, 46, 50, 53, 52, 46,
950            49, 54, 53, 46, 49, 48, 48, 32, 83, 73, 80, 47, 50, 46, 48, 13, 10, 86, 105, 97, 58,
951            32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 49, 54, 57, 46, 50, 53, 52, 46, 49,
952            54, 53, 46, 49, 49, 58, 53, 48, 54, 48, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57,
953            104, 71, 52, 98, 75, 46, 83, 122, 118, 80, 120, 103, 80, 76, 98, 59, 114, 112, 111,
954            114, 116, 13, 10, 70, 114, 111, 109, 58, 32, 60, 115, 105, 112, 58, 49, 48, 48, 48, 64,
955            49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 48, 48, 62, 59, 116, 97, 103, 61,
956            116, 78, 76, 84, 55, 87, 69, 114, 80, 13, 10, 84, 111, 58, 32, 115, 105, 112, 58, 49,
957            48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 48, 48, 13, 10, 67,
958            83, 101, 113, 58, 32, 50, 48, 32, 82, 69, 71, 73, 83, 84, 69, 82, 13, 10, 67, 97, 108,
959            108, 45, 73, 68, 58, 32, 101, 71, 66, 55, 97, 103, 98, 118, 69, 73, 13, 10, 77, 97,
960            120, 45, 70, 111, 114, 119, 97, 114, 100, 115, 58, 32, 55, 48, 13, 10, 83, 117, 112,
961            112, 111, 114, 116, 101, 100, 58, 32, 111, 117, 116, 98, 111, 117, 110, 100, 13, 10,
962            65, 99, 99, 101, 112, 116, 58, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110,
963            47, 115, 100, 112, 44, 32, 116, 101, 120, 116, 47, 112, 108, 97, 105, 110, 44, 32, 97,
964            112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 118, 110, 100, 46, 103, 115, 109,
965            97, 46, 114, 99, 115, 45, 102, 116, 45, 104, 116, 116, 112, 43, 120, 109, 108, 13, 10,
966            67, 111, 110, 116, 97, 99, 116, 58, 32, 60, 115, 105, 112, 58, 49, 48, 48, 48, 64, 49,
967            54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49, 62, 59, 43, 115, 105, 112, 46, 105,
968            110, 115, 116, 97, 110, 99, 101, 61, 34, 60, 117, 114, 110, 58, 117, 117, 105, 100, 58,
969            54, 102, 98, 98, 102, 101, 48, 51, 45, 54, 99, 54, 57, 45, 52, 101, 50, 99, 45, 57, 99,
970            51, 97, 45, 57, 52, 49, 54, 52, 57, 54, 56, 99, 54, 97, 48, 62, 34, 13, 10, 69, 120,
971            112, 105, 114, 101, 115, 58, 32, 51, 54, 48, 48, 13, 10, 85, 115, 101, 114, 45, 65,
972            103, 101, 110, 116, 58, 32, 76, 105, 110, 112, 104, 111, 110, 101, 47, 51, 46, 56, 46,
973            49, 32, 40, 98, 101, 108, 108, 101, 45, 115, 105, 112, 47, 49, 46, 52, 46, 48, 41, 13,
974            10, 13, 10,
975        ];
976
977        use super::*;
978
979        let mut check = Chunk::new();
980        check.set_ip_protocol_family(2)
981             .set_ip_protocol_id(17)
982             .set_proto_src_port(5060)
983             .set_proto_dst_port(5060)
984             .set_timestamp_seconds(1621327329)
985             .set_timestamp_micro_seconds_offset(796000)
986             .set_proto_type(CapProtoType::Sip)
987             .set_capture_agent_id(100)
988             .set_ipv4_src_address("169.254.165.11".parse().unwrap())
989             .set_ipv4_dst_address("169.254.165.100".parse().unwrap())
990             .set_packet_payload("REGISTER sip:169.254.165.100 SIP/2.0\r\nVia: SIP/2.0/UDP 169.254.165.11:5060;branch=z9hG4bK.SzvPxgPLb;rport\r\nFrom: <sip:1000@169.254.165.100>;tag=tNLT7WErP\r\nTo: sip:1000@169.254.165.100\r\nCSeq: 20 REGISTER\r\nCall-ID: eGB7agbvEI\r\nMax-Forwards: 70\r\nSupported: outbound\r\nAccept: application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml\r\nContact: <sip:1000@169.254.165.11>;+sip.instance=\"<urn:uuid:6fbbfe03-6c69-4e2c-9c3a-94164968c6a0>\"\r\nExpires: 3600\r\nUser-Agent: Linphone/3.8.1 (belle-sip/1.4.0)\r\n\r\n".parse().unwrap());
991
992        assert_eq!(parse_hep_v3(packet).unwrap(), check)
993    }
994
995    #[test]
996    fn parse_packet_version_1() {
997        let packet = &[
998            1, 82, 69, 71, 73, 83, 84, 69, 82, 32, 115, 105, 112,
999            58, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 48, 48, 32, 83, 73, 80, 47, 50,
1000            46, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32,
1001            49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49, 58, 53, 48, 54, 48, 59, 98,
1002            114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 46, 51, 76, 106, 69, 126, 83,
1003            97, 106, 70, 59, 114, 112, 111, 114, 116, 13, 10, 70, 114, 111, 109, 58, 32, 60, 115,
1004            105, 112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49,
1005            48, 48, 62, 59, 116, 97, 103, 61, 67, 88, 76, 112, 109, 106, 74, 120, 77, 13, 10, 84,
1006            111, 58, 32, 115, 105, 112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49,
1007            54, 53, 46, 49, 48, 48, 13, 10, 67, 83, 101, 113, 58, 32, 50, 48, 32, 82, 69, 71, 73,
1008            83, 84, 69, 82, 13, 10, 67, 97, 108, 108, 45, 73, 68, 58, 32, 71, 119, 67, 103, 48, 85,
1009            100, 88, 49, 98, 13, 10, 77, 97, 120, 45, 70, 111, 114, 119, 97, 114, 100, 115, 58, 32,
1010            55, 48, 13, 10, 83, 117, 112, 112, 111, 114, 116, 101, 100, 58, 32, 111, 117, 116, 98,
1011            111, 117, 110, 100, 13, 10, 65, 99, 99, 101, 112, 116, 58, 32, 97, 112, 112, 108, 105,
1012            99, 97, 116, 105, 111, 110, 47, 115, 100, 112, 44, 32, 116, 101, 120, 116, 47, 112,
1013            108, 97, 105, 110, 44, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 118,
1014            110, 100, 46, 103, 115, 109, 97, 46, 114, 99, 115, 45, 102, 116, 45, 104, 116, 116,
1015            112, 43, 120, 109, 108, 13, 10, 67, 111, 110, 116, 97, 99, 116, 58, 32, 60, 115, 105,
1016            112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49,
1017            62, 59, 43, 115, 105, 112, 46, 105, 110, 115, 116, 97, 110, 99, 101, 61, 34, 60, 117,
1018            114, 110, 58, 117, 117, 105, 100, 58, 54, 102, 98, 98, 102, 101, 48, 51, 45, 54, 99,
1019            54, 57, 45, 52, 101, 50, 99, 45, 57, 99, 51, 97, 45, 57, 52, 49, 54, 52, 57, 54, 56,
1020            99, 54, 97, 48, 62, 34, 13, 10, 69, 120, 112, 105, 114, 101, 115, 58, 32, 51, 54, 48,
1021            48, 13, 10, 85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 76, 105, 110, 112,
1022            104, 111, 110, 101, 47, 51, 46, 56, 46, 49, 32, 40, 98, 101, 108, 108, 101, 45, 115,
1023            105, 112, 47, 49, 46, 52, 46, 48, 41, 13, 10, 13, 10,
1024        ];
1025
1026        use super::*;
1027
1028        let mut check = Chunk::new();
1029        check.set_packet_payload("REGISTER sip:169.254.165.100 SIP/2.0\r\nVia: SIP/2.0/UDP 169.254.165.11:5060;branch=z9hG4bK.3LjE~SajF;rport\r\nFrom: <sip:1000@169.254.165.100>;tag=CXLpmjJxM\r\nTo: sip:1000@169.254.165.100\r\nCSeq: 20 REGISTER\r\nCall-ID: GwCg0UdX1b\r\nMax-Forwards: 70\r\nSupported: outbound\r\nAccept: application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml\r\nContact: <sip:1000@169.254.165.11>;+sip.instance=\"<urn:uuid:6fbbfe03-6c69-4e2c-9c3a-94164968c6a0>\"\r\nExpires: 3600\r\nUser-Agent: Linphone/3.8.1 (belle-sip/1.4.0)\r\n\r\n".parse().unwrap());
1030
1031        assert_eq!(parse_packet(packet).unwrap(), check);
1032    }
1033
1034    #[test]
1035    fn parse_packet_version_2() {
1036        let packet = &[
1037            2, 28, 2, 17, 19, 196, 19, 196, 169, 254, 165, 11, 169, 254, 165, 100, 113, 223, 164,
1038            96, 51, 111, 3, 0, 255, 255, 0, 0, 82, 69, 71, 73, 83, 84, 69, 82, 32, 115, 105, 112,
1039            58, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 48, 48, 32, 83, 73, 80, 47, 50,
1040            46, 48, 13, 10, 86, 105, 97, 58, 32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32,
1041            49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49, 58, 53, 48, 54, 48, 59, 98,
1042            114, 97, 110, 99, 104, 61, 122, 57, 104, 71, 52, 98, 75, 46, 51, 76, 106, 69, 126, 83,
1043            97, 106, 70, 59, 114, 112, 111, 114, 116, 13, 10, 70, 114, 111, 109, 58, 32, 60, 115,
1044            105, 112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49,
1045            48, 48, 62, 59, 116, 97, 103, 61, 67, 88, 76, 112, 109, 106, 74, 120, 77, 13, 10, 84,
1046            111, 58, 32, 115, 105, 112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49,
1047            54, 53, 46, 49, 48, 48, 13, 10, 67, 83, 101, 113, 58, 32, 50, 48, 32, 82, 69, 71, 73,
1048            83, 84, 69, 82, 13, 10, 67, 97, 108, 108, 45, 73, 68, 58, 32, 71, 119, 67, 103, 48, 85,
1049            100, 88, 49, 98, 13, 10, 77, 97, 120, 45, 70, 111, 114, 119, 97, 114, 100, 115, 58, 32,
1050            55, 48, 13, 10, 83, 117, 112, 112, 111, 114, 116, 101, 100, 58, 32, 111, 117, 116, 98,
1051            111, 117, 110, 100, 13, 10, 65, 99, 99, 101, 112, 116, 58, 32, 97, 112, 112, 108, 105,
1052            99, 97, 116, 105, 111, 110, 47, 115, 100, 112, 44, 32, 116, 101, 120, 116, 47, 112,
1053            108, 97, 105, 110, 44, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 118,
1054            110, 100, 46, 103, 115, 109, 97, 46, 114, 99, 115, 45, 102, 116, 45, 104, 116, 116,
1055            112, 43, 120, 109, 108, 13, 10, 67, 111, 110, 116, 97, 99, 116, 58, 32, 60, 115, 105,
1056            112, 58, 49, 48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49,
1057            62, 59, 43, 115, 105, 112, 46, 105, 110, 115, 116, 97, 110, 99, 101, 61, 34, 60, 117,
1058            114, 110, 58, 117, 117, 105, 100, 58, 54, 102, 98, 98, 102, 101, 48, 51, 45, 54, 99,
1059            54, 57, 45, 52, 101, 50, 99, 45, 57, 99, 51, 97, 45, 57, 52, 49, 54, 52, 57, 54, 56,
1060            99, 54, 97, 48, 62, 34, 13, 10, 69, 120, 112, 105, 114, 101, 115, 58, 32, 51, 54, 48,
1061            48, 13, 10, 85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 76, 105, 110, 112,
1062            104, 111, 110, 101, 47, 51, 46, 56, 46, 49, 32, 40, 98, 101, 108, 108, 101, 45, 115,
1063            105, 112, 47, 49, 46, 52, 46, 48, 41, 13, 10, 13, 10,
1064        ];
1065
1066        use super::*;
1067
1068        let mut check = Chunk::new();
1069        check.set_ip_protocol_family(2)
1070             .set_proto_src_port(5060)
1071             .set_proto_dst_port(5060)
1072             .set_ipv4_src_address("169.254.165.11".parse().unwrap())
1073             .set_ipv4_dst_address("169.254.165.100".parse().unwrap())
1074             .set_capture_agent_id(65535)
1075             .set_timestamp_seconds("1621417841".parse().unwrap())
1076             .set_timestamp_micro_seconds_offset("225075".parse().unwrap())
1077             .set_translation_type(String::from("UDP"))
1078             .set_packet_payload("REGISTER sip:169.254.165.100 SIP/2.0\r\nVia: SIP/2.0/UDP 169.254.165.11:5060;branch=z9hG4bK.3LjE~SajF;rport\r\nFrom: <sip:1000@169.254.165.100>;tag=CXLpmjJxM\r\nTo: sip:1000@169.254.165.100\r\nCSeq: 20 REGISTER\r\nCall-ID: GwCg0UdX1b\r\nMax-Forwards: 70\r\nSupported: outbound\r\nAccept: application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml\r\nContact: <sip:1000@169.254.165.11>;+sip.instance=\"<urn:uuid:6fbbfe03-6c69-4e2c-9c3a-94164968c6a0>\"\r\nExpires: 3600\r\nUser-Agent: Linphone/3.8.1 (belle-sip/1.4.0)\r\n\r\n".parse().unwrap());
1079
1080        assert_eq!(parse_packet(packet).unwrap(), check);
1081    }
1082
1083    #[test]
1084    fn parse_packet_version_3() {
1085        let packet = &[
1086            72, 69, 80, 51, 2, 89, 0, 0, 0, 1, 0, 7, 2, 0, 0, 0, 2, 0, 7, 17, 0, 0, 0, 7, 0, 8, 19,
1087            196, 0, 0, 0, 8, 0, 8, 19, 196, 0, 0, 0, 9, 0, 10, 96, 163, 125, 225, 0, 0, 0, 10, 0,
1088            10, 0, 12, 37, 96, 0, 0, 0, 11, 0, 7, 1, 0, 0, 0, 12, 0, 10, 0, 0, 0, 100, 0, 0, 0, 3,
1089            0, 10, 169, 254, 165, 11, 0, 0, 0, 4, 0, 10, 169, 254, 165, 100, 0, 0, 0, 15, 1, 252,
1090            82, 69, 71, 73, 83, 84, 69, 82, 32, 115, 105, 112, 58, 49, 54, 57, 46, 50, 53, 52, 46,
1091            49, 54, 53, 46, 49, 48, 48, 32, 83, 73, 80, 47, 50, 46, 48, 13, 10, 86, 105, 97, 58,
1092            32, 83, 73, 80, 47, 50, 46, 48, 47, 85, 68, 80, 32, 49, 54, 57, 46, 50, 53, 52, 46, 49,
1093            54, 53, 46, 49, 49, 58, 53, 48, 54, 48, 59, 98, 114, 97, 110, 99, 104, 61, 122, 57,
1094            104, 71, 52, 98, 75, 46, 83, 122, 118, 80, 120, 103, 80, 76, 98, 59, 114, 112, 111,
1095            114, 116, 13, 10, 70, 114, 111, 109, 58, 32, 60, 115, 105, 112, 58, 49, 48, 48, 48, 64,
1096            49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 48, 48, 62, 59, 116, 97, 103, 61,
1097            116, 78, 76, 84, 55, 87, 69, 114, 80, 13, 10, 84, 111, 58, 32, 115, 105, 112, 58, 49,
1098            48, 48, 48, 64, 49, 54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 48, 48, 13, 10, 67,
1099            83, 101, 113, 58, 32, 50, 48, 32, 82, 69, 71, 73, 83, 84, 69, 82, 13, 10, 67, 97, 108,
1100            108, 45, 73, 68, 58, 32, 101, 71, 66, 55, 97, 103, 98, 118, 69, 73, 13, 10, 77, 97,
1101            120, 45, 70, 111, 114, 119, 97, 114, 100, 115, 58, 32, 55, 48, 13, 10, 83, 117, 112,
1102            112, 111, 114, 116, 101, 100, 58, 32, 111, 117, 116, 98, 111, 117, 110, 100, 13, 10,
1103            65, 99, 99, 101, 112, 116, 58, 32, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110,
1104            47, 115, 100, 112, 44, 32, 116, 101, 120, 116, 47, 112, 108, 97, 105, 110, 44, 32, 97,
1105            112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 118, 110, 100, 46, 103, 115, 109,
1106            97, 46, 114, 99, 115, 45, 102, 116, 45, 104, 116, 116, 112, 43, 120, 109, 108, 13, 10,
1107            67, 111, 110, 116, 97, 99, 116, 58, 32, 60, 115, 105, 112, 58, 49, 48, 48, 48, 64, 49,
1108            54, 57, 46, 50, 53, 52, 46, 49, 54, 53, 46, 49, 49, 62, 59, 43, 115, 105, 112, 46, 105,
1109            110, 115, 116, 97, 110, 99, 101, 61, 34, 60, 117, 114, 110, 58, 117, 117, 105, 100, 58,
1110            54, 102, 98, 98, 102, 101, 48, 51, 45, 54, 99, 54, 57, 45, 52, 101, 50, 99, 45, 57, 99,
1111            51, 97, 45, 57, 52, 49, 54, 52, 57, 54, 56, 99, 54, 97, 48, 62, 34, 13, 10, 69, 120,
1112            112, 105, 114, 101, 115, 58, 32, 51, 54, 48, 48, 13, 10, 85, 115, 101, 114, 45, 65,
1113            103, 101, 110, 116, 58, 32, 76, 105, 110, 112, 104, 111, 110, 101, 47, 51, 46, 56, 46,
1114            49, 32, 40, 98, 101, 108, 108, 101, 45, 115, 105, 112, 47, 49, 46, 52, 46, 48, 41, 13,
1115            10, 13, 10,
1116        ];
1117
1118        use super::*;
1119
1120        let mut check = Chunk::new();
1121        check.set_ip_protocol_family(2)
1122             .set_ip_protocol_id(17)
1123             .set_proto_src_port(5060)
1124             .set_proto_dst_port(5060)
1125             .set_timestamp_seconds(1621327329)
1126             .set_timestamp_micro_seconds_offset(796000)
1127             .set_proto_type(CapProtoType::Sip)
1128             .set_capture_agent_id(100)
1129             .set_ipv4_src_address("169.254.165.11".parse().unwrap())
1130             .set_ipv4_dst_address("169.254.165.100".parse().unwrap())
1131             .set_packet_payload("REGISTER sip:169.254.165.100 SIP/2.0\r\nVia: SIP/2.0/UDP 169.254.165.11:5060;branch=z9hG4bK.SzvPxgPLb;rport\r\nFrom: <sip:1000@169.254.165.100>;tag=tNLT7WErP\r\nTo: sip:1000@169.254.165.100\r\nCSeq: 20 REGISTER\r\nCall-ID: eGB7agbvEI\r\nMax-Forwards: 70\r\nSupported: outbound\r\nAccept: application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml\r\nContact: <sip:1000@169.254.165.11>;+sip.instance=\"<urn:uuid:6fbbfe03-6c69-4e2c-9c3a-94164968c6a0>\"\r\nExpires: 3600\r\nUser-Agent: Linphone/3.8.1 (belle-sip/1.4.0)\r\n\r\n".parse().unwrap());
1132
1133        assert_eq!(parse_packet(packet).unwrap(), check)
1134    }
1135}