[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:
parent
0fc84a548f
commit
c95257f26a
|
@ -216,13 +216,13 @@ void* keep_mode_monitor(void *iface) ;
|
||||||
int iface_mode_monitor(const char *const iface) ;
|
int iface_mode_monitor(const char *const iface) ;
|
||||||
#endif // ENABLE_KEEP_MONITOR
|
#endif // ENABLE_KEEP_MONITOR
|
||||||
int capture(void) ;
|
int capture(void) ;
|
||||||
void read_packet(u_char *args, const struct pcap_pkthdr *header,
|
void read_packet(const struct pcap_pkthdr *pkt_header,
|
||||||
const u_char *packet) ;
|
const u_char *pkt_data) ;
|
||||||
void extract_calibration_data(const u_char *packet,
|
void extract_calibration_data(const u_char *pkt_data,
|
||||||
owl_captured_request *request) ;
|
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) ;
|
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_captured_request *request,
|
||||||
owl_bool rtap_fields[15]) ;
|
owl_bool rtap_fields[15]) ;
|
||||||
void get_mac_addr(char *eth, uint8_t mac_bytes[ETHER_ADDR_LEN]) ;
|
void get_mac_addr(char *eth, uint8_t mac_bytes[ETHER_ADDR_LEN]) ;
|
||||||
|
|
|
@ -878,8 +878,23 @@ int capture()
|
||||||
&aggregation_server, NULL) ;
|
&aggregation_server, NULL) ;
|
||||||
|
|
||||||
while (owl_run)
|
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
|
pcap_close(capture_handler) ; // Stop capture
|
||||||
close(aggregation_sockfd) ; // Close socket
|
close(aggregation_sockfd) ; // Close socket
|
||||||
|
@ -892,8 +907,8 @@ int capture()
|
||||||
/*
|
/*
|
||||||
* Treats a packet and sends it to the aggregator.
|
* Treats a packet and sends it to the aggregator.
|
||||||
*/
|
*/
|
||||||
void read_packet(u_char *args, const struct pcap_pkthdr *header,
|
void read_packet(const struct pcap_pkthdr *pkt_header,
|
||||||
const u_char *packet)
|
const u_char *pkt_data)
|
||||||
{
|
{
|
||||||
owl_captured_request request ; // Message to send to the aggregator
|
owl_captured_request request ; // Message to send to the aggregator
|
||||||
uint16_t rtap_bytes ; // Radiotap header size
|
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
|
// Copy 2 bytes from the 3rd packet byte, that is the size of the rtap
|
||||||
// header (changes with the flags):
|
// header (changes with the flags):
|
||||||
offset = 2 ;
|
offset = 2 ;
|
||||||
memcpy(&rtap_bytes, &packet[offset], sizeof(rtap_bytes)) ;
|
memcpy(&rtap_bytes, &pkt_data[offset], sizeof(rtap_bytes)) ;
|
||||||
// Radiotap header is little-endian
|
// Radiotap header is little-endian
|
||||||
rtap_bytes = le16toh(rtap_bytes) ;
|
rtap_bytes = le16toh(rtap_bytes) ;
|
||||||
// Check rtap_bytes for buggy values
|
// 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
|
// the type of the packet (Management, Control or Data) and its subtype
|
||||||
// (QoS, etc.):
|
// (QoS, etc.):
|
||||||
offset = rtap_bytes ;
|
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
|
// The second byte of the FC field contains the frame flags. The two
|
||||||
// first bits indicate the frame source and destination types: the
|
// 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
|
// bit is 0 the frame comes from a STA. That's what we want for an
|
||||||
// explicit packet:
|
// explicit packet:
|
||||||
offset = rtap_bytes + 1 ;
|
offset = rtap_bytes + 1 ;
|
||||||
raw_packet_fc2 = packet[offset] ;
|
raw_packet_fc2 = pkt_data[offset] ;
|
||||||
|
|
||||||
if (! IS_DATA_FRAME(raw_packet_fc1)) // Data frame?
|
if (! IS_DATA_FRAME(raw_packet_fc1)) // Data frame?
|
||||||
goto not_explicit_packet ;
|
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:
|
// Get the packet type (protocol, 2 bytes) from the LLC header:
|
||||||
offset = rtap_bytes + ieee80211_header_size + 6 ;
|
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) ;
|
llc_packet_type = ntohs(llc_packet_type) ;
|
||||||
|
|
||||||
if (llc_packet_type != ETHERTYPE_IP) // IP packet?
|
if (llc_packet_type != ETHERTYPE_IP) // IP packet?
|
||||||
goto not_explicit_packet ;
|
goto not_explicit_packet ;
|
||||||
|
|
||||||
offset = rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE ;
|
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:
|
// Get the source IP:
|
||||||
memcpy(request.mobile_ip_addr_bytes, &packet_ip_header->saddr, 4) ;
|
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 =
|
offset =
|
||||||
rtap_bytes + ieee80211_header_size +
|
rtap_bytes + ieee80211_header_size +
|
||||||
LLC_HEADER_SIZE + sizeof(struct iphdr) ;
|
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) ;
|
dest_port = ntohs(packet_udp_header->dest) ;
|
||||||
|
|
||||||
#ifdef USE_PTHREAD
|
#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:
|
// Source MAC address is 10 bytes after the 802.11 packet type:
|
||||||
offset = rtap_bytes + 10 ;
|
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:
|
// Drop the packet if it comes from the AP itself:
|
||||||
if (owl_mac_equals(my_mac_bytes, request.mobile_mac_addr_bytes))
|
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 :
|
// Copy AP MAC :
|
||||||
memcpy(request.ap_mac_addr_bytes, my_mac_bytes, ETHER_ADDR_LEN) ;
|
memcpy(request.ap_mac_addr_bytes, my_mac_bytes, ETHER_ADDR_LEN) ;
|
||||||
// Capture time is in the pcap header (host-endian):
|
// 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) ;
|
owl_hton_timestamp(&request.capture_time) ;
|
||||||
|
|
||||||
/* Active mode */
|
/* Active mode */
|
||||||
|
@ -1027,12 +1043,12 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header,
|
||||||
offset =
|
offset =
|
||||||
rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE +
|
rtap_bytes + ieee80211_header_size + LLC_HEADER_SIZE +
|
||||||
sizeof(struct iphdr) + sizeof(struct udphdr) ;
|
sizeof(struct iphdr) + sizeof(struct udphdr) ;
|
||||||
request.type = packet[offset] ;
|
request.type = pkt_data[offset] ;
|
||||||
extract_packet_numbers(&packet[++offset], &request) ;
|
extract_packet_numbers(&pkt_data[++offset], &request) ;
|
||||||
offset += 2 * sizeof(uint16_t) ;
|
offset += 2 * sizeof(uint16_t) ;
|
||||||
// Copy the timestamp "as is" (i.e. without changing endianness)
|
// Copy the timestamp "as is" (i.e. without changing endianness)
|
||||||
// because it will return to the network soon:
|
// because it will return to the network soon:
|
||||||
memcpy(&request.request_time, &packet[offset],
|
memcpy(&request.request_time, &pkt_data[offset],
|
||||||
sizeof(owl_timestamp)) ;
|
sizeof(owl_timestamp)) ;
|
||||||
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 :
|
case OWL_REQUEST_CALIBRATION :
|
||||||
if (VERBOSE_INFO)
|
if (VERBOSE_INFO)
|
||||||
printf("\nExplicit calibration packet received.\n") ;
|
printf("\nExplicit calibration packet received.\n") ;
|
||||||
extract_calibration_data(&packet[offset], &request) ;
|
extract_calibration_data(&pkt_data[offset], &request) ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
case OWL_REQUEST_AUTOCALIBRATION :
|
case OWL_REQUEST_AUTOCALIBRATION :
|
||||||
|
@ -1057,7 +1073,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header,
|
||||||
printf(".. on the wrong port!") ;
|
printf(".. on the wrong port!") ;
|
||||||
putchar('\n') ;
|
putchar('\n') ;
|
||||||
}
|
}
|
||||||
extract_calibration_data(&packet[offset], &request) ;
|
extract_calibration_data(&pkt_data[offset], &request) ;
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
|
@ -1088,7 +1104,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header,
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
/* Radiotap header handling */
|
/* Radiotap header handling */
|
||||||
extract_radiotap_data(packet, &request, rtap_fields) ;
|
extract_radiotap_data(pkt_data, &request, rtap_fields) ;
|
||||||
|
|
||||||
/* Display the packet details */
|
/* Display the packet details */
|
||||||
if (VERBOSE_DISPLAY_CAPTURED)
|
if (VERBOSE_DISPLAY_CAPTURED)
|
||||||
|
@ -1143,7 +1159,7 @@ void read_packet(u_char *args, const struct pcap_pkthdr *header,
|
||||||
request.direction,
|
request.direction,
|
||||||
ntohs(request.packet_id),
|
ntohs(request.packet_id),
|
||||||
ntohs(request.nb_packets),
|
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'.
|
* Fills 'request' with the calibration data extracted from 'pkt_data'.
|
||||||
* Note: 'packet' is read from its first byte, therefore you must not
|
* Note: 'pkt_data' is read from its first byte, therefore you must not
|
||||||
* pass the whole received packet to this function.
|
* 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)
|
owl_captured_request *request)
|
||||||
{
|
{
|
||||||
request->direction = packet[0] ;
|
request->direction = pkt_data[0] ;
|
||||||
assert(sizeof(float) == 4) ;
|
assert(sizeof(float) == 4) ;
|
||||||
memcpy(&request->x_position, &packet[1], sizeof(float)) ;
|
memcpy(&request->x_position, &pkt_data[1], sizeof(float)) ;
|
||||||
memcpy(&request->y_position, &packet[5], sizeof(float)) ;
|
memcpy(&request->y_position, &pkt_data[5], sizeof(float)) ;
|
||||||
memcpy(&request->z_position, &packet[9], sizeof(float)) ;
|
memcpy(&request->z_position, &pkt_data[9], sizeof(float)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fills 'request' with the number of packets and packet ID extracted
|
* Fills 'request' with the number of packets and packet ID extracted
|
||||||
* from 'packet'.
|
* from 'pkt_data'.
|
||||||
* Note: 'packet' is read from its first byte, therefore you must not
|
* Note: 'pkt_data' is read from its first byte, therefore you must not
|
||||||
* pass the whole received packet to this function.
|
* 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)
|
owl_captured_request *request)
|
||||||
{
|
{
|
||||||
// Current packet's ID:
|
// Current packet's ID:
|
||||||
memcpy(&request->packet_id, packet,
|
memcpy(&request->packet_id, pkt_data,
|
||||||
sizeof(uint16_t)) ;
|
sizeof(uint16_t)) ;
|
||||||
request->packet_id = request->packet_id ;
|
request->packet_id = request->packet_id ;
|
||||||
// Number of packets:
|
// Number of packets:
|
||||||
memcpy(&request->nb_packets, &packet[sizeof(uint16_t)],
|
memcpy(&request->nb_packets, &pkt_data[sizeof(uint16_t)],
|
||||||
sizeof(uint16_t)) ;
|
sizeof(uint16_t)) ;
|
||||||
request->nb_packets = request->nb_packets ;
|
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
|
* Fills 'request' with the required data extracted from the Radiotap
|
||||||
* header of 'packet'. The elements of 'rtap_fields' are set to owl_true
|
* header of 'pkt_data'. The elements of 'rtap_fields' are set to
|
||||||
* when the corresponding Radiotap flag is found in the packet.
|
* 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_captured_request *request,
|
||||||
owl_bool rtap_fields[15])
|
owl_bool rtap_fields[15])
|
||||||
{
|
{
|
||||||
|
@ -1214,7 +1230,7 @@ void extract_radiotap_data(const u_char *packet,
|
||||||
|
|
||||||
// Get rtap flags:
|
// Get rtap flags:
|
||||||
memcpy(&rtap_presentflags,
|
memcpy(&rtap_presentflags,
|
||||||
&packet[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS) ;
|
&pkt_data[RTAP_P_PRESENTFLAGS], RTAP_L_PRESENTFLAGS) ;
|
||||||
// The Radiotap header is little-endian
|
// The Radiotap header is little-endian
|
||||||
rtap_presentflags = le32toh(rtap_presentflags) ;
|
rtap_presentflags = le32toh(rtap_presentflags) ;
|
||||||
|
|
||||||
|
@ -1252,7 +1268,7 @@ void extract_radiotap_data(const u_char *packet,
|
||||||
break ;
|
break ;
|
||||||
case RTAP_ANTENNASIGNALDBM:
|
case RTAP_ANTENNASIGNALDBM:
|
||||||
memcpy(&request->ss_dbm,
|
memcpy(&request->ss_dbm,
|
||||||
&packet[rtap_position], RTAP_L_ANTENNASIGNALDBM) ;
|
&pkt_data[rtap_position], RTAP_L_ANTENNASIGNALDBM) ;
|
||||||
rtap_fields[RTAP_ANTENNASIGNALDBM] = owl_true;
|
rtap_fields[RTAP_ANTENNASIGNALDBM] = owl_true;
|
||||||
if (VERBOSE_INFO)
|
if (VERBOSE_INFO)
|
||||||
printf("Antenna signal: %d dBm\n",
|
printf("Antenna signal: %d dBm\n",
|
||||||
|
|
Loading…
Reference in New Issue