Logo Search packages:      
Sourcecode: tcpreplay version File versions

flowstate.c

/* $Id: flowstate.c 767 2004-10-06 12:48:49Z aturner $ */

/*
 * Copyright (c) 2001-2004 Aaron Turner.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the names of the copyright owners nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "flowreplay.h"
#include "flownode.h"
#include "tcpreplay.h"
#include "flowstate.h"
#include "err.h"

/*
 * determines the new state for a TCP flow based on 
 * the last known state and the current packet
 * returns the new state as well as setting it in the node
 */
u_int32_t
tcp_state(tcp_hdr_t * tcp_hdr, struct session_t *node)
{
    /* 
     * figure out the TCP state 
     */
    if (node->state == 0x0) {
        /*
         * We go here if this is the first packet in the 
         * in the TCP stream.  This could be a Syn or
         * if we're trying to pickup the state from mid-stream
         */

        /* = Syn, start of new flow */
        if (tcp_hdr->th_flags & TH_SYN) {
            node->state = TH_SYN;
            dbg(3, "Setting state: New -> Syn");
        }

        /* Anything matching after this point is a mid-stream pickup */

        /* + Ack */
        if (tcp_hdr->th_flags & TH_ACK) {
            node->state ^= TH_ACK;
            dbg(3, "Mid-stream state pickup: +Ack");
        }

        /* = Fin */
        if (tcp_hdr->th_flags & TH_FIN) {
            node->state = TH_FIN;
            dbg(3, "Mid-stream state pickup: Fin");
        }

        /* else, just close */
        if (!node->state) {
            node->state = TCP_CLOSE;
            dbg(3, "Mid-stream state pickup: Close");
        }

    }

    else if ((tcp_hdr->th_flags & TH_SYN) &&
             (tcp_hdr->th_flags & TH_ACK) && (node->state == TH_SYN)) {
        /* server sent SYN/ACK */
        node->state = TH_SYN | TH_ACK;
        dbg(4, "Setting state: Syn -> Syn/Ack");
    }

    else if ((tcp_hdr->th_flags & TH_ACK) &&
             (node->state & TH_SYN) && (node->state & TH_ACK)) {
        /* Client sent ACK when we're Syn/Ack */
        node->state = TH_ACK;
        dbg(4, "Setting state: Syn/Ack -> Ack");
    }

    /* someone sent us the FIN */
    else if (tcp_hdr->th_flags & TH_FIN) {
        if (node->state == TH_ACK) {
            /* first FIN */
            node->state = TH_FIN;
            dbg(4, "Setting state: Ack -> Fin");
        }
        else {
            /* second FIN, close connection */
            dbg(4, "Setting state: Fin -> Close");
            node->state = TCP_CLOSE;
        }
    }

    /* Reset */
    else if (tcp_hdr->th_flags & TH_RST) {
        dbg(4, "Reset packet!  Setting state: Rst");
        node->state = TCP_CLOSE;
    }

    else if ((node->state == TH_ACK) && (tcp_hdr->th_flags & TH_ACK)) {
        dbg(3, "No state change: Ack");
    }

    else {
        warnx("Unable to determine TCP state for node 0x%llx",
              pkeygen(node->key));
    }
    return node->state;
}

Generated by  Doxygen 1.6.0   Back to index