From c95257f26acf83b63aec64027ae9c96710ee5e3b Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Tue, 23 Apr 2013 11:25:43 -0400 Subject: [PATCH] [Listener] Use pcap_next_ex instead of pcap_loop pcap_next_ex() will allow us to detect the end of a capture file. Since we used pcap_loop() to capture one packet at a time anyway, this won't change anything for live captures. The variable names were standardised in functions using pcap data types ('pkt_header' and 'pkt_data' instead of 'header' and 'packet'). --- owlps-listener/owlps-listener.h | 10 ++-- owlps-listener/owlps-listenerd.c | 88 +++++++++++++++++++------------- 2 files changed, 57 insertions(+), 41 deletions(-) diff --git a/owlps-listener/owlps-listener.h b/owlps-listener/owlps-listener.h index 253513f..bc1cf18 100644 --- a/owlps-listener/owlps-listener.h +++ b/owlps-listener/owlps-listener.h @@ -216,13 +216,13 @@ void* keep_mode_monitor(void *iface) ; int iface_mode_monitor(const char *const iface) ; #endif // ENABLE_KEEP_MONITOR int capture(void) ; -void read_packet(u_char *args, const struct pcap_pkthdr *header, - const u_char *packet) ; -void extract_calibration_data(const u_char *packet, +void read_packet(const struct pcap_pkthdr *pkt_header, + const u_char *pkt_data) ; +void extract_calibration_data(const u_char *pkt_data, owl_captured_request *request) ; -void extract_packet_numbers(const u_char *packet, +void extract_packet_numbers(const u_char *pkt_data, owl_captured_request *request) ; -void extract_radiotap_data(const u_char *packet, +void extract_radiotap_data(const u_char *pkt_data, owl_captured_request *request, owl_bool rtap_fields[15]) ; void get_mac_addr(char *eth, uint8_t mac_bytes[ETHER_ADDR_LEN]) ; diff --git a/owlps-listener/owlps-listenerd.c b/owlps-listener/owlps-listenerd.c index b5b0091..53a707d 100644 --- a/owlps-listener/owlps-listenerd.c +++ b/owlps-listener/owlps-listenerd.c @@ -878,8 +878,23 @@ int capture() &aggregation_server, NULL) ; while (owl_run) - // Capture one packet at time, and call read_packet() on it: - pcap_loop(capture_handler, 1, read_packet, NULL) ; + { + // Capture one packet at time, and call read_packet() on it: + int ret = pcap_next_ex(capture_handler, &pkt_header, &pkt_data) ; + switch (ret) + { + case 1: // packet read successfuly + read_packet(pkt_header, pkt_data) ; + break ; + case 0: // timeout reached + break ; + case -2: // no more packet to read from input file + owl_run = owl_false ; + break ; + case -1: // an error occured + pcap_perror(capture_handler, "Error during capture") ; + } + } pcap_close(capture_handler) ; // Stop capture close(aggregation_sockfd) ; // Close socket @@ -892,8 +907,8 @@ int capture() /* * Treats a packet and sends it to the aggregator. */ -void read_packet(u_char *args, const struct pcap_pkthdr *header, - const u_char *packet) +void read_packet(const struct pcap_pkthdr *pkt_header, + const u_char *pkt_data) { owl_captured_request request ; // Message to send to the aggregator uint16_t rtap_bytes ; // Radiotap header size @@ -923,7 +938,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, // Copy 2 bytes from the 3rd packet byte, that is the size of the rtap // header (changes with the flags): offset = 2 ; - memcpy(&rtap_bytes, &packet[offset], sizeof(rtap_bytes)) ; + memcpy(&rtap_bytes, &pkt_data[offset], sizeof(rtap_bytes)) ; // Radiotap header is little-endian rtap_bytes = le16toh(rtap_bytes) ; // Check rtap_bytes for buggy values @@ -935,7 +950,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, // the type of the packet (Management, Control or Data) and its subtype // (QoS, etc.): offset = rtap_bytes ; - raw_packet_fc1 = packet[offset] ; + raw_packet_fc1 = pkt_data[offset] ; // The second byte of the FC field contains the frame flags. The two // first bits indicate the frame source and destination types: the @@ -943,7 +958,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, // bit is 0 the frame comes from a STA. That's what we want for an // explicit packet: offset = rtap_bytes + 1 ; - raw_packet_fc2 = packet[offset] ; + raw_packet_fc2 = pkt_data[offset] ; if (! IS_DATA_FRAME(raw_packet_fc1)) // Data frame? goto not_explicit_packet ; @@ -956,14 +971,14 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, // Get the packet type (protocol, 2 bytes) from the LLC header: offset = rtap_bytes + ieee80211_header_size + 6 ; - memcpy(&llc_packet_type, &packet[offset], 2) ; + memcpy(&llc_packet_type, &pkt_data[offset], 2) ; llc_packet_type = ntohs(llc_packet_type) ; if (llc_packet_type != ETHERTYPE_IP) // IP packet? goto not_explicit_packet ; offset = rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE ; - packet_ip_header = (struct iphdr *) &packet[offset] ; + packet_ip_header = (struct iphdr *) &pkt_data[offset] ; // Get the source IP: memcpy(request.mobile_ip_addr_bytes, &packet_ip_header->saddr, 4) ; @@ -979,7 +994,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, offset = rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE + sizeof(struct iphdr) ; - packet_udp_header = (struct udphdr *) &packet[offset] ; + packet_udp_header = (struct udphdr *) &pkt_data[offset] ; dest_port = ntohs(packet_udp_header->dest) ; #ifdef USE_PTHREAD @@ -1006,7 +1021,8 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, // Source MAC address is 10 bytes after the 802.11 packet type: offset = rtap_bytes + 10 ; - memcpy(request.mobile_mac_addr_bytes, &packet[offset], ETHER_ADDR_LEN) ; + memcpy(request.mobile_mac_addr_bytes, &pkt_data[offset], + ETHER_ADDR_LEN) ; // Drop the packet if it comes from the AP itself: if (owl_mac_equals(my_mac_bytes, request.mobile_mac_addr_bytes)) @@ -1015,7 +1031,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, // Copy AP MAC : memcpy(request.ap_mac_addr_bytes, my_mac_bytes, ETHER_ADDR_LEN) ; // Capture time is in the pcap header (host-endian): - owl_timeval_to_timestamp(&header->ts, &request.capture_time) ; + owl_timeval_to_timestamp(&pkt_header->ts, &request.capture_time) ; owl_hton_timestamp(&request.capture_time) ; /* Active mode */ @@ -1027,12 +1043,12 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, offset = rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE + sizeof(struct iphdr) + sizeof(struct udphdr) ; - request.type = packet[offset] ; - extract_packet_numbers(&packet[++offset], &request) ; + request.type = pkt_data[offset] ; + extract_packet_numbers(&pkt_data[++offset], &request) ; offset += 2 * sizeof(uint16_t) ; // Copy the timestamp "as is" (i.e. without changing endianness) // because it will return to the network soon: - memcpy(&request.request_time, &packet[offset], + memcpy(&request.request_time, &pkt_data[offset], sizeof(owl_timestamp)) ; offset += sizeof(owl_timestamp) ; @@ -1046,7 +1062,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, case OWL_REQUEST_CALIBRATION : if (VERBOSE_INFO) printf("\nExplicit calibration packet received.\n") ; - extract_calibration_data(&packet[offset], &request) ; + extract_calibration_data(&pkt_data[offset], &request) ; break ; case OWL_REQUEST_AUTOCALIBRATION : @@ -1057,7 +1073,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, printf(".. on the wrong port!") ; putchar('\n') ; } - extract_calibration_data(&packet[offset], &request) ; + extract_calibration_data(&pkt_data[offset], &request) ; break ; default : @@ -1088,7 +1104,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, return ; /* Radiotap header handling */ - extract_radiotap_data(packet, &request, rtap_fields) ; + extract_radiotap_data(pkt_data, &request, rtap_fields) ; /* Display the packet details */ if (VERBOSE_DISPLAY_CAPTURED) @@ -1143,7 +1159,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, request.direction, ntohs(request.packet_id), ntohs(request.nb_packets), - header->len + pkt_header->len ) ; } @@ -1162,37 +1178,37 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header, /* - * Fills 'request' with the calibration data extracted from 'packet'. - * Note: 'packet' is read from its first byte, therefore you must not + * Fills 'request' with the calibration data extracted from 'pkt_data'. + * Note: 'pkt_data' is read from its first byte, therefore you must not * pass the whole received packet to this function. */ -void extract_calibration_data(const u_char *packet, +void extract_calibration_data(const u_char *pkt_data, owl_captured_request *request) { - request->direction = packet[0] ; + request->direction = pkt_data[0] ; assert(sizeof(float) == 4) ; - memcpy(&request->x_position, &packet[1], sizeof(float)) ; - memcpy(&request->y_position, &packet[5], sizeof(float)) ; - memcpy(&request->z_position, &packet[9], sizeof(float)) ; + memcpy(&request->x_position, &pkt_data[1], sizeof(float)) ; + memcpy(&request->y_position, &pkt_data[5], sizeof(float)) ; + memcpy(&request->z_position, &pkt_data[9], sizeof(float)) ; } /* * Fills 'request' with the number of packets and packet ID extracted - * from 'packet'. - * Note: 'packet' is read from its first byte, therefore you must not + * from 'pkt_data'. + * Note: 'pkt_data' is read from its first byte, therefore you must not * pass the whole received packet to this function. */ -void extract_packet_numbers(const u_char *packet, +void extract_packet_numbers(const u_char *pkt_data, owl_captured_request *request) { // Current packet's ID: - memcpy(&request->packet_id, packet, + memcpy(&request->packet_id, pkt_data, sizeof(uint16_t)) ; request->packet_id = request->packet_id ; // Number of packets: - memcpy(&request->nb_packets, &packet[sizeof(uint16_t)], + memcpy(&request->nb_packets, &pkt_data[sizeof(uint16_t)], sizeof(uint16_t)) ; request->nb_packets = request->nb_packets ; } @@ -1201,10 +1217,10 @@ void extract_packet_numbers(const u_char *packet, /* * Fills 'request' with the required data extracted from the Radiotap - * header of 'packet'. The elements of 'rtap_fields' are set to owl_true - * when the corresponding Radiotap flag is found in the packet. + * header of 'pkt_data'. The elements of 'rtap_fields' are set to + * owl_true when the corresponding Radiotap flag is found in the packet. */ -void extract_radiotap_data(const u_char *packet, +void extract_radiotap_data(const u_char *pkt_data, owl_captured_request *request, owl_bool rtap_fields[15]) { @@ -1214,7 +1230,7 @@ void extract_radiotap_data(const u_char *packet, // Get rtap flags: memcpy(&rtap_presentflags, - &packet[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS) ; + &pkt_data[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS) ; // The Radiotap header is little-endian rtap_presentflags = le32toh(rtap_presentflags) ; @@ -1252,7 +1268,7 @@ void extract_radiotap_data(const u_char *packet, break ; case RTAP_ANTENNASIGNALDBM: memcpy(&request->ss_dbm, - &packet[rtap_position], RTAP_L_ANTENNASIGNALDBM) ; + &pkt_data[rtap_position], RTAP_L_ANTENNASIGNALDBM) ; rtap_fields[RTAP_ANTENNASIGNALDBM] = owl_true; if (VERBOSE_INFO) printf("Antenna signal: %d dBm\n",