capture_packet_t * capture_eep_receive_v3() { struct hep_generic hg; hep_chunk_ip4_t src_ip4, dst_ip4; #ifdef USE_IPV6 hep_chunk_ip6_t src_ip6, dst_ip6; #endif hep_chunk_t payload_chunk; hep_chunk_t authkey_chunk; uint8_t family, proto; char password[100]; int password_len; unsigned char *payload = 0; unsigned int len, pos; char buffer[MAX_CAPTURE_LEN] ; //! Source and Destination Address char ip_src[ADDRESSLEN], ip_dst[ADDRESSLEN]; //! EEP client data struct sockaddr eep_client; socklen_t eep_client_len; //! Source and Destination Port u_short sport, dport; //! Packet header struct pcap_pkthdr header; //! New created packet pointer capture_packet_t *pkt; /* Receive EEP generic header */ if (recvfrom(eep_cfg.server_sock, buffer, MAX_CAPTURE_LEN, 0, &eep_client, &eep_client_len) == -1) return NULL; /* Copy initial bytes to EEP Generic header */ memcpy(&hg, buffer, sizeof(struct hep_generic)); /* header check */ if (memcmp(hg.header.id, "\x48\x45\x50\x33", 4) != 0) return NULL; /* IP proto */ family = hg.ip_family.data; /* Proto ID */ proto = hg.ip_proto.data; len = ntohs(hg.header.length) - sizeof(struct hep_generic); pos = sizeof(struct hep_generic); /* IPv4 */ if (family == AF_INET) { /* SRC IP */ memcpy(&src_ip4, (void*) buffer + pos, sizeof(struct hep_chunk_ip4)); inet_ntop(AF_INET, &src_ip4.data, ip_src, sizeof(ip_src)); pos += sizeof(struct hep_chunk_ip4); /* DST IP */ memcpy(&dst_ip4, (void*) buffer + pos, sizeof(struct hep_chunk_ip4)); inet_ntop(AF_INET, &dst_ip4.data, ip_dst, sizeof(ip_dst)); pos += sizeof(struct hep_chunk_ip4); } #ifdef USE_IPV6 /* IPv6 */ else if(family == AF_INET6) { /* SRC IPv6 */ memcpy(&src_ip6, (void*) buffer + pos, sizeof(struct hep_chunk_ip6)); inet_ntop(AF_INET6, &src_ip6.data, ip_src, sizeof(ip_src)); pos += sizeof(struct hep_chunk_ip6); /* DST IP */ memcpy(&src_ip6, (void*) buffer + pos, sizeof(struct hep_chunk_ip6)); inet_ntop(AF_INET6, &dst_ip6.data, ip_dst, sizeof(ip_dst)); pos += sizeof(struct hep_chunk_ip6); } #endif /* SRC PORT */ sport = ntohs(hg.src_port.data); /* DST PORT */ dport = ntohs(hg.dst_port.data); /* TIMESTAMP*/ header.ts.tv_sec = ntohl(hg.time_sec.data); header.ts.tv_usec = ntohl(hg.time_usec.data); /* Protocol TYPE */ /* Capture ID */ /* auth key */ if (eep_cfg.capt_srv_password != NULL) { memcpy(&authkey_chunk, (void*) buffer + pos, sizeof(authkey_chunk)); pos += sizeof(authkey_chunk); password_len = ntohs(authkey_chunk.length) - sizeof(authkey_chunk); memcpy(password, (void*) buffer + pos, password_len); pos += password_len; // Validate the password if (strncmp(password, eep_cfg.capt_srv_password, password_len) != 0) return NULL; } /* Payload */ memcpy(&payload_chunk, (void*) buffer + pos, sizeof(payload_chunk)); pos += sizeof(payload_chunk); // Calculate payload size header.caplen = header.len = ntohs(payload_chunk.length) - sizeof(payload_chunk); // Receive packet payload payload = sng_malloc(header.caplen); memcpy(payload, (void*) buffer + pos, header.caplen); // Create a new packet pkt = capture_packet_create((family == AF_INET)?4:6, proto, ip_src, ip_dst, 0); capture_packet_add_frame(pkt, &header, payload); capture_packet_set_transport_data(pkt, sport, dport, CAPTURE_PACKET_SIP_UDP); capture_packet_set_payload(pkt, payload, header.caplen); /* FREE */ sng_free(payload); return pkt; }
void parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packet) { // IP header data struct ip *ip4; #ifdef WITH_IPV6 // IPv6 header data struct ip6_hdr *ip6; #endif // IP version uint32_t ip_ver; // IP protocol uint8_t ip_proto; // IP header size uint32_t ip_hl = 0; // Fragment offset uint32_t ip_off = 0; // Fragmentation flag uint8_t ip_frag = 0; // Fragmentation offset uint16_t ip_frag_off = 0; //! Source Address char ip_src[ADDRESSLEN]; //! Destination Address char ip_dst[ADDRESSLEN]; // Source and Destination Ports u_short sport, dport; // UDP header data struct udphdr *udp; // UDP header size uint16_t udp_off; // TCP header data struct tcphdr *tcp; // TCP header size uint16_t tcp_off; // Packet payload data u_char *payload = NULL; // Packet payload size uint32_t size_payload = header->caplen; // SIP message transport int transport; // Media structure for RTP packets rtp_stream_t *stream; // Captured packet info capture_packet_t *pkt; // Ignore packets while capture is paused if (capture_is_paused()) return; // Check if we have reached capture limit if (capinfo.limit && sip_calls_count() >= capinfo.limit) return; // Get IP header ip4 = (struct ip *) (packet + capinfo.link_hl); #ifdef WITH_IPV6 // Get IPv6 header ip6 = (struct ip6_hdr *) (packet + capinfo.link_hl); #endif // Get IP version ip_ver = ip4->ip_v; switch (ip_ver) { case 4: ip_hl = ip4->ip_hl * 4; ip_proto = ip4->ip_p; ip_off = ntohs(ip4->ip_off); ip_frag = ip_off & (IP_MF | IP_OFFMASK); ip_frag_off = (ip_frag) ? (ip_off & IP_OFFMASK) * 8 : 0; // TODO Get fragment information inet_ntop(AF_INET, &ip4->ip_src, ip_src, sizeof(ip_src)); inet_ntop(AF_INET, &ip4->ip_dst, ip_dst, sizeof(ip_dst)); break; #ifdef WITH_IPV6 case 6: ip_hl = sizeof(struct ip6_hdr); ip_proto = ip6->ip6_nxt; if (ip_proto == IPPROTO_FRAGMENT) { struct ip6_frag *ip6f = (struct ip6_frag *) (ip6 + ip_hl); ip_frag_off = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK); // TODO Get fragment information } inet_ntop(AF_INET6, &ip6->ip6_src, ip_src, sizeof(ip_src)); inet_ntop(AF_INET6, &ip6->ip6_dst, ip_dst, sizeof(ip_dst)); break; #endif default: return; } // Only interested in UDP packets if (ip_proto == IPPROTO_UDP) { // Get UDP header udp = (struct udphdr *)((u_char *)(ip4) + ip_hl); udp_off = (ip_frag_off) ? 0 : sizeof(struct udphdr); // Set packet ports sport = htons(udp->uh_sport); dport = htons(udp->uh_dport); // Get actual payload size size_payload -= capinfo.link_hl + ip_hl + udp_off; #ifdef WITH_IPV6 if (ip_ver == 6) size_payload -= ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen); #endif // Get payload start payload = (u_char *) (udp) + udp_off; // Set transport UDP transport = CAPTURE_PACKET_SIP_UDP; } else if (ip_proto == IPPROTO_TCP) { // Get TCP header tcp = (struct tcphdr *)((u_char *)(ip4 )+ ip_hl); tcp_off = (ip_frag_off) ? 0 : (tcp->th_off * 4); // Set packet ports sport = htons(tcp->th_sport); dport = htons(tcp->th_dport); // Get actual payload size size_payload -= capinfo.link_hl + ip_hl + tcp_off; #ifdef WITH_IPV6 if (ip_ver == 6) size_payload -= ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen); #endif // Get payload start payload = (u_char *)(tcp) + tcp_off; // Set transport TCP transport = CAPTURE_PACKET_SIP_TCP; } else { // Not handled protocol return; } if ((int32_t)size_payload < 0) size_payload = 0; // Create a structure for this captured packet pkt = capture_packet_create(header, packet, header->caplen); capture_packet_set_type(pkt, transport); // For TCP and UDP, use payload directly from the packet capture_packet_set_payload(pkt, NULL, size_payload); #ifdef WITH_OPENSSL // Check if packet is TLS if (capinfo.keyfile && transport == CAPTURE_PACKET_SIP_TCP) tls_process_segment(ip4, pkt); #endif // Check if packet is WS or WSS if (transport == CAPTURE_PACKET_SIP_TCP) capture_ws_check_packet(pkt); // We're only interested in packets with payload if (capture_packet_get_payload_len(pkt)) { // Parse this header and payload if (sip_load_message(pkt, ip_src, sport, ip_dst, dport)) { // Store this packets in output file dump_packet(capinfo.pd, header, packet); return; } // Check if this packet belongs to a RTP stream // TODO Store this packet in the stream if ((stream = rtp_check_stream(pkt, ip_src, sport, ip_dst, dport))) { // We have an RTP packet! capture_packet_set_type(pkt, CAPTURE_PACKET_RTP); // Store this pacekt if capture rtp is enabled if (capinfo.rtp_capture) { call_add_rtp_packet(stream_get_call(stream), pkt); } else { capture_packet_destroy(pkt); } // Store this packets in output file dump_packet(capinfo.pd, header, packet); return; } } // Not an interesting packet ... capture_packet_destroy(pkt); }
capture_packet_t * capture_eep_receive_v2() { uint8_t family, proto; unsigned char *payload = 0; unsigned int pos; char buffer[MAX_CAPTURE_LEN] ; //! Source and Destination Address char ip_src[ADDRESSLEN], ip_dst[ADDRESSLEN]; //! Source and Destination Port u_short sport, dport; //! Packet header struct pcap_pkthdr header; //! New created packet pointer capture_packet_t *pkt; //! EEP client data struct sockaddr eep_client; socklen_t eep_client_len; struct hep_hdr hdr; struct hep_timehdr hep_time; struct hep_iphdr hep_ipheader; #ifdef USE_IPV6 struct hep_ip6hdr hep_ip6header; #endif // Initialize buffer memset(buffer, 0, MAX_CAPTURE_LEN); /* Receive EEP generic header */ if (recvfrom(eep_cfg.server_sock, buffer, MAX_CAPTURE_LEN, 0, &eep_client, &eep_client_len) == -1) return NULL; /* Copy initial bytes to HEPv2 header */ memcpy(&hdr, buffer, sizeof(struct hep_hdr)); // Check HEP version if (hdr.hp_v != 2) return NULL; /* IP proto */ family = hdr.hp_f; /* Proto ID */ proto = hdr.hp_p; pos = sizeof(struct hep_hdr); /* IPv4 */ if (family == AF_INET) { memcpy(&hep_ipheader, (void*) buffer + pos, sizeof(struct hep_iphdr)); inet_ntop(AF_INET, &hep_ipheader.hp_src, ip_src, sizeof(ip_src)); inet_ntop(AF_INET, &hep_ipheader.hp_dst, ip_dst, sizeof(ip_dst)); pos += sizeof(struct hep_iphdr); } #ifdef USE_IPV6 /* IPv6 */ else if(family == AF_INET6) { memcpy(&hep_ip6header, (void*) buffer + pos, sizeof(struct hep_ip6hdr)); inet_ntop(AF_INET6, &hep_ip6header.hp6_src, ip_src, sizeof(ip_src)); inet_ntop(AF_INET6, &hep_ip6header.hp6_dst, ip_dst, sizeof(ip_dst)); pos += sizeof(struct hep_ip6hdr); } #endif /* PORTS */ sport = ntohs(hdr.hp_sport); dport = ntohs(hdr.hp_dport); /* TIMESTAMP*/ memcpy(&hep_time, (void*) buffer + pos, sizeof(struct hep_timehdr)); pos += sizeof(struct hep_timehdr); header.ts.tv_sec = hep_time.tv_sec; header.ts.tv_usec = hep_time.tv_usec; /* Protocol TYPE */ /* Capture ID */ // Calculate payload size (Total size - headers size) header.caplen = header.len = ntohs(hdr.hp_l) - pos; // Copy packet payload payload = sng_malloc(header.caplen + 1); memcpy(payload, (void*) buffer + pos, header.caplen); // Create a new packet pkt = capture_packet_create((family == AF_INET) ? 4 : 6, proto, ip_src, ip_dst, 0); capture_packet_add_frame(pkt, &header, payload); capture_packet_set_transport_data(pkt, sport, dport, CAPTURE_PACKET_SIP_UDP); capture_packet_set_payload(pkt, payload, header.caplen); /* FREE */ sng_free(payload); return pkt; }