예제 #1
0
파일: httpry.c 프로젝트: gwtony/c-example
/* 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;
}
예제 #2
0
파일: httpry.c 프로젝트: wishdev/httpry
/* 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;
}