Back to index

natlog  0.91.0
pcappacket.h
Go to the documentation of this file.
00001 #ifndef INCLUDED_PCAPPACKET_
00002 #define INCLUDED_PCAPPACKET_
00003 
00004 #include <pcap.h>
00005 #include <bobcat/inetaddress>
00006 
00007 class PcapPacket
00008 {
00009     struct pcap_pkthdr const &d_hdr;    // struct timeval: see gettimeofday(2)
00010     u_char const *d_packet;             // the captured packet
00011 
00012     struct Ethernet_Header      // http://en.wikipedia.org/wiki/EtherType
00013     {
00014         u_char destMac[6];      // Destination host MAC address
00015         u_char srcMac[6];       // Source host MAC address
00016         u_short ether_type;     // IP? ARP? RARP? etc 
00017     };
00018 
00019     enum class IP_Fragment
00020     {
00021         RESERVED =          0x8000,
00022         DONT_FRAGMENT =     0x4000,
00023         MORE_FRAGMENTS =    0x2000,
00024         MASK =              0x1fff
00025     };
00026     struct IP_Header 
00027     {
00028         u_char versionHdrLength;    // version << 4 | header length >> 2 
00029         u_char tos;                 // type of service
00030         u_short length;             // total length 
00031         u_short identification;
00032         u_short fragmentOffset;
00033         u_char  timeToLive;
00034         u_char  protocol;
00035         u_short checkSum;
00036         struct in_addr sourceAddr;
00037         struct in_addr destAddr;
00038     };
00039 
00040     struct TCP_Header 
00041     {
00042         u_short sourcePort;
00043         u_short destPort;
00044         uint32_t sequenceNr;
00045         uint32_t ackNumber;
00046 
00047         u_char dataOffset;          // data offset, 
00048                                     // (((th)->th_offx2 & 0xf0) >> 4)
00049         u_char flags;
00050         u_short window;
00051         u_short checkSum;
00052         u_short urgentPtr;
00053     };
00054 
00055     enum Offsets                // offsets to the various headers
00056     {                           // the Ethernet header starts at `d_packet'
00057         ETHER_OFFSET =  0,       
00058         IP_OFFSET =     ETHER_OFFSET + sizeof(Ethernet_Header),
00059         TCP_OFFSET =    IP_OFFSET + sizeof(IP_Header),
00060         DATA_OFFSET =   TCP_OFFSET + sizeof(TCP_Header)
00061     };
00062 
00063     public:
00064         enum SizeofTCPheader
00065         {
00066             SIZEOF_ETHERNET_HEADER = IP_OFFSET,
00067             SIZEOF_TCP_HEADER = DATA_OFFSET
00068         };
00069 
00070         enum TCP_Flags
00071         {
00072             FIN  = 0x01,
00073             SYN  = 0x02,
00074             RST  = 0x04,
00075             PUSH = 0x08,
00076             ACK  = 0x10,
00077             URG  = 0x20,
00078             ECE  = 0x40,
00079             CWR  = 0x80,
00080             TCP_Flags_MASK = FIN | SYN | RST | ACK | URG | ECE | CWR
00081         };
00082         struct Address: public FBB::InetAddress
00083         {
00084             Address(struct in_addr const &addr, u_short port);
00085         };
00086 
00087         PcapPacket(struct pcap_pkthdr const &hdr, u_char const *packet);
00088 
00089         pcap_pkthdr const &timeval() const;
00090 
00091         time_t seconds() const;
00092         suseconds_t microSeconds() const;
00093 
00094         struct in_addr const &sourceAddr() const;
00095         struct in_addr const &destAddr() const;
00096 
00097         u_short sourcePort() const;
00098         u_short destPort() const;
00099   
00100         Address sourceIP() const;
00101         Address destIP() const;
00102 
00103         TCP_Flags flags() const;
00104         bool flags(u_char testFlags) const;
00105 
00106         uint32_t sequenceNr() const;
00107 
00108     private:
00109         template <typename Type>
00110         Type const &get() const;
00111 
00112         Address inetAddr(struct in_addr const &addr, u_short port) const;
00113 };
00114 
00115 template <>
00116 inline PcapPacket::IP_Header const &PcapPacket::get() const
00117 {
00118     return *reinterpret_cast<IP_Header const *>(d_packet + IP_OFFSET);
00119 }
00120 
00121 template <>
00122 inline PcapPacket::TCP_Header const &PcapPacket::get() const
00123 {
00124     return *reinterpret_cast<TCP_Header const *>(d_packet + TCP_OFFSET);
00125 }
00126 
00127 inline PcapPacket::TCP_Flags PcapPacket::flags() const
00128 {
00129     return static_cast<TCP_Flags>(get<TCP_Header>().flags);
00130 }
00131 
00132 inline PcapPacket::Address::Address(struct in_addr const &addr, u_short port)
00133 :
00134     FBB::InetAddress( sockaddr_in{0, port, addr} )
00135 {}
00136 
00137 inline bool PcapPacket::flags(u_char testFlags) const
00138 {
00139     return get<TCP_Header>().flags == testFlags;
00140 }
00141 
00142 inline pcap_pkthdr const &PcapPacket::timeval() const
00143 {
00144     return d_hdr;
00145 }
00146         
00147 inline time_t PcapPacket::seconds() const
00148 {
00149     return d_hdr.ts.tv_sec;
00150 }
00151         
00152 inline suseconds_t PcapPacket::microSeconds() const
00153 {
00154     return d_hdr.ts.tv_usec;
00155 }
00156 
00157 inline struct in_addr const &PcapPacket::sourceAddr() const
00158 {
00159     return get<IP_Header>().sourceAddr;
00160 }
00161 
00162 inline struct in_addr const &PcapPacket::destAddr() const
00163 {
00164     return get<IP_Header>().destAddr;
00165 }
00166 
00167 
00168 inline u_short PcapPacket::sourcePort() const
00169 {
00170     return get<TCP_Header>().sourcePort;
00171 }
00172 
00173 inline u_short PcapPacket::destPort() const
00174 {
00175     return get<TCP_Header>().destPort;
00176 }
00177 
00178 
00179 inline PcapPacket::Address PcapPacket::sourceIP() const
00180 {
00181     return 
00182         inetAddr(get<IP_Header>().sourceAddr, get<TCP_Header>().sourcePort);
00183 }
00184 
00185 inline PcapPacket::Address PcapPacket::destIP() const
00186 {
00187     return 
00188         inetAddr(get<IP_Header>().destAddr, get<TCP_Header>().destPort);
00189 }
00190 
00191 inline PcapPacket::Address PcapPacket::inetAddr(struct in_addr const &addr, 
00192                                                 u_short port) const
00193 {
00194     return Address(addr, port);
00195 }
00196 
00197 inline uint32_t PcapPacket::sequenceNr() const
00198 {
00199     return get<TCP_Header>().sequenceNr;
00200 }
00201 
00202         
00203 #endif
00204 
00205 
00206