PacketParser.cpp
author Markus Bröker <mbroeker@largo.homelinux.org>
Tue, 02 Feb 2010 13:26:30 +0100
changeset 8 6097dc1fe2cf
parent 0 826dd5531eb0
permissions -rw-r--r--
perror is declared in cstdio

/*
 *  $Id: PacketParser.cpp 54 2008-01-10 00:24:52Z mbroeker $
 * $URL: http://localhost/svn/cpp/qMonitor/trunk/PacketParser.cpp $
 */

#include <PacketParser.h>
#include <iomanip>

PacketParser::PacketParser (int tm)
:PacketReader (tm)
{
    protocol = IPPROTO_IP;
    port = 0;
}

PacketParser::PacketParser (std::string filename)
:  PacketReader (filename)
{
    protocol = IPPROTO_IP;
    port = 0;
}

PacketParser::~PacketParser ()
{
}

std::string PacketParser::getProtocol (int i)
{
    proto = getprotobynumber (i);
    return ((proto != NULL) ? proto->p_name : "unknown");
}

std::string PacketParser::getPacket ()
{
    if (port != 0)
        if ((sport != port) && (dport != port))
            return "";

    return str;
}

void PacketParser::setPort (unsigned short p)
{
    port = p;
}

void PacketParser::setProtocol (int proto)
{
    protocol = proto;
}

std::string PacketParser::read ()
{
    std::ostringstream s;
    struct iphdr *iph;
    struct tcphdr *tcph;
    struct udphdr *udph;

    struct in_addr src;
    struct in_addr dst;

    int size = 0;

    uint i;

    str = PacketReader::read ();

    iph = (struct iphdr *)(str.c_str () + sizeof (struct ethhdr));

    switch (iph->protocol) {
    case IPPROTO_TCP:
        size = sizeof (tcphdr);
        break;
    case IPPROTO_UDP:
        size = sizeof (udphdr);
        break;
    case IPPROTO_ICMP:
        size = sizeof (icmphdr);
        break;
    case IPPROTO_IP:
        size += (sizeof (ethhdr) + sizeof (iphdr));
        break;
    default:
        size += (sizeof (ethhdr) + sizeof (iphdr));
    }

    src.s_addr = (iph->saddr);
    dst.s_addr = (iph->daddr);

    dhost = inet_ntoa (dst);
    shost = inet_ntoa (src);

    s.str () = "";

    if (protocol != iph->protocol) {
        switch (protocol) {
        case IPPROTO_IP:
            /*
             * filter the content later
             */
            break;

        case IPPROTO_RAW:
            for (i = size; i < str.length (); i++) {
                if (!isgraph (str[i]))
                    s << ".";
                else
                    s << str[i];
            }
            return s.str ();
            break;
        default:
            /*
             * discard packet
             */
            return s.str ();
        }
    }

    switch (iph->protocol) {
    case IPPROTO_IP:
        s << getProtocol (iph->protocol) << " " << std::setw (15) << shost << " ==> " << std::setw (15) << dhost;
        break;

    case IPPROTO_ICMP:
        s << getProtocol (iph->protocol) << " " << std::setw (15) << shost << " ==> " << std::setw (15) << dhost;

        break;

    case IPPROTO_TCP:
        tcph = (struct tcphdr *)(str.c_str () + sizeof (struct ethhdr) + sizeof (struct iphdr));

        sport = ntohs (tcph->source);
        dport = ntohs (tcph->dest);

        s << getProtocol (iph->protocol) << " "
            << std::setw (15) << shost << ":" << std::setw (5) << sport
            << " ==> " << std::setw (15) << dhost << ":" << std::setw (5) << dport;

        if (tcph->urg)
            s << (" urg ");
        if (tcph->ack) {
            s << (" ack ") << ntohl (tcph->ack_seq);
        }
        if (tcph->psh)
            s << (" psh ");
        if (tcph->rst)
            s << (" rst ");
        if (tcph->syn) {
            s << (" syn ") << ntohl (tcph->seq);
        }
        if (tcph->fin)
            s << (" fin ");

        break;

    case IPPROTO_UDP:
        udph = (struct udphdr *)(str.c_str () + sizeof (struct ethhdr) + sizeof (struct iphdr));

        sport = ntohs (udph->source);
        dport = ntohs (udph->dest);

        s << getProtocol (iph->protocol) << " "
            << std::setw (15) << shost << ":" << std::setw (5) << sport
            << " ==> " << std::setw (15) << dhost << ":" << std::setw (5) << dport;

        break;

    default:
        s << getProtocol (iph->protocol);
        break;
    }

    if (port != 0)
        if ((sport != port) && (dport != port))
            s.str ("");

    return (s.str ());
}