/* 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; }
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(); }
/* 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; }
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); }