summaryrefslogtreecommitdiffstats
path: root/src/pcap.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/pcap.h')
-rw-r--r--src/pcap.h209
1 files changed, 209 insertions, 0 deletions
diff --git a/src/pcap.h b/src/pcap.h
new file mode 100644
index 0000000..26bef6a
--- /dev/null
+++ b/src/pcap.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2017-2024 OARC, Inc.
+ * Copyright (c) 2011-2017, IIS - The Internet Foundation in Sweden
+ * All rights reserved.
+ *
+ * This file is part of PacketQ.
+ *
+ * PacketQ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * PacketQ is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with PacketQ. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __packetq_pcap_h
+#define __packetq_pcap_h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <zlib.h>
+
+#include "segzip.h"
+#include "sql.h"
+
+namespace packetq {
+
+class Pcap_file {
+private:
+ Pcap_file& operator=(const Pcap_file& other);
+ Pcap_file(Pcap_file&& other) noexcept;
+ Pcap_file const& operator=(Pcap_file&& other);
+
+public:
+ static const bool TAKE_OVER_FP = true;
+
+ Pcap_file(FILE* fp, bool take_over_fp = false)
+ {
+ m_fp_owned = take_over_fp;
+ m_fp = fp;
+ m_reverse_order = false;
+ m_packetbuffer = 0;
+ m_packetbuffer_len = 0;
+ m_eof = false;
+ m_snapshot_length = 0;
+ m_link_layer_type = 0;
+ m_gzipped = false;
+ }
+ ~Pcap_file()
+ {
+ if (m_packetbuffer)
+ delete[] m_packetbuffer;
+ if (m_fp_owned)
+ fclose(m_fp);
+ }
+
+ bool get_header();
+
+ unsigned char* get_packet(int& len, int& s, int& us);
+
+ int get_int32()
+ {
+ int res = 0;
+ get_bytes((unsigned char*)&res, 4);
+ if (m_reverse_order) {
+ return flip32(res);
+ }
+ return res;
+ }
+ int get_int16()
+ {
+ short res = 0;
+ get_bytes((unsigned char*)&res, 2);
+ if (m_reverse_order) {
+ return flip16(res);
+ }
+ return res;
+ }
+ unsigned char* get_bytes(int count)
+ {
+ Buffer& buf = m_gzipped ? m_zipbuffer : m_filebuffer;
+ if (count < buf.m_buffer_len - buf.m_buffer_pos) {
+ unsigned char* ptr = &buf.m_buffer[buf.m_buffer_pos];
+ buf.m_buffer_pos += count;
+ return ptr;
+ }
+
+ unsigned char* bufp = get_pbuffer(count + 400);
+ int r = get_bytes(bufp, count);
+
+ if (r == count)
+ return bufp;
+ return 0;
+ }
+ int get_bytes(unsigned char* dst, int count)
+ {
+ Buffer& buf = m_gzipped ? m_zipbuffer : m_filebuffer;
+ if (count == 0)
+ return 0;
+
+ int bytes = 0;
+ while (count > 0) {
+ if (buf.m_buffer_len == buf.m_buffer_pos) {
+ buffread();
+ if (buf.m_buffer_len == 0) {
+ m_eof = true;
+ return bytes;
+ }
+ }
+ int n = (buf.m_buffer_len - buf.m_buffer_pos) > count ? count : buf.m_buffer_len - buf.m_buffer_pos;
+ for (int i = 0; i < n; i++) {
+ *dst++ = buf.m_buffer[buf.m_buffer_pos++];
+ }
+ bytes += n;
+ count -= n;
+ }
+ return bytes;
+ }
+ void buffread()
+ {
+ if (!m_fp)
+ throw Error("No file");
+
+ Buffer& buf = m_filebuffer;
+ if (buf.m_buffer_len == buf.m_buffer_pos) {
+ buf.m_buffer_len = (int)fread(buf.m_buffer, 1, buf.m_nextread, m_fp);
+ buf.m_buffer_pos = 0;
+ buf.m_nextread = sizeof(buf.m_buffer);
+ }
+ if (m_gzipped) {
+ if (m_zip.m_error || buf.m_buffer_len == buf.m_buffer_pos) {
+ m_zipbuffer.m_buffer_pos = m_zipbuffer.m_buffer_len = 0;
+ return;
+ }
+ if (m_zipbuffer.m_buffer_len == m_zipbuffer.m_buffer_pos)
+ m_zip.inflate(m_filebuffer, m_zipbuffer);
+ }
+ }
+ void set_gzipped()
+ {
+ m_gzipped = true;
+ m_filebuffer.m_buffer_pos = 0;
+ }
+ int flip16(unsigned short i)
+ {
+ unsigned int r = i & 0xff;
+ r <<= 8;
+ i >>= 8;
+ r |= i & 0xff;
+ return int(r);
+ }
+ int flip32(unsigned int i)
+ {
+ unsigned int r = i & 0xff;
+ r <<= 8;
+ i >>= 8;
+ r |= i & 0xff;
+ r <<= 8;
+ i >>= 8;
+ r |= i & 0xff;
+ r <<= 8;
+ i >>= 8;
+ r |= i & 0xff;
+ return int(r);
+ }
+
+ unsigned char* get_pbuffer(int len)
+ {
+ if (!m_packetbuffer || len >= m_packetbuffer_len) {
+ if (m_packetbuffer) {
+ delete[] m_packetbuffer;
+ m_packetbuffer = 0;
+ }
+ m_packetbuffer_len = len + 4096;
+ m_packetbuffer = new (std::nothrow) unsigned char[m_packetbuffer_len];
+ if (!m_packetbuffer)
+ m_packetbuffer_len = 0;
+ }
+ return m_packetbuffer;
+ }
+ bool get_eof() { return m_eof; }
+ int get_link_layer_type() { return m_link_layer_type; }
+
+private:
+ int m_snapshot_length;
+ int m_link_layer_type;
+ bool m_reverse_order;
+ bool m_eof;
+ bool m_gzipped;
+ FILE* m_fp;
+ bool m_fp_owned;
+
+ unsigned char* m_packetbuffer;
+ int m_packetbuffer_len;
+
+ Buffer m_filebuffer;
+ Buffer m_zipbuffer;
+ Zip m_zip;
+};
+
+} // namespace packetq
+
+#endif // __packetq_pcap_h