File: flowbuff.c

package info (click to toggle)
tcpreplay 2.3.3-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 2,760 kB
  • ctags: 992
  • sloc: ansic: 7,343; sh: 2,723; makefile: 330; perl: 65
file content (133 lines) | stat: -rw-r--r-- 4,541 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* $Id: flowbuff.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 <stdlib.h>             /* malloc/free */

#include "flowreplay.h"
#include "flownode.h"
#include "err.h"

extern int32_t pernodebufflim;
extern int32_t totalbufflim;

/*
 * adds a packet read from pcap_next() to the chain of buffered
 * packets for the given node.  Mallocs memory. Returns a ptr to 
 * the new buffer or NULL on fail
 */
struct pktbuffhdr_t *
addpkt2buff(struct session_t *node, u_char * pktdata, u_int32_t len)
{
    struct pktbuffhdr_t *buffhdr = NULL;    /* packet buffer hdr */

    /* check per node buffer limit */
    if ((node->buffmem + len) > pernodebufflim) {
        warnx("Unable to buffer next packet: per node buffer limit reached");
        return (NULL);
    }

    /* check total buffer limit */
    totalbufflim -= len;
    if (totalbufflim < 0) {
        warnx("Unable to buffer next packet: total buffer limit reached");
        totalbufflim += len;    /* reset */
        return (NULL);
    }

    /* prep the buffer header for the linked list */
    if ((buffhdr =
         (struct pktbuffhdr_t *)malloc(sizeof(struct pktbuffhdr_t))) == NULL)
        errx(1, "Unable to malloc *pktbuffhdr in addpkt2buff()");

    buffhdr->len = len;

    /* allocate memory for the packet data */
    if ((buffhdr->packet = (u_char *) malloc(len)) == NULL)
        errx(1, "Unable to malloc *buff in addpkt2buff()");

    /* copy over the packet */
    memcpy(buffhdr->packet, pktdata, len);

    /* is this the first packet ? */
    if (node->lastbuff == NULL) {
        /* start the chain by pointing both buffered and lastbuff to the new buffer */
        node->buffered = buffhdr;
        node->lastbuff = buffhdr;
    }
    else {
        /* otherwise add the buffer to the end of the list */
        node->lastbuff->next = buffhdr;
        node->lastbuff = buffhdr;
    }

    /* return a ptr to the packet */
    return (buffhdr);
}


/* 
 * frees the last sent packet, relinks the linked list, and returns a
 * pointer to the packet.  packet len is returned in len.  Returns
 * NULL/len = 0 when last packet is reached.
 */
const u_char *
nextbuffpkt(struct session_t *node, u_int32_t len)
{
    struct pktbuffhdr_t *packet = NULL;

    /* mode temp ptr to next packet, which may be NULL */
    packet = node->sentbuff->next;

    /* first thing first, free the last packet, update the node's
     * buffmem counter, the total buffer limit, and free the buffer header
     */
    if (node->sentbuff != NULL) {
        free(node->sentbuff->packet);
        node->buffmem -= node->sentbuff->len;
        totalbufflim += len;
        free(node->sentbuff);
    }

    /* relink the list */
    node->buffered = packet;

    /* was that the last packet ? */
    if (node->buffered == NULL) {
        len = 0;
        return (NULL);
    }

    /* otherwise we've got another packet, so update len and return it */
    len = node->buffered->len;
    return (node->buffered->packet);
}