#include <usi++/usi++.h> #include <iostream> #include <string> #include <vector> #define MAXDATALEN 1000 /* a unique connection */ typedef struct { long seq, src, dst; int sport, dport, count, lwm; char buf[MAXDATALEN]; } connection; vector<connection*> conn; #define min(x,y) ((x)<(y)?(x):(y)) /* look whether the opened connection starts from * a xterm. */ bool fromX(connection *c) { char *s = new char[c->count+1]; memset(s, 0, c->count + 1); bool r; int j = 0; /* skip 0-bytes, so a strstr() works now */ for (int i = 0; i < c->count; i++) { if (c->buf[i]) s[j++] = c->buf[i]; } if (strstr(s, "xterm") != NULL || strstr(s, "XTERM") != NULL) r = true; else r = false; delete [] s; return r; } int print_conn(connection *c, int j) { char src[1000], dst[1000]; if (!c) return 0; /* set lwm higher, if connection comes from xterm * and lwm was not already increased. */ if (fromX(c) && c->lwm < 160) { c->lwm += 50; return 0; } /* This is a dummy. We use it to resolve the * source and destinationadresses */ UDP dummy("localhost"); dummy.set_src(c->src); dummy.set_dst(c->dst); cout<<dummy.get_src(0, src, 1000)<<":"<<c->sport<<"->" <<dummy.get_dst(0, dst, 1000)<<":"<<c->dport<<endl; /* now print data in readable format */ for (int i = 0; i < c->count && i < MAXDATALEN; i++) { if (isprint(c->buf[i]) || c->buf[i] == '\n') printf("%c", c->buf[i]); fflush(stdout); } printf("\n"); /* this connection is not longer needed */ conn[j] = NULL; delete c; return 0; } /* Add a new connection */ int add_conn(TCP *tcp) { int p = tcp->get_dstport(); if (p != 21 && p != 23 && p != 110 && p != 513) return -1; connection *c = new connection; memset(c, 0, sizeof(connection)); c->src = tcp->get_src(); c->dst = tcp->get_dst(); c->sport = tcp->get_srcport(); c->dport = tcp->get_dstport(); /* set the low-watermark -- port specific */ switch (c->dport) { case 21: c->lwm = 30; break; case 23: c->lwm = 110; break; case 110: c->lwm = 30; break; case 513: c->lwm = 55; break; default: c->lwm = 100; break; } conn.push_back(c); return 0; } connection *get_conn(TCP *tcp) { for (int i = 0; i < conn.size(); i++) { if (!conn[i]) continue; if (tcp->get_dst() == conn[i]->dst && tcp->get_src() == conn[i]->src && tcp->get_dstport() == conn[i]->dport && tcp->get_srcport() == conn[i]->sport) return conn[i]; } return NULL; } int main(int argc, char **argv) { if (argc < 2) { cout<<argv[0]<<" [intf]\n"; exit(1); } TCP *sn = new TCP("localhost"); sn->init_device(argv[1], 1, 500); char buf[1000]; while (1) { memset(buf, 0, 1000); int l = sn->sniffpack(buf, 1000); /* if connection is opened, save characteristics */ if (sn->get_flags() == TH_SYN) { add_conn(sn); /* otherwise save data */ } else { /* don't fetch the ACK only packets */ if (sn->get_flags() == TH_ACK) continue; connection *c = get_conn(sn); if (!c) continue; /* insert data */ int j = 0; while (l-- > 0 && c->count < MAXDATALEN) c->buf[c->count++] = buf[j++]; } /* look if one connection has enough data */ for (int i = 0; i < conn.size(); i++) { /* skip already printed connections */ if (!conn[i]) continue; if (conn[i]->count > conn[i]->lwm) print_conn(conn[i], i); } } return 0; }