text: # -*- coding: utf-8 -*-
  
  """
  lswifi.libpcap
  ~~~~~~~~~~~~~~
  
  define libpcap class to help export to pcap
  """
  
  
  import logging
  
  # python imports
  import struct
  import time
  
  # app imports
  
  """ global header
  This header starts the libpcap file and will be followed by the first packet header:
  
  typedef struct pcap_hdr_s {
          guint32 magic_number;   /* magic number */
          guint16 version_major;  /* major version number */
          guint16 version_minor;  /* minor version number */
          gint32  thiszone;       /* GMT to local correction */
          guint32 sigfigs;        /* accuracy of timestamps */
          guint32 snaplen;        /* max length of captured packets, in octets */
          guint32 network;        /* data link type */
  } pcap_hdr_t;
  
  struct format characters
  
  | format | C Type             | Python type | standard size |
  | ------ | ------------------ | ----------- | ------------- |
  | H      | unsigned short     | integer     | 2             |
  | I      | unsigned int       | integer     | 4             |
  | i      | int                | integer     | 4             |
  | B      | u_int8_t           | integer     | 1             |
  | b      | signed char        | integer     | 1             |
  
  byte order, size, and alignment
  
  | character | byte order    | size     | alignment |
  | --------- | ------------- | -------- | --------- |
  | @         | native        | native   | native    |
  | =         | native        | standard | none      |
  | <         | little-endian | standard | none      |
  | >         | big-endian    | standard | none      |
  | !         | network       | standard | none      |
  
  """
  
  LIBPCAP_GLOBAL_HEADER_FMT = "@ I H H i I I I "
  
  LIBPCAP_MAGIC_NUMBER = 2712847316  # hex 0xA1B2C3D4
  LIBPCAP_VERSION_MAJOR = 2
  LIBPCAP_VERSION_MINOR = 4
  LIBPCAP_THISZONE = 0
  LIBPCAP_SIGFIGS = 0
  LIBPCAP_SNAPLEN = 65535
  LIBPCAP_LINK_LAYER_HEADER_TYPE = 127
  
  LIBPCAP_RECORD_HEADER_FMT = "@ I I I I"
  
  # LINK-LAYER HEADER TYPE VALUES:
  # LINKTYPE_ETHERNET             , 1  , IEEE 802.3 Ethernet
  # LINKTYPE_IEEE802_11           , 105, IEEE 802.11
  # LINKTYPE_IEEE802_11_RADIOTAP  , 127, Radiotap link-layer information followed by an 802.11 header
  
  """ Record (Packet) Header
  Each captured packet starts with (any byte alignment possible):
  
  typedef struct pcaprec_hdr_s {
          guint32 ts_sec;         /* timestamp seconds */
          guint32 ts_usec;        /* timestamp microseconds */
          guint32 incl_len;       /* number of octets of packet saved in file */
          guint32 orig_len;       /* actual length of packet */
  } pcaprec_hdr_t;
  """
  
  
  class LIBPCAP:
      def __init__(self, file, header_type=LIBPCAP_LINK_LAYER_HEADER_TYPE):
          log = logging.getLogger(__name__)
          self.pcap = open(file, "wb")
          self.pcap.write(
              struct.pack(
                  LIBPCAP_GLOBAL_HEADER_FMT,
                  LIBPCAP_MAGIC_NUMBER,
                  LIBPCAP_VERSION_MAJOR,
                  LIBPCAP_VERSION_MINOR,
                  LIBPCAP_THISZONE,
                  LIBPCAP_SIGFIGS,
                  LIBPCAP_SNAPLEN,
                  header_type,
              )
          )
          log.debug(f"[+] Header Type: {header_type}")
  
      def writelist(self, data=[]):
          for i in data:
              self.write(i)
          return
  
      def write(self, data):
          ts_sec, ts_usec = map(int, str(time.time()).split("."))
          length = len(data)
          self.pcap.write(
              struct.pack(LIBPCAP_RECORD_HEADER_FMT, ts_sec, ts_usec, length, length)
          )
          self.pcap.write(data)
  
      def close(self):
          self.pcap.close()
  
  
  """ radiotap header
  struct ieee80211_radiotap_header {
          u_int8_t        it_version;     /* set to 0 */
          u_int8_t        it_pad;
          u_int16_t       it_len;         /* entire length */
          u_int32_t       it_present;     /* fields present */
  } __attribute__((__packed__));
  """
  
  RADIOTAP_HEADER_FMT = "@ B B H I"
  
  RADIOTAP_VERSION = 0
  RADIOTAP_PAD = 0
  RADIOTAP_LEN = 0
  RADIOTAP_FIELDS_PRESENT = 0x0000  # fields are strictly ordered, must appear in the header in order they are specified here
  # Channel           (bit 3 (pos 4)) u16 freq, u16 flags, format I
  # Antenna signal    (bit 5 (pos 6)) 8-bit signed, format b
  # OFDM
  # 2 GHz spectrum
  # 5 GHz spectrum
  
  
  def set_bit(value, bit):
      return value | (1 << bit)
  
  
  RADIOTAP_FIELDS_PRESENT = set_bit(RADIOTAP_FIELDS_PRESENT, 3)
  RADIOTAP_FIELDS_PRESENT = set_bit(RADIOTAP_FIELDS_PRESENT, 5)
  RADIOTAP_HEADER_FMT = RADIOTAP_HEADER_FMT + "I b"
  
  
  class RADIOTAP:
      def __init__(self, channel, rssi):
          return struct.pack(RADIO)
  
  
  """ IEEE header
  TODO: fill in. 
  """
  
  
  class IEEE80211:
      pass
  