[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').
This commit is contained in:
Matteo Cypriani 2013-04-23 11:25:43 -04:00
parent 0fc84a548f
commit c95257f26a
2 changed files with 57 additions and 41 deletions

View File

@ -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]) ;

View File

@ -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",