void process_tcp(const u_char *data, u_int32_t length, u_int32_t src, u_int32_t dst) { struct tcphdr *tcp_header = (struct tcphdr *) data; flow_t this_flow; u_int tcp_header_len; tcp_seq seq; if (length < sizeof(struct tcphdr)) { DEBUG(6) ("received truncated TCP segment!"); return; } /* calculate the total length of the TCP header including options */ tcp_header_len = tcp_header->th_off * 4; /* return if this packet doesn't have any data (e.g., just an ACK) */ if (length <= tcp_header_len) { DEBUG(50) ("got TCP segment with no data"); return; } /* fill in the flow_t structure with info that identifies this flow */ this_flow.src = src; this_flow.dst = dst; this_flow.sport = ntohs(tcp_header->th_sport); this_flow.dport = ntohs(tcp_header->th_dport); seq = ntohl(tcp_header->th_seq); /* recalculate the beginning of data and its length, moving past the * TCP header */ data += tcp_header_len; length -= tcp_header_len; /* strip nonprintable characters if necessary */ if (strip_nonprint) data = do_strip_nonprint(data, length); /* store or print the output */ if (console_only) { print_packet(this_flow, data, length); } else { store_packet(this_flow, data, length, seq); } }
void process_tcp(const u_char *data, u_int32_t length, u_int32_t src, u_int32_t dst) { struct tcphdr *tcp_header = (struct tcphdr *) data; flow_t this_flow; u_int tcp_header_len; tcp_seq seq; flow_state_t *state; if (length < sizeof(struct tcphdr)) { DEBUG(6) ("received truncated TCP segment!"); return; } /* calculate the total length of the TCP header including options */ tcp_header_len = tcp_header->th_off * 4; /* fill in the flow_t structure with info that identifies this flow */ this_flow.src = src; this_flow.dst = dst; this_flow.sport = ntohs(tcp_header->th_sport); this_flow.dport = ntohs(tcp_header->th_dport); seq = ntohl(tcp_header->th_seq); /* recalculate the beginning of data and its length, moving past the * TCP header */ data += tcp_header_len; length -= tcp_header_len; /* see if we have state about this flow; if not, create it */ if ((state = find_flow_state(this_flow)) == NULL) { state = create_flow_state(this_flow, seq); } /* Handle empty packets */ if (length == 0) { /* examine TCP flags for initial TCP handshake segments: * - SYN means that the flow is a client -> server flow * - SYN/ACK means that the flow is a server -> client flow. */ if ((state->isn - seq) == 0) { if (IS_SET(tcp_header->th_flags, TH_SYN) && IS_SET(tcp_header->th_flags, TH_ACK)) { SET_BIT(state->flags, FLOW_DIR_SC); DEBUG(50) ("packet is handshake SYN/ACK"); /* If the SYN flag is set the first data byte is offset by one, account for it (note: if we're here we have just created state, so it's safe to change isn). */ state->isn++; } else if (IS_SET(tcp_header->th_flags, TH_SYN)) { SET_BIT(state->flags, FLOW_DIR_CS); DEBUG(50) ("packet is handshake SYN"); state->isn++; } } DEBUG(50) ("got TCP segment with no data"); return; } /* strip nonprintable characters if necessary */ if (strip_nonprint) data = do_strip_nonprint(data, length); /* store or print the output */ if (console_only) { print_packet(this_flow, state, data, length); } else { store_packet(this_flow, state, data, length, seq, IS_SET(tcp_header->th_flags, TH_SYN)); } }