Пример #1
0
/* 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
void *server_fn(void *cfd)
{
	int client_fd = (intptr_t) cfd;
	int num_requests = 0, offset = 0;

	/* Reply will be constructed from first client request */
	char *send_msg = NULL;
	int send_msg_size = 0;

	char recv_msg[max_msg_len];

	setsockopt(client_fd, SOL_SOCKET, SO_LINGER, &clo, sizeof(clo));
	ssize_t recv_len;

	while (1) {
		recv_len = sock_recv_poll(client_fd, recv_msg,
			max_msg_len, offset);

		if (recv_len == 0)
			break;

		if (recv_len < 0 || (offset + recv_len) > max_msg_len ||
		   (recv_msg[0] != start_byte &&
		    recv_msg[0] != start_fin_byte)) {
			tst_resm(TFAIL, "recv failed, sock '%d'", client_fd);
			goto out;
		}

		offset += recv_len;

		if (recv_msg[offset - 1] != end_byte) {
			/* msg is not complete, continue recv */
			continue;
		}

		/* client asks to terminate */
		if (recv_msg[0] == start_fin_byte)
			goto out;

		if (verbose) {
			tst_resm_hexd(TINFO, recv_msg, offset,
				"msg recv from sock %d:", client_fd);
		}

		/* if we send reply for the first time, construct it here */
		if (!send_msg) {
			send_msg_size = parse_client_request(recv_msg);
			if (send_msg_size < 0) {
				tst_resm(TFAIL, "wrong msg size '%d'",
					send_msg_size);
				goto out;
			}
			send_msg = make_server_reply(send_msg_size);
		}

		/*
		 * It will tell client that server is going
		 * to close this connection.
		 */
		if (++num_requests >= server_max_requests)
			send_msg[0] = start_fin_byte;

		if (send(client_fd, send_msg, send_msg_size,
		    MSG_NOSIGNAL) == -1) {
			tst_resm(TFAIL | TERRNO, "send failed");
			goto out;
		}

		offset = 0;

		if (num_requests >= server_max_requests) {
			/* max reqs, close socket */
			shutdown(client_fd, SHUT_WR);
			break;
		}
	}

	free(send_msg);
	SAFE_CLOSE(cleanup, client_fd);
	return NULL;

out:
	free(send_msg);
	SAFE_CLOSE(cleanup, client_fd);
	cleanup();
	tst_exit();
}
Пример #3
0
/* 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;
}
Пример #4
0
void run_daemon(void)
{
   pid_t pid;
   FILE *fp = NULL;
   pid_t sid = 0;
   int sockfd,newfd;
   struct sockaddr_un addr;

   pid = fork();

   if (pid < 0) {
      printf("Fork a daemon process failed\n");
      exit(1);
   }

   if (pid > 0) {
      //exit the parent process successfully
      printf("Fork succeeded\n");
      exit(0);
   }

   sid = setsid();

   if (sid < 0) {
      printf("setsid failed\n");
      exit(1);
   }

   chdir("/");

   close(STDIN_FILENO);
   close(STDOUT_FILENO);
   close(STDERR_FILENO);

   fp = fopen("/var/lib/switch", "w+");
   daemon_fp = fp;
   log_fd = fileno(fp);

   kvm_fd = open("/dev/kvm", O_RDWR);
   if (kvm_fd < 0)
      fprintf(fp, "error in opening kvm device file\n");
   fprintf(fp, "kvm device file descriptor %d\n", kvm_fd);
      

   sockfd = socket(AF_UNIX, SOCK_STREAM, 0);

   if (sockfd < 0) {
      fprintf(fp, "Socket Creation failed\n");
      exit(1);
   }

   memset((void *)&addr, 0, sizeof(addr));
   addr.sun_family = AF_UNIX;
   strncpy(addr.sun_path, "/var/lib/switch.sock", sizeof(addr.sun_path)-1);
   if (bind(sockfd, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
      fprintf(fp, "error on binding unix file to socket\n");
      exit(1);
   }

   if (listen(sockfd, 1) < 0) {
      fprintf(fp, "error on listening to socket\n");
      exit(1);
   }

   while (1) {
       newfd = accept(sockfd, NULL, NULL);
       parse_client_request(newfd, fp);
       fprintf(fp, "Logging info");
       fflush(fp);
   }

   unlink("/var/lib/switch.sock");
   fclose(fp);
   exit(0);
}