File: connection.c

package info (click to toggle)
driftnet 0.1.6-2
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 200 kB
  • ctags: 283
  • sloc: ansic: 1,947; makefile: 93
file content (107 lines) | stat: -rw-r--r-- 2,909 bytes parent folder | download | duplicates (4)
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
/*
 * connection.c:
 *
 * Copyright (c) 2002 Chris Lightfoot. All rights reserved.
 * Email: chris@ex-parrot.com; WWW: http://www.ex-parrot.com/~chris/
 *
 */

static const char rcsid[] = "$Id: connection.c,v 1.3 2002/07/08 23:32:33 chris Exp $";

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "driftnet.h"

/* connection_new:
 * Allocate a new connection structure between the given addresses. */
connection connection_new(const struct in_addr *src, const struct in_addr *dst, const short int sport, const short int dport) {
    connection c = (connection)calloc(1, sizeof(struct _connection));
    c->src = *src;
    c->dst = *dst;
    c->sport = sport;
    c->dport = dport;
    c->alloc = 16384;
    c->data = c->gif = c->jpeg = c->mpeg = malloc(c->alloc);
    c->last = time(NULL);
    c->blocks = NULL;
    return c;
}

/* connection_delete:
 * Free the named connection structure. */
void connection_delete(connection c) {
    free(c->data);
    free(c);
}

/* connection_push:
 * Put some more data in a connection. */
void connection_push(connection c, const unsigned char *data, unsigned int off, unsigned int len) {
    size_t goff = c->gif - c->data, joff = c->jpeg - c->data, moff = c->mpeg - c->data;
    struct datablock *B, *b, *bl, BZ = {0};
    int a;

    assert(c->alloc > 0);
    if (off + len > c->alloc) {
        /* Allocate more memory. */
        while (off + len > c->alloc) {
            c->alloc *= 2;
            c->data = (unsigned char*)realloc(c->data, c->alloc);
        }
    }
    c->gif = c->data + goff;
    c->jpeg = c->data + joff;
    c->mpeg = c->data + moff;
    memcpy(c->data + off, data, len);

    if (off + len > c->len) c->len = off + len;
    c->last = time(NULL);
    
    B = malloc(sizeof *B);
    *B = BZ;
    B->off = off;
    B->len = len;
    B->dirty = 1;
    B->next = NULL;
    
    /* Insert the block into the sorted block list. */
    for (b = c->blocks, bl = NULL; ; bl = b, b = b->next) {
        if ((!b || off <= b->off) && (!bl || off > bl->off)) {
            B->next = b;
            if (bl)
                bl->next = B;
            else
                c->blocks = B;
            break;
        }
    }

    /* Now go through the list combining blocks. */
    do {
        a = 0;
        for (b = c->blocks; b; b = b->next) {
            if (b->next && b->off + b->len >= b->next->off) {
                struct datablock *bb;
                bb = b->next;
                b->len = (bb->off + bb->len) - b->off;
                b->next = bb->next;
                b->dirty = 1;
                free(bb);
                ++a;
            }
        }
    } while (a);
/*
        {
            printf("%p: ", c);
            for (b = c->blocks; b; b = b->next)
                printf("[%d (%d) -> %d] ", b->off, b->len, b->off + b->len);
            printf("\n");
        }
*/
}