📄 tcp_raw.c
字号:
/* tcp_raw.c Copyright (c) 2000 Dug Song <dugsong@monkey.org> $Id: tcp_raw.c,v 1.8 2000/08/28 01:30:22 dugsong Exp $*/#include "config.h"#include <sys/types.h>#include <sys/uio.h>#include <time.h>#include <err.h>#include <libnet.h>#include "options.h"#include "tcp_raw.h"struct tha { in_addr_t src; in_addr_t dst; u_short port;};struct tcp_seg { u_int32_t seq; u_char *data; int len;};struct tcp_conn { struct tha tha; time_t mtime; struct tcp_seg *seg; int segcnt; int segmax; struct tcp_conn *next;};#define TCP_TIMEOUT 60#define TCP_HASHSIZE 919static struct tcp_conn conntab[TCP_HASHSIZE];static inttcp_seg_compare(const void *a, const void *b){ struct tcp_seg *sa, *sb; sa = (struct tcp_seg *) a; sb = (struct tcp_seg *) b; if (sa->seq < sb->seq) return (-1); else if (sa->seq > sb->seq) return (1); else return (0);}static voidtcp_raw_delete(struct tcp_conn *conn){ struct tcp_conn *hold; int i; if (conn->next != NULL) { for (i = 0; i < conn->segcnt; i++) { if (conn->seg[i].data) free(conn->seg[i].data); } free(conn->seg); conn->seg = NULL; conn->segcnt = conn->segmax = 0; if (conn->next->next != NULL) { hold = conn->next; *conn = *conn->next; free(hold); } else { free(conn->next); conn->next = NULL; } }}static struct iovec *tcp_raw_reassemble(struct tcp_conn *conn, int minlen){ struct iovec *iov; int i, len; len = 0; for (i = 0; i < conn->segcnt; i++) len += conn->seg[i].len; if (len < minlen) return (NULL); if ((iov = (struct iovec *) malloc(sizeof(*iov))) == NULL) err(1, "tcp_raw_reassemble: malloc"); if ((iov->iov_base = (u_char *) malloc(len)) == NULL) err(1, "tcp_raw_reassemble: malloc"); iov->iov_len = 0; qsort(conn->seg, conn->segcnt, sizeof(*conn->seg), tcp_seg_compare); for (i = 0; i < conn->segcnt; i++) { len = conn->seg[i].len; memcpy(iov->iov_base + iov->iov_len, conn->seg[i].data, len); iov->iov_len += len; } return (iov);}struct iovec *tcp_raw_input(struct libnet_ip_hdr *ip, struct libnet_tcp_hdr *tcp, int len){ struct tha tha; struct tcp_conn *conn; struct tcp_seg seg; struct iovec *iov; u_short cksum; u_char *buf; int tcp_hl = tcp->th_off * 4; /* Verify TCP checksum. */ cksum = tcp->th_sum; libnet_do_checksum((u_char *) ip, IPPROTO_TCP, len); if (cksum != tcp->th_sum) return (NULL); tha.src = ip->ip_src.s_addr; tha.dst = ip->ip_dst.s_addr; tha.port = ntohs(tcp->th_sport) << 16 | ntohs(tcp->th_dport); buf = (u_char *)tcp + tcp_hl; len -= tcp_hl; iov = NULL; /* Find half-duplex stream associated with this segment. */ for (conn = &conntab[tha.port % TCP_HASHSIZE]; conn->next != NULL; conn = conn->next) { if (memcmp((char *)&tha, (char *)&conn->tha, sizeof(tha)) == 0) break; } /* Process by TCP flags. */ if (conn->next == NULL) { if (tcp->th_flags & TH_SYN) { if (conn->next == NULL && (conn->next = (struct tcp_conn *) calloc(1, sizeof(*conn))) == NULL) { err(1, "tcp_raw_input: calloc"); } conn->tha = tha; if (conn->seg == NULL && (conn->seg = (struct tcp_seg *) malloc(sizeof(seg) * 128)) == NULL) { err(1, "tcp_raw_input: malloc"); } conn->segmax = 128; } } else if (tcp->th_flags & TH_FIN || tcp->th_flags & TH_RST) { iov = tcp_raw_reassemble(conn, 1); } else if (tcp->th_flags & TH_ACK && len > 0) { seg.seq = ntohl(tcp->th_seq); if (bsearch(&seg, conn->seg, conn->segcnt, sizeof(seg), tcp_seg_compare) == NULL) { if ((seg.data = (u_char *) malloc(len)) == NULL) err(1, "tcp_raw_input: malloc"); memcpy(seg.data, buf, len); seg.len = len; if (conn->segcnt == conn->segmax) { if ((conn->seg = (struct tcp_seg *) realloc(conn->seg, (conn->segmax * 2) * sizeof(seg))) == NULL) err(1, "tcp_raw_input: realloc"); conn->segmax *= 2; } conn->seg[conn->segcnt++] = seg; iov = tcp_raw_reassemble(conn, Opt_snaplen); } } conn->mtime = time(NULL); /* If we successfully reassembled the stream, delete its entry. */ if (iov != NULL) { tcp_raw_delete(conn); } return (iov);}voidtcp_raw_timeout(int timeout, tcp_raw_callback_t callback){ struct tcp_conn *conn; struct iovec *iov; time_t now; int i; now = time(NULL); for (i = 0; i < TCP_HASHSIZE; i++) { for (conn = &conntab[i]; conn != NULL && conn->next != NULL; conn = conn->next) { if (now - conn->mtime > timeout) { iov = tcp_raw_reassemble(conn, 1); if (iov != NULL) { callback(conn->tha.src, conn->tha.dst, conn->tha.port >> 16, conn->tha.port & 0xffff, iov->iov_base, iov->iov_len); free(iov->iov_base); free(iov); } tcp_raw_delete(conn); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -