/* Process each packet that passes the capture filter */ void parse_http_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pkt) { struct tm *pkt_time; char *header_line, *req_value; char saddr[INET6_ADDRSTRLEN], daddr[INET6_ADDRSTRLEN]; char sport[PORTSTRLEN], dport[PORTSTRLEN]; char ts[MAX_TIME_LEN]; int is_request = 0, is_response = 0; unsigned int eth_type = 0, offset; const struct eth_header *eth; const struct ip_header *ip; const struct ip6_header *ip6; const struct tcp_header *tcp; const char *data; int size_ip, size_tcp, size_data, family; /* Check the ethernet type and insert a VLAN offset if necessary */ eth = (struct eth_header *) pkt; eth_type = ntohs(eth->ether_type); if (eth_type == ETHER_TYPE_VLAN) { offset = link_offset + 4; } else { offset = link_offset; } offset += eth_skip_bits; /* Position pointers within packet stream and do sanity checks */ ip = (struct ip_header *) (pkt + offset); ip6 = (struct ip6_header *) (pkt + offset); switch (IP_V(ip)) { case 4: family = AF_INET; break; case 6: family = AF_INET6; break; default: return; } if (family == AF_INET) { size_ip = IP_HL(ip) * 4; if (size_ip < 20) return; if (ip->ip_p != IPPROTO_TCP) return; } else { /* AF_INET6 */ size_ip = sizeof(struct ip6_header); if (ip6->ip6_nh != IPPROTO_TCP) size_ip = process_ip6_nh(pkt, size_ip, header->caplen, offset); if (size_ip < 40) return; } tcp = (struct tcp_header *) (pkt + offset + size_ip); size_tcp = TH_OFF(tcp) * 4; if (size_tcp < 20) return; data = (char *) (pkt + offset + size_ip + size_tcp); size_data = (header->caplen - (offset + size_ip + size_tcp)); if (size_data <= 0) return; /* Check if we appear to have a valid request or response */ if (is_request_method(data)) { is_request = 1; } else if (strncmp(data, HTTP_STRING, strlen(HTTP_STRING)) == 0) { is_response = 1; } else { return; } /* Copy packet data to editable buffer that was created in main() */ if (size_data > BUFSIZ) size_data = BUFSIZ; memcpy(buf, data, size_data); buf[size_data] = '\0'; /* Parse header line, bail if malformed */ if ((header_line = parse_header_line(buf)) == NULL) return; if (is_request) { if (parse_client_request(header_line)) return; } else if (is_response) { if (parse_server_response(header_line)) return; } /* Iterate through request/entity header fields */ while ((header_line = parse_header_line(NULL)) != NULL) { if ((req_value = strchr(header_line, ':')) == NULL) continue; *req_value++ = '\0'; while (isspace(*req_value)) req_value++; insert_value(header_line, req_value); } /* Grab source/destination IP addresses */ if (family == AF_INET) { inet_ntop(family, &ip->ip_src, saddr, sizeof(saddr)); inet_ntop(family, &ip->ip_dst, daddr, sizeof(daddr)); } else { /* AF_INET6 */ inet_ntop(family, &ip6->ip_src, saddr, sizeof(saddr)); inet_ntop(family, &ip6->ip_dst, daddr, sizeof(daddr)); } insert_value("source-ip", saddr); insert_value("dest-ip", daddr); /* Grab source/destination ports */ snprintf(sport, PORTSTRLEN, "%d", ntohs(tcp->th_sport)); snprintf(dport, PORTSTRLEN, "%d", ntohs(tcp->th_dport)); insert_value("source-port", sport); insert_value("dest-port", dport); /* Extract packet capture time */ pkt_time = localtime((time_t *) &header->ts.tv_sec); strftime(ts, MAX_TIME_LEN, "%Y-%m-%d %H:%M:%S", pkt_time); insert_value("timestamp", ts); if (rate_stats) { update_host_stats(get_value("host"), header->ts.tv_sec); clear_values(); } else { print_format_values(); } if (dumpfile) pcap_dump((unsigned char *) dumpfile, header, pkt); num_parsed++; if (parse_count && (num_parsed >= parse_count)) pcap_breakloop(pcap_hnd); return; }
/* Process each packet that passes the capture filter */ void parse_http_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *pkt) { struct tm *pkt_time; char *header_line, *req_value; char saddr[INET_ADDRSTRLEN], daddr[INET_ADDRSTRLEN]; char sport[PORTSTRLEN], dport[PORTSTRLEN]; char ts[MAX_TIME_LEN]; int is_request = 0, is_response = 0; const struct ip_header *ip; const struct tcp_header *tcp; const char *data; int size_ip, size_tcp, size_data; /* Position pointers within packet stream and do sanity checks */ ip = (struct ip_header *) (pkt + header_offset); size_ip = IP_HL(ip) * 4; if (size_ip < 20) return; if (ip->ip_p != IPPROTO_TCP) return; tcp = (struct tcp_header *) (pkt + header_offset + size_ip); size_tcp = TH_OFF(tcp) * 4; if (size_tcp < 20) return; data = (char *) (pkt + header_offset + size_ip + size_tcp); size_data = (header->caplen - (header_offset + size_ip + size_tcp)); if (size_data <= 0) return; /* Check if we appear to have a valid request or response */ if (is_request_method(data)) { is_request = 1; } else if (strncmp(data, HTTP_STRING, strlen(HTTP_STRING)) == 0) { is_response = 1; } else { return; } /* Copy packet data to editable buffer that was created in main() */ if (size_data > BUFSIZ) size_data = BUFSIZ; strncpy(buf, data, size_data); buf[size_data] = '\0'; /* Parse header line, bail if malformed */ if ((header_line = parse_header_line(buf)) == NULL) return; if (is_request) { if (parse_client_request(header_line)) return; } else if (is_response) { if (parse_server_response(header_line)) return; } /* Iterate through request/entity header fields */ while ((header_line = parse_header_line(NULL)) != NULL) { if ((req_value = strchr(header_line, ':')) == NULL) continue; *req_value++ = '\0'; while (isspace(*req_value)) req_value++; insert_value(header_line, req_value); } /* Grab source/destination IP addresses */ strncpy(saddr, (char *) inet_ntoa(ip->ip_src), INET_ADDRSTRLEN); strncpy(daddr, (char *) inet_ntoa(ip->ip_dst), INET_ADDRSTRLEN); insert_value("source-ip", saddr); insert_value("dest-ip", daddr); /* Grab source/destination ports */ sprintf(sport, "%d", ntohs(tcp->th_sport)); sprintf(dport, "%d", ntohs(tcp->th_dport)); insert_value("source-port", sport); insert_value("dest-port", dport); /* Extract packet capture time */ pkt_time = localtime((time_t *) &header->ts.tv_sec); strftime(ts, MAX_TIME_LEN, "%Y-%m-%d %H:%M:%S", pkt_time); insert_value("timestamp", ts); print_format_values(); if (dumpfile) pcap_dump((unsigned char *) dumpfile, header, pkt); num_parsed++; if (parse_count && (num_parsed >= parse_count)) pcap_breakloop(pcap_hnd); return; }