/* * Paglo Crawler * Copyright (C) 2006-2008 Paglo Labs Inc. All rights reserved. * www.paglo.com * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ //--------------------------------------------------------------------------- #include #include #include #include "Packet.h" #include "ScanAgentUtils.h" #include "Debug.h" //--------------------------------------------------------------------------- /* Pass in contents of pcap_pkthdr struct and the packet data * We duplicate the fields int he struct and copy the data into our object * * NOTE: the caller should *NEVER* free the packet data (i.e., Pkt) -- libpcap manages that */ TPacket::TPacket(struct timeval *Ts, int CapLen, int Len, const unsigned char *Pkt) { Data = NULL; memcpy(&PcapHeader.ts, Ts, sizeof(struct timeval)); PcapHeader.caplen = CapLen; PcapHeader.len = Len; InitPacket(Pkt); } //--------------------------------------------------------------------------- TPacket::TPacket(const struct pcap_pkthdr *PktHdr, const unsigned char *Pkt) { Data = NULL; memcpy(&PcapHeader, PktHdr, sizeof(struct pcap_pkthdr)); InitPacket(Pkt); } //--------------------------------------------------------------------------- TPacket::~TPacket(void) { if (Data) { free((void *)Data); } } //--------------------------------------------------------------------------- void TPacket::InitPacket(const unsigned char *Pkt) { TEthHeader *EthHdr; TIPv4Header *IPv4Hdr; int ExpectedLen = sizeof(TEthHeader) + sizeof(TIPv4Header); IsSFlow = false; IPLength = 0; IPPayload = NULL; Payload = NULL; CDPPayload = NULL; Data = (const unsigned char *)malloc(sizeof(unsigned char) * PcapHeader.caplen); memcpy((void *)Data, (void *)Pkt, PcapHeader.caplen); /* * Data should always be padded out to the min frame size, but we'll do a * sanity check here just in case. */ if (PcapHeader.caplen < sizeof(TEthHeader)) { free((void *)Data); Data = NULL; throw runtime_error("packet is too short to contain an ethernet frame"); } EthHdr = (TEthHeader *)Data; SrcMac = TMacAddress(EthHdr->EthSource); DstMac = TMacAddress(EthHdr->EthDest); Proto = ntohs(EthHdr->EthProto); IPProto = 255; if(Proto == ETHER_IPV4 && PcapHeader.caplen > ExpectedLen) { IPv4Hdr = (TIPv4Header *)(Data + sizeof(TEthHeader)); SrcIP = TIPAddress(ntohl(IPv4Hdr->Source)); DstIP = TIPAddress(ntohl(IPv4Hdr->Dest)); IPPayload = Data + sizeof(TEthHeader) + IPv4Hdr->HeaderLen * 4; if (IPPayload > (Data + PcapHeader.caplen)) { IPPayload = NULL; return; } IPProto = IPv4Hdr->Protocol; IPLength = ntohs(IPv4Hdr->Length); if(IPProto == IPPROTO_TCP && PcapHeader.caplen >= ((IPPayload - Data) + sizeof(TTCPv4Header))) { TTCPv4Header *TCPHdr = (TTCPv4Header *)IPPayload; TCPFlags = TCPHdr->Flags; SrcPort = htons(TCPHdr->SourcePort); DestPort = htons(TCPHdr->DestPort); Payload = (unsigned char*)TCPHdr + TCPHdr->Offset * 4; } else if (IPProto == IPPROTO_UDP && PcapHeader.caplen >= ((IPPayload - Data) + sizeof(TUDPv4Header))) { TUDPv4Header *UDPHdr = (TUDPv4Header *)IPPayload; SrcPort = htons(UDPHdr->SourcePort); DestPort = htons(UDPHdr->DestPort); Payload = (unsigned char*)UDPHdr + sizeof(TUDPv4Header); } else if (IPProto == IPPROTO_ICMP && PcapHeader.caplen >= ((IPPayload - Data) + sizeof(TICMPHeader))) { TICMPHeader *ICMPHdr = (TICMPHeader *)IPPayload; ICMPType = ICMPHdr->Type; ICMPCode = ICMPHdr->Code; Payload = IPPayload + sizeof(TICMPHeader); } } else if (Proto <= ETHER_LLC){ TLLCHeader *LLCHdr = (TLLCHeader *)(Data + sizeof(TEthHeader)); if ((LLCHdr->DSAP == 0xAA || LLCHdr->DSAP == 0xAB) && (LLCHdr->SSAP == 0xAA || LLCHdr->SSAP == 0xAB)) { TSNAPHeader *SNAPHdr = (TSNAPHeader *)((unsigned char *)LLCHdr + sizeof(TLLCHeader)); if (memcmp(SNAPHdr->OrgCode, SNAP_ORG_CISCO, 3) == 0) { if (ntohs(SNAPHdr->PID) == SNAP_PID_CDP) { CDPPayload = (unsigned char *)SNAPHdr + sizeof(TSNAPHeader); } } } IPProto = -1; } else { IPProto = -1; } /* TODO: Add IPv6 support. */ } //--------------------------------------------------------------------------- string TPacket::ToHexString(void) { return HexDump(Data, PcapHeader.caplen); } //---------------------------------------------------------------------------