int tcpdemux::process_pkt(const be13::packet_info &pi) { int r = 1; // not processed yet switch(pi.ip_version()){ case 4: r = process_ip4(pi); break; case 6: r = process_ip6(pi); break; } if(r!=0){ // packet not processed? /* Write the packet if we didn't process it */ if(pwriter) pwriter->writepkt(pi.pcap_hdr,pi.pcap_data); } /* Process the timeout, if there is any */ if(tcp_timeout){ std::vector<flow *> to_close; for(flow_map_t::iterator it = flow_map.begin(); it!=flow_map.end(); it++){ tcpip &tcp = *(it->second); flow &f = tcp.myflow; uint32_t age = pi.ts.tv_sec - f.tlast.tv_sec; if (age > tcp_timeout){ to_close.push_back(&f); } } for(std::vector<flow *>::iterator it = to_close.begin(); it!=to_close.end(); it++){ remove_flow(*(*it)); } } return r; }
int tcpdemux::process_pkt(const be13::packet_info &pi) { DEBUG(10)("process_pkt.............................................................................."); int r = 1; // not processed yet switch(pi.ip_version()){ case 4: r = process_ip4(pi); break; case 6: r = process_ip6(pi); break; } if(r!=0){ // packet not processed? /* Write the packet if we didn't process it */ if(pwriter) pwriter->writepkt(pi.pcap_hdr,pi.pcap_data); } /* Process the timeout, if there is any */ if(tcp_timeout){ /* Get a list of the flows that need to be closed. */ std::vector<flow_addr *> to_close; for(flow_map_t::iterator it = flow_map.begin(); it!=flow_map.end(); it++){ tcpip &tcp = *(it->second); uint32_t age = pi.ts.tv_sec - tcp.myflow.tlast.tv_sec; if (age > tcp_timeout){ to_close.push_back(&tcp.myflow); } } /* Close them. This removes the flows from the flow_map(), which is why we need * to create the list first. */ for(std::vector<flow_addr *>::iterator it = to_close.begin(); it!=to_close.end(); it++){ remove_flow(*(*it)); } } return r; }
int tcpdemux::process_ip4(const be13::packet_info &pi) { /* make sure that the packet is at least as long as the min IP header */ if (pi.ip_datalen < sizeof(struct be13::ip4)) { DEBUG(6) ("received truncated IP datagram!"); return -1; // couldn't process } const struct be13::ip4 *ip_header = (struct be13::ip4 *) pi.ip_data; DEBUG(100)("process_ip4. caplen=%d vlan=%d ip_p=%d",(int)pi.pcap_hdr->caplen,(int)pi.vlan(),(int)ip_header->ip_p); if(debug>200){ sbuf_t sbuf(pos0_t(),(const uint8_t *)pi.ip_data,pi.ip_datalen,pi.ip_datalen,false); sbuf.hex_dump(std::cerr); } /* for now we're only looking for TCP; throw away everything else */ if (ip_header->ip_p != IPPROTO_TCP) { DEBUG(50) ("got non-TCP frame -- IP proto %d", ip_header->ip_p); return -1; // couldn't process } /* check and see if we got everything. NOTE: we must use * ip_total_len after this, because we may have captured bytes * beyond the end of the packet (e.g. ethernet padding). */ size_t ip_len = ntohs(ip_header->ip_len); if (pi.ip_datalen < ip_len) { DEBUG(6) ("warning: captured only %ld bytes of %ld-byte IP datagram", (long) pi.ip_datalen, (long) ip_len); } /* XXX - throw away everything but fragment 0; this version doesn't * know how to do fragment reassembly. */ if (ntohs(ip_header->ip_off) & 0x1fff) { DEBUG(2) ("warning: throwing away IP fragment from X to X"); return -1; } /* figure out where the IP header ends */ size_t ip_header_len = ip_header->ip_hl * 4; /* make sure there's some data */ if (ip_header_len > ip_len) { DEBUG(6) ("received truncated IP datagram!"); return -1; } /* do TCP processing, faking an ipv6 address */ uint16_t ip_payload_len = ip_len - ip_header_len; ipaddr src(ip_header->ip_src.addr); ipaddr dst(ip_header->ip_dst.addr); return process_tcp(src, dst, AF_INET, pi.ip_data + ip_header_len, ip_payload_len, pi); }